Enhanced the histogram example with some basic mouse interaction.
This commit is contained in:
parent
2b4ba6ad16
commit
10cba66bbf
|
@ -9,12 +9,14 @@ uiWindow *mainwin;
|
||||||
uiArea *histogram;
|
uiArea *histogram;
|
||||||
uiAreaHandler handler;
|
uiAreaHandler handler;
|
||||||
uiSpinbox *datapoints[10];
|
uiSpinbox *datapoints[10];
|
||||||
|
int currentPoint = -1;
|
||||||
|
|
||||||
// some metrics
|
// some metrics
|
||||||
#define xoffLeft 20 /* histogram margins */
|
#define xoffLeft 20 /* histogram margins */
|
||||||
#define yoffTop 20
|
#define yoffTop 20
|
||||||
#define xoffRight 20
|
#define xoffRight 20
|
||||||
#define yoffBottom 20
|
#define yoffBottom 20
|
||||||
|
#define pointRadius 5
|
||||||
|
|
||||||
// helper to quickly set a brush color
|
// helper to quickly set a brush color
|
||||||
static void setSolidBrush(uiDrawBrush *brush, uint32_t color, double alpha)
|
static void setSolidBrush(uiDrawBrush *brush, uint32_t color, double alpha)
|
||||||
|
@ -37,30 +39,37 @@ static void setSolidBrush(uiDrawBrush *brush, uint32_t color, double alpha)
|
||||||
#define colorBlack 0x000000
|
#define colorBlack 0x000000
|
||||||
#define colorDodgerBlue 0x1E90FF
|
#define colorDodgerBlue 0x1E90FF
|
||||||
|
|
||||||
static uiDrawPath *constructGraph(double width, double height, int extend)
|
static void pointLocations(double width, double height, double *xs, double *ys)
|
||||||
{
|
{
|
||||||
uiDrawPath *path;
|
|
||||||
double xincr, yincr;
|
double xincr, yincr;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
path = uiDrawNewPath(uiDrawFillModeWinding);
|
|
||||||
|
|
||||||
xincr = width / 9; // 10 - 1 to make the last point be at the end
|
xincr = width / 9; // 10 - 1 to make the last point be at the end
|
||||||
yincr = height / 100;
|
yincr = height / 100;
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
// get the value of the point
|
// get the value of the point
|
||||||
n = uiSpinboxValue(datapoints[i]);
|
n = uiSpinboxValue(datapoints[i]);
|
||||||
// because y=0 is the top but n=0 is the bottom, we need to flip
|
// because y=0 is the top but n=0 is the bottom, we need to flip
|
||||||
n = 100 - n;
|
n = 100 - n;
|
||||||
if (i == 0)
|
xs[i] = xincr * i;
|
||||||
uiDrawPathNewFigure(path,
|
ys[i] = yincr * n;
|
||||||
xincr * i,
|
|
||||||
yincr * n);
|
|
||||||
else
|
|
||||||
uiDrawPathLineTo(path,
|
|
||||||
xincr * i,
|
|
||||||
yincr * n);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uiDrawPath *constructGraph(double width, double height, int extend)
|
||||||
|
{
|
||||||
|
uiDrawPath *path;
|
||||||
|
double xs[10], ys[10];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pointLocations(width, height, xs, ys);
|
||||||
|
|
||||||
|
path = uiDrawNewPath(uiDrawFillModeWinding);
|
||||||
|
|
||||||
|
uiDrawPathNewFigure(path, xs[0], ys[0]);
|
||||||
|
for (i = 1; i < 10; i++)
|
||||||
|
uiDrawPathLineTo(path, xs[i], ys[i]);
|
||||||
|
|
||||||
if (extend) {
|
if (extend) {
|
||||||
uiDrawPathLineTo(path, width, height);
|
uiDrawPathLineTo(path, width, height);
|
||||||
|
@ -72,6 +81,12 @@ static uiDrawPath *constructGraph(double width, double height, int extend)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void graphSize(double clientWidth, double clientHeight, double *graphWidth, double *graphHeight)
|
||||||
|
{
|
||||||
|
*graphWidth = clientWidth - xoffLeft - xoffRight;
|
||||||
|
*graphHeight = clientHeight - yoffTop - yoffBottom;
|
||||||
|
}
|
||||||
|
|
||||||
static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
|
static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
|
||||||
{
|
{
|
||||||
uiDrawPath *path;
|
uiDrawPath *path;
|
||||||
|
@ -89,8 +104,7 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
|
||||||
uiDrawFreePath(path);
|
uiDrawFreePath(path);
|
||||||
|
|
||||||
// figure out dimensions
|
// figure out dimensions
|
||||||
graphWidth = p->ClientWidth - xoffLeft - xoffRight;
|
graphSize(p->ClientWidth, p->ClientHeight, &graphWidth, &graphHeight);
|
||||||
graphHeight = p->ClientHeight - yoffTop - yoffBottom;
|
|
||||||
|
|
||||||
// make a stroke for both the axes and the histogram line
|
// make a stroke for both the axes and the histogram line
|
||||||
sp.Cap = uiDrawLineCapFlat;
|
sp.Cap = uiDrawLineCapFlat;
|
||||||
|
@ -127,6 +141,23 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
|
||||||
setSolidBrush(&brush, colorDodgerBlue, 1.0);
|
setSolidBrush(&brush, colorDodgerBlue, 1.0);
|
||||||
uiDrawStroke(p->Context, path, &brush, &sp);
|
uiDrawStroke(p->Context, path, &brush, &sp);
|
||||||
uiDrawFreePath(path);
|
uiDrawFreePath(path);
|
||||||
|
|
||||||
|
// now draw the point being hovered over
|
||||||
|
if (currentPoint != -1) {
|
||||||
|
double xs[10], ys[10];
|
||||||
|
|
||||||
|
pointLocations(graphWidth, graphHeight, xs, ys);
|
||||||
|
path = uiDrawNewPath(uiDrawFillModeWinding);
|
||||||
|
uiDrawPathNewFigureWithArc(path,
|
||||||
|
xs[currentPoint], ys[currentPoint],
|
||||||
|
pointRadius,
|
||||||
|
0, 6.23, // TODO pi
|
||||||
|
0);
|
||||||
|
uiDrawPathEnd(path);
|
||||||
|
// use the same brush as for the histogram lines
|
||||||
|
uiDrawFill(p->Context, path, &brush);
|
||||||
|
uiDrawFreePath(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintmax_t handlerHScrollMax(uiAreaHandler *a, uiArea *area)
|
static uintmax_t handlerHScrollMax(uiAreaHandler *a, uiArea *area)
|
||||||
|
@ -147,9 +178,35 @@ static int handlerRedrawOnResize(uiAreaHandler *a, uiArea *area)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int inPoint(double x, double y, double xtest, double ytest)
|
||||||
|
{
|
||||||
|
// TODO switch to using a matrix
|
||||||
|
x -= xoffLeft;
|
||||||
|
y -= yoffTop;
|
||||||
|
return (x >= xtest - pointRadius) &&
|
||||||
|
(x <= xtest + pointRadius) &&
|
||||||
|
(y >= ytest - pointRadius) &&
|
||||||
|
(y <= ytest + pointRadius);
|
||||||
|
}
|
||||||
|
|
||||||
static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e)
|
static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e)
|
||||||
{
|
{
|
||||||
// do nothing
|
double graphWidth, graphHeight;
|
||||||
|
double xs[10], ys[10];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
graphSize(e->ClientWidth, e->ClientHeight, &graphWidth, &graphHeight);
|
||||||
|
pointLocations(graphWidth, graphHeight, xs, ys);
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
if (inPoint(e->X, e->Y, xs[i], ys[i]))
|
||||||
|
break;
|
||||||
|
if (i == 10) // not in a point
|
||||||
|
i = -1;
|
||||||
|
|
||||||
|
currentPoint = i;
|
||||||
|
// TODO only redraw the relevant area
|
||||||
|
uiAreaQueueRedrawAll(histogram);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handlerDragBroken(uiAreaHandler *ah, uiArea *a)
|
static void handlerDragBroken(uiAreaHandler *ah, uiArea *a)
|
||||||
|
|
Loading…
Reference in New Issue