static void dialog_motion (Display *dpy, Window win, int x, int y) { struct XJDialog *dlg = NULL; XFindContext (dpy, win, _dlg_ctx, (XPointer*)&dlg); if (!dlg) return; x -= dlg->x0; y -= dlg->y0; int am; if (x <= 0 || y <= 0 || x >= dlg->width || y >= dlg->height) { am = -1; } else { am = y / (_dlg_font_height + 2); // TODO skip hidden if (am < 0 || am >= dlg->menu_count || !(dlg->menu_items[am].callback || dlg->menu_items[am].submenu) || !(dlg->menu_items[am].sensitive) ) { am = -1; } } #define HAS_SUBMENU(i) (i >= 0 && i <= dlg->menu_count && dlg->menu_items[i].submenu) if (am != dlg->menu_hover) { if (am == -1 && HAS_SUBMENU(dlg->menu_hover)) { ; // keep submenu } else { dlg->menu_hover = am; if (win == _dlg_mwin) { // TOP LEVEL ONLY, not self if (HAS_SUBMENU(dlg->menu_hover)) { show_submenu(dpy, dlg->menu_items[dlg->menu_hover].submenu, dlg->x0, dlg->y0 + (am + .5) * (_dlg_font_height + 2), dlg->width - 1); } else { hide_submenu(dpy); } } dialog_expose (dpy, win); } } }
static gboolean gnt_menu_key_pressed(GntWidget *widget, const char *text) { GntMenu *menu = GNT_MENU(widget); guint current = menu->selected; if (menu->submenu) { GntMenu *sub = menu; do sub = sub->submenu; while (sub->submenu); if (gnt_widget_key_pressed(GNT_WIDGET(sub), text)) return TRUE; if (menu->type != GNT_MENU_TOPLEVEL) return FALSE; } if ((text[0] == 27 && text[1] == 0) || (menu->type != GNT_MENU_TOPLEVEL && strcmp(text, GNT_KEY_LEFT) == 0)) { /* Escape closes menu */ GntMenu *par = menu->parentmenu; if (par != NULL) { par->submenu = NULL; gnt_widget_hide(widget); } else gnt_widget_hide(widget); if (par && par->type == GNT_MENU_TOPLEVEL) gnt_menu_key_pressed(GNT_WIDGET(par), text); return TRUE; } if (menu->type == GNT_MENU_TOPLEVEL) { GntMenuItem *item; GList *it; if (strcmp(text, GNT_KEY_LEFT) == 0) { do { if (menu->selected == 0) menu->selected = g_list_length(menu->list) - 1; else menu->selected--; it = g_list_nth(menu->list, menu->selected); item = it ? it->data : NULL; } while (!gnt_menuitem_is_visible(item)); } else if (strcmp(text, GNT_KEY_RIGHT) == 0) { do { menu->selected++; if (menu->selected >= g_list_length(menu->list)) menu->selected = 0; it = g_list_nth(menu->list, menu->selected); item = it ? it->data : NULL; } while (!gnt_menuitem_is_visible(item)); } else if (strcmp(text, GNT_KEY_ENTER) == 0 || strcmp(text, GNT_KEY_DOWN) == 0) { gnt_widget_activate(widget); } if (current != menu->selected) { GntMenu *sub = menu->submenu; if (sub) gnt_widget_hide(GNT_WIDGET(sub)); show_submenu(menu); gnt_widget_draw(widget); return TRUE; } } else { if (text[1] == '\0') { if (check_for_trigger(menu, text[0])) return TRUE; } else if (strcmp(text, GNT_KEY_RIGHT) == 0) { GntMenuItem *item = gnt_tree_get_selection_data(GNT_TREE(menu)); if (item && item->submenu) { menuitem_activate(menu, item); return TRUE; } } if (gnt_bindable_perform_action_key(GNT_BINDABLE(widget), text)) return TRUE; return org_key_pressed(widget, text); } return gnt_bindable_perform_action_key(GNT_BINDABLE(widget), text); }