1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/framecmn.cpp
3 // Purpose: common (for all platforms) wxFrame functions
4 // Author: Julian Smart, Vadim Zeitlin
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
20 #pragma implementation "framebase.h"
23 // For compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
33 #include "wx/menuitem.h"
34 #include "wx/dcclient.h"
38 #include "wx/toolbar.h"
41 #include "wx/statusbr.h"
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 BEGIN_EVENT_TABLE(wxFrameBase
, wxWindow
)
49 EVT_IDLE(wxFrameBase::OnIdle
)
50 EVT_CLOSE(wxFrameBase::OnCloseWindow
)
51 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
)
52 EVT_SIZE(wxFrameBase::OnSize
)
55 // ============================================================================
57 // ============================================================================
59 // ----------------------------------------------------------------------------
60 // construction/destruction
61 // ----------------------------------------------------------------------------
63 wxFrameBase::wxFrameBase()
66 m_frameMenuBar
= NULL
;
70 m_frameToolBar
= NULL
;
71 #endif // wxUSE_TOOLBAR
74 m_frameStatusBar
= NULL
;
75 #endif // wxUSE_STATUSBAR
78 bool wxFrameBase::Destroy()
80 // delayed destruction: the frame will be deleted during the next idle
82 if ( !wxPendingDelete
.Member(this) )
83 wxPendingDelete
.Append(this);
88 wxFrame
*wxFrameBase::New(wxWindow
*parent
,
90 const wxString
& title
,
96 return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
);
99 void wxFrameBase::DeleteAllBars()
102 if ( m_frameMenuBar
)
104 delete m_frameMenuBar
;
105 m_frameMenuBar
= (wxMenuBar
*) NULL
;
107 #endif // wxUSE_MENUS
110 if ( m_frameStatusBar
)
112 delete m_frameStatusBar
;
113 m_frameStatusBar
= (wxStatusBar
*) NULL
;
115 #endif // wxUSE_STATUSBAR
118 if ( m_frameToolBar
)
120 delete m_frameToolBar
;
121 m_frameToolBar
= (wxToolBar
*) NULL
;
123 #endif // wxUSE_TOOLBAR
126 bool wxFrameBase::IsOneOfBars(const wxWindow
*win
) const
129 if ( win
== GetMenuBar() )
131 #endif // wxUSE_MENUS
134 if ( win
== GetStatusBar() )
136 #endif // wxUSE_STATUSBAR
139 if ( win
== GetToolBar() )
141 #endif // wxUSE_TOOLBAR
146 // ----------------------------------------------------------------------------
147 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
148 // from the client area, so the client area is what's really available for the
150 // ----------------------------------------------------------------------------
152 // get the origin of the client area in the client coordinates
153 wxPoint
wxFrameBase::GetClientAreaOrigin() const
158 if ( GetToolBar() && GetToolBar()->IsShown() )
161 GetToolBar()->GetSize(& w
, & h
);
163 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
172 #endif // wxUSE_TOOLBAR
177 void wxFrameBase::DoScreenToClient(int *x
, int *y
) const
179 wxWindow::DoScreenToClient(x
, y
);
181 // We may be faking the client origin.
182 // So a window that's really at (0, 30) may appear
183 // (to wxWin apps) to be at (0, 0).
184 wxPoint
pt(GetClientAreaOrigin());
189 void wxFrameBase::DoClientToScreen(int *x
, int *y
) const
191 // We may be faking the client origin.
192 // So a window that's really at (0, 30) may appear
193 // (to wxWin apps) to be at (0, 0).
194 wxPoint
pt1(GetClientAreaOrigin());
198 wxWindow::DoClientToScreen(x
, y
);
201 // ----------------------------------------------------------------------------
203 // ----------------------------------------------------------------------------
205 // make the window modal (all other windows unresponsive)
206 void wxFrameBase::MakeModal(bool modal
)
210 wxEnableTopLevelWindows(FALSE
);
211 Enable(TRUE
); // keep this window enabled
215 wxEnableTopLevelWindows(TRUE
);
219 bool wxFrameBase::ProcessCommand(int id
)
222 wxMenuBar
*bar
= GetMenuBar();
226 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
227 commandEvent
.SetEventObject(this);
229 wxMenuItem
*item
= bar
->FindItem(id
);
230 if ( item
&& item
->IsCheckable() )
235 commandEvent
.SetInt(item
->IsChecked());
238 return GetEventHandler()->ProcessEvent(commandEvent
);
239 #else // !wxUSE_MENUS
241 #endif // wxUSE_MENUS/!wxUSE_MENUS
244 // ----------------------------------------------------------------------------
246 // ----------------------------------------------------------------------------
248 // default resizing behaviour - if only ONE subwindow, resize to fill the
250 void wxFrameBase::OnSize(wxSizeEvent
& WXUNUSED(event
))
252 // if we're using constraints - do use them
253 #if wxUSE_CONSTRAINTS
254 if ( GetAutoLayout() )
259 #endif // wxUSE_CONSTRAINTS
261 // do we have _exactly_ one child?
262 wxWindow
*child
= (wxWindow
*)NULL
;
263 for ( wxWindowList::Node
*node
= GetChildren().GetFirst();
265 node
= node
->GetNext() )
267 wxWindow
*win
= node
->GetData();
269 // exclude top level and managed windows (status bar isn't
270 // currently in the children list except under wxMac anyhow, but
271 // it makes no harm to test for it)
272 if ( !win
->IsTopLevel() && !IsOneOfBars(win
) )
276 return; // it's our second subwindow - nothing to do
283 // do we have any children at all?
286 // exactly one child - set it's size to fill the whole frame
287 int clientW
, clientH
;
288 DoGetClientSize(&clientW
, &clientH
);
290 // for whatever reasons, wxGTK wants to have a small offset - it
291 // probably looks better with it?
293 static const int ofs
= 1;
295 static const int ofs
= 0;
298 child
->SetSize(ofs
, ofs
, clientW
- 2*ofs
, clientH
- 2*ofs
);
303 // The default implementation for the close window event.
304 void wxFrameBase::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
309 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
)
312 (void)ShowMenuHelp(GetStatusBar(), event
.GetMenuId());
313 #endif // wxUSE_STATUSBAR
316 bool wxFrameBase::SendIconizeEvent(bool iconized
)
318 wxIconizeEvent
event(GetId(), iconized
);
319 event
.SetEventObject(this);
321 return GetEventHandler()->ProcessEvent(event
);
324 void wxFrameBase::OnIdle(wxIdleEvent
& WXUNUSED(event
) )
328 #endif // wxUSE_MENUS
331 // ----------------------------------------------------------------------------
333 // ----------------------------------------------------------------------------
337 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
,
340 const wxString
& name
)
342 // the main status bar can only be created once (or else it should be
343 // deleted before calling CreateStatusBar() again)
344 wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar
*)NULL
,
345 wxT("recreating status bar in wxFrame") );
347 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
348 if ( m_frameStatusBar
)
351 return m_frameStatusBar
;
354 wxStatusBar
*wxFrameBase::OnCreateStatusBar(int number
,
357 const wxString
& name
)
359 wxStatusBar
*statusBar
= new wxStatusBar(this, id
, style
, name
);
361 // Set the height according to the font and the border size
362 wxClientDC
dc(statusBar
);
363 dc
.SetFont(statusBar
->GetFont());
366 dc
.GetTextExtent( "X", NULL
, &y
);
368 int height
= (int)( (11*y
)/10 + 2*statusBar
->GetBorderY());
370 statusBar
->SetSize( -1, -1, -1, height
);
372 statusBar
->SetFieldsCount(number
);
377 void wxFrameBase::SetStatusText(const wxString
& text
, int number
)
379 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
381 m_frameStatusBar
->SetStatusText(text
, number
);
384 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] )
386 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
388 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
393 bool wxFrameBase::ShowMenuHelp(wxStatusBar
*statbar
, int menuId
)
399 // if no help string found, we will clear the status bar text
402 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
404 wxMenuBar
*menuBar
= GetMenuBar();
407 // it's ok if we don't find the item because it might belong
409 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
411 helpString
= item
->GetHelp();
415 // set status text even if the string is empty - this will at least
416 // remove the string from the item which was previously selected
417 statbar
->SetStatusText(helpString
);
419 return !helpString
.IsEmpty();
420 #else // !wxUSE_MENUS
422 #endif // wxUSE_MENUS/!wxUSE_MENUS
425 #endif // wxUSE_STATUSBAR
427 // ----------------------------------------------------------------------------
429 // ----------------------------------------------------------------------------
433 wxToolBar
* wxFrameBase::CreateToolBar(long style
,
435 const wxString
& name
)
437 // the main toolbar can't be recreated (unless it was explicitly deeleted
439 wxCHECK_MSG( !m_frameToolBar
, (wxToolBar
*)NULL
,
440 wxT("recreating toolbar in wxFrame") );
442 m_frameToolBar
= OnCreateToolBar(style
, id
, name
);
444 return m_frameToolBar
;
447 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
,
449 const wxString
& name
)
451 return new wxToolBar(this, id
,
452 wxDefaultPosition
, wxDefaultSize
,
456 #endif // wxUSE_TOOLBAR
458 // ----------------------------------------------------------------------------
460 // ----------------------------------------------------------------------------
465 void wxFrameBase::DoMenuUpdates()
467 wxMenuBar
* bar
= GetMenuBar();
470 wxWindow
* focusWin
= wxFindFocusDescendant((wxWindow
*) this);
472 wxWindow
* focusWin
= (wxWindow
*) NULL
;
476 int nCount
= bar
->GetMenuCount();
477 for (int n
= 0; n
< nCount
; n
++)
478 DoMenuUpdates(bar
->GetMenu(n
), focusWin
);
482 // update a menu and all submenus recursively
483 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
, wxWindow
* focusWin
)
485 wxEvtHandler
* evtHandler
= focusWin
? focusWin
->GetEventHandler() : GetEventHandler();
486 wxMenuItemList::Node
* node
= menu
->GetMenuItems().GetFirst();
489 wxMenuItem
* item
= node
->GetData();
490 if ( !item
->IsSeparator() )
492 wxWindowID id
= item
->GetId();
493 wxUpdateUIEvent
event(id
);
494 event
.SetEventObject( this );
496 if (evtHandler
->ProcessEvent(event
))
498 if (event
.GetSetText())
499 menu
->SetLabel(id
, event
.GetText());
500 if (event
.GetSetChecked())
501 menu
->Check(id
, event
.GetChecked());
502 if (event
.GetSetEnabled())
503 menu
->Enable(id
, event
.GetEnabled());
506 if (item
->GetSubMenu())
507 DoMenuUpdates(item
->GetSubMenu(), (wxWindow
*) NULL
);
509 node
= node
->GetNext();
513 void wxFrameBase::DetachMenuBar()
515 if ( m_frameMenuBar
)
517 m_frameMenuBar
->Detach();
518 m_frameMenuBar
= NULL
;
522 void wxFrameBase::AttachMenuBar(wxMenuBar
*menubar
)
526 m_frameMenuBar
= menubar
;
527 menubar
->Attach((wxFrame
*)this);
531 void wxFrameBase::SetMenuBar(wxMenuBar
*menubar
)
533 if ( menubar
== GetMenuBar() )
541 AttachMenuBar(menubar
);
544 #endif // wxUSE_MENUS