Index: ChangeLog =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/ChangeLog,v retrieving revision 1.1.2.32 diff -u -r1.1.2.32 ChangeLog --- ChangeLog 1999/09/23 05:56:58 1.1.2.32 +++ ChangeLog 1999/10/21 13:56:46 @@ -1,3 +1,9 @@ +1999-09-09 Andy Piper + + * xlwtabs.c: updated tabs widget from Ed Falk. + * xlwtabs.h: ditto. + * xlwtabsP.h: ditto. + 1999-09-22 Martin Buchholz * lwlib-internal.h: Index: xlwtabs.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/Attic/xlwtabs.c,v retrieving revision 1.1.2.12 diff -u -r1.1.2.12 xlwtabs.c --- xlwtabs.c 1999/09/22 20:05:34 1.1.2.12 +++ xlwtabs.c 1999/10/21 13:56:51 @@ -18,7 +18,7 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* Synched up with: Tabs.c 1.21 */ + /* Synched up with: Tabs.c 1.23 */ /* * Tabs.c - Index Tabs composite widget @@ -82,6 +82,8 @@ static char defaultTranslations[] = "\ : select() \n\ + : highlight() \n\ + : unhighlight() \n\ Page_Up: page(up) \n\ KP_Page_Up: page(up) \n\ Prior: page(up) \n\ @@ -94,6 +96,11 @@ KP_Home: page(home) \n\ End: page(end) \n\ KP_End: page(end) \n\ + Up: highlight(up) \n\ + KP_Up: highlight(up) \n\ + Down: highlight(down) \n\ + KP_Down: highlight(down) \n\ + : page(select) \n\ " ; static char accelTable[] = " #augment\n\ @@ -109,6 +116,11 @@ KP_Home: page(home) \n\ End: page(end) \n\ KP_End: page(end) \n\ + Up: highlight(up) \n\ + KP_Up: highlight(up) \n\ + Down: highlight(down) \n\ + KP_Down: highlight(down) \n\ + : page(select) \n\ " ; static XtAccelerators defaultAccelerators ; @@ -139,7 +151,7 @@ offset(bot_shadow_contrast), XtRImmediate, (XtPointer) 40}, {XtNinsensitiveContrast, XtCInsensitiveContrast, XtRInt, sizeof(int), offset(insensitive_contrast), XtRImmediate, (XtPointer) 33}, - {XtNaccelerators, XtCAccelerators, XtRAcceleratorTable, sizeof(XtTranslations), + {XtNaccelerators, XtCAccelerators, XtRAcceleratorTable,sizeof(XtTranslations), XtOffsetOf(TabsRec,core.accelerators), XtRString, accelTable}, }; #undef offset @@ -187,6 +199,8 @@ static void TabsSelect() ; static void TabsPage() ; +static void TabsHighlight() ; +static void TabsUnhighlight() ; /* internal privates */ @@ -197,6 +211,7 @@ static void DrawFrame() ; /* draw frame around contents */ static void DrawTrim() ; /* draw trim around a tab */ static void DrawBorder() ; /* draw border */ +static void DrawHighlight() ; /* draw highlight */ static void UndrawTab() ; /* undraw interior of a tab */ static void TabWidth() ; /* recompute tab size */ static void GetPreferredSizes() ; /* query all children for their sizes */ @@ -232,6 +247,8 @@ static void TabsSelect(Widget, XEvent *, String *, Cardinal *) ; static void TabsPage(Widget, XEvent *, String *, Cardinal *) ; +static void TabsHighlight(Widget, XEvent *, String *, Cardinal *) ; +static void TabsUnhighlight(Widget, XEvent *, String *, Cardinal *) ; static void DrawTabs( TabsWidget tw, Bool labels) ; static void DrawTab( TabsWidget tw, Widget child, Bool labels) ; @@ -239,6 +256,7 @@ static void DrawTrim( TabsWidget, int x, int y, int wid, int hgt, Bool bottom, Bool undraw) ; static void DrawBorder( TabsWidget tw, Widget child, Bool undraw) ; +static void DrawHighlight( TabsWidget tw, Widget child, Bool undraw) ; static void UndrawTab( TabsWidget tw, Widget child) ; static void TabWidth( Widget w) ; @@ -272,6 +290,8 @@ { {"select", TabsSelect}, {"page", TabsPage}, + {"highlight", TabsHighlight}, + {"unhighlight", TabsUnhighlight}, } ; @@ -281,7 +301,11 @@ * ****************************************************************/ -#define SuperClass ((ConstraintWidgetClass)&constraintClassRec) +#ifndef NEED_MOTIF +#define SuperClass (&constraintClassRec) +#else +#define SuperClass (&xmManagerClassRec) +#endif TabsClassRec tabsClassRec = { { @@ -337,6 +361,18 @@ /* set_values */ TabsConstraintSetValues, /* extension */ NULL, }, +#ifdef NEED_MOTIF +/* Manager Class fields */ + { + /* translations */ NULL, + /* syn_resources */ NULL, + /* num_syn_resources */ 0, + /* syn_constraint_resources */ NULL, + /* num_syn_constraint_resources */ 0, + /* parent_process */ XmInheritParentProcess, + /* extension */ NULL + }, +#endif { /* Tabs class fields */ /* extension */ NULL, @@ -424,6 +460,13 @@ newTw->tabs.grey50 = None ; newTw->tabs.needs_layout = False ; + + newTw->tabs.hilight = NULL ; + +#ifdef NEED_MOTIF + newTw->manager.navigation_type = XmTAB_GROUP ; + newTw->manager.traversal_on = True ; +#endif } @@ -602,12 +645,16 @@ */ if( tw->tabs.topWidget != curtw->tabs.topWidget ) - if( XtIsRealized(curtw->tabs.topWidget) ) + if( XtIsRealized(tw->tabs.topWidget) ) { - Widget w = curtw->tabs.topWidget ; + Widget w = tw->tabs.topWidget ; TabsConstraints tab = (TabsConstraints) w->core.constraints ; XRaiseWindow(XtDisplay(w), XtWindow(w)) ; +#ifdef NEED_MOTIF + XtVaSetValues(curtw->tabs.topWidget, XmNtraversalOn, False, 0) ; + XtVaSetValues(w, XmNtraversalOn, True, 0) ; +#endif if( tab->tabs.row != tw->tabs.numRows-1 ) TabsShuffleRows(tw) ; @@ -917,13 +964,32 @@ /* make sure the top widget stays on top. This requires * making sure that all new children are realized first. */ - if( tw->tabs.topWidget != NULL && XtIsRealized(tw->tabs.topWidget) ) { + if( tw->tabs.topWidget != NULL && XtIsRealized(tw->tabs.topWidget) ) + { for(i=tw->tabs.displayChildren; --i >= 0; ++childP) if( !XtIsRealized(*childP) ) XtRealizeWidget(*childP) ; + XRaiseWindow(dpy, XtWindow(tw->tabs.topWidget)) ; } } + +#ifdef NEED_MOTIF + /* Only top widget may receive input */ + + for(childP = tw->composite.children, i=tw->composite.num_children; + --i >= 0; + ++childP) + { + XtVaSetValues(*childP, XmNtraversalOn, False, 0) ; + } + + if( tw->tabs.topWidget != NULL ) + XtVaSetValues(tw->tabs.topWidget, XmNtraversalOn, True, 0) ; +#endif + + + } @@ -948,6 +1014,10 @@ Dimension h = tw->tabs.tab_height ; int i ; +#ifdef NEED_MOTIF + XmProcessTraversal (w, XmTRAVERSE_CURRENT) ; +#endif + /* TODO: is there an Xmu function or something to do this instead? */ switch( event->type ) { case ButtonPress: @@ -989,43 +1059,40 @@ TabsWidget tw = (TabsWidget) w ; Widget newtop ; Widget *childP ; + int idx ; int i ; int nc = tw->composite.num_children ; + if( nc <= 0 ) + return ; + if( *num_params < 1 ) { XtAppWarning(XtWidgetToApplicationContext(w), "Tabs: page() action called with no arguments") ; return ; } + if( tw->tabs.topWidget == NULL ) + tw->tabs.topWidget = tw->composite.children[0] ; + + for(idx=0, childP=tw->composite.children; idx < nc; ++idx, ++childP ) + if( tw->tabs.topWidget == *childP ) + break ; + switch( params[0][0] ) { case 'u': /* up */ case 'U': - if( tw->tabs.topWidget == NULL ) - newtop = tw->composite.children[0] ; - else if( tw->tabs.topWidget == tw->composite.children[0] ) - newtop = tw->composite.children[nc-1] ; - else - for(i=0, childP=tw->composite.children; i < nc; ++i, ++childP ) - if( tw->tabs.topWidget == *childP ) { - newtop = tw->composite.children[i-1] ; - break ; - } - break ; + if( idx == 0 ) + idx = nc ; + newtop = tw->composite.children[idx-1] ; + break ; case 'd': /* down */ case 'D': - if( tw->tabs.topWidget == NULL ) - newtop = tw->composite.children[0] ; - else if( tw->tabs.topWidget == tw->composite.children[nc-1] ) - newtop = tw->composite.children[0] ; - else - for(i=0, childP=tw->composite.children; i < nc; ++i, ++childP ) - if( tw->tabs.topWidget == *childP ) { - newtop = tw->composite.children[i+1] ; - break ; - } - break ; + if( ++idx >= nc ) + idx = 0 ; + newtop = tw->composite.children[idx] ; + break ; case 'h': case 'H': @@ -1036,12 +1103,95 @@ case 'E': newtop = tw->composite.children[nc-1] ; break ; + + case 's': /* selected */ + case 'S': + if( (newtop = tw->tabs.hilight) == NULL ) + return ; + break ; } XawTabsSetTop(newtop, True) ; } + /* User hits up/down key */ + +static void +TabsHighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TabsWidget tw = (TabsWidget) w ; + Widget newhl ; + Widget *childP ; + int idx ; + int i ; + int nc = tw->composite.num_children ; + + if( nc <= 0 ) + return ; + + if( *num_params < 1 ) + { + if( tw->tabs.hilight != NULL ) + DrawHighlight(tw, tw->tabs.hilight, False) ; + return ; + } + + if( tw->tabs.hilight == NULL ) + newhl = tw->composite.children[0] ; + + else + { + for(idx=0, childP=tw->composite.children; idx < nc; ++idx, ++childP ) + if( tw->tabs.hilight == *childP ) + break ; + + switch( params[0][0] ) { + case 'u': /* up */ + case 'U': + if( idx == 0 ) + idx = nc ; + newhl = tw->composite.children[idx-1] ; + break ; + + case 'd': /* down */ + case 'D': + if( ++idx >= nc ) + idx = 0 ; + newhl = tw->composite.children[idx] ; + break ; + + case 'h': + case 'H': + newhl = tw->composite.children[0] ; + break ; + + case 'e': + case 'E': + newhl = tw->composite.children[nc-1] ; + break ; + } + } + + XawTabsSetHighlight(w, newhl) ; +} + + + +static void +TabsUnhighlight(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + TabsWidget tw = (TabsWidget) w ; + int nc = tw->composite.num_children ; + + if( nc <= 0 ) + return ; + + if( tw->tabs.hilight != NULL ) + DrawHighlight(tw, tw->tabs.hilight, True) ; +} + + @@ -1079,6 +1229,10 @@ } XRaiseWindow(XtDisplay(w), XtWindow(w)) ; +#ifdef NEED_MOTIF + XtVaSetValues(oldtop, XmNtraversalOn, False, 0) ; + XtVaSetValues(w, XmNtraversalOn, True, 0) ; +#endif tab = (TabsConstraints) w->core.constraints ; if( tab->tabs.row == 0 ) @@ -1105,11 +1259,36 @@ XtClass(tw)->core_class.expose((Widget)tw,NULL,None) ; } + XawTabsSetHighlight((Widget)tw, w) ; + if( callCallbacks ) XtCallCallbackList(w, tw->tabs.callbacks, (XtPointer)w) ; } + /* Set the top tab, optionally call all callbacks. */ +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) ; + } + + tw->tabs.hilight = w ; +} + + /**************************************************************** @@ -1261,6 +1440,9 @@ x+tab->tabs.l_x, y+tab->tabs.l_y, lbl, (int)strlen(lbl)) ; } + + if( child == tw->tabs.hilight ) + DrawHighlight(tw, child, False) ; } @@ -1340,6 +1522,51 @@ } +/* Draw highlight around tab that has focus */ + +static void +DrawHighlight(TabsWidget tw, Widget child, Bool undraw) +{ + TabsConstraints tab = (TabsConstraints)child->core.constraints; + Display *dpy = XtDisplay((Widget)tw) ; + Window win = XtWindow((Widget)tw) ; + GC gc ; + Position x = tab->tabs.x ; + Position y = tab->tabs.y ; + Dimension wid = tab->tabs.width ; + Dimension hgt = tw->tabs.tab_height ; + XPoint points[6] ; + + /* top tab does not have a highlight */ + + if( child == tw->tabs.topWidget ) + return ; + + if( undraw ) + gc = tw->tabs.backgroundGC ; + + else if( XtIsSensitive(child) ) + { + gc = tw->tabs.foregroundGC ; + XSetForeground(dpy, gc, tab->tabs.foreground) ; + } + else + { + gc = tw->tabs.greyGC ; + XSetForeground(dpy, gc, tab->tabs.grey) ; + } + + points[0].x = x+1 ; points[0].y = y+hgt-1 ; + points[1].x = x+1 ; points[1].y = y+2 ; + points[2].x = x+2 ; points[2].y = y+1 ; + points[3].x = x+wid-4 ; points[3].y = y+1 ; + points[4].x = x+wid-3 ; points[4].y = y+2 ; + points[5].x = x+wid-3 ; points[5].y = y+hgt-1 ; + + XDrawLines(dpy,win,gc, points,6, CoordModeOrigin) ; +} + + /* Undraw one tab interior */ static void @@ -1796,10 +2023,12 @@ values.background = tw->core.background_pixel ; values.font = tw->tabs.font->fid ; + values.line_style = LineOnOffDash ; + values.line_style = LineSolid ; tw->tabs.foregroundGC = XtAllocateGC(w, w->core.depth, - GCBackground|GCFont, &values, + GCBackground|GCFont|GCLineStyle, &values, GCForeground, GCSubwindowMode|GCGraphicsExposures|GCDashOffset| GCDashList|GCArcMode) ; Index: xlwtabs.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/Attic/xlwtabs.h,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 xlwtabs.h --- xlwtabs.h 1999/09/11 08:58:01 1.1.2.2 +++ xlwtabs.h 1999/10/21 13:56:51 @@ -183,11 +183,20 @@ typedef struct _TabsRec *TabsWidget; _XFUNCPROTOBEGIN + extern void XawTabsSetTop( #if NeedFunctionPrototypes Widget w, Bool callCallbacks +#endif +) ; + +extern void +XawTabsSetHighlight( +#if NeedFunctionPrototypes + Widget tabs, + Widget w #endif ) ; Index: xlwtabsP.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/Attic/xlwtabsP.h,v retrieving revision 1.1.2.3 diff -u -r1.1.2.3 xlwtabsP.h --- xlwtabsP.h 1999/08/29 20:57:19 1.1.2.3 +++ xlwtabsP.h 1999/10/21 13:56:51 @@ -18,7 +18,7 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Synched up with: TabsP.h 1.5 */ +/* Synched up with: TabsP.h 1.7 */ /* * TabsP.h - Private definitions for Index Tabs widget @@ -34,6 +34,12 @@ ***********************************************************************/ #include + +#ifdef NEED_MOTIF +#include +#include +#endif + #include "xlwtabs.h" /* New fields for the Tabs widget class record */ @@ -44,6 +50,9 @@ CoreClassPart core_class; CompositeClassPart composite_class; ConstraintClassPart constraint_class; +#ifdef NEED_MOTIF + XmManagerClassPart manager_class; +#endif TabsClassPart tabs_class; } TabsClassRec; @@ -72,6 +81,7 @@ int insensitive_contrast ; /* private state */ + Widget hilight ; GC foregroundGC ; GC backgroundGC ; GC greyGC ; @@ -94,6 +104,9 @@ CorePart core; CompositePart composite; ConstraintPart constraint; +#ifdef NEED_MOTIF + XmManagerPart manager; +#endif TabsPart tabs; } TabsRec; @@ -128,6 +141,9 @@ } TabsConstraintsPart ; typedef struct _TabsConstraintsRec { +#ifdef NEED_MOTIF + XmManagerConstraintPart manager; +#endif TabsConstraintsPart tabs ; } TabsConstraintsRec, *TabsConstraints ;