Mercurial > emacs
changeset 44707:3444517c6483
(xlwMenuTranslations, xlwMenuActionsList): Add translations for cursor keys
and RET.
(find_next_selectable, find_prev_selectable): New functions used for
finding menu-items.
(Down, Up, Left, Right): New functions.
author | Pavel Janík <Pavel@Janik.cz> |
---|---|
date | Fri, 19 Apr 2002 18:56:51 +0000 |
parents | e697e304aa68 |
children | b4274ec69fa3 |
files | lwlib/xlwmenu.c |
diffstat | 1 files changed, 160 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/lwlib/xlwmenu.c Fri Apr 19 18:38:16 2002 +0000 +++ b/lwlib/xlwmenu.c Fri Apr 19 18:56:51 2002 +0000 @@ -1,5 +1,6 @@ /* Implements a lightweight menubar widget. Copyright (C) 1992 Lucid, Inc. + Copyright (C) 2002 Free Software Foundation, Inc. This file is part of the Lucid Widget Library. @@ -114,10 +115,21 @@ <KeyUp>Alt_R: nothing()\n\ <KeyUp>Caps_Lock: nothing()\n\ <KeyUp>Shift_Lock:nothing()\n\ +<Key>Return: select()\n\ +<Key>Down: down()\n\ +<Key>Up: up()\n\ +<Key>Left: left()\n\ +<Key>Right: right()\n\ <Key>: key()\n\ <KeyUp>: key()\n\ "; +/* FIXME: Space should toggle toggleable menu item but not remove the menu + so you can toggle the next one without entering the menu again. */ + +/* FIXME: Should ESC close one level of menu structure or the complete menu? */ + + #define offset(field) XtOffset(XlwMenuWidget, field) static XtResource xlwMenuResources[] = @@ -174,6 +186,10 @@ static void XlwMenuClassInitialize(); static void Start(); static void Drag(); +static void Down(); +static void Up(); +static void Left(); +static void Right(); static void Select(); static void Key(); static void Nothing(); @@ -184,6 +200,10 @@ { {"start", Start}, {"drag", Drag}, + {"down", Down}, + {"up", Up}, + {"left", Left}, + {"right", Right}, {"select", Select}, {"key", Key}, {"nothing", Nothing}, @@ -1984,6 +2004,146 @@ { } +widget_value * +find_next_selectable (mw, item) + XlwMenuWidget mw; + widget_value *item; +{ + widget_value *current = item; + enum menu_separator separator; + + while (current->next && (current=current->next) && + (lw_separator_p (current->name, &separator, 0) || !current->enabled)) + ; + + if (current == item) + { + current = mw->menu.old_stack [mw->menu.old_depth - 2]->contents; + + while (lw_separator_p (current->name, &separator, 0) || !current->enabled) + if (current->next) + current=current->next; + } + + return current; +} + +widget_value * +find_prev_selectable (mw, item) + XlwMenuWidget mw; + widget_value *item; +{ + widget_value *current = item; + widget_value *prev = item; + + while ((current=find_next_selectable (mw, current)) != item) + prev=current; + + return prev; +} + +static void +Down (w, ev, params, num_params) + Widget w; + XEvent *ev; + String *params; + Cardinal *num_params; +{ + XlwMenuWidget mw = (XlwMenuWidget) w; + widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; + + /* Inside top-level menu-bar? */ + if (mw->menu.old_depth == 2) + /* When <down> in the menu-bar is pressed, display the corresponding + sub-menu and select the first menu item there. */ + set_new_state (mw, selected_item->contents, mw->menu.old_depth); + else + /* Highlight next possible (enabled and not separator) menu item. */ + set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1); + + remap_menubar (mw); +} + +static void +Up (w, ev, params, num_params) + Widget w; + XEvent *ev; + String *params; + Cardinal *num_params; +{ + XlwMenuWidget mw = (XlwMenuWidget) w; + widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; + + /* Inside top-level menu-bar? */ + if (mw->menu.old_depth == 2) + { + /* FIXME: this is tricky. <up> in the menu-bar should select the + last selectable item in the list. So we select the first one and + find the previous selectable item. Is there a better way? */ + set_new_state (mw, selected_item->contents, mw->menu.old_depth); + remap_menubar (mw); + selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; + set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); + } + else + /* Highlight previous (enabled and not separator) menu item. */ + set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); + + remap_menubar (mw); +} + +static void +Left (w, ev, params, num_params) + Widget w; + XEvent *ev; + String *params; + Cardinal *num_params; +{ + XlwMenuWidget mw = (XlwMenuWidget) w; + widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; + + /* Inside top-level menu-bar? */ + if (mw->menu.old_depth == 2) + /* When <left> in the menu-bar is pressed, display the previous item on + the menu-bar. If the current item is the first one, highlight the + last item in the menubar (probably Help). */ + set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); + else + { + pop_new_stack_if_no_contents (mw); + set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2); + } + + remap_menubar (mw); +} + +static void +Right (w, ev, params, num_params) + Widget w; + XEvent *ev; + String *params; + Cardinal *num_params; +{ + XlwMenuWidget mw = (XlwMenuWidget) w; + widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; + + /* Inside top-level menu-bar? */ + if (mw->menu.old_depth == 2) + /* When <right> in the menu-bar is pressed, display the next item on + the menu-bar. If the current item is the last one, highlight the + first item (probably File). */ + set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1); + else if (selected_item->contents) /* Is this menu item expandable? */ + set_new_state (mw, selected_item->contents, mw->menu.old_depth); + else + { + pop_new_stack_if_no_contents (mw); + set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2); + } + + remap_menubar (mw); +} + /* Handle key press and release events while menu is popped up. Our action is to get rid of the menu. */ static void