processEventsAfter
Parameters
- self:*ScrollContainerWidget
- *ScrollContainerWidget
Source
Implementation
pub fn processEventsAfter(self: *ScrollContainerWidget) void {
const focus_id = dvui.lastFocusedIdInFrameSince(self.last_focus);
const evts = dvui.events();
for (evts) |*e| {
if (dvui.captured(self.wd.id) and e.evt == .mouse and e.evt.mouse.action == .release and e.evt.mouse.button.touch()) {
// release our capture even if this event was already handled, see
// comment in the .motion handling
dvui.captureMouse(null, e.num);
dvui.dragEnd();
if (!e.handled) e.handle(@src(), self.data());
}
if (!dvui.eventMatch(e, .{ .id = self.data().id, .focus_id = focus_id, .r = self.init_opts.event_rect orelse self.data().borderRectScale().r }))
continue;
switch (e.evt) {
.mouse => |me| {
if (me.action == .focus) {
e.handle(@src(), self.data());
// focus so that we can receive keyboard input
dvui.focusWidget(self.data().id, null, e.num);
} else if (me.action == .wheel_x) {
if (self.si.scrollMax(.horizontal) > 0) {
if ((me.action.wheel_x > 0 and self.si.viewport.x <= 0) or (me.action.wheel_x < 0 and self.si.viewport.x >= self.si.scrollMax(.horizontal))) {
// propagate the scroll event because we are already maxxed out
} else {
e.handle(@src(), self.data());
self.si.scrollByOffset(.horizontal, -me.action.wheel_x);
if (self.init_opts.user_scroll) |us| us.*.x -= me.action.wheel_x;
dvui.refresh(null, @src(), self.data().id);
}
}
} else if (me.action == .wheel_y) {
if (self.si.scrollMax(.vertical) > 0) {
if ((me.action.wheel_y > 0 and self.si.viewport.y <= 0) or (me.action.wheel_y < 0 and self.si.viewport.y >= self.si.scrollMax(.vertical))) {
// propagate the scroll event because we are already maxxed out
} else {
e.handle(@src(), self.data());
self.si.scrollByOffset(.vertical, -me.action.wheel_y);
if (self.init_opts.user_scroll) |us| us.*.y -= me.action.wheel_y;
dvui.refresh(null, @src(), self.data().id);
}
}
} else if (me.action == .press and me.button.touch()) {
// don't let this event go through to floating window
// which would capture the mouse preventing scrolling
e.handle(@src(), self.data());
dvui.captureMouse(self.data(), e.num);
} else if (me.action == .release and dvui.captured(self.data().id)) {
e.handle(@src(), self.data());
dvui.captureMouse(null, e.num);
dvui.dragEnd();
} else if (me.action == .motion and me.button.touch()) {
e.handle(@src(), self.data());
// Need to capture here because it's common for the touch
// down to happen on top of a different widget. Example is
// a touch down on a button, which captures. Then when the
// drag starts the button gives up capture, so we get here,
// never having seen the touch down.
//
// We will give up capture on any touch release even if
// already handled (see comment at top of loop):
// * finger down/motion/up in same frame in textLayout
// * textLayout gives up capture on the motion event
// * textLayout processes the finger up
// * we capture here on the motion event
// * we would never see the finger up (already processed)
dvui.captureMouse(self.data(), e.num);
self.processMotionScroll(me.action.motion);
}
},
.key => |ke| {
if (ke.code == .up and (ke.action == .down or ke.action == .repeat)) {
e.handle(@src(), self.data());
if (self.si.vertical != .none) {
self.si.scrollByOffset(.vertical, -10);
if (self.init_opts.user_scroll) |us| us.*.y -= 10;
}
dvui.refresh(null, @src(), self.data().id);
} else if (ke.code == .down and (ke.action == .down or ke.action == .repeat)) {
e.handle(@src(), self.data());
if (self.si.vertical != .none) {
self.si.scrollByOffset(.vertical, 10);
if (self.init_opts.user_scroll) |us| us.*.y += 10;
}
dvui.refresh(null, @src(), self.data().id);
} else if (ke.code == .left and (ke.action == .down or ke.action == .repeat)) {
e.handle(@src(), self.data());
if (self.si.horizontal != .none) {
self.si.scrollByOffset(.horizontal, -10);
if (self.init_opts.user_scroll) |us| us.*.x -= 10;
}
dvui.refresh(null, @src(), self.data().id);
} else if (ke.code == .right and (ke.action == .down or ke.action == .repeat)) {
e.handle(@src(), self.data());
if (self.si.horizontal != .none) {
self.si.scrollByOffset(.horizontal, 10);
if (self.init_opts.user_scroll) |us| us.*.x += 10;
}
dvui.refresh(null, @src(), self.data().id);
} else if (ke.code == .page_up and (ke.action == .down or ke.action == .repeat)) {
e.handle(@src(), self.data());
const before = self.si.viewport.topLeft();
self.si.scrollPageUp(.vertical);
if (self.init_opts.user_scroll) |us| us.* = us.*.plus(self.si.viewport.topLeft().diff(before));
dvui.refresh(null, @src(), self.data().id);
} else if (ke.code == .page_down and (ke.action == .down or ke.action == .repeat)) {
e.handle(@src(), self.data());
const before = self.si.viewport.topLeft();
self.si.scrollPageDown(.vertical);
if (self.init_opts.user_scroll) |us| us.* = us.*.plus(self.si.viewport.topLeft().diff(before));
dvui.refresh(null, @src(), self.data().id);
}
},
else => {},
}
}
}