Skip to content

Commit f852610

Browse files
experimental responsiveness
1 parent 1b82a43 commit f852610

File tree

5 files changed

+97
-51
lines changed

5 files changed

+97
-51
lines changed

samples/FluidHostPage.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,37 @@ public class FluidHostPage : ContentPage, IFluidHost
88
private int _zIndex = 0;
99
private View? _currentView;
1010
private readonly AbsoluteLayout _presenter = [];
11+
private static readonly Dictionary<int, int> s_screens = new()
12+
{
13+
{ (int)BreakPoint.sm, 640 },
14+
{ (int)BreakPoint.md, 768 },
15+
{ (int)BreakPoint.lg, 1024 },
16+
{ (int)BreakPoint.xl, 1280 },
17+
{ (int)BreakPoint.xxl, 1536 }
18+
};
1119

1220
public FluidHostPage()
1321
{
1422
Content = _presenter = [];
1523
Loaded += (_, _) => FlowNavigation.Current.Initialize(this);
16-
SizeChanged += (_, _) => _currentView?.Size(Width, Height);
24+
SizeChanged += (_, _) =>
25+
{
26+
_ = (_currentView?.Size(Width, Height));
27+
28+
var bp = GetBreakpoint();
29+
if (bp == ActiveBreakpoint) return;
30+
31+
ActiveBreakpoint = bp;
32+
BreakpointChanged?.Invoke(ActiveBreakpoint);
33+
};
1734

1835
Presenter = _presenter;
1936
}
2037

2138
public View Presenter { get; }
39+
public BreakPoint ActiveBreakpoint { get; private set; } = BreakPoint.sm;
40+
41+
public event Action<BreakPoint>? BreakpointChanged;
2242

2343
public void ShowView(View view)
2444
{
@@ -29,4 +49,19 @@ public void ShowView(View view)
2949
if (!_presenter.Children.Contains(view))
3050
_presenter.Children.Add(view);
3151
}
52+
53+
private BreakPoint GetBreakpoint()
54+
{
55+
var screenWidth = Width;
56+
57+
// sm is the default breakpoint
58+
var breakPoint = BreakPoint.sm;
59+
60+
if (screenWidth >= s_screens[1]) breakPoint = BreakPoint.md;
61+
if (screenWidth >= s_screens[2]) breakPoint = BreakPoint.lg;
62+
if (screenWidth >= s_screens[3]) breakPoint = BreakPoint.xl;
63+
if (screenWidth >= s_screens[4]) breakPoint = BreakPoint.xxl;
64+
65+
return breakPoint;
66+
}
3267
}

src/FluidView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace FluidNav;
22

