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) {
|
||||
mouse_pressed: rl.MouseButton,
|
||||
mouse_released: rl.MouseButton,
|
||||
mouse_move: Vec2
|
||||
mouse_move: Vec2,
|
||||
mouse_scroll: Vec2
|
||||
};
|
||||
|
||||
pub const Signal = struct {
|
||||
@ -173,11 +174,14 @@ pub const Signal = struct {
|
||||
right_clicked,
|
||||
|
||||
left_dragging,
|
||||
right_dragging
|
||||
right_dragging,
|
||||
|
||||
scrolled
|
||||
};
|
||||
|
||||
flags: std.EnumSet(Flag) = .{},
|
||||
drag: Vec2 = .{ .x = 0, .y = 0 },
|
||||
scroll: Vec2 = .{ .x = 0, .y = 0 },
|
||||
|
||||
pub fn clicked(self: Signal) bool {
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn scrolled(self: Signal) bool {
|
||||
return self.flags.contains(.scrolled);
|
||||
}
|
||||
|
||||
fn insertMousePressed(self: *Signal, mouse_button: rl.MouseButton) void {
|
||||
if (mouse_button == .mouse_button_left) {
|
||||
self.flags.insert(.left_pressed);
|
||||
@ -237,6 +245,8 @@ pub const Box = struct {
|
||||
draggable_x,
|
||||
draggable_y,
|
||||
|
||||
scrollable,
|
||||
|
||||
fixed_x,
|
||||
fixed_y,
|
||||
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);
|
||||
root_box.size.x = Size.pixels(@floatFromInt(window_width), 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 clickable = box.flags.contains(.clickable);
|
||||
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);
|
||||
|
||||
var event_index: usize = 0;
|
||||
@ -1055,6 +1071,13 @@ pub fn signalFromBox(self: *UI, box: *Box) Signal {
|
||||
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) {
|
||||
_ = self.events.swapRemove(event_index);
|
||||
} else {
|
||||
@ -1160,6 +1183,7 @@ pub fn pushScrollbar(self: *UI, key: UI.Key) *Box {
|
||||
self.pushParent(container);
|
||||
|
||||
const content_area = self.newBoxFromString("Scroll area");
|
||||
content_area.flags.insert(.scrollable);
|
||||
content_area.size = .{
|
||||
.x = 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");
|
||||
scrollbar_area.background = rl.Color.gold;
|
||||
scrollbar_area.flags.insert(.scrollable);
|
||||
scrollbar_area.size = .{
|
||||
.x = UI.Size.pixels(24, 1),
|
||||
.y = UI.Size.percent(1, 0),
|
||||
@ -1206,11 +1231,23 @@ pub fn popScrollbar(self: *UI) void {
|
||||
const max_offset = scrollbar_height * (1 - visible_percent);
|
||||
draggable.setFixedY(scrollbar_area.persistent.position.y + sroll_offset.* * max_offset);
|
||||
|
||||
const signal = self.signalFromBox(draggable);
|
||||
if (signal.dragged()) {
|
||||
sroll_offset.* += signal.drag.y / max_offset;
|
||||
sroll_offset.* = clamp(sroll_offset.*, 0, 1);
|
||||
const draggable_signal = self.signalFromBox(draggable);
|
||||
if (draggable_signal.dragged()) {
|
||||
sroll_offset.* += draggable_signal.drag.y / max_offset;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue
Block a user