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