DVUI

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 => {},
    }
}