|
|
1.1 ! root 1: #ifndef lint ! 2: static char rcsid[] = "$Header: VPane.c,v 1.7 87/09/13 13:31:15 swick Exp $"; ! 3: #endif lint ! 4: ! 5: /* ! 6: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 7: * ! 8: * All Rights Reserved ! 9: * ! 10: * Permission to use, copy, modify, and distribute this software and its ! 11: * documentation for any purpose and without fee is hereby granted, ! 12: * provided that the above copyright notice appear in all copies and that ! 13: * both that copyright notice and this permission notice appear in ! 14: * supporting documentation, and that the name of Digital Equipment ! 15: * Corporation not be used in advertising or publicity pertaining to ! 16: * distribution of the software without specific, written prior permission. ! 17: * ! 18: * ! 19: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 20: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 21: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 22: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 23: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 24: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 25: * SOFTWARE. ! 26: */ ! 27: /* ! 28: * VPane.c - VPane composite Widget (Converted to classing toolkit) ! 29: * ! 30: * Author: Jeanne M. Rich (Original Terry Weissman) ! 31: * Digital Equipment Corporation ! 32: * Western Research Laboratory ! 33: * Date: Friday, Aug 28 1987 ! 34: * ! 35: */ ! 36: ! 37: #include "Xlib.h" ! 38: #include "cursorfont.h" ! 39: #include "Intrinsic.h" ! 40: #include "VPaneP.h" ! 41: #include "VPane.h" ! 42: #include "Knob.h" ! 43: #include "Atoms.h" ! 44: ! 45: #define offset(field) XtOffset(VPaneWidget,v_pane.field) ! 46: #define suboffset(field) XtOffset(SubWidgetPtr,field) ! 47: ! 48: /********************************************************************************** ! 49: * ! 50: * Full instance record declaration ! 51: * ! 52: *********************************************************************************/ ! 53: ! 54: static XtResource resources[] = { ! 55: {XtNforeground, XtCColor, XrmRPixel, sizeof(Pixel), ! 56: offset(foreground_pixel), XrmRString, "Black"}, ! 57: {XtNknobWidth, XtCWidth, XrmRInt, sizeof(int), ! 58: offset(knob_width), XrmRString, "9"}, ! 59: {XtNknobHeight, XtCHeight, XrmRInt, sizeof(int), ! 60: offset(knob_height), XrmRString, "9"}, ! 61: {XtNknobIndent, XtCKnobIndent, XrmRInt, sizeof(int), ! 62: offset(knob_indent), XrmRString, "16"}, ! 63: {XtNknobPixel, XtCKnobPixel, XrmRPixel, sizeof(int), ! 64: offset(knob_pixel), XrmRString, "Black"}, ! 65: {XtNrefigureMode, XtCRefigureMode, XrmRBoolean, sizeof(int), ! 66: offset(refiguremode), XrmRString, "On"} ! 67: }; ! 68: ! 69: static XtResource subresources[] = { ! 70: {XtNposition, XtCPosition, XrmRInt, sizeof(int), ! 71: suboffset(position), XrmRString, "0"}, ! 72: {XtNmin, XtCMin, XrmRInt, sizeof(int), ! 73: suboffset(min), XrmRString, "0"}, ! 74: {XtNmax, XtCMax, XrmRInt, sizeof(int), ! 75: suboffset(max), XrmRString, "1000"}, ! 76: {XtNautoChange, XtCAutoChange, XrmRBoolean, sizeof(int), ! 77: suboffset(autochange), XrmRString, "On"} ! 78: }; ! 79: ! 80: static void Initialize(); ! 81: static void Realize(); ! 82: static void Destroy(); ! 83: static void Resize(); ! 84: static void SetValues(); ! 85: static XtGeometryResult GeometryManager(); ! 86: static void ChangeManaged(); ! 87: static void InsertChild(); ! 88: static void DeleteChild(); ! 89: ! 90: VPaneClassRec vPaneClassRec = { ! 91: { ! 92: /* core class fields */ ! 93: /* superclass */ (WidgetClass) &constraintClassRec, ! 94: /* class name */ "VPane", ! 95: /* size */ sizeof(VPaneRec), ! 96: /* class initialize */ NULL, ! 97: /* class_inited */ FALSE, ! 98: /* initialize */ Initialize, ! 99: /* realize */ Realize, ! 100: /* actions */ NULL, ! 101: /* num_actions */ 0, ! 102: /* resourses */ resources, ! 103: /* resource_count */ XtNumber(resources), ! 104: /* xrm_class */ NULLQUARK, ! 105: /* compress_motion */ TRUE, ! 106: /* compress_exposure */ TRUE, ! 107: /* visible_interest */ FALSE, ! 108: /* destroy */ Destroy, ! 109: /* resize */ Resize, ! 110: /* expose */ NULL, ! 111: /* set_values */ SetValues, ! 112: /* accept_focus */ NULL ! 113: }, { ! 114: /* composite class fields */ ! 115: /* geometry_manager */ GeometryManager, ! 116: /* change_managed */ ChangeManaged, ! 117: /* insert_child */ InsertChild, ! 118: /* delete_child */ DeleteChild, ! 119: /* move_focus_to_next */ NULL, ! 120: /* move_focus_to_prev */ NULL ! 121: }, { ! 122: /* constraint class fields */ ! 123: /* subresourses */ subresources, ! 124: /* subresource_count */ XtNumber(subresources) ! 125: }, { ! 126: /* mumble */ 0 /* make C compiler happy */ ! 127: } ! 128: }; ! 129: ! 130: static int CursorNums[4] = {0, ! 131: XC_sb_up_arrow, ! 132: XC_sb_v_double_arrow, ! 133: XC_sb_down_arrow}; ! 134: ! 135: static Boolean NeedsAdjusting(vpw) ! 136: VPaneWidget vpw; ! 137: { ! 138: ! 139: int needed, i; ! 140: ! 141: for (i = 0; i < (vpw->composite.num_children/2); i++) { ! 142: if (vpw->composite.children[i * 2]->core.managed) ! 143: needed += sublist[i].dheight + BORDERWIDTH; ! 144: } ! 145: needed -= BORDERWIDTH; ! 146: if (needed > vpw->composite.children[i * 2]->core.height) ! 147: return(TRUE); ! 148: else return(FALSE); ! 149: ! 150: } ! 151: ! 152: static void AdjustVPaneHeight(vpw, newheight) ! 153: VPaneWidget vpw; ! 154: Dimension newheight; ! 155: { ! 156: XtWidgetGeometry request, reply; ! 157: XtGeometryResult result; ! 158: if (newheight < 1) newheight = 1; ! 159: request.height = newheight; ! 160: request.request_mode = CWHeight; ! 161: result = XtMakeGeometryRequest(vpw, &request, &reply); ! 162: if (result == XtGeometryAlmost) { ! 163: request = reply; ! 164: result = XtMakeGeometryRequest(vpw, &request, &reply); ! 165: } ! 166: if (result == XtGeometryYes) { ! 167: vpw->core.height = reply.height; ! 168: } ! 169: } ! 170: ! 171: ! 172: static RefigureLocations(vpw, position, dir) ! 173: VPaneWidget vpw; ! 174: int position; ! 175: int dir; /* -1 = up, 1 = down, 0 = this border only */ ! 176: { ! 177: SubWidgetPtr sub, firstsub; ! 178: WidgetList children; ! 179: int i, old, y, cdir, num_children, child, firstchild; ! 180: ! 181: if (vpw->composite.num_mapped_children == 0 || !vpw->v_pane.refiguremode) ! 182: return; ! 183: ! 184: children = vpw->composite.children; ! 185: num_children = vpw->composite.num_children / 2; ! 186: do { ! 187: vpw->v_pane.heightused = 0; ! 188: for (i = 0, sub = vpw->v_pane.sublist; i < num_children; i++, sub++) { ! 189: if (children[i * 2]->core.managed) { ! 190: if (sub->dheight < sub->min) ! 191: sub->dheight = sub->min; ! 192: if (sub->dheight > sub->max) ! 193: sub->dheight = sub->max; ! 194: vpw->v_pane.heightused += sub->dheight + BORDERWIDTH; ! 195: } ! 196: } ! 197: vpw->v_pane.heightused -= BORDERWIDTH; ! 198: if (dir == 0 && vpw->v_pane.heightused != vpw->core.height) { ! 199: for (i = 0, sub = vpw->v_pane.sublist; i < num_children; i++, sub++) { ! 200: if (children[i * 2]->core.managed) { ! 201: if (sub->dheight != children[i * 2]->core.height) ! 202: sub->dheight += vpw->core.height - vpw->v_pane.heightused; ! 203: } ! 204: } ! 205: } ! 206: } while (dir == 0 && vpw->v_pane.heightused != vpw->core.height); ! 207: ! 208: firstsub = vpw->v_pane.sublist + position; ! 209: firstchild = position * 2; ! 210: sub = firstsub; ! 211: child = firstchild; ! 212: cdir = dir; ! 213: while (vpw->v_pane.heightused != vpw->core.height) { ! 214: if (children[child]->core.managed) { ! 215: if (sub->autochange || cdir != dir) { ! 216: old = sub->dheight; ! 217: sub->dheight = vpw->core.height - vpw->v_pane.heightused + old; ! 218: if (sub->dheight < sub->min) ! 219: sub->dheight = sub->min; ! 220: if (sub->dheight > sub->max) ! 221: sub->dheight = sub->max; ! 222: vpw->v_pane.heightused += (sub->dheight - old); ! 223: } ! 224: sub += cdir; ! 225: child += (cdir * 2); ! 226: while (sub < vpw->v_pane.sublist || ! 227: sub - vpw->v_pane.sublist == num_children) { ! 228: cdir = -cdir; ! 229: if (cdir == dir) goto triplebreak; ! 230: sub = firstsub + cdir; ! 231: child = firstchild + (cdir * 2); ! 232: } ! 233: } ! 234: } ! 235: triplebreak: ! 236: y = -BORDERWIDTH; ! 237: for (i = 0, sub = vpw->v_pane.sublist; i < num_children; i++, sub++) { ! 238: if (child[i * 2]->core.managed) { ! 239: sub->dy = y; ! 240: y += sub->dheight + BORDERWIDTH; ! 241: } ! 242: } ! 243: } ! 244: ! 245: ! 246: static CommitNewLocations(vpw) ! 247: VPaneWidget vpw; ! 248: { ! 249: int i, kx, ky, num_children; ! 250: WidgetList children; ! 251: KnobWidget lastknob; ! 252: SubWidgetPtr sub; ! 253: ! 254: num_children = vpw->composite.num_children / 2; ! 255: children = vpw->composite.children ! 256: lastknob = NULL: ! 257: ! 258: /* First unmap all the knobs that are not managed */ ! 259: for (i = 0; i < vpw_composite.num_children; i+2) ! 260: if (children[i]->core.managed == FALSE) { ! 261: if (children[i + 1]->core.managed == TRUE) { ! 262: XtUnmapWidget(children[i + 1]); ! 263: children[i + 1]->core.managed = FALSE; ! 264: } ! 265: } ! 266: } ! 267: ! 268: for (i = 0, sub = vpw->v_pane.sublist; i < num_children; i++, sub++) { ! 269: if (children[i * 2]->core.managed) { ! 270: ! 271: /* see if the widget needs to be moved */ ! 272: if (sub->dy != children[i * 2]->core.y) ! 273: XtMoveWidget(children[i * 2], sub->dy, -BORDERWIDTH); ! 274: ! 275: /* see if the widget needs to be resized */ ! 276: if ((sub->dheight != children[i * 2]->core.height) || ! 277: (children[i * 2]->core.width != vpw->core.width) || ! 278: (children[i * 2]->core.borderwidth != BORDERWIDTH)) ! 279: XtResizeWidget(children[i * 2], vpw->core.height, sub->dheight, ! 280: BORDERWIDTH); ! 281: ! 282: /* Move and Display the Knob */ ! 283: kx = vpw->core.width - vpw->v_pane.knobindent; ! 284: ky = children[i * 2]->core.y + children[i * 2]->core.height - ! 285: (vpw->v_pane.knobheight/2)+1; ! 286: XtMoveWidget(sub->knob, kx, ky); ! 287: if (sub->knob->core.managed == FALSE) { ! 288: XtMapWidget(sub->knob); ! 289: sub->knob->core.managed = TRUE; ! 290: } ! 291: XRaiseWindow(XtDisplay(sub->knob), XtWindow(sub->knob)); ! 292: lastknob = sub->knob; ! 293: ! 294: } ! 295: } ! 296: ! 297: if (lastknob != NULL) { ! 298: XtUnMapWidget(lastknob); ! 299: lastknob->core.managed = FALSE; ! 300: } ! 301: } ! 302: ! 303: ! 304: static RefigureLocationsAndCommit(vpw, position, dir) ! 305: VPaneWidget data; ! 306: int position, dir; ! 307: { ! 308: RefigureLocations(vpw, position, dir); ! 309: CommitNewLocations(vpw); ! 310: } ! 311: ! 312: ! 313: EraseInternalBorders(data) ! 314: WidgetData data; ! 315: { ! 316: int i; ! 317: for (i = 1; i < data->numsubwindows; i++) ! 318: XFillRectangle(data->dpy, data->window, data->invgc, ! 319: 0, data->sub[i].y, data->width, BORDERWIDTH); ! 320: } ! 321: /* ! 322: ! 323: DrawInternalBorders(data) ! 324: WidgetData data; ! 325: { ! 326: int i; ! 327: for (i = 1; i < data->numsubwindows; i++) ! 328: XFillRectangle(data->dpy, data->window, data->normgc, ! 329: 0, data->sub[i].y, data->width, BORDERWIDTH); ! 330: } ! 331: ! 332: ! 333: static DrawTrackLines(data) ! 334: WidgetData data; ! 335: { ! 336: int i; ! 337: SubWindowPtr sub; ! 338: for (i = 1, sub = data->sub + 1; i < data->numsubwindows; i++, sub++) { ! 339: if (sub->olddy != sub->dy) { ! 340: XDrawLine(data->dpy, data->window, data->flipgc, ! 341: 0, sub->olddy, (Position) data->width, sub->olddy); ! 342: XDrawLine(data->dpy, data->window, data->flipgc, ! 343: 0, sub->dy, (Position) data->width, sub->dy); ! 344: sub->olddy = sub->dy; ! 345: } ! 346: } ! 347: } ! 348: ! 349: static EraseTrackLines(data) ! 350: WidgetData data; ! 351: { ! 352: int i; ! 353: SubWindowPtr sub; ! 354: for (i = 1, sub = data->sub + 1; i < data->numsubwindows; i++, sub++) ! 355: XDrawLine(data->dpy, data->window, data->flipgc, ! 356: 0, sub->olddy, (Position) data->width, sub->olddy); ! 357: } ! 358: ! 359: static XtEventReturnCode HandleKnob(event) ! 360: XEvent *event; ! 361: { ! 362: WidgetData data; ! 363: int position, diff, y, i; ! 364: ! 365: data = DataFromWindow(event->xbutton.display, event->xbutton.window); ! 366: if (!data) return XteventNotHandled; ! 367: switch (event->type) { ! 368: case ButtonPress: ! 369: y = event->xbutton.y; ! 370: if (data->whichtracking != -1) ! 371: return XteventNotHandled; ! 372: for (position = 0; position < data->numsubwindows; position++) ! 373: if (data->sub[position].knob == event->xbutton.window) ! 374: break; ! 375: if (position >= data->numsubwindows) ! 376: return XteventNotHandled; ! 377: ! 378: (void) XGrabPointer(data->dpy, event->xbutton.window, FALSE, ! 379: (unsigned int)PointerMotionMask | ButtonReleaseMask, ! 380: GrabModeAsync, GrabModeAsync, None, ! 381: XtGetCursor(data->dpy, ! 382: CursorNums[event->xbutton.button]), ! 383: CurrentTime); ! 384: data->whichadd = data->whichsub = NULL; ! 385: data->whichdirection = 2 - event->xbutton.button; * Hack! * ! 386: data->starty = y; ! 387: if (data->whichdirection >= 0) { ! 388: data->whichadd = data->sub + position; ! 389: while (data->whichadd->max == data->whichadd->min && ! 390: data->whichadd > data->sub) ! 391: (data->whichadd)--; ! 392: } ! 393: if (data->whichdirection <= 0) { ! 394: data->whichsub = data->sub + position + 1; ! 395: while (data->whichsub->max == data->whichsub->min && ! 396: data->whichsub < data->sub + data->numsubwindows - 1) ! 397: (data->whichsub)++; ! 398: } ! 399: data->whichtracking = position; ! 400: if (data->whichdirection == 1) ! 401: (data->whichtracking)++; ! 402: EraseInternalBorders(data); ! 403: for (i = 0; i < data->numsubwindows; i++) ! 404: data->sub[i].olddy = -99; ! 405: * Fall through * ! 406: ! 407: case MotionNotify: ! 408: case ButtonRelease: ! 409: if (event->type == MotionNotify) y = event->xmotion.y; ! 410: else y = event->xbutton.y; ! 411: if (data->whichtracking == -1) ! 412: return XteventNotHandled; ! 413: for (i = 0; i < data->numsubwindows; i++) ! 414: data->sub[i].dheight = data->sub[i].height; ! 415: diff = y - data->starty; ! 416: if (data->whichadd) ! 417: data->whichadd->dheight = data->whichadd->height + diff; ! 418: if (data->whichsub) ! 419: data->whichsub->dheight = data->whichsub->height - diff; ! 420: RefigureLocations(data, data->whichtracking, data->whichdirection); ! 421: ! 422: if (event->type != ButtonRelease) { ! 423: DrawTrackLines(data); * Draw new borders * ! 424: return XteventHandled; ! 425: } ! 426: XUngrabPointer(data->dpy, CurrentTime); ! 427: EraseTrackLines(data); ! 428: CommitNewLocations(data); ! 429: DrawInternalBorders(data); ! 430: data->whichtracking = -1; ! 431: return XteventHandled; ! 432: } ! 433: return XteventNotHandled; ! 434: } ! 435: */ ! 436: ! 437: /* Semi-public routines. */ ! 438: ! 439: static XtGeometryReturnCode GeometryManager(w, request, reply) ! 440: Widget w; ! 441: WidgetGeometry *request, *reply; ! 442: { ! 443: ! 444: return(XtgeometryNo); ! 445: ! 446: } ! 447: ! 448: static void Initialize(w) ! 449: Widget w; ! 450: { ! 451: ! 452: VPaneWidget vpw = (VPaneWidget) w; ! 453: unsigned long valuemask; ! 454: XGCValues values; ! 455: ! 456: values.foreground = vpw->v_pane.foreground_pixel; ! 457: values.function = GXcopy; ! 458: values.plane_mask = ~0; ! 459: values.fill_style = FillSolid; ! 460: values.fill_rule = EvenOddRule; ! 461: values.subwindow_mode = IncludeInferiors; ! 462: valuemask = GCForeground | GCFunction | GCPlaneMask | GCFillStyle ! 463: | GCFillRule | GCSubwindowMode; ! 464: vpw->v_pane.normgc = XtGetGC(vpw->core.display, vpw->core.window, valuemask, ! 465: &values); ! 466: values.foreground = vpw->core.background_pixel; ! 467: vpw->v_pane.invgc = XtGetGC(vpw->core.display, vpw->core.window, valuemask, ! 468: &values); ! 469: values.function = GXinvert; ! 470: #if BORDERWIDTH == 1 ! 471: values.line_width = 0; /* Take advantage of fast server lines. */ ! 472: #else ! 473: values.line_width = BORDERWIDTH; ! 474: #endif ! 475: values.line_style = LineSolid; ! 476: valuemask |= GCLineWidth | GCLineStyle; ! 477: vpw->v_pane.flipgc = XtGetGC(vpw->core.display, vpw->core.window, valuemask, ! 478: &values); ! 479: vpw->v_pane.heightused = 0; ! 480: vpw->v_pane.sublist = NULL; ! 481: vpw->v_pane.whichtracking = -1; ! 482: vpw->v_pane.refiguremode = TRUE; ! 483: } ! 484: ! 485: ! 486: static void Realize(w, valueMask, attributes) ! 487: register Widget w; ! 488: Mask valueMask; ! 489: XSetWindowAttributes *attributes; ! 490: ! 491: { ! 492: ! 493: attributes->bit_gravity = NorthWestGravity; ! 494: valueMask |= CWBitGravity; ! 495: ! 496: w->core.window = ! 497: XCreateWindow(w->core.display, w->core.parent, w->core.x, w->core.y, ! 498: w->core.width, w->core.height, w_core.border_width, ! 499: 0, InputOutput, (Visual *)CopyFromParent, valueMask, ! 500: attributes); ! 501: } /* Realize */ ! 502: ! 503: static void Destroy(vpw) ! 504: register VPaneWidget vpw; ! 505: { ! 506: ! 507: XtFree((char *) vpw->v_pane.sublist); ! 508: ! 509: } /* Destroy */ ! 510: ! 511: ! 512: static void InsertChild(w, args, argcount) ! 513: register Widget w; ! 514: ArgList args; ! 515: int argcount; ! 516: { ! 517: ! 518: static Arg knobargs[] = { ! 519: {XtNwidth, (XtArgVal) 0}, ! 520: {XtNheight, (XtArgVal) 0}, ! 521: {XtNbackground, (XtArgVal) "Black"} ! 522: }; ! 523: ! 524: Cardinal position; ! 525: VPaneWidgetClass myclass; ! 526: ConstraintWidgetClass superclass; ! 527: ConstraintWidget cw; ! 528: SubWidgetPtr sub; ! 529: int i; ! 530: ! 531: myclass = (VPaneWidgetClass) vPaneWidgetClass; ! 532: superclass = (ConstraintWidgetClass) myclass->core_class.superclass; ! 533: ! 534: /* insert the child widget in the composite children list with the */ ! 535: /* superclass insert_child routine. */ ! 536: superclass->composite_class.insert_child(w, args, argcount); ! 537: ! 538: if (!XtIsSubclass(w, KnobWidgetClass)) { ! 539: cw = w->core.parent; ! 540: ! 541: /* ||| Panes will be added in the order they are created, temporarilly */ ! 542: /* they are also managed at creation time. */ ! 543: ! 544: /* will normally get the position from the insert position routine */ ! 545: position = cw->composite_widget.num_children / 2; ! 546: cw->v_pane.sublist = ! 547: (SubWidgetPtr) XtRealloc((caddr_t) cw->v_pane.sublist, ! 548: ((cw->composite_widget.num_children/2 + 1) * sizeof(SubWidgetInfo))); ! 549: ! 550: /* shift up pane info then position new pane info */ ! 551: for (i = cw->composite_widget.num_children/2; i > position; i++) ! 552: cw->v_pane.sublist[i] = cw->v_pane.sublist[i - 1]; ! 553: ! 554: /* set the desired height of the pane */ ! 555: cw->v_pane.sublist[position].dheight = w->core.height; ! 556: ! 557: /* Get the subresources for this child widget */ ! 558: sub = &(cw->v_pane.sublist[position]); ! 559: XtGetSubResources(cw, sub, w->core.name, ! 560: w->core.widget_class->core_class.class_name, ! 561: subresources, XtNumber(subresources), args, argcount); ! 562: ! 563: /* Create the Knob Widget */ ! 564: knobargs[0].value = (XtArgVal) cw->v_pane.knob_width; ! 565: knobargs[1].value = (XtArgVal) cw->v_pane.knob_height; ! 566: knobargs[2].value = (XtArgVal) cw->v_pane.knob_pixel; ! 567: sub->knob = XtCreateWidget("Knob", KnobWidgetClass, (CompositeWidget) cw, ! 568: knobargs, XtNumber(knobargs)); ! 569: /* ! 570: XtSetEventHandler(sub->knob, ! 571: ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, FALSE, HandleKnob, ! 572: (caddr_t) NULL); ! 573: */ ! 574: ! 575: XDefineCursor(XtDisplay(sub->knob), sub->knob, ! 576: XtGetCursor(XtDisplay(sub->knob), XC_double_arrow)); ! 577: ! 578: } ! 579: ! 580: } /* InsertChild */ ! 581: ! 582: static void DeleteChild(w) ! 583: Widget w; ! 584: { ! 585: ! 586: Cardinal position; ! 587: VPaneWidgetClass myclass; ! 588: ConstraintWidgetClass superclass; ! 589: ConstraintWidget cw; ! 590: SubWidgetPtr sub; ! 591: ! 592: /* remove the subwidget info and destroy the knob */ ! 593: if (!XtIsSubClass(w, KnobWidgetClass)) { ! 594: cw = w->core.parent; ! 595: ! 596: /* find out the postion of the widget */ ! 597: for (position = 0; position < cw->composite.num_children; position++) { ! 598: if (cw->composite.children[position] == w) ! 599: break; ! 600: } ! 601: position = position/2; ! 602: ! 603: /* Destroy the knob */ ! 604: XtDestroyWidget(cw->v_pane.sublist[position].knob); ! 605: ! 606: /* Ripple the subwidget info down, over the deleted pane */ ! 607: for (i = position; i < cw->composite.num_children/2; i++) ! 608: cw->v_pane.sublist[i] = cw->v_pane.sublist[i + 1]; ! 609: ! 610: } ! 611: ! 612: myclass = (VPaneWidgetClass) vPaneWidgetClass; ! 613: superclass = (ConstraintWidgetClass) myclass->core_class.superclass; ! 614: ! 615: /* delete the child widget in the composite children list with the */ ! 616: /* superclass delete_child routine. */ ! 617: superclass->composite_class.delete_child(w); ! 618: ! 619: } /* DeleteChild */ ! 620: ! 621: static void ChangeManaged(vpw) ! 622: VPaneWidget vpw; ! 623: { ! 624: ! 625: /* see if the height of the VPane needs to be adjusted to fit all the panes */ ! 626: if (NeedsAdjusting(vpw)) ! 627: AdjustVPaneHeight(vpw); ! 628: RefigureLocationsAndCommit(vpw, 0, 1); ! 629: ! 630: } /* ChangeManaged */ ! 631: ! 632: static void Resize(vpw) ! 633: VPaneWidget vpw; ! 634: { ! 635: ! 636: RefigureLocationsAndCommit(vpw, 0, 1); ! 637: ! 638: } /* Resize */ ! 639: ! 640: static void SetValues(oldvpw, newvpw) ! 641: VPaneWidget oldvpw, newvpw; ! 642: { ! 643: } /* SetValues */ ! 644: ! 645: ! 646: /* Change the min and max size of the given sub window. */ ! 647: ! 648: void XtVPanedSetMinMax(vpw, paneWidget, min, max) ! 649: VPaneWidget vpw; ! 650: Widget paneWidget; ! 651: int min, max; ! 652: { ! 653: ! 654: int i; ! 655: ! 656: for (i = 0; i < vpw->composite.num_children; i + 2) { ! 657: if (vpw->composite.children[i] == paneWidget) { ! 658: vpw->v_pane.sublist[i / 2].min = min; ! 659: vpw->v_pane.sublist[i / 2].max = max; ! 660: RefigureLocationsAndCommit(vpw, i/2, 1); ! 661: return; ! 662: } ! 663: } ! 664: } ! 665: ! 666: ! 667: /* Get the min and max size of the given sub window. */ ! 668: ! 669: void XtVPanedGetMinMax(vpw, paneWidget, min, max) ! 670: VPaneWidget vpw; ! 671: Widget paneWindow; ! 672: int *min, *max; ! 673: { ! 674: ! 675: int i; ! 676: ! 677: for (i = 0; i < vpw->composite.num_children; i + 2) { ! 678: if (vpw->composite.children[i] == paneWidget) { ! 679: *min = vpw->v_pane.sublist[i / 2].min; ! 680: *max = vpw->v_pane.sublist[i / 2].max; ! 681: return; ! 682: } ! 683: } ! 684: } ! 685: ! 686: int XtVPanedGetNumSub(vpw) ! 687: VPaneWidget vpw; ! 688: { ! 689: ! 690: int i, num_sub_widgets; ! 691: ! 692: num_sub_widgets = 0; ! 693: ! 694: for (i = 0; i < vpw->composite.num_children; i + 2) { ! 695: if (vpw->composite.children[i]->core.managed) ! 696: num_sub_widgets++; ! 697: } ! 698: ! 699: return(num_sub_widgets); ! 700: } ! 701: ! 702: ! 703: ! 704: ! 705: void XtVPanedRefigureMode(vpw, mode) ! 706: VPaneWidget vpw; ! 707: Boolean mode; ! 708: { ! 709: vpw->v_pane.refiguremode = mode; ! 710: if (mode) ! 711: RefigureLocationsAndCommit(vpw, vpw->composite.num_children/2 - 1, -1); ! 712: } ! 713: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.