Fix of f13 key handling.
[midnight-commander.git] / lib / widget / menu.c
blob34a79d751c21a4b4fb34087f8a41b46d60b7cb63
1 /*
2 Pulldown menu code
4 Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5 2007, 2009, 2011, 2012
6 The Free Software Foundation, Inc.
8 Written by:
9 Andrew Borodin <aborodin@vmail.ru>, 2012
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 /** \file menu.c
28 * \brief Source: pulldown menu code
31 #include <config.h>
33 #include <ctype.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <sys/types.h>
38 #include "lib/global.h"
40 #include "lib/tty/tty.h"
41 #include "lib/skin.h"
42 #include "lib/tty/mouse.h"
43 #include "lib/tty/key.h" /* key macros */
44 #include "lib/strutil.h"
45 #include "lib/widget.h"
46 #include "lib/event.h" /* mc_event_raise() */
48 /*** global variables ****************************************************************************/
50 /*** file scope macro definitions ****************************************************************/
52 /*** file scope type declarations ****************************************************************/
54 /*** file scope variables ************************************************************************/
56 static cb_ret_t menubar_callback (Widget * w, widget_msg_t msg, int parm);
58 /*** file scope functions ************************************************************************/
59 /* --------------------------------------------------------------------------------------------- */
61 static void
62 menu_arrange (Menu * menu, dlg_shortcut_str get_shortcut)
64 if (menu != NULL)
66 GList *i;
67 size_t max_shortcut_len = 0;
69 menu->max_entry_len = 1;
70 menu->max_hotkey_len = 1;
72 for (i = menu->entries; i != NULL; i = g_list_next (i))
74 menu_entry_t *entry = i->data;
76 if (entry != NULL)
78 size_t len;
80 len = (size_t) hotkey_width (entry->text);
81 menu->max_hotkey_len = max (menu->max_hotkey_len, len);
83 if (get_shortcut != NULL)
84 entry->shortcut = get_shortcut (entry->command);
86 if (entry->shortcut != NULL)
88 len = (size_t) str_term_width1 (entry->shortcut);
89 max_shortcut_len = max (max_shortcut_len, len);
94 menu->max_entry_len = menu->max_hotkey_len + max_shortcut_len;
98 /* --------------------------------------------------------------------------------------------- */
100 static void
101 menubar_paint_idx (WMenuBar * menubar, unsigned int idx, int color)
103 const Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
104 const menu_entry_t *entry = g_list_nth_data (menu->entries, idx);
105 const int y = 2 + idx;
106 int x = menu->start_x;
108 if (x + menu->max_entry_len + 4 > (gsize) menubar->widget.cols)
109 x = menubar->widget.cols - menu->max_entry_len - 4;
111 if (entry == NULL)
113 /* menu separator */
114 tty_setcolor (MENU_ENTRY_COLOR);
116 widget_move (&menubar->widget, y, x - 1);
117 tty_print_alt_char (ACS_LTEE, FALSE);
119 tty_draw_hline (menubar->widget.y + y, menubar->widget.x + x,
120 ACS_HLINE, menu->max_entry_len + 3);
122 widget_move (&menubar->widget, y, x + menu->max_entry_len + 3);
123 tty_print_alt_char (ACS_RTEE, FALSE);
125 else
127 /* menu text */
128 tty_setcolor (color);
129 widget_move (&menubar->widget, y, x);
130 tty_print_char ((unsigned char) entry->first_letter);
131 tty_draw_hline (-1, -1, ' ', menu->max_entry_len + 2); /* clear line */
132 tty_print_string (entry->text.start);
134 if (entry->text.hotkey != NULL)
136 tty_setcolor (color == MENU_SELECTED_COLOR ? MENU_HOTSEL_COLOR : MENU_HOT_COLOR);
137 tty_print_string (entry->text.hotkey);
138 tty_setcolor (color);
141 if (entry->text.end != NULL)
142 tty_print_string (entry->text.end);
144 if (entry->shortcut != NULL)
146 widget_move (&menubar->widget, y, x + menu->max_hotkey_len + 3);
147 tty_print_string (entry->shortcut);
150 /* move cursor to the start of entry text */
151 widget_move (&menubar->widget, y, x + 1);
155 /* --------------------------------------------------------------------------------------------- */
157 static void
158 menubar_draw_drop (WMenuBar * menubar)
160 const Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
161 const unsigned int count = g_list_length (menu->entries);
162 int column = menu->start_x - 1;
163 unsigned int i;
165 if (column + menu->max_entry_len + 5 > (gsize) menubar->widget.cols)
166 column = menubar->widget.cols - menu->max_entry_len - 5;
168 tty_setcolor (MENU_ENTRY_COLOR);
169 draw_box (menubar->widget.owner,
170 menubar->widget.y + 1, menubar->widget.x + column,
171 count + 2, menu->max_entry_len + 5, FALSE);
173 for (i = 0; i < count; i++)
174 menubar_paint_idx (menubar, i,
175 i == menu->selected ? MENU_SELECTED_COLOR : MENU_ENTRY_COLOR);
178 /* --------------------------------------------------------------------------------------------- */
180 static void
181 menubar_set_color (WMenuBar * menubar, gboolean current, gboolean hotkey)
183 if (!menubar->is_active)
184 tty_setcolor (MENU_INACTIVE_COLOR);
185 else if (current)
186 tty_setcolor (hotkey ? MENU_HOTSEL_COLOR : MENU_SELECTED_COLOR);
187 else
188 tty_setcolor (hotkey ? MENU_HOT_COLOR : MENU_ENTRY_COLOR);
191 /* --------------------------------------------------------------------------------------------- */
193 static void
194 menubar_draw (WMenuBar * menubar)
196 GList *i;
198 /* First draw the complete menubar */
199 tty_setcolor (menubar->is_active ? MENU_ENTRY_COLOR : MENU_INACTIVE_COLOR);
200 tty_draw_hline (menubar->widget.y, menubar->widget.x, ' ', menubar->widget.cols);
202 /* Now each one of the entries */
203 for (i = menubar->menu; i != NULL; i = g_list_next (i))
205 Menu *menu = i->data;
206 gboolean is_selected = (menubar->selected == (gsize) g_list_position (menubar->menu, i));
208 menubar_set_color (menubar, is_selected, FALSE);
209 widget_move (&menubar->widget, 0, menu->start_x);
211 tty_print_char (' ');
212 tty_print_string (menu->text.start);
214 if (menu->text.hotkey != NULL)
216 menubar_set_color (menubar, is_selected, TRUE);
217 tty_print_string (menu->text.hotkey);
218 menubar_set_color (menubar, is_selected, FALSE);
221 if (menu->text.end != NULL)
222 tty_print_string (menu->text.end);
224 tty_print_char (' ');
227 if (menubar->is_dropped)
228 menubar_draw_drop (menubar);
229 else
230 widget_move (&menubar->widget, 0,
231 ((Menu *) g_list_nth_data (menubar->menu, menubar->selected))->start_x);
234 /* --------------------------------------------------------------------------------------------- */
236 static void
237 menubar_remove (WMenuBar * menubar)
239 if (menubar->is_dropped)
241 menubar->is_dropped = FALSE;
242 do_refresh ();
243 menubar->is_dropped = TRUE;
247 /* --------------------------------------------------------------------------------------------- */
249 static void
250 menubar_left (WMenuBar * menubar)
252 menubar_remove (menubar);
253 if (menubar->selected == 0)
254 menubar->selected = g_list_length (menubar->menu) - 1;
255 else
256 menubar->selected--;
257 menubar_draw (menubar);
260 /* --------------------------------------------------------------------------------------------- */
262 static void
263 menubar_right (WMenuBar * menubar)
265 menubar_remove (menubar);
266 menubar->selected = (menubar->selected + 1) % g_list_length (menubar->menu);
267 menubar_draw (menubar);
270 /* --------------------------------------------------------------------------------------------- */
272 static void
273 menubar_finish (WMenuBar * menubar)
275 menubar->is_dropped = FALSE;
276 menubar->is_active = FALSE;
277 menubar->widget.lines = 1;
278 widget_want_hotkey (menubar->widget, 0);
280 dlg_select_by_id (menubar->widget.owner, menubar->previous_widget);
281 do_refresh ();
284 /* --------------------------------------------------------------------------------------------- */
286 static void
287 menubar_drop (WMenuBar * menubar, unsigned int selected)
289 menubar->is_dropped = TRUE;
290 menubar->selected = selected;
291 menubar_draw (menubar);
294 /* --------------------------------------------------------------------------------------------- */
296 static void
297 menubar_execute (WMenuBar * menubar)
299 const Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
300 const menu_entry_t *entry = g_list_nth_data (menu->entries, menu->selected);
302 if ((entry != NULL) && (entry->command != CK_IgnoreKey))
304 mc_global.widget.is_right = (menubar->selected != 0);
305 menubar_finish (menubar);
306 menubar->widget.owner->callback (menubar->widget.owner, &menubar->widget,
307 DLG_ACTION, entry->command, NULL);
308 do_refresh ();
312 /* --------------------------------------------------------------------------------------------- */
314 static void
315 menubar_down (WMenuBar * menubar)
317 Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
318 const unsigned int len = g_list_length (menu->entries);
319 menu_entry_t *entry;
321 menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR);
325 menu->selected = (menu->selected + 1) % len;
326 entry = (menu_entry_t *) g_list_nth_data (menu->entries, menu->selected);
328 while ((entry == NULL) || (entry->command == CK_IgnoreKey));
330 menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR);
333 /* --------------------------------------------------------------------------------------------- */
335 static void
336 menubar_up (WMenuBar * menubar)
338 Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
339 const unsigned int len = g_list_length (menu->entries);
340 menu_entry_t *entry;
342 menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR);
346 if (menu->selected == 0)
347 menu->selected = len - 1;
348 else
349 menu->selected--;
350 entry = (menu_entry_t *) g_list_nth_data (menu->entries, menu->selected);
352 while ((entry == NULL) || (entry->command == CK_IgnoreKey));
354 menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR);
357 /* --------------------------------------------------------------------------------------------- */
359 static void
360 menubar_first (WMenuBar * menubar)
362 Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
363 menu_entry_t *entry;
365 if (menu->selected == 0)
366 return;
368 menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR);
370 menu->selected = 0;
372 while (TRUE)
374 entry = (menu_entry_t *) g_list_nth_data (menu->entries, menu->selected);
376 if ((entry == NULL) || (entry->command == CK_IgnoreKey))
377 menu->selected++;
378 else
379 break;
382 menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR);
385 /* --------------------------------------------------------------------------------------------- */
387 static void
388 menubar_last (WMenuBar * menubar)
390 Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
391 const unsigned int len = g_list_length (menu->entries);
392 menu_entry_t *entry;
394 if (menu->selected == len - 1)
395 return;
397 menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR);
399 menu->selected = len;
403 menu->selected--;
404 entry = (menu_entry_t *) g_list_nth_data (menu->entries, menu->selected);
406 while ((entry == NULL) || (entry->command == CK_IgnoreKey));
408 menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR);
411 /* --------------------------------------------------------------------------------------------- */
413 static int
414 menubar_handle_key (WMenuBar * menubar, int key)
416 /* Lowercase */
417 if (isascii (key))
418 key = g_ascii_tolower (key);
420 if (is_abort_char (key))
422 menubar_finish (menubar);
423 return 1;
426 /* menubar help or menubar navigation */
427 switch (key)
429 case KEY_F (1):
431 ev_help_t event_data = { NULL, NULL };
433 if (menubar->is_dropped)
434 event_data.node =
435 ((Menu *) g_list_nth_data (menubar->menu, menubar->selected))->help_node;
436 else
437 event_data.node = "[Menu Bar]";
439 mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data);
440 menubar_draw (menubar);
441 return 1;
443 case KEY_LEFT:
444 case XCTRL ('b'):
445 menubar_left (menubar);
446 return 1;
448 case KEY_RIGHT:
449 case XCTRL ('f'):
450 menubar_right (menubar);
451 return 1;
454 if (!menubar->is_dropped)
456 GList *i;
458 /* drop menu by hotkey */
459 for (i = menubar->menu; i != NULL; i = g_list_next (i))
461 Menu *menu = i->data;
463 if ((menu->text.hotkey != NULL) && (key == g_ascii_tolower (menu->text.hotkey[0])))
465 menubar_drop (menubar, g_list_position (menubar->menu, i));
466 return 1;
470 /* drop menu by Enter or Dowwn key */
471 if (key == KEY_ENTER || key == XCTRL ('n') || key == KEY_DOWN || key == '\n')
472 menubar_drop (menubar, menubar->selected);
474 return 1;
478 Menu *menu = g_list_nth_data (menubar->menu, menubar->selected);
479 GList *i;
481 /* execute menu command by hotkey */
482 for (i = menu->entries; i != NULL; i = g_list_next (i))
484 const menu_entry_t *entry = i->data;
486 if ((entry != NULL) && (entry->command != CK_IgnoreKey)
487 && (entry->text.hotkey != NULL) && (key == g_ascii_tolower (entry->text.hotkey[0])))
489 menu->selected = g_list_position (menu->entries, i);
490 menubar_execute (menubar);
491 return 1;
495 /* menu execute by Enter or menu navigation */
496 switch (key)
498 case KEY_ENTER:
499 case '\n':
500 menubar_execute (menubar);
501 return 1;
503 case KEY_HOME:
504 case ALT ('<'):
505 menubar_first (menubar);
506 break;
508 case KEY_END:
509 case ALT ('>'):
510 menubar_last (menubar);
511 break;
513 case KEY_DOWN:
514 case XCTRL ('n'):
515 menubar_down (menubar);
516 break;
518 case KEY_UP:
519 case XCTRL ('p'):
520 menubar_up (menubar);
521 break;
525 return 0;
528 /* --------------------------------------------------------------------------------------------- */
530 static cb_ret_t
531 menubar_callback (Widget * w, widget_msg_t msg, int parm)
533 WMenuBar *menubar = (WMenuBar *) w;
535 switch (msg)
537 /* We do not want the focus unless we have been activated */
538 case WIDGET_FOCUS:
539 if (!menubar->is_active)
540 return MSG_NOT_HANDLED;
542 /* Trick to get all the mouse events */
543 menubar->widget.lines = LINES;
545 /* Trick to get all of the hotkeys */
546 widget_want_hotkey (menubar->widget, 1);
547 menubar_draw (menubar);
548 return MSG_HANDLED;
550 /* We don't want the buttonbar to activate while using the menubar */
551 case WIDGET_HOTKEY:
552 case WIDGET_KEY:
553 if (menubar->is_active)
555 menubar_handle_key (menubar, parm);
556 return MSG_HANDLED;
558 return MSG_NOT_HANDLED;
560 case WIDGET_CURSOR:
561 /* Put the cursor in a suitable place */
562 return MSG_NOT_HANDLED;
564 case WIDGET_UNFOCUS:
565 return menubar->is_active ? MSG_NOT_HANDLED : MSG_HANDLED;
567 case WIDGET_DRAW:
568 if (menubar->is_visible)
570 menubar_draw (menubar);
571 return MSG_HANDLED;
573 /* fall through */
575 case WIDGET_RESIZED:
576 /* try show menu after screen resize */
577 send_message (w, WIDGET_FOCUS, 0);
578 return MSG_HANDLED;
581 case WIDGET_DESTROY:
582 menubar_set_menu (menubar, NULL);
583 return MSG_HANDLED;
585 default:
586 return default_proc (msg, parm);
590 /* --------------------------------------------------------------------------------------------- */
592 static int
593 menubar_event (Gpm_Event * event, void *data)
595 WMenuBar *menubar = data;
596 gboolean was_active = TRUE;
597 int left_x, right_x, bottom_y;
598 Menu *menu;
600 /* ignore unsupported events */
601 if ((event->type & (GPM_UP | GPM_DOWN | GPM_DRAG)) == 0)
602 return MOU_NORMAL;
604 /* ignore wheel events if menu is inactive */
605 if (!menubar->is_active && ((event->buttons & (GPM_B_MIDDLE | GPM_B_UP | GPM_B_DOWN)) != 0))
606 return MOU_NORMAL;
608 if (event->y == 1 && (event->type & GPM_UP) != 0)
609 return MOU_NORMAL;
611 if (!menubar->is_dropped)
613 menubar->previous_widget = dlg_get_current_widget_id (menubar->widget.owner);
614 menubar->is_active = TRUE;
615 menubar->is_dropped = TRUE;
616 was_active = FALSE;
619 /* Mouse operations on the menubar */
620 if (event->y == 1 || !was_active)
622 /* wheel events on menubar */
623 if (event->buttons & GPM_B_UP)
624 menubar_left (menubar);
625 else if (event->buttons & GPM_B_DOWN)
626 menubar_right (menubar);
627 else
629 const unsigned int len = g_list_length (menubar->menu);
630 unsigned int new_selection = 0;
632 while ((new_selection < len)
633 && (event->x > ((Menu *) g_list_nth_data (menubar->menu,
634 new_selection))->start_x))
635 new_selection++;
637 if (new_selection != 0) /* Don't set the invalid value -1 */
638 new_selection--;
640 if (!was_active)
642 menubar->selected = new_selection;
643 dlg_select_widget (menubar);
645 else
647 menubar_remove (menubar);
648 menubar->selected = new_selection;
650 menubar_draw (menubar);
652 return MOU_NORMAL;
655 if (!menubar->is_dropped || (event->y < 2))
656 return MOU_NORMAL;
658 /* middle click -- everywhere */
659 if (((event->buttons & GPM_B_MIDDLE) != 0) && ((event->type & GPM_DOWN) != 0))
661 menubar_execute (menubar);
662 return MOU_NORMAL;
665 /* the mouse operation is on the menus or it is not */
666 menu = (Menu *) g_list_nth_data (menubar->menu, menubar->selected);
667 left_x = menu->start_x;
668 right_x = left_x + menu->max_entry_len + 3;
669 if (right_x > menubar->widget.cols)
671 left_x = menubar->widget.cols - menu->max_entry_len - 3;
672 right_x = menubar->widget.cols;
675 bottom_y = g_list_length (menu->entries) + 3;
677 if ((event->x >= left_x) && (event->x <= right_x) && (event->y <= bottom_y))
679 int pos = event->y - 3;
680 const menu_entry_t *entry = g_list_nth_data (menu->entries, pos);
682 /* mouse wheel */
683 if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN))
685 menubar_up (menubar);
686 return MOU_NORMAL;
688 if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN))
690 menubar_down (menubar);
691 return MOU_NORMAL;
694 /* ignore events above and below dropped down menu */
695 if ((pos < 0) || (pos >= bottom_y - 3))
696 return MOU_NORMAL;
698 if ((entry != NULL) && (entry->command != CK_IgnoreKey))
700 menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR);
701 menu->selected = pos;
702 menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR);
704 if ((event->type & GPM_UP) != 0)
705 menubar_execute (menubar);
708 else
709 /* use click not wheel to close menu */
710 if (((event->type & GPM_DOWN) != 0) && ((event->buttons & (GPM_B_UP | GPM_B_DOWN)) == 0))
711 menubar_finish (menubar);
713 return MOU_NORMAL;
716 /* --------------------------------------------------------------------------------------------- */
717 /*** public functions ****************************************************************************/
718 /* --------------------------------------------------------------------------------------------- */
720 menu_entry_t *
721 menu_entry_create (const char *name, unsigned long command)
723 menu_entry_t *entry;
725 entry = g_new (menu_entry_t, 1);
726 entry->first_letter = ' ';
727 entry->text = parse_hotkey (name);
728 entry->command = command;
729 entry->shortcut = NULL;
731 return entry;
734 /* --------------------------------------------------------------------------------------------- */
736 void
737 menu_entry_free (menu_entry_t * entry)
739 if (entry != NULL)
741 release_hotkey (entry->text);
742 g_free (entry->shortcut);
743 g_free (entry);
747 /* --------------------------------------------------------------------------------------------- */
749 Menu *
750 create_menu (const char *name, GList * entries, const char *help_node)
752 Menu *menu;
754 menu = g_new (Menu, 1);
755 menu->start_x = 0;
756 menu->text = parse_hotkey (name);
757 menu->entries = entries;
758 menu->max_entry_len = 1;
759 menu->max_hotkey_len = 0;
760 menu->selected = 0;
761 menu->help_node = g_strdup (help_node);
763 return menu;
766 /* --------------------------------------------------------------------------------------------- */
768 void
769 menu_set_name (Menu * menu, const char *name)
771 release_hotkey (menu->text);
772 menu->text = parse_hotkey (name);
775 /* --------------------------------------------------------------------------------------------- */
777 void
778 destroy_menu (Menu * menu)
780 release_hotkey (menu->text);
781 g_list_foreach (menu->entries, (GFunc) menu_entry_free, NULL);
782 g_list_free (menu->entries);
783 g_free (menu->help_node);
784 g_free (menu);
787 /* --------------------------------------------------------------------------------------------- */
789 WMenuBar *
790 menubar_new (int y, int x, int cols, GList * menu)
792 WMenuBar *menubar;
794 menubar = g_new0 (WMenuBar, 1);
795 init_widget (&menubar->widget, y, x, 1, cols, menubar_callback, menubar_event);
796 widget_want_cursor (menubar->widget, FALSE);
797 menubar->is_visible = TRUE; /* by default */
798 menubar_set_menu (menubar, menu);
800 return menubar;
803 /* --------------------------------------------------------------------------------------------- */
805 void
806 menubar_set_menu (WMenuBar * menubar, GList * menu)
808 /* delete previous menu */
809 if (menubar->menu != NULL)
811 g_list_foreach (menubar->menu, (GFunc) destroy_menu, NULL);
812 g_list_free (menubar->menu);
814 /* add new menu */
815 menubar->is_active = FALSE;
816 menubar->is_dropped = FALSE;
817 menubar->menu = menu;
818 menubar->selected = 0;
819 menubar_arrange (menubar);
822 /* --------------------------------------------------------------------------------------------- */
824 void
825 menubar_add_menu (WMenuBar * menubar, Menu * menu)
827 if (menu != NULL)
829 menu_arrange (menu, menubar->widget.owner->get_shortcut);
830 menubar->menu = g_list_append (menubar->menu, menu);
833 menubar_arrange (menubar);
836 /* --------------------------------------------------------------------------------------------- */
838 * Properly space menubar items. Should be called when menubar is created
839 * and also when widget width is changed (i.e. upon xterm resize).
842 void
843 menubar_arrange (WMenuBar * menubar)
845 int start_x = 1;
846 GList *i;
847 int gap;
849 if (menubar->menu == NULL)
850 return;
852 #ifndef RESIZABLE_MENUBAR
853 gap = 3;
855 for (i = menubar->menu; i != NULL; i = g_list_next (i))
857 Menu *menu = i->data;
858 int len = hotkey_width (menu->text) + 2;
860 menu->start_x = start_x;
861 start_x += len + gap;
863 #else /* RESIZABLE_MENUBAR */
864 gap = menubar->widget.cols - 2;
866 /* First, calculate gap between items... */
867 for (i = menubar->menu; i != NULL; i = g_list_next (i))
869 Menu *menu = i->data;
870 /* preserve length here, to be used below */
871 menu->start_x = hotkey_width (menu->text) + 2;
872 gap -= menu->start_x;
875 gap /= (menubar->menu->len - 1);
877 if (gap <= 0)
879 /* We are out of luck - window is too narrow... */
880 gap = 1;
883 /* ...and now fix start positions of menubar items */
884 for (i = menubar->menu; i != NULL; i = g_list_next (i))
886 Menu *menu = i->data;
887 int len = menu->start_x;
889 menu->start_x = start_x;
890 start_x += len + gap;
892 #endif /* RESIZABLE_MENUBAR */
895 /* --------------------------------------------------------------------------------------------- */
896 /** Find MenuBar widget in the dialog */
898 WMenuBar *
899 find_menubar (const Dlg_head * h)
901 return (WMenuBar *) find_widget_type (h, menubar_callback);
904 /* --------------------------------------------------------------------------------------------- */