Merge pull request #4 from TheSUPERCD/upstream-clone

Resolved merge conflicts and update fork with upstream changes
This commit is contained in:
Chayan Deb 2025-01-26 11:32:20 +05:30 committed by GitHub
commit 7740c0706f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 179 additions and 113 deletions

View File

@ -3879,7 +3879,7 @@ void fix_restore_rect(double x1, double y1, double x2, double y2)
/* 20150927 select=1: select objects, select=0: unselect objects */
void select_rect(int what, int select)
void select_rect(int stretch, int what, int select)
{
int incremental_select = tclgetboolvar("incremental_select");
int sel_touch = tclgetboolvar("select_touch");
@ -3901,7 +3901,7 @@ void select_rect(int what, int select)
draw_selection(xctx->gc[SELLAYER], 0);
if(!xctx->nl_sel || (incremental_select && xctx->nl_dir == 0))
select_inside(xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2, xctx->nl_sel);
select_inside(stretch, xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2, xctx->nl_sel);
else if(incremental_select && xctx->nl_dir == 1 && sel_touch)
select_touch(xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2, xctx->nl_sel);
xctx->nl_xx1=xctx->nl_xr;xctx->nl_xx2=xctx->nl_xr2;xctx->nl_yy1=xctx->nl_yr;xctx->nl_yy2=xctx->nl_yr2;
@ -3935,7 +3935,7 @@ void select_rect(int what, int select)
drawtemprect(xctx->gctiled, NOW, xctx->nl_xr,xctx->nl_yr,xctx->nl_xr2,xctx->nl_yr2);
if(!sel_touch || xctx->nl_dir == 0)
select_inside(xctx->nl_xr,xctx->nl_yr,xctx->nl_xr2,xctx->nl_yr2, xctx->nl_sel);
select_inside(stretch, xctx->nl_xr,xctx->nl_yr,xctx->nl_xr2,xctx->nl_yr2, xctx->nl_sel);
else
select_touch(xctx->nl_xr,xctx->nl_yr,xctx->nl_xr2,xctx->nl_yr2, xctx->nl_sel);

View File

@ -74,7 +74,7 @@ static int waves_selected(int event, KeySym key, int state, int button)
if(! (xctx->ui_state & GRAPHPAN) ) {
xctx->graph_master = i;
}
if(draw_xhair) draw_crosshair(1);
if(draw_xhair) draw_crosshair(1); /* remove crosshair, re-enable mouse cursor */
tclvareval(xctx->top_path, ".drw configure -cursor tcross" , NULL);
break;
}
@ -1372,28 +1372,28 @@ void draw_crosshair(int what)
if(fix_broken_tiled_fill || !_unix) {
if(xhair_size) {
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size,
4 * INT_WIDTH(xctx->lw) + 4 * xhair_size,
4 * INT_WIDTH(xctx->lw) + 4 * xhair_size,
(int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size);
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size);
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size,
4 * INT_WIDTH(xctx->lw) + 4 * xhair_size,
4 * INT_WIDTH(xctx->lw) + 4 * xhair_size,
(int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size);
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size);
} else { /* full screen span xhair */
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw),
xctx->xrect[0].width, 4 * INT_WIDTH(xctx->lw),
0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw));
0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw),
xctx->xrect[0].width, 2 * INT_WIDTH(xctx->lw),
0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw));
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0,
4 * INT_WIDTH(xctx->lw), xctx->xrect[0].height,
(int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0);
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw), 0,
2 * INT_WIDTH(xctx->lw), xctx->xrect[0].height,
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw), 0);
}
} else {
@ -1758,8 +1758,7 @@ static int check_menu_start_commands(double c_snap)
return 0;
}
static int add_wire_from_inst_pin(Selected *sel, double mx, double my)
static int add_wire_from_inst(Selected *sel, double mx, double my)
{
int res = 0;
int prev_state = xctx->ui_state;
@ -1785,7 +1784,16 @@ static int add_wire_from_inst_pin(Selected *sel, double mx, double my)
}
res = 1;
}
} else if(type == WIRE) {
}
return res;
}
static int add_wire_from_wire(Selected *sel, double mx, double my)
{
int res = 0;
int prev_state = xctx->ui_state;
int type = sel->type;
if(type == WIRE) {
int n = sel->n;
double x1 = xctx->wire[n].x1;
double y1 = xctx->wire[n].y1;
@ -1804,7 +1812,6 @@ static int add_wire_from_inst_pin(Selected *sel, double mx, double my)
return res;
}
/* sets xctx->shape_point_selected */
static int edit_line_point(int state)
{
@ -1842,7 +1849,7 @@ static int edit_line_point(int state)
static int edit_wire_point(int state)
{
int wire_n = -1;
dbg(1, "1 Wire selected\n");
dbg(1, "edit_wire_point\n");
wire_n = xctx->sel_array[0].n;
/* wire point: Check is user is clicking a control point of a wire */
if(wire_n >= 0) {
@ -2366,7 +2373,9 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
#else
XKeyboardState kbdstate;
#endif
int enable_stretch = tclgetboolvar("enable_stretch");
int draw_xhair = tclgetboolvar("draw_crosshair");
int crosshair_size = tclgetintvar("crosshair_size");
int infix_interface = tclgetboolvar("infix_interface");
int snap_cursor = tclgetboolvar("snap_cursor");
int wire_draw_active = (xctx->ui_state & STARTWIRE) ||
@ -2498,7 +2507,7 @@ int rstate; /* (reduced state, without ShiftMask) */
dbg(2, "callback(): Enter event, ui_state=%d\n", xctx->ui_state);
xctx->mouse_inside = 1;
if(draw_xhair) {
if(tclgetintvar("crosshair_size") == 0) {
if(crosshair_size == 0) {
tclvareval(xctx->top_path, ".drw configure -cursor none" , NULL);
}
} else
@ -2558,18 +2567,22 @@ int rstate; /* (reduced state, without ShiftMask) */
break;
}
if(draw_xhair) {
draw_crosshair(1);
draw_crosshair(1); /* when moving mouse: first action is delete crosshair, will be drawn later */
}
/* pan schematic */
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
if(xctx->ui_state & STARTPAN) pan(RUBBER, mx, my);
if(xctx->semaphore >= 2) {
if(draw_xhair) {
draw_crosshair(2);
draw_crosshair(2); /* locked UI: draw new crosshair and break out */
}
if(snap_cursor && wire_draw_active) draw_snap_cursor(2);
break;
}
dbg(1, "ui_state=%d deltax=%g\n", xctx->ui_state, xctx->deltax);
/* update status bar messages */
if(xctx->ui_state) {
if(abs(mx-xctx->mx_save) > 8 || abs(my-xctx->my_save) > 8 ) {
my_snprintf(str, S(str), "mouse = %.16g %.16g - selected: %d w=%.6g h=%.6g",
@ -2580,6 +2593,8 @@ int rstate; /* (reduced state, without ShiftMask) */
statusmsg(str,1);
}
}
/* update zoom rectangle drag */
if(xctx->ui_state & STARTZOOM) zoom_rectangle(RUBBER);
/* determine direction of a rectangle selection (or unselection with ALT key) */
@ -2588,26 +2603,32 @@ int rstate; /* (reduced state, without ShiftMask) */
if( (state & Button1Mask) && SET_MODMASK) {
if(mx >= xctx->mx_save) xctx->nl_dir = 0;
else xctx->nl_dir = 1;
select_rect(RUBBER,0);
select_rect(enable_stretch, RUBBER,0);
/* select by area : determine direction */
} else if(state & Button1Mask) {
if(mx >= xctx->mx_save) xctx->nl_dir = 0;
else xctx->nl_dir = 1;
select_rect(RUBBER,1);
select_rect(enable_stretch, RUBBER,1);
}
}
/* draw objects being moved */
if(xctx->ui_state & STARTMOVE) {
if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save;
if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save;
move_objects(RUBBER,0,0,0);
}
/* draw objects being copied */
if(xctx->ui_state & STARTCOPY) {
if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save;
if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save;
copy_objects(RUBBER);
}
/* draw moving objects being inserted, wires, arcs, lines, rectangles, polygons */
redraw_w_a_l_r_p_rubbers();
/* start of a mouse area select. Button1 pressed. No shift pressed
* Do not start an area select if user is dragging a polygon/bezier point */
if(!(xctx->ui_state & STARTPOLYGON) && (state&Button1Mask) && !(xctx->ui_state & STARTWIRE) &&
@ -2618,7 +2639,7 @@ int rstate; /* (reduced state, without ShiftMask) */
xctx->mouse_moved = 1;
if(!xctx->drag_elements) {
if( !(xctx->ui_state & STARTSELECT)) {
select_rect(START,1);
select_rect(enable_stretch, START,1);
xctx->onetime=1;
}
if(abs(mx-xctx->mx_save) > 8 ||
@ -2637,7 +2658,7 @@ int rstate; /* (reduced state, without ShiftMask) */
!(xctx->ui_state & STARTPAN) && !xctx->shape_point_selected &&
!(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT))) { /* unselect area */
if( !(xctx->ui_state & STARTSELECT)) {
select_rect(START,0);
select_rect(enable_stretch, START,0);
}
}
/* Select by area. Shift pressed */
@ -2646,7 +2667,7 @@ int rstate; /* (reduced state, without ShiftMask) */
!xctx->drag_elements && !(xctx->ui_state & STARTPAN) ) {
if(mx != xctx->mx_save || my != xctx->my_save) {
if( !(xctx->ui_state & STARTSELECT)) {
select_rect(START,1);
select_rect(enable_stretch, START,1);
}
if(abs(mx-xctx->mx_save) > 8 ||
abs(my-xctx->my_save) > 8 ) { /* set reasonable threshold before unsel */
@ -3287,16 +3308,8 @@ int rstate; /* (reduced state, without ShiftMask) */
}
if(key=='y' && rstate == 0) /* toggle stretching */
{
int en_s;
en_s = tclgetboolvar("enable_stretch");
en_s = !en_s;
if(en_s) {
tclsetvar("enable_stretch","1");
}
else {
tclsetvar("enable_stretch","0");
}
enable_stretch = !enable_stretch;
tclsetboolvar("enable_stretch", enable_stretch);
break;
}
if(key=='x' && EQUAL_MODMASK) /* toggle draw crosshair at mouse pos */
@ -3820,8 +3833,7 @@ int rstate; /* (reduced state, without ShiftMask) */
waves_callback(event, mx, my, key, button, aux, state);
break;
}
if(tclgetboolvar("enable_stretch"))
select_attached_nets(); /* stretch nets that land on selected instance pins */
if(enable_stretch) select_attached_nets(); /* stretch nets that land on selected instance pins */
if(infix_interface) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
@ -3856,8 +3868,7 @@ int rstate; /* (reduced state, without ShiftMask) */
waves_callback(event, mx, my, key, button, aux, state);
break;
}
if(!tclgetboolvar("enable_stretch"))
select_attached_nets(); /* stretch nets that land on selected instance pins */
if(!enable_stretch) select_attached_nets(); /* stretch nets that land on selected instance pins */
if(infix_interface) {
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
@ -3873,8 +3884,7 @@ int rstate; /* (reduced state, without ShiftMask) */
if(key=='M' && state == (ControlMask | ShiftMask) &&
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
{
if(!tclgetboolvar("enable_stretch"))
select_attached_nets(); /* stretch nets that land on selected instance pins */
if(!enable_stretch) select_attached_nets(); /* stretch nets that land on selected instance pins */
xctx->connect_by_kissing = 2; /* 2 will be used to reset var to 0 at end of move */
if(infix_interface) {
xctx->mx_double_save=xctx->mousex_snap;
@ -4179,31 +4189,37 @@ int rstate; /* (reduced state, without ShiftMask) */
}
break;
case ButtonPress: /* end operation */
case ButtonPress:
dbg(1, "callback(): ButtonPress ui_state=%d state=%d\n",xctx->ui_state,state);
if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
/* terminate a schematic pan action */
if(xctx->ui_state & STARTPAN) {
xctx->ui_state &=~STARTPAN;
break;
}
/* select instance and connected nets stopping at wire junctions */
if(button == Button3 && state == ControlMask && xctx->semaphore <2)
{
Selected sel;
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
if(sel.type) select_connected_nets(1);
}
/* break wire at mouse coordinates, move break point to nearest grid point */
else if(button == Button3 && EQUAL_MODMASK && !(state & ShiftMask) && xctx->semaphore <2)
{
break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1);
}
/* break wire at mouse coordinates */
else if(button == Button3 && EQUAL_MODMASK && (state & ShiftMask) && xctx->semaphore <2)
{
break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0);
}
/* select instance and connected nets NOT stopping at wire junctions */
else if(button == Button3 && state == ShiftMask && xctx->semaphore <2)
{
Selected sel;
@ -4216,6 +4232,8 @@ int rstate; /* (reduced state, without ShiftMask) */
* context_menu_action(xctx->mousex_snap, xctx->mousey_snap);
* }
*/
/* zoom rectangle by right clicking and drag */
else if(button == Button3 && state == 0 && xctx->semaphore < 2) {
zoom_rectangle(START);break;
}
@ -4236,10 +4254,13 @@ int rstate; /* (reduced state, without ShiftMask) */
select_object(xctx->mousex, xctx->mousey, 0, 0, NULL);
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
}
/* Middle button press (Button2) will pan the schematic. */
else if(button==Button2 && (state == 0)) {
pan(START, mx, my);
xctx->ui_state |= STARTPAN;
}
/* button1 click to select another instance while edit prop dialog open */
else if(button==Button1 && xctx->semaphore >= 2) {
if(tcleval("winfo exists .dialog.textinput")[0] == '1') { /* proc text_line */
@ -4256,11 +4277,15 @@ int rstate; /* (reduced state, without ShiftMask) */
rebuild_selected_array();
}
}
/* Handle the remaining Button1Press events */
else if(button==Button1) /* MOD button is not pressed here. Processed above */
{
xctx->onetime = 0;
xctx->mouse_moved = 0;
xctx->drag_elements = 0;
/* start another wire or line in persistent mode */
if(tclgetboolvar("persistent_command") && xctx->last_command) {
if(xctx->last_command == STARTLINE) start_line(xctx->mousex_snap, xctx->mousey_snap);
if(xctx->last_command == STARTWIRE){
@ -4279,7 +4304,8 @@ int rstate; /* (reduced state, without ShiftMask) */
}
/* handle all object insertions started from Tools/Edit menu */
if(check_menu_start_commands(c_snap)) break;
/* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
/* complete the pending STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
if(end_place_move_copy_zoom()) break;
/* Button1Press to select objects */
@ -4294,16 +4320,31 @@ int rstate; /* (reduced state, without ShiftMask) */
xctx->mx_double_save=xctx->mousex;
xctx->my_double_save=xctx->mousey;
/* Clicking on an instance pin -> drag a new wire
* if an instance is already selected */
#if 0 /* disabled */
/* Clicking and dragging from a **selected** instance pin will start a new wire
* if no other elements are selected */
if(xctx->lastsel == 1 && xctx->sel_array[0].type==ELEMENT) {
if(add_wire_from_inst_pin(&xctx->sel_array[0], xctx->mousex_snap, xctx->mousey_snap)) break;
if(add_wire_from_wire(&xctx->sel_array[0], xctx->mousex_snap, xctx->mousey_snap)) break;
if(add_wire_from_inst(&xctx->sel_array[0], xctx->mousex_snap, xctx->mousey_snap)) break;
}
#endif
/* In *NON* intuitive interface a button1 press with no modifiers will
* first unselect everything...
* For intuitive interface unselection see below... */
if(!xctx->intuitive_interface && no_shift_no_ctrl ) unselect_all(1);
if(draw_xhair) sel = find_closest_obj(xctx->mousex_snap, xctx->mousey_snap, 0);
else sel = find_closest_obj(xctx->mousex, xctx->mousey, 0);
/* find closest object. Use snap coordinates if full crosshair is enabled
* since the mouse pointer is obscured and crosshair is snapped to grid points */
if(draw_xhair && crosshair_size == 0) {
sel = find_closest_obj(xctx->mousex_snap, xctx->mousey_snap, 0);
} else {
sel = find_closest_obj(xctx->mousex, xctx->mousey, 0);
}
dbg(1, "sel.type=%d\n", sel.type);
/* determine if closest object was already selected when button1 was pressed */
switch(sel.type) {
case WIRE: if(xctx->wire[sel.n].sel) already_selected = 1; break;
case xTEXT: if(xctx->text[sel.n].sel) already_selected = 1; break;
@ -4315,42 +4356,65 @@ int rstate; /* (reduced state, without ShiftMask) */
default: break;
} /*end switch */
/* Clicking on an instance pin -> drag a new wire */
/* Clicking and drag on an instance pin -> drag a new wire */
if(xctx->intuitive_interface && !already_selected) {
if(add_wire_from_inst_pin(&sel, xctx->mousex_snap, xctx->mousey_snap)) break;
if(add_wire_from_inst(&sel, xctx->mousex_snap, xctx->mousey_snap)) break;
}
/* Clicking and drag on a wire end -> drag a new wire */
if(xctx->intuitive_interface && !already_selected) {
if(add_wire_from_wire(&sel, xctx->mousex_snap, xctx->mousey_snap)) break;
}
/* In intuitive interface a button1 press with no modifiers will
* unselect everything... we do it here */
if(xctx->intuitive_interface && !already_selected && no_shift_no_ctrl ) unselect_all(1);
/* select the object under the mouse and rebuild the selected array */
if(!already_selected) select_object(xctx->mousex, xctx->mousey, SELECTED, 0, &sel);
rebuild_selected_array();
dbg(1, "Button1Press to select objects, lastsel = %d\n", xctx->lastsel);
if(xctx->lastsel == 1 && xctx->sel_array[0].type==POLYGON)
if(edit_polygon_point(state)) break; /* sets xctx->shape_point_selected */
/* if clicking on some object endpoints or vertices set shape_point_selected
* this information will be used in Motion events to draw the stretched vertices */
if(xctx->lastsel == 1 && xctx->sel_array[0].type==POLYGON) {
if(edit_polygon_point(state)) break; /* sets xctx->shape_point_selected */
}
if(xctx->lastsel == 1 && xctx->intuitive_interface) {
int cond = already_selected;
if(xctx->lastsel == 1 && xctx->sel_array[0].type==xRECT)
if(edit_rect_point(state)) break; /* sets xctx->shape_point_selected */
if(cond && xctx->sel_array[0].type==xRECT) {
if(edit_rect_point(state)) break; /* sets xctx->shape_point_selected */
}
if(xctx->lastsel == 1 && xctx->sel_array[0].type==LINE)
if(edit_line_point(state)) break; /* sets xctx->shape_point_selected */
if(cond && xctx->sel_array[0].type==LINE) {
if(edit_line_point(state)) break; /* sets xctx->shape_point_selected */
}
if(xctx->lastsel == 1 && xctx->sel_array[0].type==WIRE)
if(cond && xctx->sel_array[0].type==WIRE) {
if(edit_wire_point(state)) break; /* sets xctx->shape_point_selected */
}
}
dbg(1, "shape_point_selected=%d, lastsel=%d\n", xctx->shape_point_selected, xctx->lastsel);
/* intuitive interface: directly drag elements */
if(sel.type && xctx->intuitive_interface && xctx->lastsel >= 1 &&
!xctx->shape_point_selected) {
/* xctx->push_undo(); */
int stretch = (state & ControlMask ? 1 : 0) ^ enable_stretch;
xctx->drag_elements = 1;
if( (state & ControlMask) && !(state & ShiftMask) && !tclgetboolvar("enable_stretch")) {
/* select attached nets depending on ControlMask and enable_stretch */
if(stretch && !(state & ShiftMask)) {
select_attached_nets(); /* stretch nets that land on selected instance pins */
}
/* if dragging instances with Ctrl and Shift down add wires to pins attached to something */
if(state == (ShiftMask | ControlMask) ) {
xctx->connect_by_kissing = 2; /* 2 will be used to reset var to 0 at end of move */
move_objects(START,0,0,0);
}
/* dragging away an object with Shift pressed is a copy (duplicate object) */
else if(state == ShiftMask) copy_objects(START);
/* else it is a move */
else move_objects(START,0,0,0);
}
@ -4375,7 +4439,8 @@ int rstate; /* (reduced state, without ShiftMask) */
waves_callback(event, mx, my, key, button, aux, state);
break;
}
dbg(1, "release: shape_point_selected=%d\n", xctx->shape_point_selected);
/* bring up context menu if no pending operation */
if(state == Button3Mask && xctx->semaphore <2) {
if(!end_place_move_copy_zoom()) {
context_menu_action(xctx->mousex_snap, xctx->mousey_snap);
@ -4442,14 +4507,11 @@ int rstate; /* (reduced state, without ShiftMask) */
if(xctx->semaphore >= 2) break;
if(xctx->ui_state & STARTSELECT) {
if(state & ControlMask) {
int es = tclgetboolvar("enable_stretch");
tclsetboolvar("enable_stretch", !es);
select_rect(END,-1);
tclsetboolvar("enable_stretch", es);
select_rect(!enable_stretch, END,-1);
} else {
/* Button1 release: end of rectangle select */
if(!(state & (Button4Mask|Button5Mask) ) ) {
select_rect(END,-1);
select_rect(enable_stretch, END,-1);
}
}
rebuild_selected_array();

View File

@ -375,13 +375,17 @@ static void find_closest_box(double mx ,double my, int override_lock)
{
double tmp;
double ds = xctx->cadhalfdotsize;
int i, c, r=-1, col = 0;
/* correction for very small boxes */
for(c=0;c<cadlayers; ++c)
{
if(!xctx->enable_layer[c]) continue;
for(i=0;i<xctx->rects[c]; ++i)
{
double min = MINOR(xctx->rect[c][i].x2 - xctx->rect[c][i].x1,
xctx->rect[c][i].y2 - xctx->rect[c][i].y1);
ds = (xctx->cadhalfdotsize * 8 <= min ) ? xctx->cadhalfdotsize : min / 8;
if( POINTINSIDE(mx, my, xctx->rect[c][i].x1 - ds, xctx->rect[c][i].y1 - ds,
xctx->rect[c][i].x2 + ds, xctx->rect[c][i].y2 + ds) )
{
@ -402,25 +406,25 @@ static void find_closest_box(double mx ,double my, int override_lock)
static void find_closest_element(double mx, double my, int override_lock)
{
double tmp;
int i, r=-1;
for(i=0;i<xctx->instances; ++i)
{
dbg(2, "find_closest_element(): %s: %g %g %g %g\n",
xctx->inst[i].instname, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
if( POINTINSIDE(mx, my, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2) )
double tmp;
int i, r=-1;
for(i = 0;i < xctx->instances; ++i)
{
tmp=pow(mx-(xctx->inst[i].xx1 + xctx->inst[i].xx2)/2, 2)+pow(my-(xctx->inst[i].yy1 + xctx->inst[i].yy2)/2, 2);
if(tmp*0.1 < distance)
{
r = i; distance = tmp*0.1;
}
dbg(2, "find_closest_element(): finding closest element, instances=%d, dist=%.16g\n", i, tmp);
dbg(1, "find_closest_element(): %s: %g %g %g %g\n",
xctx->inst[i].instname, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
if( POINTINSIDE(mx, my, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2) )
{
tmp=dist_from_rect(mx, my, xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2);
if(tmp < distance)
{
r = i; distance = tmp;
}
dbg(2, "find_closest_element(): finding closest element, instances=%d, dist=%.16g\n", i, tmp);
}
} /* end for i */
if( r != -1 && (override_lock || strboolcmp(get_tok_value(xctx->inst[r].prop_ptr, "lock", 0), "true")) ) {
sel.n = r; sel.type = ELEMENT;
}
} /* end for i */
if( r!=-1 && (override_lock || strboolcmp(get_tok_value(xctx->inst[r].prop_ptr, "lock", 0), "true")) ) {
sel.n = r; sel.type = ELEMENT;
}
}
static void find_closest_text(double mx, double my)

View File

@ -35,7 +35,7 @@ void compile_font(void)
for(code=0;code<127;code++)
{
unselect_all(1);
select_inside(code*FONTOFFSET-1,-FONTHEIGHT-1,
select_inside(0, code*FONTOFFSET-1,-FONTHEIGHT-1,
code*FONTOFFSET+FONTWIDTH+1,FONTWHITESPACE + FONTDESCENT+1, 1);
rebuild_selected_array();
character[code] = my_calloc(_ALLOC_ID_, xctx->lastsel*4+1, sizeof(double));

View File

@ -5018,7 +5018,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
y1 = atof(argv[3]);
x2 = atof(argv[4]);
y2 = atof(argv[5]);
select_inside(x1, y1, x2, y2, sel);
select_inside(tclgetboolvar("enable_stretch"), x1, y1, x2, y2, sel);
Tcl_ResetResult(interp);
}

View File

@ -1298,20 +1298,18 @@ void select_attached_nets(void)
rebuild_selected_array();
}
void select_inside(double x1,double y1, double x2, double y2, int sel) /*added unselect (sel param) */
void select_inside(int stretch, double x1,double y1, double x2, double y2, int sel)
{
int c,i, tmpint;
double x, y, r, a, b, xa, ya, xb, yb; /* arc */
double xx1,yy1,xx2,yy2, dtmp;
xRect tmp;
int en_s;
int select_rot = 0, select_flip = 0;
#if HAS_CAIRO==1
int customfont;
#endif
char *estr = NULL;
en_s = tclgetboolvar("enable_stretch");
for(i=0;i<xctx->wires; ++i)
{
if(sel) {
@ -1320,12 +1318,12 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
select_wire(i, SELECTED, 1);
}
else if(en_s && POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) )
else if(stretch && POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_wire(i, SELECTED1, 1);
}
else if(en_s && POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2) )
else if(stretch && POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_wire(i, SELECTED2, 1);
@ -1412,7 +1410,7 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u
select_polygon(c, i, SELECTED, 1);
} else if(selected_points) {
/* for polygon, SELECTED1 means partial sel */
if(sel && en_s) select_polygon(c, i, SELECTED1,1);
if(sel && stretch) select_polygon(c, i, SELECTED1,1);
}
}
@ -1425,12 +1423,12 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u
xctx->ui_state |= SELECTION;
select_line(c,i,SELECTED,1);
}
else if(en_s && POINTINSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1, x1,y1,x2,y2) )
else if(stretch && POINTINSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
select_line(c, i,SELECTED1,1);
}
else if(en_s && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) )
else if(stretch && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_line(c, i,SELECTED2,1);
@ -1458,17 +1456,17 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
sel? select_arc(c, i, SELECTED,1): select_arc(c, i, 0,1);
}
else if( sel && en_s && POINTINSIDE(x, y, x1, y1, x2, y2) )
else if( sel && stretch && POINTINSIDE(x, y, x1, y1, x2, y2) )
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
select_arc(c, i,SELECTED1,1);
}
else if( sel && en_s && POINTINSIDE(xb, yb, x1, y1, x2, y2) )
else if( sel && stretch && POINTINSIDE(xb, yb, x1, y1, x2, y2) )
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
select_arc(c, i,SELECTED3,1);
}
else if( sel && en_s && POINTINSIDE(xa, ya, x1, y1, x2, y2) )
else if( sel && stretch && POINTINSIDE(xa, ya, x1, y1, x2, y2) )
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
select_arc(c, i,SELECTED2,1);
@ -1490,22 +1488,22 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u
}
}
else if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 2048)){ /* no stretch on unscaled images */
if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y1, x1,y1,x2,y2) )
if( sel && stretch && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y1, x1,y1,x2,y2) )
{ /*20070302 added stretch select */
xctx->ui_state |= SELECTION;
select_box(c, i,SELECTED1,1, 0);
}
if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y1, x1,y1,x2,y2) )
if( sel && stretch && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y1, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_box(c, i,SELECTED2,1, 0);
}
if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y2, x1,y1,x2,y2) )
if( sel && stretch && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y2, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_box(c, i,SELECTED3,1, 0);
}
if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y2, x1,y1,x2,y2) )
if( sel && stretch && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y2, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_box(c, i,SELECTED4,1, 0);

View File

@ -1172,12 +1172,14 @@ static int source_tcl_file(char *s)
{
char tmp[1024];
if(Tcl_EvalFile(interp, s)==TCL_ERROR) {
fprintf(errfp, "Tcl_AppInit() error: can not execute %s, please fix:\n", s);
fprintf(errfp, "Line No: %d\n", Tcl_GetErrorLine(interp));
fprintf(errfp, "%s", tclresult());
fprintf(errfp, "\n");
my_snprintf(tmp, S(tmp), "tk_messageBox -icon error -type ok -message \
{Tcl_AppInit() err 1: can not execute %s, please fix:\n %s}",
s, tclresult());
{Tcl_AppInit() err 1: can not execute %s, please fix:\n%s\nLine No: %d\n}",
s, tclresult(), Tcl_GetErrorLine(interp));
if(has_x) {
tcleval( "wm withdraw .");
tcleval( tmp);

View File

@ -1385,7 +1385,7 @@ extern Selected select_object(double mx,double my, unsigned short sel_mode,
extern int set_first_sel(unsigned short type, int n, unsigned int col);
extern void unselect_all(int dr);
extern void select_attached_nets(void);
extern void select_inside(double x1,double y1, double x2, double y2, int sel);
extern void select_inside(int stretch, double x1,double y1, double x2, double y2, int sel);
extern void select_touch(double x1,double y1, double x2, double y2, int sel);
/* Select all nets that are dangling, ie not attached to any non pin/port/probe components */
extern int select_dangling_nets(void);
@ -1548,7 +1548,7 @@ extern void pan(int what, int mx, int my);
extern void zoom_rectangle(int what);
extern void zoom_box(double x1, double y1, double x2, double y2, double factor);
extern void save_restore_zoom(int save, Zoom_info *zi);
extern void select_rect(int what, int select);
extern void select_rect(int stretch, int what, int select);
extern void new_rect(int what, double mousex_snap, double mousey_snap);
extern void new_polygon(int what, double mousex_snap, double mousey_snap);
extern void compile_font(void);