home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute these examples for any
- purpose and without fee is hereby granted, provided that the above
- copyright notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting documentation,
- and that the name of Digital not be used in advertising or publicity
- pertaining to distribution of the software without specific, written
- prior permission.
-
- DIGITAL AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
- OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- OR PERFORMANCE OF THIS SOFTWARE.
-
- ******************************************************************/
-
- #include <X11/IntrinsicP.h> /* Intrinsics header file */
- #include <X11/StringDefs.h> /* Resource string definitions */
- #include "MinMaxP.h" /* MinMax private header file */
- #include "LabelGadge.h" /* To check LabelGadgets */
-
- #define Offset(field) XtOffsetOf(MinMaxRec, minMax.field)
-
- static XtResource resources[] = {
- {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension),
- Offset(margin), XtRImmediate, (XtPointer) 10},
- };
-
- #undef Offset
-
- #define Offset(field) XtOffsetOf(MinMaxConstraintRec, field)
-
- static XtResource constraintResources[] = {
- {XtNminWidth, XtCMinWidth, XtRShort, sizeof(short),
- Offset(minMax.min_width), XtRImmediate, (XtPointer) -1},
- {XtNmaxWidth, XtCMaxWidth, XtRShort, sizeof(short),
- Offset(minMax.max_width), XtRImmediate, (XtPointer) -1},
- {XtNminHeight, XtCMinHeight, XtRShort, sizeof(short),
- Offset(minMax.min_height), XtRImmediate, (XtPointer) -1},
- {XtNmaxHeight, XtCMaxHeight, XtRShort, sizeof(short),
- Offset(minMax.max_height), XtRImmediate, (XtPointer) -1},
- };
- #undef Offset
-
- /* Forward declarations */
-
- static void ChangeManaged(), Initialize(), ConstraintInitialize(),
- Resize(), InsertChild(), DeleteChild(), Redisplay();
- static XtGeometryResult GeometryManager();
- static Boolean SetValues(), AcceptFocus(), ConstraintSetValues();
-
- static CompositeClassExtensionRec compositeExtension = {
- /* next_extension */ NULL,
- /* record_type */ NULLQUARK,
- /* version */ XtCompositeExtensionVersion,
- /* record_size */ sizeof(CompositeClassExtensionRec),
- /* accepts_objects */ TRUE
- };
-
- MinMaxClassRec minMaxClassRec = {
- /* Core class part */
- {
- /* superclass */ (WidgetClass) &constraintClassRec,
- /* class_name */ "MinMax",
- /* widget_size */ sizeof(MinMaxRec),
- /* class_initialize */ NULL,
- /* class_part_initialize */ 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 */ XtExposeCompressMultiple,
- /* compress_enterleave */ TRUE,
- /* visible_interest */ FALSE,
- /* destroy */ NULL,
- /* resize */ Resize,
- /* expose */ Redisplay,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* accept_focus */ AcceptFocus,
- /* version */ XtVersion,
- /* callback offsets */ NULL,
- /* tm_table */ NULL,
- /* query_geometry */ XtInheritQueryGeometry,
- /* display_accelerator */ NULL,
- /* extension */ NULL,
- },
- /* Composite class part */
- {
- /* geometry_manager */ GeometryManager,
- /* change_managed */ ChangeManaged,
- /* insert_child */ InsertChild,
- /* delete_child */ DeleteChild,
- /* extension */ (XtPointer) &compositeExtension,
- },
- /* Constraint class part */
- {
- /* resources */ constraintResources,
- /* num_resources */ XtNumber(constraintResources),
- /* constraint_size */ sizeof(MinMaxConstraintRec),
- /* initialize */ ConstraintInitialize,
- /* destroy */ NULL,
- /* set_values */ ConstraintSetValues,
- /* extension */ NULL
- },
- /* MinMax class part */
- {
- /* extension */ NULL,
- }
- };
-
- WidgetClass minMaxWidgetClass = (WidgetClass) &minMaxClassRec;
-
- static void InsertChild(w)
- Widget w;
- {
- String params[2];
- Cardinal num_params;
- Widget parent = XtParent(w);
-
- if (!XtIsWidget(w) && !XtIsSubclass(w, labelGadgetClass)) {
- params[0] = XtClass(w)->core_class.class_name;
- params[1] = XtClass(parent)->core_class.class_name;
- num_params = 2;
- XtAppErrorMsg(XtWidgetToApplicationContext(w),
- "childError", "class", "WidgetError",
- "Children of class %s cannot be added to %n widgets",
- params, &num_params);
- }
-
- (*((CompositeWidgetClass)(minMaxWidgetClass->
- core_class.superclass))->composite_class.insert_child) (w);
- }
-
- static void DeleteChild(w)
- Widget w;
- {
- MinMaxWidget minMax = (MinMaxWidget) XtParent(w);
-
- if (minMax->minMax.last_focus == w) {
- minMax->minMax.last_focus = NULL;
- }
-
- (*((CompositeWidgetClass)(minMaxWidgetClass->
- core_class.superclass))->composite_class.delete_child) (w);
- }
-
- static void Initialize(req, new, args, num_args)
- Widget req, new;
- ArgList args;
- Cardinal *num_args;
- {
- ((MinMaxWidget) new)->minMax.last_focus = NULL;
- }
-
- static void CheckConstraint(w, smaller, larger, which)
- Widget w;
- short *smaller, *larger;
- String which;
- {
- String params[3];
- Cardinal num_params;
-
- if (*smaller > *larger) {
- params[0] = params[1] = which;
- params[2] = XtName(w);
- num_params = 3;
- XtAppWarningMsg(XtWidgetToApplicationContext(w),
- "constraintError",
- "width", "WidgetError",
- "Min %s greater than max %s for widget %s",
- params, &num_params);
- *smaller = *larger;
- }
- }
-
- static void ResizeWithinConstraints(w, width, height)
- Widget w;
- Dimension *width, *height;
- {
- register MinMaxConstraint mmc =
- (MinMaxConstraint) w->core.constraints;
-
- if (*width < mmc->minMax.min_width) {
- *width = mmc->minMax.min_width;
- } else if (*width > mmc->minMax.max_width) {
- *width = mmc->minMax.max_width;
- }
-
- if (*height < mmc->minMax.min_height) {
- *height = mmc->minMax.min_height;
- } else if (*height > mmc->minMax.max_height) {
- *height = mmc->minMax.max_height;
- }
- }
-
- static void ConstraintInitialize(req, new, args, num_args)
- Widget req, new;
- ArgList args;
- Cardinal *num_args;
- {
- MinMaxConstraint mmc = (MinMaxConstraint) new->core.constraints;
- Dimension width = new->core.width, height = new->core.height;
- #define MAXDIM 32768
-
- if (mmc->minMax.min_width == -1 && mmc->minMax.max_width == -1) {
- mmc->minMax.min_width = mmc->minMax.max_width = width;
- }
- if (mmc->minMax.min_height == -1 && mmc->minMax.max_height == -1) {
- mmc->minMax.min_height = mmc->minMax.max_height = height;
- }
-
- if (mmc->minMax.min_width == -1) mmc->minMax.min_width = 1;
- if (mmc->minMax.max_width == -1) mmc->minMax.max_width = MAXDIM;
- if (mmc->minMax.min_height == -1) mmc->minMax.min_height = 1;
- if (mmc->minMax.max_height == -1) mmc->minMax.max_height = MAXDIM;
-
- CheckConstraint(new, &mmc->minMax.min_width,
- &mmc->minMax.max_width, "width");
- CheckConstraint(new, &mmc->minMax.min_height,
- &mmc->minMax.max_height, "height");
- ResizeWithinConstraints(new, &width, &height);
-
- if (width != new->core.width || height != new->core.height) {
- XtResizeWidget(new, width, height);
- }
- #undef MAXDIM
- }
-
- static void CalculateNewSize(minMax, width, height)
- MinMaxWidget minMax;
- register Dimension *width, *height;
- {
- register Widget child;
- register int i;
- int right, bottom;
-
- *width = *height = 0;
-
- for (i = 0; i < minMax->composite.num_children; i++) {
- child = minMax->composite.children[i];
- if (!XtIsManaged(child)) continue;
- right = child->core.x + child->core.width +
- 2 * child->core.border_width;
- bottom = child->core.y + child->core.height +
- 2 * child->core.border_width;
- if (right > (int) *width) *width = right;
- if (bottom > (int) *height) *height = bottom;
- }
-
- *width += minMax->minMax.margin;
- *height += minMax->minMax.margin;
-
- if (*width == 0) *width = 1;
- if (*height == 0) *height = 1;
- }
-
- static void ResizeChildren(minMax, initiator)
- MinMaxWidget minMax;
- Widget initiator;
- {
- register Widget child;
- register MinMaxConstraint mmc;
- register int i;
- int right, bottom;
- int new_width, new_height;
- int minMax_right = minMax->core.width - minMax->minMax.margin,
- minMax_bottom = minMax->core.height - minMax->minMax.margin;
-
- for (i = 0; i < minMax->composite.num_children; i++) {
- child = minMax->composite.children[i];
- if (!XtIsManaged(child) || child == initiator) continue;
-
- mmc = (MinMaxConstraint) child->core.constraints;
- new_width = child->core.width;
- new_height = child->core.height;
-
- right = child->core.x + child->core.width +
- 2 * child->core.border_width;
- bottom = child->core.y + child->core.height +
- 2 * child->core.border_width;
-
- if (right > minMax_right &&
- child->core.width > mmc->minMax.min_width) {
- new_width -= right - minMax_right;
- if (new_width < mmc->minMax.min_width) {
- new_width = mmc->minMax.min_width;
- }
- } else if (right < minMax_right &&
- child->core.width < mmc->minMax.max_width) {
- new_width += minMax_right - right;
- if (new_width > mmc->minMax.max_width) {
- new_width = mmc->minMax.max_width;
- }
- }
-
- if (bottom > minMax_bottom &&
- child->core.height > mmc->minMax.min_height) {
- new_height -= bottom - minMax_bottom;
- if (new_height < mmc->minMax.min_height) {
- new_height = mmc->minMax.min_height;
- }
- } else if (bottom < minMax_bottom &&
- child->core.height < mmc->minMax.max_height) {
- new_height += minMax_bottom - bottom;
- if (new_height > mmc->minMax.max_height) {
- new_height = mmc->minMax.max_height;
- }
- }
-
- XtResizeWidget(child, new_width, new_height,
- child->core.border_width);
- }
- }
-
- static void Resize(w)
- Widget w;
- {
- ResizeChildren((MinMaxWidget) w, (Widget) NULL);
- }
-
- static void ChangeManaged(w)
- Widget w;
- {
- MinMaxWidget minMax = (MinMaxWidget) w;
- XtWidgetGeometry request;
- XtGeometryResult result;
-
- CalculateNewSize(minMax, &request.width, &request.height);
-
- if (request.width != minMax->core.width ||
- request.height != minMax->core.height) {
- request.request_mode = CWWidth | CWHeight;
- do {
- result = XtMakeGeometryRequest(w,
- &request, (XtWidgetGeometry *) NULL);
- } while (result == XtGeometryAlmost);
-
- if (result == XtGeometryYes) {
- ResizeChildren(minMax, (Widget) NULL);
- }
- }
- }
-
- static XtGeometryResult GeometryManager(w, desired, allowed)
- Widget w;
- XtWidgetGeometry *desired, *allowed;
- {
- MinMaxWidget minMax = (MinMaxWidget) XtParent(w);
- MinMaxConstraint mmc = (MinMaxConstraint) w->core.constraints;
- XtWidgetGeometry request;
- XtGeometryResult result;
- Dimension save_width, save_height, save_border_width;
- Position save_x, save_y;
-
- #define Wants(flag) (desired->request_mode & flag)
- #define RestoreGeometry(w) { \
- w->core.x = save_x; w->core.y = save_y; \
- w->core.width = save_width; w->core.height = save_height; \
- w->core.border_width = save_border_width; }
-
- /* If the desired change goes outside the constraints, say no */
-
- if ((Wants(CWWidth) && (desired->width < mmc->minMax.min_width ||
- desired->width > mmc->minMax.max_width)) ||
- (Wants(CWHeight) &&
- (desired->height < mmc->minMax.min_height ||
- desired->height > mmc->minMax.max_height))) {
- return XtGeometryNo;
- }
-
- /* Figure out how big we would be with this change */
-
- save_x = w->core.x;
- save_y = w->core.y;
- save_width = w->core.width;
- save_height = w->core.height;
- save_border_width = w->core.border_width;
- if (Wants(CWX)) w->core.x = desired->x;
- if (Wants(CWY)) w->core.y = desired->y;
- if (Wants(CWWidth)) w->core.width = desired->width;
- if (Wants(CWHeight)) w->core.height = desired->height;
- if (Wants(CWBorderWidth)) {
- w->core.border_width = desired->border_width;
- }
-
- CalculateNewSize(minMax, &request.width, &request.height);
-
- if (request.width == minMax->core.width &&
- request.height == minMax->core.height) {
- if (Wants(XtCWQueryOnly)) RestoreGeometry(w);
- return XtGeometryYes;
- }
-
- /* We need to change size in order to accommodate; see if we can */
-
- request.request_mode = CWWidth | CWHeight;
- if (Wants(XtCWQueryOnly)) request.request_mode |= XtCWQueryOnly;
-
- result = XtMakeGeometryRequest((Widget) minMax, &request, NULL);
- if (result == XtGeometryAlmost) result = XtGeometryNo;
-
- if (result == XtGeometryYes && !Wants(XtCWQueryOnly)) {
- ResizeChildren(minMax, w);
- return XtGeometryYes;
- }
-
- /* Undo the saved changes */
-
- RestoreGeometry(w);
- return result;
- #undef Wants
- #undef RestoreGeometry
- }
-
- static Boolean SetValues(old, req, new, args, num_args)
- Widget old, req, new;
- ArgList args;
- Cardinal *num_args;
- {
- register MinMaxWidget oldminMax = (MinMaxWidget) old;
- register MinMaxWidget newminMax = (MinMaxWidget) new;
-
- if (newminMax->minMax.margin != oldminMax->minMax.margin ||
- newminMax->core.width == 0 ||
- newminMax->core.height == 0) {
- CalculateNewSize(newminMax,
- &newminMax->core.width, &newminMax->core.height);
- }
-
- return FALSE;
- }
-
- static Boolean ConstraintSetValues(old, req, new, args, num_args)
- Widget old, req;
- ArgList args;
- Cardinal *num_args;
- register Widget new;
- {
- register MinMaxConstraint mmc =
- (MinMaxConstraint) new->core.constraints;
-
- CheckConstraint(new, &mmc->minMax.min_width,
- &mmc->minMax.max_width, "width");
- CheckConstraint(new, &mmc->minMax.min_height,
- &mmc->minMax.max_height, "height");
- ResizeWithinConstraints(new, &new->core.width, &new->core.height);
-
- return FALSE;
- }
-
- static Boolean AcceptFocus(w, time)
- Widget w;
- Time *time;
- {
- MinMaxWidget minMax = (MinMaxWidget) w;
- register int i;
-
- if (minMax->minMax.last_focus != NULL &&
- XtIsManaged(minMax->minMax.last_focus)) {
- if (XtCallAcceptFocus(minMax->minMax.last_focus, time)) {
- return TRUE;
- }
- }
-
- for (i = 0; i < minMax->composite.num_children; i++) {
- if (!XtIsManaged(minMax->composite.children[i])) continue;
- if (XtCallAcceptFocus(minMax->composite.children[i], time)) {
- minMax->minMax.last_focus = minMax->composite.children[i];
- return TRUE;
- }
- }
-
- minMax->minMax.last_focus = NULL;
- return FALSE;
- }
-
- static void Redisplay(w, event, region)
- Widget w;
- XEvent *event;
- Region region;
- {
- CompositeWidget comp = (CompositeWidget) w;
- int i;
- Widget c; /* child */
-
- for (i = 0; i < comp->composite.num_children; i++) {
- c = comp->composite.children[i];
- if (XtIsManaged(c) && XtIsSubclass(c, labelGadgetClass) &&
- XRectInRegion(region, c->core.x, c->core.y,
- c->core.width + 2*c->core.border_width,
- c->core.height + 2*c->core.border_width)
- != RectangleOut) {
- (*(XtClass(c)->core_class.expose))(c, event, region);
- }
- }
- }
-