Mercurial > emacs
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; |