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.

124 lines
4.0 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <dialogs/hotkey_cycle_popup.h>
  24. #include <eda_draw_frame.h>
  25. #ifdef __WXGTK__
  26. #define LIST_BOX_H_PADDING 20
  27. #define LIST_BOX_V_PADDING 8
  28. #elif __WXMAC__
  29. #define LIST_BOX_H_PADDING 40
  30. #define LIST_BOX_V_PADDING 5
  31. #else
  32. #define LIST_BOX_H_PADDING 10
  33. #define LIST_BOX_V_PADDING 5
  34. #endif
  35. #define SHOW_TIME_MS 500
  36. HOTKEY_CYCLE_POPUP::HOTKEY_CYCLE_POPUP( EDA_DRAW_FRAME* aParent ) :
  37. EDA_VIEW_SWITCHER_BASE( aParent ),
  38. m_drawFrame( aParent )
  39. {
  40. m_showTimer = new wxTimer( this );
  41. Bind( wxEVT_TIMER, [&]( wxTimerEvent& ) { Show( false ); m_drawFrame->GetCanvas()->SetFocus(); },
  42. m_showTimer->GetId() );
  43. // On macOS, we can't change focus to the canvas before sending the event, so the key events
  44. // just get discarded via the "don't steal from an input control" logic. So, set this input
  45. // control with a special flag because we really do want to steal from it.
  46. m_listBox->SetName( KIUI::s_FocusStealableInputName );
  47. #ifdef __WXOSX__
  48. m_listBox->Bind( wxEVT_CHAR_HOOK,
  49. [=, this]( wxKeyEvent& aEvent )
  50. {
  51. aEvent.SetEventType( wxEVT_CHAR );
  52. m_drawFrame->GetCanvas()->SetFocus();
  53. m_drawFrame->GetCanvas()->OnEvent( aEvent );
  54. } );
  55. #endif
  56. }
  57. HOTKEY_CYCLE_POPUP::~HOTKEY_CYCLE_POPUP()
  58. {
  59. delete m_showTimer;
  60. }
  61. void HOTKEY_CYCLE_POPUP::Popup( const wxString& aTitle, const wxArrayString& aItems,
  62. int aSelection )
  63. {
  64. m_stTitle->SetLabel( aTitle );
  65. m_listBox->Clear();
  66. m_listBox->InsertItems( aItems, 0 );
  67. m_listBox->SetSelection( std::min( aSelection,
  68. static_cast<int>( m_listBox->GetCount() ) - 1 ) );
  69. int width = m_stTitle->GetTextExtent( aTitle ).x;
  70. int height = 0;
  71. for( const wxString& item : aItems )
  72. {
  73. wxSize extents = m_listBox->GetTextExtent( item );
  74. width = std::max( width, extents.x );
  75. height += extents.y + LIST_BOX_V_PADDING;
  76. }
  77. m_listBox->SetMinSize( wxSize( width + LIST_BOX_H_PADDING,
  78. height + ( LIST_BOX_V_PADDING * 2 ) ) );
  79. // this line fixes an issue on Linux Ubuntu using Unity (dialog not shown),
  80. // and works fine on all systems
  81. GetSizer()->Fit( this );
  82. if( m_showTimer->IsRunning() )
  83. {
  84. m_showTimer->StartOnce( SHOW_TIME_MS );
  85. SetFocus();
  86. return;
  87. }
  88. m_showTimer->StartOnce( SHOW_TIME_MS );
  89. Show( true );
  90. Centre();
  91. SetFocus();
  92. }
  93. bool HOTKEY_CYCLE_POPUP::TryBefore( wxEvent& aEvent )
  94. {
  95. if( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
  96. {
  97. aEvent.SetEventType( wxEVT_CHAR );
  98. //m_drawFrame->GetCanvas()->SetFocus(); // on GTK causes focus flicker and is not needed
  99. m_drawFrame->GetCanvas()->OnEvent( aEvent );
  100. return true;
  101. }
  102. return EDA_VIEW_SWITCHER_BASE::TryBefore( aEvent );
  103. }