the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
- /* Synched up with: Tabs.c 1.27 */
+ /* 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. */
/*
* Tabs.c - Index Tabs composite widget
#include <X11/Xlib.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
+
+#include "lwlib-internal.h"
#include "../src/xmu.h"
#include "xlwtabsP.h"
#include "xlwgcs.h"
<Key>KP_Down: highlight(down) \n\
<Key> : page(select) \n\
" ;
-static XtAccelerators defaultAccelerators ;
+static XtAccelerators defaultAccelerators ; /* #### Never used */
#define offset(field) XtOffsetOf(TabsRec, tabs.field)
static XtResource resources[] = {
XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate, (XtPointer)0},
{XtNtopWidget, XtCTopWidget, XtRWidget, sizeof(Widget),
offset(topWidget), XtRImmediate, NULL},
+ {XtNhighlightWidget, XtCHighlightWidget, XtRWidget, sizeof(Widget),
+ offset(hilight), XtRImmediate, NULL},
{XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
offset(callbacks), XtRCallback, NULL},
{XtNpopdownCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
static void UndrawTab( TabsWidget tw, Widget child) ;
static void TabWidth( Widget w) ;
-static int TabLayout( TabsWidget, int wid, int hgt, Dimension *r_hgt,
+static int TabLayout( TabsWidget, Dimension wid, Dimension hgt, Dimension *r_hgt,
Bool query_only) ;
static void GetPreferredSizes(TabsWidget) ;
static void MaxChild(TabsWidget, Widget except, Dimension, Dimension) ;
static int PreferredSize( TabsWidget,
Dimension *reply_width, Dimension *reply_height,
Dimension *reply_cw, Dimension *reply_ch) ;
-static int PreferredSize2( TabsWidget, int cw, int ch,
+static int PreferredSize2( TabsWidget, Dimension cw, Dimension ch,
Dimension *rw, Dimension *rh) ;
-static int PreferredSize3( TabsWidget, int wid, int hgt,
+static int PreferredSize3( TabsWidget, Dimension wid, Dimension hgt,
Dimension *rw, Dimension *rh) ;
static void MakeSizeRequest(TabsWidget) ;
WidgetClass tabsWidgetClass = (WidgetClass)&tabsClassRec;
-
-
-#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
-
-
+#define TabsNumChildren(tw) (((TabsWidget)tw)->composite.num_children)
+#define TabVisible(tab) \
+ (XtIsManaged(tab) && \
+ ((TabsConstraints)((tab)->core.constraints))->tabs.visible)
\f
/****************************************************************
TabsWidget newTw = (TabsWidget)new;
newTw->tabs.numRows = 0 ;
- newTw->tabs.displayChildren = 0;
+ newTw->tabs.realRows = 0;
GetPreferredSizes(newTw) ;
{
TabsConstraints tab = (TabsConstraints) new->core.constraints ;
tab->tabs.greyAlloc = False ; /* defer allocation of pixel */
+ tab->tabs.visible = False ;
getBitmapInfo((TabsWidget)XtParent(new), tab) ;
TabWidth(new) ;
int i ;
int num_children = tw->composite.num_children ;
Widget *childP ;
- TabsConstraints tab ;
+ TabsConstraints tab ; /* #### unused */
Dimension cw,ch,bw ;
/* Our size has now been dictated by the parent. Lay out the
{
/* Loop through the tabs and assign rows & x positions */
(void) TabLayout(tw, tw->core.width, tw->core.height, NULL, False) ;
- num_children = tw->tabs.displayChildren;
+ num_children = TabsNumChildren (tw);
/* assign a top widget, bring it to bottom row. */
TabsShuffleRows(tw) ;
tw->tabs.child_width = cw = tw->core.width - 2 * SHADWID ;
tw->tabs.child_height = ch =
- tw->core.height - tw->tabs.tab_total - 2 * SHADWID ;
-
+ tw->core.height < (tw->tabs.tab_total + 2 * SHADWID) ? 0 :
+ tw->core.height - tw->tabs.tab_total - 2 * SHADWID ;
for(i=0, childP=tw->composite.children;
i < num_children;
{
tab = (TabsConstraints) (*childP)->core.constraints ;
bw = (*childP)->core.border_width ;
- XtConfigureWidget(*childP, SHADWID,tw->tabs.tab_total+SHADWID,
- cw-bw*2,ch-bw*2, bw) ;
+ /* 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) ;
}
if( XtIsRealized(w) ) {
XClearWindow(XtDisplay((Widget)tw), XtWindow((Widget)tw)) ;
if( tw->core.sensitive != curtw->core.sensitive )
needRedraw = True ;
+ /* Highlit widget changed */
+ if ( tw->tabs.hilight != curtw->tabs.hilight )
+ {
+ needRedraw = True ;
+ }
+
/* If top widget changes, need to change stacking order, redraw tabs.
* Window system will handle the redraws.
*/
if( tab->tabs.row != tw->tabs.numRows-1 )
TabsShuffleRows(tw) ;
+
needRedraw = True ;
}
else
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.
*/
Widget *childP = tw->composite.children ;
int i,bw ;
w->core.border_width = req->border_width ;
- for(i=tw->tabs.displayChildren; --i >= 0; ++childP)
- if( XtIsManaged(*childP) )
+ for(i=TabsNumChildren (tw); --i >= 0; ++childP)
+ if( TabVisible(*childP) )
{
bw = (*childP)->core.border_width ;
XtConfigureWidget(*childP, s,tw->tabs.tab_total+s,
*/
if( tw->tabs.topWidget != NULL && XtIsRealized(tw->tabs.topWidget) )
{
- for(i=tw->tabs.displayChildren; --i >= 0; ++childP)
+ for(i=TabsNumChildren (tw); --i >= 0; ++childP)
if( !XtIsRealized(*childP) )
XtRealizeWidget(*childP) ;
* widget to be top of stacking order with XawTabsSetTop().
*/
for(i=0, childP=tw->composite.children;
- i < tw->tabs.displayChildren;
+ i < TabsNumChildren (tw);
++i, ++childP)
- if( XtIsManaged(*childP) )
+ if( TabVisible(*childP) )
{
TabsConstraints tab = (TabsConstraints)(*childP)->core.constraints;
if( x > tab->tabs.x && x < tab->tabs.x + tab->tabs.width &&
Widget newtop = NULL;
Widget *childP ;
int idx ;
- int nc = tw->tabs.displayChildren ;
+ int nc = TabsNumChildren (tw) ;
if( nc <= 0 )
return ;
Widget newhl = NULL;
Widget *childP ;
int idx ;
- int nc = tw->tabs.displayChildren ;
+ int nc = TabsNumChildren (tw) ;
if( nc <= 0 )
return ;
y = tw->tabs.numRows == 1 ? TABDELTA : 0 ;
for(i=0; i<tw->tabs.numRows; ++i, y += th)
{
- for( j=tw->tabs.displayChildren, childP=tw->composite.children;
+ for( j=TabsNumChildren (tw), childP=tw->composite.children;
--j >= 0; ++childP )
- if( XtIsManaged(*childP) )
+ if( TabVisible(*childP) )
{
tab = (TabsConstraints)(*childP)->core.constraints;
if( tab->tabs.row == i && *childP != tw->tabs.topWidget )
GC botgc = tw->tabs.botGC ;
Dimension s = SHADWID ;
Dimension ch = tw->tabs.child_height ;
- Draw3dBox((Widget)tw, 0,tw->tabs.tab_total,
- tw->core.width, ch+2*s, s, topgc, botgc) ;
+ 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) ;
+ }
}
*/
static int
-TabLayout(TabsWidget tw, int wid, int hgt, Dimension *reply_height, Bool query_only)
+TabLayout(TabsWidget tw,
+ Dimension wid,
+ Dimension hgt,
+ Dimension *reply_height, Bool query_only)
{
- int i, row ;
+ int i, row, done = 0, display_rows = 0 ;
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.
{
tab = (TabsConstraints) (*childP)->core.constraints ;
w = tab->tabs.width ;
+
if( x + w > wid ) { /* new row */
- if (y + tw->tabs.tab_height > hgt)
- break;
- ++row ;
+ if (y + tw->tabs.tab_height > hgt && !done)
+ {
+ display_rows = row;
+ done = 1;
+ }
+ ++row;
x = INDENT ;
y += tw->tabs.tab_height ;
}
tab->tabs.row = row ;
}
x += w + SPACING ;
- if (!query_only)
- tw->tabs.displayChildren++;
+ if (!query_only && !done)
+ tab->tabs.visible = 1;
+
}
/* If there was only one row, increase the height by TABDELTA */
- if( ++row == 1 )
+ if( ++display_rows == 1 )
{
+ row++;
y = TABDELTA ;
if( !query_only )
for(i=num_children, childP=tw->composite.children;
y += tw->tabs.tab_height ;
}
else
- row = y = 0 ;
+ display_rows = row = y = 0 ;
if( !query_only ) {
tw->tabs.tab_total = y ;
- tw->tabs.numRows = row ;
+ tw->tabs.numRows = display_rows ;
+ tw->tabs.realRows = row;
}
if( reply_height != NULL )
*reply_height = y ;
- return row ;
+ return display_rows ;
}
XtWidgetGeometry preferred ;
for(i=tw->composite.num_children; --i >=0; ++childP)
- if( XtIsManaged(*childP) && *childP != except )
+ if( TabVisible (*childP) /*XtIsManaged(*childP)*/ && *childP != except )
{
(void) XtQueryGeometry(*childP, NULL, &preferred) ;
cw = Max(cw, preferred.width + preferred.border_width * 2 ) ;
{
TabsConstraints tab ;
int move ;
- int nrows ;
+ int real_rows, display_rows ;
Widget *childP ;
Dimension th = tw->tabs.tab_height ;
Position bottom ;
/* There must be a top widget. If not, assign one. */
if( tw->tabs.topWidget == NULL && tw->composite.children != NULL )
- for(i=tw->composite.num_children, childP=tw->composite.children;
+ for(i=TabsNumChildren (tw), childP=tw->composite.children;
--i >= 0;
++childP)
if( XtIsManaged(*childP) ) {
if( tw->tabs.topWidget != NULL )
{
- nrows = tw->tabs.numRows ;
- assert( nrows > 0 ) ;
+ display_rows = tw->tabs.numRows ;
+ real_rows = tw->tabs.realRows ;
+ assert( display_rows <= real_rows ) ;
- if( nrows > 1 )
+ if( real_rows > 1 )
{
tab = (TabsConstraints) tw->tabs.topWidget->core.constraints ;
assert( tab != NULL ) ;
- /* how far to move top row */
- move = nrows - tab->tabs.row ;
+ /* 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;
bottom = tw->tabs.tab_total - th ;
- for(i=tw->tabs.displayChildren, childP=tw->composite.children;
+ for(i=tw->composite.num_children, childP=tw->composite.children;
--i >= 0;
++childP)
if( XtIsManaged(*childP) )
{
tab = (TabsConstraints) (*childP)->core.constraints ;
- tab->tabs.row = (tab->tabs.row + move) % nrows ;
+ tab->tabs.row = (tab->tabs.row + move) % real_rows ;
tab->tabs.y = bottom - tab->tabs.row * th ;
+ tab->tabs.visible = (tab->tabs.row < display_rows);
}
}
}
*
* This function requires that max_cw, max_ch already be set.
*/
-
static int
PreferredSize(
TabsWidget tw,
static int
PreferredSize2(
TabsWidget tw,
- int cw, /* child width, height */
- int ch,
+ Dimension cw, /* child width, height */
+ Dimension 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 ;
- return PreferredSize3(tw, cw, ch, reply_width, reply_height) ;
+ ret = PreferredSize3(tw, cw, ch, reply_width, reply_height) ;
+
+ assert (*reply_width > 0 && *reply_height > 0);
+ return ret;
}
static int
PreferredSize3(
TabsWidget tw,
- int wid, /* child width, height */
- int hgt,
+ Dimension wid, /* child width, height */
+ Dimension hgt,
Dimension *reply_width, /* total widget size */
Dimension *reply_height)
{