processEvent
Parameters
- self:*MenuItemWidget
- *MenuItemWidget
- e:*Event
- *Event
Source
Implementation
pub fn processEvent(self: *MenuItemWidget, e: *Event) void {
switch (e.evt) {
.mouse => |me| {
if (me.action == .focus) {
e.handle(@src(), self.data());
dvui.focusWidget(self.data().id, null, e.num);
} else if (me.action == .press and me.button.pointer()) {
// This works differently than normal (like buttons) where we
// captureMouse on press, to support the mouse
// click-open-drag-select-release-activate pattern for menus
// and dropdowns. However, we still need to do the capture
// pattern for touch.
//
// This is how dropdowns are triggered.
e.handle(@src(), self.data());
if (self.init_opts.submenu) {
dvui.dataRemove(null, menu().?.data().id, "_submenus_activating");
if (!menu().?.floating() and !menu().?.submenus_activated) {
// If not floating, then we are toggling focus-on-hover, set a bit
dvui.dataSet(null, menu().?.data().id, "_submenus_activating", {});
}
menu().?.submenus_activated = true;
}
if (me.button.touch()) {
// with touch we have to capture otherwise any motion will
// cause scroll to capture
dvui.captureMouse(self.data(), e.num);
dvui.dragPreStart(me.button, me.p, .{});
}
} else if (me.action == .release) {
e.handle(@src(), self.data());
if (self.init_opts.submenu) {
// Only non floating menus can toggle focus-on-hover
if (!menu().?.floating() and dvui.dataGet(null, menu().?.data().id, "_submenus_activating", void) == null) {
// Toggle the submenu closed
menu().?.submenus_activated = false;
dvui.refresh(null, @src(), self.data().id);
}
} else if (self.data().id == dvui.focusedWidgetIdInCurrentSubwindow()) {
self.activated = true;
dvui.refresh(null, @src(), self.data().id);
}
if (dvui.captured(self.data().id)) {
// should only happen with touch
dvui.captureMouse(null, e.num);
}
dvui.dragEnd();
} else if (me.action == .motion and me.button.touch()) {
if (dvui.captured(self.data().id)) {
if (dvui.dragging(me.p, null)) |_| {
// if we overcame the drag threshold, then that
// means the person probably didn't want to touch
// this, maybe they were trying to scroll
dvui.captureMouse(null, e.num);
dvui.dragEnd();
}
}
} else if (me.action == .position) {
// We get a .position mouse event every frame. If we
// focus the menu item under the mouse even if it's not
// moving then it breaks keyboard navigation.
if (dvui.mouseTotalMotion().nonZero()) {
if (menu().?.focused_menuItem or menu().?.submenus_activated) {
// we shouldn't have gotten this event if the motion
// was towards a submenu (caught in MenuWidget)
dvui.focusSubwindow(null, null); // focuses the window we are in
dvui.focusWidget(self.data().id, null, null);
if (self.init_opts.submenu and menu().?.floating()) {
menu().?.submenus_activated = true;
}
}
}
if (menu().?.mouse_mode) {
self.mouse_over = true;
dvui.cursorSet(.arrow);
self.highlight = true;
}
}
},
.key => |ke| {
if (ke.action == .down and ke.matchBind("activate")) {
e.handle(@src(), self.data());
if (self.init_opts.submenu) {
menu().?.submenus_activated = true;
} else {
self.activated = true;
dvui.refresh(null, @src(), self.data().id);
}
} else if (ke.code == .right and ke.action == .down) {
if (self.init_opts.submenu and menu().?.init_opts.dir == .vertical) {
e.handle(@src(), self.data());
menu().?.submenus_activated = true;
}
} else if (ke.code == .down and ke.action == .down) {
if (self.init_opts.submenu and menu().?.init_opts.dir == .horizontal) {
e.handle(@src(), self.data());
menu().?.submenus_activated = true;
}
}
},
else => {},
}
}