summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bltGrAxis.C14
-rw-r--r--src/bltGrLegd.C202
-rw-r--r--src/bltGrLegd.h21
-rw-r--r--src/bltGrLegdOp.C3
-rw-r--r--src/bltGraph.C78
-rw-r--r--tests/legend.tcl7
6 files changed, 141 insertions, 184 deletions
diff --git a/src/bltGrAxis.C b/src/bltGrAxis.C
index 3259762..185c320 100644
--- a/src/bltGrAxis.C
+++ b/src/bltGrAxis.C
@@ -3058,21 +3058,21 @@ void Blt_LayoutGraph(Graph* graphPtr)
* Step 2: Add the legend to the appropiate margin.
*/
if (!graphPtr->legend->isHidden()) {
- switch (graphPtr->legend->site()) {
- case LEGEND_RIGHT:
+ switch (graphPtr->legend->position()) {
+ case Legend::RIGHT:
right += graphPtr->legend->width() + 2;
break;
- case LEGEND_LEFT:
+ case Legend::LEFT:
left += graphPtr->legend->width() + 2;
break;
- case LEGEND_TOP:
+ case Legend::TOP:
top += graphPtr->legend->height() + 2;
break;
- case LEGEND_BOTTOM:
+ case Legend::BOTTOM:
bottom += graphPtr->legend->height() + 2;
break;
- case LEGEND_XY:
- case LEGEND_PLOT:
+ case Legend::XY:
+ case Legend::PLOT:
/* Do nothing. */
break;
}
diff --git a/src/bltGrLegd.C b/src/bltGrLegd.C
index 4fd2cb1..1e69eed 100644
--- a/src/bltGrLegd.C
+++ b/src/bltGrLegd.C
@@ -52,106 +52,13 @@ static Blt_BindPickProc PickEntryProc;
// OptionSpecs
-static const char* selectmodeObjOption[] = {"single", "multiple", NULL};
-
-static Tk_CustomOptionSetProc PositionSetProc;
-static Tk_CustomOptionGetProc PositionGetProc;
-Tk_ObjCustomOption positionObjOption =
- {
- "position", PositionSetProc, PositionGetProc, NULL, NULL, NULL
- };
-
-static int PositionSetProc(ClientData clientData, Tcl_Interp* interp,
- Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
- int offset, char* save, int flags)
-{
- LegendOptions* ops = (LegendOptions*)widgRec;
- Legend* legendPtr = ops->legendPtr;
-
- int length;
- const char* string = Tcl_GetStringFromObj(*objPtr, &length);
- char c;
- c = string[0];
- if (c == '\0')
- legendPtr->site_ = LEGEND_RIGHT;
- else if ((c == 'l') && (strncmp(string, "leftmargin", length) == 0))
- legendPtr->site_ = LEGEND_LEFT;
- else if ((c == 'r') && (strncmp(string, "rightmargin", length) == 0))
- legendPtr->site_ = LEGEND_RIGHT;
- else if ((c == 't') && (strncmp(string, "topmargin", length) == 0))
- legendPtr->site_ = LEGEND_TOP;
- else if ((c == 'b') && (strncmp(string, "bottommargin", length) == 0))
- legendPtr->site_ = LEGEND_BOTTOM;
- else if ((c == 'p') && (strncmp(string, "plotarea", length) == 0))
- legendPtr->site_ = LEGEND_PLOT;
- else if (c == '@') {
- char *comma;
- long x, y;
- int result;
-
- comma = (char*)strchr(string + 1, ',');
- if (comma == NULL) {
- Tcl_AppendResult(interp, "bad screen position \"", string,
- "\": should be @x,y", (char *)NULL);
- return TCL_ERROR;
- }
- x = y = 0;
- *comma = '\0';
- result = ((Tcl_ExprLong(interp, string + 1, &x) == TCL_OK) &&
- (Tcl_ExprLong(interp, comma + 1, &y) == TCL_OK));
- *comma = ',';
- if (!result) {
- return TCL_ERROR;
- }
- legendPtr->xReq_ = x;
- legendPtr->yReq_ = y;
- legendPtr->site_ = LEGEND_XY;
- }
- else {
- Tcl_AppendResult(interp, "bad position \"", string, "\": should be \
-\"leftmargin\", \"rightmargin\", \"topmargin\", \"bottommargin\", \
-\"plotarea\", or @x,y", (char *)NULL);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-static Tcl_Obj* PositionGetProc(ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset)
-{
- LegendOptions* ops = (LegendOptions*)widgRec;
- Legend* legendPtr = ops->legendPtr;
-
- Tcl_Obj *objPtr;
-
- switch (legendPtr->site_) {
- case LEGEND_LEFT:
- objPtr = Tcl_NewStringObj("leftmargin", -1);
- break;
- case LEGEND_RIGHT:
- objPtr = Tcl_NewStringObj("rightmargin", -1);
- break;
- case LEGEND_TOP:
- objPtr = Tcl_NewStringObj("topmargin", -1);
- break;
- case LEGEND_BOTTOM:
- objPtr = Tcl_NewStringObj("bottommargin", -1);
- break;
- case LEGEND_PLOT:
- objPtr = Tcl_NewStringObj("plotarea", -1);
- break;
- case LEGEND_XY:
- {
- char string[200];
-
- sprintf_s(string, 200, "@%d,%d", legendPtr->xReq_, legendPtr->yReq_);
- objPtr = Tcl_NewStringObj(string, -1);
- }
- default:
- objPtr = Tcl_NewStringObj("unknown legend position", -1);
- }
- return objPtr;
-}
+static const char* selectmodeObjOption[] = {
+ "single", "multiple", NULL
+};
+static const char* positionObjOption[] = {
+ "rightmargin", "leftmargin", "topmargin", "bottommargin",
+ "plotarea", "xy", NULL
+};
static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_BORDER, "-activebackground", "activeBackground",
@@ -205,8 +112,9 @@ static Tk_OptionSpec optionSpecs[] = {
"1", -1, Tk_Offset(LegendOptions, xPad), 0, NULL, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
"1", -1, Tk_Offset(LegendOptions, yPad), 0, NULL, 0},
- {TK_OPTION_CUSTOM, "-position", "position", "Position",
- "rightmargin", -1, 0, 0, &positionObjOption, 0},
+ {TK_OPTION_STRING_TABLE, "-position", "position", "Position",
+ "rightmargin", -1, Tk_Offset(LegendOptions, position),
+ 0, &positionObjOption, 0},
{TK_OPTION_BOOLEAN, "-raised", "raised", "Raised",
"no", -1, Tk_Offset(LegendOptions, raised), 0, NULL, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
@@ -239,6 +147,10 @@ static Tk_OptionSpec optionSpecs[] = {
0, NULL, 0},
{TK_OPTION_FONT, "-titlefont", "titleFont", "TitleFont",
STD_FONT_SMALL, -1, Tk_Offset(LegendOptions, titleStyle.font), 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-x", "x", "X",
+ "0", -1, Tk_Offset(LegendOptions, xReq), 0, NULL, 0},
+ {TK_OPTION_PIXELS, "-y", "y", "Y",
+ "0", -1, Tk_Offset(LegendOptions, yReq), 0, NULL, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
};
@@ -259,9 +171,6 @@ Legend::Legend(Graph* graphPtr)
height_ =0;
entryWidth_ =0;
entryHeight_ =0;
- site_ =0;
- xReq_ = -SHRT_MAX;
- yReq_ = -SHRT_MAX;
x_ =0;
y_ =0;
maxSymSize_ =0;
@@ -434,13 +343,13 @@ void Legend::map(int plotWidth, int plotHeight)
if (nRows > nEntries) {
nRows = nEntries;
}
- switch (site_) {
- case LEGEND_TOP:
- case LEGEND_BOTTOM:
+ switch ((Position)ops->position) {
+ case TOP:
+ case BOTTOM:
nRows = ((nEntries - 1) / nColumns) + 1;
break;
- case LEGEND_LEFT:
- case LEGEND_RIGHT:
+ case LEFT:
+ case RIGHT:
default:
nColumns = ((nEntries - 1) / nRows) + 1;
break;
@@ -508,23 +417,30 @@ void Legend::draw(Drawable drawable)
if (ops->normalBg)
Tk_Fill3DRectangle(tkwin, pixmap, ops->normalBg, 0, 0,
w, h, 0, TK_RELIEF_FLAT);
-
- else if (site_ & LEGEND_PLOTAREA_MASK) {
- // Legend background is transparent and is positioned over the the
- // plot area. Either copy the part of the background from the backing
- // store pixmap or (if no backing store exists) just fill it with the
- // background color of the plot.
- if (graphPtr_->cache != None)
- XCopyArea(graphPtr_->display, graphPtr_->cache, pixmap,
- graphPtr_->drawGC, x_, y_, w, h, 0, 0);
- else
- Tk_Fill3DRectangle(tkwin, pixmap, graphPtr_->plotBg, 0, 0,
- w, h, TK_RELIEF_FLAT, 0);
+ else {
+ switch ((Position)ops->position) {
+ case TOP:
+ case BOTTOM:
+ case RIGHT:
+ case LEFT:
+ Tk_Fill3DRectangle(tkwin, pixmap, graphPtr_->normalBg, 0, 0,
+ w, h, 0, TK_RELIEF_FLAT);
+ break;
+ case PLOT:
+ case XY:
+ // Legend background is transparent and is positioned over the the
+ // plot area. Either copy the part of the background from the backing
+ // store pixmap or (if no backing store exists) just fill it with the
+ // background color of the plot.
+ if (graphPtr_->cache != None)
+ XCopyArea(graphPtr_->display, graphPtr_->cache, pixmap,
+ graphPtr_->drawGC, x_, y_, w, h, 0, 0);
+ else
+ Tk_Fill3DRectangle(tkwin, pixmap, graphPtr_->plotBg, 0, 0,
+ w, h, TK_RELIEF_FLAT, 0);
+ break;
+ };
}
- else
- // The legend is located in one of the margins
- Tk_Fill3DRectangle(tkwin, pixmap, graphPtr_->normalBg, 0, 0,
- w, h, 0, TK_RELIEF_FLAT);
Tk_FontMetrics fontMetrics;
Tk_GetFontMetrics(ops->style.font, &fontMetrics);
@@ -610,16 +526,28 @@ void Legend::draw(Drawable drawable)
bg = graphPtr_->normalBg;
// Disable crosshairs before redisplaying to the screen
- if (site_ & LEGEND_PLOTAREA_MASK)
+ switch ((Position)ops->position) {
+ case PLOT:
+ case XY:
Blt_DisableCrosshairs(graphPtr_);
+ break;
+ default:
+ break;
+ }
Tk_Draw3DRectangle(tkwin, pixmap, bg, 0, 0, w, h,
ops->borderWidth, ops->relief);
XCopyArea(graphPtr_->display, pixmap, drawable, graphPtr_->drawGC, 0, 0, w, h,
x_, y_);
- if (site_ & LEGEND_PLOTAREA_MASK)
+ switch ((Position)ops->position) {
+ case PLOT:
+ case XY:
Blt_EnableCrosshairs(graphPtr_);
+ break;
+ default:
+ break;
+ }
Tk_FreePixmap(graphPtr_->display, pixmap);
graphPtr_->flags &= ~DRAW_LEGEND;
@@ -736,22 +664,22 @@ void Legend::setOrigin()
int y =0;
int w =0;
int h =0;
- switch (site_) {
- case LEGEND_RIGHT:
+ switch ((Position)ops->position) {
+ case RIGHT:
w = graphPtr_->rightMargin.width - graphPtr_->rightMargin.axesOffset;
h = graphPtr_->bottom - graphPtr_->top;
x = graphPtr_->right + graphPtr_->rightMargin.axesOffset;
y = graphPtr_->top;
break;
- case LEGEND_LEFT:
+ case LEFT:
w = graphPtr_->leftMargin.width - graphPtr_->leftMargin.axesOffset;
h = graphPtr_->bottom - graphPtr_->top;
x = graphPtr_->inset;
y = graphPtr_->top;
break;
- case LEGEND_TOP:
+ case TOP:
w = graphPtr_->right - graphPtr_->left;
h = graphPtr_->topMargin.height - graphPtr_->topMargin.axesOffset;
if (graphPtr_->title)
@@ -763,25 +691,25 @@ void Legend::setOrigin()
y += graphPtr_->titleHeight;
break;
- case LEGEND_BOTTOM:
+ case BOTTOM:
w = graphPtr_->right - graphPtr_->left;
h = graphPtr_->bottomMargin.height - graphPtr_->bottomMargin.axesOffset;
x = graphPtr_->left;
y = graphPtr_->bottom + graphPtr_->bottomMargin.axesOffset;
break;
- case LEGEND_PLOT:
+ case PLOT:
w = graphPtr_->right - graphPtr_->left;
h = graphPtr_->bottom - graphPtr_->top;
x = graphPtr_->left;
y = graphPtr_->top;
break;
- case LEGEND_XY:
+ case XY:
w = width_;
h = height_;
- x = xReq_;
- y = yReq_;
+ x = ops->xReq;
+ y = ops->yReq;
if (x < 0)
x += graphPtr_->width;
diff --git a/src/bltGrLegd.h b/src/bltGrLegd.h
index 120755b..1ae60b4 100644
--- a/src/bltGrLegd.h
+++ b/src/bltGrLegd.h
@@ -42,15 +42,6 @@ extern "C" {
#include "bltGraph.h"
};
-#define LEGEND_RIGHT (1<<0) // Right margin
-#define LEGEND_LEFT (1<<1) // Left margin
-#define LEGEND_BOTTOM (1<<2) // Bottom margin
-#define LEGEND_TOP (1<<3) // Top margin, below the graph title
-#define LEGEND_PLOT (1<<4) // Plot area
-#define LEGEND_XY (1<<5) // Screen coordinates in the plotting area
-#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.
@@ -98,6 +89,9 @@ typedef struct {
int reqRows;
int entryBW;
int selBW;
+ int xReq;
+ int yReq;
+ int position;
const char *selectCmd;
Tk_3DBorder selOutFocusBg;
Tk_3DBorder selInFocusBg;
@@ -112,10 +106,14 @@ typedef struct {
class Legend {
public:
+ enum Position {RIGHT, LEFT, TOP, BOTTOM, PLOT, XY};
+
+ public:
Graph* graphPtr_;
Tk_OptionTable optionTable_;
void* ops_;
+
int nEntries_;
int nColumns_;
int nRows_;
@@ -123,9 +121,6 @@ class Legend {
int height_;
int entryWidth_;
int entryHeight_;
- int site_;
- int xReq_;
- int yReq_;
int x_;
int y_;
int maxSymSize_;
@@ -174,7 +169,6 @@ class Legend {
int width() {return width_;}
int height() {return height_;}
- int site() {return site_;}
int x() {return x_;}
int y() {return y_;}
@@ -185,6 +179,7 @@ class Legend {
void clearSelection();
int entryIsSelected(Element*);
+ Position position() {return (Position)((LegendOptions*)ops_)->position;}
int isRaised() {return ((LegendOptions*)ops_)->raised;}
int isHidden() {return ((LegendOptions*)ops_)->hide;}
};
diff --git a/src/bltGrLegdOp.C b/src/bltGrLegdOp.C
index da78537..ea56cd9 100644
--- a/src/bltGrLegdOp.C
+++ b/src/bltGrLegdOp.C
@@ -269,8 +269,7 @@ static int FocusOp(Graph* graphPtr, Tcl_Interp* interp,
legendPtr->focusPtr_ = elemPtr;
}
- Blt_SetFocusItem(legendPtr->bindTable_, legendPtr->focusPtr_,
- CID_LEGEND_ENTRY);
+ Blt_SetFocusItem(legendPtr->bindTable_,legendPtr->focusPtr_,CID_LEGEND_ENTRY);
graphPtr->legend->eventuallyRedraw();
if (legendPtr->focusPtr_)
diff --git a/src/bltGraph.C b/src/bltGraph.C
index 40e7556..b3cb89e 100644
--- a/src/bltGraph.C
+++ b/src/bltGraph.C
@@ -609,18 +609,27 @@ static void DisplayGraph(ClientData clientData)
XCopyArea(graphPtr->display, graphPtr->cache, drawable,
graphPtr->drawGC, 0, 0, Tk_Width(graphPtr->tkwin),
Tk_Height(graphPtr->tkwin), 0, 0);
- } else {
- DrawPlot(graphPtr, drawable);
}
- /* Draw markers above elements */
+ else
+ DrawPlot(graphPtr, drawable);
+
+ // Draw markers above elements
Blt::DrawMarkers(graphPtr, drawable, MARKER_ABOVE);
Blt_DrawActiveElements(graphPtr, drawable);
- /* Don't draw legend in the plot area. */
- if ((graphPtr->legend->site() & LEGEND_PLOTAREA_MASK) &&
- (graphPtr->legend->isRaised()))
- graphPtr->legend->draw(drawable);
- /* Draw 3D border just inside of the focus highlight ring. */
+ // Don't draw legend in the plot area.
+ if (graphPtr->legend->isRaised()) {
+ switch (graphPtr->legend->position()) {
+ case Legend::PLOT:
+ case Legend::XY:
+ graphPtr->legend->draw(drawable);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Draw 3D border just inside of the focus highlight ring
if ((graphPtr->borderWidth > 0) && (graphPtr->relief != TK_RELIEF_FLAT)) {
Tk_Draw3DRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg,
graphPtr->highlightWidth, graphPtr->highlightWidth,
@@ -1163,13 +1172,22 @@ static void DrawMargins(Graph* graphPtr, Drawable drawable)
Tk_Draw3DRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg,
x, y, w, h, graphPtr->plotBW, graphPtr->plotRelief);
}
- if (graphPtr->legend->site() & LEGEND_MARGIN_MASK)
+
+ switch (graphPtr->legend->position()) {
+ case Legend::TOP:
+ case Legend::BOTTOM:
+ case Legend::RIGHT:
+ case Legend::LEFT:
graphPtr->legend->draw(drawable);
+ break;
+ default:
+ break;
+ }
- if (graphPtr->title != NULL) {
+ if (graphPtr->title != NULL)
Blt_DrawText(graphPtr->tkwin, drawable, graphPtr->title,
&graphPtr->titleTextStyle, graphPtr->titleX, graphPtr->titleY);
- }
+
Blt_DrawAxes(graphPtr, drawable);
graphPtr->flags &= ~DRAW_MARGINS;
}
@@ -1178,7 +1196,7 @@ static void DrawPlot(Graph* graphPtr, Drawable drawable)
{
DrawMargins(graphPtr, drawable);
- /* Draw the background of the plotting area with 3D border. */
+ // Draw the background of the plotting area with 3D border
Tk_Fill3DRectangle(graphPtr->tkwin, drawable, graphPtr->plotBg,
graphPtr->left-graphPtr->plotBW,
graphPtr->top-graphPtr->plotBW,
@@ -1186,14 +1204,21 @@ static void DrawPlot(Graph* graphPtr, Drawable drawable)
graphPtr->bottom - graphPtr->top + 1 +2*graphPtr->plotBW,
graphPtr->plotBW, graphPtr->plotRelief);
- /* Draw the elements, markers, legend, and axis limits. */
+ // Draw the elements, markers, legend, and axis limits
Blt_DrawAxes(graphPtr, drawable);
Blt_DrawGrids(graphPtr, drawable);
Blt::DrawMarkers(graphPtr, drawable, MARKER_UNDER);
- if ((graphPtr->legend->site() & LEGEND_PLOTAREA_MASK) &&
- (!graphPtr->legend->isRaised()))
- graphPtr->legend->draw(drawable);
+ if (!graphPtr->legend->isRaised()) {
+ switch (graphPtr->legend->position()) {
+ case Legend::PLOT:
+ case Legend::XY:
+ graphPtr->legend->draw(drawable);
+ break;
+ default:
+ break;
+ }
+ }
Blt_DrawAxisLimits(graphPtr, drawable);
Blt_DrawElements(graphPtr, drawable);
@@ -1208,7 +1233,7 @@ void Blt_MapGraph(Graph* graphPtr)
Blt_LayoutGraph(graphPtr);
graphPtr->flags &= ~LAYOUT_NEEDED;
}
- /* Compute coordinate transformations for graph components */
+
if ((graphPtr->vRange > 1) && (graphPtr->hRange > 1)) {
if (graphPtr->flags & MAP_WORLD)
Blt_MapAxes(graphPtr);
@@ -1222,16 +1247,23 @@ void Blt_MapGraph(Graph* graphPtr)
void Blt_DrawGraph(Graph* graphPtr, Drawable drawable)
{
DrawPlot(graphPtr, drawable);
- /* Draw markers above elements */
+ // Draw markers above elements
Blt::DrawMarkers(graphPtr, drawable, MARKER_ABOVE);
Blt_DrawActiveElements(graphPtr, drawable);
- /* Don't draw legend in the plot area. */
- if ((graphPtr->legend->site() & LEGEND_PLOTAREA_MASK) &&
- (graphPtr->legend->isRaised()))
- graphPtr->legend->draw(drawable);
+ // Don't draw legend in the plot area
+ if (graphPtr->legend->isRaised()) {
+ switch (graphPtr->legend->position()) {
+ case Legend::PLOT:
+ case Legend::XY:
+ graphPtr->legend->draw(drawable);
+ break;
+ default:
+ break;
+ }
+ }
- /* Draw 3D border just inside of the focus highlight ring. */
+ // Draw 3D border just inside of the focus highlight ring
if ((graphPtr->borderWidth > 0) && (graphPtr->relief != TK_RELIEF_FLAT)) {
Tk_Draw3DRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg,
graphPtr->highlightWidth, graphPtr->highlightWidth,
diff --git a/tests/legend.tcl b/tests/legend.tcl
index 22d9e6f..13c9591 100644
--- a/tests/legend.tcl
+++ b/tests/legend.tcl
@@ -6,7 +6,7 @@ set graph [bltLineGraph $w]
$graph legend selection set data2
$graph legend focus data1
$graph legend configure -selectrelief groove
-
+return
echo "Testing Legend..."
#bltTest2 $graph legend -activebackground
@@ -32,11 +32,14 @@ bltTest2 $graph legend -ipady 20
#bltTest2 $graph legend -nofocusselectforeground
bltTest2 $graph legend -padx 20
bltTest2 $graph legend -pady 20
+bltTest2 $graph legend -position rightmargin
bltTest2 $graph legend -position leftmargin
bltTest2 $graph legend -position topmargin
bltTest2 $graph legend -position bottommargin
bltTest2 $graph legend -position plotarea
-bltTest2 $graph legend -position "@250,100"
+bltTest2 $graph legend -position xy
+bltTest2 $graph legend -x 250
+bltTest2 $graph legend -y 100
bltTest2 $graph legend -raised yes
bltTest2 $graph legend -relief groove
bltTest2 $graph legend -rows 1