1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2019 CERN 5 * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, you may find one here: 19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 20 * or you may search the http://www.gnu.org website for the version 2 license, 21 * or you may write to the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 */ 24 25 #ifndef KICAD_SCH_SELECTION_TOOL_H 26 #define KICAD_SCH_SELECTION_TOOL_H 27 28 #include <tool/selection_tool.h> 29 #include <tool/action_menu.h> 30 #include <tool/tool_menu.h> 31 #include <tools/ee_selection.h> 32 #include <ee_collectors.h> 33 #include <sch_symbol.h> 34 #include <gal/cursors.h> 35 36 class SCH_BASE_FRAME; 37 class SCH_ITEM; 38 39 namespace KIGFX 40 { 41 class GAL; 42 } 43 44 45 class EE_CONDITIONS : public SELECTION_CONDITIONS 46 { 47 public: 48 static SELECTION_CONDITION SingleSymbol; 49 static SELECTION_CONDITION SingleSymbolOrPower; 50 static SELECTION_CONDITION SingleDeMorganSymbol; 51 static SELECTION_CONDITION SingleMultiUnitSymbol; 52 }; 53 54 55 class EE_SELECTION_TOOL : public SELECTION_TOOL, public TOOL_INTERACTIVE 56 { 57 public: 58 EE_SELECTION_TOOL(); 59 ~EE_SELECTION_TOOL(); 60 61 /// @copydoc TOOL_BASE::Init() 62 bool Init() override; 63 64 /// @copydoc TOOL_BASE::Reset() 65 void Reset( RESET_REASON aReason ) override; 66 67 int UpdateMenu( const TOOL_EVENT& aEvent ); 68 69 /** 70 * The main loop. 71 */ 72 int Main( const TOOL_EVENT& aEvent ); 73 74 void OnIdle( wxIdleEvent& aEvent ); 75 76 /** 77 * Return the set of currently selected items. 78 */ 79 EE_SELECTION& GetSelection(); 80 81 /** 82 * Return either an existing selection (filtered), or the selection at the current 83 * cursor if the existing selection is empty. 84 */ 85 EE_SELECTION& RequestSelection( const KICAD_T* aFilterList = EE_COLLECTOR::AllItems ); 86 87 /** 88 * This overload of SelectPoint will create an EE_COLLECTOR and collect hits at location aWhere 89 * before calling the primary SelectPoint method. 90 * 91 * @param aWhere is the location where the item(s) should be collected 92 * @param aItem is set to the newly selected item if only one was selected, otherwise is 93 * unchanged. 94 * @param aSelectionCancelledFlag allows the function to inform its caller that a selection 95 * was canceled (for instance, by clicking outside of the 96 * disambiguation menu). 97 * @param aCheckLocked indicates if locked items should be excluded. 98 * @param aAdd indicates if found item(s) should be added to the selection 99 * @param aSubtract indicates if found item(s) should be subtracted from the selection 100 * @param aExclusiveOr indicates if found item(s) should be toggle in the selection 101 */ 102 bool SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList = EE_COLLECTOR::AllItems, 103 EDA_ITEM** aItem = nullptr, bool* aSelectionCancelledFlag = nullptr, 104 bool aCheckLocked = false, bool aAdd = false, bool aSubtract = false, 105 bool aExclusiveOr = false ); 106 107 int AddItemToSel( const TOOL_EVENT& aEvent ); 108 void AddItemToSel( EDA_ITEM* aItem, bool aQuietMode = false ); 109 int AddItemsToSel( const TOOL_EVENT& aEvent ); 110 void AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode = false ); 111 112 int RemoveItemFromSel( const TOOL_EVENT& aEvent ); 113 void RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode = false ); 114 int RemoveItemsFromSel( const TOOL_EVENT& aEvent ); 115 void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false ); 116 117 /** 118 * A safer version of RemoveItemsFromSel( EDA_ITEMS ) which doesn't require the items to 119 * still exist. 120 */ 121 void RemoveItemsFromSel( std::vector<KIID>* aList, bool aQuietMode = false ); 122 123 void BrightenItem( EDA_ITEM* aItem ); 124 void UnbrightenItem( EDA_ITEM* aItem ); 125 SelectHighlightItem(EDA_ITEM * aItem)126 void SelectHighlightItem( EDA_ITEM* aItem ) { highlight( aItem, SELECTED ); } 127 128 ///< Find (but don't select) node under cursor 129 EDA_ITEM* GetNode( VECTOR2I aPosition ); 130 131 ///< Select node under cursor 132 int SelectNode( const TOOL_EVENT& aEvent ); 133 134 ///< If node selected then expand to connection, otherwise select connection under cursor 135 int SelectConnection( const TOOL_EVENT& aEvent ); 136 137 ///< Clear current selection event handler. 138 int ClearSelection( const TOOL_EVENT& aEvent ); 139 140 ///< Select all visible items in sheet 141 int SelectAll( const TOOL_EVENT& aEvent ); 142 143 void ClearSelection(); 144 145 /** 146 * Check conditions for an item to be selected. 147 * 148 * @return True if the item fulfills conditions to be selected. 149 */ 150 bool Selectable( const EDA_ITEM* aItem, const VECTOR2I* aPos = nullptr, 151 bool checkVisibilityOnly = false ) const; 152 153 /** 154 * Apply heuristics to try and determine a single object when multiple are found under the 155 * cursor. 156 */ 157 void GuessSelectionCandidates( EE_COLLECTOR& collector, const VECTOR2I& aPos ); 158 159 /** 160 * Show a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single 161 * item. 162 * 163 * @note This routine **does not** modify the selection. 164 */ 165 int SelectionMenu( const TOOL_EVENT& aEvent ); 166 167 /** 168 * Rebuild the selection from the EDA_ITEMs' selection flags. 169 * 170 * Commonly called after rolling back an undo state to make sure there aren't any stale 171 * pointers. 172 */ 173 void RebuildSelection(); 174 175 /** 176 * Select one or more items at the location given by parameter aWhere. 177 * 178 * This method does not attempt to disambiguate multiple items and is simply "collecting" 179 * 180 * @param aCollector is the collector object that will store found item(s) 181 * @param aWhere is the place where the item should be selected. 182 * @param aFilterList is a list of items that are acceptable for collection 183 * @param aCheckLocked indicates if locked items should be excluded. 184 */ 185 bool CollectHits( EE_COLLECTOR& aCollector, const VECTOR2I& aWhere, 186 const KICAD_T* aFilterList = EE_COLLECTOR::AllItems ); 187 188 private: 189 /** 190 * Apply rules to narrow the collection down to selectable objects, and then heuristics 191 * to try and narrow it to a single object. 192 * 193 * @param collector EE_COLLECTOR with elements to filter 194 * @param aWhere point where we should narrow (if relevant) 195 * @param aCheckLocked If false, remove locked elements from #collector 196 * @param aSelectPoints If true, set STARTPOINT/ENDPOINT flags on individual wires 197 */ 198 void narrowSelection( EE_COLLECTOR& collector, const VECTOR2I& aWhere, bool aCheckLocked, bool aSelectPoints ); 199 200 /** 201 * This is the primary SelectPoint method that will prompt the user with a menu to disambiguate 202 * multiple selections and then finish by adding, subtracting or toggling the item(s) to the 203 * actual selection group. 204 * 205 * @param aCollector is an EE_COLLECTOR that already has collected items 206 * @param aItem is set to the newly selected item if only one was selected, otherwise is 207 * unchanged. 208 * @param aSelectionCancelledFlag allows the function to inform its caller that a selection 209 * was canceled (for instance, by clicking outside of the 210 * disambiguation menu). 211 * @param aAdd indicates if found item(s) should be added to the selection 212 * @param aSubtract indicates if found item(s) should be subtracted from the selection 213 * @param aExclusiveOr indicates if found item(s) should be toggle in the selection 214 */ 215 bool selectPoint( EE_COLLECTOR& aCollector, EDA_ITEM** aItem = nullptr, 216 bool* aSelectionCancelledFlag = nullptr, bool aAdd = false, 217 bool aSubtract = false, bool aExclusiveOr = false ); 218 219 /** 220 * Handle drawing a selection box that allows one to select many items at the same time. 221 * 222 * @return true if the function was canceled (i.e. CancelEvent was received). 223 */ 224 bool selectMultiple(); 225 226 /** 227 * Allow the selection of a single item from a list via pop-up menu. The items are 228 * highlighted on the canvas when hovered in the menu. The collector is trimmed to 229 * the picked item. 230 * 231 * @return true if an item was picked 232 */ 233 bool doSelectionMenu( EE_COLLECTOR* aItems ); 234 235 /** 236 * Start the process to show our disambiguation menu once the user has kept 237 * the mouse down for the minimum time 238 * @param aEvent 239 */ 240 void onDisambiguationExpire( wxTimerEvent& aEvent ); 241 242 /** 243 * Handle disambiguation actions including displaying the menu. 244 */ 245 int disambiguateCursor( const TOOL_EVENT& aEvent ); 246 247 /** 248 * Take necessary action mark an item as selected. 249 * 250 * @param aItem is an item to be selected. 251 */ 252 void select( EDA_ITEM* aItem ); 253 254 /** 255 * Take necessary action mark an item as unselected. 256 * 257 * @param aItem is an item to be unselected. 258 */ 259 void unselect( EDA_ITEM* aItem ); 260 261 /** 262 * Highlight the item visually. 263 * 264 * @param aItem is an item to be be highlighted. 265 * @param aHighlightMode should be either SELECTED or BRIGHTENED 266 * @param aGroup is the group to add the item to in the BRIGHTENED mode. 267 */ 268 void highlight( EDA_ITEM* aItem, int aHighlightMode, EE_SELECTION* aGroup = nullptr ); 269 270 /** 271 * Unhighlight the item visually. 272 * 273 * @param aItem is an item to be be highlighted. 274 * @param aHighlightMode should be either SELECTED or BRIGHTENED 275 * @param aGroup is the group to remove the item from. 276 */ 277 void unhighlight( EDA_ITEM* aItem, int aHighlightMode, EE_SELECTION* aGroup = nullptr ); 278 279 /** 280 * Set the reference point to the anchor of the top-left item. 281 */ 282 void updateReferencePoint(); 283 284 /** 285 * @return True if the given point is contained in any of selected items' bounding box. 286 */ 287 bool selectionContains( const VECTOR2I& aPoint ) const; 288 289 ///< Set up handlers for various events. 290 void setTransitions() override; 291 292 private: 293 294 SCH_BASE_FRAME* m_frame; // Pointer to the parent frame 295 EE_SELECTION m_selection; // Current state of selection 296 297 KICURSOR m_nonModifiedCursor; // Cursor in the absence of shift/ctrl/alt 298 299 bool m_isSymbolEditor; // True when the symbol editor is the parent frame 300 bool m_isSymbolViewer; // True when the symbol browser is the parent frame 301 int m_unit; // Fixed unit filter (for symbol editor) 302 int m_convert; // Fixed DeMorgan filter (for symbol editor) 303 }; 304 305 #endif //KICAD_SCH_SELECTION_TOOL_H 306