Skip to content

Instantly share code, notes, and snippets.

@SpikedPaladin
Created February 28, 2025 10:51
Show Gist options
  • Save SpikedPaladin/48f7a752935f52c94c9227eb64e69ed7 to your computer and use it in GitHub Desktop.
Save SpikedPaladin/48f7a752935f52c94c9227eb64e69ed7 to your computer and use it in GitHub Desktop.
DragView vala
public class DragView : Gtk.Widget {
construct {
new TestChild().set_parent(this);
with (var it = new Gtk.GestureDrag()) {
DragChild? drag_target = null;
Graphene.Point start_cursor_pos = { 0, 0 };
Graphene.Point cursor_offset = { 0, 0 };
it.drag_begin.connect((x, y) => {
var widget = pick(x, y, Gtk.PickFlags.DEFAULT);
if (!(widget is DragView)) {
DragChild? target = widget as DragChild;
if (!(target is DragChild))
for (var parent = widget.parent; !(parent is DragView); parent = parent.parent) {
if (parent is DragChild) {
target = parent as DragChild;
break;
}
}
if (target == null)
return;
start_cursor_pos = { (float) x, (float) y };
drag_target = target;
cursor_offset = {
start_cursor_pos.x - drag_target.x,
start_cursor_pos.y - drag_target.y
};
}
});
it.drag_update.connect((offset_x, offset_y) => {
if (drag_target == null)
return;
double start_x, start_y;
it.get_start_point(out start_x, out start_y);
Graphene.Point origin = { (float) (start_x + offset_x), (float) (start_y + offset_y) };
drag_target.x = (int) (origin.x - cursor_offset.x);
drag_target.y = (int) (origin.y - cursor_offset.y);
drag_target.x = drag_target.x.clamp(0, get_width() - drag_target.get_width());
drag_target.y = drag_target.y.clamp(0, get_height() - drag_target.get_height());
queue_allocate();
});
it.drag_end.connect(() => {
drag_target = null;
});
add_controller(it);
}
}
public override void size_allocate(int width, int height, int baseline) {
for (var child = get_first_child(); child != null; child = child.get_next_sibling()) {
var drag_child = child as DragChild;
if (drag_child == null) continue;
Gtk.Requisition _, natural_size;
child.get_preferred_size(out _, out natural_size);
child.allocate(
natural_size.width,
natural_size.height,
baseline,
new Gsk.Transform().translate({ drag_child.x, drag_child.y })
);
}
}
public class TestChild : DragChild {
construct {
set_layout_manager(new Gtk.BinLayout());
var label = new Gtk.Label("Test");
label.set_parent(this);
}
}
public abstract class DragChild : Gtk.Widget {
public virtual int x { get; set; }
public virtual int y { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment