Mercurial > emacs
comparison src/xmenu.c @ 6746:cda1ce7952ca
(Fx_popup_dialog): Doc fix.
(list_of_items): Handle nil in item list as left/right boundary.
(push_left_right_boundary): Record the boundary.
(xmenu_show): Disregard a boundary if any.
(xdialog_show): Really obey a boundary.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 08 Apr 1994 05:52:00 +0000 |
parents | 19bcf36f315e |
children | 52b64d326287 |
comparison
equal
deleted
inserted
replaced
6745:469d679ca338 | 6746:cda1ce7952ca |
---|---|
117 In some cases, multiple levels of menus may be described. | 117 In some cases, multiple levels of menus may be described. |
118 A single vector slot containing nil indicates the start of a submenu. | 118 A single vector slot containing nil indicates the start of a submenu. |
119 A single vector slot containing lambda indicates the end of a submenu. | 119 A single vector slot containing lambda indicates the end of a submenu. |
120 The submenu follows a menu item which is the way to reach the submenu. | 120 The submenu follows a menu item which is the way to reach the submenu. |
121 | 121 |
122 A single vector slot containing quote indicates that the | |
123 following items should appear on the right of a dialog box. | |
124 | |
122 Using a Lisp vector to hold this information while we decode it | 125 Using a Lisp vector to hold this information while we decode it |
123 takes care of protecting all the data from GC. */ | 126 takes care of protecting all the data from GC. */ |
124 | 127 |
125 #define MENU_ITEMS_PANE_NAME 1 | 128 #define MENU_ITEMS_PANE_NAME 1 |
126 #define MENU_ITEMS_PANE_PREFIX 2 | 129 #define MENU_ITEMS_PANE_PREFIX 2 |
222 if (menu_items_used + 1 > menu_items_allocated) | 225 if (menu_items_used + 1 > menu_items_allocated) |
223 grow_menu_items (); | 226 grow_menu_items (); |
224 | 227 |
225 XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda; | 228 XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda; |
226 menu_items_submenu_depth--; | 229 menu_items_submenu_depth--; |
230 } | |
231 | |
232 /* Indicate boundary between left and right. */ | |
233 | |
234 static void | |
235 push_left_right_boundary () | |
236 { | |
237 if (menu_items_used + 1 > menu_items_allocated) | |
238 grow_menu_items (); | |
239 | |
240 XVECTOR (menu_items)->contents[menu_items_used++] = Qquote; | |
227 } | 241 } |
228 | 242 |
229 /* Start a new menu pane in menu_items.. | 243 /* Start a new menu pane in menu_items.. |
230 NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */ | 244 NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */ |
231 | 245 |
607 for (tail = pane; !NILP (tail); tail = Fcdr (tail)) | 621 for (tail = pane; !NILP (tail); tail = Fcdr (tail)) |
608 { | 622 { |
609 item = Fcar (tail); | 623 item = Fcar (tail); |
610 if (STRINGP (item)) | 624 if (STRINGP (item)) |
611 push_menu_item (item, Qnil, Qnil, Qnil); | 625 push_menu_item (item, Qnil, Qnil, Qnil); |
626 else if (NILP (item)) | |
627 push_left_right_boundary (); | |
612 else | 628 else |
613 { | 629 { |
614 CHECK_CONS (item, 0); | 630 CHECK_CONS (item, 0); |
615 item1 = Fcar (item); | 631 item1 = Fcar (item); |
616 CHECK_STRING (item1, 1); | 632 CHECK_STRING (item1, 1); |
842 The dialog box appears in the middle of the specified frame.\n\ | 858 The dialog box appears in the middle of the specified frame.\n\ |
843 \n\ | 859 \n\ |
844 CONTENTS specifies the alternatives to display in the dialog box.\n\ | 860 CONTENTS specifies the alternatives to display in the dialog box.\n\ |
845 It is a list of the form (TITLE ITEM1 ITEM2...).\n\ | 861 It is a list of the form (TITLE ITEM1 ITEM2...).\n\ |
846 Each ITEM is a cons cell (STRING . VALUE).\n\ | 862 Each ITEM is a cons cell (STRING . VALUE).\n\ |
847 The return value is VALUE from the chosen item.") | 863 The return value is VALUE from the chosen item.\n\n\ |
864 An ITEM may also be just a string--that makes a nonselectable item.\n\ | |
865 An ITEM may also be nil--that means to put all preceding items\n\ | |
866 on the left of the dialog box and all following items on the right.\n\ | |
867 \(By default, approximately half appear on each side.)") | |
848 (position, contents) | 868 (position, contents) |
849 Lisp_Object position, contents; | 869 Lisp_Object position, contents; |
850 { | 870 { |
851 FRAME_PTR f; | 871 FRAME_PTR f; |
852 Lisp_Object window; | 872 Lisp_Object window; |
1434 i++; | 1454 i++; |
1435 } | 1455 } |
1436 else if (EQ (XVECTOR (menu_items)->contents[i], Qt) | 1456 else if (EQ (XVECTOR (menu_items)->contents[i], Qt) |
1437 && submenu_depth != 0) | 1457 && submenu_depth != 0) |
1438 i += MENU_ITEMS_PANE_LENGTH; | 1458 i += MENU_ITEMS_PANE_LENGTH; |
1459 /* Ignore a nil in the item list. | |
1460 It's meaningful only for dialog boxes. */ | |
1461 else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) | |
1462 i += 1; | |
1439 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) | 1463 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) |
1440 { | 1464 { |
1441 /* Create a new pane. */ | 1465 /* Create a new pane. */ |
1442 Lisp_Object pane_name, prefix; | 1466 Lisp_Object pane_name, prefix; |
1443 char *pane_string; | 1467 char *pane_string; |
1737 struct event_queue *next; | 1761 struct event_queue *next; |
1738 }; | 1762 }; |
1739 | 1763 |
1740 struct event_queue *queue = NULL; | 1764 struct event_queue *queue = NULL; |
1741 struct event_queue *queue_tmp; | 1765 struct event_queue *queue_tmp; |
1766 | |
1767 /* Number of elements seen so far, before boundary. */ | |
1768 int left_count = 0; | |
1769 /* 1 means we've seen the boundary between left-hand elts and right-hand. */ | |
1770 int boundary_seen = 0; | |
1742 | 1771 |
1743 *error = NULL; | 1772 *error = NULL; |
1744 | 1773 |
1745 if (menu_items_n_panes > 1) | 1774 if (menu_items_n_panes > 1) |
1746 { | 1775 { |
1781 { | 1810 { |
1782 free_menubar_widget_value_tree (first_wv); | 1811 free_menubar_widget_value_tree (first_wv); |
1783 *error = "Submenu in dialog items"; | 1812 *error = "Submenu in dialog items"; |
1784 return Qnil; | 1813 return Qnil; |
1785 } | 1814 } |
1815 if (EQ (item_name, Qquote)) | |
1816 { | |
1817 /* This is the boundary between left-side elts | |
1818 and right-side elts. Stop incrementing right_count. */ | |
1819 boundary_seen = 1; | |
1820 i++; | |
1821 continue; | |
1822 } | |
1786 if (nb_buttons >= 10) | 1823 if (nb_buttons >= 10) |
1787 { | 1824 { |
1788 free_menubar_widget_value_tree (first_wv); | 1825 free_menubar_widget_value_tree (first_wv); |
1789 *error = "Too many dialog items"; | 1826 *error = "Too many dialog items"; |
1790 return Qnil; | 1827 return Qnil; |
1798 wv->value = XSTRING (item_name)->data; | 1835 wv->value = XSTRING (item_name)->data; |
1799 wv->call_data = (void *) &XVECTOR (menu_items)->contents[i]; | 1836 wv->call_data = (void *) &XVECTOR (menu_items)->contents[i]; |
1800 wv->enabled = !NILP (enable); | 1837 wv->enabled = !NILP (enable); |
1801 prev_wv = wv; | 1838 prev_wv = wv; |
1802 | 1839 |
1840 if (! boundary_seen) | |
1841 left_count++; | |
1842 | |
1803 nb_buttons++; | 1843 nb_buttons++; |
1804 i += MENU_ITEMS_ITEM_LENGTH; | 1844 i += MENU_ITEMS_ITEM_LENGTH; |
1805 } | 1845 } |
1846 | |
1847 /* If the boundary was not specified, | |
1848 by default put half on the left and half on the right. */ | |
1849 if (! boundary_seen) | |
1850 left_count = nb_buttons - nb_buttons / 2; | |
1806 | 1851 |
1807 wv = malloc_widget_value (); | 1852 wv = malloc_widget_value (); |
1808 wv->name = dialog_name; | 1853 wv->name = dialog_name; |
1809 | 1854 |
1810 /* Dialog boxes use a really stupid name encoding | 1855 /* Dialog boxes use a really stupid name encoding |
1813 The Q means something also. */ | 1858 The Q means something also. */ |
1814 dialog_name[0] = 'Q'; | 1859 dialog_name[0] = 'Q'; |
1815 dialog_name[1] = '0' + nb_buttons; | 1860 dialog_name[1] = '0' + nb_buttons; |
1816 dialog_name[2] = 'B'; | 1861 dialog_name[2] = 'B'; |
1817 dialog_name[3] = 'R'; | 1862 dialog_name[3] = 'R'; |
1818 dialog_name[4] = '0' + nb_buttons / 2; | 1863 /* Number of buttons to put on the right. */ |
1864 dialog_name[4] = '0' + nb_buttons - left_count; | |
1819 dialog_name[5] = 0; | 1865 dialog_name[5] = 0; |
1820 wv->contents = first_wv; | 1866 wv->contents = first_wv; |
1821 first_wv = wv; | 1867 first_wv = wv; |
1822 | |
1823 } | 1868 } |
1824 | 1869 |
1825 /* Actually create the dialog. */ | 1870 /* Actually create the dialog. */ |
1826 dialog_id = ++popup_id_tick; | 1871 dialog_id = ++popup_id_tick; |
1827 menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, | 1872 menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, |
2012 *error = "Can't create pane"; | 2057 *error = "Can't create pane"; |
2013 return Qnil; | 2058 return Qnil; |
2014 } | 2059 } |
2015 i += MENU_ITEMS_PANE_LENGTH; | 2060 i += MENU_ITEMS_PANE_LENGTH; |
2016 } | 2061 } |
2062 /* Ignore a nil in the item list. | |
2063 It's meaningful only for dialog boxes. */ | |
2064 else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) | |
2065 i += 1; | |
2017 else | 2066 else |
2018 { | 2067 { |
2019 /* Create a new item within current pane. */ | 2068 /* Create a new item within current pane. */ |
2020 Lisp_Object item_name, enable, descrip; | 2069 Lisp_Object item_name, enable, descrip; |
2021 | 2070 |