Skip to content

Instantly share code, notes, and snippets.

@Brayan-724
Created June 26, 2025 22:18
Show Gist options
  • Select an option

  • Save Brayan-724/f374656ec0286de61fb93371a305999f to your computer and use it in GitHub Desktop.

Select an option

Save Brayan-724/f374656ec0286de61fb93371a305999f to your computer and use it in GitHub Desktop.
Draggable Widget
enum DraggableDirection {
Horizontal,
Vertical
}
enum DraggableSide {
Start,
End
}
struct DraggableContext {
width: length,
height: length,
direction: DraggableDirection,
is-horizontal: bool,
is-vertical: bool,
drag-proportion: float,
drag-size: length,
drag-offset: length,
drag-handle-size: length,
min-proportion: float,
max-proportion: float,
}
component DraggablePanel inherits Rectangle {
in-out property <DraggableContext> context;
in-out property <DraggableSide> drag-side;
clip: true;
states [
vertical-start when context.is-vertical && drag-side == DraggableSide.Start: {
y: 0px;
width: context.width;
height: context.drag-offset;
}
vertical-end when context.is-vertical && drag-side == DraggableSide.End: {
y: context.drag-offset + context.drag-handle-size;
width: context.width;
height: context.drag-size - context.drag-offset - context.drag-handle-size;
}
horizontal-start when context.is-horizontal && drag-side == DraggableSide.Start: {
x: 0px;
width: context.drag-offset;
height: context.height;
}
horizontal-end when context.is-horizontal && drag-side == DraggableSide.End: {
x: context.drag-offset + context.drag-handle-size;
width: context.drag-size - context.drag-offset - context.drag-handle-size;
height: context.height;
}
]
@children
}
component DraggableHandle inherits Rectangle {
in-out property <float> drag-proportion;
in-out property <DraggableContext> context;
background: ta.has-hover ? #555 : #333;
z: 1;
states [
vertical when context.is-vertical: {
y: context.drag-offset;
height: context.drag-handle-size;
width: context.width;
ta.y: -3px;
}
horizontal when context.is-horizontal: {
x: context.drag-offset;
width: context.drag-handle-size;
height: context.height;
ta.x: -3px;
}
]
ta := TouchArea {
property <float> new-proportion;
width: parent.width;
height: parent.height + 6px;
mouse-cursor: context.is-horizontal ? col-resize : row-resize;
moved => {
if (self.pressed) {
if (context.is-vertical) {
self.new-proportion = (self.mouse-y + root.y) / context.height;
} else {
self.new-proportion = (self.mouse-x + root.x) / context.width;
}
root.drag-proportion = max(context.min-proportion, min(context.max-proportion, self.new-proportion));
}
}
}
}
component Draggable {
in-out property <bool> no-handle: false;
in-out property <DraggableDirection> direction;
in-out property <float> drag-proportion: 0.25;
in-out property <length> drag-size: root.direction == DraggableDirection.Horizontal ? root.width : root.height;
in-out property <length> drag-handle-size: 10px;
in-out property <float> min-proportion: 0;
in-out property <float> max-proportion: 1;
in-out property <length> min-size: 0px;
in-out property <length> max-size: root.drag-size - root.drag-handle-size;
in-out property <DraggableContext> context: {
width: root.width,
height: root.height,
direction: root.direction,
is-horizontal: root.direction == DraggableDirection.Horizontal,
is-vertical: root.direction == DraggableDirection.Vertical,
drag-proportion: root.drag-proportion,
drag-size: root.drag-size,
drag-offset: min(root.max-size, max(root.min-size, root.drag-size * root.drag-proportion)),
drag-handle-size: root.drag-handle-size,
min-proportion: root.min-proportion,
max-proportion: root.max-proportion,
};
if !no-handle: DraggableHandle {
context <=> root.context;
drag-proportion <=> root.drag-proportion;
}
@children
}
export component Demo inherits Draggable {
direction: Horizontal;
preferred-width: 400px;
preferred-height: 600px;
DraggablePanel {
context <=> root.context;
drag-side: Start;
background: #9a3939;
VerticalLayout {
Text {
text: "Elemento";
color: white;
horizontal-alignment: center;
vertical-alignment: center;
}
}
}
DraggablePanel {
context <=> root.context;
drag-side: End;
VerticalLayout {
Draggable {
direction: Vertical;
DraggablePanel {
context <=> parent.context;
drag-side: Start;
background: #9a3939;
VerticalLayout {
Text {
text: "Elemento";
color: white;
horizontal-alignment: center;
vertical-alignment: center;
}
}
}
DraggablePanel {
context <=> parent.context;
drag-side: End;
background: #8e44ad;
VerticalLayout {
Text {
text: "Elemento";
color: white;
horizontal-alignment: center;
vertical-alignment: center;
}
}
}
}
}
}
}
{"main":"main.slint","mappings":{},"slint_version":"1.12.0"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment