summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bltGrAxis.C2
-rw-r--r--src/bltGrElemBar.C5
-rw-r--r--src/bltGrElemLine.C10
-rw-r--r--src/bltGrElemOp.C181
-rw-r--r--src/bltGrElemOp.h30
-rw-r--r--src/bltGrMarker.C2
-rw-r--r--src/bltGraph.C40
-rw-r--r--src/bltGraph.h29
-rw-r--r--tests/linegraph.tcl3
9 files changed, 104 insertions, 198 deletions
diff --git a/src/bltGrAxis.C b/src/bltGrAxis.C
index ee5a7e7..4155243 100644
--- a/src/bltGrAxis.C
+++ b/src/bltGrAxis.C
@@ -37,9 +37,9 @@
#include "bltInt.h"
#include "bltMath.h"
#include "bltGraph.h"
+#include "bltGrElem.h"
#include "bltOp.h"
#include "bltGrAxis.h"
-#include "bltGrElem.h"
#include "bltConfig.h"
#define AXIS_PAD_TITLE 2
diff --git a/src/bltGrElemBar.C b/src/bltGrElemBar.C
index 4f19b3e..ad80f1c 100644
--- a/src/bltGrElemBar.C
+++ b/src/bltGrElemBar.C
@@ -732,9 +732,10 @@ static void GetBarExtentsProc(Element *basePtr, Region2d *regPtr)
}
}
-static void ClosestBarProc(Graph* graphPtr, Element *basePtr,
- ClosestSearch *searchPtr)
+static void ClosestBarProc(Graph* graphPtr, Element *basePtr)
{
+ ClosestSearch* searchPtr = &graphPtr->search;
+
BarElement* elemPtr = (BarElement *)basePtr;
XRectangle *bp;
double minDist;
diff --git a/src/bltGrElemLine.C b/src/bltGrElemLine.C
index 78101e0..523b8d8 100644
--- a/src/bltGrElemLine.C
+++ b/src/bltGrElemLine.C
@@ -2192,8 +2192,10 @@ static double DistanceToYProc(int x, int y, Point2d *p, Point2d *q, Point2d *t)
}
static int ClosestTrace(Graph* graphPtr, LineElement* elemPtr,
- ClosestSearch *searchPtr, DistanceProc *distProc)
+ DistanceProc *distProc)
{
+ ClosestSearch* searchPtr = &graphPtr->search;
+
Blt_ChainLink link;
Point2d closest;
double dMin;
@@ -2394,9 +2396,9 @@ static void GetLineExtentsProc(Element *basePtr, Region2d *extsPtr)
}
}
-static void ClosestLineProc(Graph* graphPtr, Element *basePtr,
- ClosestSearch *searchPtr)
+static void ClosestLineProc(Graph* graphPtr, Element *basePtr)
{
+ ClosestSearch* searchPtr = &graphPtr->search;
LineElement* elemPtr = (LineElement *)basePtr;
int mode;
@@ -2423,7 +2425,7 @@ static void ClosestLineProc(Graph* graphPtr, Element *basePtr,
} else {
distProc = DistanceToLineProc;
}
- found = ClosestTrace(graphPtr, elemPtr, searchPtr, distProc);
+ found = ClosestTrace(graphPtr, elemPtr, distProc);
if ((!found) && (searchPtr->along != SEARCH_BOTH)) {
ClosestPoint(elemPtr, searchPtr);
}
diff --git a/src/bltGrElemOp.C b/src/bltGrElemOp.C
index 5965d52..7e02dd3 100644
--- a/src/bltGrElemOp.C
+++ b/src/bltGrElemOp.C
@@ -544,178 +544,75 @@ static int BindOp(Graph* graphPtr, Tcl_Interp* interp,
return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4);
}
-static Blt_OptionParseProc ObjToAlong;
-static Blt_OptionPrintProc AlongToObj;
-static Blt_CustomOption alongOption =
- {
- ObjToAlong, AlongToObj, NULL, (ClientData)0
- };
-
-static int ObjToAlong(ClientData clientData, Tcl_Interp* interp,
- Tk_Window tkwin, Tcl_Obj *objPtr, char *widgRec,
- int offset, int flags)
-{
- int *intPtr = (int *)(widgRec + offset);
- char *string;
-
- string = Tcl_GetString(objPtr);
- if ((string[0] == 'x') && (string[1] == '\0')) {
- *intPtr = SEARCH_X;
- } else if ((string[0] == 'y') && (string[1] == '\0')) {
- *intPtr = SEARCH_Y;
- } else if ((string[0] == 'b') && (strcmp(string, "both") == 0)) {
- *intPtr = SEARCH_BOTH;
- } else {
- Tcl_AppendResult(interp, "bad along value \"", string, "\"",
- (char *)NULL);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-static Tcl_Obj *AlongToObj(ClientData clientData, Tcl_Interp* interp,
- Tk_Window tkwin, char *widgRec, int offset,
- int flags)
-{
- int along = *(int *)(widgRec + offset);
- Tcl_Obj *objPtr;
-
- switch (along) {
- case SEARCH_X:
- objPtr = Tcl_NewStringObj("x", 1);
- break;
- case SEARCH_Y:
- objPtr = Tcl_NewStringObj("y", 1);
- break;
- case SEARCH_BOTH:
- objPtr = Tcl_NewStringObj("both", 4);
- break;
- default:
- objPtr = Tcl_NewStringObj("unknown along value", 4);
- break;
- }
- return objPtr;
-}
-
-static Blt_ConfigSpec closestSpecs[] = {
- {BLT_CONFIG_PIXELS, "-halo", (char *)NULL, (char *)NULL,
- (char *)NULL, Tk_Offset(ClosestSearch, halo), 0},
- {BLT_CONFIG_BOOLEAN, "-interpolate", (char *)NULL, (char *)NULL,
- (char *)NULL, Tk_Offset(ClosestSearch, mode), 0 },
- {BLT_CONFIG_CUSTOM, "-along", (char *)NULL, (char *)NULL,
- (char *)NULL, Tk_Offset(ClosestSearch, along), 0, &alongOption},
- {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL,
- (char *)NULL, 0, 0}
-};
-
static int ClosestOp(Graph* graphPtr, Tcl_Interp* interp,
int objc, Tcl_Obj* const objv[])
{
- Element* elemPtr;
- ClosestSearch search;
- int i, x, y;
- char *string;
+ ClosestSearch* searchPtr = &graphPtr->search;
- if (graphPtr->flags & RESET_AXES) {
+ if (graphPtr->flags & RESET_AXES)
Blt_ResetAxes(graphPtr);
- }
+
+ int x;
if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
Tcl_AppendResult(interp, ": bad window x-coordinate", (char *)NULL);
return TCL_ERROR;
}
+ int y;
if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
Tcl_AppendResult(interp, ": bad window y-coordinate", (char *)NULL);
return TCL_ERROR;
}
- for (i = 5; i < objc; i += 2) { /* Count switches-value pairs */
- string = Tcl_GetString(objv[i]);
- if ((string[0] != '-') ||
- ((string[1] == '-') && (string[2] == '\0'))) {
- break;
- }
- }
- if (i > objc) {
- i = objc;
- }
-
- search.mode = SEARCH_POINTS;
- search.halo = graphPtr->halo;
- search.index = -1;
- search.along = SEARCH_BOTH;
- search.x = x;
- search.y = y;
- if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, closestSpecs, i - 5,
- objv + 5, (char *)&search, BLT_CONFIG_OBJV_ONLY) != TCL_OK) {
- return TCL_ERROR; /* Error occurred processing an option. */
- }
- if (i < objc) {
- string = Tcl_GetString(objv[i]);
- if (string[0] == '-') {
- i++; /* Skip "--" */
- }
- }
- search.dist = (double)(search.halo + 1);
+ searchPtr->x = x;
+ searchPtr->y = y;
+ searchPtr->index = -1;
+ searchPtr->dist = (double)(searchPtr->halo + 1);
- if (i < objc) {
- for ( /* empty */ ; i < objc; i++) {
- if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) {
- return TCL_ERROR; /* Can't find named element */
- }
- if (IGNORE_ELEMENT(elemPtr)) {
- continue;
- }
- if ((elemPtr->flags & MAP_ITEM) && elemPtr->hide) {
- continue;
- }
- (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search);
- }
- } else {
- Blt_ChainLink link;
+ char* string = Tcl_GetString(objv[5]);
+ if (string && string[0] != '\0') {
+ Element* elemPtr;
+ if (Blt_GetElement(interp, graphPtr, objv[5], &elemPtr) != TCL_OK)
+ return TCL_ERROR; /* Can't find named element */
+ if (elemPtr && !elemPtr->hide &&
+ !(elemPtr->flags & (MAP_ITEM|DELETE_PENDING)))
+ (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr);
+ }
+ else {
/*
* Find the closest point from the set of displayed elements,
* searching the display list from back to front. That way if
* the points from two different elements overlay each other
* exactly, the last one picked will be the topmost.
*/
- for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
+ for (Blt_ChainLink link=Blt_Chain_LastLink(graphPtr->elements.displayList);
link != NULL; link = Blt_Chain_PrevLink(link)) {
- elemPtr = Blt_Chain_GetValue(link);
- if ((elemPtr->flags & (MAP_ITEM|DELETE_PENDING)) && elemPtr->hide) {
- continue;
- }
- (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search);
+ Element* elemPtr = Blt_Chain_GetValue(link);
+ if (elemPtr && !elemPtr->hide &&
+ !(elemPtr->flags & (MAP_ITEM|DELETE_PENDING)))
+ (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr);
}
}
- if (search.dist < (double)search.halo) {
- Tcl_Obj *listObjPtr;
- /*
- * Return a list of name value pairs.
- */
- listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewStringObj("name", -1));
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewStringObj(search.elemPtr->obj.name, -1));
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewStringObj("index", -1));
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewIntObj(search.index));
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewStringObj("x", -1));
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewDoubleObj(search.point.x));
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewStringObj("y", -1));
+
+ if (searchPtr->dist < (double)searchPtr->halo) {
+ // Return a list of name value pairs.
+ Tcl_Obj* listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+ Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("name", -1));
Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewDoubleObj(search.point.y));
+ Tcl_NewStringObj(searchPtr->elemPtr->obj.name, -1));
+ Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("index", -1));
+ Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(searchPtr->index));
+ Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("x", -1));
Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewStringObj("dist", -1));
+ Tcl_NewDoubleObj(searchPtr->point.x));
+ Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("y", -1));
Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewDoubleObj(search.dist));
+ Tcl_NewDoubleObj(searchPtr->point.y));
+ Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("dist", -1));
+ Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(searchPtr->dist));
Tcl_SetObjResult(interp, listObjPtr);
}
+
return TCL_OK;
}
diff --git a/src/bltGrElemOp.h b/src/bltGrElemOp.h
index ff31811..868f047 100644
--- a/src/bltGrElemOp.h
+++ b/src/bltGrElemOp.h
@@ -117,33 +117,6 @@ typedef struct {
int show; /* Flags for errorbars: none, x, y, or both */
} ErrorBarAttributes;
-typedef struct {
- /* Inputs */
- int halo; /* Maximal screen distance a candidate point
- * can be from the sample window coordinate */
-
- int mode; /* Indicates whether to find the closest data
- * point or the closest point on the trace by
- * interpolating the line segments. Can also
- * be SEARCH_AUTO, indicating to choose how to
- * search.*/
-
- int x, y; /* Screen coordinates of test point */
-
- int along; /* Indicates to let search run along a
- * particular axis: x, y, or both. */
-
- /* Outputs */
- Element* elemPtr; /* Name of the closest element */
-
- Point2d point; /* Graph coordinates of closest point */
-
- int index; /* Index of closest data point */
-
- double dist; /* Distance in screen coordinates */
-
-} ClosestSearch;
-
typedef void (ElementDrawProc) (Graph *graphPtr, Drawable drawable,
Element* elemPtr);
@@ -158,8 +131,7 @@ typedef void (ElementMapProc) (Graph *graphPtr, Element* elemPtr);
typedef void (ElementExtentsProc) (Element* elemPtr, Region2d *extsPtr);
-typedef void (ElementClosestProc) (Graph *graphPtr, Element* elemPtr,
- ClosestSearch *searchPtr);
+typedef void (ElementClosestProc) (Graph *graphPtr, Element* elemPtr);
typedef void (ElementDrawSymbolProc) (Graph *graphPtr, Drawable drawable,
Element* elemPtr, int x, int y, int symbolSize);
diff --git a/src/bltGrMarker.C b/src/bltGrMarker.C
index edbaf7d..6cb73e48 100644
--- a/src/bltGrMarker.C
+++ b/src/bltGrMarker.C
@@ -2793,7 +2793,7 @@ PointInLineProc(Marker *markerPtr, Point2d *samplePtr)
LineMarker *lmPtr = (LineMarker *)markerPtr;
return Blt_PointInSegments(samplePtr, lmPtr->segments, lmPtr->nSegments,
- (double)markerPtr->obj.graphPtr->halo);
+ (double)markerPtr->obj.graphPtr->search.halo);
}
/*
diff --git a/src/bltGraph.C b/src/bltGraph.C
index 66a4d0e..cfbd8e5 100644
--- a/src/bltGraph.C
+++ b/src/bltGraph.C
@@ -86,6 +86,8 @@ typedef int (GraphCmdProc)(Graph* graphPtr, Tcl_Interp* interp, int objc,
static char* barmodeObjOption[] =
{"normal", "stacked", "aligned", "overlap", NULL};
+char* searchModeObjOption[] = {"points", "traces", "auto", NULL};
+char* searchAlongObjOption[] = {"x", "y", "both", NULL};
static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_DOUBLE, "-aspect", "aspect", "Aspect",
@@ -124,8 +126,7 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
STD_NORMAL_FOREGROUND, -1, Tk_Offset(Graph, titleTextStyle.color), 0, NULL,
CACHE_DIRTY},
- {TK_OPTION_PIXELS, "-halo", "halo", "Halo",
- "2m", -1, Tk_Offset(Graph, halo), 0, NULL, 0},
+ {TK_OPTION_SYNONYM, "-halo", NULL, NULL, NULL, -1, 0, 0, "-searchhalo", 0},
{TK_OPTION_PIXELS, "-height", "height", "Height",
"4i", -1, Tk_Offset(Graph, reqHeight), 0, NULL, RESET_WORLD | CACHE_DIRTY},
{TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
@@ -169,6 +170,12 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_STRING, "-rightvariable", "rightVariable", "RightVariable",
NULL, -1, Tk_Offset(Graph, rightMargin.varName), TK_OPTION_NULL_OK, NULL, 0},
{TK_OPTION_SYNONYM, "-rm", NULL, NULL, NULL, -1, 0, 0, "-rightmargin", 0},
+ {TK_OPTION_PIXELS, "-searchhalo", "searchhalo", "SearchHalo",
+ "2m", -1, Tk_Offset(Graph, search.halo), 0, NULL, 0},
+ {TK_OPTION_STRING_TABLE, "-searchmode", "searchMode", "SearchMode",
+ "points", -1, Tk_Offset(Graph, search.mode), 0, &searchModeObjOption, 0},
+ {TK_OPTION_STRING_TABLE, "-searchalong", "searchAlong", "SearchAlong",
+ "both", -1, Tk_Offset(Graph, search.along), 0, &searchAlongObjOption, 0},
{TK_OPTION_BOOLEAN, "-stackaxes", "stackAxes", "StackAxes",
"no", -1, Tk_Offset(Graph, stackAxes), 0, NULL, 0},
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
@@ -1041,31 +1048,26 @@ static ClientData PickEntry(ClientData clientData, int x, int y,
return markerPtr; /* Found a marker (-under false). */
}
- ClosestSearch search;
-
- search.along = SEARCH_BOTH;
- search.halo = graphPtr->halo;
- search.index = -1;
- search.x = x;
- search.y = y;
- search.dist = (double)(search.halo + 1);
- search.mode = SEARCH_AUTO;
+ ClosestSearch* searchPtr = &graphPtr->search;
+ searchPtr->index = -1;
+ searchPtr->x = x;
+ searchPtr->y = y;
+ searchPtr->dist = (double)(searchPtr->halo + 1);
Blt_ChainLink link;
Element* elemPtr;
for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
link != NULL; link = Blt_Chain_PrevLink(link)) {
elemPtr = Blt_Chain_GetValue(link);
- if (elemPtr->flags & (HIDE|MAP_ITEM)) {
+ if (elemPtr->flags & (HIDE|MAP_ITEM))
continue;
- }
- if (elemPtr->state == BLT_STATE_NORMAL) {
- (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search);
- }
- }
- if (search.dist <= (double)search.halo) {
- return search.elemPtr;// Found an element within the minimum halo distance.
+
+ if (elemPtr->state == BLT_STATE_NORMAL)
+ (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr);
}
+ // Found an element within the minimum halo distance.
+ if (searchPtr->dist <= (double)searchPtr->halo)
+ return searchPtr->elemPtr;
markerPtr = Blt_NearestMarker(graphPtr, x, y, TRUE);
if (markerPtr != NULL) {
diff --git a/src/bltGraph.h b/src/bltGraph.h
index aaf19e0..f69beae 100644
--- a/src/bltGraph.h
+++ b/src/bltGraph.h
@@ -48,6 +48,33 @@ typedef enum {
} ClassId;
typedef struct {
+ /* Inputs */
+ int halo; /* Maximal screen distance a candidate point
+ * can be from the sample window coordinate */
+
+ int mode; /* Indicates whether to find the closest data
+ * point or the closest point on the trace by
+ * interpolating the line segments. Can also
+ * be SEARCH_AUTO, indicating to choose how to
+ * search.*/
+
+ int x, y; /* Screen coordinates of test point */
+
+ int along; /* Indicates to let search run along a
+ * particular axis: x, y, or both. */
+
+ /* Outputs */
+ Element* elemPtr; /* Name of the closest element */
+
+ Point2d point; /* Graph coordinates of closest point */
+
+ int index; /* Index of closest data point */
+
+ double dist; /* Distance in screen coordinates */
+
+} ClosestSearch;
+
+typedef struct {
/* Generic fields common to all graph objects. */
ClassId classId; /* Class type of object. */
const char *name; /* Identifier to refer the object. */
@@ -373,6 +400,8 @@ struct _Graph {
* ways: aligned, overlap, infront, or
* stacked. */
int maxBarSetSize;
+
+ ClosestSearch search;
};
/*
diff --git a/tests/linegraph.tcl b/tests/linegraph.tcl
index 41e288c..aae78a4 100644
--- a/tests/linegraph.tcl
+++ b/tests/linegraph.tcl
@@ -39,6 +39,9 @@ bltTest $graph -relief groove
bltTest $graph -rightmargin 50
#bltTest $graph -rightvariable
bltTest $graph -rm 50
+#bltTest $graph -searchhalo
+#bltTest $graph -searchmode
+#bltTest $graph -searchalong
#bltTest $graph -stackaxes
#bltTest $graph -takefocus
bltTest $graph -title "This is a Title"