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.

322 lines
8.9 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 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_i.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. using namespace std::placeholders;
  35. CVPCB_CONTROL::CVPCB_CONTROL() :
  36. TOOL_INTERACTIVE( "cvpcb.Control" ),
  37. m_frame( nullptr )
  38. {
  39. }
  40. void CVPCB_CONTROL::Reset( RESET_REASON aReason )
  41. {
  42. m_frame = getEditFrame<CVPCB_MAINFRAME>();
  43. }
  44. int CVPCB_CONTROL::Main( const TOOL_EVENT& aEvent )
  45. {
  46. // Main loop: keep receiving events
  47. while( TOOL_EVENT* evt = Wait() )
  48. {
  49. bool handled = false;
  50. // The escape key maps to the cancel event, which is used to close the window
  51. if( evt->IsCancel() )
  52. {
  53. m_frame->Close( false );
  54. handled = true;
  55. }
  56. else if( evt->IsKeyPressed() )
  57. {
  58. switch( evt->KeyCode() )
  59. {
  60. // The right arrow moves focus to the focusable object to the right
  61. case WXK_RIGHT:
  62. m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusRight );
  63. handled = true;
  64. break;
  65. // The left arrow moves focus to the focusable object to the left
  66. case WXK_LEFT:
  67. m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusLeft );
  68. handled = true;
  69. break;
  70. default:
  71. // Let every other key continue processing to the controls of the window
  72. break;
  73. }
  74. }
  75. if( !handled )
  76. evt->SetPassEvent();
  77. }
  78. return 0;
  79. }
  80. int CVPCB_CONTROL::ChangeFocus( const TOOL_EVENT& aEvent )
  81. {
  82. int tmp = aEvent.Parameter<intptr_t>();
  83. CVPCB_MAINFRAME::FOCUS_DIR dir =
  84. static_cast<CVPCB_MAINFRAME::FOCUS_DIR>( tmp );
  85. switch( dir )
  86. {
  87. case CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT:
  88. switch( m_frame->GetFocusedControl() )
  89. {
  90. case CVPCB_MAINFRAME::CONTROL_LIBRARY:
  91. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
  92. break;
  93. case CVPCB_MAINFRAME::CONTROL_COMPONENT:
  94. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
  95. break;
  96. case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
  97. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
  98. break;
  99. case CVPCB_MAINFRAME::CONTROL_NONE:
  100. default:
  101. break;
  102. }
  103. break;
  104. case CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT:
  105. switch( m_frame->GetFocusedControl() )
  106. {
  107. case CVPCB_MAINFRAME::CONTROL_LIBRARY:
  108. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
  109. break;
  110. case CVPCB_MAINFRAME::CONTROL_COMPONENT:
  111. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
  112. break;
  113. case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
  114. m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
  115. break;
  116. case CVPCB_MAINFRAME::CONTROL_NONE:
  117. default:
  118. break;
  119. }
  120. break;
  121. default:
  122. break;
  123. }
  124. return 0;
  125. }
  126. int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
  127. {
  128. DISPLAY_FOOTPRINTS_FRAME* fpframe = m_frame->GetFootprintViewerFrame();
  129. if( !fpframe )
  130. {
  131. fpframe = (DISPLAY_FOOTPRINTS_FRAME*) m_frame->Kiway().Player(
  132. FRAME_CVPCB_DISPLAY, true, m_frame );
  133. fpframe->Show( true );
  134. }
  135. else
  136. {
  137. if( fpframe->IsIconized() )
  138. fpframe->Iconize( false );
  139. // The display footprint window might be buried under some other
  140. // windows, so CreateScreenCmp() on an existing window would not
  141. // show any difference, leaving the user confused.
  142. // So we want to put it to front, second after our CVPCB_MAINFRAME.
  143. // We do this by a little dance of bringing it to front then the main
  144. // frame back.
  145. wxWindow* focus = m_frame->FindFocus();
  146. fpframe->Raise(); // Make sure that is visible.
  147. m_frame->Raise(); // .. but still we want the focus.
  148. if( focus )
  149. focus->SetFocus();
  150. }
  151. fpframe->InitDisplay();
  152. return 0;
  153. }
  154. int CVPCB_CONTROL::ToggleFootprintFilter( const TOOL_EVENT& aEvent )
  155. {
  156. m_frame->SetFootprintFilter(
  157. static_cast<FOOTPRINTS_LISTBOX::FP_FILTER_T>( aEvent.Parameter<intptr_t>() ),
  158. CVPCB_MAINFRAME::FILTER_TOGGLE );
  159. return 0;
  160. }
  161. int CVPCB_CONTROL::ShowEquFileTable( const TOOL_EVENT& aEvent )
  162. {
  163. DIALOG_CONFIG_EQUFILES dlg( m_frame );
  164. dlg.ShowModal();
  165. return 0;
  166. }
  167. int CVPCB_CONTROL::SaveAssociations( const TOOL_EVENT& aEvent )
  168. {
  169. m_frame->SaveFootprintAssociation( true );
  170. return 0;
  171. }
  172. int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
  173. {
  174. int tmp = aEvent.Parameter<intptr_t>();
  175. CVPCB_MAINFRAME::ITEM_DIR dir =
  176. static_cast<CVPCB_MAINFRAME::ITEM_DIR>( tmp );
  177. std::vector<unsigned int> naComp = m_frame->GetComponentIndices( CVPCB_MAINFRAME::NA_COMPONENTS );
  178. std::vector<unsigned int> tempSel = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
  179. // No unassociated components
  180. if( naComp.empty() )
  181. return 0;
  182. // Extract the current selection
  183. unsigned int curSel = -1;
  184. unsigned int newSel = -1;
  185. switch( dir )
  186. {
  187. case CVPCB_MAINFRAME::ITEM_NEXT:
  188. if( !tempSel.empty() )
  189. newSel = tempSel.front();
  190. // Find the next index in the component list
  191. for( unsigned int i : naComp )
  192. {
  193. if( i > newSel )
  194. {
  195. newSel = i;
  196. break;
  197. }
  198. }
  199. break;
  200. case CVPCB_MAINFRAME::ITEM_PREV:
  201. if( !tempSel.empty() )
  202. {
  203. newSel = tempSel.front();
  204. curSel = newSel - 1; // Break one before the current selection
  205. }
  206. break;
  207. default:
  208. wxASSERT_MSG( false, "Invalid direction" );
  209. }
  210. // Find the next index in the component list
  211. for( unsigned int i : naComp )
  212. {
  213. if( i >= curSel )
  214. {
  215. newSel = i;
  216. break;
  217. }
  218. }
  219. // Set the component selection
  220. m_frame->SetSelectedComponent( newSel );
  221. return 0;
  222. }
  223. int CVPCB_CONTROL::UpdateMenu( const TOOL_EVENT& aEvent )
  224. {
  225. ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
  226. CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
  227. SELECTION dummySel;
  228. if( conditionalMenu )
  229. conditionalMenu->Evaluate( dummySel );
  230. if( actionMenu )
  231. actionMenu->UpdateAll();
  232. return 0;
  233. }
  234. void CVPCB_CONTROL::setTransitions()
  235. {
  236. // Control actions
  237. Go( &CVPCB_CONTROL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
  238. Go( &CVPCB_CONTROL::Main, CVPCB_ACTIONS::controlActivate.MakeEvent() );
  239. Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusRight.MakeEvent() );
  240. Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusLeft.MakeEvent() );
  241. // Run the footprint viewer
  242. Go( &CVPCB_CONTROL::ShowFootprintViewer, CVPCB_ACTIONS::showFootprintViewer.MakeEvent() );
  243. // Management actions
  244. Go( &CVPCB_CONTROL::ShowEquFileTable, CVPCB_ACTIONS::showEquFileTable.MakeEvent() );
  245. Go( &CVPCB_CONTROL::SaveAssociations, CVPCB_ACTIONS::saveAssociations.MakeEvent() );
  246. // Navigation actions
  247. Go( &CVPCB_CONTROL::ToNA, CVPCB_ACTIONS::gotoNextNA.MakeEvent() );
  248. Go( &CVPCB_CONTROL::ToNA, CVPCB_ACTIONS::gotoPreviousNA.MakeEvent() );
  249. // Filter the footprints
  250. Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::FilterFPbyFPFilters.MakeEvent() );
  251. Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::FilterFPbyLibrary.MakeEvent() );
  252. Go( &CVPCB_CONTROL::ToggleFootprintFilter, CVPCB_ACTIONS::filterFPbyPin.MakeEvent() );
  253. }