summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorjoye <joye>2014-02-26 21:43:13 (GMT)
committerjoye <joye>2014-02-26 21:43:13 (GMT)
commitd66dafade676741ae8771f74d3fc092789786d90 (patch)
treebc1ec961f11dfc76a532f9dafa46828938bec8c2 /src
parent814edb4094b7989e769c74fd021afda8a875fe3e (diff)
downloadblt-d66dafade676741ae8771f74d3fc092789786d90.zip
blt-d66dafade676741ae8771f74d3fc092789786d90.tar.gz
blt-d66dafade676741ae8771f74d3fc092789786d90.tar.bz2
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/bltGrElemBar.C769
-rw-r--r--src/bltGrElemLine.C4
-rw-r--r--src/bltGrElemOp.C1120
-rw-r--r--src/bltGrPenOp.C422
-rw-r--r--src/bltGraph.C6
-rw-r--r--src/bltGraph.h5
6 files changed, 954 insertions, 1372 deletions
diff --git a/src/bltGrElemBar.C b/src/bltGrElemBar.C
index 52cc694..9735d1c 100644
--- a/src/bltGrElemBar.C
+++ b/src/bltGrElemBar.C
@@ -187,6 +187,39 @@ typedef struct {
int errorBarCapWidth; /* Length of cap on error bars */
} BarElement;
+// Defs
+
+static void InitBarPen(Graph* graphPtr, BarPen* penPtr);
+static void ResetBar(BarElement* elemPtr);
+
+static PenConfigureProc ConfigurePenProc;
+static PenDestroyProc DestroyPenProc;
+static ElementClosestProc ClosestBarProc;
+static ElementConfigProc ConfigureBarProc;
+static ElementDestroyProc DestroyBarProc;
+static ElementDrawProc DrawActiveBarProc;
+static ElementDrawProc DrawNormalBarProc;
+static ElementDrawSymbolProc DrawSymbolProc;
+static ElementExtentsProc GetBarExtentsProc;
+static ElementToPostScriptProc ActiveBarToPostScriptProc;
+static ElementToPostScriptProc NormalBarToPostScriptProc;
+static ElementSymbolToPostScriptProc SymbolToPostScriptProc;
+static ElementMapProc MapBarProc;
+
+static ElementProcs barProcs = {
+ ClosestBarProc,
+ ConfigureBarProc,
+ DestroyBarProc,
+ DrawActiveBarProc,
+ DrawNormalBarProc,
+ DrawSymbolProc,
+ GetBarExtentsProc,
+ ActiveBarToPostScriptProc,
+ NormalBarToPostScriptProc,
+ SymbolToPostScriptProc,
+ MapBarProc,
+};
+
// OptionSpecs
static Tk_ObjCustomOption styleObjOption =
@@ -301,123 +334,6 @@ static Tk_OptionSpec barElemOptionSpecs[] = {
{TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
};
-/*
-static Blt_ConfigSpec barElemConfigSpecs[] = {
- {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen",
- "activeBar", Tk_Offset(BarElement, activePenPtr),
- BLT_CONFIG_NULL_OK, &bltBarPenOption},
- {BLT_CONFIG_BORDER, "-background", "background", "Background",
- "navyblue", Tk_Offset(BarElement, builtinPen.fill),
- BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_DOUBLE, "-barwidth", "barWidth", "BarWidth",
- 0, Tk_Offset(BarElement, barWidth),
- BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL,
- (char *)NULL, 0, 0},
- {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL,
- (char *)NULL, 0, 0},
- {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "all",
- Tk_Offset(BarElement, obj.tags), BLT_CONFIG_NULL_OK,
- &listOption},
- {BLT_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
- STD_BORDERWIDTH, Tk_Offset(BarElement, builtinPen.borderWidth), 0},
- {BLT_CONFIG_SYNONYM, "-color", "background", (char *)NULL,
- (char *)NULL, 0, 0},
- {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor",
- "defcolor",
- Tk_Offset(BarElement, builtinPen.errorBarColor), 0, &bltColorOption},
- {BLT_CONFIG_PIXELS,"-errorbarwidth", "errorBarWidth", "ErrorBarWidth",
- "1",
- Tk_Offset(BarElement, builtinPen.errorBarLineWidth),
- BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap",
- "1",
- Tk_Offset(BarElement, builtinPen.errorBarCapWidth),
- BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0},
- {BLT_CONFIG_CUSTOM, "-data", "data", "Data", (char *)NULL, 0, 0,
- &bltValuePairsOption},
- {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL,
- (char *)NULL, 0, 0},
- {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
- "bblue", Tk_Offset(BarElement, builtinPen.outlineColor),
- BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_STRING, "-label", "label", "Label", (char *)NULL,
- Tk_Offset(BarElement, label), BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_RELIEF, "-legendrelief", "legendRelief", "LegendRelief",
- "flat", Tk_Offset(BarElement, legendRelief),
- BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_CUSTOM, "-hide", "hide", "Hide", "no",
- Tk_Offset(BarElement, flags), BLT_CONFIG_DONT_SET_DEFAULT,
- &bitmaskBarElemHideOption},
- {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x",
- Tk_Offset(BarElement, axes.x), 0, &bltXAxisOption},
- {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y",
- Tk_Offset(BarElement, axes.y), 0, &bltYAxisOption},
- {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL,
- (char *)NULL, 0, 0},
- {BLT_CONFIG_CUSTOM, "-pen", "pen", "Pen", (char *)NULL,
- Tk_Offset(BarElement, normalPenPtr), BLT_CONFIG_NULL_OK,
- &bltBarPenOption},
- {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief",
- "raised", Tk_Offset(BarElement, builtinPen.relief), 0},
- {BLT_CONFIG_CUSTOM, "-showerrorbars", "showErrorBars", "ShowErrorBars",
- "both", Tk_Offset(BarElement, builtinPen.errorBarShow),
- BLT_CONFIG_DONT_SET_DEFAULT, &fillOption},
- {BLT_CONFIG_CUSTOM, "-showvalues", "showValues", "ShowValues",
- "no", Tk_Offset(BarElement, builtinPen.valueShow),
- BLT_CONFIG_DONT_SET_DEFAULT, &fillOption},
- {BLT_CONFIG_STRING, "-stack", "stack", "Stack", NULL,
- Tk_Offset(BarElement, groupName), BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal",
- Tk_Offset(BarElement, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption},
- {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple",
- "", Tk_Offset(BarElement, builtinPen.stipple),
- BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_CUSTOM, "-styles", "styles", "Styles", "",
- Tk_Offset(BarElement, stylePalette), 0, &bltBarStylesOption},
- {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor",
- "s",
- Tk_Offset(BarElement, builtinPen.valueStyle.anchor), 0},
- {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor",
- "black",
- Tk_Offset(BarElement, builtinPen.valueStyle.color), 0},
- {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont",
- STD_FONT_SMALL,
- Tk_Offset(BarElement, builtinPen.valueStyle.font), 0},
- {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat",
- "%g", Tk_Offset(BarElement, builtinPen.valueFormat),
- BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_DOUBLE, "-valuerotate", "valueRotate", "ValueRotate",
- (char *)NULL, Tk_Offset(BarElement, builtinPen.valueStyle.angle), 0},
- {BLT_CONFIG_CUSTOM, "-weights", "weights", "Weights", (char *)NULL,
- Tk_Offset(BarElement, w), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-x", "xdata", "Xdata", (char *)NULL,
- Tk_Offset(BarElement, x), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-y", "ydata", "Ydata", (char *)NULL,
- Tk_Offset(BarElement, y), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-xdata", "xdata", "Xdata", (char *)NULL,
- Tk_Offset(BarElement, x), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-ydata", "ydata", "Ydata", (char *)NULL,
- Tk_Offset(BarElement, y), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-xerror", "xError", "XError", (char *)NULL,
- Tk_Offset(BarElement, xError), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-xhigh", "xHigh", "XHigh", (char *)NULL,
- Tk_Offset(BarElement, xHigh), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-xlow", "xLow", "XLow", (char *)NULL,
- Tk_Offset(BarElement, xLow), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-yerror", "yError", "YError", (char *)NULL,
- Tk_Offset(BarElement, yError), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-yhigh", "yHigh", "YHigh", (char *)NULL,
- Tk_Offset(BarElement, yHigh), 0, &bltValuesOption},
- {BLT_CONFIG_CUSTOM, "-ylow", "yLow", "YLow", (char *)NULL,
- Tk_Offset(BarElement, yLow), 0, &bltValuesOption},
- {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
-};
-*/
-
-//***
-
static Tk_OptionSpec barPenOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
STD_NORMAL_FOREGROUND, -1, Tk_Offset(BarPen, fill), 0, NULL, 0},
@@ -459,102 +375,134 @@ static Tk_OptionSpec barPenOptionSpecs[] = {
{TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
};
-/*
-static Blt_ConfigSpec barPenConfigSpecs[] = {
- {BLT_CONFIG_BORDER, "-background", "background", "Background",
- "rred", Tk_Offset(BarPen, fill),
- BLT_CONFIG_NULL_OK | ACTIVE_PEN},
- {BLT_CONFIG_BORDER, "-background", "background", "Background",
- "navyblue", Tk_Offset(BarPen, fill),
- BLT_CONFIG_NULL_OK | NORMAL_PEN},
- {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL,
- (char *)NULL, 0, ALL_PENS},
- {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL,
- (char *)NULL, 0, ALL_PENS},
- {BLT_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
- STD_BORDERWIDTH, Tk_Offset(BarPen, borderWidth), ALL_PENS},
- {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor",
- "defcolor", Tk_Offset(BarPen, errorBarColor), ALL_PENS,
- &bltColorOption},
- {BLT_CONFIG_PIXELS, "-errorbarwidth", "errorBarWidth","ErrorBarWidth",
- "1", Tk_Offset(BarPen, errorBarLineWidth),
- ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap",
- "1", Tk_Offset(BarPen, errorBarCapWidth),
- ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL,
- (char *)NULL, 0, ALL_PENS},
- {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL,
- (char *)NULL, 0, ALL_PENS},
- {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
- "pink", Tk_Offset(BarPen, outlineColor),
- ACTIVE_PEN | BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
- "bblue", Tk_Offset(BarPen, outlineColor),
- NORMAL_PEN | BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL,
- (char *)NULL, 0, ALL_PENS},
- {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief",
- "raised", Tk_Offset(BarPen, relief), ALL_PENS},
- {BLT_CONFIG_CUSTOM, "-showerrorbars", "showErrorBars", "ShowErrorBars",
- "both", Tk_Offset(BarPen, errorBarShow),
- BLT_CONFIG_DONT_SET_DEFAULT, &fillOption},
- {BLT_CONFIG_CUSTOM, "-showvalues", "showValues", "ShowValues",
- "no", Tk_Offset(BarPen, valueShow),
- ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT, &fillOption},
- {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", "",
- Tk_Offset(BarPen, stipple), ALL_PENS | BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_STRING, "-type", (char *)NULL, (char *)NULL, "bar",
- Tk_Offset(BarPen, typeId), ALL_PENS | BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor",
- "s", Tk_Offset(BarPen, valueStyle.anchor),
- ALL_PENS},
- {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor",
- "black", Tk_Offset(BarPen, valueStyle.color),
- ALL_PENS},
- {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont",
- STD_FONT_SMALL, Tk_Offset(BarPen, valueStyle.font),
- ALL_PENS},
- {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat",
- "%g", Tk_Offset(BarPen, valueFormat),
- ALL_PENS | BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_DOUBLE, "-valuerotate", "valueRotate", "ValueRotate",
- (char *)NULL, Tk_Offset(BarPen, valueStyle.angle), ALL_PENS},
- {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
-};
-*/
+// Create
-/* Forward declarations */
-static PenConfigureProc ConfigureBarPenProc;
-static PenDestroyProc DestroyBarPenProc;
-static ElementClosestProc ClosestBarProc;
-static ElementConfigProc ConfigureBarProc;
-static ElementDestroyProc DestroyBarProc;
-static ElementDrawProc DrawActiveBarProc;
-static ElementDrawProc DrawNormalBarProc;
-static ElementDrawSymbolProc DrawSymbolProc;
-static ElementExtentsProc GetBarExtentsProc;
-static ElementToPostScriptProc ActiveBarToPostScriptProc;
-static ElementToPostScriptProc NormalBarToPostScriptProc;
-static ElementSymbolToPostScriptProc SymbolToPostScriptProc;
-static ElementMapProc MapBarProc;
+Element* Blt_BarElement(Graph* graphPtr, const char* name, ClassId classId)
+{
+ BarElement *elemPtr = calloc(1, sizeof(BarElement));
+ elemPtr->procsPtr = &barProcs;
+ elemPtr->legendRelief = TK_RELIEF_FLAT;
+ Blt_GraphSetObjectClass(&elemPtr->obj, classId);
+ elemPtr->obj.name = Blt_Strdup(name);
+ elemPtr->obj.graphPtr = graphPtr;
+ /* By default, an element's name and label are the same. */
+ elemPtr->label = Blt_Strdup(name);
+ elemPtr->builtinPenPtr = &elemPtr->builtinPen;
+ InitBarPen(graphPtr, elemPtr->builtinPenPtr);
+ elemPtr->stylePalette = Blt_Chain_Create();
-static void ResetStylePalette(Blt_Chain stylePalette)
+ elemPtr->optionTable =
+ Tk_CreateOptionTable(graphPtr->interp, barElemOptionSpecs);
+ Tk_InitOptions(graphPtr->interp, (char*)elemPtr, elemPtr->optionTable,
+ graphPtr->tkwin);
+
+ return (Element *)elemPtr;
+}
+
+Pen* Blt_BarPen(Graph* graphPtr, const char *penName)
+{
+ BarPen* penPtr = calloc(1, sizeof(BarPen));
+ InitBarPen(graphPtr, penPtr);
+ penPtr->name = Blt_Strdup(penName);
+ if (strcmp(penName, "activeBar") == 0)
+ penPtr->flags = ACTIVE_PEN;
+
+ return (Pen*)penPtr;
+}
+
+static void InitBarPen(Graph* graphPtr, BarPen* penPtr)
{
+ /* Generic fields common to all pen types. */
+ penPtr->configProc = ConfigurePenProc;
+ penPtr->destroyProc = DestroyPenProc;
+ penPtr->flags = NORMAL_PEN;
+ /* Initialize fields specific to bar pens. */
+ Blt_Ts_InitStyle(penPtr->valueStyle);
+ penPtr->relief = TK_RELIEF_RAISED;
+ penPtr->valueShow = SHOW_NONE;
+ penPtr->borderWidth = 2;
+ penPtr->errorBarShow = SHOW_BOTH;
+
+ penPtr->optionTable =
+ Tk_CreateOptionTable(graphPtr->interp, barPenOptionSpecs);
+ Tk_InitOptions(graphPtr->interp, (char*)penPtr, penPtr->optionTable,
+ graphPtr->tkwin);
+}
+
+static void DestroyBarProc(Graph* graphPtr, Element* basePtr)
+{
+ BarElement* elemPtr = (BarElement*)basePtr;
+ Tk_FreeConfigOptions((char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin);
+ Tk_DeleteOptionTable(elemPtr->optionTable);
+
+ DestroyPenProc(graphPtr, (Pen*)&elemPtr->builtinPen);
+ if (elemPtr->activePenPtr != NULL)
+ Blt_FreePen((Pen *)elemPtr->activePenPtr);
+ if (elemPtr->normalPenPtr != NULL)
+ Blt_FreePen((Pen *)elemPtr->normalPenPtr);
+
+ ResetBar(elemPtr);
+ if (elemPtr->stylePalette != NULL) {
+ Blt_FreeStylePalette(elemPtr->stylePalette);
+ Blt_Chain_Destroy(elemPtr->stylePalette);
+ }
+ if (elemPtr->activeIndices != NULL) {
+ free(elemPtr->activeIndices);
+ }
+}
+
+static void DestroyPenProc(Graph* graphPtr, Pen* basePtr)
+{
+ BarPen* penPtr = (BarPen*)basePtr;
+ Tk_FreeConfigOptions((char*)penPtr, penPtr->optionTable, graphPtr->tkwin);
+ Tk_DeleteOptionTable(penPtr->optionTable);
+
+ Blt_Ts_FreeStyle(graphPtr->display, &penPtr->valueStyle);
+ if (penPtr->outlineGC != NULL) {
+ Tk_FreeGC(graphPtr->display, penPtr->outlineGC);
+ }
+ if (penPtr->fillGC != NULL) {
+ Tk_FreeGC(graphPtr->display, penPtr->fillGC);
+ }
+ if (penPtr->errorBarGC != NULL) {
+ Tk_FreeGC(graphPtr->display, penPtr->errorBarGC);
+ }
+}
+
+// Configure
+
+static int ConfigureBarProc(Graph *graphPtr, Element *basePtr)
+{
+ BarElement *elemPtr = (BarElement *)basePtr;
Blt_ChainLink link;
+ BarStyle *stylePtr;
- for (link = Blt_Chain_FirstLink(stylePalette); link != NULL;
- link = Blt_Chain_NextLink(link)) {
- BarStyle *stylePtr;
+ if (ConfigurePenProc(graphPtr, (Pen*)&elemPtr->builtinPen)!= TCL_OK) {
+ return TCL_ERROR;
+ }
+ /*
+ * Point to the static normal pen if no external pens have been selected.
+ */
+ link = Blt_Chain_FirstLink(elemPtr->stylePalette);
+ if (link == NULL) {
+ link = Blt_Chain_AllocLink(sizeof(BarStyle));
+ Blt_Chain_LinkAfter(elemPtr->stylePalette, link, NULL);
+ }
+ stylePtr = Blt_Chain_GetValue(link);
+ stylePtr->penPtr = NORMALPEN(elemPtr);
- stylePtr = Blt_Chain_GetValue(link);
- stylePtr->xeb.length = stylePtr->yeb.length = 0;
- stylePtr->nBars = 0;
+ /*
+ if (Blt_ConfigModified(elemPtr->configSpecs, "-barwidth", "-*data",
+ "-map*", "-label", "-hide", "-x", "-y", (char *)NULL)) {
+ elemPtr->flags |= MAP_ITEM;
}
+ */
+ return TCL_OK;
}
-static int ConfigureBarPen(Graph *graphPtr, BarPen *penPtr)
+static int ConfigurePenProc(Graph *graphPtr, Pen *basePtr)
{
+ BarPen* penPtr = (BarPen*)basePtr;
XGCValues gcValues;
unsigned long gcMask;
GC newGC;
@@ -614,87 +562,30 @@ static int ConfigureBarPen(Graph *graphPtr, BarPen *penPtr)
return TCL_OK;
}
-static void DestroyBarPen(Graph* graphPtr, BarPen* penPtr)
-{
- Tk_FreeConfigOptions((char*)penPtr, penPtr->optionTable, graphPtr->tkwin);
- Tk_DeleteOptionTable(penPtr->optionTable);
+// Support
- Blt_Ts_FreeStyle(graphPtr->display, &penPtr->valueStyle);
- if (penPtr->outlineGC != NULL) {
- Tk_FreeGC(graphPtr->display, penPtr->outlineGC);
- }
- if (penPtr->fillGC != NULL) {
- Tk_FreeGC(graphPtr->display, penPtr->fillGC);
- }
- if (penPtr->errorBarGC != NULL) {
- Tk_FreeGC(graphPtr->display, penPtr->errorBarGC);
- }
-}
-
-static int ConfigureBarPenProc(Graph *graphPtr, Pen *basePtr)
-{
- return ConfigureBarPen(graphPtr, (BarPen *)basePtr);
-}
-
-static void DestroyBarPenProc(Graph *graphPtr, Pen *basePtr)
-{
- DestroyBarPen(graphPtr, (BarPen *)basePtr);
-}
-
-static void InitBarPen(Graph* graphPtr, BarPen* penPtr)
+static void ResetStylePalette(Blt_Chain stylePalette)
{
- /* Generic fields common to all pen types. */
- penPtr->configProc = ConfigureBarPenProc;
- penPtr->destroyProc = DestroyBarPenProc;
- penPtr->flags = NORMAL_PEN;
- penPtr->optionTable =
- Tk_CreateOptionTable(graphPtr->interp, barPenOptionSpecs);
+ Blt_ChainLink link;
- /* Initialize fields specific to bar pens. */
- Blt_Ts_InitStyle(penPtr->valueStyle);
- penPtr->relief = TK_RELIEF_RAISED;
- penPtr->valueShow = SHOW_NONE;
- penPtr->borderWidth = 2;
- penPtr->errorBarShow = SHOW_BOTH;
-}
+ for (link = Blt_Chain_FirstLink(stylePalette); link != NULL;
+ link = Blt_Chain_NextLink(link)) {
+ BarStyle *stylePtr;
-Pen* Blt_BarPen(Graph* graphPtr, const char *penName)
-{
- BarPen *penPtr = calloc(1, sizeof(BarPen));
- InitBarPen(graphPtr, penPtr);
- penPtr->name = Blt_Strdup(penName);
- if (strcmp(penName, "activeBar") == 0) {
- penPtr->flags = ACTIVE_PEN;
+ stylePtr = Blt_Chain_GetValue(link);
+ stylePtr->xeb.length = stylePtr->yeb.length = 0;
+ stylePtr->nBars = 0;
}
- return (Pen *)penPtr;
}
-/*
- *---------------------------------------------------------------------------
- *
- * CheckBarStacks --
- *
- * Check that the data limits are not superseded by the heights of
- * stacked bar segments. The heights are calculated by
- * Blt_ComputeStacks.
- *
- * Results:
- * If the y-axis limits need to be adjusted for stacked segments,
- * *minPtr* or *maxPtr* are updated.
- *
- * Side effects:
- * Autoscaling of the y-axis is affected.
- *
- *---------------------------------------------------------------------------
- */
static void CheckBarStacks(Graph *graphPtr, Axis2d *pairPtr,
double *minPtr, double *maxPtr)
{
BarGroup *gp, *gend;
- if ((graphPtr->mode != BARS_STACKED) || (graphPtr->nBarGroups == 0)) {
+ if ((graphPtr->mode != BARS_STACKED) || (graphPtr->nBarGroups == 0))
return;
- }
+
for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; gp < gend;
gp++) {
if ((gp->axes.x == pairPtr->x) && (gp->axes.y == pairPtr->y)) {
@@ -715,55 +606,6 @@ static void CheckBarStacks(Graph *graphPtr, Axis2d *pairPtr,
}
}
-/*
- *---------------------------------------------------------------------------
- *
- * ConfigureBarProc --
- *
- * Sets up the appropriate configuration parameters in the GC. It is
- * assumed the parameters have been previously set by a call to
- * Blt_ConfigureWidget.
- *
- * Results:
- * The return value is a standard TCL result. If TCL_ERROR is returned,
- * then interp->result contains an error message.
- *
- * Side effects:
- * Configuration information such as bar foreground/background color and
- * stipple etc. get set in a new GC.
- *
- *---------------------------------------------------------------------------
- */
-
-static int ConfigureBarProc(Graph *graphPtr, Element *basePtr)
-{
- BarElement *elemPtr = (BarElement *)basePtr;
- Blt_ChainLink link;
- BarStyle *stylePtr;
-
- if (ConfigureBarPen(graphPtr, elemPtr->builtinPenPtr)!= TCL_OK) {
- return TCL_ERROR;
- }
- /*
- * Point to the static normal pen if no external pens have been selected.
- */
- link = Blt_Chain_FirstLink(elemPtr->stylePalette);
- if (link == NULL) {
- link = Blt_Chain_AllocLink(sizeof(BarStyle));
- Blt_Chain_LinkAfter(elemPtr->stylePalette, link, NULL);
- }
- stylePtr = Blt_Chain_GetValue(link);
- stylePtr->penPtr = NORMALPEN(elemPtr);
-
- /*
- if (Blt_ConfigModified(elemPtr->configSpecs, "-barwidth", "-*data",
- "-map*", "-label", "-hide", "-x", "-y", (char *)NULL)) {
- elemPtr->flags |= MAP_ITEM;
- }
- */
- return TCL_OK;
-}
-
static void GetBarExtentsProc(Element *basePtr, Region2d *regPtr)
{
BarElement *elemPtr = (BarElement *)basePtr;
@@ -906,28 +748,8 @@ static void GetBarExtentsProc(Element *basePtr, Region2d *regPtr)
}
}
-/*
- *---------------------------------------------------------------------------
- *
- * ClosestBar --
- *
- * Find the bar segment closest to the window coordinates point
- * specified.
- *
- * Note: This does not return the height of the stacked segment
- * (in graph coordinates) properly.
- *
- * Results:
- * Returns 1 if the point is width any bar segment, otherwise 0.
- *
- *---------------------------------------------------------------------------
- */
-
-static void ClosestBarProc(
- Graph *graphPtr, /* Not used. */
- Element *basePtr, /* Bar element */
- ClosestSearch *searchPtr) /* Information about closest point in
- * element */
+static void ClosestBarProc(Graph *graphPtr, Element *basePtr,
+ ClosestSearch *searchPtr)
{
BarElement *elemPtr = (BarElement *)basePtr;
XRectangle *bp;
@@ -987,23 +809,6 @@ static void ClosestBarProc(
}
}
-/*
- *---------------------------------------------------------------------------
- *
- * MergePens --
- *
- * Reorders the both arrays of points and errorbars to merge pens.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The old arrays are freed and new ones allocated containing
- * the reordered points and errorbars.
- *
- *---------------------------------------------------------------------------
- */
-
static void MergePens(BarElement *elemPtr, BarStyle **dataToStyle)
{
if (Blt_Chain_GetLength(elemPtr->stylePalette) < 2) {
@@ -1122,22 +927,6 @@ static void MergePens(BarElement *elemPtr, BarStyle **dataToStyle)
}
}
-/*
- *---------------------------------------------------------------------------
- *
- * MapActiveBars --
- *
- * Creates an array of points of the active graph coordinates.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Memory is freed and allocated for the active point array.
- *
- *---------------------------------------------------------------------------
- */
-
static void MapActiveBars(BarElement *elemPtr)
{
if (elemPtr->activeRects != NULL) {
@@ -1216,22 +1005,6 @@ static void ResetBar(BarElement *elemPtr)
elemPtr->nBars = 0;
}
-/*
- *---------------------------------------------------------------------------
- *
- * Blt_MapErrorBars --
- *
- * Creates two arrays of points and pen indices, filled with the screen
- * coordinates of the visible
- *
- * Results:
- * None.
- *
- * Side effects:
- * Memory is freed and allocated for the index array.
- *
- *---------------------------------------------------------------------------
- */
static void MapErrorBars(Graph *graphPtr, BarElement *elemPtr,
BarStyle **dataToStyle)
{
@@ -1370,30 +1143,6 @@ static void MapErrorBars(Graph *graphPtr, BarElement *elemPtr,
}
}
-
-/*
- *---------------------------------------------------------------------------
- *
- * MapBarProc --
- *
- * Calculates the actual window coordinates of the bar element. The
- * window coordinates are saved in the bar element structure.
- *
- * Results:
- * None.
- *
- * Notes:
- * A bar can have multiple segments (more than one x,y pairs). In this
- * case, the bar can be represented as either a set of non-contiguous
- * bars or a single multi-segmented (stacked) bar.
- *
- * The x-axis layout for a barchart may be presented in one of two ways.
- * If abscissas are used, the bars are placed at those coordinates.
- * Otherwise, the range will represent the number of values.
- *
- *---------------------------------------------------------------------------
- */
-
static void MapBarProc(Graph *graphPtr, Element *basePtr)
{
BarElement *elemPtr = (BarElement *)basePtr;
@@ -1627,23 +1376,6 @@ static void MapBarProc(Graph *graphPtr, Element *basePtr)
free(dataToStyle);
}
-/*
- *---------------------------------------------------------------------------
- *
- * DrawSymbolProc --
- *
- * Draw a symbol centered at the given x,y window coordinate based upon
- * the element symbol type and size.
- *
- * Results:
- * None.
- *
- * Problems:
- * Most notable is the round-off errors generated when calculating the
- * centered position of the symbol.
- *---------------------------------------------------------------------------
- */
-
static void DrawSymbolProc(Graph *graphPtr, Drawable drawable,
Element *basePtr, int x, int y, int size)
{
@@ -1706,19 +1438,6 @@ static void UnsetBackgroundClipRegion(Tk_Window tkwin, Tk_3DBorder border)
XSetClipMask(display, gc, None);
}
-/*
- *---------------------------------------------------------------------------
- *
- * DrawBarSegments --
- *
- * Draws each of the rectangular segments for the element.
- *
- * Results:
- * None.
- *
- *---------------------------------------------------------------------------
- */
-
static void DrawBarSegments(Graph *graphPtr, Drawable drawable, BarPen *penPtr,
XRectangle *bars, int nBars)
{
@@ -1779,18 +1498,6 @@ static void DrawBarSegments(Graph *graphPtr, Drawable drawable, BarPen *penPtr,
TkDestroyRegion(rgn);
}
-/*
- *---------------------------------------------------------------------------
- *
- * DrawBarValues --
- *
- * Draws the numeric value of the bar.
- *
- * Results:
- * None.
- *
- *---------------------------------------------------------------------------
- */
static void DrawBarValues(Graph *graphPtr, Drawable drawable,
BarElement *elemPtr,
BarPen *penPtr, XRectangle *bars, int nBars,
@@ -1841,28 +1548,6 @@ static void DrawBarValues(Graph *graphPtr, Drawable drawable,
}
}
-
-/*
- *---------------------------------------------------------------------------
- *
- * DrawNormalBar --
- *
- * Draws the rectangle representing the bar element. If the relief
- * option is set to "raised" or "sunken" and the bar borderwidth is set
- * (borderwidth > 0), a 3D border is drawn around the bar.
- *
- * Don't draw bars that aren't visible (i.e. within the limits of the
- * axis).
- *
- * Results:
- * None.
- *
- * Side effects:
- * X drawing commands are output.
- *
- *---------------------------------------------------------------------------
- */
-
static void DrawNormalBarProc(Graph *graphPtr, Drawable drawable,
Element *basePtr)
{
@@ -1899,24 +1584,6 @@ static void DrawNormalBarProc(Graph *graphPtr, Drawable drawable,
}
}
-/*
- *---------------------------------------------------------------------------
- *
- * DrawActiveBar --
- *
- * Draws bars representing the active segments of the bar element. If
- * the -relief option is set (other than "flat") and the borderwidth is
- * greater than 0, a 3D border is drawn around the each bar segment.
- *
- * Results:
- * None.
- *
- * Side effects:
- * X drawing commands are output.
- *
- *---------------------------------------------------------------------------
- */
-
static void DrawActiveBarProc(Graph *graphPtr, Drawable drawable,
Element *basePtr)
{
@@ -1947,30 +1614,8 @@ static void DrawActiveBarProc(Graph *graphPtr, Drawable drawable,
}
}
-/*
- *---------------------------------------------------------------------------
- *
- * SymbolToPostScript --
- *
- * Draw a symbol centered at the given x,y window coordinate based upon
- * the element symbol type and size.
- *
- * Results:
- * None.
- *
- * Problems:
- * Most notable is the round-off errors generated when calculating the
- * centered position of the symbol.
- *
- *---------------------------------------------------------------------------
- */
-
-static void SymbolToPostScriptProc(
- Graph *graphPtr,
- Blt_Ps ps,
- Element *basePtr,
- double x, double y,
- int size)
+static void SymbolToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr,
+ double x, double y, int size)
{
BarElement *elemPtr = (BarElement *)basePtr;
BarPen *penPtr;
@@ -2006,9 +1651,8 @@ static void SymbolToPostScriptProc(
Blt_Ps_Format(ps, "%g %g %d Sq\n", x, y, size);
}
-static void
-SegmentsToPostScript(Graph *graphPtr, Blt_Ps ps, BarPen *penPtr,
- XRectangle *bars, int nBars)
+static void SegmentsToPostScript(Graph *graphPtr, Blt_Ps ps, BarPen *penPtr,
+ XRectangle *bars, int nBars)
{
XRectangle *rp, *rend;
@@ -2038,8 +1682,8 @@ SegmentsToPostScript(Graph *graphPtr, Blt_Ps ps, BarPen *penPtr,
}
if ((penPtr->fill != NULL) && (penPtr->borderWidth > 0) &&
(penPtr->relief != TK_RELIEF_FLAT)) {
- Blt_Ps_Draw3DRectangle(ps, penPtr->fill,
- (double)rp->x, (double)rp->y, (int)rp->width, (int)rp->height,
+ Blt_Ps_Draw3DRectangle(ps, penPtr->fill, (double)rp->x, (double)rp->y,
+ (int)rp->width, (int)rp->height,
penPtr->borderWidth, penPtr->relief);
}
}
@@ -2093,24 +1737,6 @@ static void BarValuesToPostScript(Graph *graphPtr, Blt_Ps ps,
}
}
-/*
- *---------------------------------------------------------------------------
- *
- * ActiveBarToPostScript --
- *
- * Similar to the NormalBarToPostScript procedure, generates PostScript
- * commands to display the bars representing the active bar segments of
- * the element.
- *
- * Results:
- * None.
- *
- * Side effects:
- * PostScript pen width, dashes, and color settings are changed.
- *
- *---------------------------------------------------------------------------
- */
-
static void ActiveBarToPostScriptProc(Graph *graphPtr, Blt_Ps ps,
Element *basePtr)
{
@@ -2185,61 +1811,6 @@ static void NormalBarToPostScriptProc(Graph *graphPtr, Blt_Ps ps,
}
}
-static void DestroyBarProc(Graph* graphPtr, Element* basePtr)
-{
- BarElement* elemPtr = (BarElement*)basePtr;
- Tk_FreeConfigOptions((char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin);
- Tk_DeleteOptionTable(elemPtr->optionTable);
-
- DestroyBarPen(graphPtr, elemPtr->builtinPenPtr);
- if (elemPtr->activePenPtr != NULL)
- Blt_FreePen((Pen *)elemPtr->activePenPtr);
- if (elemPtr->normalPenPtr != NULL)
- Blt_FreePen((Pen *)elemPtr->normalPenPtr);
-
- ResetBar(elemPtr);
- if (elemPtr->stylePalette != NULL) {
- Blt_FreeStylePalette(elemPtr->stylePalette);
- Blt_Chain_Destroy(elemPtr->stylePalette);
- }
- if (elemPtr->activeIndices != NULL) {
- free(elemPtr->activeIndices);
- }
-}
-
-static ElementProcs barProcs = {
- ClosestBarProc,
- ConfigureBarProc,
- DestroyBarProc,
- DrawActiveBarProc,
- DrawNormalBarProc,
- DrawSymbolProc,
- GetBarExtentsProc,
- ActiveBarToPostScriptProc,
- NormalBarToPostScriptProc,
- SymbolToPostScriptProc,
- MapBarProc,
-};
-
-Element* Blt_BarElement(Graph* graphPtr, const char* name, ClassId classId)
-{
- BarElement *elemPtr = calloc(1, sizeof(BarElement));
- elemPtr->procsPtr = &barProcs;
- elemPtr->optionTable =
- Tk_CreateOptionTable(graphPtr->interp, barElemOptionSpecs);
- elemPtr->legendRelief = TK_RELIEF_FLAT;
- Blt_GraphSetObjectClass(&elemPtr->obj, classId);
- elemPtr->obj.name = Blt_Strdup(name);
- elemPtr->obj.graphPtr = graphPtr;
- /* By default, an element's name and label are the same. */
- elemPtr->label = Blt_Strdup(name);
- elemPtr->builtinPenPtr = &elemPtr->builtinPen;
- InitBarPen(graphPtr, elemPtr->builtinPenPtr);
- elemPtr->stylePalette = Blt_Chain_Create();
-
- return (Element *)elemPtr;
-}
-
void Blt_InitBarSetTable(Graph *graphPtr)
{
Blt_ChainLink link;
diff --git a/src/bltGrElemLine.C b/src/bltGrElemLine.C
index 50b47d2..4032f37 100644
--- a/src/bltGrElemLine.C
+++ b/src/bltGrElemLine.C
@@ -832,9 +832,9 @@ static int ConfigureLineProc(Graph *graphPtr, Element *basePtr)
return TCL_OK;
}
-static int ConfigurePenProc(Graph* graphPtr, Pen* penPtr)
+static int ConfigurePenProc(Graph* graphPtr, Pen* basePtr)
{
- LinePen* lpPtr = (LinePen*)penPtr;
+ LinePen* lpPtr = (LinePen*)basePtr;
unsigned long gcMask;
GC newGC;
XGCValues gcValues;
diff --git a/src/bltGrElemOp.C b/src/bltGrElemOp.C
index 5e954ad..73bad98 100644
--- a/src/bltGrElemOp.C
+++ b/src/bltGrElemOp.C
@@ -45,28 +45,31 @@
/* Ignore elements that aren't in the display list or have been deleted. */
#define IGNORE_ELEMENT(e) (((e)->link == NULL) || ((e)->flags & DELETE_PENDING))
-static int ParseValues(Tcl_Interp *interp, Tcl_Obj *objPtr, int *nValuesPtr,
- double **arrayPtr);
+// Defs
+
+static void DestroyElement(Element *elemPtr);
+static int ElementObjConfigure(Tcl_Interp *interp, Graph* graphPtr,
+ Element* elemPtr,
+ int objc, Tcl_Obj* const objv[]);
static void FreeDataValues(ElemValues *valuesPtr);
+static void FreeElement(char* data);
static void FindRange(ElemValues *valuesPtr);
+static int GetIndex(Tcl_Interp *interp, Element *elemPtr,
+ Tcl_Obj *objPtr, int *indexPtr);
static int GetPenStyleFromObj(Tcl_Interp *interp, Graph *graphPtr,
Tcl_Obj *objPtr, ClassId classId,
PenStyle *stylePtr);
static int GetVectorData(Tcl_Interp *interp, ElemValues *valuesPtr,
const char *vecName);
-static void DestroyElement(Element *elemPtr);
-static int ElementObjConfigure(Tcl_Interp *interp, Graph* graphPtr,
- Element* elemPtr,
- int objc, Tcl_Obj* const objv[]);
+static int ParseValues(Tcl_Interp *interp, Tcl_Obj *objPtr, int *nValuesPtr,
+ double **arrayPtr);
typedef int (GraphElementProc)(Graph *graphPtr, Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
// OptionSpecs
-// Fill
char* fillObjOption[] = {"none", "x", "y", "both", NULL};
-// Values
static Tk_CustomOptionSetProc ValuesSetProc;
static Tk_CustomOptionGetProc ValuesGetProc;
Tk_ObjCustomOption valuesObjOption =
@@ -146,7 +149,6 @@ static Tcl_Obj* ValuesGetProc(ClientData clientData, Tk_Window tkwin,
}
}
-// Pairs
static Tk_CustomOptionSetProc PairsSetProc;
static Tk_CustomOptionGetProc PairsGetProc;
Tk_ObjCustomOption pairsObjOption =
@@ -212,7 +214,6 @@ static Tcl_Obj* PairsGetProc(ClientData clientData, Tk_Window tkwin,
return listObjPtr;
};
-// Style
int StyleSetProc(ClientData clientData, Tcl_Interp *interp,
Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
int offset, char* save, int flags)
@@ -281,31 +282,29 @@ Tcl_Obj* StyleGetProc(ClientData clientData, Tk_Window tkwin,
return listObjPtr;
}
-// Configure
-
-static Blt_VectorChangedProc VectorChangedProc;
+// Create
static int CreateElement(Graph *graphPtr, Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv, ClassId classId)
{
- Element *elemPtr;
- Tcl_HashEntry *hPtr;
- int isNew;
- char *string;
-
- string = Tcl_GetString(objv[3]);
+ char *string = Tcl_GetString(objv[3]);
if (string[0] == '-') {
Tcl_AppendResult(graphPtr->interp, "name of element \"", string,
"\" can't start with a '-'", (char *)NULL);
return TCL_ERROR;
}
- hPtr = Tcl_CreateHashEntry(&graphPtr->elements.table, string, &isNew);
+
+ int isNew;
+ Tcl_HashEntry* hPtr =
+ Tcl_CreateHashEntry(&graphPtr->elements.table, string, &isNew);
if (!isNew) {
Tcl_AppendResult(interp, "element \"", string,
"\" already exists in \"", Tcl_GetString(objv[0]),
"\"", (char *)NULL);
return TCL_ERROR;
}
+
+ Element *elemPtr;
switch (classId) {
case CID_ELEM_BAR:
elemPtr = Blt_BarElement(graphPtr, string, classId);
@@ -319,23 +318,59 @@ static int CreateElement(Graph *graphPtr, Tcl_Interp *interp, int objc,
if (!elemPtr)
return TCL_ERROR;
- elemPtr->hashPtr = hPtr;
- Tcl_SetHashValue(hPtr, elemPtr);
-
- if ((Tk_InitOptions(graphPtr->interp, (char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4) != TCL_OK)) {
+ if (ElementObjConfigure(interp,graphPtr, elemPtr, objc-4, objv+4) != TCL_OK) {
DestroyElement(elemPtr);
return TCL_ERROR;
}
+ elemPtr->hashPtr = hPtr;
+ Tcl_SetHashValue(hPtr, elemPtr);
+
elemPtr->link = Blt_Chain_Append(graphPtr->elements.displayList, elemPtr);
- graphPtr->flags |= CACHE_DIRTY;
- Blt_EventuallyRedrawGraph(graphPtr);
elemPtr->flags |= MAP_ITEM;
+ graphPtr->flags |= CACHE_DIRTY;
graphPtr->flags |= RESET_AXES;
+ Blt_EventuallyRedrawGraph(graphPtr);
+
Tcl_SetObjResult(interp, objv[3]);
return TCL_OK;
}
+static void DestroyElement(Element *elemPtr)
+{
+ Graph *graphPtr = elemPtr->obj.graphPtr;
+
+ Blt_DeleteBindings(graphPtr->bindTable, elemPtr);
+ Blt_Legend_RemoveElement(graphPtr, elemPtr);
+
+ FreeDataValues(&elemPtr->x);
+ FreeDataValues(&elemPtr->y);
+
+ (*elemPtr->procsPtr->destroyProc) (graphPtr, elemPtr);
+
+ /* Remove it also from the element display list */
+ if (elemPtr->link) {
+ Blt_Chain_DeleteLink(graphPtr->elements.displayList, elemPtr->link);
+ if (!IGNORE_ELEMENT(elemPtr)) {
+ graphPtr->flags |= RESET_WORLD;
+ Blt_EventuallyRedrawGraph(graphPtr);
+ }
+ }
+ /* Remove the element for the graph's hash table of elements */
+ if (elemPtr->hashPtr)
+ Tcl_DeleteHashEntry(elemPtr->hashPtr);
+
+ if (elemPtr->obj.name)
+ free((void*)(elemPtr->obj.name));
+
+ if (elemPtr->label)
+ free((void*)(elemPtr->label));
+
+ free(elemPtr);
+}
+
+// Configure
+
static int CgetOp(Graph* graphPtr, Tcl_Interp* interp,
int objc, Tcl_Obj* const objv[])
{
@@ -422,537 +457,6 @@ static int ElementObjConfigure(Tcl_Interp *interp, Graph* graphPtr,
}
}
-// Support
-
-static int GetPenStyleFromObj(Tcl_Interp *interp, Graph *graphPtr,
- Tcl_Obj *objPtr, ClassId classId,
- PenStyle *stylePtr)
-{
- Pen *penPtr;
- Tcl_Obj **objv;
- int objc;
-
- if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
- return TCL_ERROR;
- }
- if ((objc != 1) && (objc != 3)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "bad style entry \"",
- Tcl_GetString(objPtr),
- "\": should be \"penName\" or \"penName min max\"",
- (char *)NULL);
- }
- return TCL_ERROR;
- }
- if (Blt_GetPenFromObj(interp, graphPtr, objv[0], classId, &penPtr)
- != TCL_OK) {
- return TCL_ERROR;
- }
- if (objc == 3) {
- double min, max;
-
- if ((Tcl_GetDoubleFromObj(interp, objv[1], &min) != TCL_OK) ||
- (Tcl_GetDoubleFromObj(interp, objv[2], &max) != TCL_OK)) {
- return TCL_ERROR;
- }
- SetWeight(stylePtr->weight, min, max);
- }
- stylePtr->penPtr = penPtr;
- return TCL_OK;
-}
-
-static void FreeVectorSource(ElemValues *valuesPtr)
-{
- if (valuesPtr->vectorSource.vector != NULL) {
- Blt_SetVectorChangedProc(valuesPtr->vectorSource.vector, NULL, NULL);
- Blt_FreeVectorId(valuesPtr->vectorSource.vector);
- valuesPtr->vectorSource.vector = NULL;
- }
-}
-
-static int FetchVectorValues(Tcl_Interp *interp, ElemValues *valuesPtr,
- Blt_Vector *vector)
-{
- double *array;
-
- if (valuesPtr->values == NULL) {
- array = malloc(Blt_VecLength(vector) * sizeof(double));
- } else {
- array = realloc(valuesPtr->values,
- Blt_VecLength(vector) * sizeof(double));
- }
- if (array == NULL) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL);
- }
- return TCL_ERROR;
- }
- memcpy(array, Blt_VecData(vector), sizeof(double) * Blt_VecLength(vector));
- valuesPtr->min = Blt_VecMin(vector);
- valuesPtr->max = Blt_VecMax(vector);
- valuesPtr->values = array;
- valuesPtr->nValues = Blt_VecLength(vector);
- /* FindRange(valuesPtr); */
- return TCL_OK;
-}
-
-static void VectorChangedProc(Tcl_Interp *interp, ClientData clientData,
- Blt_VectorNotify notify)
-{
- ElemValues *valuesPtr = clientData;
-
- if (notify == BLT_VECTOR_NOTIFY_DESTROY) {
- FreeDataValues(valuesPtr);
- } else {
- Blt_Vector *vector;
-
- Blt_GetVectorById(interp, valuesPtr->vectorSource.vector, &vector);
- if (FetchVectorValues(NULL, valuesPtr, vector) != TCL_OK) {
- return;
- }
- }
- {
- Element *elemPtr = valuesPtr->elemPtr;
- Graph *graphPtr;
-
- graphPtr = elemPtr->obj.graphPtr;
- graphPtr->flags |= RESET_AXES;
- elemPtr->flags |= MAP_ITEM;
- if (!IGNORE_ELEMENT(elemPtr)) {
- graphPtr->flags |= CACHE_DIRTY;
- Blt_EventuallyRedrawGraph(graphPtr);
- }
- }
-}
-
-static int GetVectorData(Tcl_Interp *interp, ElemValues *valuesPtr,
- const char *vecName)
-{
- Blt_Vector *vecPtr;
- VectorDataSource *srcPtr;
-
- srcPtr = &valuesPtr->vectorSource;
- srcPtr->vector = Blt_AllocVectorId(interp, vecName);
- if (Blt_GetVectorById(interp, srcPtr->vector, &vecPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if (FetchVectorValues(interp, valuesPtr, vecPtr) != TCL_OK) {
- FreeVectorSource(valuesPtr);
- return TCL_ERROR;
- }
- Blt_SetVectorChangedProc(srcPtr->vector, VectorChangedProc, valuesPtr);
- valuesPtr->type = ELEM_SOURCE_VECTOR;
- return TCL_OK;
-}
-
-static int ParseValues(Tcl_Interp *interp, Tcl_Obj *objPtr, int *nValuesPtr,
- double **arrayPtr)
-{
- int objc;
- Tcl_Obj **objv;
-
- if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
- return TCL_ERROR;
- }
- *arrayPtr = NULL;
- *nValuesPtr = 0;
- if (objc > 0) {
- double *array;
- double *p;
- int i;
-
- array = malloc(sizeof(double) * objc);
- if (array == NULL) {
- Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL);
- return TCL_ERROR;
- }
- for (p = array, i = 0; i < objc; i++, p++) {
- if (Blt_ExprDoubleFromObj(interp, objv[i], p) != TCL_OK) {
- free(array);
- return TCL_ERROR;
- }
- }
- *arrayPtr = array;
- *nValuesPtr = objc;
- }
- return TCL_OK;
-}
-
-static void FreeDataValues(ElemValues *valuesPtr)
-{
- switch (valuesPtr->type) {
- case ELEM_SOURCE_VECTOR:
- FreeVectorSource(valuesPtr);
- break;
- case ELEM_SOURCE_VALUES:
- break;
- }
- if (valuesPtr->values != NULL) {
- free(valuesPtr->values);
- }
- valuesPtr->values = NULL;
- valuesPtr->nValues = 0;
- valuesPtr->type = ELEM_SOURCE_VALUES;
-}
-
-static void FindRange(ElemValues *valuesPtr)
-{
- int i;
- double *x;
- double min, max;
-
- if ((valuesPtr->nValues < 1) || (valuesPtr->values == NULL)) {
- return; /* This shouldn't ever happen. */
- }
- x = valuesPtr->values;
-
- min = DBL_MAX, max = -DBL_MAX;
- for(i = 0; i < valuesPtr->nValues; i++) {
- if (isfinite(x[i])) {
- min = max = x[i];
- break;
- }
- }
- /* Initialize values to track the vector range */
- for (/* empty */; i < valuesPtr->nValues; i++) {
- if (isfinite(x[i])) {
- if (x[i] < min) {
- min = x[i];
- } else if (x[i] > max) {
- max = x[i];
- }
- }
- }
- valuesPtr->min = min, valuesPtr->max = max;
-}
-
-double Blt_FindElemValuesMinimum(ElemValues *valuesPtr, double minLimit)
-{
- int i;
- double min;
-
- min = DBL_MAX;
- for (i = 0; i < valuesPtr->nValues; i++) {
- double x;
-
- x = valuesPtr->values[i];
- if (x < 0.0) {
- /* What do you do about negative values when using log
- * scale values seems like a grey area. Mirror. */
- x = -x;
- }
- if ((x > minLimit) && (min > x)) {
- min = x;
- }
- }
- if (min == DBL_MAX) {
- min = minLimit;
- }
- return min;
-}
-
-void Blt_FreeStylePalette(Blt_Chain stylePalette)
-{
- Blt_ChainLink link;
-
- /* Skip the first slot. It contains the built-in "normal" pen of
- * the element. */
- link = Blt_Chain_FirstLink(stylePalette);
- if (link != NULL) {
- Blt_ChainLink next;
-
- for (link = Blt_Chain_NextLink(link); link != NULL; link = next) {
- PenStyle *stylePtr;
-
- next = Blt_Chain_NextLink(link);
- stylePtr = Blt_Chain_GetValue(link);
- Blt_FreePen(stylePtr->penPtr);
- Blt_Chain_DeleteLink(stylePalette, link);
- }
- }
-}
-
-PenStyle **Blt_StyleMap(Element *elemPtr)
-{
- int i;
- int nWeights; /* Number of weights to be examined.
- * If there are more data points than
- * weights, they will default to the
- * normal pen. */
-
- PenStyle **dataToStyle; /* Directory of styles. Each array
- * element represents the style for
- * the data point at that index */
- Blt_ChainLink link;
- PenStyle *stylePtr;
- double *w; /* Weight vector */
- int nPoints;
-
- nPoints = NUMBEROFPOINTS(elemPtr);
- nWeights = MIN(elemPtr->w.nValues, nPoints);
- w = elemPtr->w.values;
- link = Blt_Chain_FirstLink(elemPtr->stylePalette);
- stylePtr = Blt_Chain_GetValue(link);
-
- /*
- * Create a style mapping array (data point index to style),
- * initialized to the default style.
- */
- dataToStyle = malloc(nPoints * sizeof(PenStyle *));
- for (i = 0; i < nPoints; i++) {
- dataToStyle[i] = stylePtr;
- }
-
- for (i = 0; i < nWeights; i++) {
- for (link = Blt_Chain_LastLink(elemPtr->stylePalette); link != NULL;
- link = Blt_Chain_PrevLink(link)) {
- stylePtr = Blt_Chain_GetValue(link);
-
- if (stylePtr->weight.range > 0.0) {
- double norm;
-
- norm = (w[i] - stylePtr->weight.min) / stylePtr->weight.range;
- if (((norm - 1.0) <= DBL_EPSILON) &&
- (((1.0 - norm) - 1.0) <= DBL_EPSILON)) {
- dataToStyle[i] = stylePtr;
- break; /* Done: found range that matches. */
- }
- }
- }
- }
- return dataToStyle;
-}
-
-
-static int GetIndex(Tcl_Interp *interp, Element *elemPtr,
- Tcl_Obj *objPtr, int *indexPtr)
-{
- char *string;
-
- string = Tcl_GetString(objPtr);
- if ((*string == 'e') && (strcmp("end", string) == 0)) {
- *indexPtr = NUMBEROFPOINTS(elemPtr) - 1;
- } else if (Blt_ExprIntFromObj(interp, objPtr, indexPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-int Blt_GetElement(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
- Element **elemPtrPtr)
-{
- Tcl_HashEntry *hPtr;
- char *name;
-
- name = Tcl_GetString(objPtr);
- hPtr = Tcl_FindHashEntry(&graphPtr->elements.table, name);
- if (hPtr == NULL) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't find element \"", name,
- "\" in \"", Tk_PathName(graphPtr->tkwin), "\"",
- (char *)NULL);
- }
- return TCL_ERROR;
- }
- *elemPtrPtr = Tcl_GetHashValue(hPtr);
- return TCL_OK;
-}
-
-static void DestroyElement(Element *elemPtr)
-{
- Graph *graphPtr = elemPtr->obj.graphPtr;
-
- Blt_DeleteBindings(graphPtr->bindTable, elemPtr);
- Blt_Legend_RemoveElement(graphPtr, elemPtr);
-
- FreeDataValues(&elemPtr->x);
- FreeDataValues(&elemPtr->y);
-
- (*elemPtr->procsPtr->destroyProc) (graphPtr, elemPtr);
-
- /* Remove it also from the element display list */
- if (elemPtr->link != NULL) {
- Blt_Chain_DeleteLink(graphPtr->elements.displayList, elemPtr->link);
- if (!IGNORE_ELEMENT(elemPtr)) {
- graphPtr->flags |= RESET_WORLD;
- Blt_EventuallyRedrawGraph(graphPtr);
- }
- }
- /* Remove the element for the graph's hash table of elements */
- if (elemPtr->hashPtr != NULL)
- Tcl_DeleteHashEntry(elemPtr->hashPtr);
-
- if (elemPtr->obj.name != NULL)
- free((void*)(elemPtr->obj.name));
-
- if (elemPtr->label != NULL)
- free((void*)(elemPtr->label));
-
- free(elemPtr);
-}
-
-static void FreeElement(char* data)
-{
- Element *elemPtr = (Element *)data;
- DestroyElement(elemPtr);
-}
-
-void Blt_DestroyElements(Graph *graphPtr)
-{
- Tcl_HashEntry *hPtr;
- Tcl_HashSearch iter;
- Element *elemPtr;
-
- for (hPtr = Tcl_FirstHashEntry(&graphPtr->elements.table, &iter);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&iter)) {
- elemPtr = Tcl_GetHashValue(hPtr);
- elemPtr->hashPtr = NULL;
- DestroyElement(elemPtr);
- }
- Tcl_DeleteHashTable(&graphPtr->elements.table);
- Tcl_DeleteHashTable(&graphPtr->elements.tagTable);
- Blt_Chain_Destroy(graphPtr->elements.displayList);
-}
-
-void Blt_ConfigureElements(Graph *graphPtr)
-{
- Blt_ChainLink link;
-
- for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_NextLink(link)) {
- Element *elemPtr;
-
- elemPtr = Blt_Chain_GetValue(link);
- (*elemPtr->procsPtr->configProc) (graphPtr, elemPtr);
- }
-}
-
-void Blt_MapElements(Graph *graphPtr)
-{
- Blt_ChainLink link;
-
- if (graphPtr->mode != BARS_INFRONT) {
- Blt_ResetBarGroups(graphPtr);
- }
- for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_NextLink(link)) {
- Element *elemPtr;
-
- elemPtr = Blt_Chain_GetValue(link);
- if (IGNORE_ELEMENT(elemPtr)) {
- continue;
- }
- if ((graphPtr->flags & MAP_ALL) || (elemPtr->flags & MAP_ITEM)) {
- (*elemPtr->procsPtr->mapProc) (graphPtr, elemPtr);
- elemPtr->flags &= ~MAP_ITEM;
- }
- }
-}
-
-void Blt_DrawElements(Graph *graphPtr, Drawable drawable)
-{
- Blt_ChainLink link;
-
- /* Draw with respect to the stacking order. */
- for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_PrevLink(link)) {
- Element *elemPtr;
-
- elemPtr = Blt_Chain_GetValue(link);
- if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) {
- (*elemPtr->procsPtr->drawNormalProc)(graphPtr, drawable, elemPtr);
- }
- }
-}
-
-void Blt_DrawActiveElements(Graph *graphPtr, Drawable drawable)
-{
- Blt_ChainLink link;
-
- for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_PrevLink(link)) {
- Element *elemPtr;
-
- elemPtr = Blt_Chain_GetValue(link);
- if (!(elemPtr->flags & DELETE_PENDING) &&
- (elemPtr->flags & ACTIVE) &&
- !elemPtr->hide) {
- (*elemPtr->procsPtr->drawActiveProc)(graphPtr, drawable, elemPtr);
- }
- }
-}
-
-void Blt_ElementsToPostScript(Graph *graphPtr, Blt_Ps ps)
-{
- Blt_ChainLink link;
-
- for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_PrevLink(link)) {
- Element *elemPtr;
-
- elemPtr = Blt_Chain_GetValue(link);
- if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) {
- continue;
- }
- /* Comment the PostScript to indicate the start of the element */
- Blt_Ps_Format(ps, "\n%% Element \"%s\"\n\n", elemPtr->obj.name);
- (*elemPtr->procsPtr->printNormalProc) (graphPtr, ps, elemPtr);
- }
-}
-
-void Blt_ActiveElementsToPostScript( Graph *graphPtr, Blt_Ps ps)
-{
- Blt_ChainLink link;
-
- for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
- link != NULL; link = Blt_Chain_PrevLink(link)) {
- Element *elemPtr;
-
- elemPtr = Blt_Chain_GetValue(link);
- if (!(elemPtr->flags & DELETE_PENDING) &&
- (elemPtr->flags & ACTIVE) &&
- !elemPtr->hide) {
- Blt_Ps_Format(ps, "\n%% Active Element \"%s\"\n\n",
- elemPtr->obj.name);
- (*elemPtr->procsPtr->printActiveProc)(graphPtr, ps, elemPtr);
- }
- }
-}
-
-ClientData Blt_MakeElementTag(Graph *graphPtr, const char *tagName)
-{
- Tcl_HashEntry *hPtr;
- int isNew;
-
- hPtr = Tcl_CreateHashEntry(&graphPtr->elements.tagTable, tagName, &isNew);
- return Tcl_GetHashKey(&graphPtr->elements.tagTable, hPtr);
-}
-
-// waj
-/*
- if (Blt_ConfigModified(elemPtr->configSpecs, "-hide", (char *)NULL)) {
- graphPtr->flags |= RESET_AXES;
- elemPtr->flags |= MAP_ITEM;
- }
-*/
-/* If data points or axes have changed, reset the axes (may
- * affect autoscaling) and recalculate the screen points of
- * the element. */
-
-/*
- if (Blt_ConfigModified(elemPtr->configSpecs, "-*data", "-map*", "-x",
- "-y", (char *)NULL)) {
- graphPtr->flags |= RESET_WORLD;
- elemPtr->flags |= MAP_ITEM;
- }
-*/
-/* The new label may change the size of the legend */
-/*
- if (Blt_ConfigModified(elemPtr->configSpecs, "-label", (char *)NULL)) {
- graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD);
- }
-*/
-
// Ops
static int ActivateOp(Graph *graphPtr, Tcl_Interp *interp,
@@ -1032,8 +536,8 @@ 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 int CreateOp(Graph *graphPtr, Tcl_Interp *interp,
- int objc, Tcl_Obj *const *objv, ClassId classId)
+static int CreateOp(Graph* graphPtr, Tcl_Interp* interp,
+ int objc, Tcl_Obj* const objv[], ClassId classId)
{
return CreateElement(graphPtr, interp, objc, objv, classId);
}
@@ -1517,3 +1021,501 @@ int Blt_ElementOp(Graph *graphPtr, Tcl_Interp *interp,
}
return result;
}
+// Support
+
+static void FreeElement(char* data)
+{
+ Element *elemPtr = (Element *)data;
+ DestroyElement(elemPtr);
+}
+
+static int GetPenStyleFromObj(Tcl_Interp *interp, Graph *graphPtr,
+ Tcl_Obj *objPtr, ClassId classId,
+ PenStyle *stylePtr)
+{
+ Pen *penPtr;
+ Tcl_Obj **objv;
+ int objc;
+
+ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((objc != 1) && (objc != 3)) {
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "bad style entry \"",
+ Tcl_GetString(objPtr),
+ "\": should be \"penName\" or \"penName min max\"",
+ (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ if (Blt_GetPenFromObj(interp, graphPtr, objv[0], classId, &penPtr)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ double min, max;
+
+ if ((Tcl_GetDoubleFromObj(interp, objv[1], &min) != TCL_OK) ||
+ (Tcl_GetDoubleFromObj(interp, objv[2], &max) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ SetWeight(stylePtr->weight, min, max);
+ }
+ stylePtr->penPtr = penPtr;
+ return TCL_OK;
+}
+
+static void FreeVectorSource(ElemValues *valuesPtr)
+{
+ if (valuesPtr->vectorSource.vector != NULL) {
+ Blt_SetVectorChangedProc(valuesPtr->vectorSource.vector, NULL, NULL);
+ Blt_FreeVectorId(valuesPtr->vectorSource.vector);
+ valuesPtr->vectorSource.vector = NULL;
+ }
+}
+
+static int FetchVectorValues(Tcl_Interp *interp, ElemValues *valuesPtr,
+ Blt_Vector *vector)
+{
+ double *array;
+
+ if (valuesPtr->values == NULL) {
+ array = malloc(Blt_VecLength(vector) * sizeof(double));
+ } else {
+ array = realloc(valuesPtr->values,
+ Blt_VecLength(vector) * sizeof(double));
+ }
+ if (array == NULL) {
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ memcpy(array, Blt_VecData(vector), sizeof(double) * Blt_VecLength(vector));
+ valuesPtr->min = Blt_VecMin(vector);
+ valuesPtr->max = Blt_VecMax(vector);
+ valuesPtr->values = array;
+ valuesPtr->nValues = Blt_VecLength(vector);
+ /* FindRange(valuesPtr); */
+ return TCL_OK;
+}
+
+static void VectorChangedProc(Tcl_Interp *interp, ClientData clientData,
+ Blt_VectorNotify notify)
+{
+ ElemValues *valuesPtr = clientData;
+
+ if (notify == BLT_VECTOR_NOTIFY_DESTROY) {
+ FreeDataValues(valuesPtr);
+ } else {
+ Blt_Vector *vector;
+
+ Blt_GetVectorById(interp, valuesPtr->vectorSource.vector, &vector);
+ if (FetchVectorValues(NULL, valuesPtr, vector) != TCL_OK) {
+ return;
+ }
+ }
+ {
+ Element *elemPtr = valuesPtr->elemPtr;
+ Graph *graphPtr;
+
+ graphPtr = elemPtr->obj.graphPtr;
+ graphPtr->flags |= RESET_AXES;
+ elemPtr->flags |= MAP_ITEM;
+ if (!IGNORE_ELEMENT(elemPtr)) {
+ graphPtr->flags |= CACHE_DIRTY;
+ Blt_EventuallyRedrawGraph(graphPtr);
+ }
+ }
+}
+
+static int GetVectorData(Tcl_Interp *interp, ElemValues *valuesPtr,
+ const char *vecName)
+{
+ Blt_Vector *vecPtr;
+ VectorDataSource *srcPtr;
+
+ srcPtr = &valuesPtr->vectorSource;
+ srcPtr->vector = Blt_AllocVectorId(interp, vecName);
+ if (Blt_GetVectorById(interp, srcPtr->vector, &vecPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (FetchVectorValues(interp, valuesPtr, vecPtr) != TCL_OK) {
+ FreeVectorSource(valuesPtr);
+ return TCL_ERROR;
+ }
+ Blt_SetVectorChangedProc(srcPtr->vector, VectorChangedProc, valuesPtr);
+ valuesPtr->type = ELEM_SOURCE_VECTOR;
+ return TCL_OK;
+}
+
+static int ParseValues(Tcl_Interp *interp, Tcl_Obj *objPtr, int *nValuesPtr,
+ double **arrayPtr)
+{
+ int objc;
+ Tcl_Obj **objv;
+
+ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ *arrayPtr = NULL;
+ *nValuesPtr = 0;
+ if (objc > 0) {
+ double *array;
+ double *p;
+ int i;
+
+ array = malloc(sizeof(double) * objc);
+ if (array == NULL) {
+ Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL);
+ return TCL_ERROR;
+ }
+ for (p = array, i = 0; i < objc; i++, p++) {
+ if (Blt_ExprDoubleFromObj(interp, objv[i], p) != TCL_OK) {
+ free(array);
+ return TCL_ERROR;
+ }
+ }
+ *arrayPtr = array;
+ *nValuesPtr = objc;
+ }
+ return TCL_OK;
+}
+
+static void FreeDataValues(ElemValues *valuesPtr)
+{
+ switch (valuesPtr->type) {
+ case ELEM_SOURCE_VECTOR:
+ FreeVectorSource(valuesPtr);
+ break;
+ case ELEM_SOURCE_VALUES:
+ break;
+ }
+ if (valuesPtr->values != NULL) {
+ free(valuesPtr->values);
+ }
+ valuesPtr->values = NULL;
+ valuesPtr->nValues = 0;
+ valuesPtr->type = ELEM_SOURCE_VALUES;
+}
+
+static void FindRange(ElemValues *valuesPtr)
+{
+ int i;
+ double *x;
+ double min, max;
+
+ if ((valuesPtr->nValues < 1) || (valuesPtr->values == NULL)) {
+ return; /* This shouldn't ever happen. */
+ }
+ x = valuesPtr->values;
+
+ min = DBL_MAX, max = -DBL_MAX;
+ for(i = 0; i < valuesPtr->nValues; i++) {
+ if (isfinite(x[i])) {
+ min = max = x[i];
+ break;
+ }
+ }
+ /* Initialize values to track the vector range */
+ for (/* empty */; i < valuesPtr->nValues; i++) {
+ if (isfinite(x[i])) {
+ if (x[i] < min) {
+ min = x[i];
+ } else if (x[i] > max) {
+ max = x[i];
+ }
+ }
+ }
+ valuesPtr->min = min, valuesPtr->max = max;
+}
+
+double Blt_FindElemValuesMinimum(ElemValues *valuesPtr, double minLimit)
+{
+ int i;
+ double min;
+
+ min = DBL_MAX;
+ for (i = 0; i < valuesPtr->nValues; i++) {
+ double x;
+
+ x = valuesPtr->values[i];
+ if (x < 0.0) {
+ /* What do you do about negative values when using log
+ * scale values seems like a grey area. Mirror. */
+ x = -x;
+ }
+ if ((x > minLimit) && (min > x)) {
+ min = x;
+ }
+ }
+ if (min == DBL_MAX) {
+ min = minLimit;
+ }
+ return min;
+}
+
+void Blt_FreeStylePalette(Blt_Chain stylePalette)
+{
+ Blt_ChainLink link;
+
+ /* Skip the first slot. It contains the built-in "normal" pen of
+ * the element. */
+ link = Blt_Chain_FirstLink(stylePalette);
+ if (link != NULL) {
+ Blt_ChainLink next;
+
+ for (link = Blt_Chain_NextLink(link); link != NULL; link = next) {
+ PenStyle *stylePtr;
+
+ next = Blt_Chain_NextLink(link);
+ stylePtr = Blt_Chain_GetValue(link);
+ Blt_FreePen(stylePtr->penPtr);
+ Blt_Chain_DeleteLink(stylePalette, link);
+ }
+ }
+}
+
+PenStyle **Blt_StyleMap(Element *elemPtr)
+{
+ int i;
+ int nWeights; /* Number of weights to be examined.
+ * If there are more data points than
+ * weights, they will default to the
+ * normal pen. */
+
+ PenStyle **dataToStyle; /* Directory of styles. Each array
+ * element represents the style for
+ * the data point at that index */
+ Blt_ChainLink link;
+ PenStyle *stylePtr;
+ double *w; /* Weight vector */
+ int nPoints;
+
+ nPoints = NUMBEROFPOINTS(elemPtr);
+ nWeights = MIN(elemPtr->w.nValues, nPoints);
+ w = elemPtr->w.values;
+ link = Blt_Chain_FirstLink(elemPtr->stylePalette);
+ stylePtr = Blt_Chain_GetValue(link);
+
+ /*
+ * Create a style mapping array (data point index to style),
+ * initialized to the default style.
+ */
+ dataToStyle = malloc(nPoints * sizeof(PenStyle *));
+ for (i = 0; i < nPoints; i++) {
+ dataToStyle[i] = stylePtr;
+ }
+
+ for (i = 0; i < nWeights; i++) {
+ for (link = Blt_Chain_LastLink(elemPtr->stylePalette); link != NULL;
+ link = Blt_Chain_PrevLink(link)) {
+ stylePtr = Blt_Chain_GetValue(link);
+
+ if (stylePtr->weight.range > 0.0) {
+ double norm;
+
+ norm = (w[i] - stylePtr->weight.min) / stylePtr->weight.range;
+ if (((norm - 1.0) <= DBL_EPSILON) &&
+ (((1.0 - norm) - 1.0) <= DBL_EPSILON)) {
+ dataToStyle[i] = stylePtr;
+ break; /* Done: found range that matches. */
+ }
+ }
+ }
+ }
+ return dataToStyle;
+}
+
+
+static int GetIndex(Tcl_Interp *interp, Element *elemPtr,
+ Tcl_Obj *objPtr, int *indexPtr)
+{
+ char *string;
+
+ string = Tcl_GetString(objPtr);
+ if ((*string == 'e') && (strcmp("end", string) == 0)) {
+ *indexPtr = NUMBEROFPOINTS(elemPtr) - 1;
+ } else if (Blt_ExprIntFromObj(interp, objPtr, indexPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
+int Blt_GetElement(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+ Element **elemPtrPtr)
+{
+ Tcl_HashEntry *hPtr;
+ char *name;
+
+ name = Tcl_GetString(objPtr);
+ hPtr = Tcl_FindHashEntry(&graphPtr->elements.table, name);
+ if (hPtr == NULL) {
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "can't find element \"", name,
+ "\" in \"", Tk_PathName(graphPtr->tkwin), "\"",
+ (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ *elemPtrPtr = Tcl_GetHashValue(hPtr);
+ return TCL_OK;
+}
+
+void Blt_DestroyElements(Graph *graphPtr)
+{
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch iter;
+ Element *elemPtr;
+
+ for (hPtr = Tcl_FirstHashEntry(&graphPtr->elements.table, &iter);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&iter)) {
+ elemPtr = Tcl_GetHashValue(hPtr);
+ elemPtr->hashPtr = NULL;
+ DestroyElement(elemPtr);
+ }
+ Tcl_DeleteHashTable(&graphPtr->elements.table);
+ Tcl_DeleteHashTable(&graphPtr->elements.tagTable);
+ Blt_Chain_Destroy(graphPtr->elements.displayList);
+}
+
+void Blt_ConfigureElements(Graph *graphPtr)
+{
+ Blt_ChainLink link;
+
+ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_NextLink(link)) {
+ Element *elemPtr;
+
+ elemPtr = Blt_Chain_GetValue(link);
+ (*elemPtr->procsPtr->configProc) (graphPtr, elemPtr);
+ }
+}
+
+void Blt_MapElements(Graph *graphPtr)
+{
+ Blt_ChainLink link;
+
+ if (graphPtr->mode != BARS_INFRONT) {
+ Blt_ResetBarGroups(graphPtr);
+ }
+ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_NextLink(link)) {
+ Element *elemPtr;
+
+ elemPtr = Blt_Chain_GetValue(link);
+ if (IGNORE_ELEMENT(elemPtr)) {
+ continue;
+ }
+ if ((graphPtr->flags & MAP_ALL) || (elemPtr->flags & MAP_ITEM)) {
+ (*elemPtr->procsPtr->mapProc) (graphPtr, elemPtr);
+ elemPtr->flags &= ~MAP_ITEM;
+ }
+ }
+}
+
+void Blt_DrawElements(Graph *graphPtr, Drawable drawable)
+{
+ Blt_ChainLink link;
+
+ /* Draw with respect to the stacking order. */
+ for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_PrevLink(link)) {
+ Element *elemPtr;
+
+ elemPtr = Blt_Chain_GetValue(link);
+ if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) {
+ (*elemPtr->procsPtr->drawNormalProc)(graphPtr, drawable, elemPtr);
+ }
+ }
+}
+
+void Blt_DrawActiveElements(Graph *graphPtr, Drawable drawable)
+{
+ Blt_ChainLink link;
+
+ for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_PrevLink(link)) {
+ Element *elemPtr;
+
+ elemPtr = Blt_Chain_GetValue(link);
+ if (!(elemPtr->flags & DELETE_PENDING) &&
+ (elemPtr->flags & ACTIVE) &&
+ !elemPtr->hide) {
+ (*elemPtr->procsPtr->drawActiveProc)(graphPtr, drawable, elemPtr);
+ }
+ }
+}
+
+void Blt_ElementsToPostScript(Graph *graphPtr, Blt_Ps ps)
+{
+ Blt_ChainLink link;
+
+ for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_PrevLink(link)) {
+ Element *elemPtr;
+
+ elemPtr = Blt_Chain_GetValue(link);
+ if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) {
+ continue;
+ }
+ /* Comment the PostScript to indicate the start of the element */
+ Blt_Ps_Format(ps, "\n%% Element \"%s\"\n\n", elemPtr->obj.name);
+ (*elemPtr->procsPtr->printNormalProc) (graphPtr, ps, elemPtr);
+ }
+}
+
+void Blt_ActiveElementsToPostScript( Graph *graphPtr, Blt_Ps ps)
+{
+ Blt_ChainLink link;
+
+ for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
+ link != NULL; link = Blt_Chain_PrevLink(link)) {
+ Element *elemPtr;
+
+ elemPtr = Blt_Chain_GetValue(link);
+ if (!(elemPtr->flags & DELETE_PENDING) &&
+ (elemPtr->flags & ACTIVE) &&
+ !elemPtr->hide) {
+ Blt_Ps_Format(ps, "\n%% Active Element \"%s\"\n\n",
+ elemPtr->obj.name);
+ (*elemPtr->procsPtr->printActiveProc)(graphPtr, ps, elemPtr);
+ }
+ }
+}
+
+ClientData Blt_MakeElementTag(Graph *graphPtr, const char *tagName)
+{
+ Tcl_HashEntry *hPtr;
+ int isNew;
+
+ hPtr = Tcl_CreateHashEntry(&graphPtr->elements.tagTable, tagName, &isNew);
+ return Tcl_GetHashKey(&graphPtr->elements.tagTable, hPtr);
+}
+
+// waj
+/*
+ if (Blt_ConfigModified(elemPtr->configSpecs, "-hide", (char *)NULL)) {
+ graphPtr->flags |= RESET_AXES;
+ elemPtr->flags |= MAP_ITEM;
+ }
+*/
+/* If data points or axes have changed, reset the axes (may
+ * affect autoscaling) and recalculate the screen points of
+ * the element. */
+
+/*
+ if (Blt_ConfigModified(elemPtr->configSpecs, "-*data", "-map*", "-x",
+ "-y", (char *)NULL)) {
+ graphPtr->flags |= RESET_WORLD;
+ elemPtr->flags |= MAP_ITEM;
+ }
+*/
+/* The new label may change the size of the legend */
+/*
+ if (Blt_ConfigModified(elemPtr->configSpecs, "-label", (char *)NULL)) {
+ graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD);
+ }
+*/
+
diff --git a/src/bltGrPenOp.C b/src/bltGrPenOp.C
index e1d5ec7..84a2ef0 100644
--- a/src/bltGrPenOp.C
+++ b/src/bltGrPenOp.C
@@ -41,6 +41,18 @@
#include "bltGrElem.h"
#include "bltOp.h"
+// Defs
+
+static void DestroyPen(Pen* penPtr);
+static int GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+ Pen **penPtrPtr);
+static int PenObjConfigure(Tcl_Interp *interp, Graph* graphPtr, Pen* penPtr,
+ int objc, Tcl_Obj* const objv[]);
+typedef int (GraphPenProc)(Tcl_Interp *interp, Graph *graphPtr, int objc,
+ Tcl_Obj *const *objv);
+
+// OptionSpecs
+
static Tk_CustomOptionSetProc PenSetProc;
static Tk_CustomOptionGetProc PenGetProc;
Tk_ObjCustomOption barPenObjOption =
@@ -92,193 +104,96 @@ static Tcl_Obj* PenGetProc(ClientData clientData, Tk_Window tkwin,
return Tcl_NewStringObj(penPtr->name, -1);
};
-static int PenObjConfigure(Tcl_Interp *interp, Graph* graphPtr,
- Pen* penPtr,
- int objc, Tcl_Obj* const objv[]);
-typedef int (GraphPenProc)(Tcl_Interp *interp, Graph *graphPtr, int objc,
- Tcl_Obj *const *objv);
+// Create
-static int GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
- Pen **penPtrPtr)
+int Blt_CreatePen(Graph* graphPtr, Tcl_Interp* interp,
+ const char* penName, ClassId classId,
+ int objc, Tcl_Obj* const objv[])
{
- Tcl_HashEntry *hPtr;
- Pen *penPtr;
- const char *name;
-
- penPtr = NULL;
- name = Tcl_GetString(objPtr);
- hPtr = Tcl_FindHashEntry(&graphPtr->penTable, name);
- if (hPtr != NULL) {
- penPtr = Tcl_GetHashValue(hPtr);
- if (penPtr->flags & DELETE_PENDING) {
- penPtr = NULL;
- }
- }
- if (penPtr == NULL) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"",
- Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
- }
- return TCL_ERROR;
- }
- *penPtrPtr = penPtr;
- return TCL_OK;
-}
-
-static void DestroyPen(Pen* penPtr)
-{
- Graph *graphPtr = penPtr->graphPtr;
-
- (*penPtr->destroyProc) (graphPtr, penPtr);
- if ((penPtr->name != NULL) && (penPtr->name[0] != '\0')) {
- free((void*)(penPtr->name));
- }
- if (penPtr->hashPtr != NULL) {
- Tcl_DeleteHashEntry(penPtr->hashPtr);
- }
- free(penPtr);
-}
-
-void Blt_FreePen(Pen *penPtr)
-{
- if (penPtr != NULL) {
- penPtr->refCount--;
- if ((penPtr->refCount == 0) && (penPtr->flags & DELETE_PENDING)) {
- DestroyPen(penPtr);
- }
- }
-}
-
-Pen* Blt_CreatePen(Graph* graphPtr, const char* penName, ClassId classId,
- int objc, Tcl_Obj* const objv[])
-{
- Pen *penPtr;
- Tcl_HashEntry *hPtr;
- int isNew;
- int i;
-
/*
* Scan the option list for a "-type" entry. This will indicate what type
* of pen we are creating. Otherwise we'll default to the suggested type.
* Last -type option wins.
*/
- for (i = 0; i < objc; i += 2) {
+ for (int ii = 0; ii<objc; ii += 2) {
char *string;
int length;
- string = Tcl_GetStringFromObj(objv[i], &length);
+ string = Tcl_GetStringFromObj(objv[ii], &length);
if ((length > 2) && (strncmp(string, "-type", length) == 0)) {
char *arg;
- arg = Tcl_GetString(objv[i + 1]);
- if (strcmp(arg, "bar") == 0) {
+ arg = Tcl_GetString(objv[ii + 1]);
+ if (strcmp(arg, "bar") == 0)
classId = CID_ELEM_BAR;
- } else if (strcmp(arg, "line") == 0) {
+ else if (strcmp(arg, "line") == 0)
classId = CID_ELEM_LINE;
- } else {
- Tcl_AppendResult(graphPtr->interp, "unknown pen type \"",
+ else {
+ Tcl_AppendResult(interp, "unknown pen type \"",
arg, "\" specified", (char *)NULL);
- return NULL;
+ return TCL_ERROR;
}
}
}
- classId = CID_ELEM_LINE;
- hPtr = Tcl_CreateHashEntry(&graphPtr->penTable, penName, &isNew);
+
+ Pen *penPtr;
+ int isNew;
+ Tcl_HashEntry *hPtr =
+ Tcl_CreateHashEntry(&graphPtr->penTable, penName, &isNew);
if (!isNew) {
penPtr = Tcl_GetHashValue(hPtr);
- if ((penPtr->flags & DELETE_PENDING) == 0) {
- Tcl_AppendResult(graphPtr->interp, "pen \"", penName,
- "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"",
- (char *)NULL);
- return NULL;
- }
- if (penPtr->classId != classId) {
- Tcl_AppendResult(graphPtr->interp, "pen \"", penName,
- "\" in-use: can't change pen type from \"",
- Blt_GraphClassName(penPtr->classId), "\" to \"",
- Blt_GraphClassName(classId), "\"", (char *)NULL);
- return NULL;
- }
- penPtr->flags &= ~DELETE_PENDING; /* Undelete the pen. */
- } else {
- if (classId == CID_ELEM_BAR)
- penPtr = Blt_BarPen(graphPtr, penName);
- else
- penPtr = Blt_LinePen(graphPtr, penName);
- penPtr->classId = classId;
- penPtr->hashPtr = hPtr;
- penPtr->graphPtr = graphPtr;
- Tcl_SetHashValue(hPtr, penPtr);
- }
+ if ((penPtr->flags & DELETE_PENDING) == 0)
+ Tcl_AppendResult(interp, "pen \"", penName, "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+ else if (penPtr->classId != classId)
+ Tcl_AppendResult(interp, "pen \"", penName, "\" in-use: can't change pen type from \"", Blt_GraphClassName(penPtr->classId), "\" to \"", Blt_GraphClassName(classId), "\"", (char *)NULL);
- /*
- if ((Tk_InitOptions(graphPtr->interp, (char*)penPtr, penPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (PenObjConfigure(interp, graphPtr, penPtr, objc-4, objv+4) != TCL_OK)) {
- if (isNew)
- DestroyElement(penPtr);
return TCL_ERROR;
}
- */
-
- // (*penPtr->configProc) (graphPtr, penPtr);
- return penPtr;
-}
-int Blt_GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
- ClassId classId, Pen **penPtrPtr)
-{
- Tcl_HashEntry *hPtr;
- Pen *penPtr;
- const char *name;
-
- penPtr = NULL;
- name = Tcl_GetString(objPtr);
- hPtr = Tcl_FindHashEntry(&graphPtr->penTable, name);
- if (hPtr != NULL) {
- penPtr = Tcl_GetHashValue(hPtr);
- if (penPtr->flags & DELETE_PENDING) {
- penPtr = NULL;
- }
- }
- if (penPtr == NULL) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"",
- Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
- }
+ if (classId == CID_ELEM_BAR)
+ penPtr = Blt_BarPen(graphPtr, penName);
+ else
+ penPtr = Blt_LinePen(graphPtr, penName);
+ if (!penPtr)
return TCL_ERROR;
- }
- classId = CID_ELEM_LINE;
- if (penPtr->classId != classId) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "pen \"", name,
- "\" is the wrong type (is \"",
- Blt_GraphClassName(penPtr->classId), "\"", ", wanted \"",
- Blt_GraphClassName(classId), "\")", (char *)NULL);
- }
+
+ penPtr->graphPtr = graphPtr;
+ penPtr->classId = classId;
+
+ if (PenObjConfigure(interp, graphPtr, penPtr, objc-4, objv+4) != TCL_OK) {
+ DestroyPen(penPtr);
return TCL_ERROR;
}
- penPtr->refCount++;
- *penPtrPtr = penPtr;
+
+ penPtr->hashPtr = hPtr;
+ Tcl_SetHashValue(hPtr, penPtr);
+
+ graphPtr->flags |= CACHE_DIRTY;
+ Blt_EventuallyRedrawGraph(graphPtr);
+
+ Tcl_SetObjResult(interp, objv[3]);
return TCL_OK;
}
-void Blt_DestroyPens(Graph *graphPtr)
+static void DestroyPen(Pen* penPtr)
{
- Tcl_HashEntry *hPtr;
- Tcl_HashSearch iter;
+ Graph *graphPtr = penPtr->graphPtr;
- for (hPtr = Tcl_FirstHashEntry(&graphPtr->penTable, &iter);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&iter)) {
- Pen *penPtr;
+ (*penPtr->destroyProc) (graphPtr, penPtr);
- penPtr = Tcl_GetHashValue(hPtr);
- penPtr->hashPtr = NULL;
- DestroyPen(penPtr);
- }
- Tcl_DeleteHashTable(&graphPtr->penTable);
+ if (penPtr->name)
+ free((void*)(penPtr->name));
+
+ if (penPtr->hashPtr)
+ Tcl_DeleteHashEntry(penPtr->hashPtr);
+
+ free(penPtr);
}
-static int CgetOp(Tcl_Interp *interp, Graph *graphPtr,
- int objc, Tcl_Obj *const *objv)
+// Configure
+
+static int CgetOp(Tcl_Interp* interp, Graph* graphPtr,
+ int objc, Tcl_Obj* const objv[])
{
if (objc != 5) {
Tcl_WrongNumArgs(interp, 3, objv, "cget option");
@@ -303,78 +218,73 @@ static int CgetOp(Tcl_Interp *interp, Graph *graphPtr,
static int ConfigureOp(Tcl_Interp *interp, Graph *graphPtr,
int objc, Tcl_Obj *const *objv)
{
- Pen *penPtr;
- int nNames, nOpts;
- int redraw;
- Tcl_Obj *const *options;
- int i;
-
- /* Figure out where the option value pairs begin */
- objc -= 3;
- objv += 3;
- for (i = 0; i < objc; i++) {
- char *string;
+ Pen* penPtr;
+ if (GetPenFromObj(interp, graphPtr, objv[3], &penPtr) != TCL_OK)
+ return TCL_ERROR;
- string = Tcl_GetString(objv[i]);
- if (string[0] == '-') {
- break;
- }
- if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) {
+ if (objc <= 5) {
+ Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp, (char*)penPtr,
+ penPtr->optionTable,
+ (objc == 5) ? objv[4] : NULL,
+ graphPtr->tkwin);
+ if (objPtr == NULL)
return TCL_ERROR;
- }
- }
- nNames = i; /* Number of pen names specified */
- nOpts = objc - i; /* Number of options specified */
- options = objv + i; /* Start of options in objv */
+ else
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+ }
+ else
+ return PenObjConfigure(interp, graphPtr, penPtr, objc-4, objv+4);
+}
- redraw = 0;
- for (i = 0; i < nNames; i++) {
- if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- /*
- // waj
- flags = BLT_CONFIG_OBJV_ONLY | (penPtr->flags&(ACTIVE_PEN|NORMAL_PEN));
- if (nOpts == 0) {
- return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin,
- penPtr->configSpecs, (char *)penPtr, (Tcl_Obj *)NULL, flags);
- } else if (nOpts == 1) {
- return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin,
- penPtr->configSpecs, (char *)penPtr, options[0], flags);
- }
- if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin,
- penPtr->configSpecs, nOpts, options, (char *)penPtr, flags)
- != TCL_OK) {
- break;
+static int PenObjConfigure(Tcl_Interp *interp, Graph* graphPtr, Pen* penPtr,
+ int objc, Tcl_Obj* const objv[])
+{
+ Tk_SavedOptions savedOptions;
+ int mask =0;
+ int error;
+ Tcl_Obj* errorResult;
+
+ for (error=0; error<=1; error++) {
+ if (!error) {
+ if (Tk_SetOptions(interp, (char*)penPtr, penPtr->optionTable,
+ objc, objv, graphPtr->tkwin, &savedOptions, &mask)
+ != TCL_OK)
+ continue;
}
- */
- (*penPtr->configProc) (graphPtr, penPtr);
- if (penPtr->refCount > 0) {
- redraw++;
+ else {
+ errorResult = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(errorResult);
+ Tk_RestoreSavedOptions(&savedOptions);
}
- }
- if (redraw) {
+
+ graphPtr->flags |= mask;
graphPtr->flags |= CACHE_DIRTY;
+ if ((*penPtr->configProc) (graphPtr, penPtr) != TCL_OK)
+ return TCL_ERROR;
Blt_EventuallyRedrawGraph(graphPtr);
+
+ break;
+ }
+
+ if (!error) {
+ Tk_FreeSavedOptions(&savedOptions);
+ return TCL_OK;
}
- if (i < nNames) {
+ else {
+ Tcl_SetObjResult(interp, errorResult);
+ Tcl_DecrRefCount(errorResult);
return TCL_ERROR;
}
- return TCL_OK;
}
+// Ops
+
static int CreateOp(Tcl_Interp *interp, Graph *graphPtr,
int objc, Tcl_Obj *const *objv)
{
- Pen *penPtr;
-
- penPtr = Blt_CreatePen(graphPtr, Tcl_GetString(objv[3]), graphPtr->classId,
- objc - 4, objv + 4);
- if (penPtr == NULL)
- return TCL_ERROR;
-
- Tcl_SetObjResult(interp, objv[3]);
- return TCL_OK;
+ return Blt_CreatePen(graphPtr, interp, Tcl_GetString(objv[3]),
+ graphPtr->classId, objc, objv);
}
static int DeleteOp(Tcl_Interp *interp, Graph *graphPtr,
@@ -475,6 +385,8 @@ static Blt_OpSpec penOps[] =
};
static int nPenOps = sizeof(penOps) / sizeof(Blt_OpSpec);
+// Extern
+
int Blt_PenOp(Graph *graphPtr, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv)
{
@@ -485,3 +397,97 @@ int Blt_PenOp(Graph *graphPtr, Tcl_Interp *interp,
}
return (*proc) (interp, graphPtr, objc, objv);
}
+
+void Blt_DestroyPens(Graph *graphPtr)
+{
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch iter;
+
+ for (hPtr = Tcl_FirstHashEntry(&graphPtr->penTable, &iter);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&iter)) {
+ Pen *penPtr;
+
+ penPtr = Tcl_GetHashValue(hPtr);
+ penPtr->hashPtr = NULL;
+ DestroyPen(penPtr);
+ }
+ Tcl_DeleteHashTable(&graphPtr->penTable);
+}
+
+void Blt_FreePen(Pen *penPtr)
+{
+ if (penPtr != NULL) {
+ penPtr->refCount--;
+ if ((penPtr->refCount == 0) && (penPtr->flags & DELETE_PENDING)) {
+ DestroyPen(penPtr);
+ }
+ }
+}
+
+int Blt_GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+ ClassId classId, Pen **penPtrPtr)
+{
+ Tcl_HashEntry *hPtr;
+ Pen *penPtr;
+ const char *name;
+
+ penPtr = NULL;
+ name = Tcl_GetString(objPtr);
+ hPtr = Tcl_FindHashEntry(&graphPtr->penTable, name);
+ if (hPtr != NULL) {
+ penPtr = Tcl_GetHashValue(hPtr);
+ if (penPtr->flags & DELETE_PENDING) {
+ penPtr = NULL;
+ }
+ }
+ if (penPtr == NULL) {
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"",
+ Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ classId = CID_ELEM_LINE;
+ if (penPtr->classId != classId) {
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "pen \"", name,
+ "\" is the wrong type (is \"",
+ Blt_GraphClassName(penPtr->classId), "\"", ", wanted \"",
+ Blt_GraphClassName(classId), "\")", (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ penPtr->refCount++;
+ *penPtrPtr = penPtr;
+ return TCL_OK;
+}
+
+// Support
+
+static int GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr,
+ Pen **penPtrPtr)
+{
+ Tcl_HashEntry *hPtr;
+ Pen *penPtr;
+ const char *name;
+
+ penPtr = NULL;
+ name = Tcl_GetString(objPtr);
+ hPtr = Tcl_FindHashEntry(&graphPtr->penTable, name);
+ if (hPtr != NULL) {
+ penPtr = Tcl_GetHashValue(hPtr);
+ if (penPtr->flags & DELETE_PENDING) {
+ penPtr = NULL;
+ }
+ }
+ if (penPtr == NULL) {
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"",
+ Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ *penPtrPtr = penPtr;
+ return TCL_OK;
+}
+
diff --git a/src/bltGraph.C b/src/bltGraph.C
index a02a818..50d42e1 100644
--- a/src/bltGraph.C
+++ b/src/bltGraph.C
@@ -301,9 +301,11 @@ static int NewGraph(ClientData clientData, Tcl_Interp*interp,
goto error;
if (Blt_CreateLegend(graphPtr) != TCL_OK)
goto error;
- if (Blt_CreatePen(graphPtr, "activeLine", CID_ELEM_LINE, 0, NULL) == NULL)
+ if (Blt_CreatePen(graphPtr, interp, "activeLine", CID_ELEM_LINE, 0, NULL) !=
+ TCL_OK)
goto error;
- if (Blt_CreatePen(graphPtr, "activeBar", CID_ELEM_BAR, 0, NULL) == NULL)
+ if (Blt_CreatePen(graphPtr, interp, "activeBar", CID_ELEM_BAR, 0, NULL) !=
+ TCL_OK)
goto error;
if (Blt_CreatePageSetup(graphPtr) != TCL_OK)
diff --git a/src/bltGraph.h b/src/bltGraph.h
index 2907965..db67c88 100644
--- a/src/bltGraph.h
+++ b/src/bltGraph.h
@@ -556,8 +556,9 @@ extern Pen* Blt_BarPen(Graph* graphPtr, const char* penName);
extern Pen* Blt_LinePen(Graph* graphPtr, const char* penName);
-extern Pen* Blt_CreatePen(Graph* graphPtr, const char* penName,
- ClassId classId, int objc, Tcl_Obj* const objv[]);
+extern int Blt_CreatePen(Graph* graphPtr, Tcl_Interp* interp,
+ const char* penName, ClassId classId,
+ int objc, Tcl_Obj* const objv[]);
extern int Blt_InitLinePens(Graph *graphPtr);