2021-11-04 01:23:40 +01:00
|
|
|
/* File: callback.c
|
2020-10-12 13:13:31 +02:00
|
|
|
*
|
2020-08-08 15:47:34 +02:00
|
|
|
* This file is part of XSCHEM,
|
2020-10-12 13:13:31 +02:00
|
|
|
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
|
2020-08-08 15:47:34 +02:00
|
|
|
* simulation.
|
2021-07-27 16:42:54 +02:00
|
|
|
* Copyright (C) 1998-2021 Stefan Frederik Schippers
|
2020-08-08 15:47:34 +02:00
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "xschem.h"
|
2021-12-30 15:45:38 +01:00
|
|
|
|
|
|
|
|
static int waves_selected(int event, int key, int state, int button)
|
2021-12-22 04:39:23 +01:00
|
|
|
{
|
2021-12-30 15:45:38 +01:00
|
|
|
int i;
|
2022-01-03 18:43:34 +01:00
|
|
|
int is_inside = 0, skip = 0;
|
|
|
|
|
if(xctx->ui_state & STARTPAN2) skip = 1;
|
|
|
|
|
if(state & Mod1Mask) skip = 1;
|
|
|
|
|
if(event == MotionNotify && (state & Button2Mask)) skip = 1;
|
|
|
|
|
if(event == ButtonPress && button == Button2) skip = 1;
|
|
|
|
|
if(event == ButtonRelease && button == Button2) skip = 1;
|
|
|
|
|
if(xctx->ui_state & STARTSELECT) skip = 1;
|
2021-12-30 15:45:38 +01:00
|
|
|
|
2022-01-03 18:43:34 +01:00
|
|
|
if(!skip) for(i=0; i< xctx->rects[GRIDLAYER]; i++) {
|
2021-12-30 15:45:38 +01:00
|
|
|
xRect *r;
|
|
|
|
|
r = &xctx->rect[GRIDLAYER][i];
|
|
|
|
|
if(!(r->flags & 1) ) continue;
|
|
|
|
|
if( (xctx->ui_state & GRAPHPAN) ||
|
2022-01-02 22:24:44 +01:00
|
|
|
POINTINSIDE(xctx->mousex, xctx->mousey, r->x1 + 40, r->y1 + 20, r->x2 - 30, r->y2 - 10) ) {
|
2021-12-30 15:45:38 +01:00
|
|
|
is_inside = 1;
|
|
|
|
|
}
|
2021-12-22 04:39:23 +01:00
|
|
|
}
|
2022-01-03 18:43:34 +01:00
|
|
|
if(!is_inside && (xctx->graph_flags & 64) ) {
|
|
|
|
|
tcleval("graph_stop_measure");
|
|
|
|
|
}
|
2021-12-22 18:25:15 +01:00
|
|
|
return is_inside;
|
2021-12-22 04:39:23 +01:00
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
|
2020-12-29 03:45:12 +01:00
|
|
|
void redraw_w_a_l_r_p_rubbers(void)
|
|
|
|
|
{
|
|
|
|
|
if(xctx->ui_state & STARTWIRE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-12-29 03:45:12 +01:00
|
|
|
new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap);
|
|
|
|
|
}
|
|
|
|
|
if(xctx->ui_state & STARTARC) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-12-29 03:45:12 +01:00
|
|
|
new_arc(RUBBER, 0);
|
|
|
|
|
}
|
|
|
|
|
if(xctx->ui_state & STARTLINE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-12-29 03:45:12 +01:00
|
|
|
new_line(RUBBER);
|
|
|
|
|
}
|
|
|
|
|
if(xctx->ui_state & STARTRECT) new_rect(RUBBER);
|
|
|
|
|
if(xctx->ui_state & STARTPOLYGON) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-12-29 03:45:12 +01:00
|
|
|
new_polygon(RUBBER);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-04 02:07:41 +01:00
|
|
|
void abort_operation(void)
|
|
|
|
|
{
|
|
|
|
|
xctx->no_draw = 0;
|
|
|
|
|
tcleval("set constrained_move 0" );
|
|
|
|
|
constrained_move=0;
|
|
|
|
|
xctx->last_command=0;
|
|
|
|
|
xctx->manhattan_lines = 0;
|
|
|
|
|
dbg(1, "abort_operation(): Escape: ui_state=%ld\n", xctx->ui_state);
|
|
|
|
|
if(xctx->ui_state & STARTMOVE)
|
|
|
|
|
{
|
|
|
|
|
move_objects(ABORT,0,0,0);
|
2021-11-04 15:08:54 +01:00
|
|
|
if(xctx->ui_state & (START_SYMPIN | PLACE_SYMBOL | PLACE_TEXT)) {
|
2021-11-04 02:07:41 +01:00
|
|
|
delete(1/* to_push_undo */);
|
|
|
|
|
xctx->ui_state &= ~START_SYMPIN;
|
2021-11-04 15:08:54 +01:00
|
|
|
xctx->ui_state &= ~PLACE_SYMBOL;
|
|
|
|
|
xctx->ui_state &= ~PLACE_TEXT;
|
2021-11-04 02:07:41 +01:00
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(xctx->ui_state & STARTCOPY)
|
|
|
|
|
{
|
|
|
|
|
copy_objects(ABORT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(xctx->ui_state & STARTMERGE) {
|
|
|
|
|
delete(1/* to_push_undo */);
|
|
|
|
|
set_modify(0); /* aborted merge: no change, so reset modify flag set by delete() */
|
|
|
|
|
}
|
|
|
|
|
xctx->ui_state = 0;
|
|
|
|
|
unselect_all();
|
|
|
|
|
draw();
|
|
|
|
|
}
|
2020-12-29 03:45:12 +01:00
|
|
|
|
2021-11-04 01:13:44 +01:00
|
|
|
void start_place_symbol(double mx, double my)
|
|
|
|
|
{
|
|
|
|
|
xctx->last_command = 0;
|
|
|
|
|
rebuild_selected_array();
|
|
|
|
|
if(xctx->lastsel && xctx->sel_array[0].type==ELEMENT) {
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval("set INITIALINSTDIR [file dirname {",
|
2021-11-04 01:13:44 +01:00
|
|
|
abs_sym_path(xctx->inst[xctx->sel_array[0].n].name, ""), "}]", NULL);
|
|
|
|
|
}
|
|
|
|
|
unselect_all();
|
|
|
|
|
xctx->mx_double_save = xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save = xctx->mousey_snap;
|
|
|
|
|
if(place_symbol(-1,NULL,xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/* to_push_undo */) ) {
|
|
|
|
|
xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
xctx->mousex_snap = xctx->mx_double_save;
|
|
|
|
|
move_objects(START,0,0,0);
|
|
|
|
|
xctx->ui_state |= PLACE_SYMBOL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
void start_line(double mx, double my)
|
|
|
|
|
{
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = STARTLINE;
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTLINE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move != 2) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move != 1) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
} else {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
new_line(PLACE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void start_wire(double mx, double my)
|
|
|
|
|
{
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = STARTWIRE;
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTWIRE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move != 2) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move != 1) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
} else {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
new_wire(PLACE,xctx->mousex_snap, xctx->mousey_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
|
|
|
|
|
}
|
2021-12-22 04:39:23 +01:00
|
|
|
|
|
|
|
|
/* process user input (arrow keys for now) when only graphs are selected */
|
2021-12-22 18:25:15 +01:00
|
|
|
#define W_X(x) (cx * (x) + dx)
|
|
|
|
|
#define W_Y(y) (cy * (y) + dy)
|
2021-12-26 14:33:54 +01:00
|
|
|
#define G_X(x) (((x) - dx) / cx)
|
2021-12-27 05:22:19 +01:00
|
|
|
#define G_Y(y) (((y) - dy) / cy)
|
2022-01-03 00:27:15 +01:00
|
|
|
/* for digital graphs (ypos1, ypos2 instead of wy1, wy2) */
|
|
|
|
|
#define DG_Y(y) (((y) - ddy) / dcy)
|
2022-01-03 18:43:34 +01:00
|
|
|
#define DW_Y(y) (dcy * (y) + ddy)
|
2022-01-02 04:42:15 +01:00
|
|
|
|
|
|
|
|
/* xctx->graph_flags:
|
|
|
|
|
* 1:
|
|
|
|
|
* 2: draw x-cursor1
|
|
|
|
|
* 4: draw x-cursor2
|
|
|
|
|
* 8: dnu, reserved, used in draw_graphs()
|
|
|
|
|
* 16: move cursor1
|
|
|
|
|
* 32: move cursor2
|
2022-01-03 18:43:34 +01:00
|
|
|
* 64: show measurement tooltip
|
2022-01-02 04:42:15 +01:00
|
|
|
*/
|
|
|
|
|
|
2021-12-22 04:39:23 +01:00
|
|
|
static int waves_callback(int event, int mx, int my, KeySym key, int button, int aux, int state)
|
|
|
|
|
{
|
2021-12-27 18:42:56 +01:00
|
|
|
int digital = 0;
|
2022-01-03 02:28:34 +01:00
|
|
|
double wx1 = 0, wy1 = 0, wx2 = 1e-6, wy2 = 5, ypos1 = 0, ypos2 = 5;
|
2021-12-22 18:25:15 +01:00
|
|
|
double x1, y1, x2, y2, marginx, marginy;
|
2022-01-03 00:27:15 +01:00
|
|
|
double cx, dx, cy, dy, dcy, ddy;
|
2022-01-02 22:24:44 +01:00
|
|
|
int divx = 10, divy = 5;
|
2021-12-22 04:39:23 +01:00
|
|
|
const char *val;
|
2021-12-22 18:25:15 +01:00
|
|
|
char s[30];
|
2022-01-02 22:24:44 +01:00
|
|
|
int i, need_redraw = 0;
|
2021-12-25 13:37:49 +01:00
|
|
|
double xx1, xx2, yy1, yy2;
|
Better axis label placement, smooth waves move/zoom with mouse, compile option to store sim data as floats instead of doubles, option for axis scaling (p,n,u,m,k,M,G), load waveforms command is a toggle (load / free)
2021-12-24 12:17:00 +01:00
|
|
|
double delta_threshold = 0.25;
|
2021-12-25 13:37:49 +01:00
|
|
|
int dataset = 0;
|
2021-12-30 15:45:38 +01:00
|
|
|
double zoom_m = 0.5;
|
2021-12-22 18:25:15 +01:00
|
|
|
#if HAS_CAIRO==1
|
|
|
|
|
cairo_save(xctx->cairo_ctx);
|
|
|
|
|
cairo_save(xctx->cairo_save_ctx);
|
|
|
|
|
cairo_select_font_face(xctx->cairo_ctx, "Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
|
|
|
|
cairo_select_font_face(xctx->cairo_save_ctx, "Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-01-01 15:46:03 +01:00
|
|
|
for(i=0; i < xctx->rects[GRIDLAYER]; i++) {
|
2021-12-30 20:52:15 +01:00
|
|
|
/* process only graph boxes */
|
|
|
|
|
xRect *r;
|
2022-01-01 15:46:03 +01:00
|
|
|
if( (xctx->ui_state & GRAPHPAN) && i != xctx->graph_master) continue;
|
2021-12-30 20:52:15 +01:00
|
|
|
r = &xctx->rect[GRIDLAYER][i];
|
|
|
|
|
if(!(r->flags & 1) ) continue;
|
|
|
|
|
/* check if this is the master graph (the one containing the mouse pointer) */
|
|
|
|
|
/* determine if mouse pointer is below xaxis or left of yaxis in some graph */
|
|
|
|
|
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);
|
|
|
|
|
else wx1 = 0;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"y1",0);
|
|
|
|
|
if(val[0]) wy1 = atof(val);
|
|
|
|
|
else wy1 = 0;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"x2",0);
|
|
|
|
|
if(val[0]) wx2 = atof(val);
|
|
|
|
|
else wx2 = 1e-6;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"y2",0);
|
|
|
|
|
if(val[0]) wy2 = atof(val);
|
|
|
|
|
else wy2 = 5;
|
2022-01-03 02:28:34 +01:00
|
|
|
if(wx1 == wx2) wx2 += 1e-6; /* avoid division by 0 */
|
|
|
|
|
if(wy1 == wy2) wy2 += 1.0; /* avoid division by 0 */
|
2021-12-30 20:52:15 +01:00
|
|
|
val = get_tok_value(r->prop_ptr,"digital",0);
|
|
|
|
|
if(val[0]) digital = atoi(val);
|
|
|
|
|
else digital = 0;
|
|
|
|
|
calc_graph_area(GRIDLAYER, i, digital, &x1, &y1, &x2, &y2, &marginx, &marginy);
|
|
|
|
|
cx = (x2 - x1) / (wx2 - wx1);
|
|
|
|
|
dx = x1 - wx1 * cx;
|
|
|
|
|
cy = (y1 - y2) / (wy2 - wy1);
|
|
|
|
|
dy = y2 - wy1 * cy;
|
2022-01-03 18:43:34 +01:00
|
|
|
|
2022-01-01 15:46:03 +01:00
|
|
|
/* move cursor1 */
|
|
|
|
|
/* set cursor position from master graph x-axis */
|
|
|
|
|
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
|
|
|
|
|
xctx->graph_cursor1_x = G_X(xctx->mousex);
|
|
|
|
|
}
|
|
|
|
|
/* move cursor2 */
|
|
|
|
|
/* set cursor position from master graph x-axis */
|
|
|
|
|
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) {
|
|
|
|
|
xctx->graph_cursor2_x = G_X(xctx->mousex);
|
|
|
|
|
}
|
|
|
|
|
if(xctx->ui_state & GRAPHPAN) break; /* After GRAPHPAN only need to check Motion events for cursors */
|
|
|
|
|
|
2021-12-30 20:52:15 +01:00
|
|
|
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 = i;
|
2022-01-01 15:46:03 +01:00
|
|
|
zoom_m = (xctx->mousex - x1) / (x2 - x1);
|
2021-12-30 15:45:38 +01:00
|
|
|
|
2021-12-31 11:58:28 +01:00
|
|
|
/* dragging cursors when mouse is very close */
|
2021-12-30 20:52:15 +01:00
|
|
|
if(event == ButtonPress && button == Button1) {
|
|
|
|
|
if( (xctx->graph_flags & 2) && fabs(xctx->mousex - W_X(xctx->graph_cursor1_x)) < 10) {
|
2021-12-31 11:58:28 +01:00
|
|
|
xctx->graph_flags |= 16; /* Start move cursor1 */
|
2021-12-30 15:45:38 +01:00
|
|
|
}
|
2021-12-30 20:52:15 +01:00
|
|
|
if( (xctx->graph_flags & 4) && fabs(xctx->mousex - W_X(xctx->graph_cursor2_x)) < 10) {
|
2021-12-31 11:58:28 +01:00
|
|
|
xctx->graph_flags |= 32; /* Start move cursor2 */
|
2021-12-30 15:45:38 +01:00
|
|
|
}
|
2021-12-30 20:52:15 +01:00
|
|
|
}
|
2021-12-31 11:58:28 +01:00
|
|
|
/* x cursor1 toggle */
|
2021-12-30 20:52:15 +01:00
|
|
|
if((key == 'a') ) {
|
|
|
|
|
xctx->graph_flags ^= 2;
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
if(xctx->graph_flags & 2) xctx->graph_cursor1_x = G_X(xctx->mousex);
|
|
|
|
|
}
|
2021-12-31 11:58:28 +01:00
|
|
|
/* x cursor2 toggle */
|
2021-12-30 20:52:15 +01:00
|
|
|
else if((key == 'b') ) {
|
|
|
|
|
xctx->graph_flags ^= 4;
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
if(xctx->graph_flags & 4) xctx->graph_cursor2_x = G_X(xctx->mousex);
|
|
|
|
|
}
|
2022-01-03 18:43:34 +01:00
|
|
|
/* measurement tooltip */
|
|
|
|
|
else if((key == 'm') ) {
|
|
|
|
|
xctx->graph_flags ^= 64;
|
|
|
|
|
if(!(xctx->graph_flags & 64)) {
|
|
|
|
|
tcleval("graph_stop_measure");
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-30 20:52:15 +01:00
|
|
|
break;
|
|
|
|
|
} /* if( POINTINSIDE(...) */
|
2022-01-01 15:46:03 +01:00
|
|
|
} /* for(i=0; i < xctx->rects[GRIDLAYER]; i++) */
|
|
|
|
|
|
|
|
|
|
/* save mouse position when doing pan operations */
|
|
|
|
|
if(
|
|
|
|
|
(
|
|
|
|
|
(event == ButtonPress && (button == Button1 || button == Button3)) ||
|
|
|
|
|
(event == MotionNotify && (state & (Button1Mask | Button3Mask)))
|
|
|
|
|
) &&
|
|
|
|
|
!(xctx->ui_state & GRAPHPAN)
|
|
|
|
|
) {
|
|
|
|
|
xctx->ui_state |= GRAPHPAN;
|
|
|
|
|
xctx->mx_double_save = xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save = xctx->mousey_snap;
|
2021-12-26 14:33:54 +01:00
|
|
|
}
|
2021-12-30 15:45:38 +01:00
|
|
|
|
2021-12-29 05:11:39 +01:00
|
|
|
/* lock x-axis to working graph when moving/zooming multiple graphs */
|
2021-12-27 05:22:19 +01:00
|
|
|
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x1",0);
|
|
|
|
|
if(val[0]) wx1 = atof(val);
|
2021-12-30 15:45:38 +01:00
|
|
|
else wx1 = 0;
|
2021-12-27 05:22:19 +01:00
|
|
|
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x2",0);
|
|
|
|
|
if(val[0]) wx2 = atof(val);
|
2021-12-30 15:45:38 +01:00
|
|
|
else wx2 = 1e-6;
|
2022-01-03 02:28:34 +01:00
|
|
|
if(wx1 == wx2) wx2 += 1e-6; /* avoid division by 0 */
|
2021-12-30 15:45:38 +01:00
|
|
|
|
2021-12-31 11:58:28 +01:00
|
|
|
/* second loop: after having determined the master graph do the others */
|
2022-01-02 04:42:15 +01:00
|
|
|
for(i=0; i< xctx->rects[GRIDLAYER]; i++) {
|
|
|
|
|
xRect *r;
|
2021-12-22 04:39:23 +01:00
|
|
|
/* process only graph boxes */
|
2022-01-02 04:42:15 +01:00
|
|
|
r = &xctx->rect[GRIDLAYER][i];
|
|
|
|
|
if( !(r->flags & 1) ) continue;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"divx",0);
|
|
|
|
|
if(val[0]) divx = atoi(val);
|
|
|
|
|
else divx = 4;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"divy",0);
|
|
|
|
|
if(val[0]) divy = atoi(val);
|
|
|
|
|
else divy = 4;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"y1",0);
|
|
|
|
|
if(val[0]) wy1 = atof(val);
|
|
|
|
|
else wy1 = 0;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"y2",0);
|
|
|
|
|
if(val[0]) wy2 = atof(val);
|
|
|
|
|
else wy2 = 5;
|
2022-01-03 02:28:34 +01:00
|
|
|
if(wy1 == wy2) wy2 += 1.0; /* avoid division by 0 */
|
2022-01-02 04:42:15 +01:00
|
|
|
val = get_tok_value(r->prop_ptr,"dataset",0);
|
|
|
|
|
if(val[0]) dataset = atoi(val);
|
|
|
|
|
else dataset = 0;
|
|
|
|
|
if(dataset >= xctx->graph_datasets) dataset = xctx->graph_datasets - 1;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"digital",0);
|
|
|
|
|
if(val[0]) digital = atoi(val);
|
|
|
|
|
else digital = 0;
|
2022-01-03 02:28:34 +01:00
|
|
|
if(digital) {
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"ypos1",0);
|
|
|
|
|
if(val[0]) ypos1 = atof(val);
|
|
|
|
|
else ypos1 = 0;
|
|
|
|
|
val = get_tok_value(r->prop_ptr,"ypos2",0);
|
|
|
|
|
if(val[0]) ypos2 = atof(val);
|
|
|
|
|
else ypos2 = 5;
|
|
|
|
|
if(ypos2 == ypos1) ypos2 += 1.0;
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
calc_graph_area(GRIDLAYER, i, digital, &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;
|
2022-01-03 00:27:15 +01:00
|
|
|
/* graph --> xschem transform for digital waves y axis */
|
|
|
|
|
dcy = (y1 - y2) / (ypos2 - ypos1);
|
|
|
|
|
ddy = y2 - ypos1 * dcy;
|
|
|
|
|
|
2022-01-03 18:43:34 +01:00
|
|
|
|
|
|
|
|
/* destroy / show measurement widget */
|
|
|
|
|
if(i == xctx->graph_master) {
|
|
|
|
|
if(xctx->graph_flags & 64) {
|
|
|
|
|
if( POINTINSIDE(xctx->mousex_snap, xctx->mousey_snap, x1, y1, x2, y2)) {
|
|
|
|
|
char sx[100], sy[100];
|
|
|
|
|
double yval;
|
|
|
|
|
if(digital) {
|
|
|
|
|
double deltag = wy2 - wy1;
|
|
|
|
|
double s1 = 0.1; /* 10 waveforms fit in graph if unscaled vertically */
|
|
|
|
|
double s2 = .08; /* 20% spacing between traces */
|
|
|
|
|
double c = s1 * deltag;
|
|
|
|
|
deltag = deltag * s1 / s2;
|
|
|
|
|
yval=(DG_Y(xctx->mousey) - c) / s2;
|
|
|
|
|
yval=fmod(yval, deltag ) + wy1;
|
|
|
|
|
if(yval > wy2 + deltag * (s1 + s2) * 0.5) yval -= deltag;
|
|
|
|
|
} else {
|
|
|
|
|
yval = G_Y(xctx->mousey);
|
|
|
|
|
}
|
|
|
|
|
my_snprintf(sx, S(sx), "%.4g", G_X(xctx->mousex));
|
|
|
|
|
my_snprintf(sy, S(sy), "%.4g", yval);
|
|
|
|
|
|
|
|
|
|
tclvareval("set measure_text \"y=", sy, "\nx=", sx, "\"", NULL);
|
|
|
|
|
tcleval("graph_show_measure");
|
|
|
|
|
} else {
|
|
|
|
|
tcleval("graph_stop_measure");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-01-02 04:42:15 +01:00
|
|
|
dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divx, divy);
|
|
|
|
|
if( event == KeyPress || event == ButtonPress || event == MotionNotify ) {
|
|
|
|
|
/* move cursor1 */
|
|
|
|
|
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
|
|
|
|
/* move cursor2 */
|
|
|
|
|
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) {
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
|
|
|
|
else /* drag waves with mouse */
|
|
|
|
|
if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom) {
|
|
|
|
|
double delta;
|
|
|
|
|
if(xctx->graph_left) {
|
|
|
|
|
if(i == xctx->graph_master) {
|
2022-01-02 22:24:44 +01:00
|
|
|
if(digital) {
|
|
|
|
|
delta = (ypos2 - ypos1) / divy;
|
|
|
|
|
delta_threshold = 0.01;
|
|
|
|
|
if(fabs(xctx->my_double_save - xctx->mousey_snap) > fabs(cy * delta) * delta_threshold) {
|
|
|
|
|
yy1 = ypos1 + (xctx->my_double_save - xctx->mousey_snap) / cy;
|
|
|
|
|
yy2 = ypos2 + (xctx->my_double_save - xctx->mousey_snap) / cy;
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy1);
|
|
|
|
|
my_strdup(1424, &r->prop_ptr, subst_token(r->prop_ptr, "ypos1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1425, &r->prop_ptr, subst_token(r->prop_ptr, "ypos2", s));
|
|
|
|
|
xctx->my_double_save = xctx->mousey_snap;
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
delta = (wy2 - wy1) / divy;
|
|
|
|
|
delta_threshold = 0.01;
|
|
|
|
|
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;
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy1);
|
2022-01-03 00:27:15 +01:00
|
|
|
my_strdup(1435, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
2022-01-02 22:24:44 +01:00
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
2022-01-03 00:27:15 +01:00
|
|
|
my_strdup(1437, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
2022-01-02 22:24:44 +01:00
|
|
|
xctx->my_double_save = xctx->mousey_snap;
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
delta = (wx2 - wx1);
|
|
|
|
|
delta_threshold = 0.01;
|
|
|
|
|
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
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;
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
|
|
|
|
my_strdup(1410, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
|
|
|
|
my_strdup(1411, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
/* update saved mouse position after processing all graphs */
|
|
|
|
|
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(cx * delta) * delta_threshold) {
|
|
|
|
|
if(i >= xctx->rects[GRIDLAYER] - 1) {
|
|
|
|
|
xctx->mx_double_save = xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save = xctx->mousey_snap;
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if((button == Button5 && !(state & ShiftMask))) {
|
|
|
|
|
double delta;
|
|
|
|
|
if(xctx->graph_left) {
|
2022-01-03 00:27:15 +01:00
|
|
|
if(i == xctx->graph_master) {
|
|
|
|
|
if(digital) {
|
|
|
|
|
delta = (ypos2 - ypos1) * 0.05;
|
|
|
|
|
yy1 = ypos1 + delta;
|
|
|
|
|
yy2 = ypos2 + delta;
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy1);
|
|
|
|
|
my_strdup(1456, &r->prop_ptr, subst_token(r->prop_ptr, "ypos1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1457, &r->prop_ptr, subst_token(r->prop_ptr, "ypos2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
} else {
|
|
|
|
|
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, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1421, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
delta = (wx2 - wx1);
|
2021-12-31 11:58:28 +01:00
|
|
|
delta_threshold = 0.05;
|
2021-12-30 20:52:15 +01:00
|
|
|
xx1 = wx1 - delta * delta_threshold;
|
|
|
|
|
xx2 = wx2 - delta * delta_threshold;
|
2021-12-25 13:37:49 +01:00
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
2021-12-30 20:52:15 +01:00
|
|
|
my_strdup(1428, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
2021-12-25 13:37:49 +01:00
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
2021-12-30 20:52:15 +01:00
|
|
|
my_strdup(1429, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(key == XK_Left) {
|
|
|
|
|
double delta;
|
|
|
|
|
if(xctx->graph_left) {
|
|
|
|
|
if(!digital && i == xctx->graph_master) {
|
|
|
|
|
double m = G_Y(xctx->mousey);
|
|
|
|
|
double a = m - wy1;
|
|
|
|
|
double b = wy2 -m;
|
|
|
|
|
double delta = (wy2 - wy1);
|
|
|
|
|
double var = delta * 0.2;
|
|
|
|
|
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(1448, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
} else {
|
|
|
|
|
delta = (wx2 - wx1);
|
|
|
|
|
delta_threshold = 0.05;
|
|
|
|
|
xx1 = wx1 - delta * delta_threshold;
|
|
|
|
|
xx2 = wx2 - delta * delta_threshold;
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
|
|
|
|
my_strdup(1395, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
|
|
|
|
my_strdup(1396, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
|
|
|
|
need_redraw = 1;
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(button == Button4 && !(state & ShiftMask)) {
|
|
|
|
|
double delta;
|
|
|
|
|
if(xctx->graph_left) {
|
2022-01-03 00:27:15 +01:00
|
|
|
if(i == xctx->graph_master) {
|
|
|
|
|
if(digital) {
|
|
|
|
|
delta = (ypos2 - ypos1) * 0.05;
|
|
|
|
|
yy1 = ypos1 - delta;
|
|
|
|
|
yy2 = ypos2 - delta;
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy1);
|
|
|
|
|
my_strdup(1416, &r->prop_ptr, subst_token(r->prop_ptr, "ypos1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1417, &r->prop_ptr, subst_token(r->prop_ptr, "ypos2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
} else {
|
|
|
|
|
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(1458, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1434, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
delta = (wx2 - wx1);
|
2021-12-31 11:58:28 +01:00
|
|
|
delta_threshold = 0.05;
|
2021-12-30 20:52:15 +01:00
|
|
|
xx1 = wx1 + delta * delta_threshold;
|
|
|
|
|
xx2 = wx2 + delta * delta_threshold;
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
|
|
|
|
my_strdup(1397, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
|
|
|
|
my_strdup(1398, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(key == XK_Right) {
|
|
|
|
|
double delta;
|
|
|
|
|
if(xctx->graph_left) {
|
|
|
|
|
if(!digital && i == xctx->graph_master) {
|
|
|
|
|
double m = G_Y(xctx->mousey);
|
|
|
|
|
double a = m - wy1;
|
|
|
|
|
double b = wy2 -m;
|
|
|
|
|
double delta = (wy2 - wy1);
|
|
|
|
|
double var = delta * 0.2;
|
|
|
|
|
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, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
} else {
|
|
|
|
|
delta = (wx2 - wx1);
|
|
|
|
|
delta_threshold = 0.05;
|
|
|
|
|
xx1 = wx1 + delta * delta_threshold;
|
|
|
|
|
xx2 = wx2 + delta * delta_threshold;
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
|
|
|
|
my_strdup(1430, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
|
|
|
|
my_strdup(1431, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
|
|
|
|
need_redraw = 1;
|
Better axis label placement, smooth waves move/zoom with mouse, compile option to store sim data as floats instead of doubles, option for axis scaling (p,n,u,m,k,M,G), load waveforms command is a toggle (load / free)
2021-12-24 12:17:00 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(button == Button5 && (state & ShiftMask)) {
|
|
|
|
|
if(xctx->graph_left) {
|
2022-01-03 00:27:15 +01:00
|
|
|
if(i == xctx->graph_master) {
|
|
|
|
|
if(digital) {
|
|
|
|
|
double m = DG_Y(xctx->mousey);
|
|
|
|
|
double a = m - ypos1;
|
|
|
|
|
double b = ypos2 -m;
|
|
|
|
|
double delta = (ypos2 - ypos1);
|
|
|
|
|
double var = delta * 0.05;
|
|
|
|
|
yy2 = ypos2 + var * b / delta;
|
|
|
|
|
yy1 = ypos1 - var * a / delta;
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy1);
|
|
|
|
|
my_strdup(1461, &r->prop_ptr, subst_token(r->prop_ptr, "ypos1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1459, &r->prop_ptr, subst_token(r->prop_ptr, "ypos2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
double m = G_Y(xctx->mousey);
|
|
|
|
|
double a = m - wy1;
|
|
|
|
|
double b = wy2 -m;
|
|
|
|
|
double delta = (wy2 - wy1);
|
|
|
|
|
double var = delta * 0.2;
|
|
|
|
|
yy2 = wy2 + var * b / delta;
|
|
|
|
|
yy1 = wy1 - var * a / delta;
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy1);
|
|
|
|
|
my_strdup(1460, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1438, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
double var = 0.2 * (wx2 -wx1);
|
|
|
|
|
xx2 = wx2 + var * (1 - zoom_m);
|
|
|
|
|
xx1 = wx1 - var * zoom_m;
|
|
|
|
|
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(1400, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(key == XK_Down) {
|
2022-01-03 00:27:15 +01:00
|
|
|
if(!xctx->graph_left) {
|
2022-01-02 04:42:15 +01:00
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
double var = 0.2 * (wx2 -wx1);
|
|
|
|
|
xx2 = wx2 + var * (1 - zoom_m);
|
|
|
|
|
xx1 = wx1 - var * zoom_m;
|
|
|
|
|
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(1432, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(button == Button4 && (state & ShiftMask)) {
|
|
|
|
|
if(xctx->graph_left) {
|
2022-01-03 00:27:15 +01:00
|
|
|
if(i == xctx->graph_master) {
|
|
|
|
|
if(digital) {
|
|
|
|
|
double m = DG_Y(xctx->mousey);
|
|
|
|
|
double a = m - ypos1;
|
|
|
|
|
double b = ypos2 -m;
|
|
|
|
|
double delta = (ypos2 - ypos1);
|
|
|
|
|
double var = delta * 0.05;
|
|
|
|
|
yy2 = ypos2 - var * b / delta;
|
|
|
|
|
yy1 = ypos1 + var * a / delta;
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy1);
|
|
|
|
|
my_strdup(1447, &r->prop_ptr, subst_token(r->prop_ptr, "ypos1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", yy2);
|
|
|
|
|
my_strdup(1436, &r->prop_ptr, subst_token(r->prop_ptr, "ypos2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
} else {
|
|
|
|
|
double m = G_Y(xctx->mousey);
|
|
|
|
|
double a = m - wy1;
|
|
|
|
|
double b = wy2 -m;
|
|
|
|
|
double delta = (wy2 - wy1);
|
|
|
|
|
double var = delta * 0.2;
|
|
|
|
|
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(1444, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
|
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
double var = 0.2 * (wx2 - wx1);;
|
|
|
|
|
xx2 = wx2 - var * (1 - zoom_m);
|
|
|
|
|
xx1 = wx1 + var * zoom_m;
|
|
|
|
|
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(1450, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(key == XK_Up) {
|
2022-01-03 00:27:15 +01:00
|
|
|
if(!xctx->graph_left) {
|
2022-01-02 04:42:15 +01:00
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
double var = 0.2 * (wx2 -wx1);
|
|
|
|
|
xx2 = wx2 - var * (1 - zoom_m);
|
|
|
|
|
xx1 = wx1 + var * zoom_m;
|
|
|
|
|
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(1446, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-27 14:12:55 +01:00
|
|
|
}
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if(key == 'f') {
|
|
|
|
|
if(xctx->graph_values) {
|
|
|
|
|
if(xctx->graph_left) {
|
2022-01-03 04:20:45 +01:00
|
|
|
if(i == xctx->graph_master) {
|
|
|
|
|
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(r->prop_ptr,"node",0));
|
|
|
|
|
nptr = node;
|
|
|
|
|
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
|
|
|
|
|
nptr = NULL;
|
|
|
|
|
j = get_raw_index(ntok);
|
|
|
|
|
if(j >= 0) {
|
|
|
|
|
for(i = 0; i < xctx->graph_npoints[dataset]; i++) {
|
|
|
|
|
v = get_raw_value(dataset, j, i);
|
|
|
|
|
if(first || v < min) {min = v; first = 0;}
|
|
|
|
|
if(first || v > max) {max = v; first = 0;}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2022-01-03 04:20:45 +01:00
|
|
|
if(max == min) max += 0.01;
|
|
|
|
|
min = floor_to_n_digits(min, 2);
|
|
|
|
|
max = ceil_to_n_digits(max, 2);
|
|
|
|
|
my_free(1427, &node);
|
|
|
|
|
my_snprintf(s, S(s), "%g", min);
|
|
|
|
|
my_strdup(1422, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", max);
|
|
|
|
|
my_strdup(1423, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
|
|
|
|
need_redraw = 1;
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
xx1 = get_raw_value(dataset, 0, 0);
|
|
|
|
|
xx2 = get_raw_value(dataset, 0, xctx->graph_npoints[dataset] -1);
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
|
|
|
|
my_strdup(1409, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
|
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
|
|
|
|
my_strdup(1412, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
|
|
|
|
need_redraw = 1;
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2021-12-30 20:52:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
else if( event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
|
|
|
|
|
double wwx1, wwx2, p, delta, ccx, ddx;
|
|
|
|
|
|
|
|
|
|
if(xctx->graph_values) {
|
|
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
delta = wx2 - wx1;
|
|
|
|
|
wwx1 = get_raw_value(dataset, 0, 0);
|
|
|
|
|
wwx2 = get_raw_value(dataset, 0, xctx->graph_npoints[dataset] - 1);
|
|
|
|
|
ccx = (x2 - x1) / (wwx2 - wwx1);
|
|
|
|
|
ddx = x1 - wwx1 * ccx;
|
|
|
|
|
p = (xctx->mousex_snap - ddx) / ccx;
|
|
|
|
|
xx1 = p - delta / 2.0;
|
|
|
|
|
xx2 = p + delta / 2.0;
|
2021-12-27 18:42:56 +01:00
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
2021-12-30 20:52:15 +01:00
|
|
|
my_strdup(1442, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
2021-12-30 20:52:15 +01:00
|
|
|
my_strdup(1443, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
2021-12-25 13:37:49 +01:00
|
|
|
}
|
2021-12-26 14:33:54 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
} /* if( event == KeyPress || event == ButtonPress || event == MotionNotify ) */
|
|
|
|
|
else if( event == ButtonRelease) {
|
|
|
|
|
if(button != Button3) {
|
|
|
|
|
xctx->ui_state &= ~GRAPHPAN;
|
|
|
|
|
xctx->graph_flags &= ~(16 | 32); /* clear move cursor flags */
|
|
|
|
|
}
|
|
|
|
|
else if(button == Button3) {
|
|
|
|
|
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
|
2021-12-30 20:52:15 +01:00
|
|
|
double tmp;
|
|
|
|
|
xctx->ui_state &= ~GRAPHPAN;
|
|
|
|
|
xx1 = G_X(xctx->mx_double_save);
|
|
|
|
|
xx2 = G_X(xctx->mousex_snap);
|
|
|
|
|
if(xx2 < xx1) { tmp = xx1; xx1 = xx2; xx2 = tmp; }
|
|
|
|
|
if(xx1 == xx2) xx2 += 1e-6;
|
2021-12-27 18:42:56 +01:00
|
|
|
my_snprintf(s, S(s), "%g", xx1);
|
2021-12-30 20:52:15 +01:00
|
|
|
my_strdup(1440, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
my_snprintf(s, S(s), "%g", xx2);
|
2021-12-30 20:52:15 +01:00
|
|
|
my_strdup(1441, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
2021-12-27 18:42:56 +01:00
|
|
|
need_redraw = 1;
|
|
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
}
|
|
|
|
|
} /* else if( event == ButtonRelease) */
|
2021-12-30 15:45:38 +01:00
|
|
|
if(need_redraw) {
|
2022-01-02 04:42:15 +01:00
|
|
|
draw_graph(GRIDLAYER, i, 1 + 8 + (xctx->graph_flags & 6) ); /* draw data in each graph box */
|
2021-12-30 15:45:38 +01:00
|
|
|
}
|
2022-01-02 04:42:15 +01:00
|
|
|
} /* for(i=0; i< xctx->rects[GRIDLAYER]; i++ */
|
2021-12-22 04:39:23 +01:00
|
|
|
draw_selection(xctx->gc[SELLAYER], 0);
|
2021-12-22 18:25:15 +01:00
|
|
|
#if HAS_CAIRO==1
|
|
|
|
|
cairo_restore(xctx->cairo_ctx);
|
|
|
|
|
cairo_restore(xctx->cairo_save_ctx);
|
|
|
|
|
#endif
|
2021-12-22 04:39:23 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
/* main window callback */
|
|
|
|
|
/* mx and my are set to the mouse coord. relative to window */
|
2021-11-09 19:05:56 +01:00
|
|
|
int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
2020-10-12 13:13:31 +02:00
|
|
|
int button, int aux, int state)
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2021-11-23 23:20:10 +01:00
|
|
|
static char old_winpath[PATH_MAX] = ""; /* previous focused window, used to do context switch */
|
2021-11-16 22:28:10 +01:00
|
|
|
char str[PATH_MAX + 100];
|
2020-08-08 15:47:34 +02:00
|
|
|
struct stat buf;
|
2021-11-16 22:28:10 +01:00
|
|
|
int redraw_only;
|
2020-08-08 15:47:34 +02:00
|
|
|
unsigned short sel;
|
2021-11-17 01:30:37 +01:00
|
|
|
double c_snap;
|
2020-09-22 21:02:51 +02:00
|
|
|
#ifndef __unix__
|
2021-11-10 13:43:08 +01:00
|
|
|
short cstate = GetKeyState(VK_CAPITAL);
|
|
|
|
|
short nstate = GetKeyState(VK_NUMLOCK);
|
2021-11-16 22:28:10 +01:00
|
|
|
#else
|
|
|
|
|
XKeyboardState kbdstate;
|
|
|
|
|
#endif
|
2021-11-08 16:27:07 +01:00
|
|
|
|
2021-11-16 22:28:10 +01:00
|
|
|
|
|
|
|
|
#ifndef __unix__
|
2021-11-10 13:43:08 +01:00
|
|
|
if(cstate & 0x0001) { /* caps lock */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.8 configure -state active -text {CAPS LOCK SET! }", NULL);
|
2021-11-10 13:43:08 +01:00
|
|
|
} else if (nstate & 0x0001) { /* num lock */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.8 configure -state active -text {NUM LOCK SET! }", NULL);
|
2021-11-10 13:43:08 +01:00
|
|
|
} else { /* normal state */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.8 configure -state normal -text {}", NULL);
|
2021-11-10 13:43:08 +01:00
|
|
|
}
|
2020-09-22 21:02:51 +02:00
|
|
|
#else
|
2020-09-22 15:47:53 +02:00
|
|
|
XGetKeyboardControl(display, &kbdstate);
|
2021-11-08 16:27:07 +01:00
|
|
|
if(kbdstate.led_mask & 1) { /* caps lock */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.8 configure -state active -text {CAPS LOCK SET! }", NULL);
|
2021-11-08 16:27:07 +01:00
|
|
|
} else if(kbdstate.led_mask & 2) { /* num lock */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.8 configure -state active -text {NUM LOCK SET! }", NULL);
|
2021-11-08 16:27:07 +01:00
|
|
|
} else { /* normal state */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.8 configure -state normal -text {}", NULL);
|
2020-09-22 15:47:53 +02:00
|
|
|
}
|
2020-09-22 21:02:51 +02:00
|
|
|
#endif
|
2021-11-16 22:28:10 +01:00
|
|
|
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.7 configure -text $netlist_type", NULL);
|
|
|
|
|
tclvareval(xctx->top_path, ".statusbar.3 delete 0 end;",
|
2021-11-17 01:12:55 +01:00
|
|
|
xctx->top_path, ".statusbar.3 insert 0 $cadsnap",
|
|
|
|
|
NULL);
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval(xctx->top_path, ".statusbar.5 delete 0 end;",
|
2021-11-17 01:12:55 +01:00
|
|
|
xctx->top_path, ".statusbar.5 insert 0 $cadgrid",
|
|
|
|
|
NULL);
|
|
|
|
|
|
2021-11-16 22:28:10 +01:00
|
|
|
#if 0
|
|
|
|
|
/* exclude Motion and Expose events */
|
|
|
|
|
if(event!=6 /* && event!=12 */) dbg(0, "callback(): event=%d, winpath=%s, old_winpath=%s, semaphore=%d\n",
|
|
|
|
|
event, winpath, old_winpath, xctx->semaphore+1);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Schematic window context switch */
|
|
|
|
|
redraw_only =0;
|
|
|
|
|
if(strcmp(old_winpath, winpath) ) {
|
|
|
|
|
if( xctx->semaphore >= 1 || event == Expose) {
|
|
|
|
|
dbg(1, "callback(): semaphore >=2 (or Expose) switching window context: %s --> %s\n", old_winpath, winpath);
|
|
|
|
|
redraw_only = 1;
|
|
|
|
|
} else {
|
|
|
|
|
dbg(1, "callback(): switching window context: %s --> %s\n", old_winpath, winpath);
|
2021-12-05 12:39:05 +01:00
|
|
|
if(old_winpath[0]) tclvareval("save_ctx ", old_winpath, NULL);
|
|
|
|
|
tclvareval("restore_ctx ", winpath, NULL);
|
|
|
|
|
tclvareval("housekeeping_ctx", NULL);
|
2021-11-16 22:28:10 +01:00
|
|
|
}
|
|
|
|
|
new_schematic("switch", xctx->top_path, winpath, "");
|
|
|
|
|
}
|
|
|
|
|
/* artificially set semaphore to allow only redraw operations in switched schematic,
|
|
|
|
|
* so we don't need to switch tcl context which is costly performance-wise
|
|
|
|
|
*/
|
|
|
|
|
if(redraw_only) xctx->semaphore++;
|
|
|
|
|
|
|
|
|
|
xctx->semaphore++; /* to recognize recursive callback() calls */
|
|
|
|
|
|
2021-11-10 13:43:08 +01:00
|
|
|
c_snap = tclgetdoublevar("cadsnap");
|
2020-09-22 21:12:09 +02:00
|
|
|
state &=~Mod2Mask; /* 20170511 filter out NumLock status */
|
2021-11-16 22:28:10 +01:00
|
|
|
if(xctx->semaphore >= 2)
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-10-12 13:13:31 +02:00
|
|
|
if(debug_var>=2)
|
2020-11-22 00:51:24 +01:00
|
|
|
if(event != MotionNotify)
|
2021-11-04 12:57:41 +01:00
|
|
|
fprintf(errfp, "callback(): reentrant call of callback(), semaphore=%d, ev=%d, ui_state=%ld\n",
|
|
|
|
|
xctx->semaphore, event, xctx->ui_state);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mousex=X_TO_XSCHEM(mx);
|
|
|
|
|
xctx->mousey=Y_TO_XSCHEM(my);
|
2021-12-17 15:40:19 +01:00
|
|
|
xctx->mousex_snap=my_round(xctx->mousex / c_snap) * c_snap;
|
|
|
|
|
xctx->mousey_snap=my_round(xctx->mousey / c_snap) * c_snap;
|
2020-10-12 13:13:31 +02:00
|
|
|
my_snprintf(str, S(str), "mouse = %.16g %.16g - selected: %d path: %s",
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mousex_snap, xctx->mousey_snap, xctx->lastsel, xctx->sch_path[xctx->currsch] );
|
2020-08-08 15:47:34 +02:00
|
|
|
statusmsg(str,1);
|
2021-01-08 21:25:11 +01:00
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
switch(event)
|
|
|
|
|
{
|
|
|
|
|
case EnterNotify:
|
2021-11-16 22:28:10 +01:00
|
|
|
if(!xctx->sel_or_clip[0]) my_snprintf(xctx->sel_or_clip, S(xctx->sel_or_clip), "%s/%s",
|
|
|
|
|
user_conf_dir, ".selection.sch");
|
2020-10-02 03:21:22 +02:00
|
|
|
|
2020-10-12 13:13:31 +02:00
|
|
|
/* xschem window *sending* selected objects
|
|
|
|
|
when the pointer comes back in abort copy operation since it has been done
|
2020-12-03 04:20:05 +01:00
|
|
|
in another xschem xctx->window; STARTCOPY set and selection file does not exist any more */
|
2020-12-06 16:10:22 +01:00
|
|
|
if( stat(xctx->sel_or_clip, &buf) && (xctx->ui_state & STARTCOPY) )
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
copy_objects(ABORT); /* also unlinks sel_or_flip file */
|
2020-10-12 13:13:31 +02:00
|
|
|
unselect_all();
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-10-02 03:21:22 +02:00
|
|
|
/* xschem window *receiving* selected objects */
|
|
|
|
|
/* no selected objects and selection file exists */
|
2020-12-06 16:10:22 +01:00
|
|
|
if(xctx->lastsel == 0 && !stat(xctx->sel_or_clip, &buf)) {
|
2020-08-08 15:47:34 +02:00
|
|
|
dbg(2, "callback(): Enter event\n");
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mousex_snap = 490;
|
|
|
|
|
xctx->mousey_snap = -340;
|
2020-08-08 15:47:34 +02:00
|
|
|
merge_file(1, ".sch");
|
2020-12-06 16:10:22 +01:00
|
|
|
xunlink(xctx->sel_or_clip);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Expose:
|
2021-12-23 03:43:34 +01:00
|
|
|
dbg(1, "callback: Expose, winpath=%s, %dx%d+%d+%d\n", winpath, button, aux, mx, my);
|
2020-12-06 02:10:53 +01:00
|
|
|
XCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gctiled, mx,my,button,aux,mx,my);
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
XRectangle xr[1];
|
|
|
|
|
xr[0].x=mx;
|
|
|
|
|
xr[0].y=my;
|
|
|
|
|
xr[0].width=button;
|
|
|
|
|
xr[0].height=aux;
|
|
|
|
|
/* redraw selection on expose, needed if no backing store available on the server 20171112 */
|
2021-11-16 22:28:10 +01:00
|
|
|
XSetClipRectangles(display, xctx->gc[SELLAYER], 0,0, xr, 1, Unsorted);
|
2020-08-08 15:47:34 +02:00
|
|
|
rebuild_selected_array();
|
2021-11-16 22:28:10 +01:00
|
|
|
draw_selection(xctx->gc[SELLAYER],0);
|
|
|
|
|
XSetClipMask(display, xctx->gc[SELLAYER], None);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
dbg(1, "callback(): Expose\n");
|
|
|
|
|
break;
|
|
|
|
|
case ConfigureNotify:
|
2020-12-22 00:13:25 +01:00
|
|
|
resetwin(1, 1, 0, 0, 0);
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case MotionNotify:
|
2021-12-30 15:45:38 +01:00
|
|
|
if( waves_selected(event, key, state, button)) {
|
2021-12-22 18:25:15 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-12-07 14:07:36 +01:00
|
|
|
if(xctx->ui_state & STARTPAN2) pan2(RUBBER, mx, my);
|
2021-12-22 18:25:15 +01:00
|
|
|
#ifndef __unix__
|
2020-12-02 15:10:47 +01:00
|
|
|
if ((xctx->ui_state & STARTWIRE) || (xctx->ui_state & STARTARC) ||
|
|
|
|
|
(xctx->ui_state & STARTLINE) || (xctx->ui_state & STARTMOVE) ||
|
2020-12-03 23:17:13 +01:00
|
|
|
(xctx->ui_state & STARTCOPY) || (xctx->ui_state & STARTRECT) ||
|
2020-12-02 15:10:47 +01:00
|
|
|
(xctx->ui_state & STARTPOLYGON) || (xctx->ui_state & STARTPAN2) ||
|
|
|
|
|
(xctx->ui_state & STARTPAN) || (xctx->ui_state & STARTSELECT)) {
|
2020-12-06 02:10:53 +01:00
|
|
|
XCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gctiled, xctx->xrect[0].x, xctx->xrect[0].y,
|
2020-12-03 11:42:06 +01:00
|
|
|
xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-12-22 18:25:15 +01:00
|
|
|
#endif
|
2021-12-07 14:07:36 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state) {
|
2020-08-08 15:47:34 +02:00
|
|
|
#ifdef TURBOX_FIX
|
|
|
|
|
/* fix Exceed TurboX bugs when drawing with pixmap tiled fill pattern */
|
|
|
|
|
/* *NOT* a solution but at least makes the program useable. 20171130 */
|
2020-12-06 02:10:53 +01:00
|
|
|
XSetClipRectangles(display, xctx->gctiled, 0,0, xctx->xrect, 1, Unsorted);
|
2020-08-08 15:47:34 +02:00
|
|
|
#endif
|
2020-10-12 13:13:31 +02:00
|
|
|
my_snprintf(str, S(str), "mouse = %.16g %.16g - selected: %d w=%.16g h=%.16g",
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mousex_snap, xctx->mousey_snap,
|
|
|
|
|
xctx->lastsel ,
|
|
|
|
|
xctx->mousex_snap-xctx->mx_double_save, xctx->mousey_snap-xctx->my_double_save
|
2020-08-08 15:47:34 +02:00
|
|
|
);
|
|
|
|
|
statusmsg(str,1);
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTPAN) pan(RUBBER);
|
2020-12-22 00:13:25 +01:00
|
|
|
if(xctx->ui_state & STARTZOOM) zoom_rectangle(RUBBER);
|
2021-11-04 15:08:54 +01:00
|
|
|
if(xctx->ui_state & STARTSELECT && !(xctx->ui_state & (PLACE_SYMBOL | STARTPAN2 | PLACE_TEXT)) ) {
|
2020-08-08 15:47:34 +02:00
|
|
|
if( (state & Button1Mask) && (state & Mod1Mask)) { /* 20171026 added unselect by area */
|
|
|
|
|
select_rect(RUBBER,0);
|
|
|
|
|
} else if(state & Button1Mask) {
|
2021-12-22 18:25:15 +01:00
|
|
|
select_rect(RUBBER,1);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTMOVE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
move_objects(RUBBER,0,0,0);
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTCOPY) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
copy_objects(RUBBER);
|
|
|
|
|
}
|
2020-12-29 03:45:12 +01:00
|
|
|
|
|
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-11-22 00:51:24 +01:00
|
|
|
/* start of a mouse area select */
|
2020-12-02 15:10:47 +01:00
|
|
|
if(!(xctx->ui_state & STARTPOLYGON) && (state&Button1Mask) && !(xctx->ui_state & STARTWIRE) &&
|
|
|
|
|
!(xctx->ui_state & STARTPAN2) && !(state & Mod1Mask) &&
|
2021-11-04 15:08:54 +01:00
|
|
|
!(state & ShiftMask) && !(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT)))
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-06 16:10:22 +01:00
|
|
|
if(mx != xctx->mx_save || my != xctx->my_save) {
|
2020-12-02 15:10:47 +01:00
|
|
|
if( !(xctx->ui_state & STARTSELECT)) {
|
2020-11-03 12:10:55 +01:00
|
|
|
select_rect(START,1);
|
2021-11-18 01:55:01 +01:00
|
|
|
xctx->onetime=1;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-11-06 03:24:45 +01:00
|
|
|
if(abs(mx-xctx->mx_save) > 8 ||
|
|
|
|
|
abs(my-xctx->my_save) > 8 ) { /* set reasonable threshold before unsel */
|
2021-11-18 01:55:01 +01:00
|
|
|
if(xctx->onetime) {
|
2020-08-08 15:47:34 +02:00
|
|
|
unselect_all(); /* 20171026 avoid multiple calls of unselect_all() */
|
2021-11-18 01:55:01 +01:00
|
|
|
xctx->onetime=0;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-11-06 03:24:45 +01:00
|
|
|
xctx->ui_state|=STARTSELECT; /* set it again cause unselect_all() clears it... */
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if((state & Button1Mask) && (state & Mod1Mask) && !(state & ShiftMask) &&
|
2021-11-06 03:24:45 +01:00
|
|
|
!(xctx->ui_state & STARTPAN2) &&
|
|
|
|
|
!(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT))) { /* unselect area */
|
2020-12-02 15:10:47 +01:00
|
|
|
if( !(xctx->ui_state & STARTSELECT)) {
|
2020-11-03 12:10:55 +01:00
|
|
|
select_rect(START,0);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-11-06 03:24:45 +01:00
|
|
|
else if((state&Button1Mask) && (state & ShiftMask) &&
|
|
|
|
|
!(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT)) &&
|
2020-12-02 15:10:47 +01:00
|
|
|
!(xctx->ui_state & STARTPAN2) ) {
|
2020-12-06 16:10:22 +01:00
|
|
|
if(mx != xctx->mx_save || my != xctx->my_save) {
|
2020-12-02 15:10:47 +01:00
|
|
|
if( !(xctx->ui_state & STARTSELECT)) {
|
2020-11-03 12:10:55 +01:00
|
|
|
select_rect(START,1);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-11-06 03:24:45 +01:00
|
|
|
if(abs(mx-xctx->mx_save) > 8 ||
|
|
|
|
|
abs(my-xctx->my_save) > 8 ) { /* set reasonable threshold before unsel */
|
|
|
|
|
select_object(X_TO_XSCHEM(xctx->mx_save),
|
|
|
|
|
Y_TO_XSCHEM(xctx->my_save), 0, 0); /* remove near obj if dragging */
|
2020-09-01 10:50:08 +02:00
|
|
|
rebuild_selected_array();
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2020-10-12 13:13:31 +02:00
|
|
|
case KeyRelease:
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
2020-10-12 13:13:31 +02:00
|
|
|
case KeyPress:
|
2020-08-08 15:47:34 +02:00
|
|
|
if(key==' ') {
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTWIRE) { /* & instead of == 20190409 */
|
|
|
|
|
new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap);
|
2021-10-25 17:05:43 +02:00
|
|
|
xctx->manhattan_lines++;
|
|
|
|
|
xctx->manhattan_lines %=3;
|
2020-12-02 15:10:47 +01:00
|
|
|
new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
|
2020-12-02 15:10:47 +01:00
|
|
|
} else if(xctx->ui_state==STARTLINE) {
|
2020-08-08 15:47:34 +02:00
|
|
|
new_line(RUBBER|CLEAR);
|
2021-10-25 17:05:43 +02:00
|
|
|
xctx->manhattan_lines++;
|
|
|
|
|
xctx->manhattan_lines %=3;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_line(RUBBER);
|
|
|
|
|
} else {
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore<2) {
|
2020-12-25 15:14:41 +01:00
|
|
|
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-11-03 12:10:55 +01:00
|
|
|
pan2(START, mx, my);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state |= STARTPAN2;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == '_' ) /* toggle change line width */
|
|
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
if(!tclgetboolvar("change_lw")) {
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("alert_ { enabling change line width} {}");
|
|
|
|
|
tclsetvar("change_lw","1");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tcleval("alert_ { disabling change line width} {}");
|
|
|
|
|
tclsetvar("change_lw","0");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'b' && state==ControlMask) /* toggle show text in symbol */
|
|
|
|
|
{
|
2021-11-16 22:28:10 +01:00
|
|
|
xctx->sym_txt =!xctx->sym_txt;
|
|
|
|
|
if(xctx->sym_txt) {
|
2020-08-08 15:47:34 +02:00
|
|
|
/* tcleval("alert_ { enabling text in symbol} {}"); */
|
|
|
|
|
tclsetvar("sym_txt","1");
|
|
|
|
|
draw();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* tcleval("alert_ { disabling text in symbol} {}"); */
|
|
|
|
|
tclsetvar("sym_txt","0");
|
|
|
|
|
draw();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == '%' ) /* toggle draw grid */
|
|
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
int dr_gr;
|
|
|
|
|
dr_gr = tclgetboolvar("draw_grid");
|
|
|
|
|
dr_gr =!dr_gr;
|
|
|
|
|
if(dr_gr) {
|
2020-08-08 15:47:34 +02:00
|
|
|
/* tcleval("alert_ { enabling draw grid} {}"); */
|
|
|
|
|
tclsetvar("draw_grid","1");
|
|
|
|
|
draw();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* tcleval("alert_ { disabling draw grid} {}"); */
|
|
|
|
|
tclsetvar("draw_grid","0");
|
|
|
|
|
draw();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'j' && state==0 ) /* print list of highlight nets */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
print_hilight_net(1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'j' && state==ControlMask) /* create ipins from highlight nets */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
print_hilight_net(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'j' && state==Mod1Mask) /* create labels without i prefix from hilight nets */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
print_hilight_net(4);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(key == 'J' && state==(Mod1Mask | ShiftMask) ) /* create labels with i prefix from hilight nets */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
print_hilight_net(2);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(key == 'h' && state==ControlMask ) /* go to http link */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
launcher();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'h' && state==Mod1Mask) /* create symbol pins from schematic pins 20171208 */
|
|
|
|
|
{
|
|
|
|
|
tcleval("schpins_to_sympins");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'h' && state == 0) {
|
|
|
|
|
/* horizontally constrained drag 20171023 */
|
2021-01-05 01:24:45 +01:00
|
|
|
if ( constrained_move == 1 ) {
|
|
|
|
|
tcleval("set constrained_move 0" );
|
|
|
|
|
constrained_move = 0;
|
2020-08-08 15:47:34 +02:00
|
|
|
} else {
|
2021-01-05 01:24:45 +01:00
|
|
|
tcleval("set constrained_move 1" );
|
|
|
|
|
constrained_move = 1;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTWIRE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-12-02 15:10:47 +01:00
|
|
|
new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTLINE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_line(RUBBER);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='H' && state==ShiftMask) { /* attach labels to selected instances */
|
2021-11-29 14:37:39 +01:00
|
|
|
attach_labels_to_inst(1);
|
2021-01-05 01:24:45 +01:00
|
|
|
break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-06-05 08:58:38 +02:00
|
|
|
if (key == 'H' && state == (ControlMask | ShiftMask)) { /* create schematic and symbol from selected components */
|
|
|
|
|
make_schematic_symbol_from_sel();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
if(key == 'v' && state==0) {
|
|
|
|
|
/* vertically constrained drag 20171023 */
|
2021-01-05 01:24:45 +01:00
|
|
|
if ( constrained_move == 2 ) {
|
|
|
|
|
tcleval("set constrained_move 0" );
|
|
|
|
|
constrained_move = 0;
|
2020-08-08 15:47:34 +02:00
|
|
|
} else {
|
2021-01-05 01:24:45 +01:00
|
|
|
tcleval("set constrained_move 2" );
|
|
|
|
|
constrained_move = 2;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTWIRE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-12-02 15:10:47 +01:00
|
|
|
new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTLINE) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_line(RUBBER);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'j' && state == (ControlMask | Mod1Mask) ) /* print list of highlight net with label expansion */
|
|
|
|
|
{
|
|
|
|
|
print_hilight_net(3);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-09-17 09:05:08 +02:00
|
|
|
if(key == 'J' && state==ShiftMask) {
|
2021-09-19 00:21:20 +02:00
|
|
|
create_plot_cmd();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == '$' && ( state == ShiftMask) ) /* toggle pixmap saving */
|
|
|
|
|
{
|
2021-10-26 00:04:13 +02:00
|
|
|
xctx->draw_pixmap =!xctx->draw_pixmap;
|
|
|
|
|
if(xctx->draw_pixmap) tcleval("alert_ { enabling draw pixmap} {}");
|
2020-08-08 15:47:34 +02:00
|
|
|
else tcleval("alert_ { disabling draw pixmap} {}");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == '$' && (state &ControlMask) ) /* toggle window drawing */
|
|
|
|
|
{
|
2021-11-16 22:28:10 +01:00
|
|
|
xctx->draw_window =!xctx->draw_window;
|
|
|
|
|
if(xctx->draw_window) {
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("alert_ { enabling draw window} {}");
|
|
|
|
|
tclsetvar("draw_window","1");
|
|
|
|
|
} else {
|
|
|
|
|
tcleval("alert_ { disabling draw window} {}");
|
|
|
|
|
tclsetvar("draw_window","0");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == '=' && (state &ControlMask)) /* toggle fill rectangles */
|
|
|
|
|
{
|
|
|
|
|
int x;
|
2021-11-16 22:28:10 +01:00
|
|
|
xctx->fill_pattern++;
|
|
|
|
|
if(xctx->fill_pattern==3) xctx->fill_pattern=0;
|
2020-08-08 15:47:34 +02:00
|
|
|
|
2021-11-16 22:28:10 +01:00
|
|
|
if(xctx->fill_pattern==1) {
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("alert_ { Stippled pattern fill} {}");
|
|
|
|
|
for(x=0;x<cadlayers;x++) {
|
2021-11-16 22:28:10 +01:00
|
|
|
if(xctx->fill_type[x]==1) XSetFillStyle(display,xctx->gcstipple[x],FillSolid);
|
|
|
|
|
else XSetFillStyle(display,xctx->gcstipple[x],FillStippled);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-11-16 22:28:10 +01:00
|
|
|
else if(xctx->fill_pattern==2) {
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("alert_ { solid pattern fill} {}");
|
2020-10-12 13:13:31 +02:00
|
|
|
for(x=0;x<cadlayers;x++)
|
2021-11-16 22:28:10 +01:00
|
|
|
XSetFillStyle(display,xctx->gcstipple[x],FillSolid);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tcleval("alert_ { No pattern fill} {}");
|
2020-10-12 13:13:31 +02:00
|
|
|
for(x=0;x<cadlayers;x++)
|
2021-11-16 22:28:10 +01:00
|
|
|
XSetFillStyle(display,xctx->gcstipple[x],FillStippled);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == '+' && state&ControlMask) /* change line width */
|
|
|
|
|
{
|
2020-10-17 00:53:19 +02:00
|
|
|
xctx->lw+=0.1;
|
|
|
|
|
change_linewidth(xctx->lw);
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
if(key == '-' && state&ControlMask) /* change line width */
|
|
|
|
|
{
|
2020-10-17 00:53:19 +02:00
|
|
|
xctx->lw-=0.1;if(xctx->lw<0.0) xctx->lw=0.0;
|
|
|
|
|
change_linewidth(xctx->lw);
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key == 'X' && state == ShiftMask) /* highlight discrepanciens between selected instance pin and net names */
|
|
|
|
|
{
|
2020-10-24 23:00:41 +02:00
|
|
|
hilight_net_pin_mismatches();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-10-05 03:00:40 +02:00
|
|
|
if(key== 'W' && state == ShiftMask) { /* create wire snapping to closest instance pin */
|
2020-08-08 15:47:34 +02:00
|
|
|
double x, y;
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-02 15:10:47 +01:00
|
|
|
if(!(xctx->ui_state & STARTWIRE)){
|
|
|
|
|
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
2021-12-17 15:40:19 +01:00
|
|
|
xctx->mx_double_save = my_round(x / c_snap) * c_snap;
|
|
|
|
|
xctx->my_double_save = my_round(y / c_snap) * c_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_wire(PLACE, x, y);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-12-02 15:10:47 +01:00
|
|
|
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
2020-08-08 15:47:34 +02:00
|
|
|
new_wire(RUBBER, x, y);
|
|
|
|
|
new_wire(PLACE|END, x, y);
|
2021-01-05 01:24:45 +01:00
|
|
|
constrained_move=0;
|
|
|
|
|
tcleval("set constrained_move 0" );
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(key == 'w' && state==0) /* place wire. */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2021-01-05 01:24:45 +01:00
|
|
|
int prev_state = xctx->ui_state;
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-10-12 13:13:31 +02:00
|
|
|
start_wire(mx, my);
|
2021-01-05 01:24:45 +01:00
|
|
|
if(prev_state == STARTWIRE) {
|
|
|
|
|
tcleval("set constrained_move 0" );
|
|
|
|
|
constrained_move=0;
|
|
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(key == XK_Return && (state == 0 ) && xctx->ui_state & STARTPOLYGON) { /* close polygon */
|
2020-08-08 15:47:34 +02:00
|
|
|
new_polygon(ADD|END);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 23:52:24 +01:00
|
|
|
if(key == XK_Escape) /* abort & redraw */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2021-11-04 23:52:24 +01:00
|
|
|
if(xctx->semaphore < 2) {
|
|
|
|
|
abort_operation();
|
|
|
|
|
}
|
|
|
|
|
/* stuff that can be done reentrantly ... */
|
|
|
|
|
tclsetvar("tclstop", "1"); /* stop simulation if any running */
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='z' && state == 0) /* zoom box */
|
|
|
|
|
{
|
2020-12-22 00:13:25 +01:00
|
|
|
dbg(1, "callback(): zoom_rectangle call\n");
|
|
|
|
|
zoom_rectangle(START);break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
if(key=='Z' && state == ShiftMask) /* zoom in */
|
|
|
|
|
{
|
|
|
|
|
view_zoom(0.0); break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='p' && state == Mod1Mask) /* add symbol pin */
|
|
|
|
|
{
|
|
|
|
|
unselect_all();
|
2020-12-02 15:10:47 +01:00
|
|
|
storeobject(-1, xctx->mousex_snap-2.5, xctx->mousey_snap-2.5, xctx->mousex_snap+2.5, xctx->mousey_snap+2.5,
|
2020-08-08 15:47:34 +02:00
|
|
|
xRECT, PINLAYER, SELECTED, "name=XXX\ndir=inout");
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->need_reb_sel_arr=1;
|
2020-08-08 15:47:34 +02:00
|
|
|
rebuild_selected_array();
|
2020-11-03 12:10:55 +01:00
|
|
|
move_objects(START,0,0,0);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state |= START_SYMPIN;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(key=='w' && !xctx->ui_state && state==ControlMask) /* start polygon, 20171115 */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
dbg(1, "callback(): start polygon\n");
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = 0;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_polygon(PLACE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='p' && state == ControlMask) /* pan */
|
|
|
|
|
{
|
2020-11-03 12:10:55 +01:00
|
|
|
pan(START);break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
if(key=='P' && state == ShiftMask) /* pan, other way to. */
|
|
|
|
|
{
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->xorigin=-xctx->mousex_snap+xctx->areaw*xctx->zoom/2.0;
|
|
|
|
|
xctx->yorigin=-xctx->mousey_snap+xctx->areah*xctx->zoom/2.0;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='5' && state == 0) { /* 20110112 display only probes */
|
2021-11-17 23:12:17 +01:00
|
|
|
xctx->only_probes = !xctx->only_probes;
|
|
|
|
|
tclsetboolvar("only_probes", xctx->only_probes);
|
2020-08-08 15:47:34 +02:00
|
|
|
toggle_only_probes();
|
|
|
|
|
break;
|
|
|
|
|
} /* /20110112 */
|
|
|
|
|
if(key<='9' && key >='0' && state==ControlMask) /* choose layer */
|
|
|
|
|
{
|
2020-09-16 00:50:15 +02:00
|
|
|
char n[30];
|
2020-12-06 16:40:08 +01:00
|
|
|
xctx->rectcolor = key - '0'+4;
|
|
|
|
|
my_snprintf(n, S(n), "%d", xctx->rectcolor);
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval("xschem set rectcolor ", n, NULL);
|
2021-11-09 19:05:56 +01:00
|
|
|
|
|
|
|
|
if(!strcmp(winpath, ".drw")) {
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval("reconfigure_layers_button {}", NULL);
|
2021-11-09 19:05:56 +01:00
|
|
|
} else {
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval("reconfigure_layers_button [winfo parent ", winpath, "]", NULL);
|
2021-11-09 19:05:56 +01:00
|
|
|
}
|
2021-11-16 22:28:10 +01:00
|
|
|
dbg(1, "callback(): new color: %d\n",xctx->color_index[xctx->rectcolor]);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key==XK_Delete && (xctx->ui_state & SELECTION) ) /* delete selection */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-04 01:13:44 +01:00
|
|
|
delete(1/* to_push_undo */);break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
if(key==XK_Right) /* left */
|
|
|
|
|
{
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 04:39:23 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->xorigin+=-CADMOVESTEP*xctx->zoom;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key==XK_Left) /* right */
|
|
|
|
|
{
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 04:39:23 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->xorigin-=-CADMOVESTEP*xctx->zoom;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key==XK_Down) /* down */
|
|
|
|
|
{
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 04:39:23 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->yorigin+=-CADMOVESTEP*xctx->zoom;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key==XK_Up) /* up */
|
|
|
|
|
{
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 04:39:23 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->yorigin-=-CADMOVESTEP*xctx->zoom;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='q' && state == ControlMask) /* exit */
|
|
|
|
|
{
|
2021-11-16 22:28:10 +01:00
|
|
|
char * top_path;
|
|
|
|
|
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-16 22:28:10 +01:00
|
|
|
if(!strcmp(winpath, ".drw")) {
|
|
|
|
|
tcleval("new_window destroy_all"); /* close child schematics */
|
|
|
|
|
if(tclresult()[0] == '1') {
|
|
|
|
|
if(xctx->modified) {
|
2021-11-29 02:47:37 +01:00
|
|
|
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
|
2021-11-16 22:28:10 +01:00
|
|
|
"[get_cell [xschem get schname] 0]"
|
|
|
|
|
": UNSAVED data: want to exit?\"");
|
|
|
|
|
}
|
2021-11-29 17:29:09 +01:00
|
|
|
if(!xctx->modified || !strcmp(tclresult(),"ok")) tcleval("exit");
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-11-16 22:28:10 +01:00
|
|
|
} else {
|
|
|
|
|
/* xschem new_schematic destroy asks user confirmation if schematic changed */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval("xschem new_schematic destroy ", top_path, " ", winpath," {}" , NULL);
|
2021-11-16 22:28:10 +01:00
|
|
|
/* ================================================================ */
|
|
|
|
|
/* We must return here, since current schematic is no more existing */
|
|
|
|
|
/* ================================================================ */
|
|
|
|
|
return 0;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='t' && state == 0) /* place text */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = 0;
|
2021-11-06 03:24:45 +01:00
|
|
|
xctx->mx_double_save = xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save = xctx->mousey_snap;
|
|
|
|
|
if(place_text(0, xctx->mousex_snap, xctx->mousey_snap)) { /* 1 = draw text 24122002 */
|
|
|
|
|
xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
xctx->mousex_snap = xctx->mx_double_save;
|
|
|
|
|
move_objects(START,0,0,0);
|
|
|
|
|
xctx->ui_state |= PLACE_TEXT;
|
|
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(key=='r' && !xctx->ui_state && state==0) /* start rect */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
dbg(1, "callback(): start rect\n");
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = 0;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_rect(PLACE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='V' && state == ShiftMask) /* toggle spice/vhdl netlist */
|
|
|
|
|
{
|
2021-11-16 22:28:10 +01:00
|
|
|
xctx->netlist_type++; if(xctx->netlist_type==6) xctx->netlist_type=1;
|
2021-11-17 01:12:55 +01:00
|
|
|
set_tcl_netlist_type();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key=='s' && (state == ControlMask) ) /* save 20121201 */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-09-30 23:55:07 +02:00
|
|
|
/* check if unnamed schematic, use saveas in this case */
|
2020-10-15 17:39:21 +02:00
|
|
|
if(!strcmp(xctx->sch[xctx->currsch],"") || strstr(xctx->sch[xctx->currsch], "untitled")) {
|
2020-09-14 10:27:45 +02:00
|
|
|
saveas(NULL, SCHEMATIC);
|
2020-08-08 15:47:34 +02:00
|
|
|
} else {
|
|
|
|
|
save(1);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='s' && state == (ControlMask | Mod1Mask) ) /* save as symbol */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-09-10 10:12:51 +02:00
|
|
|
saveas(NULL, SYMBOL);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='S' && state == (ShiftMask | ControlMask)) /* save as schematic */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-09-14 10:27:45 +02:00
|
|
|
saveas(NULL, SCHEMATIC);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='e' && state == 0) /* descend to schematic */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-09-22 13:35:55 +02:00
|
|
|
descend_schematic(0);break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
if(key=='e' && state == Mod1Mask) /* edit schematic in new window */
|
|
|
|
|
{
|
|
|
|
|
schematic_in_new_window();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='i' && state == Mod1Mask) /* edit symbol in new window */
|
|
|
|
|
{
|
|
|
|
|
symbol_in_new_window();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if( (key=='e' && state == ControlMask) || (key==XK_BackSpace)) /* back */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
go_back(1);break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key=='a' && state == 0) /* make symbol */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
|
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-12-17 03:29:53 +01:00
|
|
|
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] "
|
|
|
|
|
"-message {do you want to make symbol view ?}");
|
2020-10-12 13:13:31 +02:00
|
|
|
if(strcmp(tclresult(),"ok")==0)
|
2020-09-14 10:27:45 +02:00
|
|
|
{
|
2020-10-15 17:39:21 +02:00
|
|
|
save_schematic(xctx->sch[xctx->currsch]);
|
2020-09-14 10:27:45 +02:00
|
|
|
make_symbol();
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='a' && state == ControlMask) /* select all */
|
|
|
|
|
{
|
|
|
|
|
select_all();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='y' && state == 0) /* toggle stretching */
|
|
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
int en_s;
|
|
|
|
|
en_s = tclgetboolvar("enable_stretch");
|
|
|
|
|
en_s = !en_s;
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2021-11-10 13:43:08 +01:00
|
|
|
if(en_s) {
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("alert_ { enabling stretch mode } {}");
|
|
|
|
|
tclsetvar("enable_stretch","1");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tcleval("alert_ { disabling stretch mode } {}");
|
|
|
|
|
tclsetvar("enable_stretch","0");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='x' && state == ControlMask) /* cut selection into clipboard */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
rebuild_selected_array();
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->lastsel) { /* 20071203 check if something selected */
|
2020-08-08 15:47:34 +02:00
|
|
|
save_selection(2);
|
2021-11-04 01:13:44 +01:00
|
|
|
delete(1/* to_push_undo */);
|
2020-10-12 13:13:31 +02:00
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='c' && state == ControlMask) /* copy selection into clipboard */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
rebuild_selected_array();
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->lastsel) { /* 20071203 check if something selected */
|
2020-08-08 15:47:34 +02:00
|
|
|
save_selection(2);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='C' && state == ShiftMask) /* place arc */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = 0;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_arc(PLACE, 180.);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='C' && state == (ControlMask|ShiftMask)) /* place circle */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = 0;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_arc(PLACE, 360.);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-25 04:37:53 +01:00
|
|
|
if(key=='O' && (state == (ControlMask|ShiftMask)) ) /* load most recent tile */
|
|
|
|
|
{
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval("xschem load [lindex $recentfile 0]", NULL);
|
2020-12-25 04:37:53 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='O' && state == ShiftMask) /* toggle light/dark colorscheme 20171113 */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
int d_c;
|
|
|
|
|
d_c = tclgetboolvar("dark_colorscheme");
|
|
|
|
|
d_c = !d_c;
|
|
|
|
|
tclsetboolvar("dark_colorscheme", d_c);
|
2021-11-16 22:28:10 +01:00
|
|
|
tclsetdoublevar("dim_value", 0.0);
|
|
|
|
|
tclsetdoublevar("dim_bg", 0.0);
|
|
|
|
|
build_colors(0.0, 0.0);
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='v' && state == ControlMask) /* paste from clipboard */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
merge_file(2,".sch");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='Q' && state == (ControlMask | ShiftMask) ) /* view attributes */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
edit_property(2);break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='q' && state==0) /* edit attributes */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
edit_property(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='q' && state==Mod1Mask) /* edit .sch file (DANGER!!) */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
rebuild_selected_array();
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->lastsel==0 ) {
|
2020-10-15 17:39:21 +02:00
|
|
|
my_snprintf(str, S(str), "edit_file {%s}", abs_sym_path(xctx->sch[xctx->currsch], ""));
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval(str);
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
else if(xctx->sel_array[0].type==ELEMENT) {
|
2020-10-12 13:13:31 +02:00
|
|
|
my_snprintf(str, S(str), "edit_file {%s}",
|
2020-12-02 15:10:47 +01:00
|
|
|
abs_sym_path(xctx->inst[xctx->sel_array[0].n].name, ""));
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval(str);
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='Q' && state == ShiftMask) /* edit attributes in editor */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
edit_property(1);break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='i' && state==0) /* descend to symbol */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
descend_symbol();break;
|
|
|
|
|
}
|
2020-10-24 23:00:41 +02:00
|
|
|
if(key==XK_Insert || (key == 'I' && state == ShiftMask) ) /* insert sym */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-04 01:13:44 +01:00
|
|
|
start_place_symbol(mx, my);
|
2020-08-08 15:47:34 +02:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='s' && state & Mod1Mask) /* reload */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-12-17 03:29:53 +01:00
|
|
|
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] "
|
|
|
|
|
"-message {Are you sure you want to reload from disk?}");
|
2020-08-16 03:34:45 +02:00
|
|
|
if(strcmp(tclresult(),"ok")==0) {
|
2020-08-08 15:47:34 +02:00
|
|
|
char filename[PATH_MAX];
|
|
|
|
|
unselect_all();
|
|
|
|
|
remove_symbols();
|
2020-10-15 17:39:21 +02:00
|
|
|
my_strncpy(filename, abs_sym_path(xctx->sch[xctx->currsch], ""), S(filename));
|
2020-08-08 15:47:34 +02:00
|
|
|
load_schematic(1, filename, 1);
|
|
|
|
|
draw();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='o' && state == ControlMask) /* load */
|
|
|
|
|
{
|
2020-10-20 19:48:59 +02:00
|
|
|
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
ask_new_file();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='S' && state == ShiftMask) /* change element order */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
change_elem_order();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='k' && state==Mod1Mask) /* select whole net (all attached wires/labels/pins) */
|
|
|
|
|
{
|
2020-11-16 15:44:51 +01:00
|
|
|
select_hilight_net();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='k' && state==ControlMask) /* unhilight net */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
unhilight_net();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='K' && state==(ControlMask|ShiftMask)) /* hilight net drilling thru elements */
|
2021-01-02 20:33:34 +01:00
|
|
|
/* with 'propag=' prop set on pins */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-10-25 17:05:43 +02:00
|
|
|
xctx->enable_drill=1;
|
2020-08-08 15:47:34 +02:00
|
|
|
hilight_net(0);
|
2021-01-08 21:25:11 +01:00
|
|
|
redraw_hilights(0);
|
2020-08-08 15:47:34 +02:00
|
|
|
/* draw_hilight_net(1); */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='k' && state==0) /* hilight net */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-10-25 17:05:43 +02:00
|
|
|
xctx->enable_drill=0;
|
2020-08-08 15:47:34 +02:00
|
|
|
hilight_net(0);
|
2021-01-08 21:25:11 +01:00
|
|
|
redraw_hilights(0);
|
2020-08-08 15:47:34 +02:00
|
|
|
/* draw_hilight_net(1); */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='K' && state == ShiftMask) /* delete hilighted nets */
|
|
|
|
|
{
|
2020-10-12 13:13:31 +02:00
|
|
|
xRect boundbox;
|
2020-10-18 13:53:58 +02:00
|
|
|
int big = xctx->wires> 2000 || xctx->instances > 2000 ;
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-10-25 17:05:43 +02:00
|
|
|
xctx->enable_drill=0;
|
2020-10-18 13:53:58 +02:00
|
|
|
if(!big) calc_drawing_bbox(&boundbox, 2);
|
2020-12-25 04:37:53 +01:00
|
|
|
clear_all_hilights();
|
2020-08-08 15:47:34 +02:00
|
|
|
/* undraw_hilight_net(1); */
|
2020-10-18 13:53:58 +02:00
|
|
|
if(!big) {
|
2020-11-03 12:10:55 +01:00
|
|
|
bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
|
2020-10-18 13:53:58 +02:00
|
|
|
bbox(ADD, boundbox.x1, boundbox.y1, boundbox.x2, boundbox.y2);
|
|
|
|
|
bbox(SET , 0.0 , 0.0 , 0.0 , 0.0);
|
|
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-10-18 13:53:58 +02:00
|
|
|
if(!big) bbox(END , 0.0 , 0.0 , 0.0 , 0.0);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2021-09-19 00:21:20 +02:00
|
|
|
if(key=='g' && state==Mod1Mask) { /* highlight net and send to viewer */
|
|
|
|
|
int tool = 0;
|
|
|
|
|
int exists = 0;
|
|
|
|
|
char *tool_name = NULL;
|
|
|
|
|
char str[200];
|
|
|
|
|
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-09-19 00:21:20 +02:00
|
|
|
tcleval("info exists sim");
|
|
|
|
|
if(tclresult()[0] == '1') exists = 1;
|
2021-10-25 17:05:43 +02:00
|
|
|
xctx->enable_drill = 0;
|
2021-09-19 00:21:20 +02:00
|
|
|
if(exists) {
|
|
|
|
|
tool = atol(tclgetvar("sim(spicewave,default)"));
|
|
|
|
|
my_snprintf(str, S(str), "sim(spicewave,%d,name)", tool);
|
|
|
|
|
my_strdup(1271, &tool_name, tclgetvar(str));
|
|
|
|
|
dbg(1,"callback(): tool_name=%s\n", tool_name);
|
|
|
|
|
if(strstr(tool_name, "Gaw")) tool=GAW;
|
|
|
|
|
else if(strstr(tool_name, "Bespice")) tool=BESPICE;
|
|
|
|
|
if(tool) {
|
|
|
|
|
hilight_net(tool);
|
|
|
|
|
redraw_hilights(0);
|
|
|
|
|
}
|
|
|
|
|
my_free(1272, &tool_name);
|
|
|
|
|
}
|
|
|
|
|
Tcl_ResetResult(interp);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='g' && state==0) /* half snap factor */
|
|
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
set_snap(c_snap / 2.0);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='g' && state==ControlMask) /* set snap factor 20161212 */
|
|
|
|
|
{
|
|
|
|
|
my_snprintf(str, S(str),
|
2020-10-12 13:13:31 +02:00
|
|
|
"input_line {Enter snap value (default: %.16g current: %.16g)} {xschem set cadsnap} {%g} 10",
|
2021-11-10 13:43:08 +01:00
|
|
|
CADSNAP, c_snap, c_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval(str);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='G' && state==ShiftMask) /* double snap factor */
|
|
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
set_snap(c_snap * 2.0);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='*' && state==(Mod1Mask|ShiftMask) ) /* svg print , 20121108 */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-22 00:13:25 +01:00
|
|
|
svg_draw();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='*' && state==ShiftMask ) /* postscript print */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-06-13 23:55:17 +02:00
|
|
|
ps_draw(7);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='*' && state==(ControlMask|ShiftMask) ) /* xpm print */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-22 00:13:25 +01:00
|
|
|
print_image();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='u' && state==Mod1Mask) /* align to grid */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-29 11:52:32 +01:00
|
|
|
xctx->push_undo();
|
2021-11-10 13:43:08 +01:00
|
|
|
round_schematic_to_grid(c_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
set_modify(1);
|
2021-11-10 13:43:08 +01:00
|
|
|
if(tclgetboolvar("autotrim_wires")) trim_wires();
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->prep_hash_inst=0;
|
|
|
|
|
xctx->prep_hash_wires=0;
|
|
|
|
|
xctx->prep_net_structs=0;
|
|
|
|
|
xctx->prep_hi_structs=0;
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-08-11 00:31:10 +02:00
|
|
|
if(0 && (key=='u') && (state==ControlMask)) /* testmode */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
int mult;
|
2020-08-10 09:16:11 +02:00
|
|
|
remove_symbol(2);
|
2021-01-22 01:03:16 +01:00
|
|
|
link_symbols_to_instances(-1);
|
2020-08-08 15:47:34 +02:00
|
|
|
expandlabel("/RST", &mult);
|
|
|
|
|
expandlabel("/CCC[3:0]", &mult);
|
|
|
|
|
expandlabel("CCC[AA:BB:DD]", &mult);
|
|
|
|
|
expandlabel("CCC[9:1:2]", &mult);
|
|
|
|
|
expandlabel("CCC[10:BB:DD]", &mult);
|
|
|
|
|
expandlabel("CCC[10..BB..DD]", &mult);
|
|
|
|
|
expandlabel("CCC[10..0..2]", &mult);
|
|
|
|
|
expandlabel("123", &mult);
|
|
|
|
|
expandlabel("123AA", &mult);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='u' && state==0) /* undo */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-29 11:52:32 +01:00
|
|
|
xctx->pop_undo(0, 1); /* 2nd parameter: set_modify_status */
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='U' && state==ShiftMask) /* redo */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-29 11:52:32 +01:00
|
|
|
xctx->pop_undo(1, 1); /* 2nd parameter: set_modify_status */
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='&') /* check wire connectivity */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-29 11:52:32 +01:00
|
|
|
xctx->push_undo();
|
2020-08-08 15:47:34 +02:00
|
|
|
trim_wires();
|
|
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='l' && state == ControlMask) { /* create schematic from selected symbol 20171004 */
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
create_sch_from_sym();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='l' && state == 0) /* start line */
|
|
|
|
|
{
|
2021-01-05 01:24:45 +01:00
|
|
|
int prev_state = xctx->ui_state;
|
|
|
|
|
start_line(mx, my);
|
|
|
|
|
if(prev_state == STARTLINE) {
|
|
|
|
|
tcleval("set constrained_move 0" );
|
|
|
|
|
constrained_move=0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
if(key=='l' && state == Mod1Mask) { /* add pin label*/
|
2021-01-05 01:24:45 +01:00
|
|
|
place_net_label(1);
|
|
|
|
|
break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key >= '0' && key <= '4' && state == 0) { /* toggle pin logic level */
|
2021-01-05 01:24:45 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-01-11 19:31:47 +01:00
|
|
|
if(key == '4') logic_set(-1, 1);
|
2021-01-05 01:24:45 +01:00
|
|
|
else logic_set(key - '0', 1);
|
|
|
|
|
break;
|
2020-12-26 19:26:33 +01:00
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
if(key=='L' && state == (Mod1Mask | ShiftMask)) { /* add pin label*/
|
2020-10-24 23:00:41 +02:00
|
|
|
place_net_label(0);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='F' && state==ShiftMask) /* flip */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTMOVE) move_objects(FLIP,0,0,0);
|
|
|
|
|
else if(xctx->ui_state & STARTCOPY) copy_objects(FLIP);
|
2020-08-08 15:47:34 +02:00
|
|
|
else {
|
|
|
|
|
rebuild_selected_array();
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-11-03 12:10:55 +01:00
|
|
|
move_objects(START,0,0,0);
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->lastsel>1) move_objects(FLIP,0,0,0);
|
2020-08-08 15:47:34 +02:00
|
|
|
else move_objects(FLIP|ROTATELOCAL,0,0,0);
|
|
|
|
|
move_objects(END,0,0,0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='\\' && state==0) /* fullscreen */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2021-11-09 19:05:56 +01:00
|
|
|
|
|
|
|
|
dbg(1, "callback(): toggle fullscreen, winpath=%s\n", winpath);
|
|
|
|
|
toggle_fullscreen(winpath);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='f' && state==Mod1Mask) /* flip objects around their anchor points 20171208 */
|
|
|
|
|
{
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTMOVE) move_objects(FLIP|ROTATELOCAL,0,0,0);
|
|
|
|
|
else if(xctx->ui_state & STARTCOPY) copy_objects(FLIP|ROTATELOCAL);
|
2020-08-08 15:47:34 +02:00
|
|
|
else {
|
|
|
|
|
rebuild_selected_array();
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-11-03 12:10:55 +01:00
|
|
|
move_objects(START,0,0,0);
|
2020-08-08 15:47:34 +02:00
|
|
|
move_objects(FLIP|ROTATELOCAL,0,0,0);
|
|
|
|
|
move_objects(END,0,0,0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='R' && state==ShiftMask) /* rotate */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTMOVE) move_objects(ROTATE,0,0,0);
|
|
|
|
|
else if(xctx->ui_state & STARTCOPY) copy_objects(ROTATE);
|
2020-08-08 15:47:34 +02:00
|
|
|
else {
|
|
|
|
|
rebuild_selected_array();
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-11-03 12:10:55 +01:00
|
|
|
move_objects(START,0,0,0);
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->lastsel>1) move_objects(ROTATE,0,0,0);
|
2020-08-08 15:47:34 +02:00
|
|
|
else move_objects(ROTATE|ROTATELOCAL,0,0,0);
|
|
|
|
|
move_objects(END,0,0,0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='r' && state==Mod1Mask) /* rotate objects around their anchor points 20171208 */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTMOVE) move_objects(ROTATE|ROTATELOCAL,0,0,0);
|
|
|
|
|
else if(xctx->ui_state & STARTCOPY) copy_objects(ROTATE|ROTATELOCAL);
|
2020-08-08 15:47:34 +02:00
|
|
|
else {
|
|
|
|
|
rebuild_selected_array();
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-11-03 12:10:55 +01:00
|
|
|
move_objects(START,0,0,0);
|
2020-08-08 15:47:34 +02:00
|
|
|
move_objects(ROTATE|ROTATELOCAL,0,0,0);
|
|
|
|
|
move_objects(END,0,0,0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='m' && state==0 && !(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2022-01-03 18:43:34 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
|
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-11-03 12:10:55 +01:00
|
|
|
move_objects(START,0,0,0);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='c' && state==0 && /* duplicate selection */
|
2020-12-02 15:10:47 +01:00
|
|
|
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-11-03 12:10:55 +01:00
|
|
|
copy_objects(START);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='n' && state==Mod1Mask) /* empty schematic in new window */
|
2021-10-09 00:41:39 +02:00
|
|
|
{
|
|
|
|
|
if(xctx->semaphore >= 2) break;
|
|
|
|
|
tcleval("xschem new_window");
|
2021-10-09 10:25:24 +02:00
|
|
|
break;
|
2021-10-09 00:41:39 +02:00
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='N' && state==(ShiftMask|Mod1Mask) ) /* empty symbol in new window */
|
2021-10-09 00:41:39 +02:00
|
|
|
{
|
|
|
|
|
if(xctx->semaphore >= 2) break;
|
|
|
|
|
tcleval("xschem new_symbol_window");
|
2021-10-09 10:25:24 +02:00
|
|
|
break;
|
2021-10-09 00:41:39 +02:00
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='n' && state==ControlMask) /* new schematic */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("xschem clear SCHEMATIC");
|
2021-10-09 10:25:24 +02:00
|
|
|
break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
if(key=='N' && state==(ShiftMask|ControlMask) ) /* new symbol */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("xschem clear SYMBOL");
|
2021-10-09 10:25:24 +02:00
|
|
|
break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-11-28 16:41:35 +01:00
|
|
|
if(key=='n' && state==0) /* hierarchical netlist */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
yyparse_error = 0;
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-10-12 13:13:31 +02:00
|
|
|
unselect_all();
|
2020-08-08 15:47:34 +02:00
|
|
|
if(set_netlist_dir(0, NULL)) {
|
|
|
|
|
dbg(1, "callback(): -------------\n");
|
2021-11-16 22:28:10 +01:00
|
|
|
if(xctx->netlist_type == CAD_SPICE_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_spice_netlist(1);
|
2021-11-16 22:28:10 +01:00
|
|
|
else if(xctx->netlist_type == CAD_VHDL_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_vhdl_netlist(1);
|
2021-11-16 22:28:10 +01:00
|
|
|
else if(xctx->netlist_type == CAD_VERILOG_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_verilog_netlist(1);
|
2021-11-16 22:28:10 +01:00
|
|
|
else if(xctx->netlist_type == CAD_TEDAX_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_tedax_netlist(1);
|
|
|
|
|
else
|
2021-12-17 03:29:53 +01:00
|
|
|
if(has_x) tcleval("tk_messageBox -type ok -parent [xschem get topwindow] "
|
|
|
|
|
"-message {Please Set netlisting mode (Options menu)}");
|
2020-08-08 15:47:34 +02:00
|
|
|
|
|
|
|
|
dbg(1, "callback(): -------------\n");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-11-28 16:41:35 +01:00
|
|
|
if(key=='N' && state==ShiftMask) /* current level only netlist */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
yyparse_error = 0;
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-10-12 13:13:31 +02:00
|
|
|
unselect_all();
|
2020-08-08 15:47:34 +02:00
|
|
|
if( set_netlist_dir(0, NULL) ) {
|
|
|
|
|
dbg(1, "callback(): -------------\n");
|
2021-11-16 22:28:10 +01:00
|
|
|
if(xctx->netlist_type == CAD_SPICE_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_spice_netlist(0);
|
2021-11-16 22:28:10 +01:00
|
|
|
else if(xctx->netlist_type == CAD_VHDL_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_vhdl_netlist(0);
|
2021-11-16 22:28:10 +01:00
|
|
|
else if(xctx->netlist_type == CAD_VERILOG_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_verilog_netlist(0);
|
2021-11-16 22:28:10 +01:00
|
|
|
else if(xctx->netlist_type == CAD_TEDAX_NETLIST)
|
2020-08-08 15:47:34 +02:00
|
|
|
global_tedax_netlist(0);
|
|
|
|
|
else
|
2021-12-17 03:29:53 +01:00
|
|
|
if(has_x) tcleval("tk_messageBox -type ok -parent [xschem get topwindow] "
|
|
|
|
|
"-message {Please Set netlisting mode (Options menu)}");
|
2020-08-08 15:47:34 +02:00
|
|
|
dbg(1, "callback(): -------------\n");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='A' && state==ShiftMask) /* toggle show netlist */
|
|
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
int net_s;
|
|
|
|
|
net_s = tclgetboolvar("netlist_show");
|
|
|
|
|
net_s = !net_s;
|
|
|
|
|
if(net_s) {
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("alert_ { enabling show netlist window} {}");
|
|
|
|
|
tclsetvar("netlist_show","1");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tcleval("alert_ { disabling show netlist window } {}");
|
|
|
|
|
tclsetvar("netlist_show","0");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-12 13:13:31 +02:00
|
|
|
if(key=='>') {
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-10-26 00:04:13 +02:00
|
|
|
if(xctx->draw_single_layer< cadlayers-1) xctx->draw_single_layer++;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-12 13:13:31 +02:00
|
|
|
if(key=='<') {
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-10-26 00:04:13 +02:00
|
|
|
if(xctx->draw_single_layer>=0 ) xctx->draw_single_layer--;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key==':') /* toggle flat netlist (only spice) */
|
|
|
|
|
{
|
2021-11-17 23:12:17 +01:00
|
|
|
xctx->flat_netlist = !xctx->flat_netlist;
|
|
|
|
|
if(xctx->flat_netlist) {
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("alert_ { enabling flat netlist} {}");
|
|
|
|
|
tclsetvar("flat_netlist","1");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tcleval("alert_ { set hierarchical netlist } {}");
|
|
|
|
|
tclsetvar("flat_netlist","0");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='b' && state==0) /* merge schematic */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
|
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
merge_file(0, ""); /* 2nd parameter not used any more for merge 25122002 */
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-09-05 00:58:56 +02:00
|
|
|
if(key=='b' && state==Mod1Mask) /* hide/show instance details */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2021-11-16 22:28:10 +01:00
|
|
|
xctx->hide_symbols++;
|
|
|
|
|
if(xctx->hide_symbols >= 3) xctx->hide_symbols = 0;
|
|
|
|
|
tclsetintvar("hide_symbols", xctx->hide_symbols);
|
2020-09-05 00:58:56 +02:00
|
|
|
draw();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-24 23:46:19 +02:00
|
|
|
if(key=='D' && state==ShiftMask) /* delete files */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-10-24 23:46:19 +02:00
|
|
|
delete_files();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='x' && state == 0 ) /* new cad session */
|
|
|
|
|
{
|
2021-12-03 19:15:07 +01:00
|
|
|
new_window(NULL ,0);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if((key=='#') && !(state & ControlMask) )
|
|
|
|
|
{
|
|
|
|
|
check_unique_names(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if((key=='#') && (state & ControlMask) )
|
|
|
|
|
{
|
|
|
|
|
check_unique_names(1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if( 0 && (key==';') && (state & ControlMask) ) /* testmode: for performance testing */
|
|
|
|
|
{
|
2020-10-12 13:13:31 +02:00
|
|
|
draw_stuff();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-10-09 22:19:54 +02:00
|
|
|
if(0 && key=='~' && (state & ControlMask)) { /* testmode */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(0 && key=='|' && !(state & ControlMask)) { /* testmode */
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-10-09 22:19:54 +02:00
|
|
|
if(0 && key=='|' && (state & ControlMask)) /* testmode */
|
2020-08-08 15:47:34 +02:00
|
|
|
{
|
|
|
|
|
double w, x1, y1, x2, y2;
|
|
|
|
|
int i;
|
|
|
|
|
int snap=100;
|
|
|
|
|
|
|
|
|
|
clear_drawing();
|
2020-11-16 01:28:19 +01:00
|
|
|
for(i=0;i<5000; i++) {
|
2021-12-17 15:40:19 +01:00
|
|
|
w = (1+my_round(rand()%1200/snap))*snap;
|
|
|
|
|
x1 = 40000+my_round(rand()%30000/snap)*snap;
|
|
|
|
|
y1 = 40000+my_round(rand()%30000/snap)*snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
x2=x1+w;
|
|
|
|
|
y2=y1;
|
|
|
|
|
ORDER(x1, y1, x2, y2);
|
|
|
|
|
storeobject(-1, x1, y1, x2, y2 ,WIRE,0,0,NULL);
|
|
|
|
|
}
|
2020-11-16 01:28:19 +01:00
|
|
|
for(i=0;i<5000; i++) {
|
2021-12-17 15:40:19 +01:00
|
|
|
w = (1+my_round(rand()%1200/snap))*snap;
|
|
|
|
|
x1 = 40000+my_round(rand()%30000/snap)*snap;
|
|
|
|
|
y1 = 40000+my_round(rand()%30000/snap)*snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
x2=x1;
|
|
|
|
|
y2=y1+w;
|
|
|
|
|
ORDER(x1, y1, x2, y2);
|
|
|
|
|
storeobject(-1, x1, y1, x2, y2, WIRE,0,0,NULL);
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->prep_net_structs = 0;
|
|
|
|
|
xctx->prep_hi_structs = 0;
|
|
|
|
|
xctx->prep_hash_wires = 0;
|
2020-12-22 00:13:25 +01:00
|
|
|
zoom_full(1, 0, 1, 0.97);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(key=='f' && state == ControlMask) /* search */
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
tcleval("property_search");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='f' && state == 0 ) /* full zoom */
|
|
|
|
|
{
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 18:25:15 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-12-22 04:39:23 +01:00
|
|
|
if(xctx->ui_state == SELECTION)
|
|
|
|
|
zoom_full(1, 1, 3, 0.97);
|
|
|
|
|
else
|
|
|
|
|
zoom_full(1, 0, 1, 0.97);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if((key=='z' && state==ControlMask)) /* zoom out */
|
|
|
|
|
{
|
2020-10-12 13:13:31 +02:00
|
|
|
view_unzoom(0.0);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(key=='!')
|
|
|
|
|
{
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-08-08 15:47:34 +02:00
|
|
|
break_wires_at_pins();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ButtonPress: /* end operation */
|
2021-12-27 05:22:19 +01:00
|
|
|
dbg(1, "callback(): ButtonPress ui_state=%ld state=%d\n",xctx->ui_state,state);
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-26 14:33:54 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTPAN2) {
|
|
|
|
|
xctx->ui_state &=~STARTPAN2;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->mx_save = mx; xctx->my_save = my;
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2021-12-22 18:25:15 +01:00
|
|
|
if(button == Button3 && state == ControlMask && xctx->semaphore <2)
|
2021-01-03 12:37:15 +01:00
|
|
|
{
|
|
|
|
|
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
|
|
|
|
|
if(sel) select_connected_wires(1);
|
|
|
|
|
}
|
|
|
|
|
else if(button == Button3 && state == ShiftMask && xctx->semaphore <2)
|
|
|
|
|
{
|
|
|
|
|
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
|
|
|
|
|
if(sel) select_connected_wires(0);
|
|
|
|
|
}
|
|
|
|
|
else if(button == Button3 && state == 0 && xctx->semaphore <2) {
|
2021-11-04 01:13:44 +01:00
|
|
|
int ret;
|
2022-01-03 01:38:15 +01:00
|
|
|
const char *status;
|
2021-11-04 01:13:44 +01:00
|
|
|
int prev_state;
|
2022-01-03 01:38:15 +01:00
|
|
|
xctx->semaphore++;
|
|
|
|
|
status = tcleval("context_menu");
|
|
|
|
|
xctx->semaphore--;
|
|
|
|
|
if(!status) break;
|
|
|
|
|
ret = atoi(status);
|
2021-11-04 01:13:44 +01:00
|
|
|
switch(ret) {
|
|
|
|
|
case 1:
|
|
|
|
|
start_place_symbol(mx, my);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
prev_state = xctx->ui_state;
|
|
|
|
|
start_wire(mx, my);
|
|
|
|
|
if(prev_state == STARTWIRE) {
|
|
|
|
|
tcleval("set constrained_move 0" );
|
|
|
|
|
constrained_move=0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
prev_state = xctx->ui_state;
|
|
|
|
|
start_line(mx, my);
|
|
|
|
|
if(prev_state == STARTLINE) {
|
|
|
|
|
tcleval("set constrained_move 0" );
|
|
|
|
|
constrained_move=0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
|
|
|
|
xctx->last_command = 0;
|
|
|
|
|
new_rect(PLACE);
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
|
|
|
|
xctx->last_command = 0;
|
|
|
|
|
new_polygon(PLACE);
|
|
|
|
|
break;
|
2021-11-06 03:24:45 +01:00
|
|
|
case 6: /* place text */
|
2021-11-04 01:13:44 +01:00
|
|
|
xctx->last_command = 0;
|
2021-11-04 13:30:50 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2021-11-06 03:24:45 +01:00
|
|
|
if(place_text(0, xctx->mousex_snap, xctx->mousey_snap)) { /* 1 = draw text */
|
|
|
|
|
xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
xctx->mousex_snap = xctx->mx_double_save;
|
|
|
|
|
move_objects(START,0,0,0);
|
|
|
|
|
xctx->ui_state |= PLACE_TEXT;
|
|
|
|
|
}
|
2021-11-04 01:13:44 +01:00
|
|
|
break;
|
|
|
|
|
case 7: /* cut selection into clipboard */
|
|
|
|
|
rebuild_selected_array();
|
|
|
|
|
if(xctx->lastsel) { /* 20071203 check if something selected */
|
|
|
|
|
save_selection(2);
|
|
|
|
|
delete(1/* to_push_undo */);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 8: /* paste from clipboard */
|
|
|
|
|
merge_file(2,".sch");
|
|
|
|
|
break;
|
|
|
|
|
case 9: /* load most recent file */
|
2021-12-05 12:39:05 +01:00
|
|
|
tclvareval("xschem load [lindex $recentfile 0]", NULL);
|
2021-11-04 01:13:44 +01:00
|
|
|
break;
|
|
|
|
|
case 10: /* edit attributes */
|
2020-08-08 15:47:34 +02:00
|
|
|
edit_property(0);
|
2021-11-04 01:13:44 +01:00
|
|
|
break;
|
|
|
|
|
case 11: /* edit attributes in editor */
|
|
|
|
|
edit_property(1);
|
|
|
|
|
break;
|
|
|
|
|
case 12:
|
|
|
|
|
descend_schematic(0);
|
|
|
|
|
break;
|
|
|
|
|
case 13:
|
|
|
|
|
descend_symbol();
|
|
|
|
|
break;
|
|
|
|
|
case 14:
|
|
|
|
|
go_back(1);
|
|
|
|
|
break;
|
|
|
|
|
case 15: /* copy selection into clipboard */
|
|
|
|
|
rebuild_selected_array();
|
|
|
|
|
if(xctx->lastsel) {
|
|
|
|
|
save_selection(2);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 16: /* move selection */
|
|
|
|
|
if(!(xctx->ui_state & (STARTMOVE | STARTCOPY))) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
|
|
|
|
move_objects(START,0,0,0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 17: /* duplicate selection */
|
|
|
|
|
if(!(xctx->ui_state & (STARTMOVE | STARTCOPY))) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
|
|
|
|
copy_objects(START);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 18: /* delete selection */
|
|
|
|
|
if(xctx->ui_state & SELECTION) delete(1/* to_push_undo */);
|
|
|
|
|
break;
|
|
|
|
|
case 19: /* place arc */
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
|
|
|
|
xctx->last_command = 0;
|
|
|
|
|
new_arc(PLACE, 180.);
|
|
|
|
|
break;
|
|
|
|
|
case 20: /* place circle */
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
|
|
|
|
xctx->last_command = 0;
|
|
|
|
|
new_arc(PLACE, 360.);
|
|
|
|
|
break;
|
2021-11-04 02:07:41 +01:00
|
|
|
case 21: /* abort & redraw */
|
|
|
|
|
abort_operation();
|
|
|
|
|
break;
|
2021-11-04 01:13:44 +01:00
|
|
|
default:
|
|
|
|
|
break;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-12-22 18:25:15 +01:00
|
|
|
else if(button==Button5 && state == 0 ) {
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 18:25:15 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
view_unzoom(CADZOOMSTEP);
|
|
|
|
|
}
|
|
|
|
|
else if(button==Button4 && state == 0 ) {
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 18:25:15 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
view_zoom(CADZOOMSTEP);
|
|
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
else if(button==Button4 && (state & ShiftMask) && !(state & Button2Mask)) {
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 18:25:15 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->xorigin+=-CADMOVESTEP*xctx->zoom/2.;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
else if(button==Button5 && (state & ShiftMask) && !(state & Button2Mask)) {
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-22 18:25:15 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->xorigin-=-CADMOVESTEP*xctx->zoom/2.;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
else if(button==Button4 && (state & ControlMask) && !(state & Button2Mask)) {
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->yorigin+=-CADMOVESTEP*xctx->zoom/2.;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
else if(button==Button5 && (state & ControlMask) && !(state & Button2Mask)) {
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->yorigin-=-CADMOVESTEP*xctx->zoom/2.;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
}
|
|
|
|
|
else if(button==Button1 && (state & Mod1Mask) ) {
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->last_command = 0;
|
|
|
|
|
xctx->mx_save = mx; xctx->my_save = my;
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-09-07 09:34:41 +02:00
|
|
|
|
|
|
|
|
/* useless code ? 20200905 */
|
2020-12-03 04:20:05 +01:00
|
|
|
/* if(xctx->semaphore<2) {
|
2020-08-08 15:47:34 +02:00
|
|
|
rebuild_selected_array();
|
2020-09-07 09:34:41 +02:00
|
|
|
} */
|
|
|
|
|
|
2020-12-02 15:10:47 +01:00
|
|
|
select_object(xctx->mousex, xctx->mousey, 0, 0);
|
2020-12-25 15:14:41 +01:00
|
|
|
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
else if(button==Button2 && (state == 0)) {
|
2020-11-03 12:10:55 +01:00
|
|
|
pan2(START, mx, my);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state |= STARTPAN2;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-03 04:20:05 +01:00
|
|
|
else if(xctx->semaphore >= 2) { /* button1 click to select another instance while edit prop dialog open */
|
2020-08-16 03:34:45 +02:00
|
|
|
if(button==Button1 && state==0 && tclgetvar("edit_symbol_prop_new_sel")[0]) {
|
|
|
|
|
tcleval("set edit_symbol_prop_new_sel 1; .dialog.f1.b1 invoke"); /* invoke 'OK' of edit prop dialog */
|
2020-08-16 09:41:39 +02:00
|
|
|
} else if(button==Button1 && (state & ShiftMask) && tclgetvar("edit_symbol_prop_new_sel")[0]) {
|
2020-12-02 15:10:47 +01:00
|
|
|
select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
|
2020-08-16 09:41:39 +02:00
|
|
|
rebuild_selected_array();
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(button==Button1)
|
|
|
|
|
{
|
2021-11-10 13:43:08 +01:00
|
|
|
if(tclgetboolvar("persistent_command") && xctx->last_command) {
|
2020-12-06 16:10:22 +01:00
|
|
|
if(xctx->last_command == STARTLINE) start_line(mx, my);
|
|
|
|
|
if(xctx->last_command == STARTWIRE) start_wire(mx, my);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTWIRE) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
|
|
|
|
new_wire(PLACE, xctx->mousex_snap, xctx->mousey_snap);
|
|
|
|
|
xctx->ui_state &=~MENUSTARTWIRE;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTSNAPWIRE) {
|
2020-08-08 15:47:34 +02:00
|
|
|
double x, y;
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2020-12-02 15:10:47 +01:00
|
|
|
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
2021-12-17 15:40:19 +01:00
|
|
|
xctx->mx_double_save = my_round(x / c_snap) * c_snap;
|
|
|
|
|
xctx->my_double_save = my_round(y / c_snap) * c_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_wire(PLACE, x, y);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~MENUSTARTSNAPWIRE;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTLINE) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_line(PLACE);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~MENUSTARTLINE;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTRECT) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_rect(PLACE);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~MENUSTARTRECT;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTPOLYGON) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_polygon(PLACE);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~MENUSTARTPOLYGON;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTARC) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_arc(PLACE, 180.);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~MENUSTARTARC;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTCIRCLE) {
|
|
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_arc(PLACE, 360.);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~MENUSTARTCIRCLE;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & MENUSTARTZOOM) {
|
2020-12-22 00:13:25 +01:00
|
|
|
zoom_rectangle(START);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~MENUSTARTZOOM;
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTPAN) {
|
2020-08-08 15:47:34 +02:00
|
|
|
pan(END);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTZOOM) {
|
2020-12-22 00:13:25 +01:00
|
|
|
zoom_rectangle(END);
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTWIRE) {
|
2021-11-10 13:43:08 +01:00
|
|
|
if(tclgetboolvar("persistent_command")) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move != 2) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move != 1) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-12-02 15:10:47 +01:00
|
|
|
new_wire(PLACE, xctx->mousex_snap, xctx->mousey_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
|
|
|
|
|
} else {
|
2020-12-02 15:10:47 +01:00
|
|
|
new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap);
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
constrained_move=0;
|
|
|
|
|
tcleval("set constrained_move 0" );
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTARC) {
|
2020-08-08 15:47:34 +02:00
|
|
|
new_arc(SET, 0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTLINE) {
|
2021-11-10 13:43:08 +01:00
|
|
|
if(tclgetboolvar("persistent_command")) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move != 2) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) {
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_line(PLACE);
|
|
|
|
|
} else {
|
|
|
|
|
new_line(PLACE|END);
|
|
|
|
|
}
|
2021-01-05 01:24:45 +01:00
|
|
|
constrained_move=0;
|
|
|
|
|
tcleval("set constrained_move 0" );
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTRECT) {
|
2020-08-08 15:47:34 +02:00
|
|
|
new_rect(PLACE|END);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTPOLYGON) {
|
2021-01-05 01:24:45 +01:00
|
|
|
if(constrained_move == 1) xctx->mousey_snap = xctx->my_double_save;
|
|
|
|
|
if(constrained_move == 2) xctx->mousex_snap = xctx->mx_double_save;
|
2020-08-08 15:47:34 +02:00
|
|
|
new_polygon(ADD);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2021-01-05 01:24:45 +01:00
|
|
|
constrained_move=0;
|
|
|
|
|
tcleval("set constrained_move 0" );
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTMOVE) {
|
2020-08-08 15:47:34 +02:00
|
|
|
move_objects(END,0,0,0);
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->ui_state &=~START_SYMPIN;
|
2021-01-05 01:24:45 +01:00
|
|
|
constrained_move=0;
|
|
|
|
|
tcleval("set constrained_move 0" );
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTCOPY) {
|
2020-08-08 15:47:34 +02:00
|
|
|
copy_objects(END);
|
2021-01-05 01:24:45 +01:00
|
|
|
constrained_move=0;
|
|
|
|
|
tcleval("set constrained_move 0" );
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if( !(xctx->ui_state & STARTSELECT) && !(xctx->ui_state & STARTWIRE) && !(xctx->ui_state & STARTLINE) ) {
|
|
|
|
|
int prev_last_sel = xctx->lastsel;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->mx_save = mx; xctx->my_save = my;
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-08-08 15:47:34 +02:00
|
|
|
if( !(state & ShiftMask) && !(state & Mod1Mask) ) {
|
|
|
|
|
unselect_all();
|
|
|
|
|
#ifndef __unix__
|
2020-12-06 02:10:53 +01:00
|
|
|
XCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gctiled, xctx->xrect[0].x, xctx->xrect[0].y,
|
2020-12-03 11:42:06 +01:00
|
|
|
xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y);
|
2020-08-08 15:47:34 +02:00
|
|
|
#endif
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
|
2020-09-01 10:50:08 +02:00
|
|
|
rebuild_selected_array();
|
2020-08-08 15:47:34 +02:00
|
|
|
#ifndef __unix__
|
2021-11-16 22:28:10 +01:00
|
|
|
draw_selection(xctx->gc[SELLAYER], 0); /* 20181009 moved outside of cadlayers loop */
|
2020-08-08 15:47:34 +02:00
|
|
|
#endif
|
2020-10-12 13:13:31 +02:00
|
|
|
if(sel && state == ControlMask) {
|
2020-08-08 15:47:34 +02:00
|
|
|
launcher();
|
|
|
|
|
}
|
|
|
|
|
if( !(state & ShiftMask) ) {
|
2021-11-10 13:43:08 +01:00
|
|
|
if(tclgetboolvar("auto_hilight") && xctx->hilight_nets && sel == 0 ) { /* 20160413 20160503 */
|
2020-09-01 10:50:08 +02:00
|
|
|
if(!prev_last_sel) {
|
2021-01-08 21:25:11 +01:00
|
|
|
redraw_hilights(1); /* 1: clear all hilights, then draw */
|
2020-09-01 10:50:08 +02:00
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-11-10 13:43:08 +01:00
|
|
|
if(tclgetboolvar("auto_hilight")) {
|
2020-08-08 15:47:34 +02:00
|
|
|
hilight_net(0);
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->lastsel) {
|
2021-01-08 21:25:11 +01:00
|
|
|
redraw_hilights(0);
|
2020-08-08 15:47:34 +02:00
|
|
|
/* draw_hilight_net(1); */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} /* button==Button1 */
|
|
|
|
|
break;
|
|
|
|
|
case ButtonRelease:
|
2021-12-30 15:45:38 +01:00
|
|
|
if(waves_selected(event, key, state, button)) {
|
2021-12-27 05:22:19 +01:00
|
|
|
waves_callback(event, mx, my, key, button, aux, state);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTPAN2) {
|
|
|
|
|
xctx->ui_state &=~STARTPAN2;
|
2020-12-06 16:10:22 +01:00
|
|
|
xctx->mx_save = mx; xctx->my_save = my;
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mx_double_save=xctx->mousex_snap;
|
|
|
|
|
xctx->my_double_save=xctx->mousey_snap;
|
2020-12-29 03:45:12 +01:00
|
|
|
redraw_w_a_l_r_p_rubbers();
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-06 16:40:08 +01:00
|
|
|
dbg(1, "callback(): ButtonRelease ui_state=%ld state=%d\n",xctx->ui_state,state);
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state & STARTSELECT) {
|
2020-08-08 15:47:34 +02:00
|
|
|
if(state & ControlMask) {
|
2021-11-10 13:43:08 +01:00
|
|
|
tclsetvar("enable_stretch", "1");
|
2020-08-08 15:47:34 +02:00
|
|
|
select_rect(END,-1);
|
2021-11-10 13:43:08 +01:00
|
|
|
tclsetvar("enable_stretch", "0");
|
2020-08-08 15:47:34 +02:00
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
/* 20150927 filter out button4 and button5 events */
|
|
|
|
|
if(!(state&(Button4Mask|Button5Mask) ) ) select_rect(END,-1);
|
|
|
|
|
}
|
2020-09-01 10:50:08 +02:00
|
|
|
rebuild_selected_array();
|
2020-10-12 13:13:31 +02:00
|
|
|
my_snprintf(str, S(str), "mouse = %.16g %.16g - selected: %d path: %s",
|
2020-12-02 15:10:47 +01:00
|
|
|
xctx->mousex_snap, xctx->mousey_snap, xctx->lastsel, xctx->sch_path[xctx->currsch] );
|
2020-09-01 10:50:08 +02:00
|
|
|
statusmsg(str,1);
|
|
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case -3: /* double click : edit prop */
|
2020-12-03 04:20:05 +01:00
|
|
|
if(xctx->semaphore >= 2) break;
|
2020-12-06 16:40:08 +01:00
|
|
|
dbg(1, "callback(): DoubleClick ui_state=%ld state=%d\n",xctx->ui_state,state);
|
2020-08-08 15:47:34 +02:00
|
|
|
if(button==Button1) {
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state == STARTWIRE) {
|
|
|
|
|
xctx->ui_state &= ~STARTWIRE;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if(xctx->ui_state == STARTLINE) {
|
|
|
|
|
xctx->ui_state &= ~STARTLINE;
|
2020-08-08 15:47:34 +02:00
|
|
|
}
|
2020-12-02 15:10:47 +01:00
|
|
|
if( (xctx->ui_state & STARTPOLYGON) && (state ==0 ) ) {
|
2020-08-08 15:47:34 +02:00
|
|
|
new_polygon(SET);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#ifndef __unix__
|
|
|
|
|
case MOUSE_WHEEL_UP: /* windows do not use button4 and button5 like X */
|
|
|
|
|
{
|
2020-10-15 17:39:21 +02:00
|
|
|
xctx->xorigin += -CADMOVESTEP * xctx->zoom / 2.;
|
2020-08-08 15:47:34 +02:00
|
|
|
draw();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2020-08-08 15:47:34 +02:00
|
|
|
default:
|
|
|
|
|
dbg(1, "callback(): Event:%d\n",event);
|
|
|
|
|
break;
|
2021-11-16 22:28:10 +01:00
|
|
|
} /* switch(event) */
|
2020-10-12 13:13:31 +02:00
|
|
|
|
2020-12-03 04:20:05 +01:00
|
|
|
xctx->semaphore--;
|
2021-11-16 22:28:10 +01:00
|
|
|
if(redraw_only) {
|
|
|
|
|
xctx->semaphore--; /* decrement articially incremented semaphore (see above) */
|
|
|
|
|
dbg(1, "callback(): semaphore >=2 restoring window context: %s <-- %s\n", old_winpath, winpath);
|
|
|
|
|
if(old_winpath[0]) new_schematic("switch", xctx->top_path, old_winpath, "");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if(strcmp(old_winpath, winpath)) {
|
|
|
|
|
if(old_winpath[0]) dbg(1, "callback(): reset old_winpath: %s <- %s\n", old_winpath, winpath);
|
|
|
|
|
my_strncpy(old_winpath, winpath, S(old_winpath));
|
|
|
|
|
}
|
2020-08-08 15:47:34 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|