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