KiCad PCB EDA Suite
infobar.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Ian McInerney <ian.s.mcinerney@ieee.org>
5  * Copyright (C) 2020 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 
21 #include <id.h>
22 #include <widgets/infobar.h>
23 #include "wx/artprov.h"
24 #include <wx/aui/framemanager.h>
25 #include <wx/debug.h>
26 #include <wx/infobar.h>
27 #include <wx/sizer.h>
28 #include <wx/timer.h>
29 
30 
31 wxDEFINE_EVENT( KIEVT_SHOW_INFOBAR, wxCommandEvent );
32 wxDEFINE_EVENT( KIEVT_DISMISS_INFOBAR, wxCommandEvent );
33 
34 BEGIN_EVENT_TABLE( WX_INFOBAR, wxInfoBarGeneric )
35  EVT_COMMAND( wxID_ANY, KIEVT_SHOW_INFOBAR, WX_INFOBAR::OnShowInfoBar )
36  EVT_COMMAND( wxID_ANY, KIEVT_DISMISS_INFOBAR, WX_INFOBAR::OnDismissInfoBar )
37 
40 END_EVENT_TABLE()
41 
42 
43 WX_INFOBAR::WX_INFOBAR( wxWindow* aParent, wxAuiManager* aMgr, wxWindowID aWinid )
44  : wxInfoBarGeneric( aParent, aWinid ),
45  m_showTime( 0 ),
46  m_updateLock( false ),
47  m_showTimer( nullptr ),
48  m_auiManager( aMgr )
49 {
50  m_showTimer = new wxTimer( this, ID_CLOSE_INFOBAR );
51 
52  // Don't use any effects since they leave the sizer area visible under the infobar
53  SetShowHideEffects( wxSHOW_EFFECT_NONE, wxSHOW_EFFECT_NONE );
54 
55  // The infobar seems to start too small, so increase its height
56  int sx, sy;
57  GetSize( &sx, &sy );
58  sy = 1.5 * sy;
59  SetSize( sx, sy );
60 
61  // The bitmap gets cutoff sometimes with the default size, so force it to be the same
62  // height as the infobar.
63  wxSizer* sizer = GetSizer();
64  wxSize iconSize = wxArtProvider::GetSizeHint( wxART_BUTTON );
65 
66  sizer->SetItemMinSize( (size_t) 0, iconSize.x, sy );
67 
68  // Forcefully remove all existing buttons added by the wx constructors.
69  // The default close button doesn't work with the AUI manager update scheme, so this
70  // ensures any close button displayed is ours.
71  RemoveAllButtons();
72 
73  Layout();
74 }
75 
76 
78 {
79  delete m_showTimer;
80 }
81 
82 
83 void WX_INFOBAR::SetShowTime( int aTime )
84 {
85  m_showTime = aTime;
86 }
87 
88 
89 void WX_INFOBAR::QueueShowMessage( const wxString& aMessage, int aFlags )
90 {
91  wxCommandEvent* evt = new wxCommandEvent( KIEVT_SHOW_INFOBAR );
92 
93  evt->SetString( aMessage.c_str() );
94  evt->SetInt( aFlags );
95 
96  GetEventHandler()->QueueEvent( evt );
97 }
98 
99 
101 {
102  wxCommandEvent* evt = new wxCommandEvent( KIEVT_DISMISS_INFOBAR );
103 
104  GetEventHandler()->QueueEvent( evt );
105 }
106 
107 
108 void WX_INFOBAR::ShowMessageFor( const wxString& aMessage, int aTime, int aFlags )
109 {
110  // Don't do anything if we requested the UI update
111  if( m_updateLock )
112  return;
113 
114  m_showTime = aTime;
115  ShowMessage( aMessage, aFlags );
116 }
117 
118 
119 void WX_INFOBAR::ShowMessage( const wxString& aMessage, int aFlags )
120 {
121  // Don't do anything if we requested the UI update
122  if( m_updateLock )
123  return;
124 
125  m_updateLock = true;
126 
127  wxInfoBarGeneric::ShowMessage( aMessage, aFlags );
128 
129  if( m_auiManager )
130  UpdateAuiLayout( true );
131 
132  if( m_showTime > 0 )
133  m_showTimer->StartOnce( m_showTime );
134 
135  m_updateLock = false;
136 }
137 
138 
140 {
141  // Don't do anything if we requested the UI update
142  if( m_updateLock )
143  return;
144 
145  m_updateLock = true;
146 
147  wxInfoBarGeneric::Dismiss();
148 
149  if( m_auiManager )
150  UpdateAuiLayout( false );
151 
152  m_updateLock = false;
153 }
154 
155 
156 void WX_INFOBAR::UpdateAuiLayout( bool aShow )
157 {
158  wxASSERT( m_auiManager );
159 
160  wxAuiPaneInfo& pane = m_auiManager->GetPane( this );
161 
162  // If the infobar is in a pane, then show/hide the pane
163  if( pane.IsOk() )
164  {
165  if( aShow )
166  pane.Show();
167  else
168  pane.Hide();
169  }
170 
171  // Update the AUI manager regardless
172  m_auiManager->Update();
173 }
174 
175 
176 void WX_INFOBAR::AddButton( wxWindowID aId, const wxString& aLabel )
177 {
178  wxButton* button = new wxButton( this, aId, aLabel );
179 
180  AddButton( button );
181 }
182 
183 
184 void WX_INFOBAR::AddButton( wxButton* aButton )
185 {
186  wxSizer* sizer = GetSizer();
187 
188  wxASSERT( aButton );
189 
190 #ifdef __WXMAC__
191  // Based on the code in the original class:
192  // smaller buttons look better in the (narrow) info bar under OS X
193  aButton->SetWindowVariant( wxWINDOW_VARIANT_SMALL );
194 #endif // __WXMAC__
195  sizer->Add( aButton, wxSizerFlags().Centre().Border( wxRIGHT ) );
196 
197  if( IsShown() )
198  sizer->Layout();
199 }
200 
201 
202 void WX_INFOBAR::AddCloseButton( const wxString& aTooltip )
203 {
204  wxBitmapButton* button = wxBitmapButton::NewCloseButton( this, ID_CLOSE_INFOBAR );
205 
206  button->SetToolTip( aTooltip );
207 
208  AddButton( button );
209 }
210 
211 
213 {
214  wxSizer* sizer = GetSizer();
215 
216  if( sizer->GetItemCount() == 0 )
217  return;
218 
219  // The last item is already the spacer
220  if( sizer->GetItem( sizer->GetItemCount() - 1 )->IsSpacer() )
221  return;
222 
223  for( int i = sizer->GetItemCount() - 1; i >= 0; i-- )
224  {
225  wxSizerItem* sItem = sizer->GetItem( i );
226 
227  // The spacer is the end of the custom buttons
228  if( sItem->IsSpacer() )
229  break;
230 
231  delete sItem->GetWindow();
232  }
233 }
234 
235 
236 void WX_INFOBAR::OnShowInfoBar( wxCommandEvent& aEvent )
237 {
239  AddCloseButton();
240  ShowMessage( aEvent.GetString(), aEvent.GetInt() );
241 }
242 
243 
244 void WX_INFOBAR::OnDismissInfoBar( wxCommandEvent& aEvent )
245 {
246  Dismiss();
247 }
248 
249 
250 void WX_INFOBAR::OnCloseButton( wxCommandEvent& aEvent )
251 {
252  Dismiss();
253 }
254 
255 
256 void WX_INFOBAR::OnTimer( wxTimerEvent& aEvent )
257 {
258  // Reset and clear the timer
259  m_showTimer->Stop();
260  m_showTime = 0;
261 
262  Dismiss();
263 }
264 
265 
266 EDA_INFOBAR_PANEL::EDA_INFOBAR_PANEL( wxWindow* aParent, wxWindowID aId, const wxPoint& aPos,
267  const wxSize& aSize, long aStyle, const wxString& aName )
268  : wxPanel( aParent, aId, aPos, aSize, aStyle, aName )
269 {
270  m_mainSizer = new wxFlexGridSizer( 1, 0, 0 );
271 
272  m_mainSizer->SetFlexibleDirection( wxBOTH );
273  m_mainSizer->AddGrowableCol( 0, 1 );
274 
275  SetSizer( m_mainSizer );
276 }
277 
278 
280 {
281  wxASSERT( aInfoBar );
282 
283  aInfoBar->Reparent( this );
284  m_mainSizer->Add( aInfoBar, 1, wxEXPAND, 0 );
285  m_mainSizer->Layout();
286 }
287 
288 
289 void EDA_INFOBAR_PANEL::AddOtherItem( wxWindow* aOtherItem )
290 {
291  wxASSERT( aOtherItem );
292 
293  aOtherItem->Reparent( this );
294  m_mainSizer->Add( aOtherItem, 1, wxEXPAND, 0 );
295 
296  m_mainSizer->AddGrowableRow( 1, 1 );
297  m_mainSizer->Layout();
298 }
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION)
Show the infobar with the provided message and icon for a specific period of time.
Definition: infobar.cpp:108
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: infobar.cpp:119
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: infobar.cpp:184
wxTimer * m_showTimer
The timer counting the autoclose period.
Definition: infobar.h:193
void OnDismissInfoBar(wxCommandEvent &aEvent)
Event handler for dismissing the infobar using a wxCommandEvent of the type KIEVT_DISMISS_INFOBAR.
Definition: infobar.cpp:244
~WX_INFOBAR()
Definition: infobar.cpp:77
wxDEFINE_EVENT(KIEVT_SHOW_INFOBAR, wxCommandEvent)
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: infobar.cpp:139
void AddOtherItem(wxWindow *aOtherItem)
Add the other item to the panel.
Definition: infobar.cpp:289
void OnShowInfoBar(wxCommandEvent &aEvent)
Event handler for showing the infobar using a wxCommandEvent of the type KIEVT_SHOW_INFOBAR.
Definition: infobar.cpp:236
void OnTimer(wxTimerEvent &aEvent)
Event handler for the automatic closing timer.
Definition: infobar.cpp:256
ID for the close button on the frame's infobar.
Definition: infobar.h:34
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:212
void QueueShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION)
Send the infobar an event telling it to show a message.
Definition: infobar.cpp:89
A modified version of the wxInfoBar class that allows us to:
Definition: infobar.h:68
void SetShowTime(int aTime)
Set the time period to show the infobar.
Definition: infobar.cpp:83
void QueueDismiss()
Send the infobar an event telling it to hide itself.
Definition: infobar.cpp:100
void OnCloseButton(wxCommandEvent &aEvent)
Event handler for the close button.
Definition: infobar.cpp:250
wxFlexGridSizer * m_mainSizer
Definition: infobar.h:240
EDA_INFOBAR_PANEL(wxWindow *aParent, wxWindowID aId=wxID_ANY, const wxPoint &aPos=wxDefaultPosition, const wxSize &aSize=wxSize(-1,-1), long aStyle=wxTAB_TRAVERSAL, const wxString &aName=wxEmptyString)
Definition: infobar.cpp:266
wxAuiManager * m_auiManager
The AUI manager that contains this infobar.
Definition: infobar.h:194
bool m_updateLock
True if this infobar requested the UI update.
Definition: infobar.h:192
void AddInfoBar(WX_INFOBAR *aInfoBar)
Add the given infobar object to the panel.
Definition: infobar.cpp:279
void UpdateAuiLayout(bool aShow)
Update the AUI pane to show or hide this infobar.
Definition: infobar.cpp:156
int m_showTime
The time to show the infobar. 0 = don't auto hide.
Definition: infobar.h:191
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: infobar.cpp:202