add mouse clipping to hidden boxes from scrolling
This commit is contained in:
parent
d744ab4b6b
commit
401056b676
@ -198,3 +198,16 @@ pub fn aligned(rect: Rect, align_x: AlignX, align_y: AlignY) rl.Vector2 {
|
|||||||
|
|
||||||
return rl.Vector2.init(x, y);
|
return rl.Vector2.init(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn intersect(rect: Rect, other: Rect) Rect {
|
||||||
|
const left_pos = @max(left(rect), left(other));
|
||||||
|
const top_pos = @max(top(rect), top(other));
|
||||||
|
const right_pos = @min(right(rect), right(other));
|
||||||
|
const bottom_pos = @min(bottom(rect), bottom(other));
|
||||||
|
return Rect{
|
||||||
|
.x = left_pos,
|
||||||
|
.y = top_pos,
|
||||||
|
.width = right_pos - left_pos,
|
||||||
|
.height = bottom_pos - top_pos
|
||||||
|
};
|
||||||
|
}
|
32
src/ui.zig
32
src/ui.zig
@ -378,6 +378,10 @@ pub const Box = struct {
|
|||||||
|
|
||||||
return self.flags.contains(flag);
|
return self.flags.contains(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn hasClipping(self: *Box) bool {
|
||||||
|
return self.view_offset.equals(Vec2.zero()) == 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const BoxChildIterator = struct {
|
const BoxChildIterator = struct {
|
||||||
@ -627,7 +631,7 @@ pub fn draw(self: *UI) void {
|
|||||||
fn drawBox(self: *UI, box: *Box) void {
|
fn drawBox(self: *UI, box: *Box) void {
|
||||||
const box_rect = box.computedRect();
|
const box_rect = box.computedRect();
|
||||||
|
|
||||||
const do_scissor = box.view_offset.equals(Vec2.zero()) == 0;
|
const do_scissor = box.hasClipping();
|
||||||
if (do_scissor) {
|
if (do_scissor) {
|
||||||
rl.beginScissorMode(
|
rl.beginScissorMode(
|
||||||
@intFromFloat(box_rect.x),
|
@intFromFloat(box_rect.x),
|
||||||
@ -1004,11 +1008,20 @@ fn findBoxByKey(self: *UI, key: Key) ?*Box {
|
|||||||
pub fn signalFromBox(self: *UI, box: *Box) Signal {
|
pub fn signalFromBox(self: *UI, box: *Box) Signal {
|
||||||
var result = Signal{};
|
var result = Signal{};
|
||||||
|
|
||||||
|
var rect = box.computedRect();
|
||||||
|
{
|
||||||
|
var parent_iter = self.iterUpwardByParent(box);
|
||||||
|
while (parent_iter.next()) |parent| {
|
||||||
|
if (parent.hasClipping()) {
|
||||||
|
rect = rect_utils.intersect(rect, parent.computedRect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const key = box.key;
|
const key = box.key;
|
||||||
const rect = box.computedRect();
|
|
||||||
const is_mouse_inside = rect_utils.isInsideVec2(rect, self.mouse);
|
|
||||||
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 is_mouse_inside = rect_utils.isInsideVec2(rect, self.mouse);
|
||||||
|
|
||||||
var event_index: usize = 0;
|
var event_index: usize = 0;
|
||||||
while (event_index < self.events.len) {
|
while (event_index < self.events.len) {
|
||||||
@ -1153,6 +1166,12 @@ pub fn pushScrollbar(self: *UI, key: UI.Key) *Box {
|
|||||||
};
|
};
|
||||||
self.pushParent(content_area);
|
self.pushParent(content_area);
|
||||||
|
|
||||||
|
const visible_content_size = content_area.persistent.size.y;
|
||||||
|
const used_content_size = content_area.persistent.children_size.y;
|
||||||
|
const visible_percent = clamp(visible_content_size / used_content_size, 0, 1);
|
||||||
|
const sroll_offset = content_area.persistent.sroll_offset;
|
||||||
|
content_area.view_offset.y = sroll_offset * (1 - visible_percent) * used_content_size;
|
||||||
|
|
||||||
return content_area;
|
return content_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1182,19 +1201,16 @@ pub fn popScrollbar(self: *UI) void {
|
|||||||
.y = UI.Size.percent(visible_percent, 1),
|
.y = UI.Size.percent(visible_percent, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sroll_offset = &content_area.persistent.sroll_offset;
|
||||||
const scrollbar_height = scrollbar_area.persistent.size.y;
|
const scrollbar_height = scrollbar_area.persistent.size.y;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
const sroll_offset = &draggable.persistent.sroll_offset;
|
|
||||||
const signal = self.signalFromBox(draggable);
|
const signal = self.signalFromBox(draggable);
|
||||||
if (signal.dragged()) {
|
if (signal.dragged()) {
|
||||||
sroll_offset.* += signal.drag.y / max_offset;
|
sroll_offset.* += signal.drag.y / max_offset;
|
||||||
sroll_offset.* = clamp(sroll_offset.*, 0, 1);
|
sroll_offset.* = clamp(sroll_offset.*, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
draggable.setFixedY(scrollbar_area.persistent.position.y + sroll_offset.* * max_offset);
|
|
||||||
content_area.view_offset.y = sroll_offset.* * (1 - visible_percent) * used_content_size;
|
|
||||||
|
|
||||||
self.popParent(); // pop container
|
self.popParent(); // pop container
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user