add scrolling using mouse wheel
This commit is contained in:
parent
401056b676
commit
eb97a0d832
49
src/ui.zig
49
src/ui.zig
@ -158,7 +158,8 @@ pub const Key = struct {
|
|||||||
pub const Event = union(enum) {
|
pub const Event = union(enum) {
|
||||||
mouse_pressed: rl.MouseButton,
|
mouse_pressed: rl.MouseButton,
|
||||||
mouse_released: rl.MouseButton,
|
mouse_released: rl.MouseButton,
|
||||||
mouse_move: Vec2
|
mouse_move: Vec2,
|
||||||
|
mouse_scroll: Vec2
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Signal = struct {
|
pub const Signal = struct {
|
||||||
@ -173,11 +174,14 @@ pub const Signal = struct {
|
|||||||
right_clicked,
|
right_clicked,
|
||||||
|
|
||||||
left_dragging,
|
left_dragging,
|
||||||
right_dragging
|
right_dragging,
|
||||||
|
|
||||||
|
scrolled
|
||||||
};
|
};
|
||||||
|
|
||||||
flags: std.EnumSet(Flag) = .{},
|
flags: std.EnumSet(Flag) = .{},
|
||||||
drag: Vec2 = .{ .x = 0, .y = 0 },
|
drag: Vec2 = .{ .x = 0, .y = 0 },
|
||||||
|
scroll: Vec2 = .{ .x = 0, .y = 0 },
|
||||||
|
|
||||||
pub fn clicked(self: Signal) bool {
|
pub fn clicked(self: Signal) bool {
|
||||||
return self.flags.contains(.left_clicked) or self.flags.contains(.right_clicked);
|
return self.flags.contains(.left_clicked) or self.flags.contains(.right_clicked);
|
||||||
@ -187,6 +191,10 @@ pub const Signal = struct {
|
|||||||
return self.flags.contains(.left_dragging) or self.flags.contains(.right_dragging);
|
return self.flags.contains(.left_dragging) or self.flags.contains(.right_dragging);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn scrolled(self: Signal) bool {
|
||||||
|
return self.flags.contains(.scrolled);
|
||||||
|
}
|
||||||
|
|
||||||
fn insertMousePressed(self: *Signal, mouse_button: rl.MouseButton) void {
|
fn insertMousePressed(self: *Signal, mouse_button: rl.MouseButton) void {
|
||||||
if (mouse_button == .mouse_button_left) {
|
if (mouse_button == .mouse_button_left) {
|
||||||
self.flags.insert(.left_pressed);
|
self.flags.insert(.left_pressed);
|
||||||
@ -237,6 +245,8 @@ pub const Box = struct {
|
|||||||
draggable_x,
|
draggable_x,
|
||||||
draggable_y,
|
draggable_y,
|
||||||
|
|
||||||
|
scrollable,
|
||||||
|
|
||||||
fixed_x,
|
fixed_x,
|
||||||
fixed_y,
|
fixed_y,
|
||||||
fixed_width,
|
fixed_width,
|
||||||
@ -503,6 +513,11 @@ pub fn begin(self: *UI) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mouse_wheel = rl.getMouseWheelMoveV();
|
||||||
|
if (mouse_wheel.x != 0 or mouse_wheel.y != 0) {
|
||||||
|
self.events.appendAssumeCapacity(Event{ .mouse_scroll = mouse_wheel });
|
||||||
|
}
|
||||||
|
|
||||||
const root_box = self.newBox(root_box_key);
|
const root_box = self.newBox(root_box_key);
|
||||||
root_box.size.x = Size.pixels(@floatFromInt(window_width), 1);
|
root_box.size.x = Size.pixels(@floatFromInt(window_width), 1);
|
||||||
root_box.size.y = Size.pixels(@floatFromInt(window_height), 1);
|
root_box.size.y = Size.pixels(@floatFromInt(window_height), 1);
|
||||||
@ -1021,6 +1036,7 @@ pub fn signalFromBox(self: *UI, box: *Box) Signal {
|
|||||||
const key = box.key;
|
const key = box.key;
|
||||||
const clickable = box.flags.contains(.clickable);
|
const clickable = box.flags.contains(.clickable);
|
||||||
const draggable = box.flags.contains(.draggable_x) or box.flags.contains(.draggable_y);
|
const draggable = box.flags.contains(.draggable_x) or box.flags.contains(.draggable_y);
|
||||||
|
const scrollable = box.flags.contains(.scrollable);
|
||||||
const is_mouse_inside = rect_utils.isInsideVec2(rect, self.mouse);
|
const is_mouse_inside = rect_utils.isInsideVec2(rect, self.mouse);
|
||||||
|
|
||||||
var event_index: usize = 0;
|
var event_index: usize = 0;
|
||||||
@ -1055,6 +1071,13 @@ pub fn signalFromBox(self: *UI, box: *Box) Signal {
|
|||||||
taken = true;
|
taken = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event == .mouse_scroll and is_mouse_inside and scrollable) {
|
||||||
|
result.scroll = event.mouse_scroll;
|
||||||
|
result.flags.insert(.scrolled);
|
||||||
|
|
||||||
|
taken = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (taken) {
|
if (taken) {
|
||||||
_ = self.events.swapRemove(event_index);
|
_ = self.events.swapRemove(event_index);
|
||||||
} else {
|
} else {
|
||||||
@ -1160,6 +1183,7 @@ pub fn pushScrollbar(self: *UI, key: UI.Key) *Box {
|
|||||||
self.pushParent(container);
|
self.pushParent(container);
|
||||||
|
|
||||||
const content_area = self.newBoxFromString("Scroll area");
|
const content_area = self.newBoxFromString("Scroll area");
|
||||||
|
content_area.flags.insert(.scrollable);
|
||||||
content_area.size = .{
|
content_area.size = .{
|
||||||
.x = UI.Size.percent(1, 0),
|
.x = UI.Size.percent(1, 0),
|
||||||
.y = UI.Size.percent(1, 0),
|
.y = UI.Size.percent(1, 0),
|
||||||
@ -1181,6 +1205,7 @@ pub fn popScrollbar(self: *UI) void {
|
|||||||
|
|
||||||
const scrollbar_area = self.newBoxFromString("Scrollbar area");
|
const scrollbar_area = self.newBoxFromString("Scrollbar area");
|
||||||
scrollbar_area.background = rl.Color.gold;
|
scrollbar_area.background = rl.Color.gold;
|
||||||
|
scrollbar_area.flags.insert(.scrollable);
|
||||||
scrollbar_area.size = .{
|
scrollbar_area.size = .{
|
||||||
.x = UI.Size.pixels(24, 1),
|
.x = UI.Size.pixels(24, 1),
|
||||||
.y = UI.Size.percent(1, 0),
|
.y = UI.Size.percent(1, 0),
|
||||||
@ -1206,11 +1231,23 @@ pub fn popScrollbar(self: *UI) void {
|
|||||||
const max_offset = scrollbar_height * (1 - visible_percent);
|
const max_offset = scrollbar_height * (1 - visible_percent);
|
||||||
draggable.setFixedY(scrollbar_area.persistent.position.y + sroll_offset.* * max_offset);
|
draggable.setFixedY(scrollbar_area.persistent.position.y + sroll_offset.* * max_offset);
|
||||||
|
|
||||||
const signal = self.signalFromBox(draggable);
|
const draggable_signal = self.signalFromBox(draggable);
|
||||||
if (signal.dragged()) {
|
if (draggable_signal.dragged()) {
|
||||||
sroll_offset.* += signal.drag.y / max_offset;
|
sroll_offset.* += draggable_signal.drag.y / max_offset;
|
||||||
sroll_offset.* = clamp(sroll_offset.*, 0, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const scroll_speed = 16;
|
||||||
|
const scrollbar_signal = self.signalFromBox(scrollbar_area);
|
||||||
|
if (scrollbar_signal.scrolled()) {
|
||||||
|
sroll_offset.* -= scrollbar_signal.scroll.y / max_offset * scroll_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const content_area_signal = self.signalFromBox(content_area);
|
||||||
|
if (content_area_signal.scrolled()) {
|
||||||
|
sroll_offset.* -= content_area_signal.scroll.y / max_offset * scroll_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
sroll_offset.* = clamp(sroll_offset.*, 0, 1);
|
||||||
|
|
||||||
self.popParent(); // pop container
|
self.popParent(); // pop container
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user