You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
7.0 KiB

  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-2023 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. #ifndef EE_TOOL_BASE_H
  25. #define EE_TOOL_BASE_H
  26. #include <math/vector2d.h>
  27. #include <tool/tool_event.h>
  28. #include <tool/tool_interactive.h>
  29. #include <tool/tool_manager.h>
  30. #include <tool/tool_menu.h>
  31. #include <tool/actions.h>
  32. #include <tools/ee_selection_tool.h>
  33. #include <sch_edit_frame.h>
  34. #include <sch_view.h>
  35. #include <symbol_edit_frame.h>
  36. class EE_SELECTION;
  37. /**
  38. * A foundation class for a tool operating on a schematic or symbol.
  39. */
  40. template <class T>
  41. class EE_TOOL_BASE : public TOOL_INTERACTIVE
  42. {
  43. public:
  44. /**
  45. * Create a tool with given name. The name must be unique.
  46. */
  47. EE_TOOL_BASE( const std::string& aName ) :
  48. TOOL_INTERACTIVE ( aName ),
  49. m_frame( nullptr ),
  50. m_view( nullptr ),
  51. m_selectionTool( nullptr ),
  52. m_isSymbolEditor( false )
  53. {};
  54. ~EE_TOOL_BASE() override {};
  55. /// @copydoc TOOL_INTERACTIVE::Init()
  56. bool Init() override
  57. {
  58. m_frame = getEditFrame<T>();
  59. m_selectionTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
  60. m_isSymbolEditor = m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR );
  61. // A basic context menu. Many (but not all) tools will choose to override this.
  62. auto& ctxMenu = m_menu.GetMenu();
  63. // cancel current tool goes in main context menu at the top if present
  64. ctxMenu.AddItem( ACTIONS::cancelInteractive, SELECTION_CONDITIONS::ShowAlways, 1 );
  65. ctxMenu.AddSeparator( 1 );
  66. // Finally, add the standard zoom/grid items
  67. m_frame->AddStandardSubMenus( m_menu );
  68. return true;
  69. }
  70. /// @copydoc TOOL_INTERACTIVE::Reset()
  71. void Reset( RESET_REASON aReason ) override
  72. {
  73. if( aReason == MODEL_RELOAD || aReason == SUPERMODEL_RELOAD )
  74. {
  75. // Init variables used by every drawing tool
  76. m_frame = getEditFrame<T>();
  77. m_isSymbolEditor = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame ) != nullptr;
  78. }
  79. m_view = static_cast<KIGFX::SCH_VIEW*>( getView() );
  80. }
  81. /**
  82. * Returns true if the tool is running in the symbol editor
  83. */
  84. bool IsSymbolEditor() const
  85. {
  86. return m_isSymbolEditor;
  87. }
  88. protected:
  89. /**
  90. * Similar to getView()->Update(), but handles items that are redrawn by their parents
  91. * and updating the SCH_SCREEN's RTree.
  92. */
  93. void updateItem( EDA_ITEM* aItem, bool aUpdateRTree ) const
  94. {
  95. switch( aItem->Type() )
  96. {
  97. case SCH_SHEET_PIN_T:
  98. getView()->Update( aItem );
  99. getView()->Update( aItem->GetParent() );
  100. // Moving sheet pins does not change the BBox.
  101. break;
  102. case SCH_PIN_T:
  103. case SCH_FIELD_T:
  104. case SCH_TABLECELL_T:
  105. getView()->Update( aItem );
  106. getView()->Update( aItem->GetParent() );
  107. if( aUpdateRTree )
  108. m_frame->GetScreen()->Update( static_cast<SCH_ITEM*>( aItem->GetParent() ) );
  109. break;
  110. default:
  111. getView()->Update( aItem );
  112. if( aUpdateRTree && dynamic_cast<SCH_ITEM*>( aItem ) )
  113. m_frame->GetScreen()->Update( static_cast<SCH_ITEM*>( aItem ) );
  114. break;
  115. }
  116. }
  117. ///< Similar to m_frame->SaveCopyInUndoList(), but handles items that are owned by their
  118. ///< parents.
  119. void saveCopyInUndoList( EDA_ITEM* aItem, UNDO_REDO aType, bool aAppend = false,
  120. bool aDirtyConnectivity = true )
  121. {
  122. wxASSERT( aItem );
  123. KICAD_T itemType = aItem->Type();
  124. bool selected = aItem->IsSelected();
  125. // IS_SELECTED flag should not be set on undo items which were added for
  126. // a drag operation.
  127. if( selected && aItem->HasFlag( SELECTED_BY_DRAG ) )
  128. aItem->ClearSelected();
  129. if( m_isSymbolEditor )
  130. {
  131. SYMBOL_EDIT_FRAME* editFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  132. wxCHECK_RET( editFrame, wxT( "editFrame is null" ) );
  133. editFrame->SaveCopyInUndoList( wxEmptyString, dynamic_cast<LIB_SYMBOL*>( aItem ) );
  134. }
  135. else
  136. {
  137. SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
  138. wxASSERT( editFrame );
  139. if( editFrame )
  140. {
  141. if( itemType == SCH_FIELD_T )
  142. {
  143. editFrame->SaveCopyInUndoList( editFrame->GetScreen(),
  144. static_cast<SCH_ITEM*>( aItem->GetParent() ),
  145. UNDO_REDO::CHANGED, aAppend,
  146. false );
  147. }
  148. else if( itemType == SCH_PIN_T || itemType == SCH_SHEET_PIN_T )
  149. {
  150. editFrame->SaveCopyInUndoList( editFrame->GetScreen(),
  151. static_cast<SCH_ITEM*>( aItem->GetParent() ),
  152. UNDO_REDO::CHANGED, aAppend,
  153. aDirtyConnectivity );
  154. }
  155. else
  156. {
  157. editFrame->SaveCopyInUndoList( editFrame->GetScreen(),
  158. static_cast<SCH_ITEM*>( aItem ), aType,
  159. aAppend, aDirtyConnectivity );
  160. }
  161. }
  162. }
  163. if( selected && aItem->HasFlag( SELECTED_BY_DRAG ) )
  164. aItem->SetSelected();
  165. }
  166. protected:
  167. T* m_frame;
  168. KIGFX::SCH_VIEW* m_view;
  169. EE_SELECTION_TOOL* m_selectionTool;
  170. bool m_isSymbolEditor;
  171. };
  172. // For LibEdit
  173. inline VECTOR2I mapCoords( const wxPoint& aCoord )
  174. {
  175. return VECTOR2I( aCoord.x, -aCoord.y );
  176. }
  177. inline VECTOR2I mapCoords( const VECTOR2I& aCoord )
  178. {
  179. return VECTOR2I( aCoord.x, -aCoord.y );
  180. }
  181. inline VECTOR2I mapCoords( const int x, const int y )
  182. {
  183. return VECTOR2I( x, -y );
  184. }
  185. #endif