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"
32 #include "wx/menuitem.h"
33 #include "wx/dcclient.h"
36 #include "wx/toolbar.h"
39 #include "wx/statusbr.h"
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 BEGIN_EVENT_TABLE(wxFrameBase
, wxWindow
)
47 EVT_IDLE(wxFrameBase::OnIdle
)
48 EVT_CLOSE(wxFrameBase::OnCloseWindow
)
49 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
)
50 EVT_SIZE(wxFrameBase::OnSize
)
53 // ============================================================================
55 // ============================================================================
57 // ----------------------------------------------------------------------------
58 // construction/destruction
59 // ----------------------------------------------------------------------------
61 wxFrameBase::wxFrameBase()
63 m_frameMenuBar
= NULL
;
66 m_frameToolBar
= NULL
;
67 #endif // wxUSE_TOOLBAR
70 m_frameStatusBar
= NULL
;
71 #endif // wxUSE_STATUSBAR
74 bool wxFrameBase::Destroy()
76 // delayed destruction: the frame will be deleted during the next idle
78 if ( !wxPendingDelete
.Member(this) )
79 wxPendingDelete
.Append(this);
84 wxFrame
*wxFrameBase::New(wxWindow
*parent
,
86 const wxString
& title
,
92 return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
);
95 void wxFrameBase::DeleteAllBars()
99 delete m_frameMenuBar
;
100 m_frameMenuBar
= (wxMenuBar
*) NULL
;
104 if ( m_frameStatusBar
)
106 delete m_frameStatusBar
;
107 m_frameStatusBar
= (wxStatusBar
*) NULL
;
109 #endif // wxUSE_STATUSBAR
112 if ( m_frameToolBar
)
114 delete m_frameToolBar
;
115 m_frameToolBar
= (wxToolBar
*) NULL
;
117 #endif // wxUSE_TOOLBAR
120 // ----------------------------------------------------------------------------
121 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
122 // from the client area, so the client area is what's really available for the
124 // ----------------------------------------------------------------------------
126 // get the origin of the client area in the client coordinates
127 wxPoint
wxFrameBase::GetClientAreaOrigin() const
135 GetToolBar()->GetSize(& w
, & h
);
137 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
146 #endif // wxUSE_TOOLBAR
151 void wxFrameBase::DoScreenToClient(int *x
, int *y
) const
153 wxWindow::DoScreenToClient(x
, y
);
155 // We may be faking the client origin.
156 // So a window that's really at (0, 30) may appear
157 // (to wxWin apps) to be at (0, 0).
158 wxPoint
pt(GetClientAreaOrigin());
163 void wxFrameBase::DoClientToScreen(int *x
, int *y
) const
165 // We may be faking the client origin.
166 // So a window that's really at (0, 30) may appear
167 // (to wxWin apps) to be at (0, 0).
168 wxPoint
pt1(GetClientAreaOrigin());
172 wxWindow::DoClientToScreen(x
, y
);
175 // ----------------------------------------------------------------------------
177 // ----------------------------------------------------------------------------
179 // make the window modal (all other windows unresponsive)
180 void wxFrameBase::MakeModal(bool modal
)
184 wxEnableTopLevelWindows(FALSE
);
185 Enable(TRUE
); // keep this window enabled
189 wxEnableTopLevelWindows(TRUE
);
193 bool wxFrameBase::ProcessCommand(int id
)
195 wxMenuBar
*bar
= GetMenuBar();
199 wxMenuItem
*item
= bar
->FindItem(id
);
200 if ( item
&& item
->IsCheckable() )
205 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
206 commandEvent
.SetInt(id
);
207 commandEvent
.SetEventObject(this);
209 return GetEventHandler()->ProcessEvent(commandEvent
);
212 // ----------------------------------------------------------------------------
214 // ----------------------------------------------------------------------------
216 // default resizing behaviour - if only ONE subwindow, resize to fill the
218 void wxFrameBase::OnSize(wxSizeEvent
& event
)
220 // if we're using constraints - do use them
221 #if wxUSE_CONSTRAINTS
222 if ( GetAutoLayout() )
229 // do we have _exactly_ one child?
230 wxWindow
*child
= (wxWindow
*)NULL
;
231 for ( wxWindowList::Node
*node
= GetChildren().GetFirst();
233 node
= node
->GetNext() )
235 wxWindow
*win
= node
->GetData();
237 // exclude top level and managed windows (status bar isn't
238 // currently in the children list except under wxMac anyhow, but
239 // it makes no harm to test for it)
240 if ( !win
->IsTopLevel()
242 && (win
!= GetStatusBar())
243 #endif // wxUSE_STATUSBAR
245 && (win
!= GetToolBar())
246 #endif // wxUSE_TOOLBAR
251 return; // it's our second subwindow - nothing to do
258 // do we have any children at all?
261 // exactly one child - set it's size to fill the whole frame
262 int clientW
, clientH
;
263 DoGetClientSize(&clientW
, &clientH
);
265 // for whatever reasons, wxGTK wants to have a small offset - it
266 // probably looks better with it?
268 static const int ofs
= 0;
270 static const int ofs
= 1;
273 child
->SetSize(ofs
, ofs
, clientW
- 2*ofs
, clientH
- 2*ofs
);
278 // The default implementation for the close window event.
279 void wxFrameBase::OnCloseWindow(wxCloseEvent
& event
)
284 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
)
287 if ( GetStatusBar() )
289 // if no help string found, we will clear the status bar text
292 int menuId
= event
.GetMenuId();
293 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
295 wxMenuBar
*menuBar
= GetMenuBar();
298 // it's ok if we don't find the item because it might belong
300 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
302 helpString
= item
->GetHelp();
306 // set status text even if the string is empty - this will at least
307 // remove the string from the item which was previously selected
308 SetStatusText(helpString
);
310 #endif // wxUSE_STATUSBAR
313 // ----------------------------------------------------------------------------
315 // ----------------------------------------------------------------------------
319 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
,
322 const wxString
& name
)
324 // the main status bar can only be created once (or else it should be
325 // deleted before calling CreateStatusBar() again)
326 wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar
*)NULL
,
327 wxT("recreating status bar in wxFrame") );
329 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
330 if ( m_frameStatusBar
)
333 return m_frameStatusBar
;
336 wxStatusBar
*wxFrameBase::OnCreateStatusBar(int number
,
339 const wxString
& name
)
341 wxStatusBar
*statusBar
= new wxStatusBar(this, id
,
342 wxPoint(0, 0), wxSize(100, 20),
345 // Set the height according to the font and the border size
346 wxClientDC
dc(statusBar
);
347 dc
.SetFont(statusBar
->GetFont());
350 dc
.GetTextExtent( "X", NULL
, &y
);
352 int height
= (int)( (11*y
)/10 + 2*statusBar
->GetBorderY());
354 statusBar
->SetSize( -1, -1, 100, height
);
356 statusBar
->SetFieldsCount(number
);
361 void wxFrameBase::SetStatusText(const wxString
& text
, int number
)
363 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
365 m_frameStatusBar
->SetStatusText(text
, number
);
368 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] )
370 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
372 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
377 #endif // wxUSE_STATUSBAR
379 // ----------------------------------------------------------------------------
381 // ----------------------------------------------------------------------------
385 wxToolBar
* wxFrameBase::CreateToolBar(long style
,
387 const wxString
& name
)
389 // the main toolbar can't be recreated (unless it was explicitly deeleted
391 wxCHECK_MSG( !m_frameToolBar
, (wxToolBar
*)NULL
,
392 wxT("recreating toolbar in wxFrame") );
394 m_frameToolBar
= OnCreateToolBar(style
, id
, name
);
396 return m_frameToolBar
;
399 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
,
401 const wxString
& name
)
403 return new wxToolBar(this, id
,
404 wxDefaultPosition
, wxDefaultSize
,
408 #endif // wxUSE_TOOLBAR
410 // ----------------------------------------------------------------------------
412 // ----------------------------------------------------------------------------
414 void wxFrameBase::OnIdle(wxIdleEvent
& WXUNUSED(event
) )
420 void wxFrameBase::DoMenuUpdates()
422 wxMenuBar
* bar
= GetMenuBar();
426 int nCount
= bar
->GetMenuCount();
427 for (int n
= 0; n
< nCount
; n
++)
428 DoMenuUpdates(bar
->GetMenu(n
), (wxWindow
*) NULL
);
432 // update a menu and all submenus recursively
433 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
, wxWindow
* WXUNUSED(focusWin
))
435 wxEvtHandler
* evtHandler
= GetEventHandler();
436 wxMenuItemList::Node
* node
= menu
->GetMenuItems().GetFirst();
439 wxMenuItem
* item
= node
->GetData();
440 if ( !item
->IsSeparator() )
442 wxWindowID id
= item
->GetId();
443 wxUpdateUIEvent
event(id
);
444 event
.SetEventObject( this );
446 if (evtHandler
->ProcessEvent(event
))
448 if (event
.GetSetText())
449 menu
->SetLabel(id
, event
.GetText());
450 if (event
.GetSetChecked())
451 menu
->Check(id
, event
.GetChecked());
452 if (event
.GetSetEnabled())
453 menu
->Enable(id
, event
.GetEnabled());
456 if (item
->GetSubMenu())
457 DoMenuUpdates(item
->GetSubMenu(), (wxWindow
*) NULL
);
459 node
= node
->GetNext();