1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/frame.cpp
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #include "wx/toolbar.h"
18 #include "wx/statusbr.h"
23 // ----------------------------------------------------------------------------
25 // ----------------------------------------------------------------------------
27 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxTopLevelWindow
)
29 // ============================================================================
31 // ============================================================================
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
42 bool wxFrame::Create( wxWindow
*parent
,
44 const wxString
& title
,
46 const wxSize
& sizeOrig
,
48 const wxString
&name
)
50 return wxFrameBase::Create(parent
, id
, title
, pos
, sizeOrig
, style
, name
);
55 m_isBeingDeleted
= true;
59 // ----------------------------------------------------------------------------
60 // overridden wxWindow methods
61 // ----------------------------------------------------------------------------
63 void wxFrame::DoGetClientSize( int *width
, int *height
) const
65 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
67 wxFrameBase::DoGetClientSize(width
, height
);
71 #if wxUSE_MENUS_NATIVE
73 if (m_frameMenuBar
&& m_frameMenuBar
->IsShown())
76 gtk_widget_size_request(m_frameMenuBar
->m_widget
, &req
);
77 *height
-= req
.height
;
79 #endif // wxUSE_MENUS_NATIVE
83 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
84 *height
-= m_frameStatusBar
->m_height
;
85 #endif // wxUSE_STATUSBAR
90 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
93 gtk_widget_size_request(m_frameToolBar
->m_widget
, &req
);
94 if (m_frameToolBar
->IsVertical())
102 *height
-= req
.height
;
105 #endif // wxUSE_TOOLBAR
107 if (width
!= NULL
&& *width
< 0)
109 if (height
!= NULL
&& *height
< 0)
114 // Helper for wxCreateAcceleratorTableForMenuBar
115 static void wxAddAccelerators(wxList
& accelEntries
, wxMenu
* menu
)
118 for (i
= 0; i
< menu
->GetMenuItems().GetCount(); i
++)
120 wxMenuItem
* item
= (wxMenuItem
*) menu
->GetMenuItems().Item(i
)->GetData();
121 if (item
->GetSubMenu())
123 wxAddAccelerators(accelEntries
, item
->GetSubMenu());
125 else if (!item
->GetItemLabel().IsEmpty())
127 wxAcceleratorEntry
* entry
= wxAcceleratorEntry::Create(item
->GetItemLabel());
130 entry
->Set(entry
->GetFlags(), entry
->GetKeyCode(), item
->GetId());
131 accelEntries
.Append((wxObject
*) entry
);
137 // Create an accelerator table consisting of all the accelerators
138 // from the menubar in the given menus
139 static wxAcceleratorTable
wxCreateAcceleratorTableForMenuBar(wxMenuBar
* menuBar
)
144 for (i
= 0; i
< menuBar
->GetMenuCount(); i
++)
146 wxAddAccelerators(accelEntries
, menuBar
->GetMenu(i
));
149 size_t n
= accelEntries
.GetCount();
152 return wxAcceleratorTable();
154 wxAcceleratorEntry
* entries
= new wxAcceleratorEntry
[n
];
156 for (i
= 0; i
< accelEntries
.GetCount(); i
++)
158 wxAcceleratorEntry
* entry
= (wxAcceleratorEntry
*) accelEntries
.Item(i
)->GetData();
159 entries
[i
] = (*entry
);
164 wxAcceleratorTable
table(n
, entries
);
171 bool wxFrame::ShowFullScreen(bool show
, long style
)
173 if (!wxFrameBase::ShowFullScreen(show
, style
))
177 if (show
&& GetMenuBar())
179 wxAcceleratorTable
table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
181 SetAcceleratorTable(table
);
185 wxWindow
* const bar
[] = {
202 const long fsNoBar
[] = {
203 wxFULLSCREEN_NOMENUBAR
, wxFULLSCREEN_NOTOOLBAR
, wxFULLSCREEN_NOSTATUSBAR
205 for (int i
= 0; i
< 3; i
++)
209 if (bar
[i
] && (style
& fsNoBar
[i
]))
211 if (bar
[i
]->IsShown())
214 style
&= ~fsNoBar
[i
];
219 if (bar
[i
] && (m_fsSaveFlag
& fsNoBar
[i
]))
224 m_fsSaveFlag
= style
;
229 void wxFrame::OnInternalIdle()
231 wxFrameBase::OnInternalIdle();
233 #if wxUSE_MENUS_NATIVE
234 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
235 #endif // wxUSE_MENUS_NATIVE
237 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
240 if (m_frameStatusBar
)
242 m_frameStatusBar
->OnInternalIdle();
244 // There may be controls in the status bar that
245 // need to be updated
246 for ( wxWindowList::compatibility_iterator node
= m_frameStatusBar
->GetChildren().GetFirst();
248 node
= node
->GetNext() )
250 wxWindow
*child
= node
->GetData();
251 child
->OnInternalIdle();
257 // ----------------------------------------------------------------------------
258 // menu/tool/status bar stuff
259 // ----------------------------------------------------------------------------
261 #if wxUSE_MENUS_NATIVE
263 void wxFrame::DetachMenuBar()
265 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
266 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
268 if ( m_frameMenuBar
)
270 m_frameMenuBar
->UnsetInvokingWindow( this );
272 gtk_widget_ref( m_frameMenuBar
->m_widget
);
274 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
277 wxFrameBase::DetachMenuBar();
279 // make sure next size_allocate causes a wxSizeEvent
280 m_oldClientWidth
= 0;
283 void wxFrame::AttachMenuBar( wxMenuBar
*menuBar
)
285 wxFrameBase::AttachMenuBar(menuBar
);
289 m_frameMenuBar
->SetInvokingWindow( this );
291 m_frameMenuBar
->SetParent(this);
293 // menubar goes into top of vbox (m_mainWidget)
295 GTK_BOX(m_mainWidget
), menuBar
->m_widget
, false, false, 0);
296 gtk_box_reorder_child(GTK_BOX(m_mainWidget
), menuBar
->m_widget
, 0);
298 // disconnect wxWindowGTK "size_request" handler,
299 // it interferes with sizing of detached GtkHandleBox
300 gulong handler_id
= g_signal_handler_find(
302 GSignalMatchType(G_SIGNAL_MATCH_ID
| G_SIGNAL_MATCH_DATA
),
303 g_signal_lookup("size_request", GTK_TYPE_WIDGET
),
304 0, NULL
, NULL
, menuBar
);
306 g_signal_handler_disconnect(menuBar
->m_widget
, handler_id
);
308 // reset size request to allow native sizing to work
309 gtk_widget_set_size_request(menuBar
->m_widget
, -1, -1);
311 gtk_widget_show( m_frameMenuBar
->m_widget
);
313 // make sure next size_allocate causes a wxSizeEvent
314 m_oldClientWidth
= 0;
316 #endif // wxUSE_MENUS_NATIVE
320 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
322 m_frameToolBar
= toolbar
;
325 if (toolbar
->IsVertical())
327 // Vertical toolbar and m_wxwindow go into an hbox, inside the
328 // vbox (m_mainWidget). hbox is created on demand.
329 GtkWidget
* hbox
= m_wxwindow
->parent
;
330 if (!GTK_IS_HBOX(hbox
))
332 hbox
= gtk_hbox_new(false, 0);
333 gtk_widget_show(hbox
);
334 gtk_container_add(GTK_CONTAINER(m_mainWidget
), hbox
);
335 gtk_widget_reparent(m_wxwindow
, hbox
);
337 gtk_widget_reparent(toolbar
->m_widget
, hbox
);
338 gtk_box_set_child_packing(GTK_BOX(hbox
),
339 toolbar
->m_widget
, false, false, 0, GTK_PACK_START
);
342 if (toolbar
->HasFlag(wxTB_RIGHT
))
344 gtk_box_reorder_child(GTK_BOX(hbox
), toolbar
->m_widget
, pos
);
348 // Horizontal toolbar goes into vbox (m_mainWidget)
349 gtk_widget_reparent(toolbar
->m_widget
, m_mainWidget
);
350 gtk_box_set_child_packing(GTK_BOX(m_mainWidget
),
351 toolbar
->m_widget
, false, false, 0, GTK_PACK_START
);
355 pos
= 1; // below menubar
356 if (toolbar
->HasFlag(wxTB_BOTTOM
))
357 pos
+= 2; // below client area (m_wxwindow)
358 gtk_box_reorder_child(
359 GTK_BOX(m_mainWidget
), toolbar
->m_widget
, pos
);
362 // disconnect wxWindowGTK "size_request" handler,
363 // it interferes with sizing of detached GtkHandleBox
364 gulong handler_id
= g_signal_handler_find(
366 GSignalMatchType(G_SIGNAL_MATCH_ID
| G_SIGNAL_MATCH_DATA
),
367 g_signal_lookup("size_request", GTK_TYPE_WIDGET
),
368 0, NULL
, NULL
, toolbar
);
370 g_signal_handler_disconnect(toolbar
->m_widget
, handler_id
);
372 // reset size request to allow native sizing to work
373 gtk_widget_set_size_request(toolbar
->m_widget
, -1, -1);
375 // make sure next size_allocate causes a wxSizeEvent
376 m_oldClientWidth
= 0;
379 #endif // wxUSE_TOOLBAR
383 void wxFrame::SetStatusBar(wxStatusBar
*statbar
)
385 m_frameStatusBar
= statbar
;
388 // statusbar goes into bottom of vbox (m_mainWidget)
389 gtk_widget_reparent(statbar
->m_widget
, m_mainWidget
);
390 gtk_box_set_child_packing(GTK_BOX(m_mainWidget
),
391 statbar
->m_widget
, false, false, 0, GTK_PACK_END
);
392 // make sure next size_allocate on statusbar causes a size event
393 statbar
->m_oldClientWidth
= 0;
395 // make sure next size_allocate causes a wxSizeEvent
396 m_oldClientWidth
= 0;
398 #endif // wxUSE_STATUSBAR