From: Scott Moynes Date: Sat, 26 Jul 2003 06:02:58 +0000 (+0000) Subject: Some menu updates. X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=3c92311b3c88e7da28aabe59d26c10a18c096399;p=chaz%2Fopenbox Some menu updates. Don't talk to me about menus. --- diff --git a/openbox/event.c b/openbox/event.c index 7252c379..366c91ad 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -972,7 +972,6 @@ static void event_handle_client(ObClient *client, XEvent *e) static void event_handle_menu(ObClient *client, XEvent *e) { - static ObMenuEntry *over = NULL; ObMenuEntry *entry; ObMenu *top; GList *it = NULL; @@ -982,27 +981,11 @@ static void event_handle_menu(ObClient *client, XEvent *e) ob_debug("EVENT %d\n", e->type); switch (e->type) { case KeyPress: - if (e->xkey.keycode == ob_keycode(OB_KEY_DOWN)) - over = menu_control_keyboard_nav(over, OB_KEY_DOWN); - else if (e->xkey.keycode == ob_keycode(OB_KEY_UP)) - over = menu_control_keyboard_nav(over, OB_KEY_UP); - else if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT)) /* fuck */ - over = menu_control_keyboard_nav(over, OB_KEY_RIGHT); - else if (e->xkey.keycode == ob_keycode(OB_KEY_LEFT)) /* users */ - over = menu_control_keyboard_nav(over, OB_KEY_LEFT); - else { - if (over) { - over->parent->mouseover(over, FALSE); - over = NULL; - } - - menu_hide(top); - } + menu_control_keyboard_nav(e->xkey.keycode); break; case ButtonPress: - if (e->xbutton.button > 3) break; - ob_debug("BUTTON PRESS\n"); + break; case ButtonRelease: ob_debug("BUTTON RELEASED\n"); @@ -1020,31 +1003,13 @@ static void event_handle_menu(ObClient *client, XEvent *e) m->location.x, e->xbutton.y_root - m->location.y))) { - if (over) { - over->parent->mouseover(over, FALSE); - /* this hides the menu */ - - over->parent->selected(entry, e->xbutton.button, - e->xbutton.x_root, - e->xbutton.y_root); - over = NULL; - } + m->selected(entry, e->xbutton.button, + e->xbutton.x_root, + e->xbutton.y_root); + break; } - break; } } - if (!it) { - if (over) { - over->parent->mouseover(over, FALSE); - over = NULL; - } -/* - if (top->hide) - top->hide(top); - else -*/ - menu_hide(top); - } break; case MotionNotify: @@ -1056,19 +1021,14 @@ static void event_handle_menu(ObClient *client, XEvent *e) m->location.x, e->xmotion.y_root - m->location.y))) { - if (over && entry != over) { - over->parent->mouseover(over, FALSE); - } + if (m->over && m->over->data != entry) + m->mouseover(m->over->data, FALSE); - over = entry; - over->parent->mouseover(over, TRUE); + m->mouseover(entry, TRUE); break; } } - if (!it && over) { - over->parent->mouseover(over, FALSE); - over = NULL; - } + break; } } diff --git a/openbox/menu.c b/openbox/menu.c index d832392e..2e3fb30b 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -183,6 +183,7 @@ ObMenu *menu_new_full(char *label, char *name, ObMenu *parent, self->name = g_strdup(name); self->parent = parent; self->open_submenu = NULL; + self->over = NULL; self->entries = NULL; self->shown = FALSE; @@ -318,12 +319,8 @@ void menu_hide(ObMenu *self) { if (self->open_submenu) menu_hide(self->open_submenu); if (self->parent && self->parent->open_submenu == self) { - ObMenuEntry *e; - + self->over = NULL; self->parent->open_submenu = NULL; - - e = menu_find_entry_by_submenu(self->parent, self); - self->parent->mouseover(e, FALSE); } if (!(self->parent && self->parent->shown)) { @@ -440,12 +437,14 @@ void menu_control_mouseover(ObMenuEntry *self, gboolean enter) Rect *a; ObMenuEntry *e; + g_assert(self != NULL); + if (enter) { + /* TODO: we prolly don't need open_submenu */ if (self->parent->open_submenu && self->submenu != self->parent->open_submenu) { - e = menu_find_entry_by_submenu(self->parent, - self->parent->open_submenu); + e = (ObMenuEntry *) self->parent->over->data; e->hilite = FALSE; menu_entry_render(e); menu_hide(self->parent->open_submenu); @@ -473,113 +472,100 @@ void menu_control_mouseover(ObMenuEntry *self, gboolean enter) menu_show_full(self->submenu, x, self->parent->location.y + self->y, self->parent->client); - } - } - - if (enter || !self->submenu || - menu_find_entry_by_submenu(self->parent, - self->parent->open_submenu) != self) - self->hilite = enter; - + } + self->hilite = TRUE; + self->parent->over = g_list_find(self->parent->entries, self); + + } else + self->hilite = FALSE; + menu_entry_render(self); } -ObMenuEntry *menu_control_keyboard_nav(ObMenuEntry *over, ObKey key) +void menu_control_keyboard_nav(unsigned int key) { - GList *it = NULL; - - switch (key) { + static ObMenu *current_menu = NULL; + + ObKey obkey = OB_NUM_KEYS; + + /* hrmm. could be fixed */ + if (key == ob_keycode(OB_KEY_DOWN)) + obkey = OB_KEY_DOWN; + else if (key == ob_keycode(OB_KEY_UP)) + obkey = OB_KEY_UP; + else if (key == ob_keycode(OB_KEY_RIGHT)) /* fuck */ + obkey = OB_KEY_RIGHT; + else if (key == ob_keycode(OB_KEY_LEFT)) /* users */ + obkey = OB_KEY_LEFT; + + if (current_menu == NULL) + current_menu = menu_visible->data; + + switch (obkey) { case OB_KEY_DOWN: { - if (over != NULL) { - over->parent->mouseover(over, FALSE); - - it = over->parent->entries; - while (it != NULL && it->data != over) - it = it->next; - } - - if (it && it->next) - over = (ObMenuEntry *)it->next->data; - else if (over == NULL) { - if (menu_visible && ((ObMenu *)menu_visible->data)->entries) - over = (ObMenuEntry *) - (((ObMenu *)menu_visible->data)->entries)->data; - else - over = NULL; - } else { - over = (over->parent->entries != NULL ? - over->parent->entries->data : NULL); + if (current_menu->over) { + current_menu->mouseover(current_menu->over->data, FALSE); + current_menu->over = (current_menu->over->next != NULL ? + current_menu->over->next : + current_menu->entries); } + else + current_menu->over = current_menu->entries; - if (over) - over->parent->mouseover(over, TRUE); + if (current_menu->over) + current_menu->mouseover(current_menu->over->data, TRUE); break; } case OB_KEY_UP: { - if (over != NULL) { - over->parent->mouseover(over, FALSE); - - it = g_list_last(over->parent->entries); - while (it != NULL && it->data != over) - it = it->prev; - } - - if (it && it->prev) - over = (ObMenuEntry *)it->prev->data; - else if (over == NULL) { - it = g_list_last(menu_visible); - if (it != NULL) { - it = g_list_last(((ObMenu *)it->data)->entries); - over = (ObMenuEntry *)(it != NULL ? it->data : NULL); - } + if (current_menu->over) { + current_menu->mouseover(current_menu->over->data, FALSE); + current_menu->over = (current_menu->over->prev != NULL ? + current_menu->over->prev : + g_list_last(current_menu->entries)); } else - over = (over->parent->entries != NULL ? - g_list_last(over->parent->entries)->data : - NULL); + current_menu->over = g_list_last(current_menu->entries); - over->parent->mouseover(over, TRUE); + if (current_menu->over) + current_menu->mouseover(current_menu->over->data, TRUE); + break; } case OB_KEY_RIGHT: { - if (over == NULL) - return over; - - if (over->submenu) { - over->parent->mouseover(over, FALSE); - - if (over->submenu->entries) - over = over->submenu->entries->data; - - over->parent->mouseover(over, TRUE); - } - else { - over->parent->mouseover(over, FALSE); - + ObMenuEntry *e; + if (current_menu->over == NULL) + return; + + e = (ObMenuEntry *)current_menu->over->data; + if (e->submenu) { + current_menu = e->submenu; + current_menu->over = current_menu->entries; + if (current_menu->over) + current_menu->mouseover(current_menu->over->data, TRUE); + } else { + current_menu->mouseover(e, FALSE); + current_menu->over = NULL; + /* zero is enter */ - menu_entry_fire(over, 0, 0, 0); + menu_entry_fire(e, 0, 0, 0); } break; } case OB_KEY_LEFT: { - if (over != NULL) { - over->parent->mouseover(over, FALSE); - menu_hide(over->parent); - } else { - it = g_list_last(menu_visible); - if (it) { - menu_hide((ObMenu *)it->data); - } - } + if (current_menu->over == NULL) + return; + current_menu->mouseover(current_menu->over->data, FALSE); + current_menu->over = NULL; + + menu_hide(current_menu); + + if (current_menu->parent) + current_menu = current_menu->parent; - over = NULL; break; } - default: - g_error("Unknown key"); } - - return over; + return; } void menu_noop() diff --git a/openbox/menu.h b/openbox/menu.h index 94e1daae..1d20ff03 100644 --- a/openbox/menu.h +++ b/openbox/menu.h @@ -10,14 +10,15 @@ struct _ObClient; -typedef struct _ObMenu ObMenu; +typedef struct _ObMenu ObMenu; typedef struct _ObMenuEntry ObMenuEntry; typedef void(*menu_controller_show)(ObMenu *self, int x, int y, struct _ObClient *); typedef void(*menu_controller_update)(ObMenu *self); typedef void(*menu_controller_mouseover)(ObMenuEntry *self, gboolean enter); -typedef void(*menu_controller_selected)(ObMenuEntry *self, unsigned int button, +typedef void(*menu_controller_selected)(ObMenuEntry *entry, + unsigned int button, unsigned int x, unsigned int y); typedef void(*menu_controller_hide)(ObMenu *self); @@ -29,25 +30,42 @@ struct _ObMenu { ObWindow obwin; + /* The title displayed above the menu. + NULL for no titlebar */ gchar *label; + + /* Name of the menu. + Used in the action showmenu */ gchar *name; - + + /* ObMenuEntry list */ GList *entries; + /* If the menu is currently displayed */ gboolean shown; + + /* If the rendering of the menu has changed and needs to be rerendered. */ gboolean invalid; + /* Kind of lame.Each menu can only be a submenu, and each menu can only + have one submenu open */ ObMenu *parent; - ObMenu *open_submenu; - + GList *over; + + /* behaviour callbacks + TODO: Document and split code that HAS to be in the overridden callback */ /* place a menu on screen */ menu_controller_show show; + /* Hide the menu */ menu_controller_hide hide; - /* render a menu */ menu_controller_update update; + /* Event for a mouse enter/exit on an entry + TODO: May have to split from simple render updating? + */ menu_controller_mouseover mouseover; + /* Entry is clicked/hit enter on */ menu_controller_selected selected; @@ -65,8 +83,9 @@ struct _ObMenu Size size; guint xin_area; /* index of the xinerama head/area */ - /* plugin stuff */ + /* Name of plugin for menu */ char *plugin; + /* plugin's data */ void *plugin_data; }; @@ -161,8 +180,8 @@ ObMenuEntry *menu_find_entry_by_pos(ObMenu *menu, int x, int y); void menu_entry_render(ObMenuEntry *self); -void menu_entry_fire(ObMenuEntry *self, unsigned int button, unsigned int x, - unsigned int y); +void menu_entry_fire(ObMenuEntry *entry, + unsigned int button, unsigned int x, unsigned int y); void menu_render(ObMenu *self); void menu_render_full(ObMenu *self); @@ -170,5 +189,5 @@ void menu_render_full(ObMenu *self); /*so plugins can call it? */ void parse_menu_full(xmlDocPtr doc, xmlNodePtr node, void *data, gboolean new); void menu_control_mouseover(ObMenuEntry *entry, gboolean enter); -ObMenuEntry *menu_control_keyboard_nav(ObMenuEntry *over, ObKey key); +void menu_control_keyboard_nav(unsigned int key); #endif