From 96c3dde25007276d4e14833e3cdc9988ba8ac247 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 2 Jan 2025 12:32:35 +0530 Subject: [PATCH 01/46] [Feature enhancement]: Pressing the 'w'-key now sets the schematic editor to wire-drawing mode, instead of immediately placing down the wire. Press LMB in this state to start drawing the wire. --- src/callback.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/callback.c b/src/callback.c index 53af0107..2ffefcc7 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2577,10 +2577,12 @@ int rstate; /* (reduced state, without ShiftMask) */ { int prev_state = xctx->ui_state; if(xctx->semaphore >= 2) break; - start_wire(xctx->mousex_snap, xctx->mousey_snap); if(prev_state == STARTWIRE) { + start_wire(xctx->mousex_snap, xctx->mousey_snap); tcleval("set constr_mv 0" ); xctx->constr_mv=0; + } else{ + tcleval("xschem wire"); } break; } From 76e106563ba626bb8ec98846dea583b02b870cbe Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 2 Jan 2025 18:46:46 +0530 Subject: [PATCH 02/46] [UI/UX Enhancement]: When the 'w'-key is pressed to enter wire-drawing mode, until drawing begins with an LMB-click - a new bottom status-bar entry will appear in deep blue color along with the text {WIRE READY TO DRAW! } - indicating the current editor mode. Either pressing 'Esc'-key, or starting the wire-drawing process with an LMB-click will cause this new status-bar entry to disappear. --- src/callback.c | 5 +++++ src/xschem.tcl | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/callback.c b/src/callback.c index 2ffefcc7..9a1f64d5 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2070,6 +2070,11 @@ int rstate; /* (reduced state, without ShiftMask) */ } #endif + if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) { + tclvareval(xctx->top_path, ".statusbar.10 configure -state active -text {WIRE READY TO DRAW! }", NULL); + } else { + tclvareval(xctx->top_path, ".statusbar.10 configure -state normal -text { }", NULL); + } tclvareval(xctx->top_path, ".statusbar.7 configure -text $netlist_type", NULL); tclvareval(xctx->top_path, ".statusbar.3 delete 0 end;", xctx->top_path, ".statusbar.3 insert 0 $cadsnap", diff --git a/src/xschem.tcl b/src/xschem.tcl index 1732f10e..867e5b9d 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7731,6 +7731,7 @@ proc pack_widgets { { topwin {} } } { pack $topwin.statusbar.6 -side left pack $topwin.statusbar.7 -side left pack $topwin.statusbar.10 -side left + pack $topwin.statusbar.11 -side left pack $topwin.statusbar.9 -side left pack $topwin.statusbar.8 -side left pack $topwin.statusbar.1 -side left -fill x @@ -8471,7 +8472,8 @@ tclcommand=\"xschem raw_read \$netlist_dir/[file tail [file rootname [xschem get entry_replace_selection $topwin.statusbar.5 label $topwin.statusbar.6 -text "MODE:" label $topwin.statusbar.7 -width 7 - label $topwin.statusbar.10 -text {Stretch:} + label $topwin.statusbar.11 -text {Stretch:} + label $topwin.statusbar.10 -activebackground blue -text {} label $topwin.statusbar.9 -textvariable enable_stretch label $topwin.statusbar.8 -activebackground red -text {} add_toolbuttons $topwin From 052d7e87933872ccaf07ee9510a8296685fa9c05 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 2 Jan 2025 20:03:42 +0530 Subject: [PATCH 03/46] [Added New Feature]: New menu option 'Enable infix wire' is now accessible through the 'Options' menu. This option is turned-off by default and can be enabled anytime through the menu or the 'xschemrc' file to make xschem-editor revert back to it's old behavior, prior to commit 96c3dde25007276d4e14833e3cdc9988ba8ac247 --- src/callback.c | 12 ++++++++---- src/xschem.tcl | 7 +++++-- src/xschemrc | 5 +++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/callback.c b/src/callback.c index 6c1a6f5a..7a1202c3 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2611,13 +2611,17 @@ int rstate; /* (reduced state, without ShiftMask) */ { int prev_state = xctx->ui_state; if(xctx->semaphore >= 2) break; - if(prev_state == STARTWIRE) { + if(tclgetboolvar("infix_wire")) { start_wire(xctx->mousex_snap, xctx->mousey_snap); - tcleval("set constr_mv 0" ); - xctx->constr_mv=0; - } else{ + } else if(prev_state == STARTWIRE) { + start_wire(xctx->mousex_snap, xctx->mousey_snap); + } else { tcleval("xschem wire"); } + if(prev_state == STARTWIRE) { + tcleval("set constr_mv 0"); + xctx->constr_mv = 0; + } break; } if(key == XK_Return && (state == 0 ) && xctx->ui_state & STARTPOLYGON) { /* close polygon */ diff --git a/src/xschem.tcl b/src/xschem.tcl index f4adc72c..10002cd6 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7478,7 +7478,7 @@ set tctx::global_list { PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow - autotrim_wires bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers + autotrim_wires infix_wire bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv copy_cell crosshair_layer custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names @@ -7899,7 +7899,7 @@ proc build_widgets { {topwin {} } } { global netlist_show flat_netlist split_files compare_sch intuitive_interface global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width global cadsnap cadgrid draw_window toolbar_visible hide_symbols undo_type - global disable_unique_names persistent_command autotrim_wires en_hilight_conn_inst + global disable_unique_names persistent_command autotrim_wires infix_wire en_hilight_conn_inst global local_netlist_dir editor netlist_type netlist_dir spiceprefix initial_geometry if { $dark_gui_colorscheme} { set selectcolor white @@ -8022,6 +8022,8 @@ proc build_widgets { {topwin {} } } { -onvalue disk -offvalue memory -command {switch_undo} $topwin.menubar.option add checkbutton -label "Enable stretch" -variable enable_stretch \ -selectcolor $selectcolor -accelerator Y + $topwin.menubar.option add checkbutton -label "Enable infix-wire" -variable infix_wire \ + -selectcolor $selectcolor $topwin.menubar.option add checkbutton -label "Unsel. partial sel. wires after stretch move" \ -selectcolor $selectcolor -variable unselect_partial_sel_wires @@ -8938,6 +8940,7 @@ set_ne draw_grid_axes 1 set_ne persistent_command 0 set_ne intuitive_interface 1 set_ne autotrim_wires 0 +set_ne infix_wire 0 set_ne compare_sch 0 set_ne disable_unique_names 0 set_ne sym_txt 1 diff --git a/src/xschemrc b/src/xschemrc index a31096bd..fa6f7363 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -221,6 +221,11 @@ #### if not set show selected items at end of drag. Default: enabled (1) # set incremental_select 0 +#### if set to 1, pressing 'w' will immediately place a wire at current cursor +#### position without waiting for Button1 (LMB) click. Can be disabled via menu +#### default: 0 +# set infix_wire 1 + #### if set to 1 automatically join/trim wires while editing #### this may slow down on rally big designs. Can be disabled via menu #### default: 0 From b1e4d14a805abf3d8c146c6354c03c488d47e811 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Fri, 3 Jan 2025 18:08:33 +0530 Subject: [PATCH 04/46] [Changed behavior of a workflow action]: While the 'persistent-wire-draw' checkbox is ticked in the 'Options'-menu, pressing 'Esc' will immediately eject the user from wire-drawing-mode and end any multi-segment wire being drawn. Double click behavior remains the same as before. --- src/callback.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/callback.c b/src/callback.c index 7a1202c3..96791a6c 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2635,6 +2635,9 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* stuff that can be done reentrantly ... */ tclsetvar("tclstop", "1"); /* stop simulation if any running */ + if(tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE)) { + xctx->last_command &= ~STARTWIRE; + } break; } if(key=='z' && rstate == 0) /* zoom box */ From 8981b47ed3461be615373b47e4f47db48e47e3b4 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Fri, 3 Jan 2025 18:35:15 +0530 Subject: [PATCH 05/46] [Fixed an issue]: The bottom-statusbar now correctly indicates if the schematic editor is currently in wire-drawing-mode or not. The color of the indicator has been changed to a more visible and non-alerting green, and the text has been shortened to only display 'DRAW WIRE! ' instead of the previous message. --- src/callback.c | 4 ++-- src/xschem.tcl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callback.c b/src/callback.c index 96791a6c..f95fdaea 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2099,8 +2099,8 @@ int rstate; /* (reduced state, without ShiftMask) */ } #endif - if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) { - tclvareval(xctx->top_path, ".statusbar.10 configure -state active -text {WIRE READY TO DRAW! }", NULL); + if((xctx->ui_state & STARTWIRE) || (xctx->ui_state2 & MENUSTARTWIRE) || (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE))) { + tclvareval(xctx->top_path, ".statusbar.10 configure -state active -text {DRAW WIRE! }", NULL); } else { tclvareval(xctx->top_path, ".statusbar.10 configure -state normal -text { }", NULL); } diff --git a/src/xschem.tcl b/src/xschem.tcl index 158fa05c..25e6b615 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -8565,7 +8565,7 @@ tclcommand=\"xschem raw_read \$netlist_dir/[file tail [file rootname [xschem get label $topwin.statusbar.6 -text "MODE:" label $topwin.statusbar.7 -width 7 label $topwin.statusbar.11 -text {Stretch:} - label $topwin.statusbar.10 -activebackground blue -text {} + label $topwin.statusbar.10 -activebackground green -text {} label $topwin.statusbar.9 -textvariable enable_stretch label $topwin.statusbar.8 -activebackground red -text {} add_toolbuttons $topwin From 3b5541070903a75239ba61198890e1c187ef506c Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sun, 5 Jan 2025 13:20:52 +0530 Subject: [PATCH 06/46] [Added New Feature]: New menu option 'Enable orthogonal wiring' is now accessible through the 'Options' menu. This option is kept ON-BY-DEFAULT and can be disabled through the menu, 'Shift+L'-keyboard-shortcut, or by editing the 'xschemrc' file to make xschem-editor revert back to it's old behavior - which was drawing wires in free-form mode (Unconstrained move). The functionality of the 'h' and 'v' keys are preserved, and they can still be used to force the editor to only draw horizontal or vertical wires respectively. --- src/callback.c | 19 ++++++++++++++++++- src/xschem.tcl | 7 +++++-- src/xschemrc | 6 ++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/callback.c b/src/callback.c index f95fdaea..dce70d83 100644 --- a/src/callback.c +++ b/src/callback.c @@ -87,7 +87,14 @@ void redraw_w_a_l_r_p_rubbers(void) if(xctx->ui_state & STARTWIRE) { if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; - new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); + if(tclgetboolvar("orthogonal_wiring")) { + new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); + int tmp_x2 = xctx->nl_x2 - xctx->nl_x1, tmp_y2 = xctx->nl_y2 - xctx->nl_y1; + if(tmp_x2*tmp_x2 > tmp_y2*tmp_y2) xctx->manhattan_lines = 1; + else xctx->manhattan_lines = 2; + new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); + } + else new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); } if(xctx->ui_state & STARTARC) { if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; @@ -3323,6 +3330,16 @@ int rstate; /* (reduced state, without ShiftMask) */ place_net_label(0); break; } + if(key=='L' && rstate == 0) { /* toggle orthogonal routing */ + if(tclgetboolvar("orthogonal_wiring")){ + tclsetboolvar("orthogonal_wiring", 0); + } else { + tclsetboolvar("orthogonal_wiring", 1); + } + xctx->manhattan_lines = 0; + redraw_w_a_l_r_p_rubbers(); + break; + } if(key=='F' && rstate == 0) /* flip */ { if(xctx->ui_state & STARTMOVE) move_objects(FLIP,0,0,0); diff --git a/src/xschem.tcl b/src/xschem.tcl index 8d0b32e5..1e40e473 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7521,7 +7521,7 @@ set tctx::global_list { PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow - autotrim_wires infix_wire bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers + autotrim_wires infix_wire orthogonal_wiring bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv copy_cell crosshair_layer custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names @@ -7942,7 +7942,7 @@ proc build_widgets { {topwin {} } } { global netlist_show flat_netlist split_files compare_sch intuitive_interface global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width global cadsnap cadgrid draw_window toolbar_visible hide_symbols undo_type - global disable_unique_names persistent_command autotrim_wires infix_wire en_hilight_conn_inst + global disable_unique_names persistent_command autotrim_wires infix_wire orthogonal_wiring en_hilight_conn_inst global local_netlist_dir editor netlist_type netlist_dir spiceprefix initial_geometry if { $dark_gui_colorscheme} { set selectcolor white @@ -8067,6 +8067,8 @@ proc build_widgets { {topwin {} } } { -selectcolor $selectcolor -accelerator Y $topwin.menubar.option add checkbutton -label "Enable infix-wire" -variable infix_wire \ -selectcolor $selectcolor + $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring mode" -variable orthogonal_wiring \ + -selectcolor $selectcolor -accelerator Shift+L $topwin.menubar.option add checkbutton -label "Unsel. partial sel. wires after stretch move" \ -selectcolor $selectcolor -variable unselect_partial_sel_wires @@ -8998,6 +9000,7 @@ set_ne persistent_command 0 set_ne intuitive_interface 1 set_ne autotrim_wires 0 set_ne infix_wire 0 +set_ne orthogonal_wiring 1 set_ne compare_sch 0 set_ne disable_unique_names 0 set_ne sym_txt 1 diff --git a/src/xschemrc b/src/xschemrc index fa6f7363..fc15f538 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -226,6 +226,12 @@ #### default: 0 # set infix_wire 1 +#### wires are drawn in free-form mode with this mode enabled (default). +#### if set to 0, wires drawn on the schematic will no longer strictly +#### follow orthogonal routes to connect two distinct points toegther. +#### default: 1 +# set orthogonal_wiring 0 + #### if set to 1 automatically join/trim wires while editing #### this may slow down on rally big designs. Can be disabled via menu #### default: 0 From f020e45364bc292780b1ea4dc2c1b714e998feb4 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Mon, 6 Jan 2025 15:57:37 +0530 Subject: [PATCH 07/46] [Experimental Feature Update (orthogonal_wiring)]: Modified the last added orthogonal wiring mode to only draw either a horizontal, or a vertical component when a user-click event is detected. To get the best experience with this feature, 'persistent_commands' should also be enabled from the 'Options' menu. --- src/callback.c | 19 ++++++++++++------- src/xschem.tcl | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/callback.c b/src/callback.c index dce70d83..45c645f0 100644 --- a/src/callback.c +++ b/src/callback.c @@ -85,16 +85,20 @@ static int waves_selected(int event, KeySym key, int state, int button) void redraw_w_a_l_r_p_rubbers(void) { if(xctx->ui_state & STARTWIRE) { - if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; - if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; if(tclgetboolvar("orthogonal_wiring")) { new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); int tmp_x2 = xctx->nl_x2 - xctx->nl_x1, tmp_y2 = xctx->nl_y2 - xctx->nl_y1; - if(tmp_x2*tmp_x2 > tmp_y2*tmp_y2) xctx->manhattan_lines = 1; - else xctx->manhattan_lines = 2; - new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); + if(tmp_x2*tmp_x2 > tmp_y2*tmp_y2){ + tcleval("set constr_mv 1"); + xctx->constr_mv = 1; + } else { + tcleval("set constr_mv 2"); + xctx->constr_mv = 2; + } } - else new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); + if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; + if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; + new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); } if(xctx->ui_state & STARTARC) { if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; @@ -3333,10 +3337,11 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='L' && rstate == 0) { /* toggle orthogonal routing */ if(tclgetboolvar("orthogonal_wiring")){ tclsetboolvar("orthogonal_wiring", 0); + tcleval("set constr_mv 0"); + xctx->constr_mv = 0; } else { tclsetboolvar("orthogonal_wiring", 1); } - xctx->manhattan_lines = 0; redraw_w_a_l_r_p_rubbers(); break; } diff --git a/src/xschem.tcl b/src/xschem.tcl index 1e40e473..f7ed1411 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -8067,7 +8067,7 @@ proc build_widgets { {topwin {} } } { -selectcolor $selectcolor -accelerator Y $topwin.menubar.option add checkbutton -label "Enable infix-wire" -variable infix_wire \ -selectcolor $selectcolor - $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring mode" -variable orthogonal_wiring \ + $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring" -variable orthogonal_wiring \ -selectcolor $selectcolor -accelerator Shift+L $topwin.menubar.option add checkbutton -label "Unsel. partial sel. wires after stretch move" \ -selectcolor $selectcolor -variable unselect_partial_sel_wires From 21d4abcfc038666fe2a33c0d6a1c67874fe6f5ff Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 9 Jan 2025 15:56:29 +0530 Subject: [PATCH 08/46] [Experimental Feature Update (orthogonal_wiring)]: Modified the last added orthogonal wiring mode to only FINALIZE either a horizontal, or a vertical component when a user-click event is detected. HOWEVER, the full orthogonal wire is drawn on the canvas anyways. A double-click using LMB causes both the horizontal and vertical components to get finalized, and the wire-drawing mode is simultaneously terminated. To get the best experience with this feature, 'persistent_commands' should also be enabled from the 'Options' menu. --- src/callback.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/callback.c b/src/callback.c index 45c645f0..a967ce3f 100644 --- a/src/callback.c +++ b/src/callback.c @@ -85,19 +85,17 @@ static int waves_selected(int event, KeySym key, int state, int button) void redraw_w_a_l_r_p_rubbers(void) { if(xctx->ui_state & STARTWIRE) { + if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; + if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; if(tclgetboolvar("orthogonal_wiring")) { new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); int tmp_x2 = xctx->nl_x2 - xctx->nl_x1, tmp_y2 = xctx->nl_y2 - xctx->nl_y1; if(tmp_x2*tmp_x2 > tmp_y2*tmp_y2){ - tcleval("set constr_mv 1"); - xctx->constr_mv = 1; + xctx->manhattan_lines = 1; } else { - tcleval("set constr_mv 2"); - xctx->constr_mv = 2; + xctx->manhattan_lines = 2; } } - if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; - if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); } if(xctx->ui_state & STARTARC) { @@ -201,10 +199,14 @@ static void start_line(double mx, double my) static void start_wire(double mx, double my) { - dbg(1, "start_wire(): ui_state=%d, ui_state2=%d last_command=%d\n", - xctx->ui_state, xctx->ui_state2, xctx->last_command); + dbg(1, "start_wire(): ui_state=%d, ui_state2=%d last_command=%d\n", xctx->ui_state, xctx->ui_state2, xctx->last_command); xctx->last_command = STARTWIRE; if(xctx->ui_state & STARTWIRE) { + if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){ + xctx->constr_mv = xctx->manhattan_lines; + new_wire(CLEAR, mx, my); + redraw_w_a_l_r_p_rubbers(); + } if(xctx->constr_mv != 2) { xctx->mx_double_save = mx; } @@ -218,6 +220,9 @@ static void start_wire(double mx, double my) xctx->my_double_save=my; } new_wire(PLACE,mx, my); + if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){ + xctx->constr_mv = 0; + } } static double interpolate_yval(int idx, int p, double x, int sweep_idx, int point_not_last) @@ -3337,8 +3342,7 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='L' && rstate == 0) { /* toggle orthogonal routing */ if(tclgetboolvar("orthogonal_wiring")){ tclsetboolvar("orthogonal_wiring", 0); - tcleval("set constr_mv 0"); - xctx->constr_mv = 0; + xctx->manhattan_lines = 0; } else { tclsetboolvar("orthogonal_wiring", 1); } @@ -4045,6 +4049,8 @@ int rstate; /* (reduced state, without ShiftMask) */ edit_property(0); } else { if(xctx->ui_state & STARTWIRE) { + redraw_w_a_l_r_p_rubbers(); + start_wire(mx, my); xctx->ui_state &= ~STARTWIRE; } if(xctx->ui_state & STARTLINE) { From 24bfb5b3637b8b7a1d969981e9238d633bc9f4cd Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Fri, 17 Jan 2025 11:42:59 +0530 Subject: [PATCH 09/46] [Bugfix]: Fixed an issue where the bottom statusbar showed the green zsh: command not found: Draw indicatior when the user enters and exits wire-drawing mode without actually drawing a wire. --- src/callback.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/callback.c b/src/callback.c index c0e65b64..606f95bb 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2772,6 +2772,9 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* stuff that can be done reentrantly ... */ tclsetvar("tclstop", "1"); /* stop simulation if any running */ + if(xctx->ui_state2 & MENUSTARTWIRE) { + xctx->ui_state2 &= ~MENUSTARTWIRE; + } if(tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE)) { xctx->last_command &= ~STARTWIRE; } From 8ce32b73b7ab7abb0e84e2ff5fa6aafd6307b71d Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sat, 18 Jan 2025 14:05:29 +0530 Subject: [PATCH 10/46] [Code Refactoring]: Modified the source code for compatibility with the upstream repo (due to 'infix_wire' feature integration with new name 'infix_interface') --- src/callback.c | 85 +++++++++++++++++++++++++++++++++----------------- src/xschem.tcl | 8 ++--- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/callback.c b/src/callback.c index 606f95bb..dc85ca6e 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2202,6 +2202,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, XKeyboardState kbdstate; #endif int draw_xhair = tclgetboolvar("draw_crosshair"); +int infix_interface = tclgetboolvar("infix_interface"); int rstate; /* (reduced state, without ShiftMask) */ /* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease @@ -2748,16 +2749,17 @@ int rstate; /* (reduced state, without ShiftMask) */ { int prev_state = xctx->ui_state; if(xctx->semaphore >= 2) break; - if(tclgetboolvar("infix_wire")) { - start_wire(xctx->mousex_snap, xctx->mousey_snap); - } else if(prev_state == STARTWIRE) { + + if(infix_interface) { start_wire(xctx->mousex_snap, xctx->mousey_snap); + if(prev_state == STARTWIRE) { + tcleval("set constr_mv 0"); + xctx->constr_mv = 0; + } } else { - tcleval("xschem wire"); - } - if(prev_state == STARTWIRE) { - tcleval("set constr_mv 0"); - xctx->constr_mv = 0; + xctx->last_command = 0; + xctx->ui_state |= MENUSTART; + xctx->ui_state2 = MENUSTARTWIRE; } break; } @@ -2805,10 +2807,15 @@ int rstate; /* (reduced state, without ShiftMask) */ { if(xctx->semaphore >= 2) break; dbg(1, "callback(): start polygon\n"); - xctx->mx_double_save=xctx->mousex_snap; - xctx->my_double_save=xctx->mousey_snap; - xctx->last_command = 0; - new_polygon(PLACE, xctx->mousex_snap, xctx->mousey_snap); + if(infix_interface) { + xctx->mx_double_save = xctx->mousex_snap; + xctx->my_double_save = xctx->mousey_snap; + xctx->last_command = 0; + new_polygon(PLACE, xctx->mousex_snap, xctx->mousey_snap); + } else { + xctx->ui_state |= MENUSTART; + xctx->ui_state2 = MENUSTARTPOLYGON; + } break; } if(key=='P' && rstate == 0) /* pan, other way to. */ @@ -2957,10 +2964,15 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='r' /* && !xctx->ui_state */ && rstate==0) /* start rect */ { dbg(1, "callback(): start rect\n"); - xctx->mx_double_save=xctx->mousex_snap; - xctx->my_double_save=xctx->mousey_snap; - xctx->last_command = 0; - new_rect(PLACE,xctx->mousex_snap, xctx->mousey_snap); + if(infix_interface) { + xctx->mx_double_save=xctx->mousex_snap; + xctx->my_double_save=xctx->mousey_snap; + xctx->last_command = 0; + new_rect(PLACE,xctx->mousex_snap, xctx->mousey_snap); + } else{ + xctx->ui_state |= MENUSTART; + xctx->ui_state2 = MENUSTARTRECT; + } break; } if(key=='V' && rstate == ControlMask) /* toggle spice/vhdl netlist */ @@ -3130,19 +3142,29 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='C' /* && !xctx->ui_state */ && rstate == 0) /* place arc */ { if(xctx->semaphore >= 2) break; - xctx->mx_double_save=xctx->mousex_snap; - xctx->my_double_save=xctx->mousey_snap; - xctx->last_command = 0; - new_arc(PLACE, 180., xctx->mousex_snap, xctx->mousey_snap); + if(infix_interface) { + xctx->mx_double_save=xctx->mousex_snap; + xctx->my_double_save=xctx->mousey_snap; + xctx->last_command = 0; + new_arc(PLACE, 180., xctx->mousex_snap, xctx->mousey_snap); + } else { + xctx->ui_state |= MENUSTART; + xctx->ui_state2 = MENUSTARTARC; + } break; } if(key=='C' /* && !xctx->ui_state */ && rstate == ControlMask) /* place circle */ { if(xctx->semaphore >= 2) break; - xctx->mx_double_save=xctx->mousex_snap; - xctx->my_double_save=xctx->mousey_snap; - xctx->last_command = 0; - new_arc(PLACE, 360., xctx->mousex_snap, xctx->mousey_snap); + if(infix_interface) { + xctx->mx_double_save=xctx->mousex_snap; + xctx->my_double_save=xctx->mousey_snap; + xctx->last_command = 0; + new_arc(PLACE, 360., xctx->mousex_snap, xctx->mousey_snap); + } else { + xctx->ui_state |= MENUSTART; + xctx->ui_state2 = MENUSTARTCIRCLE; + } break; } if(key=='O' && rstate == ControlMask ) /* load most recent tile */ @@ -3452,10 +3474,17 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='l' /* && !xctx->ui_state */ && rstate == 0) /* start line */ { int prev_state = xctx->ui_state; - start_line(xctx->mousex_snap, xctx->mousey_snap); - if(prev_state == STARTLINE) { - tcleval("set constr_mv 0" ); - xctx->constr_mv=0; + if(xctx->semaphore>=2) break; + if(infix_interface) { + start_line(xctx->mousex_snap, xctx->mousey_snap); + if(prev_state == STARTLINE) { + tcleval("set constr_mv 0" ); + xctx->constr_mv=0; + } + } else { + xctx->last_command = 0; + xctx->ui_state |= MENUSTART; + xctx->ui_state2 = MENUSTARTLINE; } break; } diff --git a/src/xschem.tcl b/src/xschem.tcl index 24b5da01..e615f1ea 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7589,7 +7589,7 @@ set tctx::global_list { PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow - autotrim_wires infix_wire orthogonal_wiring bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers + autotrim_wires infix_interface orthogonal_wiring bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv copy_cell crosshair_layer custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names @@ -8010,7 +8010,7 @@ proc build_widgets { {topwin {} } } { global netlist_show flat_netlist split_files compare_sch intuitive_interface global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width global cadsnap cadgrid draw_window toolbar_visible hide_symbols undo_type - global disable_unique_names persistent_command autotrim_wires infix_wire orthogonal_wiring en_hilight_conn_inst + global disable_unique_names persistent_command autotrim_wires infix_interface orthogonal_wiring en_hilight_conn_inst global local_netlist_dir editor netlist_type netlist_dir spiceprefix initial_geometry if { $dark_gui_colorscheme} { set selectcolor white @@ -8133,7 +8133,7 @@ proc build_widgets { {topwin {} } } { -onvalue disk -offvalue memory -command {switch_undo} $topwin.menubar.option add checkbutton -label "Enable stretch" -variable enable_stretch \ -selectcolor $selectcolor -accelerator Y - $topwin.menubar.option add checkbutton -label "Enable infix-wire" -variable infix_wire \ + $topwin.menubar.option add checkbutton -label "Enable infix-interface" -variable infix_interface \ -selectcolor $selectcolor $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring" -variable orthogonal_wiring \ -selectcolor $selectcolor -accelerator Shift+L @@ -9067,7 +9067,7 @@ set_ne draw_grid_axes 1 set_ne persistent_command 0 set_ne intuitive_interface 1 set_ne autotrim_wires 0 -set_ne infix_wire 0 +set_ne infix_interface 0 set_ne orthogonal_wiring 1 set_ne compare_sch 0 set_ne disable_unique_names 0 From 7fe267842a89f2136658a1d770f4cb5405f686d1 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sat, 18 Jan 2025 14:08:44 +0530 Subject: [PATCH 11/46] [Code Refactoring]: Modified the source code for compatibility with the upstream repo (due to 'infix_wire' feature integration with new name 'infix_interface') --- src/xschemrc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/xschemrc b/src/xschemrc index fc15f538..2dd5ca90 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -221,10 +221,11 @@ #### if not set show selected items at end of drag. Default: enabled (1) # set incremental_select 0 -#### if set to 1, pressing 'w' will immediately place a wire at current cursor -#### position without waiting for Button1 (LMB) click. Can be disabled via menu +#### if set to 1, pressing 'w', 'l', 'r', 'C', or 'Ctrl+C' will immediately place the +#### corresponding component at current cursor position without waiting for Button1 (LMB) click. +#### This setting can be disabled via the Options menu #### default: 0 -# set infix_wire 1 +# set infix_interface 1 #### wires are drawn in free-form mode with this mode enabled (default). #### if set to 0, wires drawn on the schematic will no longer strictly From 26df8d7d21c68ba0944b0164dcb00fcaf4b38326 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sat, 18 Jan 2025 15:50:36 +0530 Subject: [PATCH 12/46] [Code Refactoring]: Modified the source code for compatibility with the upstream repo (due to 'infix_wire' feature integration with new name 'infix_interface') --- src/callback.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/callback.c b/src/callback.c index d061ffb2..7a21213c 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2749,23 +2749,12 @@ int rstate; /* (reduced state, without ShiftMask) */ { int prev_state = xctx->ui_state; if(xctx->semaphore >= 2) break; -<<<<<<< HEAD - - if(infix_interface) { - start_wire(xctx->mousex_snap, xctx->mousey_snap); - if(prev_state == STARTWIRE) { - tcleval("set constr_mv 0"); - xctx->constr_mv = 0; - } -======= - if(infix_interface) { start_wire(xctx->mousex_snap, xctx->mousey_snap); if(prev_state == STARTWIRE) { tcleval("set constr_mv 0" ); xctx->constr_mv=0; } ->>>>>>> 025823f14c8ca1f9562a1c452fffe267c7120905 } else { xctx->last_command = 0; xctx->ui_state |= MENUSTART; @@ -2818,13 +2807,8 @@ int rstate; /* (reduced state, without ShiftMask) */ if(xctx->semaphore >= 2) break; dbg(1, "callback(): start polygon\n"); if(infix_interface) { -<<<<<<< HEAD - xctx->mx_double_save = xctx->mousex_snap; - xctx->my_double_save = xctx->mousey_snap; -======= xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; ->>>>>>> 025823f14c8ca1f9562a1c452fffe267c7120905 xctx->last_command = 0; new_polygon(PLACE, xctx->mousex_snap, xctx->mousey_snap); } else { @@ -2979,20 +2963,13 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='r' /* && !xctx->ui_state */ && rstate==0) /* start rect */ { dbg(1, "callback(): start rect\n"); -<<<<<<< HEAD -======= if(xctx->semaphore >= 2) break; ->>>>>>> 025823f14c8ca1f9562a1c452fffe267c7120905 if(infix_interface) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; xctx->last_command = 0; new_rect(PLACE,xctx->mousex_snap, xctx->mousey_snap); -<<<<<<< HEAD - } else{ -======= } else { ->>>>>>> 025823f14c8ca1f9562a1c452fffe267c7120905 xctx->ui_state |= MENUSTART; xctx->ui_state2 = MENUSTARTRECT; } @@ -3497,11 +3474,7 @@ int rstate; /* (reduced state, without ShiftMask) */ if(key=='l' /* && !xctx->ui_state */ && rstate == 0) /* start line */ { int prev_state = xctx->ui_state; -<<<<<<< HEAD - if(xctx->semaphore>=2) break; -======= if(xctx->semaphore >= 2) break; ->>>>>>> 025823f14c8ca1f9562a1c452fffe267c7120905 if(infix_interface) { start_line(xctx->mousex_snap, xctx->mousey_snap); if(prev_state == STARTLINE) { From 92428e44094f1c0a8b4a572c8ea602a24e4c10fe Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sat, 18 Jan 2025 15:52:17 +0530 Subject: [PATCH 13/46] [Code Refactoring]: Modified the source code for compatibility with the upstream repo (due to 'infix_wire' feature integration with new name 'infix_interface') --- src/xschem.tcl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xschem.tcl b/src/xschem.tcl index f12371c8..c350c7bd 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -9066,7 +9066,6 @@ set_ne big_grid_points 0 set_ne draw_grid_axes 1 set_ne persistent_command 0 set_ne intuitive_interface 1 -set_ne infix_interface 1 set_ne autotrim_wires 0 set_ne infix_interface 0 set_ne orthogonal_wiring 1 From ed1a471f5dd9f413ef7511a7e0704587455147f2 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Mon, 20 Jan 2025 14:12:33 +0530 Subject: [PATCH 14/46] [Fixed Upstream Bug]: While the schematic editor is in intuitive-interface mode, drawing a wire would immediately terminate the endpoint of it when the LMB button is released (i.e. user click drew a point - when persistent_command was disabled). This behavior is now corrected, but a non-essential feature introduced in the last set of upstream commits had to be broken (end wire creation when dragging in intuitive interface mode). The broken feature will be fixed in a future commit. --- src/callback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callback.c b/src/callback.c index d52d6727..37888f88 100644 --- a/src/callback.c +++ b/src/callback.c @@ -4207,9 +4207,9 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ - else if(xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { - if(end_place_move_copy_zoom()) break; - } + /*else if(xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) {*/ + /* if(end_place_move_copy_zoom()) break;*/ + /*}*/ /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { From 320b8efc4b3c7860a114bb9b1fd8a8c5f9c4ca34 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Mon, 20 Jan 2025 23:20:53 +0530 Subject: [PATCH 15/46] [Snap Cursor (WIP)]: Experimental feature 'snap_cursor' is now available to be selected from the Options menu (disabled by default). This is a work in progress and needs a lot more polishing to be properly usable. Currently only supports snapping to nearest component-endpoint. --- src/callback.c | 51 ++++++++++++++++++++++++++ src/draw.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/xschem.tcl | 7 ++-- 3 files changed, 154 insertions(+), 2 deletions(-) diff --git a/src/callback.c b/src/callback.c index 37888f88..3276ba95 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1393,6 +1393,51 @@ void draw_crosshair(int what) xctx->draw_pixmap = sdp; } +/* cursor_type == 0 : only erase drawn cursor + * cursor_type == 1 : erase and draw a normal grid-snapping cursor + * cursor_type == 2 : erase and draw a diamond-shaped cursor that snaps to a component endpoint */ +void draw_snap_cursor(int cursor_type) +{ + int sdw, sdp; + dbg(1, "draw_snap_cursor(): cursor_type=%d\n", cursor_type); + sdw = xctx->draw_window; + sdp = xctx->draw_pixmap; + + if(!xctx->mouse_inside) return; + xctx->draw_pixmap = 0; + xctx->draw_window = 1; + if(fix_broken_tiled_fill || !_unix) { + 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)); + + 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); + } else { + drawtemparc(xctx->gctiled, NOW, xctx->prev_crossx, xctx->prev_crossy, 1, 0, 360); + } + if(cursor_type != 1) { + /*drawline(xctx->crosshair_layer, NOW, xctx->mousex_snap, xctx->mousey_snap, xctx->mousex_snap, xctx->mousey_snap, 0, NULL);*/ + double x, y; + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + drawarc(xctx->crosshair_layer, NOW, x, y, 1, 1, 360, 1, 0); + draw_selection(xctx->gc[SELLAYER], 0); + xctx->prev_crossx = x; + xctx->prev_crossy = y; + } else { + drawarc(xctx->crosshair_layer, NOW, xctx->mousex_snap, xctx->mousey_snap, 1, 1, 360, 1, 0); + draw_selection(xctx->gc[SELLAYER], 0); + xctx->prev_crossx = xctx->mousex_snap; + xctx->prev_crossy = xctx->mousey_snap; + } + + xctx->draw_window = sdw; + xctx->draw_pixmap = sdp; +} + /* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */ static int end_place_move_copy_zoom() { @@ -2218,6 +2263,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, #endif int draw_xhair = tclgetboolvar("draw_crosshair"); int infix_interface = tclgetboolvar("infix_interface"); +int snap_cursor = tclgetboolvar("snap_cursor"); int rstate; /* (reduced state, without ShiftMask) */ /* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease @@ -2335,6 +2381,7 @@ int rstate; /* (reduced state, without ShiftMask) */ case LeaveNotify: if(draw_xhair) draw_crosshair(1); + if(snap_cursor) draw_snap_cursor(0); tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL); xctx->mouse_inside = 0; break; @@ -2403,11 +2450,13 @@ int rstate; /* (reduced state, without ShiftMask) */ if(draw_xhair) { draw_crosshair(1); } + if(snap_cursor) draw_snap_cursor(0); if(xctx->ui_state & STARTPAN) pan(RUBBER, mx, my); if(xctx->semaphore >= 2) { if(draw_xhair) { draw_crosshair(2); } + if(snap_cursor) draw_snap_cursor(2); break; } dbg(1, "ui_state=%d deltax=%g\n", xctx->ui_state, xctx->deltax); @@ -2502,6 +2551,7 @@ int rstate; /* (reduced state, without ShiftMask) */ if(draw_xhair) { draw_crosshair(2); } + if(snap_cursor) draw_snap_cursor(2); break; case KeyRelease: @@ -4259,6 +4309,7 @@ int rstate; /* (reduced state, without ShiftMask) */ statusmsg(str,1); } if(draw_xhair) draw_crosshair(0); + if(snap_cursor) draw_snap_cursor(2); break; case -3: /* double click : edit prop */ if( waves_selected(event, key, state, button)) { diff --git a/src/draw.c b/src/draw.c index 6c7bf8b7..dcf409ac 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1601,6 +1601,104 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b, } } +void draw_snap_point(int c, int what, double x, double y, double r, double a, double b, int arc_fill, int dash) +{ + static int i=0; + static XArc xarc[CADDRAWBUFFERSIZE]; + double x1, y1, x2, y2; /* arc bbox */ + double xx1, yy1, xx2, yy2; /* complete circle bbox in screen coords */ + GC gc; + + if(arc_fill || dash) what = NOW; + + if(!has_x) return; + if(what & ADD) + { + if(i>=CADDRAWBUFFERSIZE) + { + if(xctx->draw_window) XDrawArcs(display, xctx->window, xctx->gc[c], xarc,i); + if(xctx->draw_pixmap) XDrawArcs(display, xctx->save_pixmap, xctx->gc[c], xarc,i); + i=0; + } + xx1=X_TO_SCREEN(x-r); + yy1=Y_TO_SCREEN(y-r); + xx2=X_TO_SCREEN(x+r); + yy2=Y_TO_SCREEN(y+r); + arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2); + x1=X_TO_SCREEN(x1); + y1=Y_TO_SCREEN(y1); + x2=X_TO_SCREEN(x2); + y2=Y_TO_SCREEN(y2); + if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) + { + xarc[i].x=(short)xx1; + xarc[i].y=(short)yy1; + xarc[i].width =(unsigned short)(xx2 - xx1); + xarc[i].height=(unsigned short)(yy2 - yy1); + xarc[i].angle1 = (short)(a*64); + xarc[i].angle2 = (short)(b*64); + ++i; + } + } + else if(what & NOW) + { + xx1=X_TO_SCREEN(x-r); + yy1=Y_TO_SCREEN(y-r); + xx2=X_TO_SCREEN(x+r); + yy2=Y_TO_SCREEN(y+r); + if(arc_fill) + arc_bbox(x, y, r, 0, 360, &x1,&y1,&x2,&y2); + else + arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2); + x1=X_TO_SCREEN(x1); + y1=Y_TO_SCREEN(y1); + x2=X_TO_SCREEN(x2); + y2=Y_TO_SCREEN(y2); + if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) + { + if(dash) { + char dash_arr[2]; + dash_arr[0] = dash_arr[1] = (char)dash; + XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin); + } + + if(xctx->draw_window) { + XDrawArc(display, xctx->window, xctx->gc[c], (int)xx1, (int)yy1, + (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); + } + if(xctx->draw_pixmap) { + XDrawArc(display, xctx->save_pixmap, xctx->gc[c], (int)xx1, (int)yy1, + (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); + } + + if(xctx->fill_pattern && (xctx->fill_type[c] || arc_fill == 3) ){ + + if(arc_fill & 2) gc = xctx->gc[c]; + else gc = xctx->gcstipple[c]; + if(arc_fill) { + if(xctx->draw_window) + XFillArc(display, xctx->window, gc, (int)xx1, (int)yy1, + (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); + if(xctx->draw_pixmap) + XFillArc(display, xctx->save_pixmap, gc, (int)xx1, (int)yy1, + (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); + } + } + if(dash) { + XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN); + } + } + } + else if((what & END) && i) + { + if(xctx->draw_window) XDrawArcs(display, xctx->window, xctx->gc[c], xarc,i); + if(xctx->draw_pixmap) XDrawArcs(display, xctx->save_pixmap, xctx->gc[c], xarc,i); + i=0; + } +} + + void filledrect(int c, int what, double rectx1,double recty1,double rectx2,double recty2, int fill, int e_a, int e_b) { diff --git a/src/xschem.tcl b/src/xschem.tcl index 99f2c4fc..b02bb3ef 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7622,7 +7622,7 @@ set tctx::global_list { PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow - autotrim_wires infix_interface orthogonal_wiring bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers + autotrim_wires orthogonal_wiring snap_cursor bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv copy_cell crosshair_layer custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names @@ -8042,7 +8042,7 @@ proc build_widgets { {topwin {} } } { global recentfile color_ps transparent_svg menu_debug_var enable_stretch global netlist_show flat_netlist split_files compare_sch intuitive_interface global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width - global cadsnap cadgrid draw_window toolbar_visible hide_symbols undo_type + global cadsnap cadgrid draw_window toolbar_visible hide_symbols undo_type snap_cursor global disable_unique_names persistent_command autotrim_wires infix_interface orthogonal_wiring en_hilight_conn_inst global local_netlist_dir editor netlist_type netlist_dir spiceprefix initial_geometry if { $dark_gui_colorscheme} { @@ -8168,6 +8168,8 @@ proc build_widgets { {topwin {} } } { -selectcolor $selectcolor -accelerator Y $topwin.menubar.option add checkbutton -label "Enable infix-interface" -variable infix_interface \ -selectcolor $selectcolor + $topwin.menubar.option add checkbutton -label "Enable snap cursor" -variable snap_cursor \ + -selectcolor $selectcolor $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring" -variable orthogonal_wiring \ -selectcolor $selectcolor -accelerator Shift+L $topwin.menubar.option add checkbutton -label "Unsel. partial sel. wires after stretch move" \ @@ -9101,6 +9103,7 @@ set_ne persistent_command 0 set_ne intuitive_interface 1 set_ne autotrim_wires 0 set_ne infix_interface 0 +set_ne snap_cursor 0 set_ne orthogonal_wiring 1 set_ne compare_sch 0 set_ne disable_unique_names 0 From 7f613294f4897e178b99490231f41085f2f87fdb Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Tue, 21 Jan 2025 15:49:52 +0530 Subject: [PATCH 16/46] [Snap Cursor (WIP)]: Experimental feature 'snap_cursor' is updated. It can be selected from the Options menu (disabled by default) and will take effect when the wire-drawing mode is active. This is a work in progress and needs a lot more polishing to be properly usable. Currently only supports snapping to nearest component-endpoint. Cursor to snap to nearest grid point is pending. --- src/callback.c | 58 ++++++++++++++---------------- src/draw.c | 98 -------------------------------------------------- 2 files changed, 27 insertions(+), 129 deletions(-) diff --git a/src/callback.c b/src/callback.c index 3276ba95..c1406a3f 100644 --- a/src/callback.c +++ b/src/callback.c @@ -21,6 +21,7 @@ */ #include "xschem.h" +#include /* allow to use the Windows keys as alternate for Alt */ #define SET_MODMASK ( (rstate & Mod1Mask) || (rstate & Mod4Mask) ) @@ -1393,9 +1394,9 @@ void draw_crosshair(int what) xctx->draw_pixmap = sdp; } -/* cursor_type == 0 : only erase drawn cursor - * cursor_type == 1 : erase and draw a normal grid-snapping cursor - * cursor_type == 2 : erase and draw a diamond-shaped cursor that snaps to a component endpoint */ +/* cursor_type == 0 : erase and draw a new cursor + * cursor_type == 1 : erase the cursor + * cursor_type == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */ void draw_snap_cursor(int cursor_type) { int sdw, sdp; @@ -1406,33 +1407,27 @@ void draw_snap_cursor(int cursor_type) if(!xctx->mouse_inside) return; xctx->draw_pixmap = 0; xctx->draw_window = 1; - if(fix_broken_tiled_fill || !_unix) { - 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)); - - 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); - } else { - drawtemparc(xctx->gctiled, NOW, xctx->prev_crossx, xctx->prev_crossy, 1, 0, 360); + if(cursor_type != 2) { + if(fix_broken_tiled_fill || !_unix) { + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); + } else { + double prev_x = xctx->prev_crossx; + double prev_y = xctx->prev_crossy; + double points_x[5] = {prev_x, prev_x+3, prev_x, prev_x-3, prev_x}; + double points_y[5] = {prev_y-3, prev_y, prev_y+3, prev_y, prev_y-3}; + drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0); + } } if(cursor_type != 1) { - /*drawline(xctx->crosshair_layer, NOW, xctx->mousex_snap, xctx->mousey_snap, xctx->mousex_snap, xctx->mousey_snap, 0, NULL);*/ double x, y; find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - drawarc(xctx->crosshair_layer, NOW, x, y, 1, 1, 360, 1, 0); - draw_selection(xctx->gc[SELLAYER], 0); + double points_x[5] = {x, x+3, x, x-3, x}; + double points_y[5] = {y-3, y, y+3, y, y-3}; + drawpolygon(8, NOW, points_x, points_y, 5, 0, 0, 0); xctx->prev_crossx = x; xctx->prev_crossy = y; - } else { - drawarc(xctx->crosshair_layer, NOW, xctx->mousex_snap, xctx->mousey_snap, 1, 1, 360, 1, 0); - draw_selection(xctx->gc[SELLAYER], 0); - xctx->prev_crossx = xctx->mousex_snap; - xctx->prev_crossy = xctx->mousey_snap; } + draw_selection(xctx->gc[SELLAYER], 0); xctx->draw_window = sdw; xctx->draw_pixmap = sdp; @@ -2264,6 +2259,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, int draw_xhair = tclgetboolvar("draw_crosshair"); int infix_interface = tclgetboolvar("infix_interface"); int snap_cursor = tclgetboolvar("snap_cursor"); +int wire_draw_active = (xctx->ui_state & STARTWIRE) || (xctx->ui_state2 & MENUSTARTWIRE) || (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE)); int rstate; /* (reduced state, without ShiftMask) */ /* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease @@ -2298,7 +2294,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } #endif - if((xctx->ui_state & STARTWIRE) || (xctx->ui_state2 & MENUSTARTWIRE) || (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE))) { + if(wire_draw_active) { tclvareval(xctx->top_path, ".statusbar.10 configure -state active -text {DRAW WIRE! }", NULL); } else { tclvareval(xctx->top_path, ".statusbar.10 configure -state normal -text { }", NULL); @@ -2381,7 +2377,7 @@ int rstate; /* (reduced state, without ShiftMask) */ case LeaveNotify: if(draw_xhair) draw_crosshair(1); - if(snap_cursor) draw_snap_cursor(0); + if(snap_cursor && wire_draw_active) draw_snap_cursor(1); tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL); xctx->mouse_inside = 0; break; @@ -2450,13 +2446,13 @@ int rstate; /* (reduced state, without ShiftMask) */ if(draw_xhair) { draw_crosshair(1); } - if(snap_cursor) draw_snap_cursor(0); + 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); } - if(snap_cursor) draw_snap_cursor(2); + if(snap_cursor && wire_draw_active) draw_snap_cursor(2); break; } dbg(1, "ui_state=%d deltax=%g\n", xctx->ui_state, xctx->deltax); @@ -2551,7 +2547,7 @@ int rstate; /* (reduced state, without ShiftMask) */ if(draw_xhair) { draw_crosshair(2); } - if(snap_cursor) draw_snap_cursor(2); + if(snap_cursor && wire_draw_active) draw_snap_cursor(2); break; case KeyRelease: @@ -2792,7 +2788,7 @@ int rstate; /* (reduced state, without ShiftMask) */ hilight_net_pin_mismatches(); break; } - if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ + if(key== 's' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ if(xctx->semaphore >= 2) break; snapped_wire(c_snap); break; @@ -3034,7 +3030,7 @@ int rstate; /* (reduced state, without ShiftMask) */ draw(); /* needed to ungrey or grey out components due to *_ignore attribute */ break; } - if(key=='s' && rstate == 0 ) /* simulate */ + if(key=='r' && rstate == ControlMask ) /* simulate */ { if(xctx->semaphore >= 2) break; if(waves_selected(event, key, state, button)) { @@ -4309,7 +4305,7 @@ int rstate; /* (reduced state, without ShiftMask) */ statusmsg(str,1); } if(draw_xhair) draw_crosshair(0); - if(snap_cursor) draw_snap_cursor(2); + if(snap_cursor && wire_draw_active) draw_snap_cursor(0); break; case -3: /* double click : edit prop */ if( waves_selected(event, key, state, button)) { diff --git a/src/draw.c b/src/draw.c index dcf409ac..6c7bf8b7 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1601,104 +1601,6 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b, } } -void draw_snap_point(int c, int what, double x, double y, double r, double a, double b, int arc_fill, int dash) -{ - static int i=0; - static XArc xarc[CADDRAWBUFFERSIZE]; - double x1, y1, x2, y2; /* arc bbox */ - double xx1, yy1, xx2, yy2; /* complete circle bbox in screen coords */ - GC gc; - - if(arc_fill || dash) what = NOW; - - if(!has_x) return; - if(what & ADD) - { - if(i>=CADDRAWBUFFERSIZE) - { - if(xctx->draw_window) XDrawArcs(display, xctx->window, xctx->gc[c], xarc,i); - if(xctx->draw_pixmap) XDrawArcs(display, xctx->save_pixmap, xctx->gc[c], xarc,i); - i=0; - } - xx1=X_TO_SCREEN(x-r); - yy1=Y_TO_SCREEN(y-r); - xx2=X_TO_SCREEN(x+r); - yy2=Y_TO_SCREEN(y+r); - arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2); - x1=X_TO_SCREEN(x1); - y1=Y_TO_SCREEN(y1); - x2=X_TO_SCREEN(x2); - y2=Y_TO_SCREEN(y2); - if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) - { - xarc[i].x=(short)xx1; - xarc[i].y=(short)yy1; - xarc[i].width =(unsigned short)(xx2 - xx1); - xarc[i].height=(unsigned short)(yy2 - yy1); - xarc[i].angle1 = (short)(a*64); - xarc[i].angle2 = (short)(b*64); - ++i; - } - } - else if(what & NOW) - { - xx1=X_TO_SCREEN(x-r); - yy1=Y_TO_SCREEN(y-r); - xx2=X_TO_SCREEN(x+r); - yy2=Y_TO_SCREEN(y+r); - if(arc_fill) - arc_bbox(x, y, r, 0, 360, &x1,&y1,&x2,&y2); - else - arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2); - x1=X_TO_SCREEN(x1); - y1=Y_TO_SCREEN(y1); - x2=X_TO_SCREEN(x2); - y2=Y_TO_SCREEN(y2); - if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) - { - if(dash) { - char dash_arr[2]; - dash_arr[0] = dash_arr[1] = (char)dash; - XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); - XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin); - } - - if(xctx->draw_window) { - XDrawArc(display, xctx->window, xctx->gc[c], (int)xx1, (int)yy1, - (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); - } - if(xctx->draw_pixmap) { - XDrawArc(display, xctx->save_pixmap, xctx->gc[c], (int)xx1, (int)yy1, - (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); - } - - if(xctx->fill_pattern && (xctx->fill_type[c] || arc_fill == 3) ){ - - if(arc_fill & 2) gc = xctx->gc[c]; - else gc = xctx->gcstipple[c]; - if(arc_fill) { - if(xctx->draw_window) - XFillArc(display, xctx->window, gc, (int)xx1, (int)yy1, - (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); - if(xctx->draw_pixmap) - XFillArc(display, xctx->save_pixmap, gc, (int)xx1, (int)yy1, - (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64)); - } - } - if(dash) { - XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN); - } - } - } - else if((what & END) && i) - { - if(xctx->draw_window) XDrawArcs(display, xctx->window, xctx->gc[c], xarc,i); - if(xctx->draw_pixmap) XDrawArcs(display, xctx->save_pixmap, xctx->gc[c], xarc,i); - i=0; - } -} - - void filledrect(int c, int what, double rectx1,double recty1,double rectx2,double recty2, int fill, int e_a, int e_b) { From 1a7c9e11d1943582d693c89f376f9e0dac1b626a Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Tue, 21 Jan 2025 16:37:26 +0530 Subject: [PATCH 17/46] [Snap Cursor (WIP)]: Experimental feature 'snap_cursor' is updated. Yellow cursor that snaps to the nearest grid point is now available (always active, unless user activates crosshair using ALT+X). --- src/callback.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/callback.c b/src/callback.c index c1406a3f..94470b2a 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1433,6 +1433,33 @@ void draw_snap_cursor(int cursor_type) xctx->draw_pixmap = sdp; } +/* what == 0 : erase and draw a new cursor + * what == 1 : erase the cursor + * what == 2 : draw a dot-cursor that snaps to a nearest grid-point */ +void draw_grid_cursor(int what) +{ + int sdw, sdp; + dbg(1, "draw_grid_cursor(): what=%d\n", what); + sdw = xctx->draw_window; + sdp = xctx->draw_pixmap; + + if(!xctx->mouse_inside) return; + xctx->draw_pixmap = 0; + xctx->draw_window = 1; + if(what != 2) { + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); + } + if(what != 1) { + filledrect(8, NOW, xctx->prev_crossx-1, xctx->prev_crossy-1, xctx->prev_crossx+1, xctx->prev_crossy+1, 3, -1, -1); + } + draw_selection(xctx->gc[SELLAYER], 0); + xctx->prev_crossx = xctx->mousex_snap; + xctx->prev_crossy = xctx->mousey_snap; + + xctx->draw_window = sdw; + xctx->draw_pixmap = sdp; +} + /* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */ static int end_place_move_copy_zoom() { @@ -2377,6 +2404,7 @@ int rstate; /* (reduced state, without ShiftMask) */ case LeaveNotify: if(draw_xhair) draw_crosshair(1); + else draw_grid_cursor(1); if(snap_cursor && wire_draw_active) draw_snap_cursor(1); tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL); xctx->mouse_inside = 0; @@ -2445,13 +2473,13 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(draw_xhair) { draw_crosshair(1); - } + } else draw_grid_cursor(1); 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); - } + } else draw_grid_cursor(2); if(snap_cursor && wire_draw_active) draw_snap_cursor(2); break; } @@ -2546,7 +2574,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(draw_xhair) { draw_crosshair(2); - } + } else draw_grid_cursor(2); if(snap_cursor && wire_draw_active) draw_snap_cursor(2); break; @@ -4305,6 +4333,7 @@ int rstate; /* (reduced state, without ShiftMask) */ statusmsg(str,1); } if(draw_xhair) draw_crosshair(0); + else draw_grid_cursor(0); if(snap_cursor && wire_draw_active) draw_snap_cursor(0); break; case -3: /* double click : edit prop */ From ea7341742a654469c0ae033bdf360a314aa827a1 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Tue, 21 Jan 2025 21:37:04 +0530 Subject: [PATCH 18/46] [Undo Temporary Bugfix]: Discarded the temporary bugfix for commit ed1a471 --- src/callback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callback.c b/src/callback.c index 94470b2a..7022a157 100644 --- a/src/callback.c +++ b/src/callback.c @@ -4281,9 +4281,9 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ - /*else if(xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) {*/ - /* if(end_place_move_copy_zoom()) break;*/ - /*}*/ + else if(xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { + if(end_place_move_copy_zoom()) break; + } /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { From 634213d3c9b72fd50fe93fb159a1185bb9ed7ac4 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Tue, 21 Jan 2025 22:18:19 +0530 Subject: [PATCH 19/46] [Integrated Upstream + Temporary Bugfix]: Integrated the upstream changes for adding a custom rectangular grid-snap cursor, and re-implemented the temporary bugfix from commit ed1a471 --- src/callback.c | 41 ++++++----------------------------------- src/xschemrc | 6 +++--- 2 files changed, 9 insertions(+), 38 deletions(-) diff --git a/src/callback.c b/src/callback.c index 8dfd2761..752d7751 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1502,33 +1502,6 @@ void draw_snap_cursor(int cursor_type) xctx->draw_pixmap = sdp; } -/* what == 0 : erase and draw a new cursor - * what == 1 : erase the cursor - * what == 2 : draw a dot-cursor that snaps to a nearest grid-point */ -void draw_grid_cursor(int what) -{ - int sdw, sdp; - dbg(1, "draw_grid_cursor(): what=%d\n", what); - sdw = xctx->draw_window; - sdp = xctx->draw_pixmap; - - if(!xctx->mouse_inside) return; - xctx->draw_pixmap = 0; - xctx->draw_window = 1; - if(what != 2) { - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); - } - if(what != 1) { - filledrect(8, NOW, xctx->prev_crossx-1, xctx->prev_crossy-1, xctx->prev_crossx+1, xctx->prev_crossy+1, 3, -1, -1); - } - draw_selection(xctx->gc[SELLAYER], 0); - xctx->prev_crossx = xctx->mousex_snap; - xctx->prev_crossy = xctx->mousey_snap; - - xctx->draw_window = sdw; - xctx->draw_pixmap = sdp; -} - /* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */ static int end_place_move_copy_zoom() { @@ -2473,7 +2446,6 @@ int rstate; /* (reduced state, without ShiftMask) */ case LeaveNotify: if(draw_xhair) draw_crosshair(1); - else draw_grid_cursor(1); if(snap_cursor && wire_draw_active) draw_snap_cursor(1); tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL); xctx->mouse_inside = 0; @@ -2544,13 +2516,13 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(draw_xhair) { draw_crosshair(1); - } else draw_grid_cursor(1); + } 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); - } else draw_grid_cursor(2); + } if(snap_cursor && wire_draw_active) draw_snap_cursor(2); break; } @@ -2645,7 +2617,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(draw_xhair) { draw_crosshair(2); - } else draw_grid_cursor(2); + } if(snap_cursor && wire_draw_active) draw_snap_cursor(2); break; @@ -4352,9 +4324,9 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ - else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { - if(end_place_move_copy_zoom()) break; - } + /*else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) {*/ + /* if(end_place_move_copy_zoom()) break;*/ + /*}*/ /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { @@ -4404,7 +4376,6 @@ int rstate; /* (reduced state, without ShiftMask) */ statusmsg(str,1); } if(draw_xhair) draw_crosshair(0); - else draw_grid_cursor(0); if(snap_cursor && wire_draw_active) draw_snap_cursor(0); break; case -3: /* double click : edit prop */ diff --git a/src/xschemrc b/src/xschemrc index a8bccedf..bda256b9 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -277,13 +277,13 @@ # set enable_stretch 0 #### enable drawing crosshairs at mouse coordinates. Default: disabled (0) -# set draw_crosshair 1 +set draw_crosshair 1 #### set crosshair layer; Default 3 (TEXTLAYER) -# set crosshair_layer 3 +set crosshair_layer 8 #### set crosshair size; Default: 0 (full screen spanning crosshair) -# set crosshair_size 5 +set crosshair_size 4 #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0 From 2a97ca5716acbc72d25a1fdefb31c4ad367f7f91 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 22 Jan 2025 14:58:59 +0530 Subject: [PATCH 20/46] [Prepare For Upstream Integration]: Changes made to integrate upstream adoption of default yellow-colored grid-snapping cursor. --- src/xschemrc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xschemrc b/src/xschemrc index bda256b9..a8bccedf 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -277,13 +277,13 @@ # set enable_stretch 0 #### enable drawing crosshairs at mouse coordinates. Default: disabled (0) -set draw_crosshair 1 +# set draw_crosshair 1 #### set crosshair layer; Default 3 (TEXTLAYER) -set crosshair_layer 8 +# set crosshair_layer 3 #### set crosshair size; Default: 0 (full screen spanning crosshair) -set crosshair_size 4 +# set crosshair_size 5 #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0 From 196e0d737b90131cab2f14a9e133c6a3183de959 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 22 Jan 2025 15:11:17 +0530 Subject: [PATCH 21/46] [After-Merge Modifications]: Changed default behavior for grid-snapping cursor, returning it to pre-merge state. Can be undone by the user if necessary from the 'src/xschemrc' file --- src/xschemrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xschemrc b/src/xschemrc index e3dfb181..d6ff0abe 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -283,7 +283,7 @@ # set crosshair_layer 8 #### set crosshair size; Default: 0 (full screen spanning crosshair) -# set crosshair_size 5 +set crosshair_size 2 #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0 From 49442797002e44b0ea9cfb8b664788acb8e63ca0 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 22 Jan 2025 15:58:28 +0530 Subject: [PATCH 22/46] Some refactoring and cleanup to standardize the previously added code --- src/callback.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/callback.c b/src/callback.c index b59d7b3f..379e7993 100644 --- a/src/callback.c +++ b/src/callback.c @@ -21,7 +21,6 @@ */ #include "xschem.h" -#include /* allow to use the Windows keys as alternate for Alt */ #define SET_MODMASK ( (rstate & Mod1Mask) || (rstate & Mod4Mask) ) @@ -1463,20 +1462,20 @@ void draw_crosshair(int what) xctx->draw_pixmap = sdp; } -/* cursor_type == 0 : erase and draw a new cursor - * cursor_type == 1 : erase the cursor - * cursor_type == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */ -void draw_snap_cursor(int cursor_type) +/* what == 0 : erase and draw a new cursor + * what == 1 : erase the cursor + * what == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */ +void draw_snap_cursor(int what) { int sdw, sdp; - dbg(1, "draw_snap_cursor(): cursor_type=%d\n", cursor_type); + dbg(1, "draw_snap_cursor(): what=%d\n", what); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; if(!xctx->mouse_inside) return; xctx->draw_pixmap = 0; xctx->draw_window = 1; - if(cursor_type != 2) { + if(what != 2) { if(fix_broken_tiled_fill || !_unix) { MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); } else { @@ -1487,7 +1486,7 @@ void draw_snap_cursor(int cursor_type) drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0); } } - if(cursor_type != 1) { + if(what != 1) { double x, y; find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); double points_x[5] = {x, x+3, x, x-3, x}; From dc544f81fd67ebd1069b6d96315c9da22afbd5c5 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 22 Jan 2025 17:02:04 +0530 Subject: [PATCH 23/46] [Grid-Snap Cursor Update (WIP)]: The grid snap cursor is now drawn with constant-pixel-size, regardless of the schematic editor's zoom level. This behavior will be interchangeble with the upstream version's behavior via a menu-option or a custom tcl-command in the future. --- src/callback.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++---- src/xinit.c | 1 + src/xschem.h | 1 + 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/callback.c b/src/callback.c index 379e7993..09febe6b 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1353,7 +1353,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int /* what == 0 : delete and draw * what == 1 : delete * what == 2 : draw */ -void draw_crosshair(int what) +void draw_crosshair_old(int what) { int sdw, sdp; int xhair_size = tclgetintvar("crosshair_size"); @@ -1462,6 +1462,70 @@ void draw_crosshair(int what) xctx->draw_pixmap = sdp; } +/* what == 0 : delete and draw + * what == 1 : delete + * what == 2 : draw */ +void draw_crosshair(int what) /* For drawing the grid-snapping cursor with constant pixel-size */ +{ + int sdw, sdp; + int xhair_size = tclgetintvar("crosshair_size"); + dbg(1, "draw_crosshair_constpixel(): what=%d\n", what); + sdw = xctx->draw_window; + sdp = xctx->draw_pixmap; + + if(!xctx->mouse_inside) return; + + xctx->draw_pixmap = 0; + xctx->draw_window = 1; + if(what != 2) { /* delete previous */ + if(fix_broken_tiled_fill || !_unix) { + if(xhair_size) { + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); + } 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)); + 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); + } + } else { + if(xhair_size) { + drawtemprect(xctx->gctiled, NOW, + xctx->prev_crossx - xhair_size, xctx->prev_crossy - xhair_size, + xctx->prev_crossx + xhair_size, xctx->prev_crossy + xhair_size); + } else { /* full screen span xhair */ + drawtempline(xctx->gctiled, NOW, X_TO_XSCHEM(xctx->areax1), + xctx->prev_crossy, X_TO_XSCHEM(xctx->areax2), xctx->prev_crossy); + drawtempline(xctx->gctiled, NOW, xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay1), + xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay2)); + } + } + } + if(what != 1) { /* draw new */ + if(xhair_size) { + drawrect(xctx->crosshair_layer, NOW, xctx->prev_crossx - xhair_size, xctx->prev_crossy - xhair_size, + xctx->prev_crossx + xhair_size, xctx->prev_crossy + xhair_size, + 0, -1, -1); + } else { /* full screen span xhair */ + draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, + xctx->areax1, Y_TO_SCREEN(xctx->mousey_snap), + xctx->areax2, Y_TO_SCREEN(xctx->mousey_snap)); + draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, + X_TO_SCREEN(xctx->mousex_snap), xctx->areay1, + X_TO_SCREEN(xctx->mousex_snap), xctx->areay2); + } + } + draw_selection(xctx->gc[SELLAYER], 0); + xctx->prev_crossx = xctx->mousex_snap; + xctx->prev_crossy = xctx->mousey_snap; + + xctx->draw_window = sdw; + xctx->draw_pixmap = sdp; +} + /* what == 0 : erase and draw a new cursor * what == 1 : erase the cursor * what == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */ @@ -1479,8 +1543,8 @@ void draw_snap_cursor(int what) if(fix_broken_tiled_fill || !_unix) { MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); } else { - double prev_x = xctx->prev_crossx; - double prev_y = xctx->prev_crossy; + double prev_x = xctx->prev_snapx; + double prev_y = xctx->prev_snapy; double points_x[5] = {prev_x, prev_x+3, prev_x, prev_x-3, prev_x}; double points_y[5] = {prev_y-3, prev_y, prev_y+3, prev_y, prev_y-3}; drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0); @@ -1492,8 +1556,8 @@ void draw_snap_cursor(int what) double points_x[5] = {x, x+3, x, x-3, x}; double points_y[5] = {y-3, y, y+3, y, y-3}; drawpolygon(8, NOW, points_x, points_y, 5, 0, 0, 0); - xctx->prev_crossx = x; - xctx->prev_crossy = y; + xctx->prev_snapx = x; + xctx->prev_snapy = y; } draw_selection(xctx->gc[SELLAYER], 0); diff --git a/src/xinit.c b/src/xinit.c index 82edc3a3..25d2f9f6 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -646,6 +646,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->enable_drill = 0; xctx->prev_set_modify = -1; xctx->prev_crossx = xctx->prev_crossy = 0.0; + xctx->prev_snapx = xctx->prev_snapy = 0.0; xctx->mouse_inside = 0; xctx->pending_fullzoom = 0; my_strncpy(xctx->hiersep, ".", S(xctx->hiersep)); diff --git a/src/xschem.h b/src/xschem.h index 0fcae282..04f80698 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1049,6 +1049,7 @@ typedef struct { double p_xx1,p_xx2,p_yy1,p_yy2; /* draw_crosshair */ double prev_crossx, prev_crossy; + double prev_snapx, prev_snapy; int mouse_inside; /* set_modify */ int prev_set_modify; From 4c5421fddafd45f0af4b14453a96381f1e47b741 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 22 Jan 2025 17:08:16 +0530 Subject: [PATCH 24/46] [Bugfix]: Fixed a bug where the non-persistent wire-draw mode didn't put down a new anchor-point when 'w'-key was pressed by user. This bug was introduced in the upstream-merge (commit 8ce32b7) after incorrectly adopting the upstream way of handling 'infix_interface' mode. --- src/callback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/callback.c b/src/callback.c index 09febe6b..99fb8c27 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2953,6 +2953,7 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->last_command = 0; xctx->ui_state |= MENUSTART; xctx->ui_state2 = MENUSTARTWIRE; + if(prev_state & STARTWIRE) start_wire(xctx->mousex_snap, xctx->mousey_snap); } break; } From 248596f81ce2b0138c870259778062b9161a757f Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 22 Jan 2025 17:30:14 +0530 Subject: [PATCH 25/46] [Refactoring]: Renamed variables and added inline code-comments for better code readability. --- src/callback.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/callback.c b/src/callback.c index 99fb8c27..3df27b46 100644 --- a/src/callback.c +++ b/src/callback.c @@ -102,8 +102,10 @@ void redraw_w_a_l_r_p_rubbers(void) if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; if(tclgetboolvar("orthogonal_wiring")) { new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); - int tmp_x2 = xctx->nl_x2 - xctx->nl_x1, tmp_y2 = xctx->nl_y2 - xctx->nl_y1; - if(tmp_x2*tmp_x2 > tmp_y2*tmp_y2){ + /* Origin shift the cartesian coordinate p2(x2,y2) w.r.t. p1(x1,y1) */ + int origin_shifted_x2 = xctx->nl_x2 - xctx->nl_x1, origin_shifted_y2 = xctx->nl_y2 - xctx->nl_y1; + /* Draw whichever component of the resulting orthogonal-wire is bigger (either horizontal or vertical), first */ + if(origin_shifted_x2*origin_shifted_x2 > origin_shifted_y2*origin_shifted_y2){ xctx->manhattan_lines = 1; } else { xctx->manhattan_lines = 2; From 4b8a3c653b19b8bd53311d773bb8f52c33d10772 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 22 Jan 2025 19:01:48 +0530 Subject: [PATCH 26/46] [New Experimental Functionality]: Added the functionality of terminating the wire-draw mode when the user clicks a component endpoint. This feature is currently on by default (if the user has the 'Display snap cursor' option enabled. --- src/callback.c | 9 ++++++++- src/xschem.tcl | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/callback.c b/src/callback.c index 3df27b46..f1a36095 100644 --- a/src/callback.c +++ b/src/callback.c @@ -4272,7 +4272,14 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->drag_elements = 0; 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) start_wire(xctx->mousex_snap, xctx->mousey_snap); + if(xctx->last_command == STARTWIRE){ + if(tclgetboolvar("snap_cursor") && (xctx->prev_snapx == xctx->mousex_snap && xctx->prev_snapy == xctx->mousey_snap)){ + new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap); + xctx->last_command &= ~STARTWIRE; + } + else + start_wire(xctx->mousex_snap, xctx->mousey_snap); + } break; } /* handle all object insertions started from Tools/Edit menu */ diff --git a/src/xschem.tcl b/src/xschem.tcl index 6d5493ce..34696455 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -8200,7 +8200,7 @@ proc build_widgets { {topwin {} } } { -selectcolor $selectcolor -accelerator Y $topwin.menubar.option add checkbutton -label "Enable infix-interface" -variable infix_interface \ -selectcolor $selectcolor - $topwin.menubar.option add checkbutton -label "Enable snap cursor" -variable snap_cursor \ + $topwin.menubar.option add checkbutton -label "Display snap cursor" -variable snap_cursor \ -selectcolor $selectcolor $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring" -variable orthogonal_wiring \ -selectcolor $selectcolor -accelerator Shift+L From 710f8577650e746fc2685758ab9d57110f4f25a0 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 17:45:49 +0530 Subject: [PATCH 27/46] [Snap Cursor Update (WIP)]: Added keybind to activate snap_cursor + new tcl-command to adjust 'snap_cursor_size'. Added grid-coordinate checks for better performance using the 'find_closest_net_or_symbol_pin()' function (by only running the search when the grid-snap position changes). Fixed xctx->prev_crossx and xctx->prev_crossy conflict between draw_crosshair() and draw_snap_cursor() by using the new globally accesible variables 'xctx->prev_gridx' and 'xctx->prev_gridy' in draw_snap_cursor(). --- src/callback.c | 97 ++++++++++++++------------------------------------ src/xinit.c | 1 + src/xschem.h | 1 + src/xschem.tcl | 9 ++--- src/xschemrc | 3 ++ 5 files changed, 36 insertions(+), 75 deletions(-) diff --git a/src/callback.c b/src/callback.c index 30a2516e..3d7000e2 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1355,7 +1355,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int /* what == 0 : delete and draw * what == 1 : delete * what == 2 : draw */ -void draw_crosshair_old(int what) +void draw_crosshair(int what) { int sdw, sdp; int xhair_size = tclgetintvar("crosshair_size"); @@ -1464,76 +1464,14 @@ void draw_crosshair_old(int what) xctx->draw_pixmap = sdp; } -/* what == 0 : delete and draw - * what == 1 : delete - * what == 2 : draw */ -void draw_crosshair(int what) /* For drawing the grid-snapping cursor with constant pixel-size */ -{ - int sdw, sdp; - int xhair_size = tclgetintvar("crosshair_size"); - dbg(1, "draw_crosshair_constpixel(): what=%d\n", what); - sdw = xctx->draw_window; - sdp = xctx->draw_pixmap; - - if(!xctx->mouse_inside) return; - - xctx->draw_pixmap = 0; - xctx->draw_window = 1; - if(what != 2) { /* delete previous */ - if(fix_broken_tiled_fill || !_unix) { - if(xhair_size) { - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); - } 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)); - 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); - } - } else { - if(xhair_size) { - drawtemprect(xctx->gctiled, NOW, - xctx->prev_crossx - xhair_size, xctx->prev_crossy - xhair_size, - xctx->prev_crossx + xhair_size, xctx->prev_crossy + xhair_size); - } else { /* full screen span xhair */ - drawtempline(xctx->gctiled, NOW, X_TO_XSCHEM(xctx->areax1), - xctx->prev_crossy, X_TO_XSCHEM(xctx->areax2), xctx->prev_crossy); - drawtempline(xctx->gctiled, NOW, xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay1), - xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay2)); - } - } - } - if(what != 1) { /* draw new */ - if(xhair_size) { - drawrect(xctx->crosshair_layer, NOW, xctx->prev_crossx - xhair_size, xctx->prev_crossy - xhair_size, - xctx->prev_crossx + xhair_size, xctx->prev_crossy + xhair_size, - 0, -1, -1); - } else { /* full screen span xhair */ - draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - xctx->areax1, Y_TO_SCREEN(xctx->mousey_snap), - xctx->areax2, Y_TO_SCREEN(xctx->mousey_snap)); - draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - X_TO_SCREEN(xctx->mousex_snap), xctx->areay1, - X_TO_SCREEN(xctx->mousex_snap), xctx->areay2); - } - } - draw_selection(xctx->gc[SELLAYER], 0); - xctx->prev_crossx = xctx->mousex_snap; - xctx->prev_crossy = xctx->mousey_snap; - - xctx->draw_window = sdw; - xctx->draw_pixmap = sdp; -} - /* what == 0 : erase and draw a new cursor * what == 1 : erase the cursor * what == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */ void draw_snap_cursor(int what) { int sdw, sdp; + int snapcursor_size = tclgetintvar("snap_cursor_size"); + int pos_changed = (xctx->mousex_snap - xctx->prev_gridx) || (xctx->mousey_snap - xctx->prev_gridy); dbg(1, "draw_snap_cursor(): what=%d\n", what); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; @@ -1547,17 +1485,24 @@ void draw_snap_cursor(int what) } else { double prev_x = xctx->prev_snapx; double prev_y = xctx->prev_snapy; - double points_x[5] = {prev_x, prev_x+3, prev_x, prev_x-3, prev_x}; - double points_y[5] = {prev_y-3, prev_y, prev_y+3, prev_y, prev_y-3}; + double points_x[5] = {prev_x, prev_x+snapcursor_size, prev_x, prev_x-snapcursor_size, prev_x}; + double points_y[5] = {prev_y-snapcursor_size, prev_y, prev_y+snapcursor_size, prev_y, prev_y-snapcursor_size}; drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0); } } if(what != 1) { double x, y; - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - double points_x[5] = {x, x+3, x, x-3, x}; - double points_y[5] = {y-3, y, y+3, y, y-3}; - drawpolygon(8, NOW, points_x, points_y, 5, 0, 0, 0); + if(!pos_changed) { + x = xctx->prev_snapx; + y = xctx->prev_snapy; + } else { /* Only search for nearest pin if the grid-snap-point has changed */ + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + } + double points_x[5] = {x, x+snapcursor_size, x, x-snapcursor_size, x}; + double points_y[5] = {y-snapcursor_size, y, y+snapcursor_size, y, y-snapcursor_size}; + drawpolygon(xctx->crosshair_layer, NOW, points_x, points_y, 5, 0, 0, 0); + xctx->prev_gridx = xctx->mousex_snap; + xctx->prev_gridy = xctx->mousey_snap; xctx->prev_snapx = x; xctx->prev_snapy = y; } @@ -2988,6 +2933,16 @@ int rstate; /* (reduced state, without ShiftMask) */ { view_zoom(0.0); break; } + if(key=='z' && EQUAL_MODMASK) /* toggle snap-cursor option */ + { + if(tclgetboolvar("snap_cursor")) { + tclsetvar("snap_cursor", "0"); + draw_snap_cursor(1); + } else { + tclsetvar("snap_cursor", "1"); + if(wire_draw_active) draw_snap_cursor(0); + } + } if(key=='p' && EQUAL_MODMASK) /* add symbol pin */ { xctx->push_undo(); diff --git a/src/xinit.c b/src/xinit.c index 25d2f9f6..acb456ef 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -646,6 +646,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->enable_drill = 0; xctx->prev_set_modify = -1; xctx->prev_crossx = xctx->prev_crossy = 0.0; + xctx->prev_gridx = xctx->prev_gridy = 0.0; xctx->prev_snapx = xctx->prev_snapy = 0.0; xctx->mouse_inside = 0; xctx->pending_fullzoom = 0; diff --git a/src/xschem.h b/src/xschem.h index 04f80698..23d9d254 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1049,6 +1049,7 @@ typedef struct { double p_xx1,p_xx2,p_yy1,p_yy2; /* draw_crosshair */ double prev_crossx, prev_crossy; + double prev_gridx, prev_gridy; double prev_snapx, prev_snapy; int mouse_inside; /* set_modify */ diff --git a/src/xschem.tcl b/src/xschem.tcl index 34696455..fda04474 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7656,7 +7656,7 @@ set tctx::global_list { add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow autotrim_wires orthogonal_wiring snap_cursor bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv - copy_cell crosshair_layer crosshair_size custom_label_prefix custom_token dark_colors dark_colorscheme + copy_cell crosshair_layer crosshair_size snap_cursor_size custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names do_all_inst draw_crosshair draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size @@ -8200,10 +8200,8 @@ proc build_widgets { {topwin {} } } { -selectcolor $selectcolor -accelerator Y $topwin.menubar.option add checkbutton -label "Enable infix-interface" -variable infix_interface \ -selectcolor $selectcolor - $topwin.menubar.option add checkbutton -label "Display snap cursor" -variable snap_cursor \ - -selectcolor $selectcolor $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring" -variable orthogonal_wiring \ - -selectcolor $selectcolor -accelerator Shift+L + -selectcolor $selectcolor -accelerator Shift-L $topwin.menubar.option add checkbutton -label "Unsel. partial sel. wires after stretch move" \ -selectcolor $selectcolor -variable unselect_partial_sel_wires @@ -8222,6 +8220,8 @@ proc build_widgets { {topwin {} } } { $topwin.menubar.option add checkbutton -label "Draw crosshair" \ -variable draw_crosshair -selectcolor $selectcolor -accelerator {Alt-X} + $topwin.menubar.option add checkbutton -label "Draw persistent snap cursor" -variable snap_cursor \ + -selectcolor $selectcolor -accelerator {Alt-Z} $topwin.menubar.option add command -label "Replace \[ and \] for buses in SPICE netlist" \ -command { @@ -9106,6 +9106,7 @@ set_ne ps_page_title 1 ;# add a title in the top left page corner set_ne draw_crosshair 0 set_ne crosshair_layer 8 ;# Yellow set_ne crosshair_size 0 +set_ne snap_cursor_size 3 set_ne ps_paper_size {a4 842 595} set_ne transparent_svg 0 set_ne only_probes 0 ; # 20110112 diff --git a/src/xschemrc b/src/xschemrc index d6ff0abe..f7d7253e 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -285,6 +285,9 @@ #### set crosshair size; Default: 0 (full screen spanning crosshair) set crosshair_size 2 +#### set snap_cursor size; Default: 3 (Diamond-shaped cursor that snaps to nearest circuit endpoint) +# set snap_cursor size 3 + #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0 From 783bccf8cf45d86a4ee401033effe2823488ba57 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 19:14:58 +0530 Subject: [PATCH 28/46] Added changes to resolve merge conflicts --- src/callback.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/callback.c b/src/callback.c index 3d7000e2..b97cf9e9 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2882,7 +2882,7 @@ int rstate; /* (reduced state, without ShiftMask) */ hilight_net_pin_mismatches(); break; } - if(key== 's' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ + if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ if(xctx->semaphore >= 2) break; snapped_wire(c_snap); break; @@ -4366,9 +4366,9 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ - /*else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) {*/ - /* if(end_place_move_copy_zoom()) break;*/ - /*}*/ + else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { + if(end_place_move_copy_zoom()) break; + } /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { From ffcbeaec66e0d097fb799c7591f36277f0f6504e Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 19:46:16 +0530 Subject: [PATCH 29/46] [After merge-changes]: Re-introduced temporary bugfix and altered snap-cursor keybind to match pre-merge state of this fork. --- src/callback.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/callback.c b/src/callback.c index df00821a..d32a1ba1 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2864,7 +2864,7 @@ int rstate; /* (reduced state, without ShiftMask) */ hilight_net_pin_mismatches(); break; } - if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ + if(key== 's' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ if(xctx->semaphore >= 2) break; if(infix_interface) { snapped_wire(c_snap); @@ -4352,10 +4352,10 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin or wire endpoint */ - else if(state == Button1Mask && xctx->intuitive_interface && - (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) { - if(end_place_move_copy_zoom()) break; - } + /*else if(state == Button1Mask && xctx->intuitive_interface &&*/ + /* (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) {*/ + /* if(end_place_move_copy_zoom()) break;*/ + /*}*/ /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { From 8c1bfc93f67d5e65f9d794d31955498384bbd35e Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 20:00:59 +0530 Subject: [PATCH 30/46] [Revert changes] --- src/callback.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/callback.c b/src/callback.c index d32a1ba1..df00821a 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2864,7 +2864,7 @@ int rstate; /* (reduced state, without ShiftMask) */ hilight_net_pin_mismatches(); break; } - if(key== 's' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ + if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ if(xctx->semaphore >= 2) break; if(infix_interface) { snapped_wire(c_snap); @@ -4352,10 +4352,10 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin or wire endpoint */ - /*else if(state == Button1Mask && xctx->intuitive_interface &&*/ - /* (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) {*/ - /* if(end_place_move_copy_zoom()) break;*/ - /*}*/ + else if(state == Button1Mask && xctx->intuitive_interface && + (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) { + if(end_place_move_copy_zoom()) break; + } /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { From 3556f3599c034c4bb875c210e9e868efb59a7c42 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 20:03:12 +0530 Subject: [PATCH 31/46] [Revert changes] --- src/actions.c | 24 ++++++-------- src/callback.c | 86 +++++++++++++++++++++++++++----------------------- src/xschem.h | 1 - 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/actions.c b/src/actions.c index 60ee1174..4c07a46f 100644 --- a/src/actions.c +++ b/src/actions.c @@ -3019,7 +3019,7 @@ void new_wire(int what, double mx_snap, double my_snap) if( (what & PLACE) ) { if( (xctx->ui_state & STARTWIRE) && (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) ) { xctx->push_undo(); - if(xctx->manhattan_lines & 1) { + if(xctx->manhattan_lines==1) { if(xctx->nl_xx2!=xctx->nl_xx1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3038,7 +3038,7 @@ void new_wire(int what, double mx_snap, double my_snap) hash_wire(XINSERT, xctx->wires-1, 1); drawline(WIRELAYER,NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2, 0, NULL); } - } else if(xctx->manhattan_lines & 2) { + } else if(xctx->manhattan_lines==2) { if(xctx->nl_yy2!=xctx->nl_yy1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3076,8 +3076,6 @@ void new_wire(int what, double mx_snap, double my_snap) draw(); /* draw_hilight_net(1);*/ /* for updating connection bubbles on hilight nets */ } - -#if 0 if(! (what &END)) { xctx->nl_x1=mx_snap; xctx->nl_y1=my_snap; @@ -3087,7 +3085,7 @@ void new_wire(int what, double mx_snap, double my_snap) xctx->nl_yy1=xctx->nl_y1; xctx->nl_xx2=xctx->mousex_snap; xctx->nl_yy2=xctx->mousey_snap; - if(xctx->manhattan_lines & 1) { + if(xctx->manhattan_lines==1) { xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap; xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3097,7 +3095,7 @@ void new_wire(int what, double mx_snap, double my_snap) xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); - } else if(xctx->manhattan_lines & 2) { + } else if(xctx->manhattan_lines==2) { xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap; xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3115,8 +3113,6 @@ void new_wire(int what, double mx_snap, double my_snap) drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); } } -#endif - xctx->nl_x1 = xctx->nl_x2=mx_snap; xctx->nl_y1 = xctx->nl_y2=my_snap; xctx->ui_state |= STARTWIRE; if(modified) set_modify(1); } @@ -3124,7 +3120,7 @@ void new_wire(int what, double mx_snap, double my_snap) xctx->ui_state &= ~STARTWIRE; } if( (what & RUBBER) ) { - if(xctx->manhattan_lines & 1) { + if(xctx->manhattan_lines==1) { xctx->nl_xx1=xctx->nl_x1;xctx->nl_yy1=xctx->nl_y1; xctx->nl_xx2=xctx->nl_x2;xctx->nl_yy2=xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1); @@ -3145,7 +3141,7 @@ void new_wire(int what, double mx_snap, double my_snap) ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); } - } else if(xctx->manhattan_lines & 2) { + } else if(xctx->manhattan_lines==2) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2); @@ -3315,7 +3311,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) if( (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) && (xctx->ui_state & STARTLINE) ) { xctx->push_undo(); - if(xctx->manhattan_lines & 1) { + if(xctx->manhattan_lines==1) { if(xctx->nl_xx2!=xctx->nl_xx1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3332,7 +3328,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) modified = 1; drawline(xctx->rectcolor,NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2, 0, NULL); } - } else if(xctx->manhattan_lines & 2) { + } else if(xctx->manhattan_lines==2) { if(xctx->nl_yy2!=xctx->nl_yy1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3369,7 +3365,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) if(what & RUBBER) { - if(xctx->manhattan_lines & 1) { + if(xctx->manhattan_lines==1) { xctx->nl_xx1 = xctx->nl_x1;xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2;xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1); @@ -3390,7 +3386,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); drawtempline(xctx->gc[xctx->rectcolor], NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); } - } else if(xctx->manhattan_lines & 2) { + } else if(xctx->manhattan_lines==2) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2); diff --git a/src/callback.c b/src/callback.c index df00821a..b97cf9e9 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1593,25 +1593,6 @@ static int end_place_move_copy_zoom() return 0; } -void snapped_wire(double c_snap) -{ - double x, y; - if(!(xctx->ui_state & STARTWIRE)){ - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - xctx->mx_double_save = my_round(x / c_snap) * c_snap; - xctx->my_double_save = my_round(y / c_snap) * c_snap; - new_wire(PLACE, x, y); - new_wire(RUBBER, xctx->mousex_snap,xctx->mousey_snap); - } - else { - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - new_wire(RUBBER, x, y); - new_wire(PLACE|END, x, y); - xctx->constr_mv=0; - tcleval("set constr_mv 0" ); - } -} - static int check_menu_start_commands(double c_snap) { dbg(1, "check_menu_start_commands(): ui_state=%x, ui_state2=%x last_command=%d\n", @@ -1619,10 +1600,12 @@ static int check_menu_start_commands(double c_snap) if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT)) { break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT2)) { break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTMOVE)) { @@ -1631,12 +1614,14 @@ static int check_menu_start_commands(double c_snap) /* stretch nets that land on selected instance pins if connect_by_kissing == 2 */ /* select_attached_nets(); */ move_objects(START,0,0,0); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTCOPY)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; copy_objects(START); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) { @@ -1647,6 +1632,8 @@ static int check_menu_start_commands(double c_snap) tcleval("set constr_mv 0" ); xctx->constr_mv=0; } + xctx->ui_state &=~MENUSTART; + xctx->ui_state2 = 0; /* * xctx->mx_double_save=xctx->mousex_snap; @@ -1657,7 +1644,13 @@ static int check_menu_start_commands(double c_snap) return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTSNAPWIRE)) { - snapped_wire(c_snap); + double x, y; + + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + xctx->mx_double_save = my_round(x / c_snap) * c_snap; + xctx->my_double_save = my_round(y / c_snap) * c_snap; + new_wire(PLACE, x, y); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTLINE)) { @@ -1668,6 +1661,8 @@ static int check_menu_start_commands(double c_snap) tcleval("set constr_mv 0" ); xctx->constr_mv=0; } + xctx->ui_state &=~MENUSTART; + xctx->ui_state2 = 0; /* * xctx->mx_double_save=xctx->mousex_snap; @@ -1681,28 +1676,33 @@ static int check_menu_start_commands(double c_snap) xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_rect(PLACE,xctx->mousex_snap, xctx->mousey_snap); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTPOLYGON)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_polygon(PLACE, xctx->mousex_snap, xctx->mousey_snap); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTARC)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_arc(PLACE, 180., xctx->mousex_snap, xctx->mousey_snap); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTCIRCLE)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_arc(PLACE, 360., xctx->mousex_snap, xctx->mousey_snap); + xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTZOOM)) { zoom_rectangle(START); + xctx->ui_state &=~MENUSTART; return 1; } return 0; @@ -2300,6 +2300,25 @@ static int grabscreen(const char *winpath, int event, int mx, int my, KeySym key } #endif +static void snapped_wire(double c_snap) +{ + double x, y; + if(!(xctx->ui_state & STARTWIRE)){ + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + xctx->mx_double_save = my_round(x / c_snap) * c_snap; + xctx->my_double_save = my_round(y / c_snap) * c_snap; + new_wire(PLACE, x, y); + new_wire(RUBBER, xctx->mousex_snap,xctx->mousey_snap); + } + else { + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + new_wire(RUBBER, x, y); + new_wire(PLACE|END, x, y); + xctx->constr_mv=0; + tcleval("set constr_mv 0" ); + } +} + /* main window callback */ /* mx and my are set to the mouse coord. relative to window */ /* winpath: set to .drw or sub windows .x1.drw, .x2.drw, ... */ @@ -2608,8 +2627,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* snap crosshair to closest pin or net endpoint */ if(draw_xhair) { - if( ( (xctx->ui_state & (MENUSTART | STARTWIRE) ) || xctx->ui_state == 0 ) && - (state == ShiftMask) ) { + if( ( (xctx->ui_state & STARTWIRE) || xctx->ui_state == 0 ) && (state & ShiftMask) ) { double x, y, sx, sy; sx = xctx->mousex_snap; sy = xctx->mousey_snap; @@ -2637,7 +2655,7 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->manhattan_lines %=3; new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); - } else if(xctx->ui_state & STARTLINE) { + } else if(xctx->ui_state==STARTLINE) { new_line(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); xctx->manhattan_lines++; xctx->manhattan_lines %=3; @@ -2866,12 +2884,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ if(xctx->semaphore >= 2) break; - if(infix_interface) { - snapped_wire(c_snap); - } else { - xctx->ui_state |= MENUSTART; - xctx->ui_state2 = MENUSTARTSNAPWIRE; - } + snapped_wire(c_snap); break; } if(key == 'w' /* && !xctx->ui_state */ && rstate==0) /* place wire. */ @@ -4178,6 +4191,7 @@ int rstate; /* (reduced state, without ShiftMask) */ /* terminate wire placement in snap mode */ else if(button==Button1 && (state & ShiftMask) && (xctx->ui_state & STARTWIRE) ) { snapped_wire(c_snap); + here(1111); } /* Alt - Button1 click to unselect */ else if(button==Button1 && (SET_MODMASK) ) { @@ -4351,12 +4365,11 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->semaphore = savesem; } - /* end wire creation when dragging in intuitive interface from an inst pin or wire endpoint */ - else if(state == Button1Mask && xctx->intuitive_interface && - (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) { + /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ + else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { if(end_place_move_copy_zoom()) break; } - + /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { copy_objects(END); @@ -4404,13 +4417,6 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->mousex_snap, xctx->mousey_snap, xctx->lastsel, xctx->sch_path[xctx->currsch] ); statusmsg(str,1); } - - /* clear start from menu flag or infix_interface=0 start commands */ - if(xctx->ui_state & MENUSTART) { - xctx->ui_state &= ~MENUSTART; - break; - } - if(draw_xhair) draw_crosshair(0); if(snap_cursor && wire_draw_active) draw_snap_cursor(0); break; diff --git a/src/xschem.h b/src/xschem.h index 1fe3d3bd..23d9d254 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1393,7 +1393,6 @@ extern int Tcl_AppInit(Tcl_Interp *interp); extern void abort_operation(void); extern void draw_crosshair(int what); extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr); -/* extern void snapped_wire(double c_snap); */ extern int callback(const char *winpath, int event, int mx, int my, KeySym key, int button, int aux, int state); extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h); From 935696ef81905b70c7c7be40a2c3678a6104e55b Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 20:04:27 +0530 Subject: [PATCH 32/46] [Revert changes] --- src/callback.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/callback.c b/src/callback.c index b97cf9e9..3d7000e2 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2882,7 +2882,7 @@ int rstate; /* (reduced state, without ShiftMask) */ hilight_net_pin_mismatches(); break; } - if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ + if(key== 's' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */ if(xctx->semaphore >= 2) break; snapped_wire(c_snap); break; @@ -4366,9 +4366,9 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ - else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { - if(end_place_move_copy_zoom()) break; - } + /*else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) {*/ + /* if(end_place_move_copy_zoom()) break;*/ + /*}*/ /* end intuitive_interface copy or move */ if(xctx->ui_state & STARTCOPY && xctx->drag_elements) { From 0a0ef228fe1eefdf0a492b3dccd8e59d8903ed9d Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 20:26:20 +0530 Subject: [PATCH 33/46] [Bugfix]: Fixed a bug where drawing a wire in an empty canvas caused the snap-cursor to detect it's own endpoint as a snap-point and incorrectly terminate wire-drawing mode --- src/callback.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/callback.c b/src/callback.c index 3d7000e2..3d00c1ba 100644 --- a/src/callback.c +++ b/src/callback.c @@ -4230,9 +4230,10 @@ int rstate; /* (reduced state, without ShiftMask) */ 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){ - if(tclgetboolvar("snap_cursor") && (xctx->prev_snapx == xctx->mousex_snap && xctx->prev_snapy == xctx->mousey_snap)){ + if(tclgetboolvar("snap_cursor") && (xctx->prev_snapx == xctx->mousex_snap && xctx->prev_snapy == xctx->mousey_snap) + && (xctx->ui_state & STARTWIRE)){ new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap); - xctx->last_command &= ~STARTWIRE; + xctx->ui_state &= ~STARTWIRE; } else start_wire(xctx->mousex_snap, xctx->mousey_snap); From ea7d0d94c51a0e0c18252742498cfc284f810e82 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 22:58:35 +0530 Subject: [PATCH 34/46] [Snap Cursor Update (WIP)]: Added dynamically scaling snap cursor. --- src/callback.c | 26 +++++++++++++++++++++++--- src/xschem.tcl | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/callback.c b/src/callback.c index 3d00c1ba..6a2b3339 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1498,9 +1498,29 @@ void draw_snap_cursor(int what) } else { /* Only search for nearest pin if the grid-snap-point has changed */ find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); } - double points_x[5] = {x, x+snapcursor_size, x, x-snapcursor_size, x}; - double points_y[5] = {y-snapcursor_size, y, y+snapcursor_size, y, y-snapcursor_size}; - drawpolygon(xctx->crosshair_layer, NOW, points_x, points_y, 5, 0, 0, 0); + /*double points_x[5] = {x, x+snapcursor_size, x, x-snapcursor_size, x};*/ + /*double points_y[5] = {y-snapcursor_size, y, y+snapcursor_size, y, y-snapcursor_size};*/ + /*drawpolygon(xctx->crosshair_layer, NOW, points_x, points_y, 5, 0, 0, 0);*/ + draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size, + X_TO_SCREEN(x), + Y_TO_SCREEN(y) - snapcursor_size, + X_TO_SCREEN(x) + snapcursor_size, + Y_TO_SCREEN(y)); + draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size, + X_TO_SCREEN(x) + snapcursor_size, + Y_TO_SCREEN(y), + X_TO_SCREEN(x), + Y_TO_SCREEN(y) + snapcursor_size); + draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size, + X_TO_SCREEN(x), + Y_TO_SCREEN(y) + snapcursor_size, + X_TO_SCREEN(x) - snapcursor_size, + Y_TO_SCREEN(y)); + draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size, + X_TO_SCREEN(x) - snapcursor_size, + Y_TO_SCREEN(y), + X_TO_SCREEN(x), + Y_TO_SCREEN(y) - snapcursor_size); xctx->prev_gridx = xctx->mousex_snap; xctx->prev_gridy = xctx->mousey_snap; xctx->prev_snapx = x; diff --git a/src/xschem.tcl b/src/xschem.tcl index fda04474..81739137 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -9106,7 +9106,7 @@ set_ne ps_page_title 1 ;# add a title in the top left page corner set_ne draw_crosshair 0 set_ne crosshair_layer 8 ;# Yellow set_ne crosshair_size 0 -set_ne snap_cursor_size 3 +set_ne snap_cursor_size 6 set_ne ps_paper_size {a4 842 595} set_ne transparent_svg 0 set_ne only_probes 0 ; # 20110112 From fefbd922d50f08a87b885e46b9e9c08d04ec7429 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Fri, 24 Jan 2025 14:40:29 +0530 Subject: [PATCH 35/46] [Bugfix - Snap Cursor]: Fully removed the bug from commit 0a0ef22. Solved by introducing breaking change in 'find_closest_net_or_symbol_pin()' function defined in 'src/xschem.h' and implemented in 'src/findnet.c'. The function now returns a boolean value indicating if the search yielded any valid results, instead of returning nothing (void). --- src/callback.c | 57 ++++++++++++++++++++++++++++++++++++++------------ src/findnet.c | 7 ++++++- src/xinit.c | 1 + src/xschem.h | 4 +++- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/callback.c b/src/callback.c index 6a2b3339..f3a64f41 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1479,15 +1479,46 @@ void draw_snap_cursor(int what) if(!xctx->mouse_inside) return; xctx->draw_pixmap = 0; xctx->draw_window = 1; + double prev_x = xctx->prev_snapx; + double prev_y = xctx->prev_snapy; if(what != 2) { if(fix_broken_tiled_fill || !_unix) { - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); - } else { - double prev_x = xctx->prev_snapx; - double prev_y = xctx->prev_snapy; - double points_x[5] = {prev_x, prev_x+snapcursor_size, prev_x, prev_x-snapcursor_size, prev_x}; - double points_y[5] = {prev_y-snapcursor_size, prev_y, prev_y+snapcursor_size, prev_y, prev_y-snapcursor_size}; - drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0); + /*MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0);*/ + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size); + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size); + } else { + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) - snapcursor_size, + X_TO_SCREEN(prev_x) + snapcursor_size, + Y_TO_SCREEN(prev_y)); + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x) + snapcursor_size, + Y_TO_SCREEN(prev_y), + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) + snapcursor_size); + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) + snapcursor_size, + X_TO_SCREEN(prev_x) - snapcursor_size, + Y_TO_SCREEN(prev_y)); + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x) - snapcursor_size, + Y_TO_SCREEN(prev_y), + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) - snapcursor_size); } } if(what != 1) { @@ -1496,11 +1527,8 @@ void draw_snap_cursor(int what) x = xctx->prev_snapx; y = xctx->prev_snapy; } else { /* Only search for nearest pin if the grid-snap-point has changed */ - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + xctx->closest_pin_found = find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); } - /*double points_x[5] = {x, x+snapcursor_size, x, x-snapcursor_size, x};*/ - /*double points_y[5] = {y-snapcursor_size, y, y+snapcursor_size, y, y-snapcursor_size};*/ - /*drawpolygon(xctx->crosshair_layer, NOW, points_x, points_y, 5, 0, 0, 0);*/ draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size, X_TO_SCREEN(x), Y_TO_SCREEN(y) - snapcursor_size, @@ -4250,8 +4278,11 @@ int rstate; /* (reduced state, without ShiftMask) */ 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){ - if(tclgetboolvar("snap_cursor") && (xctx->prev_snapx == xctx->mousex_snap && xctx->prev_snapy == xctx->mousey_snap) - && (xctx->ui_state & STARTWIRE)){ + if(tclgetboolvar("snap_cursor") + && (xctx->prev_snapx == xctx->mousex_snap + && xctx->prev_snapy == xctx->mousey_snap) + && (xctx->ui_state & STARTWIRE) + && xctx->closest_pin_found){ new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap); xctx->ui_state &= ~STARTWIRE; } diff --git a/src/findnet.c b/src/findnet.c index 852e72bb..cc9801e1 100644 --- a/src/findnet.c +++ b/src/findnet.c @@ -185,7 +185,7 @@ static void find_closest_line(double mx, double my) /* snap wire to closest pin or net endpoint (if it is inside the current screen viewport) */ /* use spatial hash table iterators to avoid O(N) */ -void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) +int find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) { double x1, y1, x2, y2; Iterator_ctx ctx; @@ -193,6 +193,7 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) Wireentry *wireptr; double curr_dist = DBL_MAX; double xx, yy, dist, min_dist_x = xctx->mousex_snap, min_dist_y = xctx->mousey_snap; + int found_net_or_pin = 0; x1 = X_TO_XSCHEM(xctx->areax1); y1 = Y_TO_XSCHEM(xctx->areay1); @@ -218,6 +219,7 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) curr_dist = dist; min_dist_x = xx; min_dist_y = yy; + found_net_or_pin = 1; } } } @@ -236,6 +238,7 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) curr_dist = dist; min_dist_x = xx; min_dist_y = yy; + found_net_or_pin = 1; } xx = wire[i].x2; yy = wire[i].y2; @@ -245,11 +248,13 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) curr_dist = dist; min_dist_x = xx; min_dist_y = yy; + found_net_or_pin = 1; } } *x = min_dist_x; *y = min_dist_y; + return found_net_or_pin; } #if 0 diff --git a/src/xinit.c b/src/xinit.c index acb456ef..2fcb25f7 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -648,6 +648,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->prev_crossx = xctx->prev_crossy = 0.0; xctx->prev_gridx = xctx->prev_gridy = 0.0; xctx->prev_snapx = xctx->prev_snapy = 0.0; + xctx->closest_pin_found = 0; xctx->mouse_inside = 0; xctx->pending_fullzoom = 0; my_strncpy(xctx->hiersep, ".", S(xctx->hiersep)); diff --git a/src/xschem.h b/src/xschem.h index 23d9d254..de5b5f2a 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1051,6 +1051,7 @@ typedef struct { double prev_crossx, prev_crossy; double prev_gridx, prev_gridy; double prev_snapx, prev_snapy; + int closest_pin_found; int mouse_inside; /* set_modify */ int prev_set_modify; @@ -1397,7 +1398,8 @@ extern int callback(const char *winpath, int event, int mx, int my, KeySym key, int button, int aux, int state); extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h); extern Selected find_closest_obj(double mx,double my, int override_lock); -extern void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y); +/*extern void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y);*/ +extern int find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y); extern void drawline(int c, int what, double x1,double y1,double x2,double y2, int dash, void *ct); extern void draw_xhair_line(GC gc, int size, double linex1, double liney1, double linex2, double liney2); From 7e9132ff3be3ce11e22026b2d5162ada4acddc6f Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Fri, 24 Jan 2025 16:48:42 +0530 Subject: [PATCH 36/46] [Manual Upstream Merge]: Manually reintroduced the changes from commit a361505 without breaking functionalities. This fork is now effectively up-to-date with upstream. --- src/actions.c | 24 ++++++++------- src/callback.c | 80 +++++++++++++++++++++++--------------------------- src/xschem.h | 1 + 3 files changed, 51 insertions(+), 54 deletions(-) diff --git a/src/actions.c b/src/actions.c index 4c07a46f..60ee1174 100644 --- a/src/actions.c +++ b/src/actions.c @@ -3019,7 +3019,7 @@ void new_wire(int what, double mx_snap, double my_snap) if( (what & PLACE) ) { if( (xctx->ui_state & STARTWIRE) && (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) ) { xctx->push_undo(); - if(xctx->manhattan_lines==1) { + if(xctx->manhattan_lines & 1) { if(xctx->nl_xx2!=xctx->nl_xx1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3038,7 +3038,7 @@ void new_wire(int what, double mx_snap, double my_snap) hash_wire(XINSERT, xctx->wires-1, 1); drawline(WIRELAYER,NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2, 0, NULL); } - } else if(xctx->manhattan_lines==2) { + } else if(xctx->manhattan_lines & 2) { if(xctx->nl_yy2!=xctx->nl_yy1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3076,6 +3076,8 @@ void new_wire(int what, double mx_snap, double my_snap) draw(); /* draw_hilight_net(1);*/ /* for updating connection bubbles on hilight nets */ } + +#if 0 if(! (what &END)) { xctx->nl_x1=mx_snap; xctx->nl_y1=my_snap; @@ -3085,7 +3087,7 @@ void new_wire(int what, double mx_snap, double my_snap) xctx->nl_yy1=xctx->nl_y1; xctx->nl_xx2=xctx->mousex_snap; xctx->nl_yy2=xctx->mousey_snap; - if(xctx->manhattan_lines==1) { + if(xctx->manhattan_lines & 1) { xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap; xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3095,7 +3097,7 @@ void new_wire(int what, double mx_snap, double my_snap) xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); - } else if(xctx->manhattan_lines==2) { + } else if(xctx->manhattan_lines & 2) { xctx->nl_x2 = mx_snap; xctx->nl_y2 = my_snap; xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3113,6 +3115,8 @@ void new_wire(int what, double mx_snap, double my_snap) drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); } } +#endif + xctx->nl_x1 = xctx->nl_x2=mx_snap; xctx->nl_y1 = xctx->nl_y2=my_snap; xctx->ui_state |= STARTWIRE; if(modified) set_modify(1); } @@ -3120,7 +3124,7 @@ void new_wire(int what, double mx_snap, double my_snap) xctx->ui_state &= ~STARTWIRE; } if( (what & RUBBER) ) { - if(xctx->manhattan_lines==1) { + if(xctx->manhattan_lines & 1) { xctx->nl_xx1=xctx->nl_x1;xctx->nl_yy1=xctx->nl_y1; xctx->nl_xx2=xctx->nl_x2;xctx->nl_yy2=xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1); @@ -3141,7 +3145,7 @@ void new_wire(int what, double mx_snap, double my_snap) ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); drawtempline(xctx->gc[WIRELAYER], NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); } - } else if(xctx->manhattan_lines==2) { + } else if(xctx->manhattan_lines & 2) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2); @@ -3311,7 +3315,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) if( (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) && (xctx->ui_state & STARTLINE) ) { xctx->push_undo(); - if(xctx->manhattan_lines==1) { + if(xctx->manhattan_lines & 1) { if(xctx->nl_xx2!=xctx->nl_xx1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3328,7 +3332,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) modified = 1; drawline(xctx->rectcolor,NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2, 0, NULL); } - } else if(xctx->manhattan_lines==2) { + } else if(xctx->manhattan_lines & 2) { if(xctx->nl_yy2!=xctx->nl_yy1) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; @@ -3365,7 +3369,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) if(what & RUBBER) { - if(xctx->manhattan_lines==1) { + if(xctx->manhattan_lines & 1) { xctx->nl_xx1 = xctx->nl_x1;xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2;xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy1); @@ -3386,7 +3390,7 @@ void new_line(int what, double mousex_snap, double mousey_snap) ORDER(xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); drawtempline(xctx->gc[xctx->rectcolor], NOW, xctx->nl_xx2,xctx->nl_yy1,xctx->nl_xx2,xctx->nl_yy2); } - } else if(xctx->manhattan_lines==2) { + } else if(xctx->manhattan_lines & 2) { xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1; xctx->nl_xx2 = xctx->nl_x2; xctx->nl_yy2 = xctx->nl_y2; ORDER(xctx->nl_xx1,xctx->nl_yy1,xctx->nl_xx1,xctx->nl_yy2); diff --git a/src/callback.c b/src/callback.c index f3a64f41..b4f4f4e1 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1641,6 +1641,26 @@ static int end_place_move_copy_zoom() return 0; } +void snapped_wire(double c_snap) +{ + double x, y; + if(!(xctx->ui_state & STARTWIRE)){ + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + xctx->mx_double_save = my_round(x / c_snap) * c_snap; + xctx->my_double_save = my_round(y / c_snap) * c_snap; + new_wire(PLACE, x, y); + new_wire(RUBBER, xctx->mousex_snap,xctx->mousey_snap); + } + else { + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + new_wire(RUBBER, x, y); + new_wire(PLACE|END, x, y); + xctx->constr_mv=0; + tcleval("set constr_mv 0" ); + if((xctx->ui_state & MENUSTART) && !tclgetboolvar("persistent_command") ) xctx->ui_state &= ~MENUSTART; + } +} + static int check_menu_start_commands(double c_snap) { dbg(1, "check_menu_start_commands(): ui_state=%x, ui_state2=%x last_command=%d\n", @@ -1648,12 +1668,10 @@ static int check_menu_start_commands(double c_snap) if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT)) { break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT2)) { break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTMOVE)) { @@ -1662,14 +1680,12 @@ static int check_menu_start_commands(double c_snap) /* stretch nets that land on selected instance pins if connect_by_kissing == 2 */ /* select_attached_nets(); */ move_objects(START,0,0,0); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTCOPY)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; copy_objects(START); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) { @@ -1680,8 +1696,6 @@ static int check_menu_start_commands(double c_snap) tcleval("set constr_mv 0" ); xctx->constr_mv=0; } - xctx->ui_state &=~MENUSTART; - xctx->ui_state2 = 0; /* * xctx->mx_double_save=xctx->mousex_snap; @@ -1692,13 +1706,7 @@ static int check_menu_start_commands(double c_snap) return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTSNAPWIRE)) { - double x, y; - - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - xctx->mx_double_save = my_round(x / c_snap) * c_snap; - xctx->my_double_save = my_round(y / c_snap) * c_snap; - new_wire(PLACE, x, y); - xctx->ui_state &=~MENUSTART; + snapped_wire(c_snap); return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTLINE)) { @@ -1709,8 +1717,6 @@ static int check_menu_start_commands(double c_snap) tcleval("set constr_mv 0" ); xctx->constr_mv=0; } - xctx->ui_state &=~MENUSTART; - xctx->ui_state2 = 0; /* * xctx->mx_double_save=xctx->mousex_snap; @@ -1724,33 +1730,28 @@ static int check_menu_start_commands(double c_snap) xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_rect(PLACE,xctx->mousex_snap, xctx->mousey_snap); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTPOLYGON)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_polygon(PLACE, xctx->mousex_snap, xctx->mousey_snap); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTARC)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_arc(PLACE, 180., xctx->mousex_snap, xctx->mousey_snap); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTCIRCLE)) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; new_arc(PLACE, 360., xctx->mousex_snap, xctx->mousey_snap); - xctx->ui_state &=~MENUSTART; return 1; } else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTZOOM)) { zoom_rectangle(START); - xctx->ui_state &=~MENUSTART; return 1; } return 0; @@ -2348,25 +2349,6 @@ static int grabscreen(const char *winpath, int event, int mx, int my, KeySym key } #endif -static void snapped_wire(double c_snap) -{ - double x, y; - if(!(xctx->ui_state & STARTWIRE)){ - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - xctx->mx_double_save = my_round(x / c_snap) * c_snap; - xctx->my_double_save = my_round(y / c_snap) * c_snap; - new_wire(PLACE, x, y); - new_wire(RUBBER, xctx->mousex_snap,xctx->mousey_snap); - } - else { - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - new_wire(RUBBER, x, y); - new_wire(PLACE|END, x, y); - xctx->constr_mv=0; - tcleval("set constr_mv 0" ); - } -} - /* main window callback */ /* mx and my are set to the mouse coord. relative to window */ /* winpath: set to .drw or sub windows .x1.drw, .x2.drw, ... */ @@ -2386,7 +2368,9 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, int draw_xhair = tclgetboolvar("draw_crosshair"); int infix_interface = tclgetboolvar("infix_interface"); int snap_cursor = tclgetboolvar("snap_cursor"); -int wire_draw_active = (xctx->ui_state & STARTWIRE) || (xctx->ui_state2 & MENUSTARTWIRE) || (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE)); +int wire_draw_active = (xctx->ui_state & STARTWIRE) || + ((xctx->ui_state2 & MENUSTARTWIRE) && (xctx->ui_state & MENUSTART)) || + (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE)); int rstate; /* (reduced state, without ShiftMask) */ /* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease @@ -2675,7 +2659,8 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* snap crosshair to closest pin or net endpoint */ if(draw_xhair) { - if( ( (xctx->ui_state & STARTWIRE) || xctx->ui_state == 0 ) && (state & ShiftMask) ) { + if( ( (xctx->ui_state & (MENUSTART | STARTWIRE)) || xctx->ui_state == 0 ) && + (state & ShiftMask) ) { double x, y, sx, sy; sx = xctx->mousex_snap; sy = xctx->mousey_snap; @@ -2703,7 +2688,7 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->manhattan_lines %=3; new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); - } else if(xctx->ui_state==STARTLINE) { + } else if(xctx->ui_state & STARTLINE) { new_line(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); xctx->manhattan_lines++; xctx->manhattan_lines %=3; @@ -4239,7 +4224,6 @@ int rstate; /* (reduced state, without ShiftMask) */ /* terminate wire placement in snap mode */ else if(button==Button1 && (state & ShiftMask) && (xctx->ui_state & STARTWIRE) ) { snapped_wire(c_snap); - here(1111); } /* Alt - Button1 click to unselect */ else if(button==Button1 && (SET_MODMASK) ) { @@ -4418,7 +4402,8 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ - /*else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) {*/ + /*else if(state == Button1Mask && xctx->intuitive_interface + * && (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) {*/ /* if(end_place_move_copy_zoom()) break;*/ /*}*/ @@ -4469,6 +4454,13 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->mousex_snap, xctx->mousey_snap, xctx->lastsel, xctx->sch_path[xctx->currsch] ); statusmsg(str,1); } + + /* clear start from menu flag or infix_interface=0 start commands */ + if(xctx->ui_state & MENUSTART) { + xctx->ui_state &= ~MENUSTART; + break; + } + if(draw_xhair) draw_crosshair(0); if(snap_cursor && wire_draw_active) draw_snap_cursor(0); break; diff --git a/src/xschem.h b/src/xschem.h index 7d79d48b..50a7ff42 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1394,6 +1394,7 @@ extern int Tcl_AppInit(Tcl_Interp *interp); extern void abort_operation(void); extern void draw_crosshair(int what); extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr); +/* extern void snapped_wire(double c_snap); */ extern int callback(const char *winpath, int event, int mx, int my, KeySym key, int button, int aux, int state); extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h); From 2137fa0aeff529ddde8128a45352d068180daa5a Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sat, 25 Jan 2025 12:26:52 +0530 Subject: [PATCH 37/46] [Graphical Bugfix]: Fixed a small graphical bug that occurred when drawing multi-segment wires in persistent_command mode and suddenly exiting using 'Esc'-key while the snap-cursor is active. --- src/callback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/callback.c b/src/callback.c index e792181d..fb605967 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2955,6 +2955,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE)) { xctx->last_command &= ~STARTWIRE; + if(snap_cursor) draw_snap_cursor(1); } break; } From 260beffe717163602fb6023399d18d8f9440eda8 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sat, 25 Jan 2025 12:47:23 +0530 Subject: [PATCH 38/46] [Selection Using Crosshair]: Added new functionality of using the crosshair to select objects in the schematic, instead of the default mouse-pointer based selection. This functionality will only take effect if the crosshair feature is enabled by the user. --- src/callback.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/callback.c b/src/callback.c index fb605967..2601ab0b 100644 --- a/src/callback.c +++ b/src/callback.c @@ -4301,7 +4301,8 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(!xctx->intuitive_interface && no_shift_no_ctrl ) unselect_all(1); - sel = find_closest_obj(xctx->mousex, xctx->mousey, 0); + if(draw_xhair) sel = find_closest_obj(xctx->mousex_snap, xctx->mousey_snap, 0); + else sel = find_closest_obj(xctx->mousex, xctx->mousey, 0); switch(sel.type) { case WIRE: if(xctx->wire[sel.n].sel) already_selected = 1; break; From 9056da92a6a49890c10871102ead91bfe939b45a Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sun, 26 Jan 2025 11:39:04 +0530 Subject: [PATCH 39/46] [After merge-changes]: Changes made to match pre-merge state of 'snap-cursor select' in this fork. --- src/callback.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/callback.c b/src/callback.c index 1f9d4d4a..6e67c7de 100644 --- a/src/callback.c +++ b/src/callback.c @@ -4333,12 +4333,10 @@ int rstate; /* (reduced state, without ShiftMask) */ * 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) { + if(draw_xhair) { sel = find_closest_obj(xctx->mousex_snap, xctx->mousey_snap, 0); } else { sel = find_closest_obj(xctx->mousex, xctx->mousey, 0); From 999503a26a6ef45dbcefc17454b7813574d9c888 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sun, 26 Jan 2025 12:17:29 +0530 Subject: [PATCH 40/46] [Fixed Typo]: Fixed a small typo that would create a bug in TCL. --- src/xschemrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xschemrc b/src/xschemrc index 3fd4bce6..bce0f8cf 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -285,8 +285,8 @@ #### set crosshair size; Default: 0 (full screen spanning crosshair) set crosshair_size 2 -#### set snap_cursor size; Default: 3 (Diamond-shaped cursor that snaps to nearest circuit endpoint) -# set snap_cursor size 3 +#### set snap_cursor_size; Default: 3 (Diamond-shaped cursor that snaps to nearest circuit endpoint) +# set snap_cursor_size 3 #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0 From 18fb977c68ec25dccaa63ced9bed5c9193f87e95 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sun, 26 Jan 2025 12:33:21 +0530 Subject: [PATCH 41/46] [Refactor + Minor Changes]: Refactored to fix a small code-readablity issue from last upstream merge. Added the snap_cursor option to be enabled from 'src/xschemrc' config file. --- src/callback.c | 2 +- src/xschemrc | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/callback.c b/src/callback.c index 6e67c7de..ad46f9b3 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2569,8 +2569,8 @@ int rstate; /* (reduced state, without ShiftMask) */ if(draw_xhair) { 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); + /* pan schematic */ if(xctx->ui_state & STARTPAN) pan(RUBBER, mx, my); if(xctx->semaphore >= 2) { diff --git a/src/xschemrc b/src/xschemrc index bce0f8cf..db52c144 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -285,6 +285,9 @@ #### set crosshair size; Default: 0 (full screen spanning crosshair) set crosshair_size 2 +#### enable drawing a diamond-shaped cursor at the closest circuit endpoint. Default: disabled (0) +# set snap_cursor 1 + #### set snap_cursor_size; Default: 3 (Diamond-shaped cursor that snaps to nearest circuit endpoint) # set snap_cursor_size 3 From 15fc4b9bb4d6d9bce199045e522f525ad9001748 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sun, 26 Jan 2025 13:31:33 +0530 Subject: [PATCH 42/46] [Refactor + Minor Changes]: Refactored to fix a small code-readablity issue. --- src/callback.c | 13 ++++++------- src/xschem.h | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/callback.c b/src/callback.c index ad46f9b3..0742d4c7 100644 --- a/src/callback.c +++ b/src/callback.c @@ -319,7 +319,7 @@ void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr) cnt = 0; } if(xx >= start && xx <= end) { - if((dataset == sweepvar_wrap)) { + if(dataset == sweepvar_wrap) { dbg(1, "xx=%g cursor2=%g first=%d last=%d start=%g end=%g p=%d wrap=%d sweepvar_wrap=%d ofs=%d\n", xx, cursor2, first, last, start, end, p, wrap, sweepvar_wrap, ofs); if(first == -1) first = p; @@ -1465,7 +1465,7 @@ void draw_crosshair(int what) xctx->draw_pixmap = sdp; } -/* what == 0 : erase and draw a new cursor +/* what == 3 : erase and draw a new cursor * what == 1 : erase the cursor * what == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */ void draw_snap_cursor(int what) @@ -1482,9 +1482,8 @@ void draw_snap_cursor(int what) xctx->draw_window = 1; double prev_x = xctx->prev_snapx; double prev_y = xctx->prev_snapy; - if(what != 2) { + if(what & 1) { if(fix_broken_tiled_fill || !_unix) { - /*MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0);*/ MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, @@ -1522,7 +1521,7 @@ void draw_snap_cursor(int what) Y_TO_SCREEN(prev_y) - snapcursor_size); } } - if(what != 1) { + if(what & 1) { double x, y; if(!pos_changed) { x = xctx->prev_snapx; @@ -2996,7 +2995,7 @@ int rstate; /* (reduced state, without ShiftMask) */ draw_snap_cursor(1); } else { tclsetvar("snap_cursor", "1"); - if(wire_draw_active) draw_snap_cursor(0); + if(wire_draw_active) draw_snap_cursor(3); } } if(key=='p' && EQUAL_MODMASK) /* add symbol pin */ @@ -4525,7 +4524,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(draw_xhair) draw_crosshair(3); /* restore crosshair when selecting / unselecting */ - if(snap_cursor && wire_draw_active) draw_snap_cursor(0); + if(snap_cursor && wire_draw_active) draw_snap_cursor(3); break; case -3: /* double click : edit prop */ if( waves_selected(event, key, state, button)) { diff --git a/src/xschem.h b/src/xschem.h index a10139bf..4bd05ae4 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1393,6 +1393,7 @@ extern void tclmainloop(void); extern int Tcl_AppInit(Tcl_Interp *interp); extern void abort_operation(void); extern void draw_crosshair(int what); +extern void draw_snap_cursor(int what); extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr); /* extern void snapped_wire(double c_snap); */ extern int callback(const char *winpath, int event, int mx, int my, KeySym key, From 4022d0ec10aaacc28b9cadc88f0d597d8b6ca773 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Sun, 26 Jan 2025 14:39:48 +0530 Subject: [PATCH 43/46] [Graphical Bugfix]: Fixed a small graphical bug that occurred when drawing a wire while simutaneously zooming in/out in the schematic editor. --- src/callback.c | 2 +- src/xschemrc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callback.c b/src/callback.c index 0742d4c7..8ce7412c 100644 --- a/src/callback.c +++ b/src/callback.c @@ -4524,7 +4524,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } if(draw_xhair) draw_crosshair(3); /* restore crosshair when selecting / unselecting */ - if(snap_cursor && wire_draw_active) draw_snap_cursor(3); + if(snap_cursor && wire_draw_active) draw_snap_cursor(2); break; case -3: /* double click : edit prop */ if( waves_selected(event, key, state, button)) { diff --git a/src/xschemrc b/src/xschemrc index db52c144..305c308b 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -288,8 +288,8 @@ set crosshair_size 2 #### enable drawing a diamond-shaped cursor at the closest circuit endpoint. Default: disabled (0) # set snap_cursor 1 -#### set snap_cursor_size; Default: 3 (Diamond-shaped cursor that snaps to nearest circuit endpoint) -# set snap_cursor_size 3 +#### set snap_cursor_size; Default: 6 (Diamond-shaped cursor that snaps to nearest circuit endpoint) +# set snap_cursor_size 6 #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0 From 6f20174c42d89db9a631f7bc059e371183553687 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Mon, 27 Jan 2025 12:52:20 +0530 Subject: [PATCH 44/46] [Compatibility + Graphical Bugfix]: Fixed compatibility issue resulting from a breaking change in the function 'redraw_w_a_l_p_z_rubber(int force)', and also fixed (partially) a graphical bug resulting from this change. The bug shouldn't affect user workflow at the current version. --- src/callback.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/callback.c b/src/callback.c index 0dd703c6..5023ac7e 100644 --- a/src/callback.c +++ b/src/callback.c @@ -230,7 +230,7 @@ static void start_wire(double mx, double my) if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){ xctx->constr_mv = xctx->manhattan_lines; new_wire(CLEAR, mx, my); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } if(xctx->constr_mv != 2) { xctx->mx_double_save = mx; @@ -1504,19 +1504,19 @@ void draw_snap_cursor(int what) if(what & 1) { if(fix_broken_tiled_fill || !_unix) { MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], - (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, - (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, - 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, - 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, - (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, - (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size); + (int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size, + 2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size, + 2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size, + (int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size); MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], - (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, - (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, - 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, - 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, - (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, - (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size); + (int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size, + 2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size, + 2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size, + (int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size); } else { draw_xhair_line(xctx->gctiled, snapcursor_size, X_TO_SCREEN(prev_x), @@ -3708,7 +3708,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } else { tclsetboolvar("orthogonal_wiring", 1); } - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); break; } if(key=='F' && rstate == 0) /* flip */ @@ -4526,7 +4526,7 @@ int rstate; /* (reduced state, without ShiftMask) */ break; } if(draw_xhair) draw_crosshair(3, state); /* restore crosshair when selecting / unselecting */ - if(snap_cursor && wire_draw_active) draw_snap_cursor(2); + if(snap_cursor && wire_draw_active) draw_snap_cursor(3); break; case -3: /* double click : edit prop */ if( waves_selected(event, key, state, button)) { @@ -4550,7 +4550,7 @@ int rstate; /* (reduced state, without ShiftMask) */ edit_property(0); } else { if(xctx->ui_state & STARTWIRE) { - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); start_wire(mx, my); xctx->ui_state &= ~STARTWIRE; } From 753f5d24bca8cc08ace1b5ba6571f8dab31b8186 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 29 Jan 2025 11:54:25 +0530 Subject: [PATCH 45/46] Changes made to reduce git diff with upstream repo --- src/xschem.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xschem.tcl b/src/xschem.tcl index b02051d4..fa294625 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7664,7 +7664,7 @@ set tctx::global_list { autotrim_wires orthogonal_wiring snap_cursor bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv copy_cell crosshair_layer crosshair_size cursor_2_hook snap_cursor_size custom_label_prefix custom_token - dark_colors dark_colorscheme dark_gui_colorscheme delay_flag + dark_colors dark_colorscheme dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names do_all_inst draw_crosshair draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size edit_symbol_prop_new_sel editprop_sympath en_hilight_conn_inst enable_dim_bg enable_stretch From 808f89c4c60fb2908ef5c41e3389e94b3bfd53df Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Wed, 29 Jan 2025 13:44:24 +0530 Subject: [PATCH 46/46] Fix typo --- src/xschemrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xschemrc b/src/xschemrc index 305c308b..007933c8 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -234,7 +234,7 @@ #### wires are drawn in free-form mode with this mode enabled (default). #### if set to 0, wires drawn on the schematic will no longer strictly -#### follow orthogonal routes to connect two distinct points toegther. +#### follow orthogonal routes to connect two distinct points together. #### default: 1 # set orthogonal_wiring 0