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 "BarDisplaP.h" /* Bar display object */
- #include "GraphP.h" /* Graph widget */
-
- #define Offset(field) XtOffsetOf(BarDisplayRec, barDisplay.field)
-
- static XtResource resources[] = {
- {XtNspace, XtCSpace, XtRDimension, sizeof(Dimension),
- Offset(space), XtRImmediate, (XtPointer) 5},
- {XtNdefaultGraphWidth, XtCDefaultGraphWidth,
- XtRDimension, sizeof(Dimension),
- Offset(default_graph_width), XtRImmediate, (XtPointer) 200},
- {XtNformat, XtCFormat, XtRString, sizeof(String),
- Offset(format), XtRString, "%g"}
- };
- #undef Offset
-
- /* Forward declarations */
-
- static void Initialize(), Redisplay(), ComputeSize();
- static Boolean SetValues();
-
- /* Class record declaration */
-
- BarDisplayClassRec barDisplayClassRec = {
- /* Object class part */
- {
- /* superclass */ (WidgetClass) &graphDisplayClassRec,
- /* class_name */ "BarDisplay",
- /* widget_size */ sizeof(BarDisplayRec),
- /* class_initialize */ NULL,
- /* class_part_initialize */ NULL,
- /* class_inited */ FALSE,
- /* initialize */ Initialize,
- /* initialize_hook */ NULL,
- /* obj1 */ NULL,
- /* obj2 */ NULL,
- /* obj3 */ 0,
- /* resources */ resources,
- /* num_resources */ XtNumber(resources),
- /* xrm_class */ NULLQUARK,
- /* obj4 */ 0,
- /* obj5 */ 0,
- /* obj6 */ 0,
- /* obj7 */ 0,
- /* destroy */ NULL,
- /* obj8 */ NULL,
- /* obj9 */ NULL,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* obj10 */ NULL,
- /* get_values_hook */ NULL,
- /* obj11 */ NULL,
- /* version */ XtVersion,
- /* callback offsets */ NULL,
- /* obj12 */ NULL,
- /* obj13 */ NULL,
- /* obj14 */ NULL,
- /* extension */ NULL
- },
- /* GraphDisplay class part */
- {
- /* compute_size */ ComputeSize,
- /* expose */ Redisplay,
- /* extension */ NULL
- },
- /* BarDisplay class part */
- {
- /* extension */ NULL
- }
- };
-
- /* Class record pointer */
-
- WidgetClass barDisplayObjectClass = (WidgetClass) &barDisplayClassRec;
-
- static void Initialize(request, new, args, num_args)
- Widget request, new;
- ArgList args;
- Cardinal *num_args;
- {
- BarDisplayObject bd = (BarDisplayObject) new;
-
- /* Copy format */
- bd->barDisplay.format = XtNewString(bd->barDisplay.format);
- }
-
- static Boolean SetValues(old, request, new, args, num_args)
- Widget old, request, new;
- ArgList args;
- Cardinal *num_args;
- {
- BarDisplayObject oldbd = (BarDisplayObject) old;
- BarDisplayObject newbd = (BarDisplayObject) new;
-
- #define NE(field) (oldbd->barDisplay.field != newbd->barDisplay.field)
-
- if (NE(format)) {
- newbd->barDisplay.format =
- XtNewString(newbd->barDisplay.format);
- }
-
- /* If space or format has changed and we're realized, redisplay */
-
- if (NE(space) || NE(format)) {
-
- /* Kludge. There's no way to tell the Intrinsics to
- automatically redisplay, so clear the parent, causing
- expose events. Subclasses will do this too, but multiple
- redisplays are avoided since the parent has
- XtExposeCompressMultiple. */
-
- if (XtIsRealized(XtParent((Widget) newbd))) {
- XClearArea(XtDisplayOfObject(newbd),
- XtWindowOfObject(newbd), 0, 0, 0, 0, TRUE);
- }
- }
-
- return FALSE;
- }
-
- static void ComputeLabelDimensions(bd, label_w, total_w, height)
- BarDisplayObject bd;
- Dimension *label_w, *total_w, *height;
- {
- register XFontStruct *fs = bd->graphDisplay.font;
- register int i;
- int width;
- GraphWidget parent = (GraphWidget) XtParent((Widget) bd);
- char buf[100];
-
- *label_w = *total_w = 0;
- if (parent->graph.labels != NULL) {
- for (i = 0; i < parent->graph.num_entries; i++) {
- width = XTextWidth(fs, parent->graph.labels[i],
- strlen(parent->graph.labels[i]));
- if (width > *label_w) *label_w = width;
- }
- }
-
- for (i = 0; i < parent->graph.num_entries; i++) {
- (void) sprintf(buf, bd->barDisplay.format,
- (float) parent->graph.values[i] / parent->graph.scale);
- width = XTextWidth(fs, buf, strlen(buf));
- if (width > *total_w) *total_w = width;
- }
-
- *total_w += *label_w;
- *height = fs->max_bounds.ascent + fs->max_bounds.descent;
- }
-
- static void ComputeSize(w)
- GraphWidget w;
- {
- BarDisplayObject bd = (BarDisplayObject) w->composite.children[0];
- Dimension label_width, total_width, label_height;
-
- ComputeLabelDimensions(bd, &label_width,
- &total_width, &label_height);
-
- /* If parent has no width, compute one */
- if (w->core.width == 0) {
- w->core.width = 4*bd->barDisplay.space + total_width +
- bd->barDisplay.default_graph_width;
- }
-
- /* If parent has no height, compute one */
- if (w->core.height == 0) {
- w->core.height = w->graph.num_entries *
- (bd->barDisplay.space + label_height) +
- bd->barDisplay.space;
- }
- }
-
- static void Redisplay(w, event, region)
- GraphWidget w;
- XEvent *event;
- Region region;
- {
- BarDisplayObject bd = (BarDisplayObject) w->composite.children[0];
- Dimension label_width, total_width, label_height;
- Boolean displayBars;
- register int i;
- int x, y, bar_width;
- char buf[100];
- register int *values = w->graph.values;
- register String *labels = w->graph.labels;
-
- ComputeLabelDimensions(bd, &label_width, &total_width,
- &label_height);
-
- /* See if there's enough room to display bars */
-
- bar_width = w->core.width - total_width - 4*bd->barDisplay.space;
- displayBars = (bar_width > (int) bd->barDisplay.space);
-
- y = bd->barDisplay.space;
- for (i = 0; i < w->graph.num_entries; i++) {
- if (labels != NULL) {
- XDrawString(XtDisplay(w), XtWindow(w), bd->graphDisplay.gc,
- bd->barDisplay.space,
- y + bd->graphDisplay.font->max_bounds.ascent,
- labels[i], strlen(labels[i]));
- x = label_width + 2*bd->barDisplay.space;
- } else x = 0;
-
- if (displayBars) {
- XFillRectangle(XtDisplay(w), XtWindow(w),
- bd->graphDisplay.gc, x, y,
- bar_width * values[i] / w->graph.max_value,
- bd->graphDisplay.font->max_bounds.ascent);
- x += bar_width * values[i] / w->graph.max_value +
- bd->barDisplay.space;
- }
-
- (void) sprintf(buf, bd->barDisplay.format,
- (float) values[i] / w->graph.scale);
- XDrawString(XtDisplay(w), XtWindow(w), bd->graphDisplay.gc,
- x, y + bd->graphDisplay.font->max_bounds.ascent,
- buf, strlen(buf));
-
- y += label_height + bd->barDisplay.space;
- }
- }
-
-