Drag & drop

ScriptWeaver has in-application drag & drop — dragging widgets and payloads within your own windows. It comes in three layers, all built from ordinary Tk events and geometry, so it behaves the same on every platform. (This is separate from OS/file drag-and-drop — dragging a file in from the desktop.)

Each piece is a chainable widget method; pass false to turn it off.

Draggable — move a widget within its parent

.draggable() lets the user pick a widget up and move it inside its parent. The widget becomes place-managed and follows the pointer.

const card = frame.Card({ heading: 'Notes' });
card.place.configure({ x: 20, y: 20 });

card.draggable(); // free move within the frame
card.draggable({ axis: 'x' }); // horizontal only
card.draggable({ bounds: 'none', onDrag: (e) => (status.text = `${e.x},${e.y}`) });

Drag and drop — carry a payload

Make one widget a source that carries a typed payload, and others targets that accept it. A ghost follows the pointer; on release over an accepting target, onDrop fires with the payload.

card.dragSource({ type: 'card', data: model });
column.dropTarget({ accept: 'card', onDrop: (e) => addTo(column, e.data) });
bin.dropTarget({ accept: ['card', 'note'], onDrop: (e) => trash(e.data) });

Acceptance is by type tag: a source declares a type, a target an accept list (or '*' for any). onDrop fires only on a target whose accept matches the source's type; onDragEnter / onDragOver / onDragLeave fire on any target under the pointer (so a non-matching one can still show "no-drop" feedback). Each event carries { source, type, data, x, y, rootX, rootY, accepted }. The payload (data) is any JSON-serializable value — usually your model object.

Reorderable — drag to reorder a list

.reorderable() on a container lets the user drag its children into a new order. A drop-line shows where the item will land; on drop the child moves and onReorder fires with { from, to, child, container }.

list.reorderable({ onReorder: (e) => model.move(e.from, e.to) });
row.reorderable({ axis: 'x' });

It is layout-manager-aware: a Flex or Grid container reorders through its live-edit API, a packed container via pack, and a place container (absolute positions, no linear order) is a no-op. A Flex's direction sets the default axis. Call .reorderable() again after you add or remove children.

Try it — drag a row:

Live preview. In the Player's built-in docs viewer (scriptweaver --help), this renders DragReorder as a live, theme-aware widget you can interact with.

In the Designer

The same capabilities appear in the ScriptWeaver Designer's inspector as properties — the draggable, dragSource, dropTarget, and reorderable toggles (plus dragAxis, dragType, dropAccept, …) and the onDrag* / onDrop / onReorder events. They are design-only: the Designer emits the matching method calls into your app's code, so nothing drags on the design canvas itself.

Options

The drag & drop properties as they appear in sw.reflect and the Designer inspector. The methods above take the corresponding short names — e.g. the dragAxis property is axis in .draggable({ axis }).

Option Kind Description
draggable boolean Make the widget draggable within its parent (.draggable()).
dragAxis x · y · both Constrain dragging to one axis.
dragBounds parent · none Clamp the drag to the parent, or don't.
dragSource boolean Make the widget a drag source (.dragSource()).
dragType string The payload's type tag, matched against a target's dropAccept.
dropTarget boolean Make the widget a drop target (.dropTarget()).
dropAccept string · list Type tag(s) this target accepts, or * for any.
reorderable boolean Let a container's children be reordered by dragging (.reorderable()).
reorderAxis x · y The reorder direction.
onDragStart event A drag begins (draggable widget or drag source).
onDrag event A draggable widget moves.
onDragEnd event A drag ends.
onDragEnter event A drag enters a drop target.
onDragOver event A drag moves over a drop target.
onDragLeave event A drag leaves a drop target.
onDrop event A payload is dropped on an accepting target.
onReorder event A reorder completes — { from, to, child, container }.

See also