Mercurial > hg > xemacs-beta
comparison lwlib/xlwtabs.c @ 446:1ccc32a20af4 r21-2-38
Import from CVS: tag r21-2-38
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:37:21 +0200 |
parents | abe6d1db359e |
children | 3078fd1074e8 |
comparison
equal
deleted
inserted
replaced
445:34f3776fcf0e | 446:1ccc32a20af4 |
---|---|
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with XEmacs; see the file COPYING. If not, write to | 17 along with XEmacs; see the file COPYING. If not, write to |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 Boston, MA 02111-1307, USA. */ | 19 Boston, MA 02111-1307, USA. */ |
20 | 20 |
21 /* Synched up with: Tabs.c 1.27 */ | 21 /* Synched up with: Tabs.c 1.27. |
22 | |
23 #### This file contains essential XEmacs related fixes to the original | |
24 verison of the Tabs widget. Be VERY careful about syncing if you ever | |
25 update to a more recent version. In general this is probably now a | |
26 bad idea. */ | |
22 | 27 |
23 /* | 28 /* |
24 * Tabs.c - Index Tabs composite widget | 29 * Tabs.c - Index Tabs composite widget |
25 * | 30 * |
26 * Author: Edward A. Falk | 31 * Author: Edward A. Falk |
120 <Key>KP_Up: highlight(up) \n\ | 125 <Key>KP_Up: highlight(up) \n\ |
121 <Key>Down: highlight(down) \n\ | 126 <Key>Down: highlight(down) \n\ |
122 <Key>KP_Down: highlight(down) \n\ | 127 <Key>KP_Down: highlight(down) \n\ |
123 <Key> : page(select) \n\ | 128 <Key> : page(select) \n\ |
124 " ; | 129 " ; |
125 static XtAccelerators defaultAccelerators ; | 130 static XtAccelerators defaultAccelerators ; /* #### Never used */ |
126 | 131 |
127 #define offset(field) XtOffsetOf(TabsRec, tabs.field) | 132 #define offset(field) XtOffsetOf(TabsRec, tabs.field) |
128 static XtResource resources[] = { | 133 static XtResource resources[] = { |
129 | 134 |
130 {XtNselectInsensitive, XtCSelectInsensitive, XtRBoolean, sizeof(Boolean), | 135 {XtNselectInsensitive, XtCSelectInsensitive, XtRBoolean, sizeof(Boolean), |
399 #endif | 404 #endif |
400 #else | 405 #else |
401 #define assert(e) | 406 #define assert(e) |
402 #endif | 407 #endif |
403 | 408 |
404 | 409 #define TabsNumChildren(tw) (((TabsWidget)tw)->composite.num_children) |
410 #define TabVisible(tab) \ | |
411 (XtIsManaged(tab) && \ | |
412 ((TabsConstraints)((tab)->core.constraints))->tabs.visible) | |
405 | 413 |
406 | 414 |
407 /**************************************************************** | 415 /**************************************************************** |
408 * | 416 * |
409 * Member Procedures | 417 * Member Procedures |
428 TabsInit(Widget request, Widget new, ArgList args, Cardinal *num_args) | 436 TabsInit(Widget request, Widget new, ArgList args, Cardinal *num_args) |
429 { | 437 { |
430 TabsWidget newTw = (TabsWidget)new; | 438 TabsWidget newTw = (TabsWidget)new; |
431 | 439 |
432 newTw->tabs.numRows = 0 ; | 440 newTw->tabs.numRows = 0 ; |
433 newTw->tabs.displayChildren = 0; | 441 newTw->tabs.realRows = 0; |
434 | 442 |
435 GetPreferredSizes(newTw) ; | 443 GetPreferredSizes(newTw) ; |
436 | 444 |
437 /* height is easy, it's the same for all tabs: | 445 /* height is easy, it's the same for all tabs: |
438 * TODO: font height + height of tallest bitmap. | 446 * TODO: font height + height of tallest bitmap. |
484 TabsConstraintInitialize(Widget request, Widget new, | 492 TabsConstraintInitialize(Widget request, Widget new, |
485 ArgList args, Cardinal *num_args) | 493 ArgList args, Cardinal *num_args) |
486 { | 494 { |
487 TabsConstraints tab = (TabsConstraints) new->core.constraints ; | 495 TabsConstraints tab = (TabsConstraints) new->core.constraints ; |
488 tab->tabs.greyAlloc = False ; /* defer allocation of pixel */ | 496 tab->tabs.greyAlloc = False ; /* defer allocation of pixel */ |
497 tab->tabs.visible = False ; | |
489 | 498 |
490 getBitmapInfo((TabsWidget)XtParent(new), tab) ; | 499 getBitmapInfo((TabsWidget)XtParent(new), tab) ; |
491 TabWidth(new) ; | 500 TabWidth(new) ; |
492 } | 501 } |
493 | 502 |
528 { | 537 { |
529 TabsWidget tw = (TabsWidget) w; | 538 TabsWidget tw = (TabsWidget) w; |
530 int i ; | 539 int i ; |
531 int num_children = tw->composite.num_children ; | 540 int num_children = tw->composite.num_children ; |
532 Widget *childP ; | 541 Widget *childP ; |
533 TabsConstraints tab ; | 542 TabsConstraints tab ; /* #### unused */ |
534 Dimension cw,ch,bw ; | 543 Dimension cw,ch,bw ; |
535 | 544 |
536 /* Our size has now been dictated by the parent. Lay out the | 545 /* Our size has now been dictated by the parent. Lay out the |
537 * tabs, lay out the frame, lay out the children. Remember | 546 * tabs, lay out the frame, lay out the children. Remember |
538 * that the tabs overlap each other and the frame by shadowWidth. | 547 * that the tabs overlap each other and the frame by shadowWidth. |
548 | 557 |
549 if( num_children > 0 && tw->composite.children != NULL ) | 558 if( num_children > 0 && tw->composite.children != NULL ) |
550 { | 559 { |
551 /* Loop through the tabs and assign rows & x positions */ | 560 /* Loop through the tabs and assign rows & x positions */ |
552 (void) TabLayout(tw, tw->core.width, tw->core.height, NULL, False) ; | 561 (void) TabLayout(tw, tw->core.width, tw->core.height, NULL, False) ; |
553 num_children = tw->tabs.displayChildren; | 562 num_children = TabsNumChildren (tw); |
554 | 563 |
555 /* assign a top widget, bring it to bottom row. */ | 564 /* assign a top widget, bring it to bottom row. */ |
556 TabsShuffleRows(tw) ; | 565 TabsShuffleRows(tw) ; |
557 | 566 |
558 /* now assign child positions & sizes. Positions are all the | 567 /* now assign child positions & sizes. Positions are all the |
565 | 574 |
566 | 575 |
567 for(i=0, childP=tw->composite.children; | 576 for(i=0, childP=tw->composite.children; |
568 i < num_children; | 577 i < num_children; |
569 ++i, ++childP) | 578 ++i, ++childP) |
570 if( XtIsManaged(*childP) ) | 579 if( TabVisible(*childP) ) |
571 { | 580 { |
572 tab = (TabsConstraints) (*childP)->core.constraints ; | 581 tab = (TabsConstraints) (*childP)->core.constraints ; |
573 bw = (*childP)->core.border_width ; | 582 bw = (*childP)->core.border_width ; |
574 XtConfigureWidget(*childP, SHADWID,tw->tabs.tab_total+SHADWID, | 583 XtConfigureWidget(*childP, SHADWID,tw->tabs.tab_total+SHADWID, |
575 cw-bw*2,ch-bw*2, bw) ; | 584 cw-bw*2,ch-bw*2, bw) ; |
930 else | 939 else |
931 { | 940 { |
932 Widget *childP = tw->composite.children ; | 941 Widget *childP = tw->composite.children ; |
933 int i,bw ; | 942 int i,bw ; |
934 w->core.border_width = req->border_width ; | 943 w->core.border_width = req->border_width ; |
935 for(i=tw->tabs.displayChildren; --i >= 0; ++childP) | 944 for(i=TabsNumChildren (tw); --i >= 0; ++childP) |
936 if( XtIsManaged(*childP) ) | 945 if( TabVisible(*childP) ) |
937 { | 946 { |
938 bw = (*childP)->core.border_width ; | 947 bw = (*childP)->core.border_width ; |
939 XtConfigureWidget(*childP, s,tw->tabs.tab_total+s, | 948 XtConfigureWidget(*childP, s,tw->tabs.tab_total+s, |
940 rw-2*bw, rh-2*bw, bw) ; | 949 rw-2*bw, rh-2*bw, bw) ; |
941 } | 950 } |
999 /* make sure the top widget stays on top. This requires | 1008 /* make sure the top widget stays on top. This requires |
1000 * making sure that all new children are realized first. | 1009 * making sure that all new children are realized first. |
1001 */ | 1010 */ |
1002 if( tw->tabs.topWidget != NULL && XtIsRealized(tw->tabs.topWidget) ) | 1011 if( tw->tabs.topWidget != NULL && XtIsRealized(tw->tabs.topWidget) ) |
1003 { | 1012 { |
1004 for(i=tw->tabs.displayChildren; --i >= 0; ++childP) | 1013 for(i=TabsNumChildren (tw); --i >= 0; ++childP) |
1005 if( !XtIsRealized(*childP) ) | 1014 if( !XtIsRealized(*childP) ) |
1006 XtRealizeWidget(*childP) ; | 1015 XtRealizeWidget(*childP) ; |
1007 | 1016 |
1008 XRaiseWindow(dpy, XtWindow(tw->tabs.topWidget)) ; | 1017 XRaiseWindow(dpy, XtWindow(tw->tabs.topWidget)) ; |
1009 } | 1018 } |
1064 | 1073 |
1065 /* TODO: determine which tab was clicked, if any. Set that | 1074 /* TODO: determine which tab was clicked, if any. Set that |
1066 * widget to be top of stacking order with XawTabsSetTop(). | 1075 * widget to be top of stacking order with XawTabsSetTop(). |
1067 */ | 1076 */ |
1068 for(i=0, childP=tw->composite.children; | 1077 for(i=0, childP=tw->composite.children; |
1069 i < tw->tabs.displayChildren; | 1078 i < TabsNumChildren (tw); |
1070 ++i, ++childP) | 1079 ++i, ++childP) |
1071 if( XtIsManaged(*childP) ) | 1080 if( TabVisible(*childP) ) |
1072 { | 1081 { |
1073 TabsConstraints tab = (TabsConstraints)(*childP)->core.constraints; | 1082 TabsConstraints tab = (TabsConstraints)(*childP)->core.constraints; |
1074 if( x > tab->tabs.x && x < tab->tabs.x + tab->tabs.width && | 1083 if( x > tab->tabs.x && x < tab->tabs.x + tab->tabs.width && |
1075 y > tab->tabs.y && y < tab->tabs.y + h ) | 1084 y > tab->tabs.y && y < tab->tabs.y + h ) |
1076 { | 1085 { |
1090 { | 1099 { |
1091 TabsWidget tw = (TabsWidget) w ; | 1100 TabsWidget tw = (TabsWidget) w ; |
1092 Widget newtop = NULL; | 1101 Widget newtop = NULL; |
1093 Widget *childP ; | 1102 Widget *childP ; |
1094 int idx ; | 1103 int idx ; |
1095 int nc = tw->tabs.displayChildren ; | 1104 int nc = TabsNumChildren (tw) ; |
1096 | 1105 |
1097 if( nc <= 0 ) | 1106 if( nc <= 0 ) |
1098 return ; | 1107 return ; |
1099 | 1108 |
1100 if( *num_params < 1 ) { | 1109 if( *num_params < 1 ) { |
1154 { | 1163 { |
1155 TabsWidget tw = (TabsWidget) w ; | 1164 TabsWidget tw = (TabsWidget) w ; |
1156 Widget newhl = NULL; | 1165 Widget newhl = NULL; |
1157 Widget *childP ; | 1166 Widget *childP ; |
1158 int idx ; | 1167 int idx ; |
1159 int nc = tw->tabs.displayChildren ; | 1168 int nc = TabsNumChildren (tw) ; |
1160 | 1169 |
1161 if( nc <= 0 ) | 1170 if( nc <= 0 ) |
1162 return ; | 1171 return ; |
1163 | 1172 |
1164 if( *num_params < 1 ) | 1173 if( *num_params < 1 ) |
1392 */ | 1401 */ |
1393 | 1402 |
1394 y = tw->tabs.numRows == 1 ? TABDELTA : 0 ; | 1403 y = tw->tabs.numRows == 1 ? TABDELTA : 0 ; |
1395 for(i=0; i<tw->tabs.numRows; ++i, y += th) | 1404 for(i=0; i<tw->tabs.numRows; ++i, y += th) |
1396 { | 1405 { |
1397 for( j=tw->tabs.displayChildren, childP=tw->composite.children; | 1406 for( j=TabsNumChildren (tw), childP=tw->composite.children; |
1398 --j >= 0; ++childP ) | 1407 --j >= 0; ++childP ) |
1399 if( XtIsManaged(*childP) ) | 1408 if( TabVisible(*childP) ) |
1400 { | 1409 { |
1401 tab = (TabsConstraints)(*childP)->core.constraints; | 1410 tab = (TabsConstraints)(*childP)->core.constraints; |
1402 if( tab->tabs.row == i && *childP != tw->tabs.topWidget ) | 1411 if( tab->tabs.row == i && *childP != tw->tabs.topWidget ) |
1403 DrawTab(tw, *childP, labels) ; | 1412 DrawTab(tw, *childP, labels) ; |
1404 } | 1413 } |
1703 */ | 1712 */ |
1704 | 1713 |
1705 static int | 1714 static int |
1706 TabLayout(TabsWidget tw, int wid, int hgt, Dimension *reply_height, Bool query_only) | 1715 TabLayout(TabsWidget tw, int wid, int hgt, Dimension *reply_height, Bool query_only) |
1707 { | 1716 { |
1708 int i, row ; | 1717 int i, row, done = 0, display_rows = 0 ; |
1709 int num_children = tw->composite.num_children ; | 1718 int num_children = tw->composite.num_children ; |
1710 Widget *childP ; | 1719 Widget *childP ; |
1711 Dimension w ; | 1720 Dimension w ; |
1712 Position x,y ; | 1721 Position x,y ; |
1713 TabsConstraints tab ; | 1722 TabsConstraints tab ; |
1714 | |
1715 if (!query_only) | |
1716 tw->tabs.displayChildren = 0; | |
1717 | 1723 |
1718 /* Algorithm: loop through children, assign X positions. If a tab | 1724 /* Algorithm: loop through children, assign X positions. If a tab |
1719 * would extend beyond the right edge, start a new row. After all | 1725 * would extend beyond the right edge, start a new row. After all |
1720 * rows are assigned, make a second pass and assign Y positions. | 1726 * rows are assigned, make a second pass and assign Y positions. |
1721 */ | 1727 */ |
1731 for(i=num_children, childP=tw->composite.children; --i >= 0; ++childP) | 1737 for(i=num_children, childP=tw->composite.children; --i >= 0; ++childP) |
1732 if( XtIsManaged(*childP) ) | 1738 if( XtIsManaged(*childP) ) |
1733 { | 1739 { |
1734 tab = (TabsConstraints) (*childP)->core.constraints ; | 1740 tab = (TabsConstraints) (*childP)->core.constraints ; |
1735 w = tab->tabs.width ; | 1741 w = tab->tabs.width ; |
1742 | |
1736 if( x + w > wid ) { /* new row */ | 1743 if( x + w > wid ) { /* new row */ |
1737 if (y + tw->tabs.tab_height > hgt) | 1744 if (y + tw->tabs.tab_height > hgt && !done) |
1738 break; | 1745 { |
1739 ++row ; | 1746 display_rows = row; |
1747 done = 1; | |
1748 } | |
1749 ++row; | |
1740 x = INDENT ; | 1750 x = INDENT ; |
1741 y += tw->tabs.tab_height ; | 1751 y += tw->tabs.tab_height ; |
1742 } | 1752 } |
1743 if( !query_only ) { | 1753 if( !query_only ) { |
1744 tab->tabs.x = x ; | 1754 tab->tabs.x = x ; |
1745 tab->tabs.y = y ; | 1755 tab->tabs.y = y ; |
1746 tab->tabs.row = row ; | 1756 tab->tabs.row = row ; |
1747 } | 1757 } |
1748 x += w + SPACING ; | 1758 x += w + SPACING ; |
1749 if (!query_only) | 1759 if (!query_only && !done) |
1750 tw->tabs.displayChildren++; | 1760 tab->tabs.visible = 1; |
1761 | |
1751 } | 1762 } |
1752 /* If there was only one row, increase the height by TABDELTA */ | 1763 /* If there was only one row, increase the height by TABDELTA */ |
1753 if( ++row == 1 ) | 1764 if( ++display_rows == 1 ) |
1754 { | 1765 { |
1766 row++; | |
1755 y = TABDELTA ; | 1767 y = TABDELTA ; |
1756 if( !query_only ) | 1768 if( !query_only ) |
1757 for(i=num_children, childP=tw->composite.children; | 1769 for(i=num_children, childP=tw->composite.children; |
1758 --i >= 0 ; ++childP) | 1770 --i >= 0 ; ++childP) |
1759 if( XtIsManaged(*childP) ) | 1771 if( XtIsManaged(*childP) ) |
1763 } | 1775 } |
1764 } | 1776 } |
1765 y += tw->tabs.tab_height ; | 1777 y += tw->tabs.tab_height ; |
1766 } | 1778 } |
1767 else | 1779 else |
1768 row = y = 0 ; | 1780 display_rows = row = y = 0 ; |
1769 | 1781 |
1770 if( !query_only ) { | 1782 if( !query_only ) { |
1771 tw->tabs.tab_total = y ; | 1783 tw->tabs.tab_total = y ; |
1772 tw->tabs.numRows = row ; | 1784 tw->tabs.numRows = display_rows ; |
1785 tw->tabs.realRows = row; | |
1773 } | 1786 } |
1774 | 1787 |
1775 if( reply_height != NULL ) | 1788 if( reply_height != NULL ) |
1776 *reply_height = y ; | 1789 *reply_height = y ; |
1777 | 1790 |
1778 return row ; | 1791 return display_rows ; |
1779 } | 1792 } |
1780 | 1793 |
1781 | 1794 |
1782 | 1795 |
1783 /* Find max preferred child size. Returned sizes include child | 1796 /* Find max preferred child size. Returned sizes include child |
1824 static void | 1837 static void |
1825 TabsShuffleRows(TabsWidget tw) | 1838 TabsShuffleRows(TabsWidget tw) |
1826 { | 1839 { |
1827 TabsConstraints tab ; | 1840 TabsConstraints tab ; |
1828 int move ; | 1841 int move ; |
1829 int nrows ; | 1842 int real_rows, display_rows ; |
1830 Widget *childP ; | 1843 Widget *childP ; |
1831 Dimension th = tw->tabs.tab_height ; | 1844 Dimension th = tw->tabs.tab_height ; |
1832 Position bottom ; | 1845 Position bottom ; |
1833 int i ; | 1846 int i ; |
1834 | 1847 |
1835 /* There must be a top widget. If not, assign one. */ | 1848 /* There must be a top widget. If not, assign one. */ |
1836 if( tw->tabs.topWidget == NULL && tw->composite.children != NULL ) | 1849 if( tw->tabs.topWidget == NULL && tw->composite.children != NULL ) |
1837 for(i=tw->composite.num_children, childP=tw->composite.children; | 1850 for(i=TabsNumChildren (tw), childP=tw->composite.children; |
1838 --i >= 0; | 1851 --i >= 0; |
1839 ++childP) | 1852 ++childP) |
1840 if( XtIsManaged(*childP) ) { | 1853 if( XtIsManaged(*childP) ) { |
1841 tw->tabs.topWidget = *childP ; | 1854 tw->tabs.topWidget = *childP ; |
1842 break ; | 1855 break ; |
1843 } | 1856 } |
1844 | 1857 |
1845 if( tw->tabs.topWidget != NULL ) | 1858 if( tw->tabs.topWidget != NULL ) |
1846 { | 1859 { |
1847 nrows = tw->tabs.numRows ; | 1860 display_rows = tw->tabs.numRows ; |
1848 assert( nrows > 0 ) ; | 1861 real_rows = tw->tabs.realRows ; |
1849 | 1862 assert( display_rows >= real_rows ) ; |
1850 if( nrows > 1 ) | 1863 |
1864 if( real_rows > 1 ) | |
1851 { | 1865 { |
1852 tab = (TabsConstraints) tw->tabs.topWidget->core.constraints ; | 1866 tab = (TabsConstraints) tw->tabs.topWidget->core.constraints ; |
1853 assert( tab != NULL ) ; | 1867 assert( tab != NULL ) ; |
1854 | 1868 |
1855 /* how far to move top row */ | 1869 /* How far to move top row. The selected tab must be on |
1856 move = nrows - tab->tabs.row ; | 1870 the bottom row of the *visible* rows. */ |
1871 move = (real_rows + 1 - display_rows) - tab->tabs.row ; | |
1872 if (move < 0) | |
1873 move = real_rows - move; | |
1857 bottom = tw->tabs.tab_total - th ; | 1874 bottom = tw->tabs.tab_total - th ; |
1858 | 1875 |
1859 for(i=tw->tabs.displayChildren, childP=tw->composite.children; | 1876 for(i=tw->composite.num_children, childP=tw->composite.children; |
1860 --i >= 0; | 1877 --i >= 0; |
1861 ++childP) | 1878 ++childP) |
1862 if( XtIsManaged(*childP) ) | 1879 if( XtIsManaged(*childP) ) |
1863 { | 1880 { |
1864 tab = (TabsConstraints) (*childP)->core.constraints ; | 1881 tab = (TabsConstraints) (*childP)->core.constraints ; |
1865 tab->tabs.row = (tab->tabs.row + move) % nrows ; | 1882 tab->tabs.row = (tab->tabs.row + move) % real_rows ; |
1866 tab->tabs.y = bottom - tab->tabs.row * th ; | 1883 tab->tabs.y = bottom - tab->tabs.row * th ; |
1884 tab->tabs.visible = (tab->tabs.row < display_rows); | |
1867 } | 1885 } |
1868 } | 1886 } |
1869 } | 1887 } |
1870 } | 1888 } |
1871 | 1889 |
1875 * as we don't want to have too many rows of tabs; we may widen | 1893 * as we don't want to have too many rows of tabs; we may widen |
1876 * the widget to reduce # of rows. | 1894 * the widget to reduce # of rows. |
1877 * | 1895 * |
1878 * This function requires that max_cw, max_ch already be set. | 1896 * This function requires that max_cw, max_ch already be set. |
1879 */ | 1897 */ |
1880 | |
1881 static int | 1898 static int |
1882 PreferredSize( | 1899 PreferredSize( |
1883 TabsWidget tw, | 1900 TabsWidget tw, |
1884 Dimension *reply_width, /* total widget size */ | 1901 Dimension *reply_width, /* total widget size */ |
1885 Dimension *reply_height, | 1902 Dimension *reply_height, |