always set lane
This commit is contained in:
@@ -12,7 +12,10 @@ import 'timeline_view.dart';
|
||||
|
||||
/// A drop target wrapper for a timeline group.
|
||||
///
|
||||
/// Wraps group lanes content and handles drag-and-drop operations.
|
||||
/// Wraps the entire group column (header + lanes) and handles drag-and-drop
|
||||
/// operations. The [verticalOffset] accounts for the header height and padding
|
||||
/// so that lane calculations are correct relative to the lanes stack.
|
||||
///
|
||||
/// The ghost overlay is rendered by the parent widget in the same Stack.
|
||||
class GroupDropTarget extends StatelessWidget {
|
||||
const GroupDropTarget({
|
||||
@@ -24,6 +27,7 @@ class GroupDropTarget extends StatelessWidget {
|
||||
required this.laneHeight,
|
||||
required this.lanesCount,
|
||||
required this.onEntryMoved,
|
||||
required this.verticalOffset,
|
||||
required this.child,
|
||||
super.key,
|
||||
});
|
||||
@@ -36,6 +40,11 @@ class GroupDropTarget extends StatelessWidget {
|
||||
final double laneHeight;
|
||||
final int lanesCount;
|
||||
final OnEntryMoved? onEntryMoved;
|
||||
|
||||
/// The vertical offset from the top of this widget to the top of the lanes
|
||||
/// stack. This accounts for the group header height and any padding.
|
||||
final double verticalOffset;
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
@@ -65,8 +74,12 @@ class GroupDropTarget extends StatelessWidget {
|
||||
viewport.end,
|
||||
);
|
||||
|
||||
// Subtract header + padding offset so Y is relative to the lanes stack.
|
||||
// When the cursor is over the header, adjustedY is negative and clamps
|
||||
// to lane 1.
|
||||
final adjustedY = local.dy - verticalOffset;
|
||||
final rawLane = LayoutCoordinateService.yToLane(
|
||||
y: local.dy,
|
||||
y: adjustedY,
|
||||
laneHeight: laneHeight,
|
||||
);
|
||||
final maxAllowedLane = (lanesCount <= 0 ? 1 : lanesCount) + 1;
|
||||
|
||||
@@ -84,7 +84,7 @@ class ZTimelineView extends StatelessWidget {
|
||||
projected[group.id] ?? const <ProjectedEntry>[];
|
||||
final lanesCount = _countLanes(groupEntries);
|
||||
|
||||
return Column(
|
||||
final column = Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_GroupHeader(title: group.title, height: groupHeaderHeight),
|
||||
@@ -98,11 +98,31 @@ class ZTimelineView extends StatelessWidget {
|
||||
colorBuilder: colorBuilder,
|
||||
labelBuilder: labelBuilder,
|
||||
contentWidth: contentWidth,
|
||||
onEntryMoved: onEntryMoved,
|
||||
enableDrag: enableDrag,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
// Wrap the entire group (header + lanes) in a DragTarget
|
||||
// so dragging over headers still updates the ghost position.
|
||||
if (enableDrag && onEntryMoved != null) {
|
||||
return GroupDropTarget(
|
||||
group: group,
|
||||
entries: groupEntries,
|
||||
allEntries: entries,
|
||||
viewport: viewport,
|
||||
contentWidth: contentWidth,
|
||||
laneHeight: laneHeight,
|
||||
lanesCount: lanesCount,
|
||||
onEntryMoved: onEntryMoved,
|
||||
verticalOffset:
|
||||
groupHeaderHeight +
|
||||
ZTimelineConstants.verticalOuterPadding,
|
||||
child: column,
|
||||
);
|
||||
}
|
||||
|
||||
return column;
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -157,7 +177,6 @@ class _GroupLanes extends StatelessWidget {
|
||||
required this.labelBuilder,
|
||||
required this.colorBuilder,
|
||||
required this.contentWidth,
|
||||
required this.onEntryMoved,
|
||||
required this.enableDrag,
|
||||
});
|
||||
|
||||
@@ -170,7 +189,6 @@ class _GroupLanes extends StatelessWidget {
|
||||
final EntryLabelBuilder labelBuilder;
|
||||
final EntryColorBuilder colorBuilder;
|
||||
final double contentWidth;
|
||||
final OnEntryMoved? onEntryMoved;
|
||||
final bool enableDrag;
|
||||
|
||||
@override
|
||||
@@ -264,21 +282,6 @@ class _GroupLanes extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
|
||||
// Wrap with DragTarget if drag is enabled
|
||||
if (enableDrag && onEntryMoved != null) {
|
||||
innerStack = GroupDropTarget(
|
||||
group: group,
|
||||
entries: entries,
|
||||
allEntries: allEntries,
|
||||
viewport: viewport,
|
||||
contentWidth: contentWidth,
|
||||
laneHeight: laneHeight,
|
||||
lanesCount: lanesCount,
|
||||
onEntryMoved: onEntryMoved,
|
||||
child: innerStack,
|
||||
);
|
||||
}
|
||||
|
||||
return AnimatedSize(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
curve: Curves.easeInOut,
|
||||
|
||||
Reference in New Issue
Block a user