add xschem closest_object command, improve intuitive_interface (dont full-select already partially selected item when dragging)

This commit is contained in:
stefan schippers 2024-03-05 11:57:15 +01:00
parent ceafdedbbd
commit 3cdd6526c6
7 changed files with 89 additions and 31 deletions

View File

@ -519,11 +519,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
@ -572,6 +567,18 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> check_unique_names [1|0]</kbd></li><pre>
Check if all instances have a unique refdes (name attribute in xschem),
highlight such instances. If second parameter is '1' rename duplicates </pre>
<li><kbd> closest_object</kbd></li><pre>
returns index of closest object to mouse coordinates
index = type layer n
type = wire | text | line | poly | rect | arc | inst
layer is the layer number the object is drawn with
(valid for line, poly, rect, arc)
n is the index of the object in the xschem array
example:
$ after 3000 {set obj [xschem closest_object]}
(after 3s)
$ puts $obj
line 4 19 </pre>
<li><kbd> circle</kbd></li><pre>
Start a GUI placement of a circle.
User should click 3 unaligned points to define the circle </pre>
@ -713,6 +720,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> header_text </kbd> header metadata (license info etc) present in schematic </li>
<li><kbd> infowindow_text </kbd> ERC messages </li>
<li><kbd> instances </kbd> number of instances in schematic </li>
<li><kbd> intuitive_interface </kbd> ERC messages </li>
<li><kbd> last_created_window </kbd> return win_path of last created tab or window </li>
<li><kbd> lastsel </kbd> number of selected objects </li>
<li><kbd> line_width </kbd> get line width </li>
@ -1323,6 +1331,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> hide_symbols </kbd> set to 0,1,2 for various hiding level of symbols </li>
<li><kbd> hilight_color </kbd> set hilight color for next hilight </li>
<li><kbd> infowindow_text </kbd> ERC messages </li>
<li><kbd> intuitive_interface </kbd> ERC messages </li>
<li><kbd> netlist_name </kbd> set custom netlist name </li>
<li><kbd> netlist_type </kbd> set netlisting mode (spice, verilog, vhdl, tedax, symbol) </li>
<li><kbd> no_draw </kbd> set no drawing flag (0 or 1) </li>
@ -1545,6 +1554,13 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"

View File

@ -1731,7 +1731,6 @@ void launcher(void)
else if(xctx->sel_array[0].type==LINE) prop_ptr = xctx->line[c][n].prop_ptr;
else if(xctx->sel_array[0].type==WIRE) prop_ptr = xctx->wire[n].prop_ptr;
else if(xctx->sel_array[0].type==xTEXT) prop_ptr = xctx->text[n].prop_ptr;
/* select_object(mx,my,SELECTED, 0); */
my_strncpy(program, get_tok_value(prop_ptr,"program",0), S(program)); /* handle backslashes */
url = get_tok_value(prop_ptr,"url",0); /* handle backslashes */
dbg(1, "launcher(): url=%s\n", url);
@ -1744,7 +1743,7 @@ void launcher(void)
}
}
tcleval("after 300");
select_object(mx,my,0, 0);
select_object(mx,my,0, 0, NULL);
}
}

View File

