summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorjoye <joye>2014-04-08 18:50:10 (GMT)
committerjoye <joye>2014-04-08 18:50:10 (GMT)
commite9b261c35ce151313f26402ab0dcbb104f3523b5 (patch)
tree196aac8d5ff03b2ad04cae4696167b0d9a5aeb7f /src
parent73f434743c46ad0f281c488e1912ea96cc48c77e (diff)
downloadblt-e9b261c35ce151313f26402ab0dcbb104f3523b5.zip
blt-e9b261c35ce151313f26402ab0dcbb104f3523b5.tar.gz
blt-e9b261c35ce151313f26402ab0dcbb104f3523b5.tar.bz2
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/bltGrLegd.C551
-rw-r--r--src/bltGrLegd.h16
-rw-r--r--src/bltGrLegdOp.C527
-rw-r--r--src/bltGraph.C4
4 files changed, 555 insertions, 543 deletions
diff --git a/src/bltGrLegd.C b/src/bltGrLegd.C
index c85bd86..ea8a781 100644
--- a/src/bltGrLegd.C
+++ b/src/bltGrLegd.C
@@ -37,22 +37,6 @@ extern "C" {
#include "bltGrElem.h"
#include "bltGrElemOp.h"
-// Selection related flags:
-// SELECT_PENDING A "selection" command idle task is pending.
-// SELECT_CLEAR Clear selection flag of entry.
-// SELECT_SET Set selection flag of entry.
-// SELECT_TOGGLE Toggle selection flag of entry.
-// Mask of selection set/clear/toggle flags.
-// SELECT_SORTED Indicates if the entries in the selection
-// should be sorted or displayed in the order
-// they were selected.
-
-#define SELECT_CLEAR (1<<24)
-#define SELECT_PENDING (1<<25)
-#define SELECT_SET (1<<26)
-#define SELECT_SORTED (1<<27)
-#define SELECT_TOGGLE (SELECT_SET | SELECT_CLEAR)
-
#define LABEL_PAD 2
// Defs
@@ -61,19 +45,9 @@ extern "C" {
Tcl_ObjCmdProc Blt_GraphInstCmdProc;
};
-static int SelectionOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[]);
-static int LegendObjConfigure(Tcl_Interp* interp, Graph* graphPtr,
- int objc, Tcl_Obj* const objv[]);
-static void ConfigureLegend(Graph* graphPtr);
-static int EntryIsSelected(Legend* legendPtr, Element* elemPtr);
-static int GetElementFromObj(Graph* graphPtr, Tcl_Obj *objPtr,
- Element **elemPtrPtr);
-static void ClearSelection(Legend* legendPtr);
-static void DeselectElement(Legend* legendPtr, Element* elemPtr);
-static int SelectRange(Legend* legendPtr, Element *fromPtr, Element *toPtr);
-static void EventuallyInvokeSelectCmd(Legend* legendPtr);
-static void SelectEntry(Legend* legendPtr, Element* elemPtr);
+extern int EntryIsSelected(Legend* legendPtr, Element* elemPtr);
+extern void DeselectElement(Legend* legendPtr, Element* elemPtr);
+extern void SelectEntry(Legend* legendPtr, Element* elemPtr);
static int CreateLegendWindow(Tcl_Interp* interp, Legend* legendPtr,
const char *pathName);
@@ -81,12 +55,8 @@ static Tcl_IdleProc DisplayLegend;
static Blt_BindPickProc PickEntryProc;
static Tk_EventProc LegendEventProc;
static Tcl_TimerProc BlinkCursorProc;
-static Tk_LostSelProc LostSelectionProc;
static Tk_SelectionProc SelectionProc;
-typedef int (GraphLegendProc)(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[]);
-
// OptionSpecs
static const char* selectmodeObjOption[] = {"single", "multiple", NULL};
@@ -420,88 +390,7 @@ static void LegendEventProc(ClientData clientData, XEvent *eventPtr)
// Configure
-static int CgetOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "cget option");
- return TCL_ERROR;
- }
-
- Legend* legendPtr = graphPtr->legend;
- Tcl_Obj* objPtr = Tk_GetOptionValue(interp,
- (char*)legendPtr,
- legendPtr->optionTable,
- objv[3], graphPtr->tkwin);
- if (objPtr == NULL)
- return TCL_ERROR;
- else
- Tcl_SetObjResult(interp, objPtr);
- return TCL_OK;
-}
-
-static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- if (objc <= 4) {
- Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp,
- (char*)legendPtr,
- legendPtr->optionTable,
- (objc == 4) ? objv[3] : NULL,
- graphPtr->tkwin);
- if (objPtr == NULL)
- return TCL_ERROR;
- else
- Tcl_SetObjResult(interp, objPtr);
- return TCL_OK;
- }
- else
- return LegendObjConfigure(interp, graphPtr, objc-3, objv+3);
-}
-
-static int LegendObjConfigure(Tcl_Interp* interp, Graph* graphPtr,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- Tk_SavedOptions savedOptions;
- int mask =0;
- int error;
- Tcl_Obj* errorResult;
-
- for (error=0; error<=1; error++) {
- if (!error) {
- if (Tk_SetOptions(interp, (char*)legendPtr, legendPtr->optionTable,
- objc, objv, graphPtr->tkwin, &savedOptions, &mask)
- != TCL_OK)
- continue;
- }
- else {
- errorResult = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(errorResult);
- Tk_RestoreSavedOptions(&savedOptions);
- }
-
- graphPtr->flags |= mask;
- graphPtr->flags |= (RESET_WORLD | CACHE_DIRTY);
- ConfigureLegend(graphPtr);
- Blt_EventuallyRedrawGraph(graphPtr);
-
- break;
- }
-
- if (!error) {
- Tk_FreeSavedOptions(&savedOptions);
- return TCL_OK;
- }
- else {
- Tcl_SetObjResult(interp, errorResult);
- Tcl_DecrRefCount(errorResult);
- return TCL_ERROR;
- }
-}
-
-static void ConfigureLegend(Graph* graphPtr)
+void ConfigureLegend(Graph* graphPtr)
{
Legend* legendPtr = graphPtr->legend;
@@ -522,384 +411,6 @@ static void ConfigureLegend(Graph* graphPtr)
legendPtr->focusGC = newGC;
}
-// Ops
-
-static int ActivateOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- unsigned int active, redraw;
- const char *string;
- int i;
-
- string = Tcl_GetString(objv[2]);
- active = (string[0] == 'a') ? LABEL_ACTIVE : 0;
- redraw = 0;
- for (i = 3; i < objc; i++) {
- Blt_ChainLink link;
- const char *pattern;
-
- pattern = Tcl_GetString(objv[i]);
- for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_NextLink(link)) {
- Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- if (Tcl_StringMatch(elemPtr->name(), pattern)) {
- fprintf(stderr, "legend %s(%s) %s is currently %d\n",
- string, pattern, elemPtr->name(),
- (elemPtr->flags & LABEL_ACTIVE));
- if (active) {
- if ((elemPtr->flags & LABEL_ACTIVE) == 0) {
- elemPtr->flags |= LABEL_ACTIVE;
- redraw = 1;
- }
- } else {
- if (elemPtr->flags & LABEL_ACTIVE) {
- elemPtr->flags &= ~LABEL_ACTIVE;
- redraw = 1;
- }
- }
- fprintf(stderr, "legend %s(%s) %s is now %d\n",
- string, pattern, elemPtr->name(),
- (elemPtr->flags & LABEL_ACTIVE));
- }
- }
- }
- if ((redraw) && ((legendPtr->hide) == 0)) {
- /*
- * See if how much we need to draw. If the graph is already scheduled
- * for a redraw, just make sure the right flags are set. Otherwise
- * redraw only the legend: it's either in an external window or it's
- * the only thing that need updating.
- */
- if ((legendPtr->site != LEGEND_WINDOW) &&
- (graphPtr->flags & REDRAW_PENDING)) {
- graphPtr->flags |= CACHE_DIRTY;
- graphPtr->flags |= REDRAW_WORLD; /* Redraw entire graph. */
- } else {
- Blt_Legend_EventuallyRedraw(graphPtr);
- }
- }
- {
- Blt_ChainLink link;
- Tcl_Obj *listObjPtr;
-
- listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
- /* List active elements in stacking order. */
- for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_NextLink(link)) {
- Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- if (elemPtr->flags & LABEL_ACTIVE) {
- Tcl_Obj *objPtr;
-
- objPtr = Tcl_NewStringObj(elemPtr->name(), -1);
- Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
- }
- }
- Tcl_SetObjResult(interp, listObjPtr);
- }
- return TCL_OK;
-}
-
-static int BindOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- if (objc == 3) {
- Tcl_HashEntry *hPtr;
- Tcl_HashSearch iter;
- Tcl_Obj *listObjPtr;
-
- listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
- for (hPtr = Tcl_FirstHashEntry(&graphPtr->elements.tagTable, &iter);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&iter)) {
- const char *tagName =
- (const char*)Tcl_GetHashKey(&graphPtr->elements.tagTable, hPtr);
- Tcl_Obj *objPtr = Tcl_NewStringObj(tagName, -1);
- Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
- }
- Tcl_SetObjResult(interp, listObjPtr);
- return TCL_OK;
- }
- return Blt_ConfigureBindingsFromObj(interp, graphPtr->legend->bindTable, Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4);
-}
-
-static int CurselectionOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- Tcl_Obj *listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
- if (legendPtr->flags & SELECT_SORTED) {
- Blt_ChainLink link;
-
- for (link = Blt_Chain_FirstLink(legendPtr->selected); link != NULL;
- link = Blt_Chain_NextLink(link)) {
- Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- Tcl_Obj *objPtr = Tcl_NewStringObj(elemPtr->name(), -1);
- Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
- }
- }
- else {
- /* List of selected entries is in stacking order. */
- for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) {
- Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
-
- if (EntryIsSelected(legendPtr, elemPtr)) {
- Tcl_Obj *objPtr;
-
- objPtr = Tcl_NewStringObj(elemPtr->name(), -1);
- Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
- }
- }
- }
- Tcl_SetObjResult(interp, listObjPtr);
- return TCL_OK;
-}
-
-static int FocusOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
-
- if (objc == 4) {
- Element* elemPtr;
-
- if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if ((elemPtr != NULL) && (elemPtr != legendPtr->focusPtr)) {
- /* Changing focus can only affect the visible entries. The entry
- * layout stays the same. */
- legendPtr->focusPtr = elemPtr;
- }
- Blt_SetFocusItem(legendPtr->bindTable, legendPtr->focusPtr,
- CID_LEGEND_ENTRY);
- Blt_Legend_EventuallyRedraw(graphPtr);
- }
- if (legendPtr->focusPtr) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- legendPtr->focusPtr->name(), -1);
- }
- return TCL_OK;
-}
-
-static int GetOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
-
- if (((legendPtr->hide) == 0) && (legendPtr->nEntries > 0)) {
- Element* elemPtr;
-
- if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if (elemPtr) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->name(),-1);
- }
- }
- return TCL_OK;
-}
-
-static Blt_OpSpec legendOps[] =
- {
- {"activate", 1, (void*)ActivateOp, 3, 0, "?pattern?...",},
- {"bind", 1, (void*)BindOp, 3, 6, "elem sequence command",},
- {"cget", 2, (void*)CgetOp, 4, 4, "option",},
- {"configure", 2, (void*)ConfigureOp, 3, 0, "?option value?...",},
- {"curselection", 2, (void*)CurselectionOp, 3, 3, "",},
- {"deactivate", 1, (void*)ActivateOp, 3, 0, "?pattern?...",},
- {"focus", 1, (void*)FocusOp, 4, 4, "elem",},
- {"get", 1, (void*)GetOp, 4, 4, "elem",},
- {"selection", 1, (void*)SelectionOp, 3, 0, "args"},
- };
-static int nLegendOps = sizeof(legendOps) / sizeof(Blt_OpSpec);
-
-int Blt_LegendOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- GraphLegendProc *proc = (GraphLegendProc*)Blt_GetOpFromObj(interp, nLegendOps, legendOps, BLT_OP_ARG2, objc, objv,0);
- if (proc == NULL)
- return TCL_ERROR;
-
- return (*proc)(graphPtr, interp, objc, objv);
-}
-
-// Selection Widget Ops
-
-static int SelectionAnchorOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- Element* elemPtr;
-
- if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- /* Set both the anchor and the mark. Indicates that a single entry
- * is selected. */
- legendPtr->selAnchorPtr = elemPtr;
- legendPtr->selMarkPtr = NULL;
- if (elemPtr) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->name(), -1);
- }
- Blt_Legend_EventuallyRedraw(graphPtr);
- return TCL_OK;
-}
-
-static int SelectionClearallOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
-
- ClearSelection(legendPtr);
- return TCL_OK;
-}
-
-static int SelectionIncludesOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- Element* elemPtr;
- if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK)
- return TCL_ERROR;
-
- int boo = EntryIsSelected(legendPtr, elemPtr);
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp), boo);
- return TCL_OK;
-}
-
-static int SelectionMarkOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- Element* elemPtr;
-
- if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if (legendPtr->selAnchorPtr == NULL) {
- Tcl_AppendResult(interp, "selection anchor must be set first",
- (char *)NULL);
- return TCL_ERROR;
- }
- if (legendPtr->selMarkPtr != elemPtr) {
- Blt_ChainLink link, next;
-
- /* Deselect entry from the list all the way back to the anchor. */
- for (link = Blt_Chain_LastLink(legendPtr->selected); link != NULL;
- link = next) {
- next = Blt_Chain_PrevLink(link);
- Element *selectPtr = (Element*)Blt_Chain_GetValue(link);
- if (selectPtr == legendPtr->selAnchorPtr) {
- break;
- }
- DeselectElement(legendPtr, selectPtr);
- }
- legendPtr->flags &= ~SELECT_TOGGLE;
- legendPtr->flags |= SELECT_SET;
- SelectRange(legendPtr, legendPtr->selAnchorPtr, elemPtr);
- Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->name(), -1);
- legendPtr->selMarkPtr = elemPtr;
-
- Blt_Legend_EventuallyRedraw(graphPtr);
- if (legendPtr->selectCmd) {
- EventuallyInvokeSelectCmd(legendPtr);
- }
- }
- return TCL_OK;
-}
-
-static int SelectionPresentOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- int boo = (Blt_Chain_GetLength(legendPtr->selected) > 0);
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp), boo);
- return TCL_OK;
-}
-
-static int SelectionSetOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- Legend* legendPtr = graphPtr->legend;
- Element *firstPtr, *lastPtr;
- const char *string;
-
- legendPtr->flags &= ~SELECT_TOGGLE;
- string = Tcl_GetString(objv[3]);
- switch (string[0]) {
- case 's':
- legendPtr->flags |= SELECT_SET;
- break;
- case 'c':
- legendPtr->flags |= SELECT_CLEAR;
- break;
- case 't':
- legendPtr->flags |= SELECT_TOGGLE;
- break;
- }
- if (GetElementFromObj(graphPtr, objv[4], &firstPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if ((firstPtr->hide()) && ((legendPtr->flags & SELECT_CLEAR)==0)) {
- Tcl_AppendResult(interp, "can't select hidden node \"",
- Tcl_GetString(objv[4]), "\"", (char *)NULL);
- return TCL_ERROR;
- }
- lastPtr = firstPtr;
- if (objc > 5) {
- if (GetElementFromObj(graphPtr, objv[5], &lastPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if (lastPtr->hide() && ((legendPtr->flags & SELECT_CLEAR) == 0)) {
- Tcl_AppendResult(interp, "can't select hidden node \"",
- Tcl_GetString(objv[5]), "\"", (char *)NULL);
- return TCL_ERROR;
- }
- }
- if (firstPtr == lastPtr) {
- SelectEntry(legendPtr, firstPtr);
- } else {
- SelectRange(legendPtr, firstPtr, lastPtr);
- }
- /* Set both the anchor and the mark. Indicates that a single entry is
- * selected. */
- if (legendPtr->selAnchorPtr == NULL) {
- legendPtr->selAnchorPtr = firstPtr;
- }
- if (legendPtr->exportSelection) {
- Tk_OwnSelection(legendPtr->tkwin, XA_PRIMARY, LostSelectionProc,
- legendPtr);
- }
- Blt_Legend_EventuallyRedraw(graphPtr);
- if (legendPtr->selectCmd) {
- EventuallyInvokeSelectCmd(legendPtr);
- }
- return TCL_OK;
-}
-
-static Blt_OpSpec selectionOps[] =
- {
- {"anchor", 1, (void*)SelectionAnchorOp, 5, 5, "elem",},
- {"clear", 5, (void*)SelectionSetOp, 5, 6, "firstElem ?lastElem?",},
- {"clearall", 6, (void*)SelectionClearallOp, 4, 4, "",},
- {"includes", 1, (void*)SelectionIncludesOp, 5, 5, "elem",},
- {"mark", 1, (void*)SelectionMarkOp, 5, 5, "elem",},
- {"present", 1, (void*)SelectionPresentOp, 4, 4, "",},
- {"set", 1, (void*)SelectionSetOp, 5, 6, "firstElem ?lastElem?",},
- {"toggle", 1, (void*)SelectionSetOp, 5, 6, "firstElem ?lastElem?",},
- };
-static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec);
-
-static int SelectionOp(Graph* graphPtr, Tcl_Interp* interp,
- int objc, Tcl_Obj* const objv[])
-{
- GraphLegendProc* proc = (GraphLegendProc*)Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG3, objc, objv, 0);
- if (proc == NULL)
- return TCL_ERROR;
-
- return (*proc)(graphPtr, interp, objc, objv);
-}
-
// Support
static void DisplayLegend(ClientData clientData)
@@ -936,50 +447,6 @@ void Blt_Legend_EventuallyRedraw(Graph* graphPtr)
}
}
-static void SelectCmdProc(ClientData clientData)
-{
- Legend* legendPtr = (Legend*)clientData;
-
- Tcl_Preserve(legendPtr);
- legendPtr->flags &= ~SELECT_PENDING;
- if (legendPtr->selectCmd) {
- Tcl_Interp* interp;
-
- interp = legendPtr->graphPtr->interp;
- if (Tcl_GlobalEval(interp, legendPtr->selectCmd) != TCL_OK) {
- Tcl_BackgroundError(interp);
- }
- }
- Tcl_Release(legendPtr);
-}
-
-static void EventuallyInvokeSelectCmd(Legend* legendPtr)
-{
- if ((legendPtr->flags & SELECT_PENDING) == 0) {
- legendPtr->flags |= SELECT_PENDING;
- Tcl_DoWhenIdle(SelectCmdProc, legendPtr);
- }
-}
-
-static void ClearSelection(Legend* legendPtr)
-{
- Tcl_DeleteHashTable(&legendPtr->selectTable);
- Tcl_InitHashTable(&legendPtr->selectTable, TCL_ONE_WORD_KEYS);
- Blt_Chain_Reset(legendPtr->selected);
- Blt_Legend_EventuallyRedraw(legendPtr->graphPtr);
- if (legendPtr->selectCmd) {
- EventuallyInvokeSelectCmd(legendPtr);
- }
-}
-
-static void LostSelectionProc(ClientData clientData)
-{
- Legend* legendPtr = (Legend*)clientData;
-
- if (legendPtr->exportSelection)
- ClearSelection(legendPtr);
-}
-
static int CreateLegendWindow(Tcl_Interp* interp, Legend* legendPtr,
const char *pathName)
{
@@ -1138,7 +605,7 @@ static void SetLegendOrigin(Legend* legendPtr)
legendPtr->y = y + legendPtr->yPad;
}
-static int EntryIsSelected(Legend* legendPtr, Element* elemPtr)
+int EntryIsSelected(Legend* legendPtr, Element* elemPtr)
{
Tcl_HashEntry*hPtr =
Tcl_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr);
@@ -1156,7 +623,7 @@ static void SelectElement(Legend* legendPtr, Element* elemPtr)
}
}
-static void DeselectElement(Legend* legendPtr, Element* elemPtr)
+void DeselectElement(Legend* legendPtr, Element* elemPtr)
{
Tcl_HashEntry* hPtr =
Tcl_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr);
@@ -1167,7 +634,7 @@ static void DeselectElement(Legend* legendPtr, Element* elemPtr)
}
}
-static void SelectEntry(Legend* legendPtr, Element* elemPtr)
+void SelectEntry(Legend* legendPtr, Element* elemPtr)
{
Tcl_HashEntry *hPtr;
@@ -1742,7 +1209,7 @@ static Element *GetLastElement(Graph* graphPtr)
return NULL;
}
-static int GetElementFromObj(Graph* graphPtr, Tcl_Obj *objPtr,
+int GetElementFromObj(Graph* graphPtr, Tcl_Obj *objPtr,
Element **elemPtrPtr)
{
Element* elemPtr;
@@ -1808,7 +1275,7 @@ static int GetElementFromObj(Graph* graphPtr, Tcl_Obj *objPtr,
return TCL_OK;
}
-static int SelectRange(Legend* legendPtr, Element *fromPtr, Element *toPtr)
+int SelectRange(Legend* legendPtr, Element *fromPtr, Element *toPtr)
{
if (Blt_Chain_IsBefore(fromPtr->link, toPtr->link)) {
for (Blt_ChainLink link = fromPtr->link; link != NULL;
diff --git a/src/bltGrLegd.h b/src/bltGrLegd.h
index a0b8bff..d198aff 100644
--- a/src/bltGrLegd.h
+++ b/src/bltGrLegd.h
@@ -52,6 +52,22 @@ extern "C" {
#define LEGEND_MARGIN_MASK (LEGEND_RIGHT|LEGEND_LEFT|LEGEND_BOTTOM|LEGEND_TOP)
#define LEGEND_PLOTAREA_MASK (LEGEND_PLOT | LEGEND_XY)
+// Selection related flags:
+// SELECT_PENDING A "selection" command idle task is pending.
+// SELECT_CLEAR Clear selection flag of entry.
+// SELECT_SET Set selection flag of entry.
+// SELECT_TOGGLE Toggle selection flag of entry.
+// Mask of selection set/clear/toggle flags.
+// SELECT_SORTED Indicates if the entries in the selection
+// should be sorted or displayed in the order
+// they were selected.
+
+#define SELECT_CLEAR (1<<24)
+#define SELECT_PENDING (1<<25)
+#define SELECT_SET (1<<26)
+#define SELECT_SORTED (1<<27)
+#define SELECT_TOGGLE (SELECT_SET | SELECT_CLEAR)
+
typedef enum {
SELECT_MODE_SINGLE, SELECT_MODE_MULTIPLE
} SelectMode;
diff --git a/src/bltGrLegdOp.C b/src/bltGrLegdOp.C
index 5301c06..3c2ea59 100644
--- a/src/bltGrLegdOp.C
+++ b/src/bltGrLegdOp.C
@@ -33,3 +33,530 @@ extern "C" {
};
#include "bltGrLegd.h"
+#include "bltGrElem.h"
+
+extern void SelectEntry(Legend* legendPtr, Element* elemPtr);
+extern void DeselectElement(Legend* legendPtr, Element* elemPtr);
+extern int EntryIsSelected(Legend* legendPtr, Element* elemPtr);
+extern void ConfigureLegend(Graph* graphPtr);
+extern int GetElementFromObj(Graph* graphPtr, Tcl_Obj *objPtr,
+ Element **elemPtrPtr);
+extern int SelectRange(Legend* legendPtr, Element *fromPtr, Element *toPtr);
+
+static void SelectCmdProc(ClientData clientData);
+static void EventuallyInvokeSelectCmd(Legend* legendPtr);
+static int SelectionOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[]);
+static int LegendObjConfigure(Tcl_Interp* interp, Graph* graphPtr,
+ int objc, Tcl_Obj* const objv[]);
+static void ClearSelection(Legend* legendPtr);
+static Tk_LostSelProc LostSelectionProc;
+
+typedef int (GraphLegendProc)(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[]);
+
+
+static int CgetOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "cget option");
+ return TCL_ERROR;
+ }
+
+ Legend* legendPtr = graphPtr->legend;
+ Tcl_Obj* objPtr = Tk_GetOptionValue(interp,
+ (char*)legendPtr,
+ legendPtr->optionTable,
+ objv[3], graphPtr->tkwin);
+ if (objPtr == NULL)
+ return TCL_ERROR;
+ else
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+}
+
+static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ if (objc <= 4) {
+ Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp,
+ (char*)legendPtr,
+ legendPtr->optionTable,
+ (objc == 4) ? objv[3] : NULL,
+ graphPtr->tkwin);
+ if (objPtr == NULL)
+ return TCL_ERROR;
+ else
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+ }
+ else
+ return LegendObjConfigure(interp, graphPtr, objc-3, objv+3);
+}
+
+static int LegendObjConfigure(Tcl_Interp* interp, Graph* graphPtr,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ Tk_SavedOptions savedOptions;
+ int mask =0;
+ int error;
+ Tcl_Obj* errorResult;
+
+ for (error=0; error<=1; error++) {
+ if (!error) {
+ if (Tk_SetOptions(interp, (char*)legendPtr, legendPtr->optionTable,
+ objc, objv, graphPtr->tkwin, &savedOptions, &mask)
+ != TCL_OK)
+ continue;
+ }
+ else {
+ errorResult = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(errorResult);
+ Tk_RestoreSavedOptions(&savedOptions);
+ }
+
+ graphPtr->flags |= mask;
+ graphPtr->flags |= (RESET_WORLD | CACHE_DIRTY);
+ ConfigureLegend(graphPtr);
+ Blt_EventuallyRedrawGraph(graphPtr);
+
+ break;
+ }
+
+ if (!error) {
+ Tk_FreeSavedOptions(&savedOptions);
+ return TCL_OK;
+ }
+ else {
+ Tcl_SetObjResult(interp, errorResult);
+ Tcl_DecrRefCount(errorResult);
+ return TCL_ERROR;
+ }
+}
+
+// Ops
+
+static int ActivateOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ unsigned int active, redraw;
+ const char *string;
+ int i;
+
+ string = Tcl_GetString(objv[2]);
+ active = (string[0] == 'a') ? LABEL_ACTIVE : 0;
+ redraw = 0;
+ for (i = 3; i < objc; i++) {
+ Blt_ChainLink link;
+ const char *pattern;
+
+ pattern = Tcl_GetString(objv[i]);
+ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_NextLink(link)) {
+ Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
+ if (Tcl_StringMatch(elemPtr->name(), pattern)) {
+ fprintf(stderr, "legend %s(%s) %s is currently %d\n",
+ string, pattern, elemPtr->name(),
+ (elemPtr->flags & LABEL_ACTIVE));
+ if (active) {
+ if ((elemPtr->flags & LABEL_ACTIVE) == 0) {
+ elemPtr->flags |= LABEL_ACTIVE;
+ redraw = 1;
+ }
+ } else {
+ if (elemPtr->flags & LABEL_ACTIVE) {
+ elemPtr->flags &= ~LABEL_ACTIVE;
+ redraw = 1;
+ }
+ }
+ fprintf(stderr, "legend %s(%s) %s is now %d\n",
+ string, pattern, elemPtr->name(),
+ (elemPtr->flags & LABEL_ACTIVE));
+ }
+ }
+ }
+ if ((redraw) && ((legendPtr->hide) == 0)) {
+ /*
+ * See if how much we need to draw. If the graph is already scheduled
+ * for a redraw, just make sure the right flags are set. Otherwise
+ * redraw only the legend: it's either in an external window or it's
+ * the only thing that need updating.
+ */
+ if ((legendPtr->site != LEGEND_WINDOW) &&
+ (graphPtr->flags & REDRAW_PENDING)) {
+ graphPtr->flags |= CACHE_DIRTY;
+ graphPtr->flags |= REDRAW_WORLD; /* Redraw entire graph. */
+ } else {
+ Blt_Legend_EventuallyRedraw(graphPtr);
+ }
+ }
+ {
+ Blt_ChainLink link;
+ Tcl_Obj *listObjPtr;
+
+ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+ /* List active elements in stacking order. */
+ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_NextLink(link)) {
+ Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
+ if (elemPtr->flags & LABEL_ACTIVE) {
+ Tcl_Obj *objPtr;
+
+ objPtr = Tcl_NewStringObj(elemPtr->name(), -1);
+ Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+ }
+ }
+ Tcl_SetObjResult(interp, listObjPtr);
+ }
+ return TCL_OK;
+}
+
+static int BindOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ if (objc == 3) {
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch iter;
+ Tcl_Obj *listObjPtr;
+
+ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+ for (hPtr = Tcl_FirstHashEntry(&graphPtr->elements.tagTable, &iter);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&iter)) {
+ const char *tagName =
+ (const char*)Tcl_GetHashKey(&graphPtr->elements.tagTable, hPtr);
+ Tcl_Obj *objPtr = Tcl_NewStringObj(tagName, -1);
+ Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+ }
+ Tcl_SetObjResult(interp, listObjPtr);
+ return TCL_OK;
+ }
+ return Blt_ConfigureBindingsFromObj(interp, graphPtr->legend->bindTable, Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4);
+}
+
+static int CurselectionOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ Tcl_Obj *listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+ if (legendPtr->flags & SELECT_SORTED) {
+ Blt_ChainLink link;
+
+ for (link = Blt_Chain_FirstLink(legendPtr->selected); link != NULL;
+ link = Blt_Chain_NextLink(link)) {
+ Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
+ Tcl_Obj *objPtr = Tcl_NewStringObj(elemPtr->name(), -1);
+ Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+ }
+ }
+ else {
+ /* List of selected entries is in stacking order. */
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) {
+ Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
+
+ if (EntryIsSelected(legendPtr, elemPtr)) {
+ Tcl_Obj *objPtr;
+
+ objPtr = Tcl_NewStringObj(elemPtr->name(), -1);
+ Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+ }
+ }
+ }
+ Tcl_SetObjResult(interp, listObjPtr);
+ return TCL_OK;
+}
+
+static int FocusOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+
+ if (objc == 4) {
+ Element* elemPtr;
+
+ if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((elemPtr != NULL) && (elemPtr != legendPtr->focusPtr)) {
+ /* Changing focus can only affect the visible entries. The entry
+ * layout stays the same. */
+ legendPtr->focusPtr = elemPtr;
+ }
+ Blt_SetFocusItem(legendPtr->bindTable, legendPtr->focusPtr,
+ CID_LEGEND_ENTRY);
+ Blt_Legend_EventuallyRedraw(graphPtr);
+ }
+ if (legendPtr->focusPtr) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ legendPtr->focusPtr->name(), -1);
+ }
+ return TCL_OK;
+}
+
+static int GetOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+
+ if (((legendPtr->hide) == 0) && (legendPtr->nEntries > 0)) {
+ Element* elemPtr;
+
+ if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (elemPtr) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->name(),-1);
+ }
+ }
+ return TCL_OK;
+}
+
+static Blt_OpSpec legendOps[] =
+ {
+ {"activate", 1, (void*)ActivateOp, 3, 0, "?pattern?...",},
+ {"bind", 1, (void*)BindOp, 3, 6, "elem sequence command",},
+ {"cget", 2, (void*)CgetOp, 4, 4, "option",},
+ {"configure", 2, (void*)ConfigureOp, 3, 0, "?option value?...",},
+ {"curselection", 2, (void*)CurselectionOp, 3, 3, "",},
+ {"deactivate", 1, (void*)ActivateOp, 3, 0, "?pattern?...",},
+ {"focus", 1, (void*)FocusOp, 4, 4, "elem",},
+ {"get", 1, (void*)GetOp, 4, 4, "elem",},
+ {"selection", 1, (void*)SelectionOp, 3, 0, "args"},
+ };
+static int nLegendOps = sizeof(legendOps) / sizeof(Blt_OpSpec);
+
+int Blt_LegendOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ GraphLegendProc *proc = (GraphLegendProc*)Blt_GetOpFromObj(interp, nLegendOps, legendOps, BLT_OP_ARG2, objc, objv,0);
+ if (proc == NULL)
+ return TCL_ERROR;
+
+ return (*proc)(graphPtr, interp, objc, objv);
+}
+
+// Selection Widget Ops
+
+static int SelectionAnchorOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ Element* elemPtr;
+
+ if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ /* Set both the anchor and the mark. Indicates that a single entry
+ * is selected. */
+ legendPtr->selAnchorPtr = elemPtr;
+ legendPtr->selMarkPtr = NULL;
+ if (elemPtr) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->name(), -1);
+ }
+ Blt_Legend_EventuallyRedraw(graphPtr);
+ return TCL_OK;
+}
+
+static int SelectionClearallOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+
+ ClearSelection(legendPtr);
+ return TCL_OK;
+}
+
+static int SelectionIncludesOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ Element* elemPtr;
+ if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK)
+ return TCL_ERROR;
+
+ int boo = EntryIsSelected(legendPtr, elemPtr);
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp), boo);
+ return TCL_OK;
+}
+
+static int SelectionMarkOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ Element* elemPtr;
+
+ if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (legendPtr->selAnchorPtr == NULL) {
+ Tcl_AppendResult(interp, "selection anchor must be set first",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+ if (legendPtr->selMarkPtr != elemPtr) {
+ Blt_ChainLink link, next;
+
+ /* Deselect entry from the list all the way back to the anchor. */
+ for (link = Blt_Chain_LastLink(legendPtr->selected); link != NULL;
+ link = next) {
+ next = Blt_Chain_PrevLink(link);
+ Element *selectPtr = (Element*)Blt_Chain_GetValue(link);
+ if (selectPtr == legendPtr->selAnchorPtr) {
+ break;
+ }
+ DeselectElement(legendPtr, selectPtr);
+ }
+ legendPtr->flags &= ~SELECT_TOGGLE;
+ legendPtr->flags |= SELECT_SET;
+ SelectRange(legendPtr, legendPtr->selAnchorPtr, elemPtr);
+ Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->name(), -1);
+ legendPtr->selMarkPtr = elemPtr;
+
+ Blt_Legend_EventuallyRedraw(graphPtr);
+ if (legendPtr->selectCmd) {
+ EventuallyInvokeSelectCmd(legendPtr);
+ }
+ }
+ return TCL_OK;
+}
+
+static int SelectionPresentOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ int boo = (Blt_Chain_GetLength(legendPtr->selected) > 0);
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp), boo);
+ return TCL_OK;
+}
+
+static int SelectionSetOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ Legend* legendPtr = graphPtr->legend;
+ Element *firstPtr, *lastPtr;
+ const char *string;
+
+ legendPtr->flags &= ~SELECT_TOGGLE;
+ string = Tcl_GetString(objv[3]);
+ switch (string[0]) {
+ case 's':
+ legendPtr->flags |= SELECT_SET;
+ break;
+ case 'c':
+ legendPtr->flags |= SELECT_CLEAR;
+ break;
+ case 't':
+ legendPtr->flags |= SELECT_TOGGLE;
+ break;
+ }
+ if (GetElementFromObj(graphPtr, objv[4], &firstPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((firstPtr->hide()) && ((legendPtr->flags & SELECT_CLEAR)==0)) {
+ Tcl_AppendResult(interp, "can't select hidden node \"",
+ Tcl_GetString(objv[4]), "\"", (char *)NULL);
+ return TCL_ERROR;
+ }
+ lastPtr = firstPtr;
+ if (objc > 5) {
+ if (GetElementFromObj(graphPtr, objv[5], &lastPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (lastPtr->hide() && ((legendPtr->flags & SELECT_CLEAR) == 0)) {
+ Tcl_AppendResult(interp, "can't select hidden node \"",
+ Tcl_GetString(objv[5]), "\"", (char *)NULL);
+ return TCL_ERROR;
+ }
+ }
+ if (firstPtr == lastPtr) {
+ SelectEntry(legendPtr, firstPtr);
+ } else {
+ SelectRange(legendPtr, firstPtr, lastPtr);
+ }
+ /* Set both the anchor and the mark. Indicates that a single entry is
+ * selected. */
+ if (legendPtr->selAnchorPtr == NULL) {
+ legendPtr->selAnchorPtr = firstPtr;
+ }
+ if (legendPtr->exportSelection) {
+ Tk_OwnSelection(legendPtr->tkwin, XA_PRIMARY, LostSelectionProc,
+ legendPtr);
+ }
+ Blt_Legend_EventuallyRedraw(graphPtr);
+ if (legendPtr->selectCmd) {
+ EventuallyInvokeSelectCmd(legendPtr);
+ }
+ return TCL_OK;
+}
+
+static Blt_OpSpec selectionOps[] =
+ {
+ {"anchor", 1, (void*)SelectionAnchorOp, 5, 5, "elem",},
+ {"clear", 5, (void*)SelectionSetOp, 5, 6, "firstElem ?lastElem?",},
+ {"clearall", 6, (void*)SelectionClearallOp, 4, 4, "",},
+ {"includes", 1, (void*)SelectionIncludesOp, 5, 5, "elem",},
+ {"mark", 1, (void*)SelectionMarkOp, 5, 5, "elem",},
+ {"present", 1, (void*)SelectionPresentOp, 4, 4, "",},
+ {"set", 1, (void*)SelectionSetOp, 5, 6, "firstElem ?lastElem?",},
+ {"toggle", 1, (void*)SelectionSetOp, 5, 6, "firstElem ?lastElem?",},
+ };
+static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec);
+
+static int SelectionOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[])
+{
+ GraphLegendProc* proc = (GraphLegendProc*)Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG3, objc, objv, 0);
+ if (proc == NULL)
+ return TCL_ERROR;
+
+ return (*proc)(graphPtr, interp, objc, objv);
+}
+
+static void LostSelectionProc(ClientData clientData)
+{
+ Legend* legendPtr = (Legend*)clientData;
+
+ if (legendPtr->exportSelection)
+ ClearSelection(legendPtr);
+}
+
+static void ClearSelection(Legend* legendPtr)
+{
+ Tcl_DeleteHashTable(&legendPtr->selectTable);
+ Tcl_InitHashTable(&legendPtr->selectTable, TCL_ONE_WORD_KEYS);
+ Blt_Chain_Reset(legendPtr->selected);
+ Blt_Legend_EventuallyRedraw(legendPtr->graphPtr);
+ if (legendPtr->selectCmd) {
+ EventuallyInvokeSelectCmd(legendPtr);
+ }
+}
+
+static void EventuallyInvokeSelectCmd(Legend* legendPtr)
+{
+ if ((legendPtr->flags & SELECT_PENDING) == 0) {
+ legendPtr->flags |= SELECT_PENDING;
+ Tcl_DoWhenIdle(SelectCmdProc, legendPtr);
+ }
+}
+
+static void SelectCmdProc(ClientData clientData)
+{
+ Legend* legendPtr = (Legend*)clientData;
+
+ Tcl_Preserve(legendPtr);
+ legendPtr->flags &= ~SELECT_PENDING;
+ if (legendPtr->selectCmd) {
+ Tcl_Interp* interp;
+
+ interp = legendPtr->graphPtr->interp;
+ if (Tcl_GlobalEval(interp, legendPtr->selectCmd) != TCL_OK) {
+ Tcl_BackgroundError(interp);
+ }
+ }
+ Tcl_Release(legendPtr);
+}
+
+
diff --git a/src/bltGraph.C b/src/bltGraph.C
index e685ba2..8dc0977 100644
--- a/src/bltGraph.C
+++ b/src/bltGraph.C
@@ -74,6 +74,8 @@ extern "C" {
Tcl_ObjCmdProc Blt_GraphInstCmdProc;
};
+extern void ConfigureLegend(Graph* graphPtr);
+
static Tcl_IdleProc DisplayGraph;
static Tcl_FreeProc DestroyGraph;
static Tk_EventProc GraphEventProc;
@@ -1295,7 +1297,7 @@ Graph* Blt_GetGraphFromWindowData(Tk_Window tkwin)
void Blt_ReconfigureGraph(Graph* graphPtr)
{
ConfigureGraph(graphPtr);
- // Blt_ConfigureLegend(graphPtr);
+ ConfigureLegend(graphPtr);
// Blt_ConfigureElements(graphPtr);
Blt_ConfigureAxes(graphPtr);
Blt::ConfigureMarkers(graphPtr);