graph UI refinement and various fixes. Zoom in/out keeps value under mouse fixed

This commit is contained in:
Stefan Frederik 2021-12-27 05:22:19 +01:00
parent 7a286e5466
commit 547097f176
8 changed files with 298 additions and 207 deletions

View File

@ -27,6 +27,7 @@ static int waves_selected()
int is_inside = 0;
xRect *r;
rebuild_selected_array();
if(xctx->ui_state & (STARTMOVE | STARTCOPY) ) return 0;
if(!(xctx->ui_state & SELECTION) || !xctx->lastsel) return 0;
for(i=0; i<xctx->lastsel; i++) {
c = xctx->sel_array[i].col;
@ -161,7 +162,7 @@ void start_wire(double mx, double my)
#define W_X(x) (cx * (x) + dx)
#define W_Y(y) (cy * (y) + dy)
#define G_X(x) (((x) - dx) / cx)
#define G_Y(y) (((y) - dy) / dy)
#define G_Y(y) (((y) - dy) / cy)
static int waves_callback(int event, int mx, int my, KeySym key, int button, int aux, int state)
{
double wx1 = -2e-6;
@ -179,9 +180,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
int need_redraw = 0;
double delta_threshold = 0.25;
int dataset = 0;
int left = 0;
int bottom = 0;
#if HAS_CAIRO==1
cairo_save(xctx->cairo_ctx);
cairo_save(xctx->cairo_save_ctx);
@ -190,77 +188,87 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
#endif
/* determine if mouse pointer is below xaxis or left of yaxis in some graph */
if( (event == ButtonPress || event == MotionNotify) && !(xctx->ui_state & GRAPHPAN) ) {
if(state & (Button1Mask | Button3Mask)) {
xctx->ui_state |= GRAPHPAN;
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
}
for(i=0; i<xctx->lastsel; i++) {
c = xctx->sel_array[i].col;
/* process only graph boxes */
if(xctx->sel_array[i].type == xRECT && c == 2) {
xRect *r;
n = xctx->sel_array[i].n;
r = &xctx->rect[GRIDLAYER][n];
if( POINTINSIDE(xctx->mousex_snap, xctx->mousey_snap, r->x1, r->y1, r->x2, r->y2)) {
val = get_tok_value(r->prop_ptr,"x1",0);
if(val[0]) wx1 = atof(val);
val = get_tok_value(r->prop_ptr,"y1",0);
if(val[0]) wy1 = atof(val);
val = get_tok_value(r->prop_ptr,"x2",0);
if(val[0]) wx2 = atof(val);
val = get_tok_value(r->prop_ptr,"y2",0);
if(val[0]) wy2 = atof(val);
calc_graph_area(GRIDLAYER, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
cx = (x2 - x1) / (wx2 - wx1);
dx = x1 - wx1 * cx;
cy = (y1 - y2) / (wy2 - wy1);
dy = y2 - wy1 * cy;
if(xctx->mousex_snap < W_X(wx1)) {
xctx->graph_left = 1;
} else {
xctx->graph_left = 0;
}
if(xctx->mousey_snap > W_Y(wy1)) {
xctx->graph_bottom = 1;
} else {
xctx->graph_bottom = 0;
}
xctx->graph_master = n;
break;
}
}
}
}
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x1",0);
if(val[0]) wx1 = atof(val);
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x2",0);
if(val[0]) wx2 = atof(val);
for(i=0; i<xctx->lastsel; i++) {
c = xctx->sel_array[i].col;
/* process only graph boxes */
if(xctx->sel_array[i].type == xRECT && c == 2) {
xRect *r;
n = xctx->sel_array[i].n;
r = &xctx->rect[c][n];
r = &xctx->rect[GRIDLAYER][n];
if(r->flags != 1) continue;
val = get_tok_value(r->prop_ptr,"x1",0);
if(val[0]) wx1 = atof(val);
val = get_tok_value(r->prop_ptr,"divx",0);
if(val[0]) divx = atoi(val);
val = get_tok_value(r->prop_ptr,"divy",0);
if(val[0]) divy = atoi(val);
val = get_tok_value(r->prop_ptr,"y1",0);
if(val[0]) wy1 = atof(val);
val = get_tok_value(r->prop_ptr,"x2",0);
if(val[0]) wx2 = atof(val);
val = get_tok_value(r->prop_ptr,"y2",0);
if(val[0]) wy2 = atof(val);
calc_graph_area(c, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
cx = (x2 - x1) / (wx2 - wx1);
dx = x1 - wx1 * cx;
cy = (y1 - y2) / (wy2 - wy1);
dy = y2 - wy1 * cy;
if( POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x2, r->y2)) {
if(xctx->mousex_snap < W_X(wx1)) {
left = 1;
}
if(xctx->mousey_snap > W_Y(wy1)) {
bottom = 1;
}
}
}
}
for(i=0; i<xctx->lastsel; i++) {
c = xctx->sel_array[i].col;
/* process only graph boxes */
if(xctx->sel_array[i].type == xRECT && c == 2) {
n = xctx->sel_array[i].n;
if(xctx->rect[c][n].flags != 1) continue;
val = get_tok_value(xctx->rect[c][n].prop_ptr,"divx",0);
if(val[0]) divx = atoi(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"divy",0);
if(val[0]) divy = atoi(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"y1",0);
if(val[0]) wy1 = atof(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"y2",0);
if(val[0]) wy2 = atof(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"dataset",0);
val = get_tok_value(r->prop_ptr,"dataset",0);
if(val[0]) dataset = atoi(val);
if(dataset >= xctx->datasets) dataset = xctx->datasets - 1;
/* lock x-axis to first selected when moving multiple graphs */
if(i == 0) {
val = get_tok_value(xctx->rect[c][n].prop_ptr,"x1",0);
if(val[0]) wx1 = atof(val);
val = get_tok_value(xctx->rect[c][n].prop_ptr,"x2",0);
if(val[0]) wx2 = atof(val);
}
calc_graph_area(c, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
/* lock x-axis to working graph when movint/zooming multiple graphs */
calc_graph_area(GRIDLAYER, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
/* cache coefficients for faster graph coord transformations */
cx = (x2 - x1) / (wx2 - wx1);
dx = x1 - wx1 * cx;
cy = (y1 - y2) / (wy2 - wy1);
dy = y2 - wy1 * cy;
dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divx, divy);
if(event == MotionNotify &&
(state & (Button2Mask | Button1Mask) && !(state & ShiftMask) ) &&
!(bottom || (xctx->ui_state & GRAPHPAN))) {
if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom) {
double delta;
if(left) {
if(xctx->graph_left) {
delta = (wy2 - wy1) / divy;
delta_threshold = 0.10;
delta_threshold = 0.05;
if(fabs(xctx->my_double_save - xctx->mousey_snap) > fabs(cy * delta) * delta_threshold) {
yy1 = wy1 + (xctx->my_double_save - xctx->mousey_snap) / cy;
yy2 = wy2 + (xctx->my_double_save - xctx->mousey_snap) / cy;
@ -269,15 +277,15 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
xctx->my_double_save = xctx->mousey_snap;
}
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1424, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_strdup(1424, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1425, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1425, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
need_redraw = 1;
}
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 0.10;
delta_threshold = 0.05;
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(cx * delta) * delta_threshold) {
xx1 = wx1 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
xx2 = wx2 + (xctx->mx_double_save - xctx->mousex_snap) / cx;
@ -286,180 +294,233 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
xctx->my_double_save = xctx->mousey_snap;
}
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1410, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1410, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1411, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1411, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
need_redraw = 1;
}
}
}
else if((button == Button5 && state == 0)) {
double delta;
if(left) {
if(xctx->graph_left) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 + delta * delta_threshold;
yy2 = wy2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1420, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_strdup(1420, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1421, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1421, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 - delta * delta_threshold;
xx2 = wx2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1428, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1428, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1429, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1429, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Left) {
double delta;
if(left) {
delta = (wy2 - wy1);
yy2 = wy2 + delta * 0.1;
if(xctx->graph_left) {
double m = G_Y(xctx->mousey);
double a = m - wy1;
double b = wy2 -m;
double delta = (wy2 - wy1);
double var = delta * 0.1;
yy2 = wy2 + var * b / delta;
yy1 = wy1 - var * a / delta;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1451, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1419, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1448, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 - delta * delta_threshold;
xx2 = wx2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1395, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1395, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1396, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1396, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(button == Button4 && state == 0) {
double delta;
if(left) {
if(xctx->graph_left) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 - delta * delta_threshold;
yy2 = wy2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1416, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_strdup(1416, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1417, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1417, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 + delta * delta_threshold;
xx2 = wx2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1397, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1397, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1398, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1398, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Right) {
double delta;
if(left) {
delta = (wy2 - wy1);
yy2 = wy2 - delta * 0.1;
if(xctx->graph_left) {
double m = G_Y(xctx->mousey);
double a = m - wy1;
double b = wy2 -m;
double delta = (wy2 - wy1);
double var = delta * 0.1;
yy2 = wy2 - var * b / delta;
yy1 = wy1 + var * a / delta;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1433, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1439, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1439, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1) / divx;
delta_threshold = 1.0;
xx1 = wx1 + delta * delta_threshold;
xx2 = wx2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1430, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1430, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1431, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1431, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(button == Button5 && state == ShiftMask) {
double delta;
if(left) {
delta = (wy2 - wy1);
yy2 = wy2 + delta * 0.1;
if(xctx->graph_left) {
double m = G_Y(xctx->mousey);
double a = m - wy1;
double b = wy2 -m;
double delta = (wy2 - wy1);
double var = delta * 0.1;
yy2 = wy2 + var * b / delta;
yy1 = wy1 - var * a / delta;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1447, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1432, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1436, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 + delta * 0.1;
double m = G_X(xctx->mousex);
double a = m - wx1;
double b = wx2 -m;
double delta = (wx2 - wx1);
double var = delta * 0.1;
xx2 = wx2 + var * b / delta;
xx1 = wx1 - var * a / delta;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1399, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1433, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1400, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Down) {
double delta;
if(left) {
if(xctx->graph_left) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 - delta * delta_threshold;
yy2 = wy2 - delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1434, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_strdup(1434, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1435, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1435, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 + delta * 0.1;
double m = G_X(xctx->mousex);
double a = m - wx1;
double b = wx2 -m;
double delta = (wx2 - wx1);
double var = delta * 0.1;
xx2 = wx2 + var * b / delta;
xx1 = wx1 - var * a / delta;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1418, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1399, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1432, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(button == Button4 && state == ShiftMask) {
double delta;
if(left) {
delta = (wy2 - wy1);
yy2 = wy2 - delta * 0.1;
if(xctx->graph_left) {
double m = G_Y(xctx->mousey);
double a = m - wy1;
double b = wy2 -m;
double delta = (wy2 - wy1);
double var = delta * 0.1;
yy2 = wy2 - var * b / delta;
yy1 = wy1 + var * a / delta;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1419, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1418, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1444, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 - delta * 0.1;
double m = G_X(xctx->mousex);
double a = m - wx1;
double b = wx2 -m;
double delta = (wx2 - wx1);
double var = delta * 0.1;
xx2 = wx2 - var * b / delta;
xx1 = wx1 + var * a / delta;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1449, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1436, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1450, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == XK_Up) {
double delta;
if(left) {
if(xctx->graph_left) {
delta = (wy2 - wy1) / divy;
delta_threshold = 1.0;
yy1 = wy1 + delta * delta_threshold;
yy2 = wy2 + delta * delta_threshold;
my_snprintf(s, S(s), "%g", yy1);
my_strdup(1437, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_strdup(1437, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", yy2);
my_strdup(1438, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1438, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
} else {
delta = (wx2 - wx1);
xx2 = wx2 - delta * 0.1;
double m = G_X(xctx->mousex);
double a = m - wx1;
double b = wx2 -m;
double delta = (wx2 - wx1);
double var = delta * 0.1;
xx2 = wx2 - var * b / delta;
xx1 = wx1 + var * a / delta;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1445, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1400, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1446, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if(key == 'f') {
if(left) {
if(xctx->graph_left) {
if(xctx->values) {
int i, j;
double v;
double min=0.0, max=0.0;
int first = 1;
char *saven, *nptr, *ntok, *node = NULL;;
my_strdup2(1426, &node, get_tok_value(xctx->rect[c][n].prop_ptr,"node",0));
my_strdup2(1426, &node, get_tok_value(r->prop_ptr,"node",0));
nptr = node;
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
nptr = NULL;
@ -477,63 +538,56 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
max = ceil_to_n_digits(max, 2);
my_free(1427, &node);
my_snprintf(s, S(s), "%g", min);
my_strdup(1422, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y1", s));
my_strdup(1422, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
my_snprintf(s, S(s), "%g", max);
my_strdup(1423, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "y2", s));
my_strdup(1423, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
}
} else {
xx1 = 0; /* <<<< get_raw_value(dataset, 0, 0); */
xx1 = get_raw_value(dataset, 0, 0);
xx2 = get_raw_value(dataset, 0, xctx->npoints[dataset] -1);
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1409, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1409, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1412, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1412, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
}
need_redraw = 1;
}
else if( ( ( event == ButtonPress && (button == Button1)) ||
( event == MotionNotify && (state & Button1Mask)) ) &&
(bottom || (xctx->ui_state & GRAPHPAN)) ) {
else if( event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
double wwx1, wwx2, p, delta, ccx, ddx;
xctx->ui_state |= GRAPHPAN;
delta = wx2 - wx1;
wwx1 = 0; /* <<<< */
wwx1 = get_raw_value(dataset, 0, 0);
wwx2 = get_raw_value(dataset, 0, xctx->npoints[dataset] - 1);
ccx = (x2 - x1) / (wwx2 - wwx1);
ddx = x1 - wwx1 * cx;
ddx = x1 - wwx1 * ccx;
p = (xctx->mousex_snap - ddx) / ccx;
xx1 = p - delta / 2.0;
xx2 = p + delta / 2.0;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1442, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1442, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1443, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1443, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
need_redraw = 1;
}
else if(!(state & ShiftMask) && event == ButtonPress &&
(button == Button2 || button == Button1 || button == Button3)) {
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
}
else if(event == ButtonRelease && (xctx->ui_state & GRAPHPAN) ) {
else if(event == ButtonRelease && button != Button3) {
xctx->ui_state &= ~GRAPHPAN;
}
else if(!(state & ShiftMask) && event == ButtonRelease && button == Button3) {
else if(event == ButtonRelease && button == Button3) {
double tmp;
xctx->ui_state &= ~GRAPHPAN;
xx1 = G_X(xctx->mx_double_save);
xx2 = G_X(xctx->mousex_snap);
if(xx2 < xx1) { tmp = xx1; xx2 = xx1; xx1 = tmp; }
if(xx2 < xx1) { tmp = xx1; xx1 = xx2; xx2 = tmp; }
if(xx1 == xx2) xx2 += 1e-6;
my_snprintf(s, S(s), "%g", xx1);
my_strdup(1440, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x1", s));
my_strdup(1440, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
my_snprintf(s, S(s), "%g", xx2);
my_strdup(1441, &xctx->rect[c][n].prop_ptr, subst_token(xctx->rect[c][n].prop_ptr, "x2", s));
my_strdup(1441, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
need_redraw = 1;
}
}
if(need_redraw) draw_graph(c, n, 1); /* draw data in each graph box */
}
} /* if(xctx->sel_array[i].type == xRECT && c == 2) */
if(need_redraw) draw_graph(GRIDLAYER, n, 1); /* draw data in each graph box */
} /* for(i=0; i<xctx->lastsel; i++) */
draw_selection(xctx->gc[SELLAYER], 0);
#if HAS_CAIRO==1
cairo_restore(xctx->cairo_ctx);
@ -1913,11 +1967,11 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
}
break;
case ButtonPress: /* end operation */
dbg(1, "callback(): ButtonPress ui_state=%ld state=%d\n",xctx->ui_state,state);
if(waves_selected()) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
dbg(1, "callback(): ButtonPress ui_state=%ld state=%d\n",xctx->ui_state,state);
if(xctx->ui_state & STARTPAN2) {
xctx->ui_state &=~STARTPAN2;
xctx->mx_save = mx; xctx->my_save = my;
@ -2109,10 +2163,6 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
}
else if(button==Button2 && (state == 0)) {
if(waves_selected()) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
pan2(START, mx, my);
xctx->ui_state |= STARTPAN2;
}
@ -2126,10 +2176,6 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
}
else if(button==Button1)
{
if(waves_selected()) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
if(tclgetboolvar("persistent_command") && xctx->last_command) {
if(xctx->last_command == STARTLINE) start_line(mx, my);
if(xctx->last_command == STARTWIRE) start_wire(mx, my);
@ -2307,10 +2353,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
} /* button==Button1 */
break;
case ButtonRelease:
if(waves_selected()) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
if(waves_selected()) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
if(xctx->ui_state & STARTPAN2) {
xctx->ui_state &=~STARTPAN2;
xctx->mx_save = mx; xctx->my_save = my;

View File

@ -1655,8 +1655,10 @@ int read_rawfile(const char *f)
int get_raw_index(const char *node)
{
struct int_hashentry *entry;
entry = int_hash_lookup(xctx->raw_table, node, 0, XLOOKUP);
if(entry) return entry->value;
if(xctx->values) {
entry = int_hash_lookup(xctx->raw_table, node, 0, XLOOKUP);
if(entry) return entry->value;
}
return -1;
}
@ -1664,10 +1666,13 @@ double get_raw_value(int dataset, int idx, int point)
{
int i, ofs;
ofs = 0;
for(i = 0; i < dataset; i++) {
ofs += xctx->npoints[i];
if(xctx->values) {
for(i = 0; i < dataset; i++) {
ofs += xctx->npoints[i];
}
return xctx->values[idx][ofs + point];
}
return xctx->values[idx][ofs + point];
return 0.0;
}
void calc_graph_area(int c, int i, double *x1, double *y1,double *x2,double *y2,
double *marginx, double *marginy)
@ -1681,14 +1686,14 @@ void calc_graph_area(int c, int i, double *x1, double *y1,double *x2,double *y2,
rh = (ry2 - ry1);
/* set margins */
tmp = rw * 0.05;
*marginx = tmp < 50 ? 50 : tmp;
*marginx = tmp < 80 ? 80 : tmp;
tmp = rh * 0.1;
*marginy = tmp < 20 ? 20 : tmp;
/* calculate graph bounding box (container - margin)
* This is the box where plot is done */
*x1 = rx1 + *marginx;
*x2 = rx2 - *marginx/1.3;
*x2 = rx2 - *marginx/1.8;
*y1 = ry1 + *marginy;
tmp = *marginy < 30 ? 30 : *marginy;
*y2 = ry2 - tmp; /* some more space to accomodate x-axis label */
@ -1880,7 +1885,7 @@ void draw_graph(int c, int i, int flags)
tmp = marginy / 110;
if(tmp < txtsizex) txtsizex = tmp;
txtsizelab = marginy / 100;
txtsizelab = marginy / 110;
/* background */
filledrect(0, NOW, rx1, ry1, rx2, ry2);
@ -1904,7 +1909,7 @@ void draw_graph(int c, int i, int flags)
drawline(2, ADD, W_X(wx), W_Y(wy2), W_X(wx), W_Y(wy1), dash_sizey);
drawline(2, ADD, W_X(wx), W_Y(wy1), W_X(wx), W_Y(wy1) + 4, 0); /* axis marks */
/* X-axis labels */
my_snprintf(lab, S(lab), "%.4g", wx * unitx);
my_snprintf(lab, S(lab), "%g", wx * unitx);
draw_string(3, NOW, lab, 0, 0, 1, 0, W_X(wx), y2 + 30 * txtsizex, txtsizex, txtsizex);
}
/* first and last vertical box delimiters */
@ -1926,7 +1931,7 @@ void draw_graph(int c, int i, int flags)
drawline(2, ADD, W_X(wx1), W_Y(wy), W_X(wx2), W_Y(wy), dash_sizex);
drawline(2, ADD, W_X(wx1)-4, W_Y(wy), W_X(wx1), W_Y(wy), 0); /* axis marks */
/* Y-axis labels */
my_snprintf(lab, S(lab), "%.4g", wy * unity);
my_snprintf(lab, S(lab), "%g", wy * unity);
draw_string(3, NOW, lab, 0, 1, 0, 1, x1 - 2 - 30 * txtsizey, W_Y(wy), txtsizey, txtsizey);
}
/* first and last horizontal box delimiters */
@ -1955,10 +1960,13 @@ void draw_graph(int c, int i, int flags)
if(ctok && ctok[0]) wave_color = atoi(ctok);
if(stok && stok[0]) {
sweep_idx = get_raw_index(stok);
if( sweep_idx == -1) sweep_idx = 0;
if( sweep_idx == -1) {
sweep_idx = 0;
}
}
/* draw sweep variable(s) on x-axis */
if(wcnt == 0 || (stok && stok[0])) {
if(xctx->values) stok = xctx->names[sweep_idx];
if(unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", stok ? stok : "" , unitx_suffix);
else my_snprintf(tmpstr, S(tmpstr), "%s", stok ? stok : "");
draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0,

View File

@ -391,7 +391,7 @@ void set_inst_prop(int i)
}
}
void edit_rect_property(void)
static void edit_rect_property(int x)
{
int i, c, n;
int drw = 0;
@ -405,7 +405,14 @@ void edit_rect_property(void)
tclsetvar("retval","");
}
tcleval("text_line {Input property:} 0 normal");
if(x==0) tcleval("text_line {Input property:} normal");
else if(x==2) tcleval("viewdata $::retval");
else if(x==1) tcleval("edit_vi_prop {Text:}");
else {
fprintf(errfp, "edit_rect_property() : unknown parameter x=%d\n",x); exit(EXIT_FAILURE);
}
preserve = atoi(tclgetvar("preserve_unchanged_attrs"));
if(strcmp(tclgetvar("rcode"),"") )
{
@ -455,7 +462,7 @@ void edit_rect_property(void)
}
void edit_line_property(void)
static void edit_line_property(void)
{
int i, c, n;
const char *dash;
@ -508,7 +515,7 @@ void edit_line_property(void)
}
void edit_wire_property(void)
static void edit_wire_property(void)
{
int i;
int preserve;
@ -569,7 +576,7 @@ void edit_wire_property(void)
my_free(727, &oldprop);
}
void edit_arc_property(void)
static void edit_arc_property(void)
{
int old_fill;
double x1, y1, x2, y2;
@ -633,7 +640,7 @@ void edit_arc_property(void)
}
}
void edit_polygon_property(void)
static void edit_polygon_property(void)
{
int old_fill;
int k;
@ -704,7 +711,7 @@ void edit_polygon_property(void)
/* x=0 use text widget x=1 use vim editor */
void edit_text_property(int x)
static void edit_text_property(int x)
{
int rot, flip;
#if HAS_CAIRO==1
@ -732,7 +739,7 @@ void edit_text_property(int x)
tclsetvar("hsize",property);
if(x==0) tcleval("enter_text {text:} normal");
else if(x==2) tcleval("viewdata $::retval");
else if(x==1) tcleval("edit_vi_prop {xText:}");
else if(x==1) tcleval("edit_vi_prop {Text:}");
else {
fprintf(errfp, "edit_text_property() : unknown parameter x=%d\n",x); exit(EXIT_FAILURE);
}
@ -865,7 +872,7 @@ void edit_text_property(int x)
}
/* x=0 use text widget x=1 use vim editor */
void edit_symbol_property(int x)
static void edit_symbol_property(int x)
{
char *result=NULL;
int *ii = &xctx->edit_sym_i; /* static var */
@ -1243,7 +1250,7 @@ void edit_property(int x)
edit_arc_property();
break;
case xRECT:
edit_rect_property();
edit_rect_property(x);
break;
case WIRE:
edit_wire_property();

View File

@ -427,6 +427,9 @@ void alloc_xschem_data(const char *top_path)
xctx->nvars = 0;
xctx->npoints = NULL;
xctx->datasets = 0;
xctx->graph_master = 0;
xctx->graph_bottom = 0;
xctx->graph_left = 0;
xctx->raw_schname = NULL;
xctx->wires = 0;
xctx->instances = 0;

View File

@ -697,6 +697,9 @@ typedef struct {
int nvars;
int *npoints;
int datasets;
int graph_master; /* graph where mouse operations are started, used to lock x-axis */
int graph_bottom; /* graph where mouse operations are started, used to lock x-axis */
int graph_left; /* graph where mouse operations are started, used to lock x-axis */
struct int_hashentry **raw_table;
char *raw_schname;
/* */

View File

@ -17,9 +17,9 @@
## allows to see differences in number of function calls / time spent.
## move schematic and redraw in a loop.
proc draw_test {{filelist {-}}} {
proc draw_test {{filelist {-}} {hide_graphs 0}} {
global show_pin_net_names hide_empty_graphs
set hide_empty_graphs 1
set hide_empty_graphs $hide_graphs
set show_pin_net_names 1
foreach f $filelist {
if { $f ne {-}} {

View File

@ -4,12 +4,27 @@ K {}
V {}
S {}
E {}
B 2 1190 -650 1820 -170 {flags=1
y1=1.16665
y2=5.05705
divy=4
subdivy=1
x1=2.28845
x2=2.71533
divx=6
subdivx=1
node="v(diffout) v(plus) v(minus)"
color="7 8 10 11 12 13 14 15 16 17"
dataset=0
}
T {CMOS DIFFERENTIAL AMPLIFIER
EXAMPLE} 250 -650 0 0 0.4 0.4 {}
T {This is an example of a code block that will
be placed as a header in the netlist.
use 'place=header' attribute and set the
header text as a 'value' attribute} 720 -720 0 0 0.4 0.4 {}
T {Select one or more graphs (and no other objects)
and use arrow keys to zoom / pan waveforms} 740 -800 0 0 0.3 0.3 {}
N 30 -310 30 -280 {lab=VCC}
N 30 -310 60 -310 {lab=VCC}
N 260 -240 260 -190 {lab=GN}
@ -95,9 +110,11 @@ value=".temp 30
.save all @m4[gm] @m5[gm] @m1[gm]
.control
save all
set appendwrite
op
write cmos_example.raw
* tran 1n 300n
* dc vvcc 0 5 0.01
dc vplus 2.3 2.7 0.001
write cmos_example.raw
.endc
@ -121,3 +138,10 @@ only_toplevel=true
value="** ======================== **
** This is a netlist header **
** ======================== **"}
C {launcher.sym} 755 -835 0 0 {name=h3
descr="Select arrow and
Ctrl-Left-Click to load/unload waveforms"
tclcommand="
xschem raw_read $netlist_dir/[file tail [file rootname [xschem get current_name]]].raw
"
}

View File

@ -31,8 +31,8 @@ B 2 1860 -890 3010 -810 {flags=1
y1 = 0
y2 = 1
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="
v(ldbl[0]) v(ldbl[16]) v(ldbl[32])
v(ldbl[1]) v(ldbl[17]) v(ldbl[33])
@ -43,82 +43,82 @@ B 2 1860 -810 3010 -730 {flags=1
y1 = 0
y2 = 1.5
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="
v(ldl1x[0]) v(ldl1x[1]) v(ldl1x[2]) v(ldl1x[3])
"
color="6 7 8 9 10 11 12 13" unitx=n}
B 2 1860 -1180 3010 -970 {flags=1
y1 = 0
y2 = 2
y1 = -0.251577
y2 = 1.74839
divy = 4
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(ldcp) v(ldyms[4]) v(ldyms[5]) v(ldyms[6]) v(ldyms[7])"
color=6\\ 12\\ 13\\ 14\\ 15 unitx=n}
B 2 1860 -490 3010 -410 {flags=1
y1 = 0
y1 = -0.1
y2 = 1.6
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(ldprech)"
color=4 unitx=n subdivy=2}
B 2 1860 -410 3010 -330 {flags=1
y1 = 0
y2 = 1.5
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(lden) v(ldcp)"
color=12\\ 18 unitx=n subdivy=2}
B 2 1860 -730 3010 -570 {flags=1
y1 = 0
y2 = 1.5
y1 = -0.16335
y2 = 1.6335
divy = 3
subdivy=1
subdivx = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="
v(ldcp)
v(ldwl[0]) v(ldwl[1]) v(ldwl[2]) v(ldwl[3])
v(ldwl[4]) v(ldwl[5]) v(ldwl[6]) v(ldwl[8])
v(ldwl[7])"
color="12 15 16 17 18 19 11 7 4 8"
v(ldwl[4]) v(ldwl[5]) v(ldwl[6]) v(ldwl[16])
v(ldwl[7]) v(ldwl[8]) v(ldwl[9])"
color="12 15 16 17 18 19 20 21 11 7 4 8 9"
unitx=n
}
B 2 1860 -330 3010 -250 {flags=1
y1 = 0
y2 = 1
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(ldymsref)"
color=3 unitx=n subdivy=4}
B 2 1860 -250 3010 -170 {flags=1
y1 = 0
y2 = 1.5
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(lden)"
color=4 unitx=n subdivy=2}
B 2 1860 -170 3010 -90 {flags=1
y1 = 0
y2 = 1.5
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(lden) v(ldprech)"
color=12\\ 16 unitx=n subdivy=2}
B 2 1860 -90 3010 -10 {flags=1
y1 = 0
y2 = 1.5
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(lden) v(ldcp)"
color=12\\ 5 unitx=n subdivy=2}
B 2 1860 -570 3010 -490 {flags=1
@ -126,16 +126,16 @@ y1 = 0
y2 = 1.6
divy = 1
subdivy=2
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(ldl1x[1])"
color=4 unitx=n}
B 2 1860 -970 3010 -890 {flags=1
y1 = 0
y2 = 1.5
divy = 1
x1=1.25369e-07
x2=2.02265e-07 divx=10
x1=1.5111e-07
x2=3.58736e-07 divx=10
node="v(lden) v(ldprech)"
color=4\\ 6 unitx=n}
B 7 950 -250 980 -80 {}