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,