Schematic: new feature, force 45 degree lines

* New modes to force 45 deg angle at beginning or end of line

* Backspace will undo most recent segment added

* / will toggle posture of 90 and 45 degree lines

* Added alg::signbit for convenience

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/10869
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/9175
This commit is contained in:
Mike Williams 2022-03-22 12:49:38 -04:00
parent e51ab86225
commit 2a726a882f
19 changed files with 578 additions and 93 deletions

View File

@ -271,6 +271,7 @@ set( EESCHEMA_SRCS
tools/sch_drawing_tools.cpp
tools/sch_edit_tool.cpp
tools/sch_editor_control.cpp
tools/sch_editor_conditions.cpp
tools/sch_line_wire_bus_tool.cpp
tools/sch_move_tool.cpp
tools/sch_navigate_tool.cpp

View File

@ -63,7 +63,7 @@ void PANEL_EESCHEMA_EDITING_OPTIONS::loadEEschemaSettings( EESCHEMA_SETTINGS* aC
m_backgroundColorSwatch->SetSwatchBackground( schematicBackground );
m_backgroundColorSwatch->SetSwatchColor( aCfg->m_Drawing.default_sheet_background_color, false );
m_checkHVOrientation->SetValue( aCfg->m_Drawing.hv_lines_only );
m_choiceLineMode->SetSelection( aCfg->m_Drawing.line_mode );
m_footprintPreview->SetValue( aCfg->m_Appearance.footprint_preview );
m_navigatorStaysOpen->SetValue( aCfg->m_Appearance.navigator_stays_open );
@ -101,7 +101,7 @@ bool PANEL_EESCHEMA_EDITING_OPTIONS::TransferDataFromWindow()
cfg->m_Drawing.default_repeat_offset_y = Iu2Mils( (int) m_vPitch.GetValue() );
cfg->m_Drawing.repeat_label_increment = m_spinLabelRepeatStep->GetValue();
cfg->m_Drawing.hv_lines_only = m_checkHVOrientation->GetValue();
cfg->m_Drawing.line_mode = m_choiceLineMode->GetSelection();
cfg->m_Appearance.footprint_preview = m_footprintPreview->GetValue();
cfg->m_Appearance.navigator_stays_open = m_navigatorStaysOpen->GetValue();

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -20,9 +20,15 @@ PANEL_EESCHEMA_EDITING_OPTIONS_BASE::PANEL_EESCHEMA_EDITING_OPTIONS_BASE( wxWind
wxStaticBoxSizer* sbSizerEditOpt;
sbSizerEditOpt = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Editing") ), wxVERTICAL );
m_checkHVOrientation = new wxCheckBox( sbSizerEditOpt->GetStaticBox(), wxID_ANY, _("Constrain buses and wires to H or V"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkHVOrientation->SetValue(true);
sbSizerEditOpt->Add( m_checkHVOrientation, 0, wxRIGHT|wxLEFT, 5 );
m_staticText24 = new wxStaticText( sbSizerEditOpt->GetStaticBox(), wxID_ANY, _("Line Drawing Mode:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText24->Wrap( -1 );
sbSizerEditOpt->Add( m_staticText24, 0, wxALL, 5 );
wxString m_choiceLineModeChoices[] = { _("Free Angle"), _("90 deg Angle"), _("45 deg Angle"), _("135 deg Angle") };
int m_choiceLineModeNChoices = sizeof( m_choiceLineModeChoices ) / sizeof( wxString );
m_choiceLineMode = new wxChoice( sbSizerEditOpt->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceLineModeNChoices, m_choiceLineModeChoices, 0 );
m_choiceLineMode->SetSelection( 1 );
sbSizerEditOpt->Add( m_choiceLineMode, 0, wxALL, 5 );
m_mouseDragIsDrag = new wxCheckBox( sbSizerEditOpt->GetStaticBox(), wxID_ANY, _("Mouse drag performs Drag (G) operation"), wxDefaultPosition, wxDefaultSize, 0 );
m_mouseDragIsDrag->SetToolTip( _("If unchecked, mouse drag will perform move (M) operation") );

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<FileVersion major="1" minor="16" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@ -14,6 +14,7 @@
<property name="file">panel_eeschema_editing_options_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">PanelEeschemaEditingOptionsBase</property>
@ -25,6 +26,7 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="1">
@ -33,6 +35,7 @@
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="fg"></property>
@ -46,6 +49,7 @@
<property name="size">-1,-1</property>
<property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; Not forward_declare</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
@ -75,11 +79,11 @@
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxRIGHT|wxLEFT</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -93,7 +97,6 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@ -101,6 +104,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -108,7 +112,8 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Constrain buses and wires to H or V</property>
<property name="label">Line Drawing Mode:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -116,7 +121,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkHVOrientation</property>
<property name="name">m_staticText24</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -127,7 +132,69 @@
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxChoice" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;Free Angle&quot; &quot;90 deg Angle&quot; &quot;45 deg Angle&quot; &quot;135 deg Angle&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_choiceLineMode</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
@ -165,6 +232,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -229,6 +297,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -315,6 +384,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -379,6 +449,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg">wxSYS_COLOUR_WINDOW</property>
<property name="floatable">1</property>
@ -438,6 +509,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -502,6 +574,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg">wxSYS_COLOUR_WINDOW</property>
<property name="floatable">1</property>
@ -578,6 +651,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -643,6 +717,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -697,6 +772,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -760,6 +836,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -821,6 +898,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -895,6 +973,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -956,6 +1035,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1017,6 +1097,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1078,6 +1159,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1139,6 +1221,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1200,6 +1283,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1265,6 +1349,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1328,6 +1413,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1389,6 +1475,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1463,6 +1550,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1524,6 +1612,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1585,6 +1674,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1646,6 +1736,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1707,6 +1798,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1768,6 +1860,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1829,6 +1922,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1890,6 +1984,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -1982,6 +2077,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2046,6 +2142,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2110,6 +2207,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2203,6 +2301,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2264,6 +2363,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2328,6 +2428,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2389,6 +2490,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2450,6 +2552,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2514,6 +2617,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2575,6 +2679,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2636,6 +2741,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2725,6 +2831,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@ -2789,6 +2896,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -13,14 +13,15 @@
#include "widgets/color_swatch.h"
#include "widgets/resettable_panel.h"
#include <wx/string.h>
#include <wx/checkbox.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/choice.h>
#include <wx/checkbox.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/statline.h>
#include <wx/panel.h>
#include <wx/simplebook.h>
@ -37,7 +38,8 @@ class PANEL_EESCHEMA_EDITING_OPTIONS_BASE : public RESETTABLE_PANEL
private:
protected:
wxCheckBox* m_checkHVOrientation;
wxStaticText* m_staticText24;
wxChoice* m_choiceLineMode;
wxCheckBox* m_mouseDragIsDrag;
wxCheckBox* m_cbAutoStartWires;
wxStaticText* m_borderColorLabel;
@ -83,6 +85,7 @@ class PANEL_EESCHEMA_EDITING_OPTIONS_BASE : public RESETTABLE_PANEL
public:
PANEL_EESCHEMA_EDITING_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_EESCHEMA_EDITING_OPTIONS_BASE();
};

View File

@ -164,8 +164,8 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
m_params.emplace_back( new PARAM<wxString>( "drawing.field_names",
&m_Drawing.field_names, "" ) );
m_params.emplace_back( new PARAM<bool>( "drawing.hv_lines_only",
&m_Drawing.hv_lines_only, true ) );
m_params.emplace_back( new PARAM<int>( "drawing.line_mode", &m_Drawing.line_mode,
LINE_MODE::LINE_MODE_90 ) );
m_params.emplace_back( new PARAM<bool>( "drawing.auto_start_wires",
&m_Drawing.auto_start_wires, true ) );
@ -471,7 +471,7 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
ret &= fromLegacy<int>( aCfg, "RepeatStepY", "drawing.default_repeat_offset_y" );
ret &= fromLegacy<int>( aCfg, "DefaultWireWidth", "drawing.default_wire_thickness" );
ret &= fromLegacyString( aCfg, "FieldNames", "drawing.field_names" );
ret &= fromLegacy<bool>( aCfg, "HorizVertLinesOnly", "drawing.hv_lines_only" );
ret &= fromLegacy<bool>( aCfg, "HorizVertLinesOnly", "drawing.line_mode" );
ret &= fromLegacy<int>( aCfg, "RepeatLabelIncrement", "drawing.repeat_label_increment" );
ret &= fromLegacy<bool>( aCfg, "DragActionIsMove", "input.drag_is_move" );

View File

@ -30,6 +30,17 @@
using KIGFX::COLOR4D;
enum LINE_MODE
{
LINE_MODE_FREE = 0,
LINE_MODE_90 = 1,
LINE_MODE_45 = 2,
LINE_MODE_135 = 3,
LINE_MODE_COUNT,
};
class EESCHEMA_SETTINGS : public APP_SETTINGS_BASE
{
public:
@ -103,7 +114,7 @@ public:
COLOR4D default_sheet_border_color;
COLOR4D default_sheet_background_color;
wxString field_names;
bool hv_lines_only;
int line_mode;
int repeat_label_increment;
bool intersheets_ref_show;
bool intersheets_ref_own_page;

View File

@ -61,7 +61,6 @@
#include <tool/action_toolbar.h>
#include <tool/common_control.h>
#include <tool/common_tools.h>
#include <tool/editor_conditions.h>
#include <tool/picker_tool.h>
#include <tool/selection.h>
#include <tool/tool_dispatcher.h>
@ -73,6 +72,7 @@
#include <tools/ee_selection_tool.h>
#include <tools/sch_drawing_tools.h>
#include <tools/sch_edit_tool.h>
#include <tools/sch_editor_conditions.h>
#include <tools/sch_editor_control.h>
#include <tools/sch_line_wire_bus_tool.h>
#include <tools/sch_move_tool.h>
@ -386,7 +386,7 @@ void SCH_EDIT_FRAME::setupUIConditions()
SCH_BASE_FRAME::setupUIConditions();
ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
EDITOR_CONDITIONS cond( this );
SCH_EDITOR_CONDITIONS cond( this );
wxASSERT( mgr );
@ -411,6 +411,11 @@ void SCH_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( ACTIONS::inchesUnits, CHECK( cond.Units( EDA_UNITS::INCHES ) ) );
mgr->SetConditions( ACTIONS::milsUnits, CHECK( cond.Units( EDA_UNITS::MILS ) ) );
mgr->SetConditions( EE_ACTIONS::lineModeFree, CHECK( cond.LineMode( LINE_MODE::LINE_MODE_FREE ) ) );
mgr->SetConditions( EE_ACTIONS::lineMode90, CHECK( cond.LineMode( LINE_MODE::LINE_MODE_90 ) ) );
mgr->SetConditions( EE_ACTIONS::lineMode45, CHECK( cond.LineMode( LINE_MODE::LINE_MODE_45 ) ) );
mgr->SetConditions( EE_ACTIONS::lineMode135, CHECK( cond.LineMode( LINE_MODE::LINE_MODE_135 ) ) );
mgr->SetConditions( ACTIONS::cut, ENABLE( hasElements ) );
mgr->SetConditions( ACTIONS::copy, ENABLE( hasElements ) );
mgr->SetConditions( ACTIONS::paste, ENABLE( SELECTION_CONDITIONS::Idle ) );
@ -469,13 +474,6 @@ void SCH_EDIT_FRAME::setupUIConditions()
return cfg && cfg->m_Appearance.show_erc_exclusions;
};
auto forceHVCond =
[this]( const SELECTION& )
{
EESCHEMA_SETTINGS* cfg = eeconfig();
return cfg && cfg->m_Drawing.hv_lines_only;
};
auto remapSymbolsCondition =
[&]( const SELECTION& aSel )
{
@ -498,7 +496,6 @@ void SCH_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( EE_ACTIONS::toggleERCErrors, CHECK( showERCErrorsCond ) );
mgr->SetConditions( EE_ACTIONS::toggleERCWarnings, CHECK( showERCWarningsCond ) );
mgr->SetConditions( EE_ACTIONS::toggleERCExclusions, CHECK( showERCExclusionsCond ) );
mgr->SetConditions( EE_ACTIONS::toggleForceHV, CHECK( forceHVCond ) );
mgr->SetConditions( ACTIONS::toggleBoundingBoxes, CHECK( cond.BoundingBoxes() ) );

View File

@ -194,8 +194,15 @@ void SCH_EDIT_FRAME::ReCreateOptToolbar()
m_optionsToolBar->Add( ACTIONS::milsUnits, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->Add( ACTIONS::millimetersUnits, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->Add( ACTIONS::toggleCursorStyle, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->AddScaledSeparator( this );
m_optionsToolBar->Add( EE_ACTIONS::toggleHiddenPins, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->Add( EE_ACTIONS::toggleForceHV, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->AddScaledSeparator( this );
m_optionsToolBar->Add( EE_ACTIONS::lineModeFree, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->Add( EE_ACTIONS::lineMode90, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->Add( EE_ACTIONS::lineMode45, ACTION_TOOLBAR::TOGGLE );
m_optionsToolBar->Add( EE_ACTIONS::lineMode135, ACTION_TOOLBAR::TOGGLE );
if( ADVANCED_CFG::GetCfg().m_DrawBoundingBoxes )
m_optionsToolBar->Add( ACTIONS::toggleBoundingBoxes, ACTION_TOOLBAR::TOGGLE );

View File

@ -679,10 +679,30 @@ TOOL_ACTION EE_ACTIONS::toggleERCExclusions( "eeschema.EditorControl.showERCExcl
_( "Show ERC Exclusions" ),
_( "Show markers for excluded electrical rules checker violations" ) );
TOOL_ACTION EE_ACTIONS::toggleForceHV( "eeschema.EditorControl.forceHVLines",
TOOL_ACTION EE_ACTIONS::lineModeFree( "eeschema.EditorControl.lineModeFree",
AS_GLOBAL, 0, "",
_( "Force H/V Wires and Buses" ), _( "Switch H & V only mode for new wires and buses" ),
BITMAPS::lines90 );
_( "Line Mode for Wires and Buses" ), _( "Lines drawn at any angle" ),
BITMAPS::unknown, AF_NONE, (void*) LINE_MODE::LINE_MODE_FREE );
TOOL_ACTION EE_ACTIONS::lineMode90( "eeschema.EditorControl.lineModeOrthonal",
AS_GLOBAL, 0, "",
_( "Line Mode for Wires and Buses" ), _( "Lines drawn horizontally and vertically" ),
BITMAPS::lines90, AF_NONE, (void*) LINE_MODE::LINE_MODE_90);
TOOL_ACTION EE_ACTIONS::lineMode45( "eeschema.EditorControl.lineMode45",
AS_GLOBAL, 0, "",
_( "Line Mode for Wires and Buses" ), _( "Lines drawn horizontally and vertically, with a 45 degree angle end" ),
BITMAPS::unknown, AF_NONE, (void*) LINE_MODE::LINE_MODE_45);
TOOL_ACTION EE_ACTIONS::lineMode135( "eeschema.EditorControl.lineMode135",
AS_GLOBAL, 0, "",
_( "Line Mode for Wires and Buses" ), _( "Lines drawn horizontally and vertically, with a 45 degree angle start" ),
BITMAPS::unknown, AF_NONE, (void*) LINE_MODE::LINE_MODE_135);
TOOL_ACTION EE_ACTIONS::lineModeNext( "eeschema.EditorControl.lineModeNext",
AS_GLOBAL, MD_SHIFT + WXK_SPACE, "",
_( "Line Mode for Wires and Buses" ), _( "Switch to next line mode" ),
BITMAPS::unknown );
TOOL_ACTION EE_ACTIONS::repairSchematic( "eeschema.EditorControl.repairSchematic",
AS_GLOBAL, 0, "",
@ -759,6 +779,18 @@ TOOL_ACTION EE_ACTIONS::drawLines( "eeschema.InteractiveDrawingLineWireBus.drawL
_( "Add Lines" ), _( "Add connected graphic lines" ),
BITMAPS::add_dashed_line, AF_ACTIVATE, (void*) &drawLinesActionParam );
TOOL_ACTION EE_ACTIONS::undoLastSegment( "eeschema.InteractiveDrawingLineWireBus.undoLastSegment",
AS_GLOBAL,
WXK_BACK, "",
_( "Undo Last Segment" ), _( "Walks the current line back one segment." ),
BITMAPS::undo );
TOOL_ACTION EE_ACTIONS::switchSegmentPosture( "eeschema.InteractiveDrawingLineWireBus.switchPosture",
AS_GLOBAL,
'/', "",
_( "Switch Segment Posture" ), _( "Switches posture of the current segment." ),
BITMAPS::change_entry_orient, AF_NONE );
TOOL_ACTION EE_ACTIONS::finishLineWireOrBus( "eeschema.InteractiveDrawingLineWireBus.finish",
AS_GLOBAL,
'K', LEGACY_HK_NAME( "End Line Wire Bus" ),

View File

@ -96,6 +96,8 @@ public:
static TOOL_ACTION drawArc;
static TOOL_ACTION drawLines;
static TOOL_ACTION placeImage;
static TOOL_ACTION undoLastSegment;
static TOOL_ACTION switchSegmentPosture;
static TOOL_ACTION finishLineWireOrBus;
static TOOL_ACTION finishWire;
static TOOL_ACTION finishBus;
@ -211,13 +213,19 @@ public:
static TOOL_ACTION showElectricalTypes;
static TOOL_ACTION showSymbolTree;
static TOOL_ACTION hideSymbolTree;
static TOOL_ACTION toggleForceHV;
static TOOL_ACTION drawSheetOnClipboard;
static TOOL_ACTION exportSymbolView;
static TOOL_ACTION exportSymbolAsSVG;
static TOOL_ACTION showPythonConsole;
static TOOL_ACTION repairSchematic;
// Line modes
static TOOL_ACTION lineModeFree;
static TOOL_ACTION lineMode90;
static TOOL_ACTION lineMode45;
static TOOL_ACTION lineMode135;
static TOOL_ACTION lineModeNext;
// SPICE
static TOOL_ACTION runSimulation;
static TOOL_ACTION simProbe;

View File

@ -0,0 +1,52 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mike Williams <mike at mikebwilliams.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <eeschema_settings.h>
#include <tool/selection.h>
#include <tools/sch_editor_conditions.h>
#include <functional>
#include <wx/debug.h>
using namespace std::placeholders;
SELECTION_CONDITION SCH_EDITOR_CONDITIONS::LineMode( LINE_MODE aMode )
{
SCH_BASE_FRAME* schFrame = dynamic_cast<SCH_BASE_FRAME*>( m_frame );
wxASSERT( schFrame );
return std::bind( &SCH_EDITOR_CONDITIONS::lineModeFunc, _1, schFrame, aMode );
}
bool SCH_EDITOR_CONDITIONS::lineModeFunc( const SELECTION& aSelection, SCH_BASE_FRAME* aFrame,
LINE_MODE aMode )
{
return aFrame->eeconfig()->m_Drawing.line_mode == aMode;
}

View File

@ -0,0 +1,57 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mike Williams <mike at mikebwilliams.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef SCH_EDITOR_CONDITIONS_H_
#define SCH_EDITOR_CONDITIONS_H_
#include <eeschema_settings.h>
#include <tool/editor_conditions.h>
#include <sch_base_frame.h>
class EDA_BASE_FRAME;
class EDA_DRAW_FRAME;
/**
* Group generic conditions for PCB editor states.
*/
class SCH_EDITOR_CONDITIONS : public EDITOR_CONDITIONS
{
public:
SCH_EDITOR_CONDITIONS( SCH_BASE_FRAME* aFrame ) : EDITOR_CONDITIONS( aFrame ) {}
/**
* Create a functor that tests if the frame is in the specified line drawing mode.
*
* @return Functor testing the line drawing mode of a frame.
*/
SELECTION_CONDITION LineMode( LINE_MODE aMode );
protected:
///< Helper function used by LineMode().
static bool lineModeFunc( const SELECTION& aSelection, SCH_BASE_FRAME* aFrame,
LINE_MODE aMode );
};
#endif /* SCH_EDITOR_CONDITIONS_H_ */

View File

@ -2160,9 +2160,33 @@ int SCH_EDITOR_CONTROL::ToggleERCExclusions( const TOOL_EVENT& aEvent )
}
int SCH_EDITOR_CONTROL::ToggleForceHV( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::ChangeLineMode( const TOOL_EVENT& aEvent )
{
m_frame->eeconfig()->m_Drawing.hv_lines_only = !m_frame->eeconfig()->m_Drawing.hv_lines_only;
m_frame->eeconfig()->m_Drawing.line_mode = aEvent.Parameter<int>();
m_toolMgr->RunAction( ACTIONS::refreshPreview );
return 0;
}
int SCH_EDITOR_CONTROL::NextLineMode( const TOOL_EVENT& aEvent )
{
m_frame->eeconfig()->m_Drawing.line_mode++;
m_frame->eeconfig()->m_Drawing.line_mode %= LINE_MODE::LINE_MODE_COUNT;
m_toolMgr->RunAction( ACTIONS::refreshPreview );
return 0;
}
int SCH_EDITOR_CONTROL::SwitchSegmentPosture( const TOOL_EVENT& aEvent )
{
// The 45/135 angle modes are the only ones with fixed postures, so
// only toggle them if we're already in one of these modes
if (m_frame->eeconfig()->m_Drawing.line_mode == LINE_MODE::LINE_MODE_45)
m_frame->eeconfig()->m_Drawing.line_mode = LINE_MODE::LINE_MODE_135;
else if (m_frame->eeconfig()->m_Drawing.line_mode == LINE_MODE::LINE_MODE_135)
m_frame->eeconfig()->m_Drawing.line_mode = LINE_MODE::LINE_MODE_45;
m_toolMgr->RunAction( ACTIONS::refreshPreview );
return 0;
}
@ -2341,7 +2365,12 @@ void SCH_EDITOR_CONTROL::setTransitions()
Go( &SCH_EDITOR_CONTROL::ToggleERCWarnings, EE_ACTIONS::toggleERCWarnings.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ToggleERCErrors, EE_ACTIONS::toggleERCErrors.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ToggleERCExclusions, EE_ACTIONS::toggleERCExclusions.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ToggleForceHV, EE_ACTIONS::toggleForceHV.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ChangeLineMode, EE_ACTIONS::lineModeFree.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ChangeLineMode, EE_ACTIONS::lineMode90.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ChangeLineMode, EE_ACTIONS::lineMode45.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ChangeLineMode, EE_ACTIONS::lineMode135.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::NextLineMode, EE_ACTIONS::lineModeNext.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::SwitchSegmentPosture, EE_ACTIONS::switchSegmentPosture.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::TogglePythonConsole, EE_ACTIONS::showPythonConsole.MakeEvent() );

View File

@ -139,7 +139,9 @@ public:
int ToggleERCWarnings( const TOOL_EVENT& aEvent );
int ToggleERCErrors( const TOOL_EVENT& aEvent );
int ToggleERCExclusions( const TOOL_EVENT& aEvent );
int ToggleForceHV( const TOOL_EVENT& aEvent );
int ChangeLineMode( const TOOL_EVENT& aEvent );
int NextLineMode( const TOOL_EVENT& aEvent );
int SwitchSegmentPosture( const TOOL_EVENT& aEvent );
int TogglePythonConsole( const TOOL_EVENT& aEvent );
int RepairSchematic( const TOOL_EVENT& aEvent );

View File

@ -212,6 +212,10 @@ bool SCH_LINE_WIRE_BUS_TOOL::Init()
ctxMenu.AddItem( EE_ACTIONS::drawWire, wireOrBusTool && EE_CONDITIONS::Idle, 10 );
ctxMenu.AddItem( EE_ACTIONS::drawBus, wireOrBusTool && EE_CONDITIONS::Idle, 10 );
ctxMenu.AddItem( EE_ACTIONS::drawLines, lineTool && EE_CONDITIONS::Idle, 10 );
ctxMenu.AddItem( EE_ACTIONS::undoLastSegment, EE_CONDITIONS::ShowAlways, 10 );
ctxMenu.AddItem( EE_ACTIONS::switchSegmentPosture, EE_CONDITIONS::ShowAlways, 10 );
ctxMenu.AddItem( EE_ACTIONS::finishWire, IsDrawingWire, 10 );
ctxMenu.AddItem( EE_ACTIONS::finishBus, IsDrawingBus, 10 );
ctxMenu.AddItem( EE_ACTIONS::finishLine, IsDrawingLine, 10 );
@ -420,18 +424,36 @@ const SCH_SHEET_PIN* SCH_LINE_WIRE_BUS_TOOL::getSheetPin( const VECTOR2I& aPosit
void SCH_LINE_WIRE_BUS_TOOL::computeBreakPoint( const std::pair<SCH_LINE*, SCH_LINE*>& aSegments,
VECTOR2I& aPosition )
VECTOR2I& aPosition,
LINE_MODE mode )
{
wxCHECK_RET( aSegments.first && aSegments.second,
wxT( "Cannot compute break point of NULL line segment." ) );
SCH_LINE* segment = aSegments.first;
SCH_LINE* next_segment = aSegments.second;
VECTOR2I midPoint;
int iDx = segment->GetEndPoint().x - segment->GetStartPoint().x;
int iDy = segment->GetEndPoint().y - segment->GetStartPoint().y;
SCH_LINE* segment = aSegments.first;
SCH_LINE* nextSegment = aSegments.second;
VECTOR2I delta = aPosition - segment->GetStartPoint();
int xDir = delta.x > 0 ? 1 : -1;
int yDir = delta.y > 0 ? 1 : -1;
bool preferHorizontal;
bool preferVertical;
if( mode == LINE_MODE_135 )
{
preferHorizontal = ( nextSegment->GetEndPoint().x - nextSegment->GetStartPoint().x ) != 0;
preferVertical = ( nextSegment->GetEndPoint().y - nextSegment->GetStartPoint().y ) != 0;
}
else
{
preferHorizontal = ( segment->GetEndPoint().x - segment->GetStartPoint().x ) != 0;
preferVertical = ( segment->GetEndPoint().y - segment->GetStartPoint().y ) != 0;
}
// Check for times we need to force horizontal sheet pin connections
const SCH_SHEET_PIN* connectedPin = getSheetPin( segment->GetStartPoint() );
SHEET_SIDE force = connectedPin ? connectedPin->GetSide() : SHEET_SIDE::UNDEFINED;
@ -443,37 +465,89 @@ void SCH_LINE_WIRE_BUS_TOOL::computeBreakPoint( const std::pair<SCH_LINE*, SCH_L
aPosition.x += KiROUND( getView()->GetGAL()->GetGridSize().x * direction );
}
midPoint.x = aPosition.x;
midPoint.y = segment->GetStartPoint().y; // force horizontal
preferHorizontal = true;
preferVertical = false;
}
else if( iDy != 0 ) // keep the first segment orientation (vertical)
auto breakVertical = [&]() mutable
{
switch( mode )
{
case LINE_MODE_45:
midPoint.x = segment->GetStartPoint().x;
midPoint.y = aPosition.y - yDir * abs( delta.x );
break;
case LINE_MODE_135:
midPoint.x = aPosition.x;
midPoint.y = segment->GetStartPoint().y + yDir * abs( delta.x );
break;
default:
midPoint.x = segment->GetStartPoint().x;
midPoint.y = aPosition.y;
}
else if( iDx != 0 ) // keep the first segment orientation (horizontal)
};
auto breakHorizontal = [&]() mutable
{
midPoint.x = aPosition.x;
switch( mode )
{
case LINE_MODE_45:
midPoint.x = aPosition.x - xDir * abs( delta.y );
midPoint.y = segment->GetStartPoint().y;
}
else
{
if( std::abs( aPosition.x - segment->GetStartPoint().x ) <
std::abs( aPosition.y - segment->GetStartPoint().y ) )
{
midPoint.x = segment->GetStartPoint().x;
break;
case LINE_MODE_135:
midPoint.x = segment->GetStartPoint().x + xDir * abs( delta.y );
midPoint.y = aPosition.y;
}
else
{
break;
default:
midPoint.x = aPosition.x;
midPoint.y = segment->GetStartPoint().y;
}
};
// Maintain current line shape if we can, e.g. if we were originally moving
// vertically keep the first segment vertical
if( preferVertical )
breakVertical();
else if( preferHorizontal )
breakHorizontal();
// Check if our 45 degree angle is one of these shapes
// /
// /
// /
// /__________
VECTOR2I deltaMidpoint = midPoint - segment->GetStartPoint();
if( mode == LINE_MODE::LINE_MODE_45
&& ( ( alg::signbit( deltaMidpoint.x ) != alg::signbit( delta.x ) )
|| ( alg::signbit( deltaMidpoint.y ) != alg::signbit( delta.y ) ) ) )
{
preferVertical = false;
preferHorizontal = false;
}
else if( mode == LINE_MODE::LINE_MODE_135
&& ( ( abs( deltaMidpoint.x ) > abs( delta.x ) )
|| ( abs( deltaMidpoint.y ) > abs( delta.y ) ) ) )
{
preferVertical = false;
preferHorizontal = false;
}
if( !preferHorizontal && !preferVertical )
{
if( std::abs( delta.x ) < std::abs( delta.y ) )
breakVertical();
else
breakHorizontal();
}
segment->SetEndPoint( midPoint );
next_segment->SetStartPoint( midPoint );
next_segment->SetEndPoint( aPosition );
nextSegment->SetStartPoint( midPoint );
nextSegment->SetEndPoint( aPosition );
}
@ -483,7 +557,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
SCH_LINE* segment = nullptr;
EE_GRID_HELPER grid( m_toolMgr );
KIGFX::VIEW_CONTROLS* controls = getViewControls();
bool forceHV = m_frame->eeconfig()->m_Drawing.hv_lines_only;
int lastMode = m_frame->eeconfig()->m_Drawing.line_mode;
auto setCursor =
[&]()
@ -545,6 +619,9 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
LINE_MODE currentMode = (LINE_MODE) m_frame->eeconfig()->m_Drawing.line_mode;
bool twoSegments = currentMode != LINE_MODE::LINE_MODE_FREE;
setCursor();
grid.SetMask( GRID_HELPER::ALL );
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
@ -559,20 +636,18 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
grid.ClearMaskFlag( GRID_HELPER::HORIZONTAL );
}
wxPoint eventPosition = static_cast<wxPoint>( evt->HasPosition() ?
evt->Position() :
controls->GetMousePosition() );
VECTOR2I eventPosition = static_cast<VECTOR2I>(
evt->HasPosition() ? evt->Position() : controls->GetMousePosition() );
VECTOR2I cursorPos = grid.BestSnapAnchor( eventPosition, LAYER_CONNECTABLE, segment );
controls->ForceCursorPosition( true, cursorPos );
// Need to handle change in H/V mode while drawing
if( forceHV != m_frame->eeconfig()->m_Drawing.hv_lines_only )
if( currentMode != lastMode )
{
forceHV = m_frame->eeconfig()->m_Drawing.hv_lines_only;
// Need to delete extra segment if we have one
if( !forceHV && m_wires.size() >= 2 && segment != nullptr )
if( currentMode == LINE_MODE::LINE_MODE_FREE && m_wires.size() >= 2
&& segment != nullptr )
{
m_wires.pop_back();
m_selectionTool->RemoveItemFromSel( segment );
@ -581,8 +656,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
segment = m_wires.back();
segment->SetEndPoint( cursorPos );
}
// Add a segment so we can move orthogonally
else if( forceHV && segment )
// Add a segment so we can move orthogonally/45
else if( lastMode == LINE_MODE::LINE_MODE_FREE && segment )
{
segment->SetEndPoint( cursorPos );
@ -594,6 +669,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
m_selectionTool->AddItemToSel( segment, true /*quiet mode*/ );
}
lastMode = currentMode;
}
@ -674,7 +751,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
segment = startSegments( aType, VECTOR2D( cursorPos ) );
}
// Create a new segment if we're out of previously-created ones
else if( !segment->IsNull() || ( forceHV && !m_wires[ m_wires.size() - 2 ]->IsNull() ) )
else if( !segment->IsNull()
|| ( twoSegments && !m_wires[m_wires.size() - 2]->IsNull() ) )
{
// Terminate the command if the end point is on a pin, junction, label, or another
// wire or bus.
@ -691,8 +769,21 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
}
else
{
int placedSegments = 1;
// When placing lines with the forty-five degree end, the user is
// targetting the endpoint with the angled portion, so it's more
// intuitive to place both segments at the same time.
if( currentMode == LINE_MODE::LINE_MODE_45
|| currentMode == LINE_MODE::LINE_MODE_135 )
{
placedSegments++;
}
segment->SetEndPoint( cursorPos );
for( int i = 0; i < placedSegments; i++ )
{
// Create a new segment, and chain it after the current segment.
segment = static_cast<SCH_LINE*>( segment->Duplicate() );
segment->SetFlags( IS_NEW | IS_MOVING );
@ -702,11 +793,13 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
m_selectionTool->AddItemToSel( segment, true /*quiet mode*/ );
}
}
}
if( evt->IsDblClick( BUT_LEFT ) && segment )
{
if( forceHV && m_wires.size() >= 2 )
computeBreakPoint( { m_wires[ m_wires.size() - 2 ], segment }, cursorPos );
if( twoSegments && m_wires.size() >= 2 )
computeBreakPoint( { m_wires[m_wires.size() - 2], segment }, cursorPos,
currentMode );
finishSegments();
segment = nullptr;
@ -763,9 +856,10 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
if( segment )
{
// Coerce the line to vertical or horizontal if necessary
if( forceHV && m_wires.size() >= 2 )
computeBreakPoint( { m_wires[ m_wires.size() - 2 ], segment }, cursorPos );
// Coerce the line to vertical/horizontal/45 as necessary
if( twoSegments && m_wires.size() >= 2 )
computeBreakPoint( { m_wires[m_wires.size() - 2], segment }, cursorPos,
currentMode );
else
segment->SetEndPoint( cursorPos );
}
@ -776,6 +870,72 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
m_view->AddToPreview( wire->Clone() );
}
}
else if( evt->IsAction( &EE_ACTIONS::undoLastSegment ) )
{
if( ( currentMode == LINE_MODE::LINE_MODE_FREE && m_wires.size() > 1 )
|| ( LINE_MODE::LINE_MODE_90 && m_wires.size() > 2 ) )
{
m_view->ClearPreview();
m_wires.pop_back();
m_selectionTool->RemoveItemFromSel( segment );
delete segment;
segment = m_wires.back();
segment->SetEndPoint( cursorPos );
// Find new bend point for current mode
if( segment )
{
if( twoSegments && m_wires.size() >= 2 )
computeBreakPoint( { m_wires[m_wires.size() - 2], segment }, cursorPos,
currentMode );
else
segment->SetEndPoint( cursorPos );
}
for( SCH_LINE* wire : m_wires )
{
if( !wire->IsNull() )
m_view->AddToPreview( wire->Clone() );
}
}
else
{
wxBell();
}
}
else if( evt->IsAction( &EE_ACTIONS::switchSegmentPosture ) )
{
// The 90 degree mode doesn't have a forced posture like
// the 45 and 135 degree modes, so we don't have a mode to toggle
// in the UI. Instead, just swap the 90 angle here.
if( currentMode == LINE_MODE::LINE_MODE_90 && m_wires.size() >= 2 )
{
m_view->ClearPreview();
SCH_LINE* line2 = m_wires[m_wires.size() - 1];
SCH_LINE* line1 = m_wires[m_wires.size() - 2];
VECTOR2I delta2 = line2->GetEndPoint() - line2->GetStartPoint();
VECTOR2I delta1 = line1->GetEndPoint() - line1->GetStartPoint();
line2->SetStartPoint(line2->GetEndPoint() - delta1);
line1->SetEndPoint(line1->GetStartPoint() + delta2);
for( SCH_LINE* wire : m_wires )
{
if( !wire->IsNull() )
m_view->AddToPreview( wire->Clone() );
}
}
else
{
// Posture change for 45/135 will come back around as a mode
// change and we'll refresh as needed
evt->SetPassEvent();
}
}
//------------------------------------------------------------------------
// Handle context menu:
//
@ -867,7 +1027,7 @@ SCH_LINE* SCH_LINE_WIRE_BUS_TOOL::startSegments( int aType, const VECTOR2D& aPos
// We need 2 segments to go from a given start pin to an end point when the
// horizontal and vertical lines only switch is on.
if( m_frame->eeconfig()->m_Drawing.hv_lines_only )
if( m_frame->eeconfig()->m_Drawing.line_mode )
{
aSegment = static_cast<SCH_LINE*>( aSegment->Duplicate() );
aSegment->SetFlags( IS_NEW | IS_MOVING );

View File

@ -130,8 +130,10 @@ private:
* break point to compute.
* @param aPosition A reference to a wxPoint object containing the coordinates of the
* position used to calculate the line break point.
* @param mode LINE_MODE specifying the way to break the line
*/
void computeBreakPoint( const std::pair<SCH_LINE*, SCH_LINE*>& aSegments, VECTOR2I& aPosition );
void computeBreakPoint( const std::pair<SCH_LINE*, SCH_LINE*>& aSegments, VECTOR2I& aPosition,
LINE_MODE mode );
private:
bool m_inDrawingTool; // Reentrancy guard

View File

@ -386,7 +386,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
// values and if the signbit is set in the result, that means that one value
// had the sign bit set and one did not, hence the result is negative.
// We need to avoid std::signbit<int> as it is not supported by MSVC because reasons
if( ( m_moveOffset.x ^ ( m_moveOffset + delta ).x ) < 0 )
if( alg::signbit( m_moveOffset.x ) != alg::signbit( ( m_moveOffset + delta ).x ) )
{
splitMoves.emplace_back( VECTOR2I( -1 * m_moveOffset.x, 0 ) );
splitMoves.emplace_back( VECTOR2I( delta.x + m_moveOffset.x, 0 ) );
@ -394,7 +394,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
else
splitMoves.emplace_back( VECTOR2I( delta.x, 0 ) );
if( ( m_moveOffset.y ^ ( m_moveOffset + delta ).y ) < 0 )
if( alg::signbit( m_moveOffset.y ) != alg::signbit( ( m_moveOffset + delta ).y ) )
{
splitMoves.emplace_back( VECTOR2I( 0, -1 * m_moveOffset.y ) );
splitMoves.emplace_back( VECTOR2I( 0, delta.y + m_moveOffset.y ) );
@ -428,7 +428,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
item->Type() == SCH_LINE_T ? static_cast<SCH_LINE*>( item ) : nullptr;
//Only partially selected drag lines in orthogonal line mode need special handling
if( m_isDrag && cfg->m_Drawing.hv_lines_only && line
if( m_isDrag && cfg->m_Drawing.line_mode != LINE_MODE::LINE_MODE_FREE && line
&& ( line->HasFlag( STARTPOINT ) != line->HasFlag( ENDPOINT ) ) )
{
// If the move is not the same angle as this move, then we need to do something

View File

@ -176,6 +176,16 @@ void delete_if( _Container& __c, _Function&& __f )
}
/**
* @brief Integral version of std::signbit that works all compilers.
*/
template <typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
bool signbit( T v )
{
return v < 0;
}
} // namespace alg
#endif /* INCLUDE_CORE_KICAD_ALGO_H_ */