3-
public abstract class FluidView : ContentView
3+
public abstract class FluidView : ResponsiveView
44
{
55
public FluidView()
66
{

src/IFluidHost.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ public interface IFluidHost
2020
/// </summary>
2121
View Presenter { get; }
2222

23+
/// <summary>
24+
/// Gets the active breakpoint.
25+
/// </summary>
26+
BreakPoint ActiveBreakpoint { get; }
27+
28+
/// <summary>
29+
/// Called when the breakpoint changes.
30+
/// </summary>
31+
event Action<BreakPoint> BreakpointChanged;
32+
2333
/// <summary>
2434
/// Shows the specified view.
2535
/// </summary>

src/ResponsiveView.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace FluidNav;
2+
3+
public abstract class ResponsiveView : ContentView
4+
{
5+
public ResponsiveView()
6+
{
7+
var view = FlowNavigation.Current.View ?? throw new Exception("Host view not found");
8+
view.BreakpointChanged += OnBreakpointChanged;
9+
}
10+
11+
public BreakPoint ActiveBreakpoint => FlowNavigation.Current.View.ActiveBreakpoint;
12+
13+
protected virtual void OnBreakpointChanged(BreakPoint breakPoint)
14+
{
15+
var bp = (int)breakPoint;
16+
17+
OnSm();
18+
if (bp >= 1) OnMd();
19+
if (bp >= 2) OnLg();
20+
if (bp >= 3) OnXl();
21+
if (bp >= 4) OnXxl();
22+
}
23+
24+
protected virtual void OnSm() { }
25+
26+
protected virtual void OnMd() { }
27+
28+
protected virtual void OnLg() { }
29+
30+
protected virtual void OnXl() { }
31+
32+
protected virtual void OnXxl() { }
33+
}

src/TransitionView.cs

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,10 @@
22

33
namespace FluidNav;
44

5-
public abstract class TransitionView : ContentView
5+
public abstract class TransitionView : ResponsiveView
66
{
7-
private BreakPoint _activeBreakpoint = BreakPoint.sm;
87
private Type _activeType = typeof(object);
98
private readonly Dictionary<Type, IEnumerable<Flow>[]> _flows = [];
10-
private static readonly Dictionary<int, int> s_screens = new()
11-
{
12-
{ (int)BreakPoint.sm, 640 },
13-
{ (int)BreakPoint.md, 768 },
14-
{ (int)BreakPoint.lg, 1024 },
15-
{ (int)BreakPoint.xl, 1280 },
16-
{ (int)BreakPoint.xxl, 1536 }
17-
};
18-
19-
public TransitionView()
20-
{
21-
SizeChanged += (s, e) =>
22-
{
23-
var flow = GetBreakpointFlow(_activeType, out var breakPoint);
24-
if (breakPoint == _activeBreakpoint) return;
25-
26-
_activeBreakpoint = breakPoint;
27-
_ = Complete(_activeType);
28-
};
29-
}
309

3110
public Rect TransitionBounds { get; set; }
3211

@@ -48,13 +27,13 @@ public bool RemoveState<TView>()
4827
public TransitionView Complete(Type type, IEnumerable<Flow>? flow = null)
4928
{
5029
_activeType = type;
51-
return FluidAnimationsExtensions.Complete(this, flow ?? GetBreakpointFlow(type, out _activeBreakpoint));
30+
return FluidAnimationsExtensions.Complete(this, flow ?? GetBreakpointFlow(type, ActiveBreakpoint));
5231
}
5332

5433
public Task<bool> Animate(Type type, IEnumerable<Flow>? flow = null)
5534
{
5635
_activeType = type;
57-
return FluidAnimationsExtensions.Animate(this, flow ?? GetBreakpointFlow(type, out _activeBreakpoint));
36+
return FluidAnimationsExtensions.Animate(this, flow ?? GetBreakpointFlow(type, ActiveBreakpoint));
5837
}
5938

6039
/// <summary>
@@ -96,6 +75,13 @@ public static DataTemplate Build<TFromView, TToView, TTransitionView>(
9675
});
9776
}
9877

78+
protected override void OnBreakpointChanged(BreakPoint breakPoint)
79+
{
80+
base.OnBreakpointChanged(breakPoint);
81+
82+
_ = Complete(_activeType);
83+
}
84+
9985
private void SetBreakpointFlow(Type type, BreakPoint breakpoint, IEnumerable<Flow> flow)
10086
{
10187
if (!_flows.TryGetValue(type, out var typeFlows))
@@ -107,33 +93,15 @@ private void SetBreakpointFlow(Type type, BreakPoint breakpoint, IEnumerable<Flo
10793
typeFlows[(int)breakpoint] = flow;
10894
}
10995

110-
private IEnumerable<Flow> GetBreakpointFlow(Type type, out BreakPoint breakPoint)
96+
private IEnumerable<Flow> GetBreakpointFlow(Type type, BreakPoint breakpoint)
11197
{
112-
var view = FlowNavigation.Current.View ?? throw new Exception("Host view not found");
113-
114-
var screenWidth = view.Width;
115-
var ft = _flows[type];
116-
117-
var flows = ft[(int)BreakPoint.sm];
118-
breakPoint = BreakPoint.sm;
119-
120-
bool evaluateBreakpoint(BreakPoint bp)
121-
{
122-
if (screenWidth >= s_screens[(int)bp])
123-
{
124-
var f = ft![(int)bp];
125-
flows = f ?? flows;
126-
return f is not null;
127-
}
128-
129-
return false;
130-
}
98+
var flowsOnType = _flows[type];
99+
var i = (int)breakpoint;
100+
var flow = flowsOnType[i];
131101

132-
if (evaluateBreakpoint(BreakPoint.md)) breakPoint = BreakPoint.md;
133-
if (evaluateBreakpoint(BreakPoint.lg)) breakPoint = BreakPoint.lg;
134-
if (evaluateBreakpoint(BreakPoint.xl)) breakPoint = BreakPoint.xl;
135-
if (evaluateBreakpoint(BreakPoint.xxl)) breakPoint = BreakPoint.xxl;
102+
while (flow is null && i > 0)
103+
flow = flowsOnType[--i];
136104

137-
return flows;
105+
return flow ?? throw new Exception($"No flow found for {type.Name} at breakpoint {breakpoint}");
138106
}
139107
}

0 commit comments

Comments
 (0)