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.

323 lines
8.9 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
  5. * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <confirm.h>
  21. #include <cstdint>
  22. #include <functional>
  23. #include <kiface_base.h>
  24. #include <kiway_express.h>
  25. #include <lib_id.h>
  26. #include <tool/actions.h>
  27. #include <tool/tool_manager.h>
  28. #include <cvpcb_mainframe.h>
  29. #include <dialogs/dialog_config_equfiles.h>
  30. #include <display_footprints_frame.h>
  31. #include <listboxes.h>
  32. #include <tools/cvpcb_actions.h>
  33. #include <tools/cvpcb_control.h>
  34. #include <wx/settings.h>
  35. using namespace std::placeholders;
  36. CVPCB_CONTROL::CVPCB_CONTROL() :
  37. TOOL_INTERACTIVE( "cvpcb.Control" ),
  38. m_frame( nullptr )
  39. {
  40. }
  41. void CVPCB_CONTROL::Reset( RESET_REASON aReason )
  42. {
  43. m_frame = getEditFrame<CVPCB_MAINFRAME>();
  44. }
  45. int CVPCB_CONTROL::Main( const TOOL_EVENT& aEvent )
  46. {
  47. // Main loop: keep receiving events
  48. while( TOOL_EVENT* evt = Wait() )
  49. {
  50. bool handled = false;
  51. // The escape key maps to the cancel event, which is used to close the window
  52. if( evt->IsCancel() )
  53. {
  54. m_frame->Close( false );
  55. handled = true;
  56. }
  57. else if( evt->IsKeyPressed() )
  58. {
  59. switch( evt->KeyCode() )
  60. {
  61. // The right arrow moves focus to the focusable object to the right
  62. case WXK_RIGHT:
  63. m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusRight );
  64. handled = true;
  65. break;
  66. // The left arrow moves focus to the focusable object to the left
  67. case WXK_LEFT:
  68. m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusLeft );
  69. handled = true;
  70. break;
  71. default:
  72. // Let every other key continue processing to the controls of the window
  73. break;
  74. }
  75. }
  76. if( !handled )
  77. evt->SetPassEvent();
  78. }
  79. return 0;
  80. }
  81. int CVPCB_CONTROL::ChangeFocus( const TOOL_EVENT& aEvent )
  82. {
  83. int tmp = aEvent.Parameter<intptr_t>();
  84. CVPCB_MAINFRAME::FOCUS_DIR dir =
  85. static_cast<CVPCB_MAINFRAME::FOCUS_DIR>( tmp );
  86. switch( dir )
  87. {
  88. case CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT:
  89. switch( m_frame->GetFocusedControl() )
  90. {
  91. case CVPCB_MAINFRAME::CONTROL_LIBRARY:
  92. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
  93. break;
  94. case CVPCB_MAINFRAME::CONTROL_COMPONENT:
  95. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
  96. break;
  97. case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
  98. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
  99. break;
  100. case CVPCB_MAINFRAME::CONTROL_NONE:
  101. default:
  102. break;
  103. }
  104. break;
  105. case CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT:
  106. switch( m_frame->GetFocusedControl() )
  107. {
  108. case CVPCB_MAINFRAME::CONTROL_LIBRARY:
  109. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
  110. break;
  111. case CVPCB_MAINFRAME::CONTROL_COMPONENT:
  112. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
  113. break;
  114. case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
  115. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
  116. break;
  117. case CVPCB_MAINFRAME::CONTROL_NONE:
  118. default:
  119. break;
  120. }
  121. break;
  122. default:
  123. break;
  124. }
  125. return 0;
  126. }
  127. int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
  128. {
  129. DISPLAY_FOOTPRINTS_FRAME* fpframe = m_frame->GetFootprintViewerFrame();
  130. if( !fpframe )
  131. {
  132. fpframe = (DISPLAY_FOOTPRINTS_FRAME*) m_frame->Kiway().Player(
  133. FRAME_CVPCB_DISPLAY, true, m_frame );
  134. fpframe->Show( true );
  135. }
  136. else
  137. {
  138. if( fpframe->IsIconized() )
  139. fpframe->Iconize( false );
  140. // The display footprint window might be buried under some other
  141. // windows, so CreateScreenCmp() on an existing window would not
  142. // show any difference, leaving the user confused.
  143. // So we want to put it to front, second after our CVPCB_MAINFRAME.
  144. // We do this by a little dance of bringing it to front then the main
  145. // frame back.
  146. wxWindow* focus = m_frame->FindFocus();
  147. fpframe->Raise(); // Make sure that is visible.
  148. m_frame->Raise(); // .. but still we want the focus.
  149. if( focus )
  150. focus->SetFocus();
  151. }
  152. fpframe->InitDisplay();
  153. return 0;
  154. }
  155. int CVPCB_CONTROL::ToggleFootprintFilter( const TOOL_EVENT& aEvent )
  156. {
  157. m_frame->SetFootprintFilter(
  158. static_cast<FOOTPRINTS_LISTBOX::FP_FILTER_T>( aEvent.Parameter<intptr_t>() ),
  159. CVPCB_MAINFRAME::FILTER_TOGGLE );
  160. return 0;
  161. }
  162. int CVPCB_CONTROL::ShowEquFileTable( const TOOL_EVENT& aEvent )
  163. {
  164. DIALOG_CONFIG_EQUFILES dlg( m_frame );
  165. dlg.ShowModal();
  166. return 0;
  167. }
  168. int CVPCB_CONTROL::SaveAssociations( const TOOL_EVENT& aEvent )
  169. {
  170. m_frame->SaveFootprintAssociation( true );
  171. return 0;
  172. }
  173. int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
  174. {
  175. int tmp = aEvent.Parameter<intptr_t>();
  176. CVPCB_MAINFRAME::ITEM_DIR dir =
  177. static_cast<CVPCB_MAINFRAME::ITEM_DIR>( tmp );
  178. std::vector<unsigned int> naComp = m_frame->GetComponentIndices( CVPCB_MAINFRAME::NA_COMPONENTS );
  179. std::vector<unsigned int> tempSel = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
  180. // No unassociated components
  181. if( naComp.empty() )
  182. return 0;
  183. // Extract the current selection
  184. unsigned int curSel = -1;
  185. unsigned int newSel = -1;
  186. switch( dir )
  187. {
  188. case CVPCB_MAINFRAME::ITEM_NEXT:
  189. if( !tempSel.empty() )
  190. newSel = tempSel.front();
  191. // Find the next index in the component list
  192. for( unsigned int i : naComp )
  193. {
  194. if( i > newSel )
  195. {
  196. newSel = i;
  197. break;
  198. }
  199. }
  200. break;
  201. case CVPCB_MAINFRAME::ITEM_PREV:
  202. if( !tempSel.empty() )
  203. {
  204. newSel = tempSel.front();
  205. curSel = newSel - 1; // Break one before the current selection
  206. }
  207. break;
  208. default:
  209. wxASSERT_MSG( false, "Invalid direction" );
  210. }
  211. // Find the next index in the component list
  212. for( unsigned int i : naComp )
  213. {
  214. if( i >= curSel )
  215. {
  216. newSel = i;
  217. break;
  218. }
  219. }
  220. // Set the component selection
  221. m_frame->SetSelectedComponent( newSel );
  222. return 0;
  223. }
  224. int CVPCB_CONTROL::UpdateMenu( const TOOL_EVENT& aEvent )
  225. {
  226. ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
  227. CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
  228. SELECTION dummySel;
  229. if( conditionalMenu )
  230. conditionalMenu->Evaluate( dummySel );
  231. if( actionMenu )
  232. actionMenu->UpdateAll();
  233. return 0;
  234. }
  235. void CVPCB_CONTROL::setTransitions()
  236. {
  237. // Control actions
  238. Go( &CVPCB_CONTROL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
  239. Go( &CVPCB_CONTROL::Main, CVPCB_ACTIONS::controlActivate.MakeEvent() );
  240. Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusRight.MakeEvent() );
  241. Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusLeft.MakeEvent() );
  242. // Run the footprint viewer
  243. Go( &CVPCB_CONTROL::ShowFootprintViewer, CVPCB_ACTIONS::showFootprintViewer.MakeEvent() );
  244. // Management actions
  245. Go( &CVPCB_CONTROL::ShowEquFileTable, CVPCB_ACTIONS::showEquFileTable.MakeEvent() );
  246. Go( &CVPCB_CONTROL::SaveAssociations, CVPCB_ACTIONS::saveAssociations.MakeEvent() );
  247. // Navigation actions
  248. Go( &CVPCB_CONTROL::ToNA, CVPCB_ACTIONS::gotoNextNA.MakeEvent() );
  249. Go( &CVPCB_CONTROL::ToNA, CVPCB_ACTIONS::gotoPreviousNA.MakeEvent() );
  250. // Filter the footprints
  251. Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::FilterFPbyFPFilters.MakeEvent() );
  252. Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::FilterFPbyLibrary.MakeEvent() );
  253. Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::filterFPbyPin.MakeEvent() );
  254. }