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"
24 #include <hildon-widgets/hildon-window.h>
25 #endif // wxUSE_LIBHILDON
28 #include <hildon/hildon.h>
29 #endif // wxUSE_LIBHILDON2
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
35 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxTopLevelWindow
)
37 // ============================================================================
39 // ============================================================================
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
50 bool wxFrame::Create( wxWindow
*parent
,
52 const wxString
& title
,
54 const wxSize
& sizeOrig
,
56 const wxString
&name
)
58 return wxFrameBase::Create(parent
, id
, title
, pos
, sizeOrig
, style
, name
);
68 // ----------------------------------------------------------------------------
69 // overridden wxWindow methods
70 // ----------------------------------------------------------------------------
72 void wxFrame::DoGetClientSize( int *width
, int *height
) const
74 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
76 wxFrameBase::DoGetClientSize(width
, height
);
80 #if wxUSE_MENUS_NATIVE
82 if (m_frameMenuBar
&& m_frameMenuBar
->IsShown())
85 gtk_widget_size_request(m_frameMenuBar
->m_widget
, &req
);
86 #if !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
87 *height
-= req
.height
;
90 #endif // wxUSE_MENUS_NATIVE
94 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
95 *height
-= m_frameStatusBar
->m_height
;
96 #endif // wxUSE_STATUSBAR
101 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
104 gtk_widget_size_request(m_frameToolBar
->m_widget
, &req
);
105 if (m_frameToolBar
->IsVertical())
113 *height
-= req
.height
;
116 #endif // wxUSE_TOOLBAR
118 if (width
!= NULL
&& *width
< 0)
120 if (height
!= NULL
&& *height
< 0)
124 #if wxUSE_MENUS && wxUSE_ACCEL
125 // Helper for wxCreateAcceleratorTableForMenuBar
126 static void wxAddAccelerators(wxList
& accelEntries
, wxMenu
* menu
)
129 for (i
= 0; i
< menu
->GetMenuItems().GetCount(); i
++)
131 wxMenuItem
* item
= (wxMenuItem
*) menu
->GetMenuItems().Item(i
)->GetData();
132 if (item
->GetSubMenu())
134 wxAddAccelerators(accelEntries
, item
->GetSubMenu());
136 else if (!item
->GetItemLabel().IsEmpty())
138 wxAcceleratorEntry
* entry
= wxAcceleratorEntry::Create(item
->GetItemLabel());
141 entry
->Set(entry
->GetFlags(), entry
->GetKeyCode(), item
->GetId());
142 accelEntries
.Append((wxObject
*) entry
);
148 // Create an accelerator table consisting of all the accelerators
149 // from the menubar in the given menus
150 static wxAcceleratorTable
wxCreateAcceleratorTableForMenuBar(wxMenuBar
* menuBar
)
155 for (i
= 0; i
< menuBar
->GetMenuCount(); i
++)
157 wxAddAccelerators(accelEntries
, menuBar
->GetMenu(i
));
160 size_t n
= accelEntries
.GetCount();
163 return wxAcceleratorTable();
165 wxAcceleratorEntry
* entries
= new wxAcceleratorEntry
[n
];
167 for (i
= 0; i
< accelEntries
.GetCount(); i
++)
169 wxAcceleratorEntry
* entry
= (wxAcceleratorEntry
*) accelEntries
.Item(i
)->GetData();
170 entries
[i
] = (*entry
);
175 wxAcceleratorTable
table(n
, entries
);
180 #endif // wxUSE_MENUS && wxUSE_ACCEL
182 bool wxFrame::ShowFullScreen(bool show
, long style
)
184 if (!wxFrameBase::ShowFullScreen(show
, style
))
187 #if wxUSE_MENUS && wxUSE_ACCEL
188 if (show
&& GetMenuBar())
190 wxAcceleratorTable
table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
192 SetAcceleratorTable(table
);
194 #endif // wxUSE_MENUS && wxUSE_ACCEL
196 wxWindow
* const bar
[] = {
213 const long fsNoBar
[] = {
214 wxFULLSCREEN_NOMENUBAR
, wxFULLSCREEN_NOTOOLBAR
, wxFULLSCREEN_NOSTATUSBAR
216 for (int i
= 0; i
< 3; i
++)
220 if (bar
[i
] && (style
& fsNoBar
[i
]))
222 if (bar
[i
]->IsShown())
225 style
&= ~fsNoBar
[i
];
230 if (bar
[i
] && (m_fsSaveFlag
& fsNoBar
[i
]))
235 m_fsSaveFlag
= style
;
240 void wxFrame::OnInternalIdle()
242 wxFrameBase::OnInternalIdle();
244 #if wxUSE_MENUS_NATIVE
245 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
246 #endif // wxUSE_MENUS_NATIVE
248 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
251 if (m_frameStatusBar
)
253 m_frameStatusBar
->OnInternalIdle();
255 // There may be controls in the status bar that
256 // need to be updated
257 for ( wxWindowList::compatibility_iterator node
= m_frameStatusBar
->GetChildren().GetFirst();
259 node
= node
->GetNext() )
261 wxWindow
*child
= node
->GetData();
262 child
->OnInternalIdle();
268 // ----------------------------------------------------------------------------
269 // menu/tool/status bar stuff
270 // ----------------------------------------------------------------------------
272 #if wxUSE_MENUS_NATIVE
274 void wxFrame::DetachMenuBar()
276 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
277 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
279 if ( m_frameMenuBar
)
281 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
282 hildon_window_set_menu(HILDON_WINDOW(m_widget
), NULL
);
283 #else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
284 m_frameMenuBar
->UnsetInvokingWindow( this );
286 gtk_widget_ref( m_frameMenuBar
->m_widget
);
288 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
289 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
292 wxFrameBase::DetachMenuBar();
294 // make sure next size_allocate causes a wxSizeEvent
295 m_oldClientWidth
= 0;
298 void wxFrame::AttachMenuBar( wxMenuBar
*menuBar
)
300 wxFrameBase::AttachMenuBar(menuBar
);
304 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
305 hildon_window_set_menu(HILDON_WINDOW(m_widget
),
306 GTK_MENU(m_frameMenuBar
->m_menubar
));
307 #else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
308 m_frameMenuBar
->SetInvokingWindow( this );
310 m_frameMenuBar
->SetParent(this);
312 // menubar goes into top of vbox (m_mainWidget)
314 GTK_BOX(m_mainWidget
), menuBar
->m_widget
, false, false, 0);
315 gtk_box_reorder_child(GTK_BOX(m_mainWidget
), menuBar
->m_widget
, 0);
317 // disconnect wxWindowGTK "size_request" handler,
318 // it interferes with sizing of detached GtkHandleBox
319 gulong handler_id
= g_signal_handler_find(
321 GSignalMatchType(G_SIGNAL_MATCH_ID
| G_SIGNAL_MATCH_DATA
),
322 g_signal_lookup("size_request", GTK_TYPE_WIDGET
),
323 0, NULL
, NULL
, menuBar
);
325 g_signal_handler_disconnect(menuBar
->m_widget
, handler_id
);
327 // reset size request to allow native sizing to work
328 gtk_widget_set_size_request(menuBar
->m_widget
, -1, -1);
330 gtk_widget_show( m_frameMenuBar
->m_widget
);
331 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
333 // make sure next size_allocate causes a wxSizeEvent
334 m_oldClientWidth
= 0;
336 #endif // wxUSE_MENUS_NATIVE
340 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
342 m_frameToolBar
= toolbar
;
345 if (toolbar
->IsVertical())
347 // Vertical toolbar and m_wxwindow go into an hbox, inside the
348 // vbox (m_mainWidget). hbox is created on demand.
349 GtkWidget
* hbox
= m_wxwindow
->parent
;
350 if (!GTK_IS_HBOX(hbox
))
352 hbox
= gtk_hbox_new(false, 0);
353 gtk_widget_show(hbox
);
354 gtk_container_add(GTK_CONTAINER(m_mainWidget
), hbox
);
355 gtk_widget_reparent(m_wxwindow
, hbox
);
357 gtk_widget_reparent(toolbar
->m_widget
, hbox
);
358 gtk_box_set_child_packing(GTK_BOX(hbox
),
359 toolbar
->m_widget
, false, false, 0, GTK_PACK_START
);
362 if (toolbar
->HasFlag(wxTB_RIGHT
))
364 gtk_box_reorder_child(GTK_BOX(hbox
), toolbar
->m_widget
, pos
);
368 // Horizontal toolbar goes into vbox (m_mainWidget)
369 gtk_widget_reparent(toolbar
->m_widget
, m_mainWidget
);
370 gtk_box_set_child_packing(GTK_BOX(m_mainWidget
),
371 toolbar
->m_widget
, false, false, 0, GTK_PACK_START
);
375 pos
= 1; // below menubar
376 if (toolbar
->HasFlag(wxTB_BOTTOM
))
377 pos
+= 2; // below client area (m_wxwindow)
378 gtk_box_reorder_child(
379 GTK_BOX(m_mainWidget
), toolbar
->m_widget
, pos
);
382 // disconnect wxWindowGTK "size_request" handler,
383 // it interferes with sizing of detached GtkHandleBox
384 gulong handler_id
= g_signal_handler_find(
386 GSignalMatchType(G_SIGNAL_MATCH_ID
| G_SIGNAL_MATCH_DATA
),
387 g_signal_lookup("size_request", GTK_TYPE_WIDGET
),
388 0, NULL
, NULL
, toolbar
);
390 g_signal_handler_disconnect(toolbar
->m_widget
, handler_id
);
392 // reset size request to allow native sizing to work
393 gtk_widget_set_size_request(toolbar
->m_widget
, -1, -1);
395 // make sure next size_allocate causes a wxSizeEvent
396 m_oldClientWidth
= 0;
399 #endif // wxUSE_TOOLBAR
403 void wxFrame::SetStatusBar(wxStatusBar
*statbar
)
405 m_frameStatusBar
= statbar
;
408 // statusbar goes into bottom of vbox (m_mainWidget)
409 gtk_widget_reparent(statbar
->m_widget
, m_mainWidget
);
410 gtk_box_set_child_packing(GTK_BOX(m_mainWidget
),
411 statbar
->m_widget
, false, false, 0, GTK_PACK_END
);
412 // make sure next size_allocate on statusbar causes a size event
413 statbar
->m_oldClientWidth
= 0;
415 // make sure next size_allocate causes a wxSizeEvent
416 m_oldClientWidth
= 0;
418 #endif // wxUSE_STATUSBAR