Beispiel #1
0
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);
}