# HG changeset patch # User Sadrul Habib Chowdhury # Date 1183684820 0 # Node ID be10fc22d6499a66d3aec50fde3023f56e3384f3 # Parent ec80e921818cb3b4b3bff5974d361dd2dd0d68b6 Allow trigger keys for menuitems. diff -r ec80e921818c -r be10fc22d649 finch/libgnt/gntmenu.c --- a/finch/libgnt/gntmenu.c Thu Jul 05 19:58:35 2007 +0000 +++ b/finch/libgnt/gntmenu.c Fri Jul 06 01:20:20 2007 +0000 @@ -30,11 +30,20 @@ SIGS = 1, }; +enum +{ + ITEM_TEXT = 0, + ITEM_TRIGGER, + ITEM_SUBMENU, + NUM_COLUMNS +}; + static GntTreeClass *parent_class = NULL; static void (*org_draw)(GntWidget *wid); static void (*org_destroy)(GntWidget *wid); static void (*org_map)(GntWidget *wid); +static void (*org_size_request)(GntWidget *wid); static gboolean (*org_key_pressed)(GntWidget *w, const char *t); static void @@ -75,21 +84,26 @@ widget->priv.height = 1; widget->priv.width = getmaxx(stdscr); } else { + org_size_request(widget); widget->priv.height = g_list_length(menu->list) + 2; - widget->priv.width = 25; /* XXX: */ } } static void menu_tree_add(GntMenu *menu, GntMenuItem *item, GntMenuItem *parent) { + char trigger[4] = "\0 )\0"; + + if ((trigger[1] = gnt_menuitem_get_trigger(item))) + trigger[0] = '('; + if (GNT_IS_MENU_ITEM_CHECK(item)) { gnt_tree_add_choice(GNT_TREE(menu), item, - gnt_tree_create_row(GNT_TREE(menu), item->text, " "), parent, NULL); + gnt_tree_create_row(GNT_TREE(menu), item->text, trigger, " "), parent, NULL); gnt_tree_set_choice(GNT_TREE(menu), item, gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item))); } else gnt_tree_add_row_last(GNT_TREE(menu), item, - gnt_tree_create_row(GNT_TREE(menu), item->text, item->submenu ? ">" : " "), parent); + gnt_tree_create_row(GNT_TREE(menu), item->text, trigger, item->submenu ? ">" : " "), parent); if (0 && item->submenu) { GntMenu *sub = GNT_MENU(item->submenu); @@ -149,6 +163,41 @@ } } +static GList* +find_item_with_trigger(GList *start, GList *end, char trigger) +{ + GList *iter; + for (iter = start; iter != (end ? end : NULL); iter = iter->next) { + if (gnt_menuitem_get_trigger(iter->data) == trigger) + return iter; + } + return NULL; +} + +static gboolean +check_for_trigger(GntMenu *menu, char trigger) +{ + /* check for a trigger key */ + GList *iter; + GList *nth = g_list_find(menu->list, gnt_tree_get_selection_data(GNT_TREE(menu))); + GList *find = find_item_with_trigger(nth->next, NULL, trigger); + if (!find) + find = find_item_with_trigger(menu->list, nth->next, trigger); + if (!find) + return FALSE; + if (find != nth) { + gnt_tree_set_selected(GNT_TREE(menu), find->data); + iter = find_item_with_trigger(find->next, NULL, trigger); + if (iter != NULL && iter != find) + return TRUE; + iter = find_item_with_trigger(menu->list, nth, trigger); + if (iter != NULL && iter != find) + return TRUE; + } + gnt_widget_activate(GNT_WIDGET(menu)); + return TRUE; +} + static gboolean gnt_menu_key_pressed(GntWidget *widget, const char *text) { @@ -189,6 +238,10 @@ return TRUE; } } else { + if (text[1] == '\0') { + if (check_for_trigger(menu, text[0])) + return TRUE; + } return org_key_pressed(widget, text); } @@ -260,6 +313,7 @@ org_map = wid_class->map; org_draw = wid_class->draw; org_key_pressed = wid_class->key_pressed; + org_size_request = wid_class->size_request; wid_class->destroy = gnt_menu_destroy; wid_class->draw = gnt_menu_draw; @@ -327,9 +381,11 @@ widget->priv.y = 0; } else { GNT_TREE(widget)->show_separator = FALSE; - _gnt_tree_init_internals(GNT_TREE(widget), 2); - gnt_tree_set_col_width(GNT_TREE(widget), 1, 1); /* The second column is to indicate that it has a submenu */ - gnt_tree_set_column_resizable(GNT_TREE(widget), 1, FALSE); + _gnt_tree_init_internals(GNT_TREE(widget), NUM_COLUMNS); + gnt_tree_set_col_width(GNT_TREE(widget), ITEM_TRIGGER, 3); + gnt_tree_set_column_resizable(GNT_TREE(widget), ITEM_TRIGGER, FALSE); + gnt_tree_set_col_width(GNT_TREE(widget), ITEM_SUBMENU, 1); + gnt_tree_set_column_resizable(GNT_TREE(widget), ITEM_SUBMENU, FALSE); GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER); } diff -r ec80e921818c -r be10fc22d649 finch/libgnt/gntmenuitem.c --- a/finch/libgnt/gntmenuitem.c Thu Jul 05 19:58:35 2007 +0000 +++ b/finch/libgnt/gntmenuitem.c Fri Jul 06 01:20:20 2007 +0000 @@ -104,3 +104,13 @@ item->submenu = menu; } +void gnt_menuitem_set_trigger(GntMenuItem *item, char trigger) +{ + item->priv.trigger = trigger; +} + +char gnt_menuitem_get_trigger(GntMenuItem *item) +{ + return item->priv.trigger; +} + diff -r ec80e921818c -r be10fc22d649 finch/libgnt/gntmenuitem.h --- a/finch/libgnt/gntmenuitem.h Thu Jul 05 19:58:35 2007 +0000 +++ b/finch/libgnt/gntmenuitem.h Fri Jul 06 01:20:20 2007 +0000 @@ -52,6 +52,7 @@ /* These will be used to determine the position of the submenu */ int x; int y; + char trigger; }; typedef void (*GntMenuItemCallback)(GntMenuItem *item, gpointer data); @@ -114,6 +115,25 @@ */ void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu); +/** + * Set a trigger key for the item. + * + * @param item The menuitem + * @param trigger The key that will trigger the item when the parent manu is visible + */ +void gnt_menuitem_set_trigger(GntMenuItem *item, char trigger); + +/** + * Get the trigger key for a menuitem. + * + * @param item The menuitem + * + * @return The trigger key for the menuitem. + * + * @see gnt_menuitem_set_trigger + */ +char gnt_menuitem_get_trigger(GntMenuItem *item); + G_END_DECLS #endif /* GNT_MENUITEM_H */ diff -r ec80e921818c -r be10fc22d649 finch/libgnt/gnttree.c --- a/finch/libgnt/gnttree.c Thu Jul 05 19:58:35 2007 +0000 +++ b/finch/libgnt/gnttree.c Fri Jul 06 01:20:20 2007 +0000 @@ -86,13 +86,15 @@ int width; #define WIDTH(i) (tree->columns[i].width_ratio ? tree->columns[i].width_ratio : tree->columns[i].width) gnt_widget_get_size(GNT_WIDGET(tree), &width, NULL); + if (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)) + width -= 2; for (i = 0, total = 0; i < tree->ncol ; i++) { if (tree->columns[i].flags & GNT_TREE_COLUMN_INVISIBLE) continue; if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE) - width -= WIDTH(i); + width -= WIDTH(i) + 1; else - total += WIDTH(i); + total += WIDTH(i) + 1; } if (total == 0) @@ -283,10 +285,6 @@ GList *iter; int i; gboolean notfirst = FALSE; - int lastvisible = tree->ncol; - - while (lastvisible && COLUMN_INVISIBLE(tree, lastvisible)) - lastvisible--; for (i = 0, iter = row->columns; i < tree->ncol && iter; i++, iter = iter->next) { @@ -308,7 +306,7 @@ len = gnt_util_onscreen_width(display, NULL); - if (i == lastvisible) + if (i == tree->lastvisible) width = GNT_WIDGET(tree)->priv.width - gnt_util_onscreen_width(string->str, NULL); else width = tree->columns[i].width; @@ -339,8 +337,7 @@ g_string_append_printf(string, "%*s", fl, ""); } len += fl; - } - else if (notfirst) + } else if (notfirst && tree->show_separator) g_string_append_c(string, '|'); else g_string_append_c(string, ' '); @@ -598,9 +595,13 @@ { GntTree *tree = GNT_TREE(widget); int i, width = 0; + width = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)); for (i = 0; i < tree->ncol; i++) - if (!COLUMN_INVISIBLE(tree, i)) - width += tree->columns[i].width + 1; + if (!COLUMN_INVISIBLE(tree, i)) { + width = width + tree->columns[i].width; + if (tree->lastvisible != i) + width++; + } widget->priv.width = width; } } @@ -1502,6 +1503,7 @@ tree->ncol = col; tree->hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_tree_row); tree->columns = g_new0(struct _GntTreeColInfo, col); + tree->lastvisible = col - 1; while (col--) { tree->columns[col].width = 15; @@ -1647,9 +1649,14 @@ twidth = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)); for (i = 0; i < tree->ncol; i++) { + if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE) + widths[i] = tree->columns[i].width; gnt_tree_set_col_width(tree, i, widths[i]); - if (!COLUMN_INVISIBLE(tree, i)) - twidth += widths[i] + (tree->show_separator ? 1 : 0) + 1; + if (!COLUMN_INVISIBLE(tree, i)) { + twidth = twidth + widths[i]; + if (tree->lastvisible != i) + twidth += 1; + } } g_free(widths); @@ -1676,6 +1683,18 @@ { g_return_if_fail(col < tree->ncol); set_column_flag(tree, col, GNT_TREE_COLUMN_INVISIBLE, !vis); + if (vis) { + /* the column is visible */ + if (tree->lastvisible < col) + tree->lastvisible = col; + } else { + if (tree->lastvisible == col) + while (tree->lastvisible) { + tree->lastvisible--; + if (!COLUMN_INVISIBLE(tree, tree->lastvisible)) + break; + } + } } void gnt_tree_set_column_resizable(GntTree *tree, int col, gboolean res) diff -r ec80e921818c -r be10fc22d649 finch/libgnt/gnttree.h --- a/finch/libgnt/gnttree.h Thu Jul 05 19:58:35 2007 +0000 +++ b/finch/libgnt/gnttree.h Fri Jul 06 01:20:20 2007 +0000 @@ -86,6 +86,7 @@ int search_timeout; GCompareFunc compare; + int lastvisible; }; struct _GntTreeClass