Update timeline view to have a max width for the scrolling area

This commit is contained in:
Shawn 2022-10-27 10:26:43 -06:00
parent 048dae8ce8
commit 9a27803d67
2 changed files with 93 additions and 88 deletions

View File

@ -50,7 +50,7 @@ class _EventPopupsState extends State<_EventPopups> {
key: ValueKey(_eventToShow?.year), key: ValueKey(_eventToShow?.year),
child: IntrinsicHeight( child: IntrinsicHeight(
child: SizedBox( child: SizedBox(
width: 600, width: $styles.sizes.maxContentWidth3,
child: Padding( child: Padding(
padding: EdgeInsets.all($styles.insets.md), padding: EdgeInsets.all($styles.insets.md),
child: TimelineEventCard( child: TimelineEventCard(

View File

@ -24,6 +24,7 @@ class _ScalingViewportState extends State<_ScrollingViewport> {
late final _ScrollingViewportController controller = _ScrollingViewportController(this); late final _ScrollingViewportController controller = _ScrollingViewportController(this);
static const double _minTimelineSize = 100; static const double _minTimelineSize = 100;
final _currentEventMarker = ValueNotifier<TimelineEvent?>(null); final _currentEventMarker = ValueNotifier<TimelineEvent?>(null);
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -44,50 +45,41 @@ class _ScalingViewportState extends State<_ScrollingViewport> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder(builder: (_, constraints) { return GestureDetector(
// cache constraints, so they can be used to maintain the selected year while zooming // Handle pinch to zoom
controller._constraints = constraints; onScaleUpdate: controller._handleScaleUpdate,
double vtPadding = constraints.maxHeight / 2; onScaleStart: controller._handleScaleStart,
double size = controller.calculateContentHeight(); behavior: HitTestBehavior.translucent,
return GestureDetector( // Fade in entire view when first shown
// Handle pinch to zoom child: Stack(
onScaleUpdate: controller._handleScaleUpdate, children: [
onScaleStart: controller._handleScaleStart, Column(
behavior: HitTestBehavior.translucent,
// Fade in entire view when first shown
child: Animate(
effects: const [FadeEffect()],
child: Stack(
children: [ children: [
Column( /// Main scrolling area, holds the year markers, and the [WondersTimelineBuilder]
children: [ Expanded(
/// Main scrolling area, holds the year markers, and the [WondersTimelineBuilder] child: _buildScrollingArea(context),
Expanded(
child: _buildScrollingArea(vtPadding, size, context, constraints),
),
Gap($styles.insets.xs),
/// Era Text (classical, modern etc)
_buildAnimatedEraText(context),
Gap($styles.insets.xs),
],
), ),
Gap($styles.insets.xs),
/// Dashed line with a year that changes as we scroll /// Era Text (classical, modern etc)
IgnorePointer( _buildAnimatedEraText(context),
ignoringSemantics: false, Gap($styles.insets.xs),
child: AnimatedBuilder(
animation: controller.scroller,
builder: (_, __) {
return _DashedDividerWithYear(controller.calculateYearFromScrollPos());
},
),
),
], ],
).animate().fadeIn(),
/// Dashed line with a year that changes as we scroll
IgnorePointer(
ignoringSemantics: false,
child: AnimatedBuilder(
animation: controller.scroller,
builder: (_, __) {
return _DashedDividerWithYear(controller.calculateYearFromScrollPos());
},
),
), ),
), ],
); ),
}); );
} }
AnimatedBuilder _buildAnimatedEraText(BuildContext context) { AnimatedBuilder _buildAnimatedEraText(BuildContext context) {
@ -107,7 +99,7 @@ class _ScalingViewportState extends State<_ScrollingViewport> {
}); });
} }
Widget _buildScrollingArea(double vtPadding, double size, BuildContext context, BoxConstraints constraints) { Widget _buildScrollingArea(BuildContext context) {
// Builds a TimelineSection, and passes it the currently selected yr based on scroll position. // Builds a TimelineSection, and passes it the currently selected yr based on scroll position.
// Rebuilds when timeline is scrolled. // Rebuilds when timeline is scrolled.
Widget buildTimelineSection(WonderData data) { Widget buildTimelineSection(WonderData data) {
@ -124,59 +116,72 @@ class _ScalingViewportState extends State<_ScrollingViewport> {
); );
} }
return Stack( return LayoutBuilder(
children: [ builder: (_, constraints) {
SingleChildScrollView( // cache constraints, so they can be used to maintain the selected year while zooming
controller: controller.scroller, controller._constraints = constraints;
padding: EdgeInsets.symmetric(vertical: vtPadding), double vtPadding = constraints.maxHeight / 2;
// A stack inside a SizedBox which sets its overall height double size = controller.calculateContentHeight();
child: SizedBox( final contentSize = min($styles.sizes.maxContentWidth2, constraints.maxWidth);
height: size, return Stack(
width: double.infinity, children: [
child: Stack( SingleChildScrollView(
children: [ controller: controller.scroller,
/// Year Markers padding: EdgeInsets.symmetric(vertical: vtPadding),
_YearMarkers(), // A stack inside a SizedBox which sets its overall height
child: Center(
child: SizedBox(
height: size,
width: contentSize,
child: Stack(
children: [
/// Year Markers
_YearMarkers(),
/// individual timeline sections /// individual timeline sections
Positioned.fill( Positioned.fill(
left: 100, left: 100,
right: $styles.insets.sm, right: $styles.insets.sm,
child: FocusTraversalGroup( child: FocusTraversalGroup(
child: WondersTimelineBuilder( //child: Placeholder(),
axis: Axis.vertical, child: WondersTimelineBuilder(
crossAxisGap: max(6, (constraints.maxWidth - (120 * 3)) / 2), axis: Axis.vertical,
minSize: _minTimelineSize, crossAxisGap: max(6, (contentSize - (120 * 3)) / 2),
timelineBuilder: (_, data, __) => buildTimelineSection(data)), minSize: _minTimelineSize,
timelineBuilder: (_, data, __) => buildTimelineSection(data),
),
),
),
/// Event Markers, rebuilds on scroll
AnimatedBuilder(
animation: controller.scroller,
builder: (_, __) => _EventMarkers(
controller.calculateYearFromScrollPos(),
onEventChanged: _handleEventMarkerChanged,
),
),
],
), ),
), ),
),
/// Event Markers, rebuilds on scroll
AnimatedBuilder(
animation: controller.scroller,
builder: (_, __) => _EventMarkers(
controller.calculateYearFromScrollPos(),
onEventChanged: _handleEventMarkerChanged,
),
),
],
), ),
),
),
/// Top and bottom gradients for visual style /// Top and bottom gradients for visual style
ListOverscollGradient(), ListOverscollGradient(),
BottomCenter( BottomCenter(
child: ListOverscollGradient(bottomUp: true), child: ListOverscollGradient(bottomUp: true),
), ),
/// Event Popups, rebuilds when [_currentEventMarker] changes /// Event Popups, rebuilds when [_currentEventMarker] changes
ValueListenableBuilder<TimelineEvent?>( ValueListenableBuilder<TimelineEvent?>(
valueListenable: _currentEventMarker, valueListenable: _currentEventMarker,
builder: (_, data, __) { builder: (_, data, __) {
return _EventPopups(currentEvent: data); return _EventPopups(currentEvent: data);
}) })
], ],
);
},
); );
} }
} }