diff --git a/src/callback.c b/src/callback.c index e7415224..c403c4a3 100644 --- a/src/callback.c +++ b/src/callback.c @@ -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; ilastsel; 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; ilastsel; 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; ilastsel; 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; ilastsel; 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; ilastsel; 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; diff --git a/src/draw.c b/src/draw.c index dee6d562..5c6bee7c 100644 --- a/src/draw.c +++ b/src/draw.c @@ -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, diff --git a/src/editprop.c b/src/editprop.c index 992a829c..22a052b7 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -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(); diff --git a/src/xinit.c b/src/xinit.c index 0779438b..5e28ffdb 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -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; diff --git a/src/xschem.h b/src/xschem.h index 9caae970..462fcee4 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -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; /* */ diff --git a/tests/xschemtest.tcl b/tests/xschemtest.tcl index 9f92da74..1497f204 100644 --- a/tests/xschemtest.tcl +++ b/tests/xschemtest.tcl @@ -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 {-}} { diff --git a/xschem_library/examples/cmos_example.sch b/xschem_library/examples/cmos_example.sch index 2ca76242..433a4f73 100644 --- a/xschem_library/examples/cmos_example.sch +++ b/xschem_library/examples/cmos_example.sch @@ -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 +" +} diff --git a/xschem_library/rom8k/rom8k.sch b/xschem_library/rom8k/rom8k.sch index 5b246818..d9ff52cd 100644 --- a/xschem_library/rom8k/rom8k.sch +++ b/xschem_library/rom8k/rom8k.sch @@ -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 {}