1
/* $XConsortium: Paned.c,v 1.23 91/07/21 18:56:15 gildea Exp $ */
3
/***********************************************************
4
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
5
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
9
Permission to use, copy, modify, and distribute this software and its
10
documentation for any purpose and without fee is hereby granted,
11
provided that the above copyright notice appear in all copies and that
12
both that copyright notice and this permission notice appear in
13
supporting documentation, and that the names of Digital or MIT not be
14
used in advertising or publicity pertaining to distribution of the
15
software without specific, written prior permission.
17
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25
******************************************************************/
28
* Paned.c - Paned Composite Widget.
30
* Updated and significantly modified from the Athena VPaned Widget.
34
* By: Chris D. Peterson
36
* kit@expo.lcs.mit.edu
39
#include <X11/IntrinsicP.h>
40
#include <X11/cursorfont.h>
41
#include <X11/StringDefs.h>
43
#include <X11/Xmu/Misc.h>
44
#include <X11/Xmu/Converters.h>
46
#include <X11/Xaw/XawInit.h>
47
#include <X11/Xaw/Grip.h>
48
#include <X11/Xaw/PanedP.h>
52
typedef enum {UpLeftPane = 'U', LowRightPane = 'L',
53
ThisBorderOnly = 'T', AnyPane = 'A' } Direction;
58
#define PaneInfo(w) ((Pane)(w)->core.constraints)
59
#define HasGrip(w) (PaneInfo(w)->grip != NULL)
60
#define IsPane(w) ((w)->core.widget_class != gripWidgetClass)
61
#define PaneIndex(w) (PaneInfo(w)->position)
62
#define IsVert(w) ( (w)->paned.orientation == XtorientVertical )
64
#define ForAllPanes(pw, childP) \
65
for ( (childP) = (pw)->composite.children ; \
66
(childP) < (pw)->composite.children + (pw)->paned.num_panes ; \
69
#define ForAllChildren(pw, childP) \
70
for ( (childP) = (pw)->composite.children ; \
71
(childP) < (pw)->composite.children + (pw)->composite.num_children ; \
74
/*****************************************************************************
76
* Full instance record declaration
78
****************************************************************************/
80
static char defGripTranslations[] =
81
"<Btn1Down>: GripAction(Start, UpLeftPane) \n\
82
<Btn2Down>: GripAction(Start, ThisBorderOnly) \n\
83
<Btn3Down>: GripAction(Start, LowRightPane) \n\
84
<Btn1Motion>: GripAction(Move, UpLeft) \n\
85
<Btn2Motion>: GripAction(Move, ThisBorder) \n\
86
<Btn3Motion>: GripAction(Move, LowRight) \n\
87
Any<BtnUp>: GripAction(Commit)";
89
#define offset(field) XtOffsetOf(PanedRec, paned.field)
91
static XtResource resources[] = {
92
{XtNinternalBorderColor, XtCBorderColor, XtRPixel, sizeof(Pixel),
93
offset(internal_bp), XtRString,
94
(XtPointer) XtDefaultForeground},
95
{XtNinternalBorderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
96
offset(internal_bw), XtRImmediate, (XtPointer) 1},
97
{XtNgripIndent, XtCGripIndent, XtRPosition, sizeof(Position),
98
offset(grip_indent), XtRImmediate, (XtPointer) 10},
99
{XtNrefigureMode, XtCBoolean, XtRBoolean, sizeof(Boolean),
100
offset(refiguremode), XtRImmediate, (XtPointer) TRUE},
101
{XtNgripTranslations, XtCTranslations, XtRTranslationTable,
102
sizeof(XtTranslations),
103
offset(grip_translations), XtRString, (XtPointer)defGripTranslations},
104
{XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
105
offset(orientation), XtRImmediate, (XtPointer) XtorientVertical},
107
/* Cursors - both horiz and vertical have to work. */
109
{XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
110
offset(cursor), XtRImmediate, None},
111
{XtNgripCursor, XtCCursor, XtRCursor, sizeof(Cursor),
112
offset(grip_cursor), XtRImmediate, None},
113
{XtNverticalGripCursor, XtCCursor, XtRCursor, sizeof(Cursor),
114
offset(v_grip_cursor), XtRString, "sb_v_double_arrow"},
115
{XtNhorizontalGripCursor, XtCCursor, XtRCursor, sizeof(Cursor),
116
offset(h_grip_cursor), XtRString, "sb_h_double_arrow"},
118
{XtNbetweenCursor, XtCCursor, XtRCursor, sizeof(Cursor),
119
offset(adjust_this_cursor), XtRString, None},
120
{XtNverticalBetweenCursor, XtCCursor, XtRCursor, sizeof(Cursor),
121
offset(v_adjust_this_cursor), XtRString, "sb_left_arrow"},
122
{XtNhorizontalBetweenCursor, XtCCursor, XtRCursor, sizeof(Cursor),
123
offset(h_adjust_this_cursor), XtRString, "sb_up_arrow"},
125
{XtNupperCursor, XtCCursor, XtRCursor, sizeof(Cursor),
126
offset(adjust_upper_cursor), XtRString, "sb_up_arrow"},
127
{XtNlowerCursor, XtCCursor, XtRCursor, sizeof(Cursor),
128
offset(adjust_lower_cursor), XtRString, "sb_down_arrow"},
129
{XtNleftCursor, XtCCursor, XtRCursor, sizeof(Cursor),
130
offset(adjust_left_cursor), XtRString, "sb_left_arrow"},
131
{XtNrightCursor, XtCCursor, XtRCursor, sizeof(Cursor),
132
offset(adjust_right_cursor), XtRString, "sb_right_arrow"},
137
#define offset(field) XtOffsetOf(PanedConstraintsRec, paned.field)
139
static XtResource subresources[] = {
140
{XtNallowResize, XtCBoolean, XtRBoolean, sizeof(Boolean),
141
offset(allow_resize), XtRImmediate, (XtPointer) FALSE},
142
{XtNposition, XtCPosition, XtRInt, sizeof(int),
143
offset(position), XtRImmediate, (XtPointer) 0},
144
{XtNmin, XtCMin, XtRDimension, sizeof(Dimension),
145
offset(min), XtRImmediate, (XtPointer) PANED_GRIP_SIZE},
146
{XtNmax, XtCMax, XtRDimension, sizeof(Dimension),
147
offset(max), XtRImmediate, (XtPointer) ~0},
148
{XtNpreferredPaneSize, XtCPreferredPaneSize, XtRDimension,
149
sizeof(Dimension), offset(preferred_size),
150
XtRImmediate, (XtPointer) PANED_ASK_CHILD},
151
{XtNresizeToPreferred, XtCBoolean, XtRBoolean, sizeof(Boolean),
152
offset(resize_to_pref), XtRImmediate, (XtPointer) FALSE},
153
{XtNskipAdjust, XtCBoolean, XtRBoolean, sizeof(Boolean),
154
offset(skip_adjust), XtRImmediate, (XtPointer) FALSE},
155
{XtNshowGrip, XtCShowGrip, XtRBoolean, sizeof(Boolean),
156
offset(show_grip), XtRImmediate, (XtPointer) TRUE},
161
static void ClassInitialize(), Initialize();
162
static void Realize(), Resize();
163
static void Redisplay();
164
static void GetGCs(), ReleaseGCs();
165
static void RefigureLocationsAndCommit();
166
static Boolean SetValues();
167
static XtGeometryResult GeometryManager();
168
static void ChangeManaged();
169
static void InsertChild();
170
static void DeleteChild();
171
static Boolean PaneSetValues();
172
static Dimension PaneSize(), GetRequestInfo();
173
static Boolean SatisfiesRule1(), SatisfiesRule2(), SatisfiesRule3();
175
static void PushPaneStack();
176
static void GetPaneStack();
177
static Boolean PopPaneStack();
178
static void ClearPaneStack();
180
#define SuperClass ((ConstraintWidgetClass)&constraintClassRec)
182
PanedClassRec panedClassRec = {
184
/* core class fields */
185
/* superclass */ (WidgetClass) SuperClass,
186
/* class name */ "Paned",
187
/* size */ sizeof(PanedRec),
188
/* class_initialize */ ClassInitialize,
189
/* class_part init */ NULL,
190
/* class_inited */ FALSE,
191
/* initialize */ Initialize,
192
/* initialize_hook */ NULL,
193
/* realize */ Realize,
196
/* resources */ resources,
197
/* resource_count */ XtNumber(resources),
198
/* xrm_class */ NULLQUARK,
199
/* compress_motion */ TRUE,
200
/* compress_exposure */ TRUE,
201
/* compress_enterleave*/ TRUE,
202
/* visible_interest */ FALSE,
203
/* destroy */ ReleaseGCs,
205
/* expose */ Redisplay,
206
/* set_values */ SetValues,
207
/* set_values_hook */ NULL,
208
/* set_values_almost */ XtInheritSetValuesAlmost,
209
/* get_values_hook */ NULL,
210
/* accept_focus */ NULL,
211
/* version */ XtVersion,
212
/* callback_private */ NULL,
214
/* query_geometry */ XtInheritQueryGeometry,
215
/* display_accelerator*/ XtInheritDisplayAccelerator,
218
/* composite class fields */
219
/* geometry_manager */ GeometryManager,
220
/* change_managed */ ChangeManaged,
221
/* insert_child */ InsertChild,
222
/* delete_child */ DeleteChild,
225
/* constraint class fields */
226
/* subresources */ subresources,
227
/* subresource_count */ XtNumber(subresources),
228
/* constraint_size */ sizeof(PanedConstraintsRec),
229
/* initialize */ NULL,
231
/* set_values */ PaneSetValues,
236
WidgetClass panedWidgetClass = (WidgetClass) &panedClassRec;
238
/* For compatibility. */
239
WidgetClass vPanedWidgetClass = (WidgetClass) &panedClassRec;
241
/***********************************************************
245
************************************************************/
247
/* Function Name: AdjustPanedSize
248
* Description: Adjusts the size of the pane.
249
* Arguments: pw - the paned widget to adjust.
250
* off_size - the new off_size to use.
251
* result_ret - result of query ** RETURNED **
252
* on_size_ret - the new on_size ** RETURNED **
253
* off_size_ret - the new off_size ** RETURNED **
254
* Returns: the amount of change in size.
258
AdjustPanedSize(pw, off_size, result_ret, on_size_ret, off_size_ret)
261
XtGeometryResult * result_ret;
262
Dimension * on_size_ret, * off_size_ret;
264
Dimension old_size = PaneSize( (Widget) pw, IsVert(pw));
265
Dimension newsize = 0;
267
XtWidgetGeometry request, reply;
268
request.request_mode = CWWidth | CWHeight;
270
ForAllPanes(pw, childP) {
271
int size = Max(PaneInfo(*childP)->size, (int)PaneInfo(*childP)->min);
272
AssignMin(size, (int) PaneInfo(*childP)->max);
273
newsize += size + pw->paned.internal_bw;
275
newsize -= pw->paned.internal_bw;
277
if (newsize < 1) newsize = 1;
280
request.width = off_size;
281
request.height = newsize;
284
request.width = newsize;
285
request.height = off_size;
288
if (result_ret != NULL) {
289
request.request_mode |= XtCWQueryOnly;
291
*result_ret = XtMakeGeometryRequest( (Widget) pw, &request, &reply );
293
if ( (newsize == old_size) || (*result_ret == XtGeometryNo) ) {
294
*on_size_ret = old_size;
295
*off_size_ret = off_size;
298
if (*result_ret != XtGeometryAlmost) {
299
*on_size_ret = GetRequestInfo( &request, IsVert(pw) );
300
*off_size_ret = GetRequestInfo( &request, !IsVert(pw) );
303
*on_size_ret = GetRequestInfo( &reply, IsVert(pw) );
304
*off_size_ret = GetRequestInfo( &reply, !IsVert(pw) );
308
if (newsize == old_size) return;
310
if (XtMakeGeometryRequest( (Widget) pw,
311
&request, &reply) == XtGeometryAlmost)
312
XtMakeGeometryRequest( (Widget) pw, &reply, &request);
315
/* Function Name: PaneSize
316
* Description: returns the width or height of the pane depending
317
* upon the orientation we are using.
318
* Arguments: w - and widget.
319
* vertical - TRUE if this is vertically oriented pane.
320
* Returns: the size requested
322
* vertical - return height
323
* !vertical - return width
327
PaneSize(w, vertical)
331
if (vertical) return (w->core.height);
332
return (w->core.width);
335
/* Function Name: GetRequestInfo
336
* Description: returns request information.
337
* Arguments: geo_struct - a geometry struct to get information out of.
338
* vert - TRUE if this is a vertical paned widget.
339
* Returns: the request information.
343
GetRequestInfo(geo_struct, vert)
344
XtWidgetGeometry * geo_struct;
347
if ( vert ) return ( (Dimension) geo_struct->height);
348
return ( (Dimension) geo_struct->width);
351
/* Function Name: ChoosePaneToResize.
352
* Description: This function chooses a pane to resize.
353
* They are chosen using the following rules:
355
* 1) size < max && size > min
356
* 2) skip adjust == FALSE
357
* 3) widget not its prefered height &&
358
* this change will bring it closer &&
359
* The user has not resized this pane.
361
* If no widgets are found that fits all the rules then
363
* If there are still no widgets found than
365
* Rule #1 is never broken.
366
* If no widgets are found then NULL is returned.
368
* Arguments: pw - the paned widget.
369
* paneindex - the index of the current pane.
370
* dir - direction to search first.
371
* shrink - TRUE if we need to shrink a pane, FALSE otherwise.
372
* Returns: pane to resize or NULL.
376
ChoosePaneToResize(pw, paneindex, dir, shrink)
384
Direction _dir = dir;
385
int _index = paneindex;
387
if ( (paneindex == NO_INDEX) || (dir == AnyPane) ) { /* Use defaults. */
388
_dir = LowRightPane; /* Go up. - really. */
389
_index = pw->paned.num_panes - 1; /* Start the last pane, and work
392
childP = pw->composite.children + _index;
394
register Pane pane = PaneInfo(*childP);
396
if ( (rules < 3 || SatisfiesRule3(pane, shrink)) &&
397
(rules < 2 || SatisfiesRule2(pane)) &&
398
(SatisfiesRule1(pane, shrink)) &&
399
((paneindex != PaneIndex(*childP)) || (dir == AnyPane)) )
403
* This is counter-intuitive, but if we are resizing the pane
404
* above the grip we want to choose a pane below the grip to lose,
408
if (_dir == LowRightPane) --childP; else ++childP;
411
* If we have come to and edge then reduce the rule set, and try again.
412
* If we are reduced the rules to none, then return NULL.
415
if ( (childP - pw->composite.children < 0) ||
416
(childP - pw->composite.children >= pw->paned.num_panes) ) {
417
if (--rules < 1) /* less strict rules. */
419
childP = pw->composite.children + _index;
424
/* Function Name: StatisfiesRule1
425
* Description: check for to see if this pane satisfies rule 1.
426
* Arguments: pane - the pane to check.
427
* shrink -TRUE if we want to shrink this pane, FALSE otherwise
428
* Returns: TRUE if the rule is satisfied.
432
SatisfiesRule1(pane, shrink)
436
return( (shrink && (pane->size != pane->min)) ||
437
(!shrink && (pane->size != pane->max)) );
440
/* Function Name: StatisfiesRule2
441
* Description: check for to see if this pane satisfies rule 2.
442
* Arguments: pane - the pane to check.
443
* Returns: TRUE if the rule is satisfied.
450
return(!pane->skip_adjust || pane->paned_adjusted_me);
453
/* Function Name: StatisfiesRule3
454
* Description: check for to see if this pane satisfies rule 3.
455
* Arguments: pane - the pane to check.
456
* shrink -TRUE if we want to shrink this pane, FALSE otherwise
457
* Returns: TRUE if the rule is satisfied.
461
SatisfiesRule3(pane, shrink)
465
return ( pane->paned_adjusted_me &&
466
( (shrink && ((int)pane->wp_size <= pane->size)) ||
467
(!shrink && ((int)pane->wp_size >= pane->size))) );
470
/* Function Name: LoopAndRefigureChildren.
471
* Description: if we are resizing either the UpleftPane or LowRight Pane
472
* loop through all the children to see if any will allow us
474
* Arguments: pw - the paned widget.
475
* paneindex - the number of the pane border we are moving.
476
* dir - the pane to move (either UpLeftPane or LowRightPane).
477
* sizeused - current amount of space used.
478
* THIS VALUE IS USED AND RETURNED.
483
LoopAndRefigureChildren(pw, paneindex, dir, sizeused)
485
int paneindex, *sizeused;
488
int pane_size = (int) PaneSize( (Widget) pw, IsVert(pw));
489
Boolean shrink = (*sizeused > pane_size);
491
if (dir == LowRightPane) paneindex++;
493
while (*sizeused != pane_size) { /* While all panes do not fit properly. */
495
* Choose a pane to resize.
496
* First look on the Pane Stack, and then go hunting for another one.
497
* If we fail to find a pane to resize then give up.
502
Boolean rule3_ok = FALSE, from_stack = TRUE;
504
GetPaneStack(pw, shrink, &pane, &start_size);
506
pane = ChoosePaneToResize(pw, paneindex, dir, shrink);
508
return; /* no one to resize, give up. */
510
rule3_ok = SatisfiesRule3(pane, shrink);
512
PushPaneStack(pw, pane);
517
* Try to resize this pane so that all panes will fit, take min and max
521
pane->size += pane_size - *sizeused;
525
AssignMax(pane->size, start_size);
526
} /* don't remove these braces. */
528
AssignMin(pane->size, start_size);
530
if (pane->size == start_size) (void) PopPaneStack(pw);
534
AssignMax(pane->size, (int) pane->wp_size);
535
} /* don't remove these braces. */
537
AssignMin(pane->size, (int) pane->wp_size);
540
pane->paned_adjusted_me = (pane->size != pane->wp_size);
541
AssignMax(pane->size, (int) pane->min);
542
AssignMin(pane->size, (int) pane->max);
543
*sizeused += (pane->size - old);
547
/* Function Name: RefigureLocations
548
* Description: refigures all locations of children.
549
* Arguments: pw - the paned widget.
550
* paneindex - child to start refiguring at.
551
* dir - direction to move from child.
554
* There are special arguments to paneindex and dir, they are:
555
* paneindex - NO_INDEX.
558
* If either of these is true then all panes may be resized and
559
* the choosing of panes procedes in reverse order starting with the
564
RefigureLocations(pw, paneindex, dir)
569
register Widget *childP;
570
int pane_size = (int) PaneSize( (Widget) pw, IsVert(pw) );
574
if (pw->paned.num_panes == 0 || !pw->paned.refiguremode) return;
577
* Get an initial estimate of the size we will use.
580
ForAllPanes(pw, childP) {
581
register Pane pane = PaneInfo(*childP);
582
AssignMax(pane->size, (int) pane->min);
583
AssignMin(pane->size, (int) pane->max);
584
sizeused += (int) pane->size + (int) pw->paned.internal_bw;
586
sizeused -= (int) pw->paned.internal_bw;
588
if ( (dir != ThisBorderOnly) && (sizeused != pane_size) )
589
LoopAndRefigureChildren(pw, paneindex, dir, &sizeused);
592
* If we still are not the right size, then tell the pane that
593
* wanted to resize that it can't.
597
if ( (paneindex != NO_INDEX) && (dir != AnyPane) ) {
598
Pane pane = PaneInfo(*(pw->composite.children + paneindex));
599
Dimension old = pane->size;
601
pane->size += pane_size - sizeused;
602
AssignMax(pane->size, (int) pane->min);
603
AssignMin(pane->size, (int) pane->max);
604
sizeused += pane->size - old;
608
* It is possible that the panes will not fit inside the vpaned widget, but
609
* we have tried out best.
611
* Assign each pane a location.
614
ForAllPanes(pw, childP) {
615
PaneInfo(*childP)->delta = loc;
616
loc += PaneInfo(*childP)->size + pw->paned.internal_bw;
620
/* Function Name: CommitNewLocations
621
* Description: Commits all of the previously figured locations.
622
* Arguments: pw - the paned widget.
627
CommitNewLocations(pw)
630
register Widget *childP;
631
XWindowChanges changes;
633
changes.stack_mode = Above;
635
ForAllPanes(pw, childP) {
636
register Pane pane = PaneInfo(*childP);
637
register Widget grip = pane->grip; /* may be NULL. */
640
XtMoveWidget(*childP, (Position) 0, pane->delta);
641
XtResizeWidget(*childP, pw->core.width, (Dimension) pane->size,
644
if (HasGrip(*childP)) { /* Move and Display the Grip */
645
changes.x = pw->core.width - pw->paned.grip_indent -
646
grip->core.width - grip->core.border_width*2;
647
changes.y = (*childP)->core.y + (*childP)->core.height -
648
grip->core.height/2 - grip->core.border_width +
649
pw->paned.internal_bw/2;
653
XtMoveWidget(*childP, pane->delta, (Position) 0);
654
XtResizeWidget(*childP, (Dimension) pane->size, pw->core.height,
658
if (HasGrip(*childP)) { /* Move and Display the Grip */
659
changes.x = (*childP)->core.x + (*childP)->core.width -
660
grip->core.width/2 - grip->core.border_width +
661
pw->paned.internal_bw/2;
662
changes.y = pw->core.height - pw->paned.grip_indent -
663
grip->core.height - grip->core.border_width*2;
668
* This should match XtMoveWidget, except that we're also insuring the
669
* grip is Raised in the same request.
672
if (HasGrip(*childP)) {
673
grip->core.x = changes.x;
674
grip->core.y = changes.y;
676
if (XtIsRealized(pane->grip))
677
XConfigureWindow( XtDisplay(pane->grip), XtWindow(pane->grip),
678
CWX | CWY | CWStackMode, &changes );
684
/* Function Name: RefigureLocationsAndCommit
685
* Description: Refigures all locations in a paned widget and
686
* commits them immediately.
687
* Arguments: pw - the paned widget.
690
* This function does nothing if any of the following are true.
691
* o refiguremode is false.
692
* o The widget is unrealized.
693
* o There are no panes is the paned widget.
695
* NOTE: This is the resize Procedure for the Paned widget.
699
RefigureLocationsAndCommit(w)
702
PanedWidget pw = (PanedWidget) w;
703
if (pw->paned.refiguremode && XtIsRealized( (Widget) pw) &&
704
pw->paned.num_panes > 0 ) {
705
RefigureLocations(pw, NO_INDEX, AnyPane);
706
CommitNewLocations(pw);
710
/* Function Name: _DrawRect
711
* Description: Draws a rectangle in the proper orientation.
712
* Arguments: pw - the paned widget.
713
* gc - gc to used for the draw.
714
* on_olc, off_loc - location of upper left corner of rect.
715
* on_size, off_size - size of rectangle.
720
_DrawRect(pw, gc, on_loc, off_loc, on_size, off_size)
724
unsigned int on_size, off_size;
727
XFillRectangle(XtDisplay(pw), XtWindow(pw), gc,
728
off_loc, on_loc, off_size, on_size);
730
XFillRectangle(XtDisplay(pw), XtWindow(pw), gc,
731
on_loc, off_loc, on_size, off_size);
734
/* Function Name: _DrawInternalBorders
735
* Description: Draws the internal borders into the paned widget.
736
* Arguments: pw - the paned widget.
737
* gc - the GC to use to draw the borders.
742
_DrawInternalBorders(pw, gc)
748
unsigned int on_size, off_size;
751
* This is an optimization. Do not paint the internal borders if
752
* they are the same color as the background.
755
if (pw->core.background_pixel == pw->paned.internal_bp)
759
off_size = (unsigned int) PaneSize( (Widget) pw, !IsVert(pw) );
760
on_size = (unsigned int) pw->paned.internal_bw;
762
ForAllPanes(pw, childP) {
763
on_loc = IsVert(pw) ? (*childP)->core.y : (*childP)->core.x;
764
on_loc -= (int) on_size;
766
_DrawRect( pw, gc, on_loc, off_loc, on_size, off_size);
771
* This allows good reuse of code, as well as descriptive function names.
774
#define DrawInternalBorders(pw) _DrawInternalBorders((pw), (pw)->paned.normgc);
775
#define EraseInternalBorders(pw) _DrawInternalBorders((pw), (pw)->paned.invgc);
777
/* Function Name: _DrawTrackLines
778
* Description: Draws the lines that animate the pane borders when the
780
* Arguments: pw - the Paned widget.
781
* erase - if True then just erase track lines, else
787
_DrawTrackLines(pw, erase)
794
unsigned int on_size, off_size;
797
off_size = PaneSize( (Widget) pw, !IsVert(pw));
799
ForAllPanes(pw, childP) {
800
pane = PaneInfo(*childP);
801
if ( erase || (pane->olddelta != pane->delta) ) {
802
on_size = pw->paned.internal_bw;
804
on_loc = PaneInfo(*childP)->olddelta - (int) on_size;
806
_DrawRect( pw, pw->paned.flipgc,
807
on_loc, off_loc, on_size, off_size);
810
on_loc = PaneInfo(*childP)->delta - (int) on_size;
812
_DrawRect(pw, pw->paned.flipgc,
813
on_loc, off_loc, on_size, off_size);
815
pane->olddelta = pane->delta;
821
* This allows good reuse of code, as well as descriptive function names.
824
#define DrawTrackLines(pw) _DrawTrackLines((pw), FALSE);
825
#define EraseTrackLines(pw) _DrawTrackLines((pw), TRUE);
827
/* Function Name: GetEventLocation
828
* Description: Converts and event to an x and y location.
829
* Arguments: pw - the paned widget.
830
* event - a pointer to an event.
831
* Returns: if this is a vertical pane then (y) else (x).
835
GetEventLocation(pw, event)
841
switch (event->xany.type) {
844
x = event->xbutton.x_root;
845
y = event->xbutton.y_root;
849
x = event->xkey.x_root;
850
y = event->xkey.y_root;
853
x = event->xmotion.x_root;
854
y = event->xmotion.y_root;
857
x = pw->paned.start_loc;
858
y = pw->paned.start_loc;
865
/* Function Name: StartGripAdjustment
866
* Description: Starts the grip adjustment procedure.
867
* Arguments: pw - the paned widget.
868
* grip - the grip widget selected.
869
* dir - the direction that we are to be moving.
874
StartGripAdjustment(pw, grip, dir)
882
pw->paned.whichadd = pw->paned.whichsub = (Widget) NULL;
884
if (dir == ThisBorderOnly || dir == UpLeftPane)
885
pw->paned.whichadd = pw->composite.children[PaneIndex(grip)];
886
if (dir == ThisBorderOnly || dir == LowRightPane)
887
pw->paned.whichsub = pw->composite.children[PaneIndex(grip) + 1];
893
if (XtIsRealized(grip)) {
895
if (dir == UpLeftPane)
896
cursor = pw->paned.adjust_upper_cursor;
897
else if (dir == LowRightPane)
898
cursor = pw->paned.adjust_lower_cursor;
900
if ( pw->paned.adjust_this_cursor == None)
901
cursor = pw->paned.v_adjust_this_cursor;
903
cursor = pw->paned.adjust_this_cursor;
907
if (dir == UpLeftPane)
908
cursor = pw->paned.adjust_left_cursor;
909
else if (dir == LowRightPane)
910
cursor = pw->paned.adjust_right_cursor;
912
if (pw->paned.adjust_this_cursor == None)
913
cursor = pw->paned.h_adjust_this_cursor;
915
cursor = pw->paned.adjust_this_cursor;
919
XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor);
922
EraseInternalBorders(pw);
923
ForAllPanes(pw, childP)
924
PaneInfo(*childP)->olddelta = -99;
927
/* Function Name: MoveGripAdjustment
928
* Description: This routine moves all panes around when a grip is moved.
929
* Arguments: pw - the paned widget.
930
* grip - the grip that we are moving.
931
* dir - the direction the pane we are interested is w.r.t the
933
* loc - location of pointer in proper direction.
938
MoveGripAdjustment(pw, grip, dir, loc)
944
int diff, add_size = 0, sub_size = 0;
946
diff = loc - pw->paned.start_loc;
948
if (pw->paned.whichadd)
949
add_size = PaneSize(pw->paned.whichadd, IsVert(pw) ) + diff;
951
if (pw->paned.whichsub)
952
sub_size = PaneSize(pw->paned.whichsub, IsVert(pw) ) - diff;
955
* If moving this border only then do not allow either of the borders
956
* to go beyond the min or max size allowed.
959
if ( (dir == ThisBorderOnly) ) {
960
int old_add_size = add_size, old_sub_size;
962
AssignMax(add_size, (int) PaneInfo(pw->paned.whichadd)->min);
963
AssignMin(add_size, (int) PaneInfo(pw->paned.whichadd)->max);
964
if (add_size != old_add_size)
965
sub_size += old_add_size - add_size;
967
old_sub_size = sub_size;
968
AssignMax(sub_size, (int) PaneInfo(pw->paned.whichsub)->min);
969
AssignMin(sub_size, (int) PaneInfo(pw->paned.whichsub)->max);
970
if (sub_size != old_sub_size) return; /* Abort to current sizes. */
974
PaneInfo(pw->paned.whichadd)->size = add_size;
976
PaneInfo(pw->paned.whichsub)->size = sub_size;
977
RefigureLocations(pw, PaneIndex(grip), dir);
981
/* Function Name: CommitGripAdjustment
982
* Description: Commits the grip adjustment.
983
* Arguments: pw - the paned widget.
988
CommitGripAdjustment(pw)
992
CommitNewLocations(pw);
993
DrawInternalBorders(pw);
996
* Since the user selected this size then use it as the preferred size.
999
if (pw->paned.whichadd) {
1000
Pane pane = PaneInfo(pw->paned.whichadd);
1001
pane->wp_size = pane->size;
1003
if (pw->paned.whichsub) {
1004
Pane pane = PaneInfo(pw->paned.whichsub);
1005
pane->wp_size = pane->size;
1009
/* Function Name: HandleGrip
1010
* Description: Handles the grip manipulations.
1011
* Arguments: grip - the grip widget that has been moved.
1012
* junk - ** NOT USED **
1013
* call_data - data passed to us from the grip widget.
1019
HandleGrip(grip, junk, callData)
1021
XtPointer junk, callData;
1023
XawGripCallData call_data = (XawGripCallData)callData;
1024
PanedWidget pw = (PanedWidget) XtParent(grip);
1028
Direction direction;
1031
action_type = *call_data->params[0];
1033
if (call_data->num_params == 0 ||
1034
(action_type == 'C' && call_data->num_params != 1) ||
1035
(action_type != 'C' && call_data->num_params != 2))
1036
XtError( "Paned GripAction has been passed incorrect parameters." );
1038
if (islower(action_type)) action_type = toupper(action_type);
1040
loc = GetEventLocation(pw, (XEvent *) (call_data->event));
1042
if (action_type != 'C') {
1043
if ( isupper(*call_data->params[1]) )
1044
direction = (Direction) *call_data->params[1];
1046
direction = (Direction) toupper(*call_data->params[1]);
1049
switch (action_type) {
1050
case 'S': /* Start adjustment */
1051
pw->paned.resize_children_to_pref = FALSE;
1052
StartGripAdjustment(pw, grip, direction);
1053
pw->paned.start_loc = loc;
1057
MoveGripAdjustment(pw, grip, direction, loc);
1061
XtSetArg(arglist[0], XtNcursor, &cursor);
1062
XtGetValues(grip, arglist, (Cardinal) 1);
1063
XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor);
1064
CommitGripAdjustment(pw);
1068
XtError( "Paned GripAction(); 1st parameter invalid" );
1072
/* Function Name: ResortChildren
1073
* Description: Resorts the children so that all managed children
1075
* Arguments: pw - the paned widget.
1083
Widget * unmanagedP, * childP;
1086
ForAllChildren(pw, childP) {
1087
if (!IsPane(*childP) || !XtIsManaged(*childP)) {
1089
* We only keep track of the first unmanaged pane.
1091
if (unmanagedP == NULL)
1092
unmanagedP = childP;
1094
else { /* must be a managed pane */
1096
* If an earlier widget was not a managed pane, then swap
1098
if (unmanagedP != NULL) {
1099
Widget child = *unmanagedP;
1100
*unmanagedP = *childP;
1102
childP = unmanagedP; /* easiest to just back-track */
1103
unmanagedP = NULL; /* in case there is another managed */
1109
/* Function Name: ManageAndUnmanageGrips
1110
* Description: This function manages and unmanages the grips so that
1111
* the managed state of each grip matches that of its pane.
1112
* Arguments: pw - the paned widget.
1117
ManageAndUnmanageGrips(pw)
1120
WidgetList managed_grips, unmanaged_grips;
1121
Widget *managedP, *unmanagedP, *childP;
1122
Cardinal alloc_size;
1124
alloc_size = (Cardinal) sizeof(Widget) * pw->composite.num_children / 2;
1125
managedP = managed_grips = (WidgetList) XtMalloc(alloc_size);
1126
unmanagedP = unmanaged_grips = (WidgetList) XtMalloc(alloc_size);
1128
ForAllChildren(pw, childP)
1129
if (IsPane(*childP) && HasGrip(*childP))
1130
if ( XtIsManaged(*childP) )
1131
*managedP++ = PaneInfo(*childP)->grip;
1133
*unmanagedP++ = PaneInfo(*childP)->grip;
1135
if (managedP != managed_grips) {
1136
*unmanagedP++ = *--managedP; /* Last grip is never managed */
1137
XtManageChildren( managed_grips, (Cardinal)(managedP - managed_grips) );
1140
if (unmanagedP != unmanaged_grips)
1141
XtUnmanageChildren( unmanaged_grips,
1142
(Cardinal)(unmanagedP - unmanaged_grips) );
1144
XtFree((char *)managed_grips);
1145
XtFree((char *)unmanaged_grips);
1148
/* Function Name: CreateGrip
1149
* Description: Creates a grip widget.
1150
* Arguments: child - the child that wants a grip to be created for it.
1158
PanedWidget pw = (PanedWidget) XtParent(child);
1160
Cardinal num_args = 0;
1163
XtSetArg(arglist[num_args], XtNtranslations, pw->paned.grip_translations);
1165
if ( (cursor = pw->paned.grip_cursor) == None )
1167
cursor = pw->paned.v_grip_cursor;
1169
cursor = pw->paned.h_grip_cursor;
1171
XtSetArg(arglist[num_args], XtNcursor, cursor);
1173
PaneInfo(child)->grip = XtCreateWidget("grip", gripWidgetClass, (Widget)pw,
1176
XtAddCallback(PaneInfo(child)->grip, XtNcallback,
1177
HandleGrip, (XtPointer) child);
1180
/* Function Name: GetGCs
1181
* Description: Gets new GC's.
1182
* Arguments: w - the paned widget.
1190
PanedWidget pw = (PanedWidget) w;
1195
* Draw pane borders in internal border color.
1198
values.foreground = pw->paned.internal_bp;
1199
valuemask = GCForeground;
1200
pw->paned.normgc = XtGetGC(w, valuemask, &values);
1203
* Erase pane borders with background color.
1206
values.foreground = pw->core.background_pixel;
1207
valuemask = GCForeground;
1208
pw->paned.invgc = XtGetGC(w, valuemask, &values);
1211
* Draw Track lines (animate pane borders) in internal border color ^ bg color.
1214
values.function = GXinvert;
1215
values.plane_mask = pw->paned.internal_bp ^ pw->core.background_pixel;
1216
values.subwindow_mode = IncludeInferiors;
1217
valuemask = GCPlaneMask | GCFunction | GCSubwindowMode;
1218
pw->paned.flipgc = XtGetGC(w, valuemask, &values);
1221
/* Function Name: SetChildrenPrefSizes.
1222
* Description: Sets the preferred sizes of the children.
1223
* Arguments: pw - the paned widget.
1228
SetChildrenPrefSizes(pw, off_size)
1233
Boolean vert = IsVert(pw);
1234
XtWidgetGeometry request, reply;
1236
ForAllPanes(pw, childP)
1237
if ( pw->paned.resize_children_to_pref ||
1238
(PaneInfo(*childP)->size == 0) ||
1239
(PaneInfo(*childP)->resize_to_pref) ) {
1241
if (PaneInfo(*childP)->preferred_size != PANED_ASK_CHILD)
1242
PaneInfo(*childP)->wp_size=PaneInfo(*childP)->preferred_size;
1245
request.request_mode = CWWidth;
1246
request.width = off_size;
1249
request.request_mode = CWHeight;
1250
request.height = off_size;
1253
if ((XtQueryGeometry( *childP, &request, &reply )
1254
== XtGeometryAlmost) &&
1255
(reply.request_mode = (vert ? CWHeight : CWWidth)))
1256
PaneInfo(*childP)->wp_size = GetRequestInfo(&reply, vert);
1258
PaneInfo(*childP)->wp_size = PaneSize(*childP, vert);
1261
PaneInfo(*childP)->size = PaneInfo(*childP)->wp_size;
1265
/* Function Name: ChangeAllGripCursors
1266
* Description: Changes all the grip cursors.
1267
* Arguments: pw - the paned widget.
1272
ChangeAllGripCursors(pw)
1277
ForAllPanes(pw, childP) {
1281
if ( (cursor = pw->paned.grip_cursor) == None )
1283
cursor = pw->paned.v_grip_cursor;
1285
cursor = pw->paned.h_grip_cursor;
1287
if (HasGrip (*childP)) {
1288
XtSetArg(arglist[0], XtNcursor, cursor);
1289
XtSetValues(PaneInfo(*childP)->grip, arglist, (Cardinal) 1);
1294
/************************************************************
1296
* Stack Manipulation routines (Private).
1298
************************************************************/
1300
/* Function Name: PushPaneStack
1301
* Description: Pushes a value onto the pane stack.
1302
* Arguments: pw - the paned widget.
1303
* pane - the pane that we are pushing.
1308
PushPaneStack(pw, pane)
1312
PaneStack * stack = (PaneStack *) XtMalloc(sizeof(PaneStack));
1314
stack->next = pw->paned.stack;
1316
stack->start_size = pane->size;
1318
pw->paned.stack = stack;
1321
/* Function Name: GetPaneStack
1322
* Description: Gets the top value from the pane stack.
1323
* Arguments: pw - the paned widget.
1324
* shrink - TRUE if we want to shrink this pane,
1326
* ** RETURNED ** pane - the pane that we are popping.
1327
* ** RETURNED ** start_size - the size that this pane started at.
1332
GetPaneStack(pw, shrink, pane, start_size)
1338
if (pw->paned.stack == NULL) {
1343
*pane = pw->paned.stack->pane;
1344
*start_size = pw->paned.stack->start_size;
1346
if (shrink != ((*pane)->size > *start_size)) *pane = NULL;
1349
/* Function Name: PopPaneStack
1350
* Description: Pops the top item off the pane stack.
1351
* Arguments: pw - the paned widget.
1352
* Returns: TRUE if this is not the last element on the stack.
1359
PaneStack * stack = pw->paned.stack;
1361
if (stack == NULL) return(FALSE);
1363
pw->paned.stack = stack->next;
1364
XtFree((char*)stack);
1366
if (pw->paned.stack == NULL) return(FALSE);
1370
/* Function Name: ClearPaneStack
1371
* Description: removes all entries from the pane stack.
1372
* Arguments: pw - the paned widget.
1380
while(PopPaneStack(pw));
1383
/************************************************************
1385
* Semi-public routines.
1387
************************************************************/
1389
/* Function Name: ClassInitialize
1390
* Description: The Paned widgets class initialization proc.
1398
XawInitializeWidgetSet();
1399
XtAddConverter( XtRString, XtROrientation, XmuCvtStringToOrientation,
1400
NULL, (Cardinal)0 );
1403
/* The Geometry Manager only allows changes after Realize if
1404
* allow_resize is True in the constraints record.
1406
* For vertically paned widgets:
1408
* It only allows height changes, but offers the requested height
1409
* as a compromise if both width and height changes were requested.
1411
* For horizontal widgets the converse is true.
1412
* As all good Geometry Managers should, we will return No if the
1413
* request will have no effect; i.e. when the requestor is already
1414
* of the desired geometry.
1417
static XtGeometryResult GeometryManager(w, request, reply)
1419
XtWidgetGeometry *request, *reply;
1421
PanedWidget pw = (PanedWidget) XtParent(w);
1422
XtGeometryMask mask = request->request_mode;
1423
Dimension old_size, old_wpsize, old_paned_size;
1424
Pane pane = PaneInfo(w);
1425
register Boolean vert = IsVert(pw);
1426
Dimension on_size, off_size;
1427
XtGeometryResult result;
1428
Boolean almost = FALSE;
1431
* If any of the following is true, disallow the geometry change.
1433
* o The paned widget is realized and allow_resize is false for the pane.
1434
* o The child did not ask to change the on_size.
1435
* o The request is not a width or height request.
1436
* o The requested size is the same as the current size.
1439
if ( (XtIsRealized((Widget)pw) && !pane->allow_resize) ||
1440
!(mask & ((vert) ? CWHeight : CWWidth)) ||
1441
(mask & ~(CWWidth | CWHeight)) ||
1442
(GetRequestInfo(request, vert) == PaneSize(w, vert)) ) {
1443
return XtGeometryNo;
1446
old_paned_size = PaneSize( (Widget) pw, vert);
1447
old_wpsize = pane->wp_size;
1448
old_size = pane->size;
1450
pane->wp_size = pane->size = GetRequestInfo(request, vert);
1452
AdjustPanedSize(pw, PaneSize((Widget) pw, !vert), &result, &on_size,
1456
* Fool the Refigure Locations proc to thinking that we are
1457
* a different on_size;
1460
if (result != XtGeometryNo)
1462
pw->core.height = on_size;
1464
pw->core.width = on_size;
1466
RefigureLocations(pw, PaneIndex(w), AnyPane);
1469
* Set up reply struct and reset core on_size.
1473
pw->core.height = old_paned_size;
1474
reply->height = pane->size;
1475
reply->width = off_size;
1478
pw->core.width = old_paned_size;
1479
reply->height = off_size;
1480
reply->width = pane->size;
1484
* IF either of the following is true.
1486
* o There was a "off_size" request and the new "off_size" is different
1487
* from that requested.
1488
* o There was no "off_size" request and the new "off_size" is different
1490
* o The "on_size" we will allow is different from that requested.
1495
if ( !((vert ? CWWidth : CWHeight) & mask))
1497
request->width = w->core.width;
1499
request->height = w->core.height;
1501
almost = GetRequestInfo(request, !vert) != GetRequestInfo(reply, !vert);
1502
almost |= GetRequestInfo(request, vert) != GetRequestInfo(reply, vert);
1504
if ( (mask & XtCWQueryOnly) || almost ) {
1505
pane->wp_size = old_wpsize;
1506
pane->size = old_size;
1507
RefigureLocations(pw, PaneIndex(w), AnyPane);
1508
reply->request_mode = CWWidth | CWHeight;
1509
if (almost) return XtGeometryAlmost;
1512
AdjustPanedSize(pw, PaneSize((Widget) pw, !vert), NULL, NULL, NULL);
1513
CommitNewLocations( pw ); /* layout already refigured. */
1515
return XtGeometryDone;
1519
static void Initialize(request, new)
1520
Widget request, new;
1522
PanedWidget pw = (PanedWidget)new;
1524
GetGCs( (Widget) pw);
1526
pw->paned.recursively_called = False;
1527
pw->paned.stack = NULL;
1528
pw->paned.resize_children_to_pref = TRUE;
1529
pw->paned.num_panes = 0;
1533
Realize(w, valueMask, attributes)
1536
XSetWindowAttributes *attributes;
1538
PanedWidget pw = (PanedWidget) w;
1541
if ((attributes->cursor = (pw)->paned.cursor) != None)
1542
*valueMask |= CWCursor;
1544
(*SuperClass->core_class.realize) (w, valueMask, attributes);
1547
* Before we commit the new locations we need to realize all the panes and
1551
ForAllPanes(pw, childP) {
1552
XtRealizeWidget( *childP );
1553
if (HasGrip (*childP))
1554
XtRealizeWidget( PaneInfo(*childP)->grip );
1557
RefigureLocationsAndCommit(w);
1558
pw->paned.resize_children_to_pref = FALSE;
1565
register PanedWidget pw = (PanedWidget)w;
1567
XtReleaseGC( w, pw->paned.normgc );
1568
XtReleaseGC( w, pw->paned.invgc );
1569
XtReleaseGC( w, pw->paned.flipgc );
1572
static void InsertChild(w)
1575
Pane pane = PaneInfo(w);
1577
/* insert the child widget in the composite children list with the */
1578
/* superclass insert_child routine. */
1579
(*SuperClass->composite_class.insert_child)(w);
1581
if (!IsPane(w)) return;
1583
/* ||| Panes will be added in the order they are created, temporarily */
1585
if ( pane->show_grip == TRUE ) {
1587
if (pane->min == PANED_GRIP_SIZE)
1588
pane->min = PaneSize(pane->grip, IsVert((PanedWidget) XtParent(w)));
1591
if (pane->min == PANED_GRIP_SIZE)
1597
pane->paned_adjusted_me = FALSE;
1601
static void DeleteChild(w)
1604
/* remove the subwidget info and destroy the grip */
1606
if ( IsPane(w) && HasGrip(w) ) XtDestroyWidget(PaneInfo(w)->grip);
1608
/* delete the child widget in the composite children list with the */
1609
/* superclass delete_child routine. */
1610
(*SuperClass->composite_class.delete_child) (w);
1614
static void ChangeManaged(w)
1617
PanedWidget pw = (PanedWidget)w;
1618
Boolean vert = IsVert(pw);
1620
register Widget *childP;
1622
if (pw->paned.recursively_called++) return;
1625
* If the size is zero then set it to the size of the widest or tallest pane.
1628
if ( (size = PaneSize( (Widget) pw, !vert )) == 0) {
1630
ForAllChildren(pw, childP)
1631
if ( XtIsManaged(*childP) && (PaneSize( *childP, !vert ) > size) )
1632
size = PaneSize( *childP, !vert );
1635
ManageAndUnmanageGrips(pw);
1636
pw->paned.recursively_called = False;
1639
pw->paned.num_panes = 0;
1640
ForAllChildren(pw, childP)
1641
if ( IsPane(*childP) )
1642
if ( XtIsManaged(*childP) ) {
1643
Pane pane = PaneInfo(*childP);
1644
if (HasGrip(*childP))
1645
PaneInfo(pane->grip)->position = pw->paned.num_panes;
1646
pane->position = pw->paned.num_panes; /*TEMPORY -CDP 3/89 */
1647
pw->paned.num_panes++;
1650
break; /* This list is already sorted. */
1652
SetChildrenPrefSizes( (PanedWidget) w, size);
1655
* ForAllPanes can now be used.
1658
if ( PaneSize((Widget) pw, vert) == 0 )
1659
AdjustPanedSize(pw, size, NULL, NULL, NULL);
1661
if (XtIsRealized( (Widget) pw))
1662
RefigureLocationsAndCommit( (Widget) pw);
1664
} /* ChangeManaged */
1666
/* Function Name: Resize
1667
* Description: The paned widget's resize proc.
1668
* Arguments: w - the paned widget.
1676
SetChildrenPrefSizes( (PanedWidget) w,
1677
PaneSize(w, !IsVert((PanedWidget) w)) );
1678
RefigureLocationsAndCommit(w);
1683
Redisplay(w, event, region)
1685
XEvent * event; /* unused. */
1686
Region region; /* unused. */
1688
DrawInternalBorders( (PanedWidget) w);
1693
SetValues(old, request, new)
1694
Widget old, request, new;
1696
PanedWidget old_pw = (PanedWidget) old;
1697
PanedWidget new_pw = (PanedWidget) new;
1698
Boolean redisplay = FALSE;
1700
if ( (old_pw->paned.cursor != new_pw->paned.cursor) && XtIsRealized(new))
1701
XDefineCursor(XtDisplay(new), XtWindow(new), new_pw->paned.cursor);
1703
if ( (old_pw->paned.internal_bp != new_pw->paned.internal_bp) ||
1704
(old_pw->core.background_pixel != new_pw->core.background_pixel) ) {
1710
if ( (old_pw->paned.grip_cursor != new_pw->paned.grip_cursor) ||
1711
(old_pw->paned.v_grip_cursor != new_pw->paned.v_grip_cursor) ||
1712
(old_pw->paned.h_grip_cursor != new_pw->paned.h_grip_cursor) ) {
1713
ChangeAllGripCursors(new_pw);
1716
if ( IsVert(old_pw) != IsVert(new_pw)) {
1718
* We are fooling the paned widget into thinking that is needs to
1719
* fully refigure everything, which is what we want.
1722
new_pw->core.width = 0;
1724
new_pw->core.height = 0;
1726
new_pw->paned.resize_children_to_pref = TRUE;
1727
ChangeManaged(new); /* Seems weird, but does the right thing. */
1728
new_pw->paned.resize_children_to_pref = FALSE;
1729
if (new_pw->paned.grip_cursor == None)
1730
ChangeAllGripCursors(new_pw);
1734
if (old_pw->paned.internal_bw != new_pw->paned.internal_bw) {
1735
AdjustPanedSize( new_pw, PaneSize(new, !IsVert(old_pw)),
1737
RefigureLocationsAndCommit(new);
1738
return(TRUE); /* We have done a full configuration, return.*/
1741
if ( (old_pw->paned.grip_indent != new_pw->paned.grip_indent) &&
1742
(XtIsRealized(new)) ) {
1743
CommitNewLocations(new_pw);
1753
PaneSetValues(old, request, new)
1754
Widget old, request, new;
1756
Pane old_pane = PaneInfo(old);
1757
Pane new_pane = PaneInfo(new);
1758
Boolean redisplay = FALSE;
1760
/* Check for new min and max. */
1762
if (old_pane->min != new_pane->min || old_pane->max != new_pane->max)
1763
XawPanedSetMinMax(new, (int)new_pane->min, (int)new_pane->max);
1765
/* Check for change in XtNshowGrip. */
1767
if (old_pane->show_grip != new_pane->show_grip)
1768
if (new_pane->show_grip == TRUE) {
1770
if (XtIsRealized(XtParent(new))) {
1771
if (XtIsManaged(new)) /* if paned is unrealized this will
1772
happen automatically at realize time.*/
1773
XtManageChild(PaneInfo(new)->grip); /* manage the grip. */
1774
XtRealizeWidget(PaneInfo(new)->grip); /* realize the grip. */
1775
CommitNewLocations( (PanedWidget) XtParent(new) );
1778
else if ( HasGrip(old) ) {
1779
XtDestroyWidget( old_pane->grip );
1780
new_pane->grip = NULL;
1784
/* ||| need to look at position changes */
1789
/************************************************************
1793
************************************************************/
1795
/* Function Name: XawPanedSetMinMax
1796
* Description: Sets the min and max size for a pane.
1797
* Arguments: widget - the widget that is a child of the Paned widget.
1798
* min, max - the new min and max size for the pane.
1803
#if NeedFunctionPrototypes
1804
XawPanedSetMinMax(Widget widget, int min, int max)
1806
XawPanedSetMinMax(widget, min, max)
1811
Pane pane = PaneInfo(widget);
1815
RefigureLocationsAndCommit( widget->core.parent );
1818
/* Function Name: XawPanedGetMinMax
1819
* Description: Gets the min and max size for a pane.
1820
* Arguments: widget - the widget that is a child of the Paned widget.
1821
** RETURNED ** min, max - the current min and max size for the pane.
1826
#if NeedFunctionPrototypes
1827
XawPanedGetMinMax(Widget widget, int *min, int *max)
1829
XawPanedGetMinMax(widget, min, max)
1834
Pane pane = PaneInfo(widget);
1840
/* Function Name: XawPanedSetRefigureMode
1841
* Description: Allows a flag to be set the will inhibit
1842
* the paned widgets relayout routine.
1843
* Arguments: w - the paned widget.
1844
* mode - if FALSE then inhibit refigure.
1849
#if NeedFunctionPrototypes
1850
XawPanedSetRefigureMode(Widget w,
1851
#if NeedWidePrototypes
1857
XawPanedSetRefigureMode(w, mode)
1862
((PanedWidget) w)->paned.refiguremode = mode;
1863
RefigureLocationsAndCommit( w );
1866
/* Function Name: XawPanedGetNumSub
1867
* Description: Returns the number of panes in the paned widget.
1868
* Arguments: w - the paned widget.
1869
* Returns: the number of panes in the paned widget.
1873
#if NeedFunctionPrototypes
1874
XawPanedGetNumSub(Widget w)
1876
XawPanedGetNumSub(w)
1880
return ((PanedWidget)w)->paned.num_panes;
1883
/* Function Name: XawPanedAllowResize
1884
* Description: Allows a flag to be set that determines if the paned
1885
* widget will allow geometry requests from this child
1886
* Arguments: widget - a child of the paned widget.
1891
#if NeedFunctionPrototypes
1892
XawPanedAllowResize(Widget widget,
1893
#if NeedWidePrototypes
1896
Boolean allow_resize)
1899
XawPanedAllowResize(widget, allow_resize)
1901
Boolean allow_resize;
1904
PaneInfo(widget)->allow_resize = allow_resize;