17a84e134Smrg/*********************************************************** 27a84e134Smrg 37a84e134SmrgCopyright 1987, 1988, 1994, 1998 The Open Group 47a84e134Smrg 57a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its 67a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that 77a84e134Smrgthe above copyright notice appear in all copies and that both that 87a84e134Smrgcopyright notice and this permission notice appear in supporting 97a84e134Smrgdocumentation. 107a84e134Smrg 117a84e134SmrgThe above copyright notice and this permission notice shall be included in 127a84e134Smrgall copies or substantial portions of the Software. 137a84e134Smrg 147a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 177a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 187a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 197a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 207a84e134Smrg 217a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be 227a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings 237a84e134Smrgin this Software without prior written authorization from The Open Group. 247a84e134Smrg 257a84e134Smrg 267a84e134SmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 277a84e134Smrg 287a84e134Smrg All Rights Reserved 297a84e134Smrg 30421c997bSmrgPermission to use, copy, modify, and distribute this software and its 31421c997bSmrgdocumentation for any purpose and without fee is hereby granted, 327a84e134Smrgprovided that the above copyright notice appear in all copies and that 33421c997bSmrgboth that copyright notice and this permission notice appear in 347a84e134Smrgsupporting documentation, and that the name of Digital not be 357a84e134Smrgused in advertising or publicity pertaining to distribution of the 36421c997bSmrgsoftware without specific, written prior permission. 377a84e134Smrg 387a84e134SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 397a84e134SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 407a84e134SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 417a84e134SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 427a84e134SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 437a84e134SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 447a84e134SmrgSOFTWARE. 457a84e134Smrg 467a84e134Smrg******************************************************************/ 477a84e134Smrg 487a84e134Smrg/* 497a84e134Smrg * Updated and significantly modified from the Athena VPaned Widget. 507a84e134Smrg * 517a84e134Smrg * Date: March 1, 1989 527a84e134Smrg * 537a84e134Smrg * By: Chris D. Peterson 547a84e134Smrg * MIT X Consortium 557a84e134Smrg * kit@expo.lcs.mit.edu 567a84e134Smrg */ 577a84e134Smrg 587a84e134Smrg#ifdef HAVE_CONFIG_H 597a84e134Smrg#include <config.h> 607a84e134Smrg#endif 617a84e134Smrg#include <X11/IntrinsicP.h> 627a84e134Smrg#include <X11/cursorfont.h> 637a84e134Smrg#include <X11/StringDefs.h> 647a84e134Smrg#include <X11/Xmu/CharSet.h> 657a84e134Smrg#include <X11/Xmu/Converters.h> 667a84e134Smrg#include <X11/Xmu/Misc.h> 677a84e134Smrg#include <X11/Xaw/Grip.h> 687a84e134Smrg#include <X11/Xaw/PanedP.h> 69421c997bSmrg#include <X11/Xaw/XawImP.h> 707a84e134Smrg#include <X11/Xaw/XawInit.h> 717a84e134Smrg#include "Private.h" 727a84e134Smrg 737a84e134Smrgtypedef enum { 747a84e134Smrg UpLeftPane = 'U', 757a84e134Smrg LowRightPane = 'L', 767a84e134Smrg ThisBorderOnly = 'T', 777a84e134Smrg AnyPane = 'A' 787a84e134Smrg} Direction; 797a84e134Smrg 807a84e134Smrg#define NO_INDEX -100 817a84e134Smrg#define IS_GRIP NULL 827a84e134Smrg 837a84e134Smrg#define PaneInfo(w) ((Pane)(w)->core.constraints) 847a84e134Smrg#define HasGrip(w) (PaneInfo(w)->grip != NULL) 857a84e134Smrg#define IsPane(w) ((w)->core.widget_class != gripWidgetClass) 867a84e134Smrg#define PaneIndex(w) (PaneInfo(w)->position) 877a84e134Smrg#define IsVert(w) ((w)->paned.orientation == XtorientVertical) 887a84e134Smrg 897a84e134Smrg#define ForAllPanes(pw, childP) \ 907a84e134Smrgfor ((childP) = (pw)->composite.children; \ 917a84e134Smrg (childP) < (pw)->composite.children + (pw)->paned.num_panes; \ 927a84e134Smrg (childP)++) 937a84e134Smrg 947a84e134Smrg#define ForAllChildren(pw, childP) \ 957a84e134Smrgfor ((childP) = (pw)->composite.children; \ 967a84e134Smrg (childP) < (pw)->composite.children + (pw)->composite.num_children; \ 977a84e134Smrg (childP)++) 987a84e134Smrg 997a84e134Smrg#define PaneSize(paned, vertical) \ 1007a84e134Smrg ((vertical) ? XtHeight(paned) : XtWidth(paned)) 1017a84e134Smrg 1027a84e134Smrg#define GetRequestInfo(geo, vertical) \ 1037a84e134Smrg ((vertical) ? (geo)->height : (geo)->width) 1047a84e134Smrg 1057a84e134Smrg#define SatisfiesRule1(pane, shrink) \ 1067a84e134Smrg (((shrink) && ((pane)->size != (pane)->min)) \ 1077a84e134Smrg || (!(shrink) && ((pane)->size != (pane)->max))) 1087a84e134Smrg 1097a84e134Smrg#define SatisfiesRule2(pane) \ 1107a84e134Smrg (!(pane)->skip_adjust || (pane)->paned_adjusted_me) 1117a84e134Smrg 1127a84e134Smrg#define SatisfiesRule3(pane, shrink) \ 1137a84e134Smrg ((pane)->paned_adjusted_me \ 1147a84e134Smrg && (((shrink) && ((int)(pane)->wp_size <= (pane)->size)) \ 1157a84e134Smrg || (!(shrink) && ((int)(pane)->wp_size >= (pane)->size)))) 1167a84e134Smrg 1177a84e134Smrg 1187a84e134Smrg/* 1197a84e134Smrg * Class Methods 1207a84e134Smrg */ 1217a84e134Smrgstatic void XawPanedClassInitialize(void); 1227a84e134Smrgstatic void XawPanedChangeManaged(Widget); 1237a84e134Smrgstatic void XawPanedDeleteChild(Widget); 1247a84e134Smrgstatic void XawPanedDestroy(Widget); 1257a84e134Smrgstatic XtGeometryResult XawPanedGeometryManager(Widget, XtWidgetGeometry*, 1267a84e134Smrg XtWidgetGeometry*); 1277a84e134Smrgstatic void XawPanedInitialize(Widget, Widget, ArgList, Cardinal*); 1287a84e134Smrgstatic void XawPanedInsertChild(Widget); 1297a84e134Smrgstatic Boolean XawPanedPaneSetValues(Widget, Widget, Widget, 1307a84e134Smrg ArgList, Cardinal*); 1317a84e134Smrgstatic void XawPanedRealize(Widget, Mask*, XSetWindowAttributes*); 1327a84e134Smrgstatic void XawPanedRedisplay(Widget, XEvent*, Region); 1337a84e134Smrgstatic void XawPanedResize(Widget); 1347a84e134Smrgstatic Boolean XawPanedSetValues(Widget, Widget, Widget, ArgList, Cardinal*); 1357a84e134Smrg 1367a84e134Smrg/* 1377a84e134Smrg * Prototypes 1387a84e134Smrg */ 1397a84e134Smrgstatic void _DrawInternalBorders(PanedWidget, GC); 1407a84e134Smrgstatic void _DrawRect(PanedWidget, GC, int, int, unsigned int, unsigned int); 1417a84e134Smrgstatic void _DrawTrackLines(PanedWidget, Bool); 1427a84e134Smrgstatic void AdjustPanedSize(PanedWidget, unsigned int, XtGeometryResult*, 1437a84e134Smrg Dimension*, Dimension*); 1447a84e134Smrgstatic void ChangeAllGripCursors(PanedWidget); 1457a84e134Smrgstatic Pane ChoosePaneToResize(PanedWidget, int, Direction, Bool); 1467a84e134Smrgstatic void ClearPaneStack(PanedWidget); 1477a84e134Smrgstatic void CommitGripAdjustment(PanedWidget); 1487a84e134Smrgstatic void CreateGrip(Widget); 1497a84e134Smrgstatic int GetEventLocation(PanedWidget, XEvent*); 1507a84e134Smrgstatic void GetGCs(Widget); 1517a84e134Smrgstatic void GetPaneStack(PanedWidget, Bool, Pane*, int*); 1527a84e134Smrgstatic void HandleGrip(Widget, XtPointer, XtPointer); 1537a84e134Smrgstatic void LoopAndRefigureChildren(PanedWidget, int, Direction, int*); 1547a84e134Smrgstatic void ManageAndUnmanageGrips(PanedWidget); 1557a84e134Smrgstatic void MoveGripAdjustment(PanedWidget, Widget, Direction, int); 1567a84e134Smrgstatic Bool PopPaneStack(PanedWidget); 1577a84e134Smrgstatic void PushPaneStack(PanedWidget, Pane); 1587a84e134Smrgstatic void RefigureLocations(PanedWidget, int, Direction); 1597a84e134Smrgstatic void RefigureLocationsAndCommit(Widget); 1607a84e134Smrgstatic void ReleaseGCs(Widget); 1617a84e134Smrgstatic void ResortChildren(PanedWidget); 1627a84e134Smrgstatic void SetChildrenPrefSizes(PanedWidget, unsigned int); 1637a84e134Smrgstatic void StartGripAdjustment(PanedWidget, Widget, Direction); 1647a84e134Smrg 1657a84e134Smrg/* 1667a84e134Smrg * Initialization 1677a84e134Smrg */ 1687a84e134Smrgstatic char defGripTranslations[] = 1697a84e134Smrg"<Btn1Down>:" "GripAction(Start,UpLeftPane)\n" 1707a84e134Smrg"<Btn2Down>:" "GripAction(Start,ThisBorderOnly)\n" 1717a84e134Smrg"<Btn3Down>:" "GripAction(Start,LowRightPane)\n" 1727a84e134Smrg"<Btn1Motion>:" "GripAction(Move,UpLeft)\n" 1737a84e134Smrg"<Btn2Motion>:" "GripAction(Move,ThisBorder)\n" 1747a84e134Smrg"<Btn3Motion>:" "GripAction(Move,LowRight)\n" 1757a84e134Smrg"Any<BtnUp>:" "GripAction(Commit)\n" 1767a84e134Smrg; 1777a84e134Smrg 1787a84e134Smrg#define offset(field) XtOffsetOf(PanedRec, paned.field) 1797a84e134Smrgstatic XtResource resources[] = { 1807a84e134Smrg { 1817a84e134Smrg XtNinternalBorderColor, 1827a84e134Smrg XtCBorderColor, 1837a84e134Smrg XtRPixel, 1847a84e134Smrg sizeof(Pixel), 1857a84e134Smrg offset(internal_bp), 1867a84e134Smrg XtRString, 1877a84e134Smrg (XtPointer)XtDefaultForeground 1887a84e134Smrg }, 1897a84e134Smrg { 1907a84e134Smrg XtNinternalBorderWidth, 1917a84e134Smrg XtCBorderWidth, 1927a84e134Smrg XtRDimension, 1937a84e134Smrg sizeof(Dimension), 1947a84e134Smrg offset(internal_bw), 1957a84e134Smrg XtRImmediate, 1967a84e134Smrg (XtPointer)1 1977a84e134Smrg }, 1987a84e134Smrg { 1997a84e134Smrg XtNgripIndent, 2007a84e134Smrg XtCGripIndent, 2017a84e134Smrg XtRPosition, 2027a84e134Smrg sizeof(Position), 2037a84e134Smrg offset(grip_indent), 2047a84e134Smrg XtRImmediate, 2057a84e134Smrg (XtPointer)10 2067a84e134Smrg }, 2077a84e134Smrg { 2087a84e134Smrg XtNrefigureMode, 2097a84e134Smrg XtCBoolean, 2107a84e134Smrg XtRBoolean, 2117a84e134Smrg sizeof(Boolean), 2127a84e134Smrg offset(refiguremode), 2137a84e134Smrg XtRImmediate, 2147a84e134Smrg (XtPointer)True 2157a84e134Smrg }, 2167a84e134Smrg { 2177a84e134Smrg XtNgripTranslations, 2187a84e134Smrg XtCTranslations, 2197a84e134Smrg XtRTranslationTable, 2207a84e134Smrg sizeof(XtTranslations), 2217a84e134Smrg offset(grip_translations), 2227a84e134Smrg XtRString, 2237a84e134Smrg (XtPointer)defGripTranslations 2247a84e134Smrg }, 2257a84e134Smrg { 2267a84e134Smrg XtNorientation, 2277a84e134Smrg XtCOrientation, 2287a84e134Smrg XtROrientation, 2297a84e134Smrg sizeof(XtOrientation), 2307a84e134Smrg offset(orientation), 2317a84e134Smrg XtRImmediate, 2327a84e134Smrg (XtPointer)XtorientVertical 2337a84e134Smrg }, 2347a84e134Smrg { 2357a84e134Smrg XtNcursor, 2367a84e134Smrg XtCCursor, 2377a84e134Smrg XtRCursor, 2387a84e134Smrg sizeof(Cursor), 2397a84e134Smrg offset(cursor), 2407a84e134Smrg XtRImmediate, 241775e7de9Smrg NULL 2427a84e134Smrg }, 2437a84e134Smrg { 2447a84e134Smrg XtNgripCursor, 2457a84e134Smrg XtCCursor, 2467a84e134Smrg XtRCursor, 2477a84e134Smrg sizeof(Cursor), 2487a84e134Smrg offset(grip_cursor), 2497a84e134Smrg XtRImmediate, 250775e7de9Smrg NULL 2517a84e134Smrg }, 2527a84e134Smrg { 2537a84e134Smrg XtNverticalGripCursor, 2547a84e134Smrg XtCCursor, 2557a84e134Smrg XtRCursor, 2567a84e134Smrg sizeof(Cursor), 2577a84e134Smrg offset(v_grip_cursor), 2587a84e134Smrg XtRString, 2595ec34c4cSmrg (XtPointer)"sb_v_double_arrow" 2607a84e134Smrg }, 2617a84e134Smrg { 2627a84e134Smrg XtNhorizontalGripCursor, 2637a84e134Smrg XtCCursor, 2647a84e134Smrg XtRCursor, 2657a84e134Smrg sizeof(Cursor), 2667a84e134Smrg offset(h_grip_cursor), 2677a84e134Smrg XtRString, 2685ec34c4cSmrg (XtPointer)"sb_h_double_arrow" 2697a84e134Smrg }, 2707a84e134Smrg { 2717a84e134Smrg XtNbetweenCursor, 2727a84e134Smrg XtCCursor, 2737a84e134Smrg XtRCursor, 2747a84e134Smrg sizeof(Cursor), 2757a84e134Smrg offset(adjust_this_cursor), 2767a84e134Smrg XtRString, 277775e7de9Smrg NULL 2787a84e134Smrg }, 2797a84e134Smrg { 2807a84e134Smrg XtNverticalBetweenCursor, 2817a84e134Smrg XtCCursor, 2827a84e134Smrg XtRCursor, 2837a84e134Smrg sizeof(Cursor), 2847a84e134Smrg offset(v_adjust_this_cursor), 2857a84e134Smrg XtRString, 2865ec34c4cSmrg (XtPointer)"sb_left_arrow" 2877a84e134Smrg }, 2887a84e134Smrg { 2897a84e134Smrg XtNhorizontalBetweenCursor, 2907a84e134Smrg XtCCursor, 2917a84e134Smrg XtRCursor, 2927a84e134Smrg sizeof(Cursor), 2937a84e134Smrg offset(h_adjust_this_cursor), 2947a84e134Smrg XtRString, 2955ec34c4cSmrg (XtPointer)"sb_up_arrow" 2967a84e134Smrg }, 2977a84e134Smrg { 2987a84e134Smrg XtNupperCursor, 2997a84e134Smrg XtCCursor, 3007a84e134Smrg XtRCursor, 3017a84e134Smrg sizeof(Cursor), 3027a84e134Smrg offset(adjust_upper_cursor), 3037a84e134Smrg XtRString, 3045ec34c4cSmrg (XtPointer)"sb_up_arrow" 3057a84e134Smrg }, 3067a84e134Smrg { 3077a84e134Smrg XtNlowerCursor, 3087a84e134Smrg XtCCursor, 3097a84e134Smrg XtRCursor, 3107a84e134Smrg sizeof(Cursor), 3117a84e134Smrg offset(adjust_lower_cursor), 3127a84e134Smrg XtRString, 3135ec34c4cSmrg (XtPointer)"sb_down_arrow" 3147a84e134Smrg }, 3157a84e134Smrg { 3167a84e134Smrg XtNleftCursor, 3177a84e134Smrg XtCCursor, 3187a84e134Smrg XtRCursor, 3197a84e134Smrg sizeof(Cursor), 3207a84e134Smrg offset(adjust_left_cursor), 3217a84e134Smrg XtRString, 3225ec34c4cSmrg (XtPointer)"sb_left_arrow" 3237a84e134Smrg }, 3247a84e134Smrg { 3257a84e134Smrg XtNrightCursor, 3267a84e134Smrg XtCCursor, 3277a84e134Smrg XtRCursor, 3287a84e134Smrg sizeof(Cursor), 3297a84e134Smrg offset(adjust_right_cursor), 3307a84e134Smrg XtRString, 3315ec34c4cSmrg (XtPointer)"sb_right_arrow" 3327a84e134Smrg }, 3337a84e134Smrg}; 3347a84e134Smrg#undef offset 3357a84e134Smrg 3367a84e134Smrg#define offset(field) XtOffsetOf(PanedConstraintsRec, paned.field) 3377a84e134Smrgstatic XtResource subresources[] = { 3387a84e134Smrg { 3397a84e134Smrg XtNallowResize, 3407a84e134Smrg XtCBoolean, 3417a84e134Smrg XtRBoolean, 3427a84e134Smrg sizeof(Boolean), 3437a84e134Smrg offset(allow_resize), 3447a84e134Smrg XtRImmediate, 3457a84e134Smrg (XtPointer)False 3467a84e134Smrg }, 3477a84e134Smrg { 3487a84e134Smrg XtNposition, 3497a84e134Smrg XtCPosition, 3507a84e134Smrg XtRInt, 3517a84e134Smrg sizeof(int), 3527a84e134Smrg offset(position), 3537a84e134Smrg XtRImmediate, 3547a84e134Smrg (XtPointer)0 3557a84e134Smrg }, 3567a84e134Smrg { 3577a84e134Smrg XtNmin, 3587a84e134Smrg XtCMin, 3597a84e134Smrg XtRDimension, 3607a84e134Smrg sizeof(Dimension), 3617a84e134Smrg offset(min), 3627a84e134Smrg XtRImmediate, 3637a84e134Smrg (XtPointer)PANED_GRIP_SIZE 3647a84e134Smrg }, 3657a84e134Smrg { 3667a84e134Smrg XtNmax, 3677a84e134Smrg XtCMax, 3687a84e134Smrg XtRDimension, 3697a84e134Smrg sizeof(Dimension), 3707a84e134Smrg offset(max), 3717a84e134Smrg XtRImmediate, 3727a84e134Smrg (XtPointer)~0 3737a84e134Smrg }, 3747a84e134Smrg { 3757a84e134Smrg XtNpreferredPaneSize, 3767a84e134Smrg XtCPreferredPaneSize, 3777a84e134Smrg XtRDimension, 3787a84e134Smrg sizeof(Dimension), 3797a84e134Smrg offset(preferred_size), 3807a84e134Smrg XtRImmediate, 3817a84e134Smrg (XtPointer)PANED_ASK_CHILD 3827a84e134Smrg }, 3837a84e134Smrg { 3847a84e134Smrg XtNresizeToPreferred, 3857a84e134Smrg XtCBoolean, 3867a84e134Smrg XtRBoolean, 3877a84e134Smrg sizeof(Boolean), 3887a84e134Smrg offset(resize_to_pref), 3897a84e134Smrg XtRImmediate, 3907a84e134Smrg (XtPointer)False 3917a84e134Smrg }, 3927a84e134Smrg { 3937a84e134Smrg XtNskipAdjust, 3947a84e134Smrg XtCBoolean, 3957a84e134Smrg XtRBoolean, 3967a84e134Smrg sizeof(Boolean), 3977a84e134Smrg offset(skip_adjust), 3987a84e134Smrg XtRImmediate, 3997a84e134Smrg (XtPointer)False 4007a84e134Smrg }, 4017a84e134Smrg { 4027a84e134Smrg XtNshowGrip, 4037a84e134Smrg XtCShowGrip, 4047a84e134Smrg XtRBoolean, 4057a84e134Smrg sizeof(Boolean), 4067a84e134Smrg offset(show_grip), 4077a84e134Smrg XtRImmediate, 4087a84e134Smrg (XtPointer)True 4097a84e134Smrg }, 4107a84e134Smrg}; 4117a84e134Smrg#undef offset 4127a84e134Smrg 4137a84e134Smrg#define SuperClass ((ConstraintWidgetClass)&constraintClassRec) 4147a84e134Smrg 4157a84e134SmrgPanedClassRec panedClassRec = { 4167a84e134Smrg /* core */ 4177a84e134Smrg { 4187a84e134Smrg (WidgetClass)SuperClass, /* superclass */ 4197a84e134Smrg "Paned", /* class name */ 4207a84e134Smrg sizeof(PanedRec), /* size */ 4217a84e134Smrg XawPanedClassInitialize, /* class_initialize */ 4227a84e134Smrg NULL, /* class_part init */ 4237a84e134Smrg False, /* class_inited */ 4247a84e134Smrg XawPanedInitialize, /* initialize */ 4257a84e134Smrg NULL, /* initialize_hook */ 4267a84e134Smrg XawPanedRealize, /* realize */ 4277a84e134Smrg NULL, /* actions */ 4287a84e134Smrg 0, /* num_actions */ 4297a84e134Smrg resources, /* resources */ 4307a84e134Smrg XtNumber(resources), /* num_resources */ 4317a84e134Smrg NULLQUARK, /* xrm_class */ 4327a84e134Smrg True, /* compress_motion */ 4337a84e134Smrg True, /* compress_exposure */ 4347a84e134Smrg True, /* compress_enterleave */ 4357a84e134Smrg False, /* visible_interest */ 4367a84e134Smrg XawPanedDestroy, /* destroy */ 4377a84e134Smrg XawPanedResize, /* resize */ 4387a84e134Smrg XawPanedRedisplay, /* expose */ 4397a84e134Smrg XawPanedSetValues, /* set_values */ 4407a84e134Smrg NULL, /* set_values_hook */ 4417a84e134Smrg XtInheritSetValuesAlmost, /* set_values_almost */ 4427a84e134Smrg NULL, /* get_values_hook */ 4437a84e134Smrg NULL, /* accept_focus */ 4447a84e134Smrg XtVersion, /* version */ 4457a84e134Smrg NULL, /* callback_private */ 4467a84e134Smrg NULL, /* tm_table */ 4477a84e134Smrg XtInheritQueryGeometry, /* query_geometry */ 4487a84e134Smrg XtInheritDisplayAccelerator, /* display_accelerator */ 4497a84e134Smrg NULL, /* extension */ 4507a84e134Smrg }, 4517a84e134Smrg /* composite */ 4527a84e134Smrg { 4537a84e134Smrg XawPanedGeometryManager, /* geometry_manager */ 4547a84e134Smrg XawPanedChangeManaged, /* change_managed */ 4557a84e134Smrg XawPanedInsertChild, /* insert_child */ 4567a84e134Smrg XawPanedDeleteChild, /* delete_child */ 4577a84e134Smrg NULL, /* extension */ 4587a84e134Smrg }, 4597a84e134Smrg /* constraint */ 4607a84e134Smrg { 4617a84e134Smrg subresources, /* subresources */ 4627a84e134Smrg XtNumber(subresources), /* subresource_count */ 4637a84e134Smrg sizeof(PanedConstraintsRec), /* constraint_size */ 4647a84e134Smrg NULL, /* initialize */ 4657a84e134Smrg NULL, /* destroy */ 4667a84e134Smrg XawPanedPaneSetValues, /* set_values */ 4677a84e134Smrg NULL, /* extension */ 4687a84e134Smrg }, 469efbcb2bfSmrg /* paned */ 470efbcb2bfSmrg { 471efbcb2bfSmrg NULL, /* extension */ 472efbcb2bfSmrg } 4737a84e134Smrg}; 4747a84e134Smrg 4757a84e134SmrgWidgetClass panedWidgetClass = (WidgetClass)&panedClassRec; 4767a84e134SmrgWidgetClass vPanedWidgetClass = (WidgetClass)&panedClassRec; 4777a84e134Smrg 4787a84e134Smrg/* 4797a84e134Smrg * Implementation 4807a84e134Smrg */ 4817a84e134Smrg/* Function: 4827a84e134Smrg * AdjustPanedSize 4837a84e134Smrg * 4847a84e134Smrg * Parameters: 4857a84e134Smrg * pw - paned widget to adjust 4867a84e134Smrg * off_size - new off_size to use 4877a84e134Smrg * result_ret - result of query (return) 4887a84e134Smrg * on_size_ret - new on_size (return) 4897a84e134Smrg * off_size_ret - new off_size (return) 4907a84e134Smrg * 4917a84e134Smrg * Description: 4927a84e134Smrg * Adjusts the size of the pane. 4937a84e134Smrg * 4947a84e134Smrg * Returns: 4957a84e134Smrg * amount of change in size 4967a84e134Smrg */ 4977a84e134Smrgstatic void 4987a84e134SmrgAdjustPanedSize(PanedWidget pw, unsigned int off_size, 4997a84e134Smrg XtGeometryResult *result_ret, 5007a84e134Smrg Dimension *on_size_ret, Dimension *off_size_ret) 5017a84e134Smrg{ 5027a84e134Smrg Dimension old_size = PaneSize((Widget)pw, IsVert(pw)); 5037a84e134Smrg Dimension newsize = 0; 5047a84e134Smrg Widget *childP; 5057a84e134Smrg XtWidgetGeometry request, reply; 5067a84e134Smrg 5077a84e134Smrg request.request_mode = CWWidth | CWHeight; 5087a84e134Smrg 5097a84e134Smrg ForAllPanes(pw, childP) { 5107a84e134Smrg int size = Max(PaneInfo(*childP)->size, (int)PaneInfo(*childP)->min); 5117a84e134Smrg 5127a84e134Smrg AssignMin(size, (int)PaneInfo(*childP)->max); 513efbcb2bfSmrg newsize = (Dimension)(newsize + (size + pw->paned.internal_bw)); 5147a84e134Smrg } 5155ec34c4cSmrg newsize = (Dimension)(newsize - pw->paned.internal_bw); 5167a84e134Smrg 5177a84e134Smrg if (newsize < 1) 5187a84e134Smrg newsize = 1; 5197a84e134Smrg 5207a84e134Smrg if (IsVert(pw)) { 5215ec34c4cSmrg request.width = (Dimension)off_size; 5227a84e134Smrg request.height = newsize; 5237a84e134Smrg } 5247a84e134Smrg else { 5257a84e134Smrg request.width = newsize; 5265ec34c4cSmrg request.height = (Dimension)off_size; 5277a84e134Smrg } 5287a84e134Smrg 5297a84e134Smrg if (result_ret != NULL) { 5307a84e134Smrg request.request_mode |= XtCWQueryOnly; 5317a84e134Smrg 5327a84e134Smrg *result_ret = XtMakeGeometryRequest((Widget)pw, &request, &reply); 5337a84e134Smrg _XawImCallVendorShellExtResize((Widget)pw); 5347a84e134Smrg 5357a84e134Smrg if (newsize == old_size || *result_ret == XtGeometryNo) { 5367a84e134Smrg *on_size_ret = old_size; 5375ec34c4cSmrg *off_size_ret = (Dimension)off_size; 5387a84e134Smrg return; 5397a84e134Smrg } 5407a84e134Smrg if (*result_ret != XtGeometryAlmost) { 5417a84e134Smrg *on_size_ret = GetRequestInfo(&request, IsVert(pw)); 542421c997bSmrg *off_size_ret = GetRequestInfo(&request, !IsVert(pw)); 5437a84e134Smrg return; 5447a84e134Smrg } 5457a84e134Smrg *on_size_ret = GetRequestInfo(&reply, IsVert(pw)); 5467a84e134Smrg *off_size_ret = GetRequestInfo(&reply, !IsVert(pw)); 5477a84e134Smrg return; 5487a84e134Smrg } 5497a84e134Smrg 5507a84e134Smrg if (newsize == old_size) 5517a84e134Smrg return; 5527a84e134Smrg 5537a84e134Smrg if (XtMakeGeometryRequest((Widget)pw, &request, &reply) == XtGeometryAlmost) 5547a84e134Smrg XtMakeGeometryRequest((Widget)pw, &reply, &request); 5557a84e134Smrg} 5567a84e134Smrg 5577a84e134Smrg/* 5587a84e134Smrg * Function: 5597a84e134Smrg * ChoosePaneToResize. 5607a84e134Smrg * 5617a84e134Smrg * Parameters: 5627a84e134Smrg * pw - paned widget 5637a84e134Smrg * paneindex - index of the current pane 5647a84e134Smrg * dir - direction to search first 5657a84e134Smrg * shrink - True if we need to shrink a pane, False otherwise 5667a84e134Smrg * 5677a84e134Smrg * Description: 5687a84e134Smrg * This function chooses a pane to resize. 569421c997bSmrg * They are chosen using the following rules: 5707a84e134Smrg * 5717a84e134Smrg * 1) size < max && size > min 5727a84e134Smrg * 2) skip adjust == False 5735b16253fSmrg * 3) widget not its preferred height 5747a84e134Smrg * && this change will bring it closer 5757a84e134Smrg * && The user has not resized this pane. 576421c997bSmrg * 5777a84e134Smrg * If no widgets are found that fits all the rules then 5787a84e134Smrg * rule #3 is broken. 5797a84e134Smrg * If there are still no widgets found than 5807a84e134Smrg * rule #2 is broken. 5817a84e134Smrg * Rule #1 is never broken. 5827a84e134Smrg * If no widgets are found then NULL is returned. 583421c997bSmrg * 5847a84e134Smrg * Returns: 5857a84e134Smrg * pane to resize or NULL 5867a84e134Smrg */ 5877a84e134Smrgstatic Pane 5887a84e134SmrgChoosePaneToResize(PanedWidget pw, int paneindex, Direction dir, Bool shrink) 5897a84e134Smrg{ 5907a84e134Smrg Widget *childP; 5917a84e134Smrg int rules = 3; 5927a84e134Smrg Direction _dir = dir; 5937a84e134Smrg int _index = paneindex; 5947a84e134Smrg 5957a84e134Smrg if (paneindex == NO_INDEX || dir == AnyPane) { /* Use defaults */ 5967a84e134Smrg _dir = LowRightPane; /* Go up - really */ 5977a84e134Smrg _index = pw->paned.num_panes - 1; /* Start the last pane, and work 5987a84e134Smrg backwards */ 5997a84e134Smrg } 6007a84e134Smrg childP = pw->composite.children + _index; 6017a84e134Smrg 6027a84e134Smrg /*CONSTCOND*/ 6037a84e134Smrg while(True) { 6047a84e134Smrg Pane pane = PaneInfo(*childP); 605421c997bSmrg 6067a84e134Smrg if ((rules < 3 || SatisfiesRule3(pane, shrink)) 6077a84e134Smrg && (rules < 2 || SatisfiesRule2(pane)) 6087a84e134Smrg && SatisfiesRule1(pane, shrink) 6097a84e134Smrg && (paneindex != PaneIndex(*childP) || dir == AnyPane)) 6107a84e134Smrg return (pane); 6117a84e134Smrg 6127a84e134Smrg /* 6137a84e134Smrg * This is counter-intuitive, but if we are resizing the pane 6147a84e134Smrg * above the grip we want to choose a pane below the grip to lose, 6157a84e134Smrg * and visa-versa 6167a84e134Smrg */ 6177a84e134Smrg if (_dir == LowRightPane) 6187a84e134Smrg --childP; 6197a84e134Smrg else 6207a84e134Smrg ++childP; 6217a84e134Smrg 6227a84e134Smrg /* 6237a84e134Smrg * If we have come to and edge then reduce the rule set, and try again 6247a84e134Smrg * If we are reduced the rules to none, then return NULL 6257a84e134Smrg */ 6267a84e134Smrg if ((childP - pw->composite.children) < 0 || 6277a84e134Smrg (childP - pw->composite.children) >= pw->paned.num_panes) { 6287a84e134Smrg if (--rules < 1) /* less strict rules */ 6297a84e134Smrg return (NULL); 6307a84e134Smrg childP = pw->composite.children + _index; 6317a84e134Smrg } 6327a84e134Smrg } 6337a84e134Smrg} 6347a84e134Smrg 6357a84e134Smrg/* 6367a84e134Smrg * Function: 6377a84e134Smrg * LoopAndRefigureChildren 6387a84e134Smrg * 6397a84e134Smrg * Parameters: 6407a84e134Smrg * pw - paned widget 641421c997bSmrg * paneindex - number of the pane border we are moving 6427a84e134Smrg * dir - pane to move (either UpLeftPane or LowRightPane) 6437a84e134Smrg * sizeused - current amount of space used (used and returned) 6447a84e134Smrg * 6457a84e134Smrg * Description: 6467a84e134Smrg * If we are resizing either the UpleftPane or LowRight Pane loop 6477a84e134Smrg * through all the children to see if any will allow us to resize them. 6487a84e134Smrg */ 6497a84e134Smrgstatic void 6507a84e134SmrgLoopAndRefigureChildren(PanedWidget pw, int paneindex, Direction dir, 6517a84e134Smrg int *sizeused) 6527a84e134Smrg{ 6537a84e134Smrg int pane_size = (int)PaneSize((Widget)pw, IsVert(pw)); 6547a84e134Smrg Boolean shrink = (*sizeused > pane_size); 6557a84e134Smrg 6567a84e134Smrg if (dir == LowRightPane) 6577a84e134Smrg paneindex++; 6587a84e134Smrg 6597a84e134Smrg /* While all panes do not fit properly */ 6607a84e134Smrg while (*sizeused != pane_size) { 6617a84e134Smrg /* 6627a84e134Smrg * Choose a pane to resize 6637a84e134Smrg * First look on the Pane Stack, and then go hunting for another one 6647a84e134Smrg * If we fail to find a pane to resize then give up 6657a84e134Smrg */ 6667a84e134Smrg Pane pane; 6677a84e134Smrg int start_size; 6687a84e134Smrg Dimension old; 6697a84e134Smrg Boolean rule3_ok = False, from_stack = True; 6707a84e134Smrg 6717a84e134Smrg GetPaneStack(pw, shrink, &pane, &start_size); 6727a84e134Smrg if (pane == NULL) { 6737a84e134Smrg pane = ChoosePaneToResize(pw, paneindex, dir, shrink); 674421c997bSmrg if (pane == NULL) 6757a84e134Smrg return; /* no one to resize, give up */ 6767a84e134Smrg 6777a84e134Smrg rule3_ok = SatisfiesRule3(pane, shrink); 6787a84e134Smrg from_stack = False; 6797a84e134Smrg PushPaneStack(pw, pane); 6807a84e134Smrg } 6817a84e134Smrg 6827a84e134Smrg /* 6837a84e134Smrg * Try to resize this pane so that all panes will fit, take min and max 6847a84e134Smrg * into account 6857a84e134Smrg */ 6865ec34c4cSmrg old = (Dimension) pane->size; 6877a84e134Smrg pane->size += pane_size - *sizeused; 6887a84e134Smrg 6897a84e134Smrg if (from_stack) { 6907a84e134Smrg if (shrink) { 6917a84e134Smrg AssignMax(pane->size, start_size); 6927a84e134Smrg } /* don't remove these braces */ 6937a84e134Smrg else 6947a84e134Smrg AssignMin(pane->size, start_size); 6957a84e134Smrg 6967a84e134Smrg if (pane->size == start_size) 6977a84e134Smrg (void)PopPaneStack(pw); 6987a84e134Smrg } 6997a84e134Smrg else if (rule3_ok) { 7007a84e134Smrg if (shrink) { 7017a84e134Smrg AssignMax(pane->size, (int)pane->wp_size); 7027a84e134Smrg } /* don't remove these braces */ 7037a84e134Smrg else 7047a84e134Smrg AssignMin(pane->size, (int)pane->wp_size); 7057a84e134Smrg } 7067a84e134Smrg 7077a84e134Smrg pane->paned_adjusted_me = pane->size != pane->wp_size; 7087a84e134Smrg AssignMax(pane->size, (int)pane->min); 7097a84e134Smrg AssignMin(pane->size, (int)pane->max); 7107a84e134Smrg *sizeused += (pane->size - old); 7117a84e134Smrg } 7127a84e134Smrg} 7137a84e134Smrg 7147a84e134Smrg/* 7157a84e134Smrg * Function: 7167a84e134Smrg * RefigureLocations 7177a84e134Smrg * 7187a84e134Smrg * Parameters: 7197a84e134Smrg * pw - paned widget 7207a84e134Smrg * paneindex - child to start refiguring at 7217a84e134Smrg * dir - direction to move from child 7227a84e134Smrg * 7237a84e134Smrg * Description: 7247a84e134Smrg * Refigures all locations of children. 7257a84e134Smrg * There are special arguments to paneindex and dir, they are: 7267a84e134Smrg * paneindex - NO_INDEX. 7277a84e134Smrg * dir - AnyPane. 7287a84e134Smrg * 7297a84e134Smrg * If either of these is true then all panes may be resized and 7305b16253fSmrg * the choosing of panes proceeds in reverse order starting with the 7317a84e134Smrg * last child. 7327a84e134Smrg */ 733421c997bSmrgstatic void 7347a84e134SmrgRefigureLocations(PanedWidget pw, int paneindex, Direction dir) 7357a84e134Smrg{ 7367a84e134Smrg Widget *childP; 7377a84e134Smrg int pane_size = (int)PaneSize((Widget)pw, IsVert(pw)); 7387a84e134Smrg int sizeused = 0; 7397a84e134Smrg Position loc = 0; 7407a84e134Smrg 7417a84e134Smrg if (pw->paned.num_panes == 0 || !pw->paned.refiguremode) 7427a84e134Smrg return; 7437a84e134Smrg 7447a84e134Smrg /* 7457a84e134Smrg * Get an initial estimate of the size we will use 7467a84e134Smrg */ 7477a84e134Smrg ForAllPanes(pw, childP) { 7487a84e134Smrg Pane pane = PaneInfo(*childP); 7497a84e134Smrg 7507a84e134Smrg AssignMax(pane->size, (int) pane->min); 7517a84e134Smrg AssignMin(pane->size, (int) pane->max); 7527a84e134Smrg sizeused += (int)pane->size + (int)pw->paned.internal_bw; 7537a84e134Smrg } 7547a84e134Smrg sizeused -= (int)pw->paned.internal_bw; 7557a84e134Smrg 7567a84e134Smrg if (dir != ThisBorderOnly && sizeused != pane_size) 7577a84e134Smrg LoopAndRefigureChildren(pw, paneindex, dir, &sizeused); 7587a84e134Smrg 7597a84e134Smrg /* 7607a84e134Smrg * If we still are not the right size, then tell the pane that 7617a84e134Smrg * wanted to resize that it can't 7627a84e134Smrg */ 7637a84e134Smrg if (paneindex != NO_INDEX && dir != AnyPane) { 7647a84e134Smrg Pane pane = PaneInfo(*(pw->composite.children + paneindex)); 7655ec34c4cSmrg Dimension old = (Dimension)pane->size; 7667a84e134Smrg 7677a84e134Smrg pane->size += pane_size - sizeused; 7687a84e134Smrg AssignMax(pane->size, (int) pane->min); 7697a84e134Smrg AssignMin(pane->size, (int) pane->max); 7707a84e134Smrg sizeused += pane->size - old; 7717a84e134Smrg } 772421c997bSmrg 7737a84e134Smrg /* 7747a84e134Smrg * It is possible that the panes will not fit inside the vpaned widget, but 7757a84e134Smrg * we have tried out best 7767a84e134Smrg * 7777a84e134Smrg * Assign each pane a location 7787a84e134Smrg */ 7797a84e134Smrg ForAllPanes(pw, childP) { 7807a84e134Smrg PaneInfo(*childP)->delta = loc; 7815ec34c4cSmrg loc = (Position)(loc + (PaneInfo(*childP)->size + pw->paned.internal_bw)); 7827a84e134Smrg } 7837a84e134Smrg} 7847a84e134Smrg 7857a84e134Smrg/* 7867a84e134Smrg * Function: 7877a84e134Smrg * CommitNewLocations 7887a84e134Smrg * 7897a84e134Smrg * Parameters: 7907a84e134Smrg * pw - paned widget 7917a84e134Smrg * 7927a84e134Smrg * Description: 7937a84e134Smrg * Commits all of the previously figured locations. 7947a84e134Smrg */ 795421c997bSmrgstatic void 7967a84e134SmrgCommitNewLocations(PanedWidget pw) 7977a84e134Smrg{ 7987a84e134Smrg Widget *childP; 799efbcb2bfSmrg XWindowChanges changes = { .stack_mode = Above }; 8007a84e134Smrg 8017a84e134Smrg ForAllPanes(pw, childP) { 8027a84e134Smrg Pane pane = PaneInfo(*childP); 8037a84e134Smrg Widget grip = pane->grip; /* may be NULL */ 8047a84e134Smrg 8057a84e134Smrg if (IsVert(pw)) { 8067a84e134Smrg XtMoveWidget(*childP, (Position) 0, pane->delta); 8075ec34c4cSmrg XtResizeWidget(*childP, XtWidth(pw), (Dimension)pane->size, 0); 8087a84e134Smrg 8097a84e134Smrg if (HasGrip(*childP)) { /* Move and Display the Grip */ 8107a84e134Smrg changes.x = XtWidth(pw) - pw->paned.grip_indent - 8117a84e134Smrg XtWidth(grip) - (XtBorderWidth(grip) << 1); 8127a84e134Smrg changes.y = XtY(*childP) + XtHeight(*childP) - 8137a84e134Smrg (XtHeight(grip) >> 1) - XtBorderWidth(grip) + 8147a84e134Smrg (pw->paned.internal_bw >> 1); 8157a84e134Smrg } 8167a84e134Smrg } 8177a84e134Smrg else { 8187a84e134Smrg XtMoveWidget(*childP, pane->delta, 0); 8195ec34c4cSmrg XtResizeWidget(*childP, (Dimension)pane->size, (Dimension)XtHeight(pw), 0); 8207a84e134Smrg 8217a84e134Smrg if (HasGrip(*childP)) { /* Move and Display the Grip */ 8227a84e134Smrg changes.x = XtX(*childP) + XtWidth(*childP) - 8237a84e134Smrg (XtWidth(grip) >> 1) - XtBorderWidth(grip) + 8247a84e134Smrg (pw->paned.internal_bw >> 1); 8257a84e134Smrg changes.y = XtHeight(pw) - pw->paned.grip_indent - 8267a84e134Smrg XtHeight(grip) - (XtBorderWidth(grip) << 1); 8277a84e134Smrg } 8287a84e134Smrg } 8297a84e134Smrg 8307a84e134Smrg /* 831421c997bSmrg * This should match XtMoveWidget, except that we're also insuring the 8327a84e134Smrg * grip is Raised in the same request 8337a84e134Smrg */ 8347a84e134Smrg 8357a84e134Smrg if (HasGrip(*childP)) { 8365ec34c4cSmrg XtX(grip) = (Position)changes.x; 8375ec34c4cSmrg XtY(grip) = (Position)changes.y; 8387a84e134Smrg 8397a84e134Smrg if (XtIsRealized(pane->grip)) 8407a84e134Smrg XConfigureWindow(XtDisplay(pane->grip), XtWindow(pane->grip), 8417a84e134Smrg CWX | CWY | CWStackMode, &changes); 8427a84e134Smrg } 8437a84e134Smrg } 8447a84e134Smrg ClearPaneStack(pw); 8457a84e134Smrg} 8467a84e134Smrg 8477a84e134Smrg/* 8487a84e134Smrg * Function: 8497a84e134Smrg * RefigureLocationsAndCommit 8507a84e134Smrg * 8517a84e134Smrg * Parameters: 8527a84e134Smrg * pw - paned widget 8537a84e134Smrg * 8547a84e134Smrg * Description: 855421c997bSmrg * Refigures all locations in a paned widget and commits them immediately. 8567a84e134Smrg * 8577a84e134Smrg * This function does nothing if any of the following are true. 8587a84e134Smrg * o refiguremode is false. 8597a84e134Smrg * o The widget is unrealized. 8607a84e134Smrg * o There are no panes is the paned widget. 8617a84e134Smrg */ 862421c997bSmrgstatic void 8637a84e134SmrgRefigureLocationsAndCommit(Widget w) 8647a84e134Smrg{ 8657a84e134Smrg PanedWidget pw = (PanedWidget)w; 8667a84e134Smrg 8677a84e134Smrg if (pw->paned.refiguremode && XtIsRealized(w) && pw->paned.num_panes > 0) { 8687a84e134Smrg RefigureLocations(pw, NO_INDEX, AnyPane); 8697a84e134Smrg CommitNewLocations(pw); 8707a84e134Smrg } 8717a84e134Smrg} 8727a84e134Smrg 8737a84e134Smrg/* 8747a84e134Smrg * Function: 8757a84e134Smrg * _DrawRect 8767a84e134Smrg * 8777a84e134Smrg * Parameters: 8787a84e134Smrg * pw - paned widget 8797a84e134Smrg * gc - gc to used for the draw 8807a84e134Smrg * on_olc - location of upper left corner of rect 8817a84e134Smrg * off_loc - "" 8827a84e134Smrg * on_size - size of rectangle 8837a84e134Smrg * off_size - "" 8847a84e134Smrg * 8857a84e134Smrg * Description: 8867a84e134Smrg * Draws a rectangle in the proper orientation. 8877a84e134Smrg */ 8887a84e134Smrgstatic void 8897a84e134Smrg_DrawRect(PanedWidget pw, GC gc, int on_loc, int off_loc, 8907a84e134Smrg unsigned int on_size, unsigned int off_size) 8917a84e134Smrg{ 892421c997bSmrg if (IsVert(pw)) 8937a84e134Smrg XFillRectangle(XtDisplay((Widget)pw), XtWindow((Widget)pw), gc, 8947a84e134Smrg off_loc, on_loc, off_size, on_size); 8957a84e134Smrg else 8967a84e134Smrg XFillRectangle(XtDisplay((Widget)pw), XtWindow((Widget)pw), gc, 8977a84e134Smrg on_loc, off_loc, on_size, off_size); 8987a84e134Smrg} 8997a84e134Smrg 9007a84e134Smrg/* 9017a84e134Smrg * Function: 9027a84e134Smrg * _DrawInternalBorders 9037a84e134Smrg * 9047a84e134Smrg * Parameters: 9057a84e134Smrg * pw - paned widget 9067a84e134Smrg * gc - GC to use to draw the borders 9077a84e134Smrg * 9087a84e134Smrg * Description: 9097a84e134Smrg * Draws the internal borders into the paned widget. 9107a84e134Smrg */ 9117a84e134Smrgstatic void 9127a84e134Smrg_DrawInternalBorders(PanedWidget pw, GC gc) 9137a84e134Smrg{ 9147a84e134Smrg Widget *childP; 915efbcb2bfSmrg int off_loc; 9167a84e134Smrg unsigned int on_size, off_size; 9177a84e134Smrg 9187a84e134Smrg /* 9197a84e134Smrg * This is an optimization. Do not paint the internal borders if 9207a84e134Smrg * they are the same color as the background 9217a84e134Smrg */ 9227a84e134Smrg if (pw->core.background_pixel == pw->paned.internal_bp) 9237a84e134Smrg return; 9247a84e134Smrg 925421c997bSmrg off_loc = 0; 9267a84e134Smrg off_size = (unsigned int) PaneSize((Widget)pw, !IsVert(pw)); 9277a84e134Smrg on_size = (unsigned int)pw->paned.internal_bw; 9287a84e134Smrg 9297a84e134Smrg ForAllPanes(pw, childP) { 930efbcb2bfSmrg int on_loc = IsVert(pw) ? XtY(*childP) : XtX(*childP); 9317a84e134Smrg on_loc -= (int)on_size; 9327a84e134Smrg 9337a84e134Smrg _DrawRect(pw, gc, on_loc, off_loc, on_size, off_size); 9347a84e134Smrg } 9357a84e134Smrg} 9367a84e134Smrg 9377a84e134Smrg#define DrawInternalBorders(pw) \ 9387a84e134Smrg _DrawInternalBorders((pw), (pw)->paned.normgc) 9397a84e134Smrg#define EraseInternalBorders(pw) \ 9407a84e134Smrg _DrawInternalBorders((pw), (pw)->paned.invgc) 941421c997bSmrg/* 9427a84e134Smrg * Function Name: 9437a84e134Smrg * _DrawTrackLines 9447a84e134Smrg * 9457a84e134Smrg * Parameters: 9467a84e134Smrg * pw - Paned widget 9477a84e134Smrg * erase - if True then just erase track lines, else draw them in 9487a84e134Smrg * 9497a84e134Smrg * Description: 9507a84e134Smrg * Draws the lines that animate the pane borders when the grips are moved. 9517a84e134Smrg */ 9527a84e134Smrgstatic void 9537a84e134Smrg_DrawTrackLines(PanedWidget pw, Bool erase) 9547a84e134Smrg{ 9557a84e134Smrg Widget *childP; 9567a84e134Smrg Pane pane; 9577a84e134Smrg int on_loc, off_loc; 9587a84e134Smrg unsigned int on_size, off_size; 9597a84e134Smrg 9607a84e134Smrg off_loc = 0; 9617a84e134Smrg off_size = PaneSize((Widget)pw, !IsVert(pw)); 9627a84e134Smrg 9637a84e134Smrg ForAllPanes(pw, childP) { 9647a84e134Smrg pane = PaneInfo(*childP); 9657a84e134Smrg if (erase || pane->olddelta != pane->delta) { 966421c997bSmrg on_size = pw->paned.internal_bw; 9677a84e134Smrg if (!erase) { 9687a84e134Smrg on_loc = PaneInfo(*childP)->olddelta - (int) on_size; 9697a84e134Smrg _DrawRect(pw, pw->paned.flipgc, 9707a84e134Smrg on_loc, off_loc, on_size, off_size); 9717a84e134Smrg } 9727a84e134Smrg 9737a84e134Smrg on_loc = PaneInfo(*childP)->delta - (int)on_size; 9747a84e134Smrg 9757a84e134Smrg _DrawRect(pw, pw->paned.flipgc, 9767a84e134Smrg on_loc, off_loc, on_size, off_size); 9777a84e134Smrg 9787a84e134Smrg pane->olddelta = pane->delta; 9797a84e134Smrg } 9807a84e134Smrg } 9817a84e134Smrg} 9827a84e134Smrg 9837a84e134Smrg#define DrawTrackLines(pw) _DrawTrackLines((pw), False); 9847a84e134Smrg#define EraseTrackLines(pw) _DrawTrackLines((pw), True); 985421c997bSmrg/* 9867a84e134Smrg * Function: 9877a84e134Smrg * GetEventLocation 9887a84e134Smrg * 9897a84e134Smrg * Parameters: 9907a84e134Smrg * pw - the paned widget 9917a84e134Smrg * event - pointer to an event 9927a84e134Smrg * 9937a84e134Smrg * Description: 9947a84e134Smrg * Converts and event to an x and y location. 9957a84e134Smrg * 9967a84e134Smrg * Returns: 9977a84e134Smrg * if this is a vertical pane then (y) else (x) 9987a84e134Smrg */ 9997a84e134Smrgstatic int 10007a84e134SmrgGetEventLocation(PanedWidget pw, XEvent *event) 10017a84e134Smrg{ 10027a84e134Smrg int x, y; 10037a84e134Smrg 10047a84e134Smrg switch (event->xany.type) { 10057a84e134Smrg case ButtonPress: 1006421c997bSmrg case ButtonRelease: 10077a84e134Smrg x = event->xbutton.x_root; 10087a84e134Smrg y = event->xbutton.y_root; 10097a84e134Smrg break; 10107a84e134Smrg case KeyPress: 1011421c997bSmrg case KeyRelease: 10127a84e134Smrg x = event->xkey.x_root; 10137a84e134Smrg y = event->xkey.y_root; 10147a84e134Smrg break; 1015421c997bSmrg case MotionNotify: 10167a84e134Smrg x = event->xmotion.x_root; 10177a84e134Smrg y = event->xmotion.y_root; 10187a84e134Smrg break; 1019421c997bSmrg default: 10207a84e134Smrg x = pw->paned.start_loc; 10217a84e134Smrg y = pw->paned.start_loc; 10227a84e134Smrg } 10237a84e134Smrg 1024421c997bSmrg if (IsVert(pw)) 10257a84e134Smrg return (y); 10267a84e134Smrg 10277a84e134Smrg return (x); 10287a84e134Smrg} 10297a84e134Smrg 10307a84e134Smrg/* 10317a84e134Smrg * Function: 10327a84e134Smrg * StartGripAdjustment 10337a84e134Smrg * 10347a84e134Smrg * Parameters: 10357a84e134Smrg * pw - paned widget 10367a84e134Smrg * grip - grip widget selected 10377a84e134Smrg * dir - direction that we are to be moving 10387a84e134Smrg * 10397a84e134Smrg * Description: 10407a84e134Smrg * Starts the grip adjustment procedure. 10417a84e134Smrg */ 10427a84e134Smrgstatic void 10437a84e134SmrgStartGripAdjustment(PanedWidget pw, Widget grip, Direction dir) 10447a84e134Smrg{ 10457a84e134Smrg Widget *childP; 10467a84e134Smrg 10477a84e134Smrg pw->paned.whichadd = pw->paned.whichsub = NULL; 10487a84e134Smrg 10497a84e134Smrg if (dir == ThisBorderOnly || dir == UpLeftPane) 10507a84e134Smrg pw->paned.whichadd = pw->composite.children[PaneIndex(grip)]; 10517a84e134Smrg if (dir == ThisBorderOnly || dir == LowRightPane) 10527a84e134Smrg pw->paned.whichsub = pw->composite.children[PaneIndex(grip) + 1]; 10537a84e134Smrg 10547a84e134Smrg /* 10557a84e134Smrg * Change the cursor 10567a84e134Smrg */ 10577a84e134Smrg if (XtIsRealized(grip)) { 1058efbcb2bfSmrg Cursor cursor; 1059efbcb2bfSmrg 10607a84e134Smrg if (IsVert(pw)) { 1061421c997bSmrg if (dir == UpLeftPane) 10627a84e134Smrg cursor = pw->paned.adjust_upper_cursor; 1063421c997bSmrg else if (dir == LowRightPane) 1064421c997bSmrg cursor = pw->paned.adjust_lower_cursor; 10657a84e134Smrg else { 10667a84e134Smrg if (pw->paned.adjust_this_cursor == None) 10677a84e134Smrg cursor = pw->paned.v_adjust_this_cursor; 10687a84e134Smrg else 10697a84e134Smrg cursor = pw->paned.adjust_this_cursor; 10707a84e134Smrg } 10717a84e134Smrg } 10727a84e134Smrg else { 1073421c997bSmrg if (dir == UpLeftPane) 10747a84e134Smrg cursor = pw->paned.adjust_left_cursor; 1075421c997bSmrg else if (dir == LowRightPane) 1076421c997bSmrg cursor = pw->paned.adjust_right_cursor; 10777a84e134Smrg else { 10787a84e134Smrg if (pw->paned.adjust_this_cursor == None) 10797a84e134Smrg cursor = pw->paned.h_adjust_this_cursor; 10807a84e134Smrg else 10817a84e134Smrg cursor = pw->paned.adjust_this_cursor; 10827a84e134Smrg } 10837a84e134Smrg } 1084421c997bSmrg 10857a84e134Smrg XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor); 10867a84e134Smrg } 10877a84e134Smrg 10887a84e134Smrg EraseInternalBorders(pw); 1089421c997bSmrg ForAllPanes(pw, childP) 10907a84e134Smrg PaneInfo(*childP)->olddelta = -99; 10917a84e134Smrg 10927a84e134Smrg EraseTrackLines(pw); 10937a84e134Smrg} 10947a84e134Smrg 10957a84e134Smrg/* 10967a84e134Smrg * Function: 10977a84e134Smrg * MoveGripAdjustment 10987a84e134Smrg * 10997a84e134Smrg * Parameters: 11007a84e134Smrg * pw - paned widget 11017a84e134Smrg * grip - grip that we are moving 11027a84e134Smrg * dir - direction the pane we are interested is w.r.t the grip 11037a84e134Smrg * loc - location of pointer in proper direction 11047a84e134Smrg * 11057a84e134Smrg * Description: 11067a84e134Smrg * This routine moves all panes around when a grip is moved. 11077a84e134Smrg */ 11087a84e134Smrgstatic void 11097a84e134SmrgMoveGripAdjustment(PanedWidget pw, Widget grip, Direction dir, int loc) 11107a84e134Smrg{ 11117a84e134Smrg int diff, add_size = 0, sub_size = 0; 11127a84e134Smrg 11137a84e134Smrg diff = loc - pw->paned.start_loc; 11147a84e134Smrg 1115421c997bSmrg if (pw->paned.whichadd) 11167a84e134Smrg add_size = PaneSize(pw->paned.whichadd, IsVert(pw)) + diff; 11177a84e134Smrg 1118421c997bSmrg if (pw->paned.whichsub) 11197a84e134Smrg sub_size = PaneSize(pw->paned.whichsub, IsVert(pw)) - diff; 11207a84e134Smrg 11217a84e134Smrg /* 11227a84e134Smrg * If moving this border only then do not allow either of the borders 11237a84e134Smrg * to go beyond the min or max size allowed 11247a84e134Smrg */ 11257a84e134Smrg if (dir == ThisBorderOnly) { 11267a84e134Smrg int old_add_size = add_size, old_sub_size; 11277a84e134Smrg 1128efbcb2bfSmrg if (pw->paned.whichadd == NULL) 1129efbcb2bfSmrg return; 1130efbcb2bfSmrg 11317a84e134Smrg AssignMax(add_size, (int)PaneInfo(pw->paned.whichadd)->min); 11327a84e134Smrg AssignMin(add_size, (int)PaneInfo(pw->paned.whichadd)->max); 1133421c997bSmrg if (add_size != old_add_size) 11347a84e134Smrg sub_size += old_add_size - add_size; 11357a84e134Smrg 1136efbcb2bfSmrg if (pw->paned.whichsub == NULL) 1137efbcb2bfSmrg return; 1138efbcb2bfSmrg 11397a84e134Smrg old_sub_size = sub_size; 11407a84e134Smrg AssignMax(sub_size, (int)PaneInfo(pw->paned.whichsub)->min); 11417a84e134Smrg AssignMin(sub_size, (int)PaneInfo(pw->paned.whichsub)->max); 11427a84e134Smrg if (sub_size != old_sub_size) 11437a84e134Smrg return; /* Abort to current sizes */ 11447a84e134Smrg } 11457a84e134Smrg 11467a84e134Smrg if (add_size != 0) 11477a84e134Smrg PaneInfo(pw->paned.whichadd)->size = add_size; 11487a84e134Smrg if (sub_size != 0) 11497a84e134Smrg PaneInfo(pw->paned.whichsub)->size = sub_size; 11507a84e134Smrg RefigureLocations(pw, PaneIndex(grip), dir); 11517a84e134Smrg DrawTrackLines(pw); 11527a84e134Smrg} 11537a84e134Smrg 11547a84e134Smrg/* 11557a84e134Smrg * Function: 11567a84e134Smrg * CommitGripAdjustment 11577a84e134Smrg * 11587a84e134Smrg * Parameters: 11597a84e134Smrg * pw - paned widget 11607a84e134Smrg * 11617a84e134Smrg * Description: 11627a84e134Smrg * Commits the grip adjustment. 11637a84e134Smrg */ 11647a84e134Smrgstatic void 11657a84e134SmrgCommitGripAdjustment(PanedWidget pw) 11667a84e134Smrg{ 11677a84e134Smrg EraseTrackLines(pw); 11687a84e134Smrg CommitNewLocations(pw); 11697a84e134Smrg DrawInternalBorders(pw); 1170421c997bSmrg 11717a84e134Smrg /* 11727a84e134Smrg * Since the user selected this size then use it as the preferred size 11737a84e134Smrg */ 11747a84e134Smrg if (pw->paned.whichadd) { 11757a84e134Smrg Pane pane = PaneInfo(pw->paned.whichadd); 11767a84e134Smrg 11775ec34c4cSmrg pane->wp_size = (Dimension)pane->size; 11787a84e134Smrg } 11797a84e134Smrg if (pw->paned.whichsub) { 11807a84e134Smrg Pane pane = PaneInfo(pw->paned.whichsub); 11817a84e134Smrg 11825ec34c4cSmrg pane->wp_size = (Dimension)pane->size; 11837a84e134Smrg } 11847a84e134Smrg} 11857a84e134Smrg 11867a84e134Smrg/* 11877a84e134Smrg * Function: 11887a84e134Smrg * HandleGrip 11897a84e134Smrg * 11907a84e134Smrg * Parameters: 11917a84e134Smrg * grip - grip widget that has been moved 11927a84e134Smrg * temp - (not used) 11937a84e134Smrg * call_data - data passed to us from the grip widget 11947a84e134Smrg * 11957a84e134Smrg * Description: 11967a84e134Smrg * Handles the grip manipulations. 11977a84e134Smrg */ 11987a84e134Smrg/*ARGSUSED*/ 11997a84e134Smrgstatic void 12005ec34c4cSmrgHandleGrip(Widget grip, XtPointer temp _X_UNUSED, XtPointer callData) 12017a84e134Smrg{ 12027a84e134Smrg XawGripCallData call_data = (XawGripCallData)callData; 12037a84e134Smrg PanedWidget pw = (PanedWidget) XtParent(grip); 12047a84e134Smrg int loc; 12057a84e134Smrg char action_type[2], direction[2]; 12067a84e134Smrg Cursor cursor; 12077a84e134Smrg Arg arglist[1]; 12087a84e134Smrg 12097a84e134Smrg if (call_data->num_params) 12107a84e134Smrg XmuNCopyISOLatin1Uppered(action_type, call_data->params[0], 12117a84e134Smrg sizeof(action_type)); 12127a84e134Smrg 12137a84e134Smrg if (call_data->num_params == 0 12147a84e134Smrg || (action_type[0] == 'C' && call_data->num_params != 1) 12157a84e134Smrg || (action_type[0] != 'C' && call_data->num_params != 2)) 12167a84e134Smrg XtAppError(XtWidgetToApplicationContext(grip), 12177a84e134Smrg "Paned GripAction has been passed incorrect parameters."); 12187a84e134Smrg 12197a84e134Smrg loc = GetEventLocation(pw, (XEvent *)call_data->event); 12207a84e134Smrg 12217a84e134Smrg if (action_type[0] != 'C') 12227a84e134Smrg XmuNCopyISOLatin1Uppered(direction, call_data->params[1], 12237a84e134Smrg sizeof(direction)); 12247a84e134Smrg 12257a84e134Smrg switch (action_type[0]) { 12267a84e134Smrg case 'S': /* Start adjustment */ 12277a84e134Smrg pw->paned.resize_children_to_pref = False; 12287a84e134Smrg StartGripAdjustment(pw, grip, (Direction)direction[0]); 1229421c997bSmrg pw->paned.start_loc = loc; 12307a84e134Smrg break; 1231421c997bSmrg case 'M': 12327a84e134Smrg MoveGripAdjustment(pw, grip, (Direction)direction[0], loc); 12337a84e134Smrg break; 12347a84e134Smrg case 'C': 12357a84e134Smrg XtSetArg(arglist[0], XtNcursor, &cursor); 12367a84e134Smrg XtGetValues(grip, arglist, 1); 12377a84e134Smrg XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor); 12387a84e134Smrg CommitGripAdjustment(pw); 12397a84e134Smrg break; 12407a84e134Smrg default: 12417a84e134Smrg XtAppError(XtWidgetToApplicationContext(grip), 12427a84e134Smrg "Paned GripAction(); 1st parameter invalid"); 12437a84e134Smrg break; 12447a84e134Smrg } 12457a84e134Smrg} 12467a84e134Smrg 12477a84e134Smrg/* 12487a84e134Smrg * Function: 12497a84e134Smrg * ResortChildren 12507a84e134Smrg * 12517a84e134Smrg * Arguments: 12527a84e134Smrg * pw - paned widget 12537a84e134Smrg * 12547a84e134Smrg * Description: 12557a84e134Smrg * Resorts the children so that all managed children are first. 12567a84e134Smrg */ 12577a84e134Smrgstatic void 12587a84e134SmrgResortChildren(PanedWidget pw) 12597a84e134Smrg{ 12607a84e134Smrg Widget *unmanagedP, *childP; 12617a84e134Smrg 12627a84e134Smrg unmanagedP = NULL; 12637a84e134Smrg ForAllChildren(pw, childP) { 12647a84e134Smrg if (!IsPane(*childP) || !XtIsManaged(*childP)) { 12657a84e134Smrg /* 12667a84e134Smrg * We only keep track of the first unmanaged pane 12677a84e134Smrg */ 1268421c997bSmrg if (unmanagedP == NULL) 12697a84e134Smrg unmanagedP = childP; 12707a84e134Smrg } 12717a84e134Smrg else { /* must be a managed pane */ 12727a84e134Smrg /* 1273421c997bSmrg * If an earlier widget was not a managed pane, then swap 12747a84e134Smrg */ 12757a84e134Smrg if (unmanagedP != NULL) { 12767a84e134Smrg Widget child = *unmanagedP; 12777a84e134Smrg 12787a84e134Smrg *unmanagedP = *childP; 12797a84e134Smrg *childP = child; 12807a84e134Smrg childP = unmanagedP; /* easiest to just back-track */ 12817a84e134Smrg unmanagedP = NULL; /* in case there is another managed */ 12827a84e134Smrg } 12837a84e134Smrg } 12847a84e134Smrg } 12857a84e134Smrg} 12867a84e134Smrg 12877a84e134Smrg/* 12887a84e134Smrg * Function: 12897a84e134Smrg * ManageAndUnmanageGrips 12907a84e134Smrg * 12917a84e134Smrg * Parameters: 12927a84e134Smrg * pw - paned widget 12937a84e134Smrg * 12947a84e134Smrg * Description: 12957a84e134Smrg * This function manages and unmanages the grips so that 12967a84e134Smrg * the managed state of each grip matches that of its pane. 12977a84e134Smrg */ 1298421c997bSmrgstatic void 12997a84e134SmrgManageAndUnmanageGrips(PanedWidget pw) 13007a84e134Smrg{ 13017a84e134Smrg WidgetList managed_grips, unmanaged_grips; 13027a84e134Smrg Widget *managedP, *unmanagedP, *childP; 13037a84e134Smrg Cardinal alloc_size; 13047a84e134Smrg 13055ec34c4cSmrg alloc_size = (Cardinal)(sizeof(Widget) * (pw->composite.num_children >> 1)); 13067a84e134Smrg managedP = managed_grips = (WidgetList)XtMalloc(alloc_size); 13077a84e134Smrg unmanagedP = unmanaged_grips = (WidgetList)XtMalloc(alloc_size); 13087a84e134Smrg 13097a84e134Smrg ForAllChildren(pw, childP) 13107a84e134Smrg if (IsPane(*childP) && HasGrip(*childP)) { 13117a84e134Smrg if (XtIsManaged(*childP)) 13127a84e134Smrg *managedP++ = PaneInfo(*childP)->grip; 13137a84e134Smrg else 13147a84e134Smrg *unmanagedP++ = PaneInfo(*childP)->grip; 13157a84e134Smrg } 1316421c997bSmrg 13177a84e134Smrg if (managedP != managed_grips) { 13187a84e134Smrg *unmanagedP++ = *--managedP; /* Last grip is never managed */ 13195ec34c4cSmrg XtManageChildren(managed_grips, (Cardinal)(managedP - managed_grips)); 13207a84e134Smrg } 13217a84e134Smrg 13227a84e134Smrg if (unmanagedP != unmanaged_grips) 13235ec34c4cSmrg XtUnmanageChildren(unmanaged_grips, (Cardinal)(unmanagedP - unmanaged_grips)); 13247a84e134Smrg 13257a84e134Smrg XtFree((char *)managed_grips); 13267a84e134Smrg XtFree((char *)unmanaged_grips); 13277a84e134Smrg} 13287a84e134Smrg 13297a84e134Smrg/* 13307a84e134Smrg * Function: 13317a84e134Smrg * CreateGrip 13327a84e134Smrg * 13337a84e134Smrg * Parameters: 13347a84e134Smrg * child - child that wants a grip to be created for it 13357a84e134Smrg * 13367a84e134Smrg * Description: 13377a84e134Smrg * Creates a grip widget. 13387a84e134Smrg */ 13397a84e134Smrgstatic void 13407a84e134SmrgCreateGrip(Widget child) 13417a84e134Smrg{ 13427a84e134Smrg PanedWidget pw = (PanedWidget)XtParent(child); 13437a84e134Smrg Arg arglist[2]; 13447a84e134Smrg Cardinal num_args = 0; 13457a84e134Smrg Cursor cursor; 1346421c997bSmrg 13477a84e134Smrg XtSetArg(arglist[num_args], XtNtranslations, pw->paned.grip_translations); 13487a84e134Smrg num_args++; 13497a84e134Smrg if ((cursor = pw->paned.grip_cursor) == None) { 13507a84e134Smrg if (IsVert(pw)) 13517a84e134Smrg cursor = pw->paned.v_grip_cursor; 13527a84e134Smrg else 13537a84e134Smrg cursor = pw->paned.h_grip_cursor; 13547a84e134Smrg } 13557a84e134Smrg 13567a84e134Smrg XtSetArg(arglist[num_args], XtNcursor, cursor); 13577a84e134Smrg num_args++; 13587a84e134Smrg PaneInfo(child)->grip = XtCreateWidget("grip", gripWidgetClass, (Widget)pw, 13597a84e134Smrg arglist, num_args); 1360421c997bSmrg 1361421c997bSmrg XtAddCallback(PaneInfo(child)->grip, XtNcallback, 13627a84e134Smrg HandleGrip, (XtPointer)child); 13637a84e134Smrg} 13647a84e134Smrg 13657a84e134Smrg/* 13667a84e134Smrg * Function: 13677a84e134Smrg * GetGCs 13687a84e134Smrg * 13697a84e134Smrg * Parameters: 13707a84e134Smrg * w - paned widget 13717a84e134Smrg */ 13727a84e134Smrgstatic void 13737a84e134SmrgGetGCs(Widget w) 13747a84e134Smrg{ 13757a84e134Smrg PanedWidget pw = (PanedWidget)w; 13767a84e134Smrg XtGCMask valuemask; 13777a84e134Smrg XGCValues values; 13787a84e134Smrg 13797a84e134Smrg /* 13807a84e134Smrg * Draw pane borders in internal border color 13817a84e134Smrg */ 1382421c997bSmrg values.foreground = pw->paned.internal_bp; 13837a84e134Smrg valuemask = GCForeground; 13847a84e134Smrg pw->paned.normgc = XtGetGC(w, valuemask, &values); 13857a84e134Smrg 13867a84e134Smrg /* 13877a84e134Smrg * Erase pane borders with background color 13887a84e134Smrg */ 1389421c997bSmrg values.foreground = pw->core.background_pixel; 13907a84e134Smrg valuemask = GCForeground; 13917a84e134Smrg pw->paned.invgc = XtGetGC(w, valuemask, &values); 13927a84e134Smrg 13937a84e134Smrg /* 13947a84e134Smrg * Draw Track lines (animate pane borders) in 13957a84e134Smrg * internal border color ^ bg color 13967a84e134Smrg */ 13977a84e134Smrg values.function = GXinvert; 13987a84e134Smrg values.plane_mask = pw->paned.internal_bp ^ pw->core.background_pixel; 1399421c997bSmrg values.subwindow_mode = IncludeInferiors; 14007a84e134Smrg valuemask = GCPlaneMask | GCFunction | GCSubwindowMode; 14017a84e134Smrg pw->paned.flipgc = XtGetGC(w, valuemask, &values); 14027a84e134Smrg} 14037a84e134Smrg 14047a84e134Smrg/* 14057a84e134Smrg * Function: 14067a84e134Smrg * SetChildrenPrefSizes 14077a84e134Smrg * 14087a84e134Smrg * Parameters: 14097a84e134Smrg * pw - paned widget 14107a84e134Smrg * 14117a84e134Smrg * Description: 14127a84e134Smrg * Sets the preferred sizes of the children. 14137a84e134Smrg */ 14147a84e134Smrgstatic void 14157a84e134SmrgSetChildrenPrefSizes(PanedWidget pw, unsigned int off_size) 14167a84e134Smrg{ 14177a84e134Smrg Widget *childP; 14187a84e134Smrg Boolean vert = IsVert(pw); 14197a84e134Smrg XtWidgetGeometry request, reply; 14207a84e134Smrg 14217a84e134Smrg ForAllPanes(pw, childP) 14227a84e134Smrg if (pw->paned.resize_children_to_pref || PaneInfo(*childP)->size == 0 || 14237a84e134Smrg PaneInfo(*childP)->resize_to_pref) { 14247a84e134Smrg if (PaneInfo(*childP)->preferred_size != PANED_ASK_CHILD) 14257a84e134Smrg PaneInfo(*childP)->wp_size = PaneInfo(*childP)->preferred_size; 14267a84e134Smrg else { 14277a84e134Smrg if(vert) { 14287a84e134Smrg request.request_mode = CWWidth; 14295ec34c4cSmrg request.width = (Dimension) off_size; 14307a84e134Smrg } 14317a84e134Smrg else { 14327a84e134Smrg request.request_mode = CWHeight; 14335ec34c4cSmrg request.height = (Dimension) off_size; 14347a84e134Smrg } 14357a84e134Smrg 14367a84e134Smrg if ((XtQueryGeometry(*childP, &request, &reply) 14377a84e134Smrg == XtGeometryAlmost) 14387a84e134Smrg && (reply.request_mode = (vert ? CWHeight : CWWidth))) 14397a84e134Smrg PaneInfo(*childP)->wp_size = GetRequestInfo(&reply, vert); 14407a84e134Smrg else 14417a84e134Smrg PaneInfo(*childP)->wp_size = PaneSize(*childP, vert); 14427a84e134Smrg } 14437a84e134Smrg 14447a84e134Smrg PaneInfo(*childP)->size = PaneInfo(*childP)->wp_size; 14457a84e134Smrg } 14467a84e134Smrg} 14477a84e134Smrg 14487a84e134Smrg/* 14497a84e134Smrg * Function: 14507a84e134Smrg * ChangeAllGripCursors 14517a84e134Smrg * 14527a84e134Smrg * Parameters: 14537a84e134Smrg * pw - paned widget 14547a84e134Smrg * 14557a84e134Smrg * Description: 14567a84e134Smrg * Changes all the grip cursors. 14577a84e134Smrg */ 14587a84e134Smrgstatic void 14597a84e134SmrgChangeAllGripCursors(PanedWidget pw) 14607a84e134Smrg{ 14617a84e134Smrg Widget *childP; 14627a84e134Smrg 14637a84e134Smrg ForAllPanes(pw, childP) { 14647a84e134Smrg Cursor cursor; 1465421c997bSmrg 14667a84e134Smrg if ((cursor = pw->paned.grip_cursor) == None) { 14677a84e134Smrg if (IsVert(pw)) 14687a84e134Smrg cursor = pw->paned.v_grip_cursor; 14697a84e134Smrg else 14707a84e134Smrg cursor = pw->paned.h_grip_cursor; 14717a84e134Smrg } 14727a84e134Smrg 14737a84e134Smrg if (HasGrip(*childP)) { 1474efbcb2bfSmrg Arg arglist[1]; 1475efbcb2bfSmrg 14767a84e134Smrg XtSetArg(arglist[0], XtNcursor, cursor); 14777a84e134Smrg XtSetValues(PaneInfo(*childP)->grip, arglist, 1); 14787a84e134Smrg } 14797a84e134Smrg } 14807a84e134Smrg} 1481421c997bSmrg 14827a84e134Smrg/* 14837a84e134Smrg * Function: 14847a84e134Smrg * PushPaneStack 14857a84e134Smrg * 14867a84e134Smrg * Parameters: 14877a84e134Smrg * pw - paned widget 14887a84e134Smrg * pane - pane that we are pushing 14897a84e134Smrg * 14907a84e134Smrg * Description: 14917a84e134Smrg * Pushes a value onto the pane stack. 14927a84e134Smrg */ 14937a84e134Smrgstatic void 14947a84e134SmrgPushPaneStack(PanedWidget pw, Pane pane) 14957a84e134Smrg{ 14967a84e134Smrg PaneStack *stack = (PaneStack *)XtMalloc(sizeof(PaneStack)); 14977a84e134Smrg 14987a84e134Smrg stack->next = pw->paned.stack; 14997a84e134Smrg stack->pane = pane; 15007a84e134Smrg stack->start_size = pane->size; 15017a84e134Smrg 15027a84e134Smrg pw->paned.stack = stack; 15037a84e134Smrg} 15047a84e134Smrg 15057a84e134Smrg/* 15067a84e134Smrg * Function: 15077a84e134Smrg * GetPaneStack 15087a84e134Smrg * 15097a84e134Smrg * Parameters: 15107a84e134Smrg * pw - paned widget 15117a84e134Smrg * shrink - True if we want to shrink this pane, False otherwise 15127a84e134Smrg * pane - pane that we are popping (return) 15137a84e134Smrg * start_size - size that this pane started at (return) 15147a84e134Smrg * 15157a84e134Smrg * Description: 15167a84e134Smrg * Gets the top value from the pane stack. 15177a84e134Smrg */ 15187a84e134Smrgstatic void 15197a84e134SmrgGetPaneStack(PanedWidget pw, Bool shrink, Pane *pane, int *start_size) 15207a84e134Smrg{ 15217a84e134Smrg if (pw->paned.stack == NULL) { 1522421c997bSmrg *pane = NULL; 15237a84e134Smrg return; 15247a84e134Smrg } 15257a84e134Smrg 15267a84e134Smrg *pane = pw->paned.stack->pane; 15277a84e134Smrg *start_size = pw->paned.stack->start_size; 15287a84e134Smrg 15297a84e134Smrg if (shrink != ((*pane)->size > *start_size)) 15307a84e134Smrg *pane = NULL; 15317a84e134Smrg} 15327a84e134Smrg 15337a84e134Smrg/* 15347a84e134Smrg * Function: 15357a84e134Smrg * PopPaneStack 15367a84e134Smrg * 15377a84e134Smrg * Parameters: 15387a84e134Smrg * pw - paned widget 15397a84e134Smrg * 15407a84e134Smrg * Description: 15417a84e134Smrg * Pops the top item off the pane stack. 15427a84e134Smrg * 15437a84e134Smrg * Returns: True if this is not the last element on the stack 15447a84e134Smrg */ 15457a84e134Smrgstatic Bool 15467a84e134SmrgPopPaneStack(PanedWidget pw) 15477a84e134Smrg{ 15487a84e134Smrg PaneStack *stack = pw->paned.stack; 15497a84e134Smrg 15507a84e134Smrg if (stack == NULL) 15517a84e134Smrg return (False); 15527a84e134Smrg 15537a84e134Smrg pw->paned.stack = stack->next; 15547a84e134Smrg XtFree((char *)stack); 15557a84e134Smrg 15567a84e134Smrg if (pw->paned.stack == NULL) 15577a84e134Smrg return (False); 15587a84e134Smrg 15597a84e134Smrg return (True); 15607a84e134Smrg} 15617a84e134Smrg 15627a84e134Smrg/* 15637a84e134Smrg * Function: 15647a84e134Smrg * ClearPaneStack 15657a84e134Smrg * 15667a84e134Smrg * Parameters: 15677a84e134Smrg * pw - paned widget 15687a84e134Smrg * 15697a84e134Smrg * Description: 15707a84e134Smrg * Removes all entries from the pane stack. 15717a84e134Smrg */ 15727a84e134Smrgstatic void 15737a84e134SmrgClearPaneStack(PanedWidget pw) 15747a84e134Smrg{ 15757a84e134Smrg while(PopPaneStack(pw)) 15767a84e134Smrg ; 15777a84e134Smrg} 15787a84e134Smrg 1579421c997bSmrgstatic void 15807a84e134SmrgXawPanedClassInitialize(void) 15817a84e134Smrg{ 15827a84e134Smrg XawInitializeWidgetSet(); 15837a84e134Smrg XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation, 15847a84e134Smrg NULL, 0); 15857a84e134Smrg XtSetTypeConverter(XtROrientation, XtRString, XmuCvtOrientationToString, 15867a84e134Smrg NULL, 0, XtCacheNone, NULL); 15877a84e134Smrg} 15887a84e134Smrg 15897a84e134Smrg/* The Geometry Manager only allows changes after Realize if 1590421c997bSmrg * allow_resize is True in the constraints record. 1591421c997bSmrg * 15927a84e134Smrg * For vertically paned widgets: 15937a84e134Smrg * 15947a84e134Smrg * It only allows height changes, but offers the requested height 15957a84e134Smrg * as a compromise if both width and height changes were requested. 15967a84e134Smrg * 15977a84e134Smrg * For horizontal widgets the converse is true. 15987a84e134Smrg * As all good Geometry Managers should, we will return No if the 15997a84e134Smrg * request will have no effect; i.e. when the requestor is already 16007a84e134Smrg * of the desired geometry. 16017a84e134Smrg */ 16027a84e134Smrgstatic XtGeometryResult 16037a84e134SmrgXawPanedGeometryManager(Widget w, XtWidgetGeometry *request, 16047a84e134Smrg XtWidgetGeometry *reply) 16057a84e134Smrg{ 16067a84e134Smrg PanedWidget pw = (PanedWidget)XtParent(w); 16077a84e134Smrg XtGeometryMask mask = request->request_mode; 16087a84e134Smrg Dimension old_size, old_wpsize, old_paned_size; 16097a84e134Smrg Pane pane = PaneInfo(w); 16107a84e134Smrg Boolean vert = IsVert(pw); 16117a84e134Smrg Dimension on_size, off_size; 16127a84e134Smrg XtGeometryResult result; 16137a84e134Smrg Boolean almost = False; 16147a84e134Smrg 16157a84e134Smrg /* 16167a84e134Smrg * If any of the following is true, disallow the geometry change 16177a84e134Smrg * 16187a84e134Smrg * o The paned widget is realized and allow_resize is false for the pane 16197a84e134Smrg * o The child did not ask to change the on_size 16207a84e134Smrg * o The request is not a width or height request 16217a84e134Smrg * o The requested size is the same as the current size 16227a84e134Smrg */ 16237a84e134Smrg 16247a84e134Smrg if ((XtIsRealized((Widget)pw) && !pane->allow_resize) 16257a84e134Smrg || !(mask & (vert ? CWHeight : CWWidth)) 16265ec34c4cSmrg || (mask & (XtGeometryMask)(~(CWWidth | CWHeight))) 16277a84e134Smrg || GetRequestInfo(request, vert) == PaneSize(w, vert)) 16287a84e134Smrg return (XtGeometryNo); 16297a84e134Smrg 16307a84e134Smrg old_paned_size = PaneSize((Widget)pw, vert); 16317a84e134Smrg old_wpsize = pane->wp_size; 16325ec34c4cSmrg old_size = (Dimension)pane->size; 16337a84e134Smrg 16345ec34c4cSmrg pane->wp_size = (Dimension)(pane->size = GetRequestInfo(request, vert)); 16357a84e134Smrg 16367a84e134Smrg AdjustPanedSize(pw, PaneSize((Widget)pw, !vert), &result, &on_size, 16377a84e134Smrg &off_size); 16387a84e134Smrg 16397a84e134Smrg /* 16407a84e134Smrg * Fool the Refigure Locations proc to thinking that we are 16417a84e134Smrg * a different on_size 16427a84e134Smrg */ 16437a84e134Smrg 16447a84e134Smrg if (result != XtGeometryNo) { 1645421c997bSmrg if (vert) 16467a84e134Smrg XtHeight(pw) = on_size; 1647421c997bSmrg else 16487a84e134Smrg XtWidth(pw) = on_size; 16497a84e134Smrg } 16507a84e134Smrg 16517a84e134Smrg RefigureLocations(pw, PaneIndex(w), AnyPane); 16527a84e134Smrg 16537a84e134Smrg /* 16547a84e134Smrg * Set up reply struct and reset core on_size 16557a84e134Smrg */ 16567a84e134Smrg if (vert) { 16577a84e134Smrg XtHeight(pw) = old_paned_size; 16585ec34c4cSmrg reply->height = (Dimension) pane->size; 16597a84e134Smrg reply->width = off_size; 16607a84e134Smrg } 16617a84e134Smrg else { 16627a84e134Smrg XtWidth(pw) = old_paned_size; 16637a84e134Smrg reply->height = off_size; 16645ec34c4cSmrg reply->width = (Dimension) pane->size; 1665421c997bSmrg } 16667a84e134Smrg 16677a84e134Smrg /* 16687a84e134Smrg * IF either of the following is true 16697a84e134Smrg * 16707a84e134Smrg * o There was a "off_size" request and the new "off_size" is different 16717a84e134Smrg * from that requested 16727a84e134Smrg * o There was no "off_size" request and the new "off_size" is different 1673421c997bSmrg * 16747a84e134Smrg * o The "on_size" we will allow is different from that requested 1675421c997bSmrg * 16767a84e134Smrg * THEN: set almost 16777a84e134Smrg */ 16787a84e134Smrg if (!((vert ? CWWidth : CWHeight) & mask)) { 1679421c997bSmrg if (vert) 16807a84e134Smrg request->width = XtWidth(w); 16817a84e134Smrg else 16827a84e134Smrg request->height = XtHeight(w); 16837a84e134Smrg } 16847a84e134Smrg 16857a84e134Smrg almost = GetRequestInfo(request, !vert) != GetRequestInfo(reply, !vert); 16865ec34c4cSmrg almost = (Boolean)(almost | (GetRequestInfo(request, vert) != GetRequestInfo(reply, vert))); 16877a84e134Smrg 16887a84e134Smrg if ((mask & XtCWQueryOnly) || almost) { 16897a84e134Smrg pane->wp_size = old_wpsize; 16907a84e134Smrg pane->size = old_size; 16917a84e134Smrg RefigureLocations(pw, PaneIndex(w), AnyPane); 16927a84e134Smrg reply->request_mode = CWWidth | CWHeight; 16937a84e134Smrg if (almost) 16947a84e134Smrg return (XtGeometryAlmost); 16957a84e134Smrg } 16967a84e134Smrg else { 16977a84e134Smrg AdjustPanedSize(pw, PaneSize((Widget) pw, !vert), NULL, NULL, NULL); 16987a84e134Smrg CommitNewLocations(pw); /* layout already refigured */ 16997a84e134Smrg } 17007a84e134Smrg 17017a84e134Smrg return (XtGeometryDone); 17027a84e134Smrg} 17037a84e134Smrg 17047a84e134Smrg/*ARGSUSED*/ 17057a84e134Smrgstatic void 17065ec34c4cSmrgXawPanedInitialize(Widget request _X_UNUSED, Widget cnew, 17075ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 17087a84e134Smrg{ 17097a84e134Smrg PanedWidget pw = (PanedWidget)cnew; 17107a84e134Smrg 17117a84e134Smrg GetGCs((Widget)pw); 17127a84e134Smrg 17137a84e134Smrg pw->paned.recursively_called = False; 17147a84e134Smrg pw->paned.stack = NULL; 17157a84e134Smrg pw->paned.resize_children_to_pref = True; 17167a84e134Smrg pw->paned.num_panes = 0; 17177a84e134Smrg} 17187a84e134Smrg 1719421c997bSmrgstatic void 17207a84e134SmrgXawPanedRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) 17217a84e134Smrg{ 17227a84e134Smrg PanedWidget pw = (PanedWidget)w; 17237a84e134Smrg Widget *childP; 17247a84e134Smrg 17257a84e134Smrg if ((attributes->cursor = pw->paned.cursor) != None) 17267a84e134Smrg *valueMask |= CWCursor; 17277a84e134Smrg 17287a84e134Smrg (*SuperClass->core_class.realize)(w, valueMask, attributes); 17297a84e134Smrg 17307a84e134Smrg /* 17317a84e134Smrg * Before we commit the new locations we need to realize all the panes and 17327a84e134Smrg * their grips 17337a84e134Smrg */ 17347a84e134Smrg ForAllPanes(pw, childP) { 17357a84e134Smrg XtRealizeWidget(*childP); 17367a84e134Smrg if (HasGrip(*childP)) 17377a84e134Smrg XtRealizeWidget(PaneInfo(*childP)->grip); 17387a84e134Smrg } 17397a84e134Smrg 17407a84e134Smrg RefigureLocationsAndCommit(w); 17417a84e134Smrg pw->paned.resize_children_to_pref = False; 17427a84e134Smrg} 17437a84e134Smrg 1744421c997bSmrgstatic void 17457a84e134SmrgXawPanedDestroy(Widget w) 17467a84e134Smrg{ 17477a84e134Smrg ReleaseGCs(w); 17487a84e134Smrg} 17497a84e134Smrg 17507a84e134Smrgstatic void 17517a84e134SmrgReleaseGCs(Widget w) 17527a84e134Smrg{ 17537a84e134Smrg PanedWidget pw = (PanedWidget)w; 17547a84e134Smrg 17557a84e134Smrg XtReleaseGC(w, pw->paned.normgc); 17567a84e134Smrg XtReleaseGC(w, pw->paned.invgc); 17577a84e134Smrg XtReleaseGC(w, pw->paned.flipgc); 1758421c997bSmrg} 17597a84e134Smrg 17607a84e134Smrgstatic void 17617a84e134SmrgXawPanedInsertChild(Widget w) 17627a84e134Smrg{ 17637a84e134Smrg Pane pane = PaneInfo(w); 17647a84e134Smrg 17657a84e134Smrg /* insert the child widget in the composite children list with the 17667a84e134Smrg superclass insert_child routine 17677a84e134Smrg */ 17687a84e134Smrg (*SuperClass->composite_class.insert_child)(w); 17697a84e134Smrg 17707a84e134Smrg if (!IsPane(w)) 17717a84e134Smrg return; 17727a84e134Smrg 17737a84e134Smrg if (pane->show_grip == True) { 17747a84e134Smrg CreateGrip(w); 1775421c997bSmrg if (pane->min == PANED_GRIP_SIZE) 17767a84e134Smrg pane->min = PaneSize(pane->grip, IsVert((PanedWidget)XtParent(w))); 17777a84e134Smrg } 17787a84e134Smrg else { 17797a84e134Smrg if (pane->min == PANED_GRIP_SIZE) 17807a84e134Smrg pane->min = 1; 17817a84e134Smrg pane->grip = NULL; 17827a84e134Smrg } 17837a84e134Smrg 17847a84e134Smrg pane->size = 0; 17857a84e134Smrg pane->paned_adjusted_me = False; 17867a84e134Smrg} 17877a84e134Smrg 17887a84e134Smrgstatic void 17897a84e134SmrgXawPanedDeleteChild(Widget w) 17907a84e134Smrg{ 17917a84e134Smrg /* remove the subwidget info and destroy the grip */ 17927a84e134Smrg if (IsPane(w) && HasGrip(w)) 17937a84e134Smrg XtDestroyWidget(PaneInfo(w)->grip); 1794421c997bSmrg 17957a84e134Smrg /* delete the child widget in the composite children list with the 17967a84e134Smrg superclass delete_child routine 17977a84e134Smrg */ 17987a84e134Smrg (*SuperClass->composite_class.delete_child)(w); 17997a84e134Smrg} 18007a84e134Smrg 18017a84e134Smrgstatic void 18027a84e134SmrgXawPanedChangeManaged(Widget w) 18037a84e134Smrg{ 18047a84e134Smrg PanedWidget pw = (PanedWidget)w; 18057a84e134Smrg Boolean vert = IsVert(pw); 18067a84e134Smrg Dimension size; 18077a84e134Smrg Widget *childP; 18087a84e134Smrg 18097a84e134Smrg if (pw->paned.recursively_called++) 18107a84e134Smrg return; 18117a84e134Smrg 18127a84e134Smrg /* 18137a84e134Smrg * If the size is zero then set it to the size of the widest or tallest pane 18147a84e134Smrg */ 18157a84e134Smrg 18167a84e134Smrg if ((size = PaneSize((Widget)pw, !vert)) == 0) { 18177a84e134Smrg size = 1; 18187a84e134Smrg ForAllChildren(pw, childP) 18197a84e134Smrg if (XtIsManaged(*childP) && (PaneSize(*childP, !vert) > size)) 18207a84e134Smrg size = PaneSize(*childP, !vert); 18217a84e134Smrg } 18227a84e134Smrg 18237a84e134Smrg ManageAndUnmanageGrips(pw); 18247a84e134Smrg pw->paned.recursively_called = False; 1825421c997bSmrg ResortChildren(pw); 18267a84e134Smrg 18277a84e134Smrg pw->paned.num_panes = 0; 18287a84e134Smrg ForAllChildren(pw, childP) 18297a84e134Smrg if (IsPane(*childP)) { 18307a84e134Smrg if (XtIsManaged(*childP)) { 18317a84e134Smrg Pane pane = PaneInfo(*childP); 18327a84e134Smrg 18337a84e134Smrg if (HasGrip(*childP)) 18347a84e134Smrg PaneInfo(pane->grip)->position = pw->paned.num_panes; 18355b16253fSmrg pane->position = pw->paned.num_panes; /* TEMPORARY -CDP 3/89 */ 18367a84e134Smrg pw->paned.num_panes++; 18377a84e134Smrg } 18387a84e134Smrg else 1839421c997bSmrg break; /* This list is already sorted */ 18407a84e134Smrg } 18417a84e134Smrg 18427a84e134Smrg SetChildrenPrefSizes((PanedWidget) w, size); 18437a84e134Smrg 18447a84e134Smrg /* 18457a84e134Smrg * ForAllPanes can now be used 18467a84e134Smrg */ 18477a84e134Smrg if (PaneSize((Widget) pw, vert) == 0) 18487a84e134Smrg AdjustPanedSize(pw, size, NULL, NULL, NULL); 18497a84e134Smrg 18507a84e134Smrg if (XtIsRealized((Widget)pw)) 18517a84e134Smrg RefigureLocationsAndCommit((Widget)pw); 18527a84e134Smrg} 18537a84e134Smrg 18547a84e134Smrgstatic void 18557a84e134SmrgXawPanedResize(Widget w) 18567a84e134Smrg{ 18577a84e134Smrg SetChildrenPrefSizes((PanedWidget)w, 18587a84e134Smrg PaneSize(w, !IsVert((PanedWidget)w))); 18597a84e134Smrg RefigureLocationsAndCommit(w); 18607a84e134Smrg} 18617a84e134Smrg 18627a84e134Smrg/*ARGSUSED*/ 18637a84e134Smrgstatic void 18645ec34c4cSmrgXawPanedRedisplay(Widget w, XEvent *event _X_UNUSED, Region region _X_UNUSED) 18657a84e134Smrg{ 18667a84e134Smrg DrawInternalBorders((PanedWidget)w); 18677a84e134Smrg} 18687a84e134Smrg 18697a84e134Smrg/*ARGSUSED*/ 1870421c997bSmrgstatic Boolean 18715ec34c4cSmrgXawPanedSetValues(Widget old, Widget request _X_UNUSED, Widget cnew, 18725ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 18737a84e134Smrg{ 18747a84e134Smrg PanedWidget old_pw = (PanedWidget)old; 18757a84e134Smrg PanedWidget new_pw = (PanedWidget)cnew; 18767a84e134Smrg Boolean redisplay = False; 18777a84e134Smrg 18787a84e134Smrg if ((old_pw->paned.cursor != new_pw->paned.cursor) && XtIsRealized(cnew)) 18797a84e134Smrg XDefineCursor(XtDisplay(cnew), XtWindow(cnew), new_pw->paned.cursor); 18807a84e134Smrg 18817a84e134Smrg if (old_pw->paned.internal_bp != new_pw->paned.internal_bp || 18827a84e134Smrg old_pw->core.background_pixel != new_pw->core.background_pixel) { 18837a84e134Smrg ReleaseGCs(old); 18847a84e134Smrg GetGCs(cnew); 18857a84e134Smrg redisplay = True; 18867a84e134Smrg } 18877a84e134Smrg 18887a84e134Smrg if (old_pw->paned.grip_cursor != new_pw->paned.grip_cursor || 18897a84e134Smrg old_pw->paned.v_grip_cursor != new_pw->paned.v_grip_cursor || 18907a84e134Smrg old_pw->paned.h_grip_cursor != new_pw->paned.h_grip_cursor) 18917a84e134Smrg ChangeAllGripCursors(new_pw); 1892421c997bSmrg 18937a84e134Smrg if (IsVert(old_pw) != IsVert(new_pw)) { 18947a84e134Smrg /* 18957a84e134Smrg * We are fooling the paned widget into thinking that is needs to 18967a84e134Smrg * fully refigure everything, which is what we want 18977a84e134Smrg */ 18987a84e134Smrg if (IsVert(new_pw)) 18997a84e134Smrg XtWidth(new_pw) = 0; 19007a84e134Smrg else 19017a84e134Smrg XtHeight(new_pw) = 0; 19027a84e134Smrg 19037a84e134Smrg new_pw->paned.resize_children_to_pref = True; 19047a84e134Smrg XawPanedChangeManaged(cnew); /* Seems weird, but does the right thing */ 19057a84e134Smrg new_pw->paned.resize_children_to_pref = False; 19067a84e134Smrg if (new_pw->paned.grip_cursor == None) 19077a84e134Smrg ChangeAllGripCursors(new_pw); 19087a84e134Smrg return (True); 19097a84e134Smrg } 19107a84e134Smrg 19117a84e134Smrg if (old_pw->paned.internal_bw != new_pw->paned.internal_bw) { 19127a84e134Smrg AdjustPanedSize(new_pw, PaneSize(cnew, !IsVert(old_pw)), 19137a84e134Smrg NULL, NULL, NULL); 19147a84e134Smrg RefigureLocationsAndCommit(cnew); 19157a84e134Smrg return (True); /* We have done a full configuration, return */ 19167a84e134Smrg } 1917421c997bSmrg 19187a84e134Smrg if (old_pw->paned.grip_indent != new_pw->paned.grip_indent && 19197a84e134Smrg XtIsRealized(cnew)) { 19207a84e134Smrg CommitNewLocations(new_pw); 19217a84e134Smrg redisplay = True; 19227a84e134Smrg } 19237a84e134Smrg 19247a84e134Smrg return (redisplay); 19257a84e134Smrg} 19267a84e134Smrg 19277a84e134Smrg/*ARGSUSED*/ 1928421c997bSmrgstatic Boolean 19295ec34c4cSmrgXawPanedPaneSetValues(Widget old, Widget request _X_UNUSED, Widget cnew, 19305ec34c4cSmrg ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 19317a84e134Smrg{ 19327a84e134Smrg Pane old_pane = PaneInfo(old); 19337a84e134Smrg Pane new_pane = PaneInfo(cnew); 19347a84e134Smrg Boolean redisplay = False; 19357a84e134Smrg 19367a84e134Smrg /* Check for new min and max */ 19377a84e134Smrg if (old_pane->min != new_pane->min || old_pane->max != new_pane->max) 19387a84e134Smrg XawPanedSetMinMax(cnew, (int)new_pane->min, (int)new_pane->max); 19397a84e134Smrg 19407a84e134Smrg /* Check for change in XtNshowGrip */ 19417a84e134Smrg if (old_pane->show_grip != new_pane->show_grip) { 19427a84e134Smrg if (new_pane->show_grip == True) { 19437a84e134Smrg CreateGrip(cnew); 19447a84e134Smrg if (XtIsRealized(XtParent(cnew))) { 19457a84e134Smrg if (XtIsManaged(cnew)) /* if paned is unrealized this will 19467a84e134Smrg happen automatically at realize time 19477a84e134Smrg */ 19487a84e134Smrg XtManageChild(PaneInfo(cnew)->grip); /* manage the grip */ 19497a84e134Smrg XtRealizeWidget(PaneInfo(cnew)->grip); /* realize the grip */ 19507a84e134Smrg CommitNewLocations((PanedWidget)XtParent(cnew)); 19517a84e134Smrg } 19527a84e134Smrg } 19537a84e134Smrg else if (HasGrip(old)) { 19547a84e134Smrg XtDestroyWidget(old_pane->grip); 19557a84e134Smrg new_pane->grip = NULL; 19567a84e134Smrg redisplay = True; 19577a84e134Smrg } 19587a84e134Smrg } 19597a84e134Smrg 19607a84e134Smrg return (redisplay); 19617a84e134Smrg} 19627a84e134Smrg 19637a84e134Smrg/* 19647a84e134Smrg * Public routines 19657a84e134Smrg */ 19667a84e134Smrg/* 19677a84e134Smrg * Function: 19687a84e134Smrg * XawPanedSetMinMax 19697a84e134Smrg * 19707a84e134Smrg * Parameters: 19717a84e134Smrg * widget - widget that is a child of the Paned widget 19727a84e134Smrg * min - new min and max size for the pane 19737a84e134Smrg * max - "" 19747a84e134Smrg * 19757a84e134Smrg * Description: 19767a84e134Smrg * Sets the min and max size for a pane. 19777a84e134Smrg */ 1978421c997bSmrgvoid 19797a84e134SmrgXawPanedSetMinMax(Widget widget, int min, int max) 19807a84e134Smrg{ 19817a84e134Smrg Pane pane = PaneInfo(widget); 19827a84e134Smrg 19835ec34c4cSmrg pane->min = (Dimension) min; 19845ec34c4cSmrg pane->max = (Dimension) max; 19857a84e134Smrg RefigureLocationsAndCommit(widget->core.parent); 19867a84e134Smrg} 19877a84e134Smrg 19887a84e134Smrg/* 19897a84e134Smrg * Function: 19907a84e134Smrg * XawPanedGetMinMax 19917a84e134Smrg * 19927a84e134Smrg * Parameters: 19937a84e134Smrg * widget - widget that is a child of the Paned widget 19947a84e134Smrg * min - current min and max size for the pane (return) 19957a84e134Smrg * max - "" 19967a84e134Smrg * 19977a84e134Smrg * Description: 19987a84e134Smrg * Gets the min and max size for a pane. 19997a84e134Smrg */ 2000421c997bSmrgvoid 20017a84e134SmrgXawPanedGetMinMax(Widget widget, int *min, int *max) 20027a84e134Smrg{ 20037a84e134Smrg Pane pane = PaneInfo(widget); 20047a84e134Smrg 20057a84e134Smrg *min = pane->min; 20067a84e134Smrg *max = pane->max; 20077a84e134Smrg} 20087a84e134Smrg 20097a84e134Smrg/* 20107a84e134Smrg * Function: 20117a84e134Smrg * XawPanedSetRefigureMode 20127a84e134Smrg * 20137a84e134Smrg * Parameters: 20147a84e134Smrg * w - paned widget 20157a84e134Smrg * mode - if False then inhibit refigure 20167a84e134Smrg * 20177a84e134Smrg * Description: 20187a84e134Smrg * Allows a flag to be set the will inhibit 20197a84e134Smrg * the paned widgets relayout routine. 20207a84e134Smrg */ 2021421c997bSmrgvoid 20227a84e134SmrgXawPanedSetRefigureMode(Widget w, 20237a84e134Smrg#if NeedWidePrototypes 20247a84e134Smrg int mode 20257a84e134Smrg#else 20267a84e134Smrg Boolean mode 20277a84e134Smrg#endif 20287a84e134Smrg) 20297a84e134Smrg{ 20307a84e134Smrg ((PanedWidget)w)->paned.refiguremode = mode; 20317a84e134Smrg RefigureLocationsAndCommit(w); 20327a84e134Smrg} 20337a84e134Smrg 20347a84e134Smrg/* 20357a84e134Smrg * Function: 20367a84e134Smrg * XawPanedGetNumSub 20377a84e134Smrg * 20387a84e134Smrg * Parameters: 20397a84e134Smrg * w - paned widget 20407a84e134Smrg * 20417a84e134Smrg * Description: 20427a84e134Smrg * Returns the number of panes in the paned widget. 20437a84e134Smrg * Returns: 20447a84e134Smrg * the number of panes in the paned widget 20457a84e134Smrg */ 2046421c997bSmrgint 20477a84e134SmrgXawPanedGetNumSub(Widget w) 20487a84e134Smrg{ 20497a84e134Smrg return (((PanedWidget)w)->paned.num_panes); 20507a84e134Smrg} 20517a84e134Smrg 20527a84e134Smrg/* 20537a84e134Smrg * Function: 20547a84e134Smrg * XawPanedAllowResize 20557a84e134Smrg * 20567a84e134Smrg * Parameters: 20577a84e134Smrg * widget - child of the paned widget 20587a84e134Smrg * 20597a84e134Smrg * Description: 20607a84e134Smrg * Allows a flag to be set that determines if the paned 20617a84e134Smrg * widget will allow geometry requests from this child. 20627a84e134Smrg */ 2063421c997bSmrgvoid 20647a84e134SmrgXawPanedAllowResize(Widget widget, 20657a84e134Smrg#if NeedWidePrototypes 20667a84e134Smrg int allow_resize 20677a84e134Smrg#else 20687a84e134Smrg Boolean allow_resize 20697a84e134Smrg#endif 20707a84e134Smrg) 20717a84e134Smrg{ 20727a84e134Smrg PaneInfo(widget)->allow_resize = allow_resize; 20737a84e134Smrg} 2074