enclosedWithDraggable method
Wrapped with draggable widget
Implementation
Widget enclosedWithDraggable(SortableElement element) {
int index = preservedElements.indexOf(element);
/// A. Return the widget in dragging mode
if (isDragging) {
if (isDraggingMe(element)) {
return IgnorePointer(ignoring: true, child: Opacity(opacity: 0.2, child: element.view));
} else {
return SortableItem(key: ValueKey(index), element: element, onEventHit: eventDoRollingInDragging);
}
}
/// B. Return the widget in idle mode
void safeInvoke(VoidCallback fn) {
try {
fn();
} catch (e, s) {
iDebugLog('❗👠🩸 ERROR! please check it out: $e, $s');
}
}
/// Drag finish (end/complete/canceled) callback
void onDragFinished() {
int newIndex = element.visibleIndex;
int oldIndex = element.preservedIndex;
setState(() {
/// synchronize cache preserved elements with animation elements
preservedElements.clear();
preservedElements.addAll(animationElements);
syncPreservedCacheIndexes();
draggingElement = null;
});
/// invoke caller's callback
safeInvoke(() {
if (oldIndex == newIndex) {
widget.onSortCancel?.call(oldIndex);
} else {
widget.onSorted(oldIndex, newIndex);
}
});
}
/// Drag started callback
void onDragStarted() {
iDebugLog('Drag start index: $index');
iDebugLog('Context\'s size: ${wrapperContext.size}');
iDebugLog('Element\'s size: ${anyElementContext.size}');
/// calculate the row & column & count/size at this moment, for window may resizeable when running as Desktop App
assert(wrapperContext.size != null, 'Wrap\'s size cannot be determined!');
assert(anyElementContext.size != null, 'Element\'s size cannot be determined!');
wrapperSize = wrapperContext.size!;
anyElementSize = anyElementContext.size!;
double width = wrapperSize.width;
double height = wrapperSize.height;
double ew = anyElementSize.width;
double eh = anyElementSize.height;
elementCountPerRow = width ~/ ew;
elementCountPerColumn = height ~/ eh;
iDebugLog('[START] count on per row: $elementCountPerRow, count on per column: $elementCountPerColumn');
while (elementCountPerRow * ew + (elementCountPerRow - 1) * widget.spacing > width) {
elementCountPerRow--;
}
while (elementCountPerColumn * eh + (elementCountPerColumn - 1) * widget.runSpacing > height) {
elementCountPerColumn--;
}
iDebugLog('[FINAL] count on per row: $elementCountPerRow, count on per column: $elementCountPerColumn');
/// set current dragging element
setState(() {
draggingElement = element;
});
/// invoke caller's callback
safeInvoke(() => widget.onSortStart?.call(element.preservedIndex));
}
/// Drag end callback
void onDragEnd(DraggableDetails details) {
onDragFinished();
}
/// Drag complete callback
void onDragCompleted() {
onDragFinished();
}
/// Drag canceled callback
void onDraggableCanceled(Velocity velocity, Offset offset) {
onDragFinished();
}
/// a key is needed, for keeping DraggableState when inner setState called.
ValueKey valueKey = ValueKey(index);
Widget childBuilder = Builder(builder: (context) {
/// cache a context for calculate size on starting drag
anyElementContext = context;
return options.draggableChildBuilder?.call(element.view) ?? element.view;
});
return options.isLongPressDraggable
? LongPressDraggable<SortableElement>(
/// the data passing to DragTarget and its callbacks
data: element,
key: valueKey,
child: childBuilder,
feedback: options.draggableFeedbackBuilder(element.view),
onDragEnd: onDragEnd,
onDragStarted: onDragStarted,
onDragCompleted: onDragCompleted,
onDraggableCanceled: onDraggableCanceled,
)
: Draggable<SortableElement>(
/// the data passing to DragTarget and its callbacks
data: element,
key: valueKey,
child: childBuilder,
feedback: options.draggableFeedbackBuilder(element.view),
onDragEnd: onDragEnd,
onDragStarted: onDragStarted,
onDragCompleted: onDragCompleted,
onDraggableCanceled: onDraggableCanceled,
);
}