1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2016 CERN 5 * Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors. 6 * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 2 11 * of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, you may find one here: 20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 21 * or you may search the http://www.gnu.org website for the version 2 license, 22 * or you may write to the Free Software Foundation, Inc., 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 24 */ 25 26 #ifndef PCB_TOOL_BASE_H 27 #define PCB_TOOL_BASE_H 28 29 #include <string> 30 31 #include <tool/tool_interactive.h> 32 #include <pcb_edit_frame.h> 33 #include <board.h> 34 #include <view/view_group.h> 35 #include <pcb_view.h> 36 #include <pcb_draw_panel_gal.h> 37 38 #include <functional> 39 #include <tool/tool_menu.h> 40 41 /** 42 * PCB_TOOL_BASE 43 * 44 * A tool operating on a BOARD object 45 **/ 46 47 class PCB_TOOL_BASE; 48 class PCB_EDIT_FRAME; 49 class PCB_DISPLAY_OPTIONS; 50 class PCB_SELECTION; 51 52 struct INTERACTIVE_PLACER_BASE 53 { ~INTERACTIVE_PLACER_BASEINTERACTIVE_PLACER_BASE54 virtual ~INTERACTIVE_PLACER_BASE() 55 { 56 } 57 58 virtual std::unique_ptr<BOARD_ITEM> CreateItem() = 0; 59 60 virtual void SnapItem( BOARD_ITEM *aItem ); 61 62 virtual bool PlaceItem( BOARD_ITEM *aItem, BOARD_COMMIT& aCommit ); 63 64 PCB_BASE_EDIT_FRAME* m_frame; 65 BOARD* m_board; 66 int m_modifiers; 67 }; 68 69 70 class PCB_TOOL_BASE : public TOOL_INTERACTIVE 71 { 72 public: 73 /** 74 * Constructor 75 * 76 * Creates a tool with given id & name. The name must be unique. */ PCB_TOOL_BASE(TOOL_ID aId,const std::string & aName)77 PCB_TOOL_BASE( TOOL_ID aId, const std::string& aName ) : 78 TOOL_INTERACTIVE ( aId, aName ), 79 m_isFootprintEditor( false ) 80 {}; 81 82 /** 83 * Constructor 84 * 85 * Creates a tool with given name. The name must be unique. */ PCB_TOOL_BASE(const std::string & aName)86 PCB_TOOL_BASE( const std::string& aName ) : 87 TOOL_INTERACTIVE ( aName ), 88 m_isFootprintEditor( false ) 89 {}; 90 ~PCB_TOOL_BASE()91 virtual ~PCB_TOOL_BASE() {}; 92 93 virtual bool Init() override; 94 virtual void Reset( RESET_REASON aReason ) override; 95 96 /** 97 * Function SetIsFootprintEditor() 98 * 99 * Toggles edit footprint mode. When enabled, one may select parts of footprints individually 100 * (graphics, pads, etc.), so they can be modified. 101 * @param aEnabled decides if the mode should be enabled. 102 */ SetIsFootprintEditor(bool aEnabled)103 void SetIsFootprintEditor( bool aEnabled ) { m_isFootprintEditor = aEnabled; } IsFootprintEditor()104 bool IsFootprintEditor() const { return m_isFootprintEditor; } 105 106 /** 107 * Should the tool use its 45° mode option? 108 * @return True if set to use 45° 109 */ 110 virtual bool Is45Limited() const; 111 112 protected: 113 /** 114 * Options for placing items interactively. 115 */ 116 enum INTERACTIVE_PLACEMENT_OPTIONS { 117 /// Handle the rotate action in the loop by calling the item's rotate method 118 IPO_ROTATE = 0x01, 119 120 /// Handle flip action in the loop by calling the item's flip method 121 IPO_FLIP = 0x02, 122 123 /// Create an item immediately on placement starting, otherwise show the pencil cursor 124 /// until the item is created 125 IPO_SINGLE_CLICK = 0x04, 126 127 /// Allow repeat placement of the item 128 IPO_REPEAT = 0x08 129 }; 130 131 /** 132 * Helper function for performing a common interactive idiom: 133 * wait for a left click, place an item there (perhaps with a 134 * dialog or other user interaction), then have it move with 135 * the mouse and respond to rotate/flip, etc 136 * 137 * More complex interactive processes are not supported here, you 138 * should implement a customised event loop for those. 139 * 140 * @param aItemCreator the callable that will attempt to create the item 141 * @param aCommitMessage the message used on a successful commit 142 */ 143 void doInteractiveItemPlacement( const std::string& aTool, INTERACTIVE_PLACER_BASE *aPlacer, 144 const wxString& aCommitMessage, 145 int aOptions = IPO_ROTATE | IPO_FLIP | IPO_REPEAT ); 146 147 virtual void setTransitions() override; 148 149 view()150 KIGFX::PCB_VIEW* view() const 151 { 152 return static_cast<KIGFX::PCB_VIEW*>( getView() ); 153 } 154 controls()155 KIGFX::VIEW_CONTROLS* controls() const 156 { 157 return getViewControls(); 158 } 159 frame()160 PCB_BASE_EDIT_FRAME* frame() const 161 { 162 return getEditFrame<PCB_BASE_EDIT_FRAME>(); 163 } 164 board()165 BOARD* board() const { return getModel<BOARD>(); } 166 footprint()167 FOOTPRINT* footprint() const 168 { 169 return board()->GetFirstFootprint(); 170 } 171 172 const PCB_DISPLAY_OPTIONS& displayOptions() const; 173 174 PCB_DRAW_PANEL_GAL* canvas() const; 175 176 const PCB_SELECTION& selection() const; 177 178 PCB_SELECTION& selection(); 179 180 protected: 181 bool m_isFootprintEditor; 182 183 }; 184 185 #endif 186