@ -1942,7 +1942,7 @@ int rstate; /* (reduced state, without ShiftMask) */
abs(my-xctx->my_save) > 8 ) { /* set reasonable threshold before unsel */
if(!xctx->already_selected) {
select_object(X_TO_XSCHEM(xctx->mx_save),
Y_TO_XSCHEM(xctx->my_save), 0, 0); /* remove near obj if dragging */
Y_TO_XSCHEM(xctx->my_save), 0, 0, NULL); /* remove near obj if dragging */
}
rebuild_selected_array();
}
@ -3309,26 +3309,13 @@ int rstate; /* (reduced state, without ShiftMask) */
}
if(xctx->ui_state & STARTPAN) {
xctx->ui_state &=~STARTPAN;
/* xctx->mx_save = mx; xctx->my_save = my; */
/* xctx->mx_double_save=xctx->mousex_snap; */
/* xctx->my_double_save=xctx->mousey_snap; */
break;
}
/*
* if(button == Button3 && tclgetvar("graph_selected")[0] && xctx->semaphore >=2 )
* {
Selected sel;
* sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
* if(sel.type) send_net_to_graph(1);
*
* }
* else
*/
if(button == Button3 && state == ControlMask && xctx->semaphore <2)
{
Selected sel;
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
if(sel.type) select_connected_nets(1);
}
else if(button == Button3 && EQUAL_MODMASK && !(state & ShiftMask) && xctx->semaphore <2)
@ -3342,7 +3329,7 @@ int rstate; /* (reduced state, without ShiftMask) */
else if(button == Button3 && state == ShiftMask && xctx->semaphore <2)
{
Selected sel;
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
if(sel.type) select_connected_nets(0);
}
else if(button == Button3 && state == 0 && xctx->semaphore <2) {
@ -3356,7 +3343,7 @@ int rstate; /* (reduced state, without ShiftMask) */
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
select_object(xctx->mousex, xctx->mousey, 0, 0);
select_object(xctx->mousex, xctx->mousey, 0, 0, NULL);
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
}
else if(button==Button2 && (state == 0)) {
@ -3373,7 +3360,7 @@ int rstate; /* (reduced state, without ShiftMask) */
} else 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 */
} else if(button==Button1 && (state & ShiftMask) && tclgetvar("edit_symbol_prop_new_sel")[0]) {
select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
tclsetvar("preserve_unchanged_attrs", "1");
rebuild_selected_array();
}
@ -3394,6 +3381,7 @@ int rstate; /* (reduced state, without ShiftMask) */
/* Button1Press to select objects */
if( !(xctx->ui_state & STARTSELECT) && !(xctx->ui_state & STARTWIRE) && !(xctx->ui_state & STARTLINE) ) {
Selected sel;
int already_selected = 0;
int prev_last_sel = xctx->lastsel;
int no_shift_no_ctrl = !(state & (ShiftMask | ControlMask));
@ -3403,8 +3391,23 @@ int rstate; /* (reduced state, without ShiftMask) */
xctx->my_double_save=xctx->mousey_snap;
if(!xctx->intuitive_interface && no_shift_no_ctrl ) unselect_all(1);
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
sel = find_closest_obj(xctx->mousex, xctx->mousey, 0);
if(xctx->intuitive_interface && !sel.type && no_shift_no_ctrl ) unselect_all(1);
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;
case LINE: if(xctx->line[sel.col][sel.n].sel) already_selected = 1; break;
case POLYGON: if(xctx->poly[sel.col][sel.n].sel) already_selected = 1; break;
case xRECT: if(xctx->rect[sel.col][sel.n].sel) already_selected = 1; break;
case ARC: if(xctx->arc[sel.col][sel.n].sel) already_selected = 1; break;
case ELEMENT: if(xctx->inst[sel.n].sel) already_selected = 1; break;
default: break;
} /*end switch */
if(!already_selected) select_object(xctx->mousex, xctx->mousey, SELECTED, 0, &sel);
rebuild_selected_array();
if(xctx->lastsel == 1 && xctx->sel_array[0].type==POLYGON)
@ -3524,7 +3527,7 @@ int rstate; /* (reduced state, without ShiftMask) */
if(!xctx->lastsel && xctx->ui_state == 0) {
/* Following 5 lines do again a selection overriding lock,
* so locked instance attrs can be edited */
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 1);
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 1, NULL);
if(sel.type) {
xctx->ui_state = SELECTION;
rebuild_selected_array();

View File

@ -1811,7 +1811,7 @@ void edit_property(int x)
modified |= edit_symbol_property(x, j);
while( x == 0 && tclgetvar("edit_symbol_prop_new_sel")[0] == '1') {
unselect_all(1);
select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
rebuild_selected_array();
type = xctx->sel_array[0].type;

View File

@ -445,6 +445,42 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
Tcl_ResetResult(interp);
}
/* closest_object
* returns index of closest object to mouse coordinates
* index = type layer n
* type = wire | text | line | poly | rect | arc | inst
* layer is the layer number the object is drawn with
* (valid for line, poly, rect, arc)
* n is the index of the object in the xschem array
* example:
* $ after 3000 {set obj [xschem closest_object]}
* (after 3s)
* $ puts $obj
* line 4 19 */
else if(!strcmp(argv[1], "closest_object"))
{
char res[100];
const char *type;
Selected sel;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
sel = find_closest_obj(xctx->mousex, xctx->mousey, 0);
switch(sel.type)
{
case WIRE: type="wire"; break;
case xTEXT: type="text"; break;
case LINE: type="line"; break;
case POLYGON: type="poly"; break;
case xRECT: type="rect"; break;
case ARC: type="arc" ; break;
case ELEMENT: type="inst"; break;
default: break;
} /*end switch */
if(sel.type) my_snprintf(res, S(res), "%s %d %d", type, sel.col, sel.n);
else my_snprintf(res, S(res), "nosel");
Tcl_SetResult(interp, res, TCL_VOLATILE);
}
/* circle
* Start a GUI placement of a circle.

View File

@ -1166,11 +1166,15 @@ void select_line(int c, int i, unsigned short select_mode, int fast )
}
/* 20160503 return type field */
Selected select_object(double mx,double my, unsigned short select_mode, int override_lock)
Selected select_object(double mx,double my, unsigned short select_mode,
int override_lock, Selected *selptr)
{
Selected sel;
xctx->already_selected = 0;
sel = find_closest_obj(mx, my, override_lock);
if(!selptr)
sel = find_closest_obj(mx, my, override_lock);
else
sel = *selptr;
dbg(1, "select_object(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type);
switch(sel.type)

View File

@ -1353,7 +1353,7 @@ extern int text_bbox_nocairo(const char * str,double xscale, double yscale,
#endif
extern Selected select_object(double mx,double my, unsigned short sel_mode,
int override_lock); /* return type 20160503 */
int override_lock, Selected *selptr);
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);