X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=lwlib%2Fxlwtabs.c;h=e58d6fabfe5abd9fdc5609819531060855f6a848;hb=4fd8920ef927db361877bb718163ecd16ecdb224;hp=32c282c925993c0eab6f81615af231c5e4c5ce08;hpb=14144012929ab5944f367d5d1b323ab8268abb05;p=chise%2Fxemacs-chise.git.1 diff --git a/lwlib/xlwtabs.c b/lwlib/xlwtabs.c index 32c282c..e58d6fa 100644 --- a/lwlib/xlwtabs.c +++ b/lwlib/xlwtabs.c @@ -1,30 +1,25 @@ /* Tabs Widget for XEmacs. Copyright (C) 1999 Edward A. Falk - + This file is part of XEmacs. - + XEmacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + XEmacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with XEmacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - /* Synched up with: Tabs.c 1.27. - - #### This file contains essential XEmacs related fixes to the original - verison of the Tabs widget. Be VERY careful about syncing if you ever - update to a more recent version. In general this is probably now a - bad idea. */ - + + /* Synched up with: Tabs.c 1.23 */ + /* * Tabs.c - Index Tabs composite widget * @@ -56,8 +51,8 @@ * the frame. */ -/* - * TODO: min child height = tab height +/* TODO: min child height = tab height + * */ #include @@ -66,8 +61,6 @@ #include #include #include - -#include "lwlib-internal.h" #include "../src/xmu.h" #include "xlwtabsP.h" #include "xlwgcs.h" @@ -129,7 +122,7 @@ static char accelTable[] = " #augment\n\ KP_Down: highlight(down) \n\ : page(select) \n\ " ; -static XtAccelerators defaultAccelerators ; /* #### Never used */ +static XtAccelerators defaultAccelerators ; #define offset(field) XtOffsetOf(TabsRec, tabs.field) static XtResource resources[] = { @@ -196,7 +189,6 @@ static void TabsExpose(); static void TabsDestroy(); static void TabsRealize(); static Boolean TabsSetValues(); -static Boolean TabsAcceptFocus(); static XtGeometryResult TabsQueryGeometry(); static XtGeometryResult TabsGeometryManager(); static void TabsChangeManaged(); @@ -245,7 +237,6 @@ static void TabsDestroy( Widget w) ; static void TabsResize( Widget w) ; static void TabsExpose( Widget w, XEvent *event, Region region) ; static Boolean TabsSetValues(Widget, Widget, Widget, ArgList, Cardinal *) ; -static Boolean TabsAcceptFocus(Widget, Time *); static Boolean TabsConstraintSetValues(Widget, Widget, Widget, ArgList, Cardinal *) ; static XtGeometryResult TabsQueryGeometry(Widget, @@ -269,17 +260,17 @@ static void DrawHighlight( TabsWidget tw, Widget child, Bool undraw) ; static void UndrawTab( TabsWidget tw, Widget child) ; static void TabWidth( Widget w) ; -static int TabLayout( TabsWidget, Dimension wid, Dimension hgt, Dimension *r_hgt, +static int TabLayout( TabsWidget, int wid, int hgt, Dimension *r_hgt, Bool query_only) ; static void GetPreferredSizes(TabsWidget) ; -static void MaxChild(TabsWidget, Widget except, Dimension, Dimension) ; +static void MaxChild(TabsWidget) ; static void TabsShuffleRows( TabsWidget tw) ; static int PreferredSize( TabsWidget, Dimension *reply_width, Dimension *reply_height, Dimension *reply_cw, Dimension *reply_ch) ; -static int PreferredSize2( TabsWidget, Dimension cw, Dimension ch, +static int PreferredSize2( TabsWidget, int cw, int ch, Dimension *rw, Dimension *rh) ; -static int PreferredSize3( TabsWidget, Dimension wid, Dimension hgt, +static int PreferredSize3( TabsWidget, int wid, int hgt, Dimension *rw, Dimension *rh) ; static void MakeSizeRequest(TabsWidget) ; @@ -334,13 +325,9 @@ TabsClassRec tabsClassRec = { /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, -#if XtSpecificationRelease < 6 - /* compress_exposure */ XtExposeCompressMaximal, -#else - /* compress_exposure */ XtExposeCompressMaximal|XtExposeNoRegion, -#endif + /* compress_exposure */ TRUE, /* compress_enterleave*/ TRUE, - /* visible_interest */ TRUE, + /* visible_interest */ FALSE, /* destroy */ TabsDestroy, /* resize */ TabsResize, /* expose */ TabsExpose, @@ -348,7 +335,7 @@ TabsClassRec tabsClassRec = { /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, - /* accept_focus */ TabsAcceptFocus, + /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ defaultTranslations, @@ -394,10 +381,21 @@ TabsClassRec tabsClassRec = { WidgetClass tabsWidgetClass = (WidgetClass)&tabsClassRec; -#define TabsNumChildren(tw) (((TabsWidget)tw)->composite.num_children) -#define TabVisible(tab) \ - (XtIsManaged(tab) && \ - ((TabsConstraints)((tab)->core.constraints))->tabs.visible) + + +#ifdef DEBUG +#ifdef __STDC__ +#define assert(e) \ + if(!(e)) fprintf(stderr,"yak! %s at %s:%d\n",#e,__FILE__,__LINE__) +#else +#define assert(e) \ + if(!(e)) fprintf(stderr,"yak! e at %s:%d\n",__FILE__,__LINE__) +#endif +#else +#define assert(e) +#endif + + /**************************************************************** @@ -426,7 +424,7 @@ TabsInit(Widget request, Widget new, ArgList args, Cardinal *num_args) TabsWidget newTw = (TabsWidget)new; newTw->tabs.numRows = 0 ; - newTw->tabs.realRows = 0; + newTw->tabs.displayChildren = 0; GetPreferredSizes(newTw) ; @@ -462,7 +460,7 @@ TabsInit(Widget request, Widget new, ArgList args, Cardinal *num_args) newTw->tabs.grey50 = None ; newTw->tabs.needs_layout = False ; - + newTw->tabs.hilight = NULL ; #ifdef NEED_MOTIF @@ -482,7 +480,7 @@ TabsConstraintInitialize(Widget request, Widget new, { TabsConstraints tab = (TabsConstraints) new->core.constraints ; tab->tabs.greyAlloc = False ; /* defer allocation of pixel */ - tab->tabs.visible = False ; + tab->tabs.queried = False ; /* defer size query */ getBitmapInfo((TabsWidget)XtParent(new), tab) ; TabWidth(new) ; @@ -527,7 +525,7 @@ TabsResize(Widget w) int i ; int num_children = tw->composite.num_children ; Widget *childP ; - TabsConstraints tab ; /* #### unused */ + TabsConstraints tab ; Dimension cw,ch,bw ; /* Our size has now been dictated by the parent. Lay out the @@ -541,13 +539,11 @@ TabsResize(Widget w) * to the bottom row. */ - tw->tabs.needs_layout = False ; - if( num_children > 0 && tw->composite.children != NULL ) { /* Loop through the tabs and assign rows & x positions */ (void) TabLayout(tw, tw->core.width, tw->core.height, NULL, False) ; - num_children = TabsNumChildren (tw); + num_children = tw->tabs.displayChildren; /* assign a top widget, bring it to bottom row. */ TabsShuffleRows(tw) ; @@ -558,29 +554,24 @@ TabsResize(Widget w) tw->tabs.child_width = cw = tw->core.width - 2 * SHADWID ; tw->tabs.child_height = ch = - tw->core.height < (tw->tabs.tab_total + 2 * SHADWID) ? 0 : - tw->core.height - tw->tabs.tab_total - 2 * SHADWID ; + tw->core.height - tw->tabs.tab_total - 2 * SHADWID ; + for(i=0, childP=tw->composite.children; - i < num_children; + i < num_children; ++i, ++childP) if( XtIsManaged(*childP) ) { tab = (TabsConstraints) (*childP)->core.constraints ; - bw = (*childP)->core.border_width ; - /* Don't do anything if we can't see any of the child. */ - if (ch >= bw*2 && ch > 0 && cw >= bw*2 && cw > 0) - XtConfigureWidget(*childP, SHADWID,tw->tabs.tab_total+SHADWID, - cw-bw*2,ch-bw*2, bw) ; + bw = tab->tabs.bwid ; + XtConfigureWidget(*childP, SHADWID,tw->tabs.tab_total+SHADWID, + cw-bw*2,ch-bw*2, bw) ; } - if( XtIsRealized(w) ) { + if( XtIsRealized(w) ) XClearWindow(XtDisplay((Widget)tw), XtWindow((Widget)tw)) ; - /* should not be necessary to explicitly repaint after a - * resize, but XEmacs folks tell me it is. - */ - XtClass(tw)->core_class.expose((Widget)tw,NULL,None) ; - } } + + tw->tabs.needs_layout = False ; } /* Resize */ @@ -638,8 +629,7 @@ TabsSetValues(Widget current, Widget request, Widget new, /* TODO: if any color changes, need to recompute GCs and redraw */ if( tw->core.background_pixel != curtw->core.background_pixel || - tw->core.background_pixmap != curtw->core.background_pixmap || - tw->tabs.font != curtw->tabs.font ) + tw->core.background_pixmap != curtw->core.background_pixmap ) if( XtIsRealized(new) ) { TabsFreeGCs(tw) ; @@ -655,7 +645,6 @@ TabsSetValues(Widget current, Widget request, Widget new, */ if( tw->tabs.topWidget != curtw->tabs.topWidget ) - { if( XtIsRealized(tw->tabs.topWidget) ) { Widget w = tw->tabs.topWidget ; @@ -674,7 +663,6 @@ TabsSetValues(Widget current, Widget request, Widget new, } else tw->tabs.needs_layout = True ; - } return needRedraw ; } @@ -736,27 +724,11 @@ TabsConstraintSetValues(Widget current, Widget request, Widget new, } -static Boolean -TabsAcceptFocus(Widget w, Time *t) -{ - if( !w->core.being_destroyed && XtIsRealized(w) && - XtIsSensitive(w) && XtIsManaged(w) && w->core.visible ) - { - Widget p ; - for(p = XtParent(w); !XtIsShell(p); p = XtParent(p)) ; - XtSetKeyboardFocus(p,w) ; - return True ; - } - else - return False ; -} - - /* * Return preferred size. Happily accept anything >= our preferred size. * (TODO: is that the right thing to do? Should we always return "almost" - * if offered more than we need?) + * if offerred more than we need?) */ static XtGeometryResult @@ -773,9 +745,11 @@ TabsQueryGeometry(Widget w, (!(mode & CWHeight) || intended->height == w->core.height) ) return XtGeometryNo ; +#ifdef COMMENT if( (!(mode & CWWidth) || intended->width >= preferred->width) && (!(mode & CWHeight) || intended->height >= preferred->height) ) return XtGeometryYes; +#endif /* COMMENT */ return XtGeometryAlmost; } @@ -793,7 +767,6 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) Dimension s = SHADWID ; TabsConstraints tab = (TabsConstraints)w->core.constraints; XtGeometryResult result ; - Dimension rw, rh ; /* Position request always denied */ @@ -815,11 +788,11 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) req->border_width == w->core.border_width ) return XtGeometryNo ; - rw = req->width + 2 * req->border_width ; - rh = req->height + 2 * req->border_width ; - - /* find out how big the children want to be now */ - MaxChild(tw, w, rw, rh) ; + /* updated cached preferred size of the child */ + tab->tabs.bwid = req->border_width ; + tab->tabs.wid = req->width + req->border_width * 2 ; + tab->tabs.hgt = req->height + req->border_width * 2 ; + MaxChild(tw) ; /* Size changes must see if the new size can be accommodated. @@ -827,9 +800,7 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) * size. A request to shrink will be accepted only if the * new size is still big enough for all other children. A * request to shrink that is not big enough for all children - * returns an "almost" response with the new proposed size - * or a "no" response if unable to shrink at all. - * + * returns an "almost" response with the new proposed size. * A request to grow will be accepted only if the Tabs parent can * grow to accommodate. * @@ -841,19 +812,23 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) if (req->request_mode & (CWWidth | CWHeight | CWBorderWidth)) { + Dimension rw,rh ; /* child's requested width, height */ Dimension cw,ch ; /* children's preferred size */ Dimension aw,ah ; /* available size we can give child */ Dimension th ; /* space used by tabs */ Dimension wid,hgt ; /* Tabs widget size */ - cw = tw->tabs.max_cw ; - ch = tw->tabs.max_ch ; + rw = tab->tabs.wid ; + rh = tab->tabs.hgt ; - /* find out what *my* resulting preferred size would be */ + /* find out what the resulting preferred size would be */ - PreferredSize2(tw, cw, ch, &wid, &hgt) ; +#ifdef COMMENT + MaxChild(tw, &cw, &ch) ; +#endif /* COMMENT */ + PreferredSize2(tw, tw->tabs.max_cw,tw->tabs.max_ch, &wid, &hgt) ; - /* Would my size change? If so, ask to be resized. */ + /* Ask to be resized to accommodate. */ if( wid != tw->core.width || hgt != tw->core.height ) { @@ -863,8 +838,7 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) myrequest.width = wid ; myrequest.height = hgt ; myrequest.request_mode = CWWidth | CWHeight ; - - assert (wid > 0 && hgt > 0); + /* If child is only querying, or if we're going to have to * offer the child a compromise, then make this a query only. */ @@ -874,7 +848,7 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) result = XtMakeGeometryRequest((Widget)tw, &myrequest, &myreply) ; - /* !$@# Athena Box widget changes the core size even if QueryOnly + /* !$@# Box widget changes the core size even if QueryOnly * is set. I'm convinced this is a bug. At any rate, to work * around the bug, we need to restore the core size after every * query geometry request. This is only partly effective, @@ -892,7 +866,6 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) switch( result ) { case XtGeometryYes: case XtGeometryDone: - tw->tabs.needs_layout = True ; break ; case XtGeometryNo: @@ -903,8 +876,6 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) case XtGeometryAlmost: wid = myreply.width ; hgt = myreply.height ; - tw->tabs.needs_layout = True ; - break ; } } @@ -932,8 +903,8 @@ TabsGeometryManager(Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply) Widget *childP = tw->composite.children ; int i,bw ; w->core.border_width = req->border_width ; - for(i=TabsNumChildren (tw); --i >= 0; ++childP) - if( TabVisible(*childP) ) + for(i=tw->tabs.displayChildren; --i >= 0; ++childP) + if( XtIsManaged(*childP) ) { bw = (*childP)->core.border_width ; XtConfigureWidget(*childP, s,tw->tabs.tab_total+s, @@ -980,12 +951,6 @@ TabsChangeManaged(Widget w) tw->tabs.topWidget->core.being_destroyed ) ) tw->tabs.topWidget = NULL ; - /* Check whether the highlight tab is still valid. */ - if( tw->tabs.hilight != NULL && - ( !XtIsManaged(tw->tabs.hilight) || - tw->tabs.hilight->core.being_destroyed ) ) - tw->tabs.hilight = NULL ; - GetPreferredSizes(tw) ; MakeSizeRequest(tw) ; @@ -1001,7 +966,7 @@ TabsChangeManaged(Widget w) */ if( tw->tabs.topWidget != NULL && XtIsRealized(tw->tabs.topWidget) ) { - for(i=TabsNumChildren (tw); --i >= 0; ++childP) + for(i=tw->tabs.displayChildren; --i >= 0; ++childP) if( !XtIsRealized(*childP) ) XtRealizeWidget(*childP) ; @@ -1022,6 +987,9 @@ TabsChangeManaged(Widget w) if( tw->tabs.topWidget != NULL ) XtVaSetValues(tw->tabs.topWidget, XmNtraversalOn, True, 0) ; #endif + + + } @@ -1066,9 +1034,9 @@ TabsSelect(Widget w, XEvent *event, String *params, Cardinal *num_params) * widget to be top of stacking order with XawTabsSetTop(). */ for(i=0, childP=tw->composite.children; - i < TabsNumChildren (tw); + i < tw->tabs.displayChildren; ++i, ++childP) - if( TabVisible(*childP) ) + if( XtIsManaged(*childP) ) { TabsConstraints tab = (TabsConstraints)(*childP)->core.constraints; if( x > tab->tabs.x && x < tab->tabs.x + tab->tabs.width && @@ -1089,10 +1057,11 @@ static void TabsPage(Widget w, XEvent *event, String *params, Cardinal *num_params) { TabsWidget tw = (TabsWidget) w ; - Widget newtop = NULL; + Widget newtop ; Widget *childP ; int idx ; - int nc = TabsNumChildren (tw) ; + int i ; + int nc = tw->composite.num_children ; if( nc <= 0 ) return ; @@ -1113,9 +1082,9 @@ TabsPage(Widget w, XEvent *event, String *params, Cardinal *num_params) switch( params[0][0] ) { case 'u': /* up */ case 'U': - if( --idx < 0 ) - idx = nc-1 ; - newtop = tw->composite.children[idx] ; + if( idx == 0 ) + idx = nc ; + newtop = tw->composite.children[idx-1] ; break ; case 'd': /* down */ @@ -1127,7 +1096,6 @@ TabsPage(Widget w, XEvent *event, String *params, Cardinal *num_params) case 'h': case 'H': - default: newtop = tw->composite.children[0] ; break ; @@ -1153,10 +1121,11 @@ static void TabsHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) { TabsWidget tw = (TabsWidget) w ; - Widget newhl = NULL; + Widget newhl ; Widget *childP ; int idx ; - int nc = TabsNumChildren (tw) ; + int i ; + int nc = tw->composite.num_children ; if( nc <= 0 ) return ; @@ -1173,7 +1142,6 @@ TabsHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) else { - /* find index of currently highlit child */ for(idx=0, childP=tw->composite.children; idx < nc; ++idx, ++childP ) if( tw->tabs.hilight == *childP ) break ; @@ -1181,9 +1149,9 @@ TabsHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) switch( params[0][0] ) { case 'u': /* up */ case 'U': - if( --idx < 0 ) - idx = nc-1 ; - newhl = tw->composite.children[idx] ; + if( idx == 0 ) + idx = nc ; + newhl = tw->composite.children[idx-1] ; break ; case 'd': /* down */ @@ -1202,10 +1170,6 @@ TabsHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) case 'E': newhl = tw->composite.children[nc-1] ; break ; - - default: - newhl = tw->tabs.hilight ; - break ; } } @@ -1248,20 +1212,19 @@ XawTabsSetTop(Widget w, Bool callCallbacks) if( !XtIsSubclass(w->core.parent, tabsWidgetClass) ) { - char line[256] ; - sprintf(line, "XawTabsSetTop: widget \"%.64s\" is not the child of a tabs widget.", XtName(w)) ; + char line[1024] ; + sprintf(line, "XawTabsSetTop: widget \"%s\" is not the child of a tabs widget.", XtName(w)) ; XtAppWarning(XtWidgetToApplicationContext(w), line) ; return ; } if( callCallbacks ) XtCallCallbackList(w, tw->tabs.popdownCallbacks, - (XtPointer)tw->tabs.topWidget) ; + (XtPointer)tw->tabs.topWidget) ; if( !XtIsRealized(w) ) { tw->tabs.topWidget = w ; tw->tabs.needs_layout = True ; - tw->tabs.hilight = NULL; /* The highlight tab might disappear. */ return ; } @@ -1272,14 +1235,6 @@ XawTabsSetTop(Widget w, Bool callCallbacks) #endif tab = (TabsConstraints) w->core.constraints ; - - /* Unhighlight before we start messing with the stacking order. */ - if( tw->tabs.hilight != NULL ) - { - DrawHighlight(tw, tw->tabs.hilight, True) ; - tw->tabs.hilight = NULL; - } - if( tab->tabs.row == 0 ) { /* Easy case; undraw current top, undraw new top, assign new @@ -1316,12 +1271,16 @@ void XawTabsSetHighlight(Widget t, Widget w) { TabsWidget tw = (TabsWidget)t ; + TabsConstraints tab ; + Widget oldtop = tw->tabs.topWidget ; if( !XtIsSubclass(t, tabsWidgetClass) ) return ; if( XtIsRealized(t) && w != tw->tabs.hilight ) { + if( tw->tabs.hilight != NULL ) + DrawHighlight(tw, tw->tabs.hilight, True) ; if( w != NULL ) DrawHighlight(tw, w, False) ; } @@ -1385,7 +1344,7 @@ DrawTabs(TabsWidget tw, Bool labels) if( !XtIsRealized((Widget)tw)) return ; - + /* draw tabs and frames by row except for the top tab, which * is drawn last. (This is inefficiently written, but should not * be too slow as long as there are not a lot of rows.) @@ -1394,9 +1353,9 @@ DrawTabs(TabsWidget tw, Bool labels) y = tw->tabs.numRows == 1 ? TABDELTA : 0 ; for(i=0; itabs.numRows; ++i, y += th) { - for( j=TabsNumChildren (tw), childP=tw->composite.children; + for( j=tw->tabs.displayChildren, childP=tw->composite.children; --j >= 0; ++childP ) - if( TabVisible(*childP) ) + if( XtIsManaged(*childP) ) { tab = (TabsConstraints)(*childP)->core.constraints; if( tab->tabs.row == i && *childP != tw->tabs.topWidget ) @@ -1468,11 +1427,11 @@ DrawTab(TabsWidget tw, Widget child, Bool labels) { if( tab->tabs.lbm_depth == 1 ) XCopyPlane(dpy, tab->tabs.left_bitmap, win,gc, - 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, + 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, x+tab->tabs.lbm_x, y+tab->tabs.lbm_y, 1L) ; else XCopyArea(dpy, tab->tabs.left_bitmap, win,gc, - 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, + 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, x+tab->tabs.lbm_x, y+tab->tabs.lbm_y) ; } @@ -1496,26 +1455,8 @@ DrawFrame(TabsWidget tw) GC botgc = tw->tabs.botGC ; Dimension s = SHADWID ; Dimension ch = tw->tabs.child_height ; - if (ch > 0) - Draw3dBox((Widget)tw, 0,tw->tabs.tab_total, - tw->core.width, ch+2*s, s, topgc, botgc) ; - else - { - Widget w = tw->tabs.topWidget ; - if (w != NULL) - { - TabsConstraints tab = (TabsConstraints) w->core.constraints ; - Draw3dBox((Widget)tw, 0,tw->core.height - 2*s, - tab->tabs.x, 2*s, s, topgc, botgc); - Draw3dBox((Widget)tw, tab->tabs.x + tab->tabs.width, - tw->core.height - 2*s, - tw->core.width - tab->tabs.x - tab->tabs.width, 2*s, s, - topgc, botgc); - } - else - Draw3dBox((Widget)tw, 0,tw->core.height - 2*s, - tw->core.width, 2*s, s, topgc, botgc) ; - } + Draw3dBox((Widget)tw, 0,tw->tabs.tab_total, + tw->core.width, ch+2*s, s, topgc, botgc) ; } @@ -1649,27 +1590,8 @@ UndrawTab(TabsWidget tw, Widget child) /* GEOMETRY UTILITIES */ - /* Overview: - * - * MaxChild(): ask all children (except possibly one) their - * preferred sizes, set max_cw, max_ch accordingly. - * - * GetPreferredSizes(): ask all children their preferred sizes, - * set max_cw, max_ch accordingly. - * - * PreferredSize(): given max_cw, max_ch, return tabs widget - * preferred size. Iterate with other widths in order to get - * a reasonable aspect ratio. - * - * PreferredSize2(): Given child dimensions, return Tabs - * widget dimensions. - * - * PreferredSize3(): Same, except given child dimensions plus - * shadow. - */ - - /* Compute the width of one child's tab. Positions will be computed + /* Compute the size of one child's tab. Positions will be computed * elsewhere. * * height: font height + vertical_space*2 + shadowWid*2 @@ -1702,7 +1624,7 @@ TabWidth(Widget w) { tab->tabs.width += XTextWidth( font, lbl, (int)strlen(lbl) ) + iw ; tab->tabs.l_y = (tw->tabs.tab_height + - tw->tabs.font->max_bounds.ascent - + tw->tabs.font->max_bounds.ascent - tw->tabs.font->max_bounds.descent)/2 ; } } @@ -1721,18 +1643,18 @@ TabWidth(Widget w) */ static int -TabLayout(TabsWidget tw, - Dimension wid, - Dimension hgt, - Dimension *reply_height, Bool query_only) +TabLayout(TabsWidget tw, int wid, int hgt, Dimension *reply_height, Bool query_only) { - int i, row, done = 0, display_rows = 0 ; + int i, row ; int num_children = tw->composite.num_children ; Widget *childP ; Dimension w ; Position x,y ; TabsConstraints tab ; + if (!query_only) + tw->tabs.displayChildren = 0; + /* Algorithm: loop through children, assign X positions. If a tab * would extend beyond the right edge, start a new row. After all * rows are assigned, make a second pass and assign Y positions. @@ -1751,14 +1673,10 @@ TabLayout(TabsWidget tw, { tab = (TabsConstraints) (*childP)->core.constraints ; w = tab->tabs.width ; - if( x + w > wid ) { /* new row */ - if (y + tw->tabs.tab_height > hgt && !done) - { - display_rows = row; - done = 1; - } - ++row; + if (y + tw->tabs.tab_height > hgt) + break; + ++row ; x = INDENT ; y += tw->tabs.tab_height ; } @@ -1768,14 +1686,12 @@ TabLayout(TabsWidget tw, tab->tabs.row = row ; } x += w + SPACING ; - if (!query_only && !done) - tab->tabs.visible = 1; - + if (!query_only) + tw->tabs.displayChildren++; } - /* If there was only one row, increase the height by TABDELTA */ - if( ++display_rows == 1 ) + /* If there was only one row, increse the height by TABDELTA */ + if( ++row == 1 ) { - row++; y = TABDELTA ; if( !query_only ) for(i=num_children, childP=tw->composite.children; @@ -1789,51 +1705,75 @@ TabLayout(TabsWidget tw, y += tw->tabs.tab_height ; } else - display_rows = row = y = 0 ; + row = y = 0 ; if( !query_only ) { tw->tabs.tab_total = y ; - tw->tabs.numRows = display_rows ; - tw->tabs.realRows = row; + tw->tabs.numRows = row ; } if( reply_height != NULL ) *reply_height = y ; - return display_rows ; + return row ; } /* Find max preferred child size. Returned sizes include child - * border widths. + * border widths. We only ever ask a child its preferred + * size once. After that, the preferred size is updated only + * if the child makes a geometry request. */ static void GetPreferredSizes(TabsWidget tw) { - MaxChild(tw, NULL, 0,0) ; + int i ; + Widget *childP = tw->composite.children ; + XtWidgetGeometry preferred ; + TabsConstraints tab ; + Dimension cw = 0, ch = 0 ; + + for(i=tw->tabs.displayChildren; --i >= 0; ++childP) + if( XtIsManaged(*childP) ) + { + tab = (TabsConstraints) (*childP)->core.constraints ; + if( !tab->tabs.queried ) { + (void) XtQueryGeometry(*childP, NULL, &preferred) ; + tab->tabs.bwid = preferred.border_width ; + tab->tabs.wid = preferred.width + preferred.border_width * 2 ; + tab->tabs.hgt = preferred.height + preferred.border_width * 2 ; + tab->tabs.queried = True ; + } + cw = Max(cw, tab->tabs.wid ) ; + ch = Max(ch, tab->tabs.hgt ) ; + } + tw->tabs.max_cw = cw ; + tw->tabs.max_ch = ch ; } /* Find max preferred child size. Returned sizes include child - * border widths. If except is non-null, don't ask that one. - */ + * border widths. */ static void -MaxChild(TabsWidget tw, Widget except, Dimension cw, Dimension ch) +MaxChild(TabsWidget tw) { - int i ; - Widget *childP = tw->composite.children ; - XtWidgetGeometry preferred ; + Dimension cw,ch ; /* child width, height */ + int i ; + Widget *childP = tw->composite.children ; + TabsConstraints tab ; + + cw = ch = 0 ; for(i=tw->composite.num_children; --i >=0; ++childP) - if( TabVisible (*childP) /*XtIsManaged(*childP)*/ && *childP != except ) + if( XtIsManaged(*childP) ) { - (void) XtQueryGeometry(*childP, NULL, &preferred) ; - cw = Max(cw, preferred.width + preferred.border_width * 2 ) ; - ch = Max(ch, preferred.height + preferred.border_width * 2 ) ; + tab = (TabsConstraints) (*childP)->core.constraints ; + cw = Max(cw, tab->tabs.wid ) ; + ch = Max(ch, tab->tabs.hgt ) ; } tw->tabs.max_cw = cw ; @@ -1851,7 +1791,7 @@ TabsShuffleRows(TabsWidget tw) { TabsConstraints tab ; int move ; - int real_rows, display_rows ; + int nrows ; Widget *childP ; Dimension th = tw->tabs.tab_height ; Position bottom ; @@ -1859,7 +1799,7 @@ TabsShuffleRows(TabsWidget tw) /* There must be a top widget. If not, assign one. */ if( tw->tabs.topWidget == NULL && tw->composite.children != NULL ) - for(i=TabsNumChildren (tw), childP=tw->composite.children; + for(i=tw->composite.num_children, childP=tw->composite.children; --i >= 0; ++childP) if( XtIsManaged(*childP) ) { @@ -1869,44 +1809,38 @@ TabsShuffleRows(TabsWidget tw) if( tw->tabs.topWidget != NULL ) { - display_rows = tw->tabs.numRows ; - real_rows = tw->tabs.realRows ; - assert( display_rows <= real_rows ) ; + nrows = tw->tabs.numRows ; + assert( nrows > 0 ) ; - if( real_rows > 1 ) + if( nrows > 1 ) { tab = (TabsConstraints) tw->tabs.topWidget->core.constraints ; assert( tab != NULL ) ; - /* How far to move top row. The selected tab must be on - the bottom row of the *visible* rows. */ - move = (real_rows + 1 - display_rows) - tab->tabs.row ; - if (move < 0) - move = real_rows - move; + /* how far to move top row */ + move = nrows - tab->tabs.row ; bottom = tw->tabs.tab_total - th ; - for(i=tw->composite.num_children, childP=tw->composite.children; + for(i=tw->tabs.displayChildren, childP=tw->composite.children; --i >= 0; ++childP) if( XtIsManaged(*childP) ) { tab = (TabsConstraints) (*childP)->core.constraints ; - tab->tabs.row = (tab->tabs.row + move) % real_rows ; + tab->tabs.row = (tab->tabs.row + move) % nrows ; tab->tabs.y = bottom - tab->tabs.row * th ; - tab->tabs.visible = (tab->tabs.row < display_rows); } } } } - /* Find preferred size. Ask children, find size of largest, + /* find preferred size. Ask children, find size of largest, * add room for tabs & return. This can get a little involved, * as we don't want to have too many rows of tabs; we may widen * the widget to reduce # of rows. - * - * This function requires that max_cw, max_ch already be set. */ + static int PreferredSize( TabsWidget tw, @@ -1920,6 +1854,12 @@ PreferredSize( Dimension rwid,rhgt ; int nrow ; + + /* find max desired child height */ +#ifdef COMMENT + MaxChild(tw, &cw, &ch) ; +#endif /* COMMENT */ + wid = cw = tw->tabs.max_cw ; hgt = ch = tw->tabs.max_ch ; @@ -1933,7 +1873,6 @@ PreferredSize( if( nrow > 2 && rhgt > rwid ) { Dimension w0, w1 ; - int maxloop = 20 ; /* step 1: start doubling size until it's too big */ do { @@ -1946,7 +1885,7 @@ PreferredSize( /* step 2: use Newton's method to find ideal size. Stop within * 8 pixels. */ - while( --maxloop > 0 && w1 > w0 + 8 ) + while( w1 > w0 + 8 ) { wid = (w0+w1)/2 ; nrow = PreferredSize2(tw, wid,hgt, &rwid,&rhgt) ; @@ -1971,22 +1910,18 @@ PreferredSize( static int PreferredSize2( TabsWidget tw, - Dimension cw, /* child width, height */ - Dimension ch, + int cw, /* child width, height */ + int ch, Dimension *reply_width, /* total widget size */ Dimension *reply_height) { Dimension s = SHADWID ; - int ret; /* make room for shadow frame */ cw += s*2 ; ch += s*2 ; - ret = PreferredSize3(tw, cw, ch, reply_width, reply_height) ; - - assert (*reply_width > 0 && *reply_height > 0); - return ret; + return PreferredSize3(tw, cw, ch, reply_width, reply_height) ; } @@ -1995,8 +1930,8 @@ PreferredSize2( static int PreferredSize3( TabsWidget tw, - Dimension wid, /* child width, height */ - Dimension hgt, + int wid, /* child width, height */ + int hgt, Dimension *reply_width, /* total widget size */ Dimension *reply_height) { @@ -2068,7 +2003,7 @@ getBitmapInfo(TabsWidget tw, TabsConstraints tab) if( tab->tabs.left_bitmap == None || !XGetGeometry(XtDisplay(tw), tab->tabs.left_bitmap, &root, &x, &y, - &tab->tabs.lbm_width, &tab->tabs.lbm_height, + &tab->tabs.lbm_width, &tab->tabs.lbm_height, &bw, &tab->tabs.lbm_depth) ) tab->tabs.lbm_width = tab->tabs.lbm_height = 0 ; }