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.

263 lines
7.1 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2013-2023 CERN
  5. * Copyright The 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. #include <cstring>
  26. #include <string>
  27. #include <tool/tool_event.h>
  28. #include <tool/tool_action.h>
  29. #include <tool/tool_manager.h>
  30. #include <tool/actions.h>
  31. #include <wx/debug.h>
  32. struct FlagString
  33. {
  34. int flag;
  35. std::string str;
  36. };
  37. static const std::string flag2string( int aFlag, const FlagString* aExps )
  38. {
  39. std::string rv;
  40. for( int i = 0; aExps[i].str.length(); i++ )
  41. {
  42. if( aExps[i].flag & aFlag )
  43. rv += aExps[i].str + " ";
  44. }
  45. return rv;
  46. }
  47. void TOOL_EVENT::init()
  48. {
  49. // By default only MESSAGEs and Cancels are passed to multiple recipients
  50. m_passEvent = m_category == TC_MESSAGE || IsCancelInteractive() || IsActivate();
  51. m_hasPosition = ( m_category == TC_MOUSE || m_category == TC_COMMAND );
  52. // Cancel tool doesn't contain a position
  53. if( IsCancel() )
  54. m_hasPosition = false;
  55. m_forceImmediate = false;
  56. m_reactivate = false;
  57. }
  58. VECTOR2D TOOL_EVENT::returnCheckedPosition( const VECTOR2D& aPos ) const
  59. {
  60. wxCHECK_MSG( HasPosition(), VECTOR2D(), "Attempted to get position from non-position event" );
  61. return aPos;
  62. }
  63. bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const
  64. {
  65. return Matches( aAction->MakeEvent() );
  66. }
  67. bool TOOL_EVENT::IsActionInGroup( const TOOL_ACTION_GROUP& aGroup ) const
  68. {
  69. if( m_actionGroup.has_value() )
  70. return m_actionGroup.value() == aGroup;
  71. return false;
  72. }
  73. const std::string TOOL_EVENT::Format() const
  74. {
  75. std::string ev;
  76. const FlagString categories[] =
  77. {
  78. { TC_MOUSE, "mouse" },
  79. { TC_KEYBOARD, "keyboard" },
  80. { TC_COMMAND, "command" },
  81. { TC_MESSAGE, "message" },
  82. { TC_VIEW, "view" },
  83. { 0, "" }
  84. };
  85. const FlagString actions[] =
  86. {
  87. { TA_MOUSE_CLICK, "click" },
  88. { TA_MOUSE_DBLCLICK, "double click" },
  89. { TA_MOUSE_UP, "button-up" },
  90. { TA_MOUSE_DOWN, "button-down" },
  91. { TA_MOUSE_DRAG, "drag" },
  92. { TA_MOUSE_MOTION, "motion" },
  93. { TA_MOUSE_WHEEL, "wheel" },
  94. { TA_KEY_PRESSED, "key-pressed" },
  95. { TA_VIEW_REFRESH, "view-refresh" },
  96. { TA_VIEW_ZOOM, "view-zoom" },
  97. { TA_VIEW_PAN, "view-pan" },
  98. { TA_VIEW_DIRTY, "view-dirty" },
  99. { TA_CHANGE_LAYER, "change-layer" },
  100. { TA_CANCEL_TOOL, "cancel-tool" },
  101. { TA_CHOICE_MENU_UPDATE, "choice-menu-update" },
  102. { TA_CHOICE_MENU_CHOICE, "choice-menu-choice" },
  103. { TA_UNDO_REDO_PRE, "undo-redo-pre" },
  104. { TA_UNDO_REDO_POST, "undo-redo-post" },
  105. { TA_ACTION, "action" },
  106. { TA_ACTIVATE, "activate" },
  107. { 0, "" }
  108. };
  109. const FlagString buttons[] =
  110. {
  111. { BUT_NONE, "none" },
  112. { BUT_LEFT, "left" },
  113. { BUT_RIGHT, "right" },
  114. { BUT_MIDDLE, "middle" },
  115. { BUT_AUX1, "aux1" },
  116. { BUT_AUX2, "aux2" },
  117. { 0, "" }
  118. };
  119. const FlagString modifiers[] =
  120. {
  121. { MD_SHIFT, "shift" },
  122. { MD_CTRL, "ctrl" },
  123. { MD_ALT, "alt" },
  124. { MD_SUPER, "super" },
  125. { MD_META, "meta" },
  126. { MD_ALTGR, "altgr" },
  127. { 0, "" }
  128. };
  129. ev = "category: " + flag2string( m_category, categories ) + " ";
  130. ev += "action: " + flag2string( m_actions, actions ) + " ";
  131. ev += "action-group: ";
  132. if( m_actionGroup.has_value() )
  133. {
  134. ev += m_actionGroup.value().GetName() +
  135. "(" + std::to_string( m_actionGroup.value().GetGroupID() ) + ")" + " ";
  136. }
  137. else
  138. {
  139. ev += "none ";
  140. }
  141. if( m_actions & TA_MOUSE )
  142. ev += "btns: " + flag2string( m_mouseButtons, buttons ) + " ";
  143. if( m_actions & TA_KEYBOARD )
  144. ev += "key: " + std::to_string( m_keyCode ) + " ";
  145. if( m_actions & ( TA_MOUSE | TA_KEYBOARD ) )
  146. ev += "mods: " + flag2string( m_modifiers, modifiers ) + " ";
  147. if( m_commandId )
  148. ev += "cmd-id: " + std::to_string( *m_commandId ) + " ";
  149. ev += "cmd-str: " + m_commandStr;
  150. return ev;
  151. }
  152. const std::string TOOL_EVENT_LIST::Format() const
  153. {
  154. std::string s;
  155. for( const TOOL_EVENT& e : m_events )
  156. s += e.Format() + " ";
  157. return s;
  158. }
  159. const std::string TOOL_EVENT_LIST::Names() const
  160. {
  161. std::string s;
  162. for( const TOOL_EVENT& e : m_events )
  163. s += e.m_commandStr + " ";
  164. return s;
  165. }
  166. bool TOOL_EVENT::IsClick( int aButtonMask ) const
  167. {
  168. return ( m_actions & TA_MOUSE_CLICK ) && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
  169. }
  170. bool TOOL_EVENT::IsDblClick( int aButtonMask ) const
  171. {
  172. return m_actions == TA_MOUSE_DBLCLICK && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
  173. }
  174. bool TOOL_EVENT::IsCancelInteractive() const
  175. {
  176. return ( ( m_commandStr == ACTIONS::cancelInteractive.GetName() )
  177. || ( m_commandId && *m_commandId == ACTIONS::cancelInteractive.GetId() )
  178. || ( m_actions == TA_CANCEL_TOOL ) );
  179. }
  180. bool TOOL_EVENT::IsSelectionEvent() const
  181. {
  182. return Matches( EVENTS::ClearedEvent )
  183. || Matches( EVENTS::UnselectedEvent )
  184. || Matches( EVENTS::SelectedEvent )
  185. || Matches( EVENTS::PointSelectedEvent );
  186. }
  187. bool TOOL_EVENT::IsPointEditor() const
  188. {
  189. return ( ( m_commandStr.find( "PointEditor" ) != getCommandStr().npos )
  190. || ( m_commandId && *m_commandId == ACTIONS::activatePointEditor.GetId() ) );
  191. }
  192. bool TOOL_EVENT::IsMoveTool() const
  193. {
  194. return ( m_commandStr.find( "InteractiveMove" ) != getCommandStr().npos );
  195. }
  196. bool TOOL_EVENT::IsEditorTool() const
  197. {
  198. return ( m_commandStr.find( "InteractiveEdit" ) != getCommandStr().npos );
  199. }
  200. bool TOOL_EVENT::IsSimulator() const
  201. {
  202. return ( m_commandStr.find( "Simulation" ) != getCommandStr().npos );
  203. }