From b4eafc000bac06ca2eace24a35f4ab4a72a5c194 Mon Sep 17 00:00:00 2001 From: joye Date: Mon, 10 Mar 2014 20:29:57 +0000 Subject: *** empty log message *** --- src/bltGrAxis.C | 2 +- src/bltGrElemBar.C | 5 +- src/bltGrElemLine.C | 10 +-- src/bltGrElemOp.C | 181 +++++++++++----------------------------------------- src/bltGrElemOp.h | 30 +-------- src/bltGrMarker.C | 2 +- src/bltGraph.C | 40 ++++++------ src/bltGraph.h | 29 +++++++++ tests/linegraph.tcl | 3 + 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" -- cgit v0.12