|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: S T
Length: 8610 (0x21a2) Types: TextFile Names: »ScrollBox.c«
└─⟦8648bda34⟧ Bits:30007244 EUUGD5_II: X11R5 └─⟦2ca9b63e1⟧ »./contrib-1/contrib-1.00« └─⟦a8392fb20⟧ └─⟦this⟧ »contrib/examples/OReilly/Vol4/ch11/ScrollBox.c«
/* * Copyright 1989 O'Reilly and Associates, Inc. * See ../Copyright for complete rights and liability information. */ /* * ScrollBox.c - scrollBox composite widget */ #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> #include "ScrollBoxP.h" #include <stdio.h> #define INITIAL_WIDTH 300 #define INITIAL_HEIGHT 300 /**************************************************************** * * scrollBox Resources * ****************************************************************/ static XtResource resources[] = { {XtNhSpace, XtCHSpace, XtRDimension, sizeof(Dimension), XtOffset(ScrollBoxWidget, scrollBox.h_space), XtRImmediate, (XtPointer)4}, {XtNvSpace, XtCVSpace, XtRDimension, sizeof(Dimension), XtOffset(ScrollBoxWidget, scrollBox.v_space), XtRImmediate, (XtPointer)4}, }; /**************************************************************** * * Full class record constant * ****************************************************************/ static void Initialize(); static void Resize(); static Boolean SetValues(); static void ChangeManaged(); static XtGeometryResult QueryGeometry(), GeometryManager(); static void RefigureLocations(); ScrollBoxClassRec scrollBoxClassRec = { { /* core_class fields */ /* superclass */ (WidgetClass) &compositeClassRec, /* class_name */ "scrollBox", /* widget_size */ sizeof(ScrollBoxRec), /* class_initialize */ NULL, /* class_part_init */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ NULL, /* num_actions */ 0, /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave*/ TRUE, /* visible_interest */ FALSE, /* destroy */ NULL, /* resize */ Resize, /* expose */ NULL, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL, /* query_geometry */ QueryGeometry, /* display_accelerator*/ XtInheritDisplayAccelerator, /* extension */ NULL },{ /* composite_class fields */ /* geometry_manager */ GeometryManager, /* change_managed */ ChangeManaged, /* insert_child */ XtInheritInsertChild, /* delete_child */ XtInheritDeleteChild, /* extension */ NULL },{ /* scrollBox class fields */ /* empty */ 0, } }; WidgetClass scrollBoxWidgetClass = (WidgetClass)&scrollBoxClassRec; /**************************************************************** * * Private Routines * ****************************************************************/ /* * Do a layout, either actually assigning positions, or just * calculating size. */ /* ARGSUSED */ static DoLayout(w, doit) Widget w; Boolean doit; { ScrollBoxWidget sbw = (ScrollBoxWidget) w; Widget main, vscroll, hscroll; Widget child; Dimension mw, mh; /* main window */ Dimension vh; /* vertical scrollbar length (height) */ Dimension hw; /* horizontal scrollbar length (width) */ Position vx; Position hy; int i; if (sbw->composite.num_children != 3) XtAppError(XtWidgetToApplicationContext(sbw), "ScrollBox: must manage exactly three widgets."); for (i = 0; i < sbw->composite.num_children; i++) { child = sbw->composite.children[i]; if (!XtIsManaged(child)) { XtAppError(XtWidgetToApplicationContext(sbw), "ScrollBox: all three widgets must be managed."); } } /* * Child one is the main window, two is the vertical scrollbar, * and three is the horizontal scrollbar. */ main = sbw->composite.children[0]; vscroll = sbw->composite.children[1]; hscroll = sbw->composite.children[2]; /* * Size all three widgets so that space is fully utilized. */ mw = sbw->core.width - (2 * sbw->scrollBox.h_space) - vscroll->core.width - (2 * vscroll->core.border_width) - (2 * main->core.border_width); mh = sbw->core.height - (2 * sbw->scrollBox.v_space) - hscroll->core.height - (2 * hscroll->core.border_width) - (2 * main->core.border_width); vx = main->core.x + mw + sbw->scrollBox.h_space + main->core.border_width + vscroll->core.border_width; hy = main->core.y + mh + sbw->scrollBox.v_space + main->core.border_width + hscroll->core.border_width; vh = mh; /* scrollbars are always same length as main window */ hw = mw; if (doit) { XtResizeWidget(main, mw, mh, 1); XtResizeWidget(vscroll, vscroll->core.width, vh, 1); XtMoveWidget(vscroll, vx, vscroll->core.y); XtResizeWidget(hscroll, hw, hscroll->core.height, 1); XtMoveWidget(hscroll, hscroll->core.x, hy); } } /* ARGSUSED */ static XtGeometryResult GeometryManager(w, request, reply) Widget w; XtWidgetGeometry *request; XtWidgetGeometry *reply; /* RETURN */ { XtWidgetGeometry allowed; if (request->request_mode & ~(XtCWQueryOnly | CWWidth | CWHeight)) return XtGeometryNo; if (request->request_mode & CWWidth) allowed.width = request->width; else allowed.width = w->core.width; if (request->request_mode & CWHeight) allowed.height = request->height; else allowed.height = w->core.height; if (allowed.width == w->core.width && allowed.height == w->core.height) return XtGeometryNo; if (!(request->request_mode & XtCWQueryOnly)) { RefigureLocations(w); } return XtGeometryYes; } static void RefigureLocations(sbw) ScrollBoxWidget sbw; { DoLayout(sbw, False); } /* * Calculate preferred size. We can't just use the current sizes * of the children, because that calculation would always end up with * our current size. Could query each child, and use that size to * recalculate a size for us, then if it ends up being larger * than width and height passed in, accept bounding box. * However, we know our children and they don't have any particular * preferred geometry, except the bigger the better. * Therefore, if the parent suggested a size, we'll take it. */ /* ARGSUSED */ static XtGeometryResult QueryGeometry(w, request, reply_return) Widget w; XtWidgetGeometry *request, *reply_return; { XtGeometryResult result; request->request_mode &= CWWidth | CWHeight; if (request->request_mode == 0) /* parent isn't going to change w or h, so nothing to re-compute */ return XtGeometryYes; /* if proposed size is large enough, accept it. Otherwise, * suggest our arbitrary initial size. */ if (request->request_mode & CWHeight) { if (request->height < INITIAL_HEIGHT) { result = XtGeometryAlmost; reply_return->height = INITIAL_HEIGHT; reply_return->request_mode &= CWHeight; } else result = XtGeometryYes; } if (request->request_mode & CWWidth) { if (request->width < INITIAL_WIDTH) { result = XtGeometryAlmost; reply_return->width = INITIAL_WIDTH; reply_return->request_mode &= CWWidth; } else result = XtGeometryYes; } return(result); } /* * Actually layout the scrollBox */ static void Resize(w) Widget w; { ScrollBoxWidget sbw = (ScrollBoxWidget) w; DoLayout(sbw, True); } static void ChangeManaged(w) ScrollBoxWidget w; { ScrollBoxWidget sbw = (ScrollBoxWidget) w; DoLayout(sbw, True); } /* ARGSUSED */ static void Initialize(request, new) Widget request, new; { ScrollBoxWidget newsbw = (ScrollBoxWidget)new; if (newsbw->core.width == 0) newsbw->core.width = INITIAL_WIDTH; if (newsbw->core.height == 0) newsbw->core.height = INITIAL_HEIGHT; } /* Initialize */ /* ARGSUSED */ static Boolean SetValues(current, request, new, args, num_args) Widget current, request, new; ArgList args; Cardinal *num_args; { ScrollBoxWidget sbwcurrent = (ScrollBoxWidget) current; ScrollBoxWidget sbwnew = (ScrollBoxWidget) new; /* need to relayout if h_space or v_space change */ if ((sbwnew->scrollBox.h_space != sbwcurrent->scrollBox.h_space) || (sbwnew->scrollBox.v_space != sbwcurrent->scrollBox.v_space)) DoLayout(sbwnew, True); return False; }