comparison lwlib/xlwmenu.c @ 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 7fb1caba0f51
children a05c8614feee
comparison
equal deleted inserted replaced
44706:e697e304aa68 44707:3444517c6483
1 /* Implements a lightweight menubar widget. 1 /* Implements a lightweight menubar widget.
2 Copyright (C) 1992 Lucid, Inc. 2 Copyright (C) 1992 Lucid, Inc.
3 Copyright (C) 2002 Free Software Foundation, Inc.
3 4
4 This file is part of the Lucid Widget Library. 5 This file is part of the Lucid Widget Library.
5 6
6 The Lucid Widget Library is free software; you can redistribute it and/or 7 The Lucid Widget Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as published by 8 modify it under the terms of the GNU General Public License as published by
112 <KeyUp>Super_R: nothing()\n\ 113 <KeyUp>Super_R: nothing()\n\
113 <KeyUp>Alt_L: nothing()\n\ 114 <KeyUp>Alt_L: nothing()\n\
114 <KeyUp>Alt_R: nothing()\n\ 115 <KeyUp>Alt_R: nothing()\n\
115 <KeyUp>Caps_Lock: nothing()\n\ 116 <KeyUp>Caps_Lock: nothing()\n\
116 <KeyUp>Shift_Lock:nothing()\n\ 117 <KeyUp>Shift_Lock:nothing()\n\
118 <Key>Return: select()\n\
119 <Key>Down: down()\n\
120 <Key>Up: up()\n\
121 <Key>Left: left()\n\
122 <Key>Right: right()\n\
117 <Key>: key()\n\ 123 <Key>: key()\n\
118 <KeyUp>: key()\n\ 124 <KeyUp>: key()\n\
119 "; 125 ";
126
127 /* FIXME: Space should toggle toggleable menu item but not remove the menu
128 so you can toggle the next one without entering the menu again. */
129
130 /* FIXME: Should ESC close one level of menu structure or the complete menu? */
131
120 132
121 #define offset(field) XtOffset(XlwMenuWidget, field) 133 #define offset(field) XtOffset(XlwMenuWidget, field)
122 static XtResource 134 static XtResource
123 xlwMenuResources[] = 135 xlwMenuResources[] =
124 { 136 {
172 static void XlwMenuRedisplay(); 184 static void XlwMenuRedisplay();
173 static void XlwMenuDestroy(); 185 static void XlwMenuDestroy();
174 static void XlwMenuClassInitialize(); 186 static void XlwMenuClassInitialize();
175 static void Start(); 187 static void Start();
176 static void Drag(); 188 static void Drag();
189 static void Down();
190 static void Up();
191 static void Left();
192 static void Right();
177 static void Select(); 193 static void Select();
178 static void Key(); 194 static void Key();
179 static void Nothing(); 195 static void Nothing();
180 static int separator_height (); 196 static int separator_height ();
181 197
182 static XtActionsRec 198 static XtActionsRec
183 xlwMenuActionsList [] = 199 xlwMenuActionsList [] =
184 { 200 {
185 {"start", Start}, 201 {"start", Start},
186 {"drag", Drag}, 202 {"drag", Drag},
203 {"down", Down},
204 {"up", Up},
205 {"left", Left},
206 {"right", Right},
187 {"select", Select}, 207 {"select", Select},
188 {"key", Key}, 208 {"key", Key},
189 {"nothing", Nothing}, 209 {"nothing", Nothing},
190 }; 210 };
191 211
1982 String *params; 2002 String *params;
1983 Cardinal *num_params; 2003 Cardinal *num_params;
1984 { 2004 {
1985 } 2005 }
1986 2006
2007 widget_value *
2008 find_next_selectable (mw, item)
2009 XlwMenuWidget mw;
2010 widget_value *item;
2011 {
2012 widget_value *current = item;
2013 enum menu_separator separator;
2014
2015 while (current->next && (current=current->next) &&
2016 (lw_separator_p (current->name, &separator, 0) || !current->enabled))
2017 ;
2018
2019 if (current == item)
2020 {
2021 current = mw->menu.old_stack [mw->menu.old_depth - 2]->contents;
2022
2023 while (lw_separator_p (current->name, &separator, 0) || !current->enabled)
2024 if (current->next)
2025 current=current->next;
2026 }
2027
2028 return current;
2029 }
2030
2031 widget_value *
2032 find_prev_selectable (mw, item)
2033 XlwMenuWidget mw;
2034 widget_value *item;
2035 {
2036 widget_value *current = item;
2037 widget_value *prev = item;
2038
2039 while ((current=find_next_selectable (mw, current)) != item)
2040 prev=current;
2041
2042 return prev;
2043 }
2044
2045 static void
2046 Down (w, ev, params, num_params)
2047 Widget w;
2048 XEvent *ev;
2049 String *params;
2050 Cardinal *num_params;
2051 {
2052 XlwMenuWidget mw = (XlwMenuWidget) w;
2053 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2054
2055 /* Inside top-level menu-bar? */
2056 if (mw->menu.old_depth == 2)
2057 /* When <down> in the menu-bar is pressed, display the corresponding
2058 sub-menu and select the first menu item there. */
2059 set_new_state (mw, selected_item->contents, mw->menu.old_depth);
2060 else
2061 /* Highlight next possible (enabled and not separator) menu item. */
2062 set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1);
2063
2064 remap_menubar (mw);
2065 }
2066
2067 static void
2068 Up (w, ev, params, num_params)
2069 Widget w;
2070 XEvent *ev;
2071 String *params;
2072 Cardinal *num_params;
2073 {
2074 XlwMenuWidget mw = (XlwMenuWidget) w;
2075 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2076
2077 /* Inside top-level menu-bar? */
2078 if (mw->menu.old_depth == 2)
2079 {
2080 /* FIXME: this is tricky. <up> in the menu-bar should select the
2081 last selectable item in the list. So we select the first one and
2082 find the previous selectable item. Is there a better way? */
2083 set_new_state (mw, selected_item->contents, mw->menu.old_depth);
2084 remap_menubar (mw);
2085 selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2086 set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1);
2087 }
2088 else
2089 /* Highlight previous (enabled and not separator) menu item. */
2090 set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1);
2091
2092 remap_menubar (mw);
2093 }
2094
2095 static void
2096 Left (w, ev, params, num_params)
2097 Widget w;
2098 XEvent *ev;
2099 String *params;
2100 Cardinal *num_params;
2101 {
2102 XlwMenuWidget mw = (XlwMenuWidget) w;
2103 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2104
2105 /* Inside top-level menu-bar? */
2106 if (mw->menu.old_depth == 2)
2107 /* When <left> in the menu-bar is pressed, display the previous item on
2108 the menu-bar. If the current item is the first one, highlight the
2109 last item in the menubar (probably Help). */
2110 set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1);
2111 else
2112 {
2113 pop_new_stack_if_no_contents (mw);
2114 set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2);
2115 }
2116
2117 remap_menubar (mw);
2118 }
2119
2120 static void
2121 Right (w, ev, params, num_params)
2122 Widget w;
2123 XEvent *ev;
2124 String *params;
2125 Cardinal *num_params;
2126 {
2127 XlwMenuWidget mw = (XlwMenuWidget) w;
2128 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2129
2130 /* Inside top-level menu-bar? */
2131 if (mw->menu.old_depth == 2)
2132 /* When <right> in the menu-bar is pressed, display the next item on
2133 the menu-bar. If the current item is the last one, highlight the
2134 first item (probably File). */
2135 set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1);
2136 else if (selected_item->contents) /* Is this menu item expandable? */
2137 set_new_state (mw, selected_item->contents, mw->menu.old_depth);
2138 else
2139 {
2140 pop_new_stack_if_no_contents (mw);
2141 set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2);
2142 }
2143
2144 remap_menubar (mw);
2145 }
2146
1987 /* Handle key press and release events while menu is popped up. 2147 /* Handle key press and release events while menu is popped up.
1988 Our action is to get rid of the menu. */ 2148 Our action is to get rid of the menu. */
1989 static void 2149 static void
1990 Key (w, ev, params, num_params) 2150 Key (w, ev, params, num_params)
1991 Widget w; 2151 Widget w;