file: brush.c
/* brush.c - XmdvTool functions for brush manipulation */ /* Copyright 1994, Matthew O. Ward * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without fee * is granted provided that the above copyright notice appears in all copies. * It is provided "as is" without express or implied warranty. */ #include "XmdvTool.h" #include "brush.h" #include "brush_oper.h" #include "multi_select.h" #include "util.h" extern Widget appShell; extern GC gc; extern int dims; extern int curr_dim; extern double dim_min[MAXDIM], dim_max[MAXDIM], thumb; /* structures to hold current brush attributes and state variables */ Brush brushes[MAXBRUSH]; /* the brushes */ Brush all_brushes[MAXBRUSH]; /* the complete brushes */ Brush *brush; /* the current brush */ int brush_number; /* the current brush number */ /* array of brush and brush overlap colors */ XColor brush_colors[NUM_BRUSH_CELLS]; double *br_pos; /* pointer to current brush position */ double *br_size; /* pointer to current brush size */ XColor outline_col; /* the current brush color */ char message[30]; /* * InitBrush() - set initial brush position in the middle of a dimension * and size to be 50 percent of whole range. Also * set initial enable/display states. */ void InitBrush(void) { int br; /* brush num counter */ int dim; /* dim num counter */ for(br=0; br<MAXBRUSH; br++) { for(dim=0; dim<dims; dim++) { brushes[br].pos[dim] = (dim_max[dim] + dim_min[dim]) / 2.0; brushes[br].size[dim] = (dim_max[dim] - dim_min[dim]) / 2.0; brushes[br].bound_offset[dim] = (dim_max[dim] - dim_min[dim]) / 10.0; all_brushes[br].pos[dim] = brushes[br].pos[dim]; all_brushes[br].size[dim] = brushes[br].size[dim]; all_brushes[br].bound_offset[dim] = brushes[br].bound_offset[dim]; } brushes[br].enable = FALSE; brushes[br].display = FALSE; } /* enable the first brush */ brushes[0].enable = TRUE; brushes[0].display = TRUE; /* set the current brush */ ChangeBrush(0); } /* * ChangeBrushCB() - Callback function when the brush selector * is clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void ChangeBrushCB(Widget w, XtPointer params, XtPointer call_data) { int brush_no; /* the brush to change to */ /* extract the brush num from the passed string */ brush_no = atoi(params); brush_no--; /* sanity check */ if(brush_no < 0 || brush_no >= MAXBRUSH) { XBell(XtDisplay(w), 0); return; } ChangeBrush(brush_no); } /* * ChangeBrush() - Change the current brush number. * * PARAMETERS * newbrush The new brush number * * RETURNS * 1 Error * 0 Success */ int ChangeBrush(int newbrush) { if(newbrush<0 || newbrush>=MAXBRUSH) return 1; brush = &brushes[newbrush]; brush_number = newbrush; br_pos = brush->pos; br_size = brush->size; outline_col = brush_colors[BRUSH_COLOR(newbrush)]; return 0; } /* * ResizeBrushCB() - Callback function when one of the automatic brush * resize buttons is clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void ResizeBrushCB(Widget w, XtPointer params, XtPointer call_data) { int dim; /* current dimension num */ double newmin, newmax; /* new min/max values */ /* params as a char pointer */ char *params_text = (char *)params; if(!strcmp(params_text, "Max")) { /* resize to max */ for(dim=0; dim<dims; dim++) { br_pos[dim] = (dim_max[dim] + dim_min[dim]) / 2.0; br_size[dim] = dim_max[dim] - dim_min[dim]; } } else if(!strcmp(params_text, "Half")) { /* resize to half max */ for(dim=0; dim<dims; dim++) { br_pos[dim] = (dim_max[dim] + dim_min[dim]) / 2.0; br_size[dim] = (dim_max[dim] - dim_min[dim]) / 2.0; } } else if(!strcmp(params_text, "+10")) { /* resize +10% */ for(dim=0; dim<dims; dim++) { /* calculate current min/max */ newmin = br_pos[dim] - br_size[dim]/2.0; newmax = br_pos[dim] + br_size[dim]/2.0; /* adjust +10% */ newmin -= (dim_max[dim] - dim_min[dim]) * 0.05; newmax += (dim_max[dim] - dim_min[dim]) * 0.05; /* bound min/max */ newmin = MAX(newmin, dim_min[dim]); newmax = MIN(newmax, dim_max[dim]); /* recalculate pos/size */ br_pos[dim] = (newmin + newmax) / 2.0; br_size[dim] = newmax - newmin; } } else if(!strcmp(params_text, "-10")) { /* resize -10% */ for(dim=0; dim<dims; dim++) { br_size[dim] -= (dim_max[dim] - dim_min[dim]) * 0.1; br_size[dim] = MAX(br_size[dim], 0.0); } } else { /* bad value passed in */ XBell(XtDisplay(w), 0); } } /* * CheckBrushCoverage() - Given a data point and a brush number, this * function checks if the point is covered * by the brush * * PARAMETERS * point The data point * brush The brush number * * RETURNS * TRUE The point is covered by the brush * FALSE The point is NOT covered by the brush */ int CheckBrushCoverage(double *point, int br) { int i; switch(brushes[br].bound) { case BOUND_STEP: for(i=0; i<dims; i++) if((point[i] < (brushes[br].pos[i] - brushes[br].size[i]/2.0)) || (point[i] > (brushes[br].pos[i] + brushes[br].size[i]/2.))) return(0); return(1); case BOUND_RAMP: for(i=0; i<dims; i++) if((point[i] < (brushes[br].pos[i] - brushes[br].size[i]/2.0 - brushes[br].bound_offset[i])) || (point[i] > (brushes[br].pos[i] + brushes[br].size[i]/2.0 + brushes[br].bound_offset[i]))) return(0); return(1); default: fprintf(stderr, "Invalid brush boundary passed to CheckBrushCoverage()\n"); return(0); } } /* * PercentBrushCoverage() - Given a data point and a brush number, this * function checks the amount that the point * is covered by the brush. Only makes sense * for brushes with non stepped boundaries. * * PARAMETERS * point The data point * br The brush number * * RETURNS * The amount of brush coverage (0..1) */ double PercentBrushCoverage(double *point, int br) { int i; double coverage, amount, min=1.0; /* the brush coverage */ switch(brushes[br].bound) { case BOUND_STEP: for(i=0; i<dims; i++) { if((point[i] < (brushes[br].pos[i] - brushes[br].size[i]/2.0)) || (point[i] > (brushes[br].pos[i] + brushes[br].size[i]/2.))) return(0.0); } return(1.0); /* compute coverage as linear interpolation between brush */ /* start and end */ case BOUND_RAMP: for(coverage = 0.0, i=0; i<dims; i++) { /* if fully within brush for this dimension, add 1 */ if(point[i] >= brushes[br].pos[i] - brushes[br].size[i]/2.0 && point[i] <= brushes[br].pos[i] + brushes[br].size[i]/2.0) coverage += 1.0; /* if in lower ramp, compute what percent of ramp it is located at */ else if (point[i] >= brushes[br].pos[i] - brushes[br].size[i]/2.0 - brushes[br].bound_offset[i] && point[i] < brushes[br].pos[i] - brushes[br].size[i]/2.0) { amount = (brushes[br].bound_offset[i] - ((brushes[br].pos[i] - brushes[br].size[i]/2.0) - point[i])) / (double)brushes[br].bound_offset[i]; coverage += amount; if(amount < min) min = amount; } /* if in upper ramp, compute what percent of ramp it is located at */ else if (point[i] <= brushes[br].pos[i] + brushes[br].size[i]/2.0 + brushes[br].bound_offset[i] && point[i] > brushes[br].pos[i] + brushes[br].size[i]/2.0) { amount = (brushes[br].bound_offset[i] - (point[i] - (brushes[br].pos[i] + brushes[br].size[i] / 2.0))) / (double)brushes[br].bound_offset[i]; coverage += amount; if(amount < min) min = amount; } else /* no coverage, return 0.0 */ return(0.0); } coverage /= (double)dims; break; default: fprintf(stderr, "Invalid boundary type in PercentBrushCoverage()\n"); } /* change to minimum ramp value */ /* return(coverage); */ return(min); } /* * CoverageRank() - Given a data point, returns the number of brushes * that contain that point. * * PARAMETERS * point The data point * * RETURNS * The number of brushes that cover the point. * */ int CoverageRank(double *point) { int br; /* current brush number */ int coverage=0; /* the total coverage */ for(br=0; br<MAXBRUSH; br++) { /* skip this brush if disabled */ if(brushes[br].enable == FALSE) continue; if(CheckBrushCoverage(point, br)) coverage++; } return(coverage); } /* * EnableBrushCB() - Callback function when a brush is enabled. * The bursh number to enable is passed as a * parameter. * * PARAMETERS * w Selected widget * params User data passed to callback (brush number) * call_data Data about this callback * * RETURNS * void */ void EnableBrushCB(Widget w, XtPointer params, XtPointer call_data) { char *brush_name = (char *)params; /* char pointer to passed brush name */ int brush_no; /* the brush number */ Boolean state; /* off/on state of toggle widget */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ brush_no = atoi(brush_name) - 1; /* check validity */ if(brush_no < 0 || brush_no >= MAXBRUSH) { fprintf(stderr, "Bad value passed to EnableBrush()\n"); XBell(XtDisplay(w), 0); return; } /* get the widget's off/on state */ n = 0; XtSetArg(wargs[n], XtNstate, &state); n++; XtGetValues(w, wargs, n); brushes[brush_no].enable = state; } /* * DisplayBrushCB() - Callback function when a brush display is enabled. * The bursh number to enable is passed as a * parameter. * * PARAMETERS * w Selected widget * params User data passed to callback (brush number) * call_data Data about this callback * * RETURNS * void */ void DisplayBrushCB(Widget w, XtPointer params, XtPointer call_data) { char *brush_name = (char *)params; /* char pointer to passed brush name */ int brush_no; /* the brush number */ Boolean state; /* off/on state of toggle widget */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ brush_no = atoi(brush_name) - 1; /* check validity */ if(brush_no < 0 || brush_no >= MAXBRUSH) { fprintf(stderr, "Bad value passed to DisplayBrushCB()\n"); XBell(XtDisplay(w), 0); return; } /* get the widget's off/on state */ n = 0; XtSetArg(wargs[n], XtNstate, &state); n++; XtGetValues(w, wargs, n); brushes[brush_no].display = state; } /* * BoundaryStepCB() - Callback function when the brush boundary * step button is pressed. * * PARAMETERS * w Selected widget * params User data passed to callback (brush number) * call_data Data about this callback * * RETURNS * void */ void BoundaryStepCB(Widget w, XtPointer params, XtPointer call_data) { char *brush_name = (char *)params; /* char pointer to passed brush name */ int brush_no; /* the brush number */ Boolean state; /* off/on state of toggle widget */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ brush_no = atoi(brush_name) - 1; /* check validity */ if(brush_no < 0 || brush_no >= MAXBRUSH) { fprintf(stderr, "Bad value passed to BoundaryStepCB()\n"); XBell(XtDisplay(w), 0); return; } /* get the widget's off/on state */ n = 0; XtSetArg(wargs[n], XtNstate, &state); n++; XtGetValues(w, wargs, n); if(state == False) return; brushes[brush_no].bound = BOUND_STEP; } /* * BoundaryRampCB() - Callback function when the brush boundary * ramp button is pressed. * * PARAMETERS * w Selected widget * params User data passed to callback (brush number) * call_data Data about this callback * * RETURNS * void */ void BoundaryRampCB(Widget w, XtPointer params, XtPointer call_data) { char *brush_name = (char *)params; /* char pointer to passed brush name */ int brush_no; /* the brush number */ Boolean state; /* off/on state of toggle widget */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ brush_no = atoi(brush_name) - 1; /* check validity */ if(brush_no < 0 || brush_no >= MAXBRUSH) { fprintf(stderr, "Bad value passed to BoundaryRampCB()\n"); XBell(XtDisplay(w), 0); return; } /* get the widget's off/on state */ n = 0; XtSetArg(wargs[n], XtNstate, &state); n++; XtGetValues(w, wargs, n); if(state == False) return; brushes[brush_no].bound = BOUND_RAMP; }
Back to Source File Index
C++ to HTML Conversion by ctoohtml