dragging to the right a selection rectangle will select objects fully enclosed. Dragging to the left will select all objects intersected by the select rectangle.

This commit is contained in:
Stefan Schippers 2023-10-21 19:09:17 +02:00
parent 109cef6c52
commit 73c4a17c2c
5 changed files with 159 additions and 12 deletions

View File

@ -3395,6 +3395,8 @@ void pan(int what, int mx, int my)
/* 20150927 select=1: select objects, select=0: unselect objects */
void select_rect(int what, int select)
{
dbg(1, "select_rect(): mousex_save=%g mousey_save=%g, mousex_snap=%g mousey_snap=%g\n",
xctx->mx_double_save, xctx->my_double_save, xctx->mousex_snap, xctx->mousey_snap);
if(what & RUBBER)
{
if(xctx->nl_sem==0) {
@ -3408,12 +3410,19 @@ void select_rect(int what, int select)
/* 20171026 update unselected objects while dragging */
rebuild_selected_array();
bbox(START,0.0, 0.0, 0.0, 0.0);
bbox(ADD, xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2);
bbox(SET,0.0, 0.0, 0.0, 0.0);
if(xctx->nl_dir == 0) {
bbox(START,0.0, 0.0, 0.0, 0.0);
bbox(ADD, xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2);
bbox(SET,0.0, 0.0, 0.0, 0.0);
}
draw_selection(xctx->gc[SELLAYER], 0);
if(!xctx->nl_sel) select_inside(xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2, xctx->nl_sel);
bbox(END,0.0, 0.0, 0.0, 0.0);
/* if(xctx->nl_sel) { */
if(xctx->nl_dir == 0) select_inside(xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2, xctx->nl_sel);
else select_touch(xctx->nl_xx1, xctx->nl_yy1, xctx->nl_xx2, xctx->nl_yy2, xctx->nl_sel);
/* } */
if(xctx->nl_dir == 0) {
bbox(END,0.0, 0.0, 0.0, 0.0);
}
xctx->nl_xx1=xctx->nl_xr;xctx->nl_xx2=xctx->nl_xr2;xctx->nl_yy1=xctx->nl_yr;xctx->nl_yy2=xctx->nl_yr2;
RECTORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
drawtemprect(xctx->gc[SELLAYER],NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2);
@ -3456,13 +3465,18 @@ void select_rect(int what, int select)
}
/* draw_selection(xctx->gc[SELLAYER], 0); */
select_inside(xctx->nl_xr,xctx->nl_yr,xctx->nl_xr2,xctx->nl_yr2, xctx->nl_sel);
if(xctx->nl_dir == 0) select_inside(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);
bbox(START,0.0, 0.0, 0.0, 0.0);
bbox(ADD, xctx->nl_xr, xctx->nl_yr, xctx->nl_xr2, xctx->nl_yr2);
bbox(SET,0.0, 0.0, 0.0, 0.0);
if(xctx->nl_dir == 0) {
bbox(START,0.0, 0.0, 0.0, 0.0);
bbox(ADD, xctx->nl_xr, xctx->nl_yr, xctx->nl_xr2, xctx->nl_yr2);
bbox(SET,0.0, 0.0, 0.0, 0.0);
}
draw_selection(xctx->gc[SELLAYER], 0);
bbox(END,0.0, 0.0, 0.0, 0.0);
if(xctx->nl_dir == 0) {
bbox(END,0.0, 0.0, 0.0, 0.0);
}
/* /20171219 */
xctx->ui_state &= ~STARTSELECT;

View File

@ -1228,8 +1228,12 @@ int rstate; /* (reduced state, without ShiftMask) */
if(xctx->ui_state & STARTZOOM) zoom_rectangle(RUBBER);
if(xctx->ui_state & STARTSELECT && !(xctx->ui_state & (PLACE_SYMBOL | STARTPAN | PLACE_TEXT)) ) {
if( (state & Button1Mask) && SET_MODMASK) { /* 20171026 added unselect by area */
select_rect(RUBBER,0);
if(mx >= xctx->mx_save) xctx->nl_dir = 0;
else xctx->nl_dir = 1;
select_rect(RUBBER,0);
} else if(state & Button1Mask) {
if(mx >= xctx->mx_save) xctx->nl_dir = 0;
else xctx->nl_dir = 1;
select_rect(RUBBER,1);
}
}

View File

@ -1518,6 +1518,128 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u
drawtempline(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);
}
void select_touch(double x1,double y1, double x2, double y2, int sel) /*added unselect (sel param) */
{
int c,i, tmpint;
double x, y, r, a, b, xa, ya, xb, yb; /* arc */
double xx1,yy1,xx2,yy2, dtmp;
xRect tmp;
int select_rot = 0, select_flip = 0;
#if HAS_CAIRO==1
int customfont;
#endif
for(i=0;i<xctx->wires; ++i)
{
if(POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) ||
POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2)) {
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
sel ? select_wire(i,SELECTED, 1): select_wire(i,0, 1);
}
}
for(i=0;i<xctx->texts; ++i)
{
select_rot = xctx->text[i].rot;
select_flip = xctx->text[i].flip;
#if HAS_CAIRO==1
customfont = set_text_custom_font(&xctx->text[i]);
#endif
text_bbox(get_text_floater(i),
xctx->text[i].xscale, xctx->text[i].yscale, (short)select_rot, (short)select_flip,
xctx->text[i].hcenter, xctx->text[i].vcenter,
xctx->text[i].x0, xctx->text[i].y0,
&xx1,&yy1, &xx2,&yy2, &tmpint, &dtmp);
#if HAS_CAIRO==1
if(customfont) {
cairo_restore(xctx->cairo_ctx);
}
#endif
if(RECT_TOUCH(xx1, yy1, xx2, yy2,x1,y1,x2,y2))
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
sel ? select_text(i, SELECTED, 1): select_text(i, 0, 1);
}
}
for(i=0;i<xctx->instances; ++i)
{
if(RECT_TOUCH(xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2, x1,y1,x2,y2))
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) {
if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) {
select_element(i, SELECTED, 1, 1);
}
} else {
select_element(i, 0, 1, 0);
}
}
}
for(c=0;c<cadlayers; ++c)
{
if(!xctx->enable_layer[c]) continue;
for(i=0;i<xctx->polygons[c]; ++i) {
int k, flag;
polygon_bbox(xctx->poly[c][i].x, xctx->poly[c][i].y, xctx->poly[c][i].points, &xa, &ya, &xb, &yb);
if(OUTSIDE(xa, ya, xb, yb, x1, y1, x2, y2)) continue;
flag=0;
for(k=0; k<xctx->poly[c][i].points; ++k) {
if(xctx->poly[c][i].sel==SELECTED) xctx->poly[c][i].selected_point[k] = 1;
if( POINTINSIDE(xctx->poly[c][i].x[k],xctx->poly[c][i].y[k], x1,y1,x2,y2)) {
xctx->ui_state |= SELECTION;
flag=1;
break;
}
}
if(flag) {
sel ? select_polygon(c, i, SELECTED, 1): select_polygon(c, i, 0, 1);
}
}
for(i=0;i<xctx->lines[c]; ++i)
{
if(POINTINSIDE(xctx->line[c][i].x1, xctx->line[c][i].y1, x1,y1,x2,y2) ||
POINTINSIDE(xctx->line[c][i].x2, xctx->line[c][i].y2, x1,y1,x2,y2)) {
xctx->ui_state |= SELECTION;
sel? select_line(c,i,SELECTED,1): select_line(c,i,0,1);
}
}
for(i=0;i<xctx->arcs[c]; ++i) {
x = xctx->arc[c][i].x;
y = xctx->arc[c][i].y;
a = xctx->arc[c][i].a;
b = xctx->arc[c][i].b;
r = xctx->arc[c][i].r;
xa = x + r * cos(a * XSCH_PI/180.);
ya = y - r * sin(a * XSCH_PI/180.);
xb = x + r * cos((a+b) * XSCH_PI/180.);
yb = y - r * sin((a+b) * XSCH_PI/180.);
arc_bbox(x, y, r, a, b, &tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2);
if(RECT_TOUCH(tmp.x1, tmp.y1, tmp.x2, tmp.y2, x1,y1,x2,y2)) {
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);
}
}
for(i=0;i<xctx->rects[c]; ++i)
{
if(RECT_TOUCH(xctx->rect[c][i].x1,xctx->rect[c][i].y1,xctx->rect[c][i].x2,xctx->rect[c][i].y2, x1,y1,x2,y2))
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) {
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) {
select_box(c,i, SELECTED, 1, 1);
}
} else {
select_box(c,i, 0, 1, 0);
}
}
} /* end for i */
} /* end for c */
drawtemparc(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0, 0.0);
drawtemprect(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);
drawtempline(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);
}
void select_all(void)
{
int c,i;

View File

@ -541,7 +541,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
xctx->nl_points = xctx->nl_maxpoints = 0;
/* select_rect */
xctx->nl_xr = xctx->nl_yr = xctx->nl_xr2 = xctx->nl_yr2 = 0.0;
xctx->nl_sel = xctx->nl_sem = 0;
xctx->nl_sel = xctx->nl_sem = xctx->nl_dir = 0;
xctx->hilight_time = 0; /* timestamp for sims */
xctx->hilight_nets = 0;

View File

@ -323,6 +323,11 @@ extern char win_temp_dir[PATH_MAX];
#define RECT_OUTSIDE(xa,ya,xb,yb,x1,y1,x2,y2) \
( (xa) > (x2) || (xb) < (x1) || (ya) > (y2) || (yb) < (y1) )
#define RECT_TOUCH(xa,ya,xb,yb,x1,y1,x2,y2) \
( POINTINSIDE(xa,ya,x1,y1,x2,y2) || \
POINTINSIDE(xa,yb,x1,y1,x2,y2) || \
POINTINSIDE(xb,ya,x1,y1,x2,y2) || \
POINTINSIDE(xb,yb,x1,y1,x2,y2) )
@ -1007,6 +1012,7 @@ typedef struct {
/* select_rect */
double nl_xr, nl_yr, nl_xr2, nl_yr2;
int nl_sel, nl_sem; /* nl_sel is the select mode (select) the select_rect() was called with */
int nl_dir; /* direction of the drag mode select_rect was called with */
/* compare_schematics */
char sch_to_compare[PATH_MAX];
/* pan */
@ -1312,6 +1318,7 @@ extern void 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_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);
extern int Tcl_AppInit(Tcl_Interp *interp);