1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/gtk/frame.cpp
3 // Purpose:
4 // Author:      Robert Roebling
5 // Copyright:   (c) 1998 Robert Roebling
6 // Licence:     wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8 
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
11 
12 #include "wx/frame.h"
13 
14 #ifndef WX_PRECOMP
15     #include "wx/menu.h"
16     #include "wx/toolbar.h"
17     #include "wx/statusbr.h"
18 #endif // WX_PRECOMP
19 
20 #include <gtk/gtk.h>
21 #include "wx/gtk/private/gtk2-compat.h"
22 
23 #if wxUSE_LIBHILDON
24     #include <hildon-widgets/hildon-window.h>
25 #endif // wxUSE_LIBHILDON
26 
27 #if wxUSE_LIBHILDON2
28     #include <hildon/hildon.h>
29 #endif // wxUSE_LIBHILDON2
30 
31 // ----------------------------------------------------------------------------
32 // event tables
33 // ----------------------------------------------------------------------------
34 
35 // ============================================================================
36 // implementation
37 // ============================================================================
38 
39 // ----------------------------------------------------------------------------
40 // wxFrame creation
41 // ----------------------------------------------------------------------------
42 
Init()43 void wxFrame::Init()
44 {
45     m_fsSaveFlag = 0;
46 }
47 
Create(wxWindow * parent,wxWindowID id,const wxString & title,const wxPoint & pos,const wxSize & sizeOrig,long style,const wxString & name)48 bool wxFrame::Create( wxWindow *parent,
49                       wxWindowID id,
50                       const wxString& title,
51                       const wxPoint& pos,
52                       const wxSize& sizeOrig,
53                       long style,
54                       const wxString &name )
55 {
56     return wxFrameBase::Create(parent, id, title, pos, sizeOrig, style, name);
57 }
58 
~wxFrame()59 wxFrame::~wxFrame()
60 {
61     SendDestroyEvent();
62 
63     DeleteAllBars();
64 }
65 
66 // ----------------------------------------------------------------------------
67 // overridden wxWindow methods
68 // ----------------------------------------------------------------------------
69 
DoGetClientSize(int * width,int * height) const70 void wxFrame::DoGetClientSize( int *width, int *height ) const
71 {
72     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
73 
74     wxFrameBase::DoGetClientSize(width, height);
75 
76     if (m_useCachedClientSize)
77         return;
78 
79     if (height)
80     {
81 #if wxUSE_MENUS_NATIVE
82         // menu bar
83         if (m_frameMenuBar && m_frameMenuBar->IsShown())
84         {
85             int h;
86             gtk_widget_get_preferred_height(m_frameMenuBar->m_widget, NULL, &h);
87 #if !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
88             *height -= h;
89 #endif
90         }
91 #endif // wxUSE_MENUS_NATIVE
92 
93 #if wxUSE_STATUSBAR
94         // status bar
95         if (m_frameStatusBar && m_frameStatusBar->IsShown())
96             *height -= m_frameStatusBar->m_height;
97 #endif // wxUSE_STATUSBAR
98     }
99 
100 #if wxUSE_TOOLBAR
101     // tool bar
102     if (m_frameToolBar && m_frameToolBar->IsShown())
103     {
104         if (m_frameToolBar->IsVertical())
105         {
106             if (width)
107             {
108                 int w;
109                 gtk_widget_get_preferred_width(m_frameToolBar->m_widget, NULL, &w);
110                 *width -= w;
111             }
112         }
113         else
114         {
115             if (height)
116             {
117                 int h;
118                 gtk_widget_get_preferred_height(m_frameToolBar->m_widget, NULL, &h);
119                 *height -= h;
120             }
121         }
122     }
123 #endif // wxUSE_TOOLBAR
124 
125     if (width != NULL && *width < 0)
126         *width = 0;
127     if (height != NULL && *height < 0)
128         *height = 0;
129 }
130 
ShowFullScreen(bool show,long style)131 bool wxFrame::ShowFullScreen(bool show, long style)
132 {
133     if (!wxFrameBase::ShowFullScreen(show, style))
134         return false;
135 
136     wxWindow* const bar[] = {
137 #if wxUSE_MENUS
138         m_frameMenuBar,
139 #else
140         NULL,
141 #endif
142 #if wxUSE_TOOLBAR
143         m_frameToolBar,
144 #else
145         NULL,
146 #endif
147 #if wxUSE_STATUSBAR
148         m_frameStatusBar,
149 #else
150         NULL,
151 #endif
152     };
153     const long fsNoBar[] = {
154         wxFULLSCREEN_NOMENUBAR, wxFULLSCREEN_NOTOOLBAR, wxFULLSCREEN_NOSTATUSBAR
155     };
156     for (int i = 0; i < 3; i++)
157     {
158         if (show)
159         {
160             if (bar[i] && (style & fsNoBar[i]))
161             {
162                 if (bar[i]->IsShown())
163                     bar[i]->Show(false);
164                 else
165                     style &= ~fsNoBar[i];
166             }
167         }
168         else
169         {
170             if (bar[i] && (m_fsSaveFlag & fsNoBar[i]))
171                 bar[i]->Show(true);
172         }
173     }
174     if (show)
175         m_fsSaveFlag = style;
176 
177     return true;
178 }
179 
SendIdleEvents(wxIdleEvent & event)180 bool wxFrame::SendIdleEvents(wxIdleEvent& event)
181 {
182     bool needMore = wxFrameBase::SendIdleEvents(event);
183 
184 #if wxUSE_MENUS
185     if (m_frameMenuBar && m_frameMenuBar->SendIdleEvents(event))
186         needMore = true;
187 #endif
188 #if wxUSE_TOOLBAR
189     if (m_frameToolBar && m_frameToolBar->SendIdleEvents(event))
190         needMore = true;
191 #endif
192 #if wxUSE_STATUSBAR
193     if (m_frameStatusBar && m_frameStatusBar->SendIdleEvents(event))
194         needMore = true;
195 #endif
196 
197     return needMore;
198 }
199 
200 // ----------------------------------------------------------------------------
201 // menu/tool/status bar stuff
202 // ----------------------------------------------------------------------------
203 
204 #if wxUSE_MENUS_NATIVE
205 
DetachMenuBar()206 void wxFrame::DetachMenuBar()
207 {
208     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
209     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
210 
211     if ( m_frameMenuBar )
212     {
213 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
214         hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
215 #else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
216         gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
217 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
218     }
219 
220     wxFrameBase::DetachMenuBar();
221 
222     // make sure next size_allocate causes a wxSizeEvent
223     m_useCachedClientSize = false;
224     m_clientWidth = 0;
225 }
226 
AttachMenuBar(wxMenuBar * menuBar)227 void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
228 {
229     wxFrameBase::AttachMenuBar(menuBar);
230 
231     if (m_frameMenuBar)
232     {
233 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
234         hildon_window_set_menu(HILDON_WINDOW(m_widget),
235                                GTK_MENU(m_frameMenuBar->m_widget));
236 #else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
237 
238         // menubar goes into top of vbox (m_mainWidget)
239         gtk_box_pack_start(
240             GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
241         gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
242 
243         // reset size request to allow native sizing to work
244         gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
245 
246         gtk_widget_show( m_frameMenuBar->m_widget );
247 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
248     }
249     // make sure next size_allocate causes a wxSizeEvent
250     m_useCachedClientSize = false;
251     m_clientWidth = 0;
252 }
253 #endif // wxUSE_MENUS_NATIVE
254 
255 #if wxUSE_TOOLBAR
256 
SetToolBar(wxToolBar * toolbar)257 void wxFrame::SetToolBar(wxToolBar *toolbar)
258 {
259     m_frameToolBar = toolbar;
260     if (toolbar)
261     {
262         gtk_container_remove(
263             GTK_CONTAINER(gtk_widget_get_parent(toolbar->m_widget)), toolbar->m_widget);
264         if (toolbar->IsVertical())
265         {
266             // Vertical toolbar and m_wxwindow go into an hbox, inside the
267             // vbox (m_mainWidget). hbox is created on demand.
268             GtkWidget* hbox = gtk_widget_get_parent(m_wxwindow);
269             if (hbox == m_mainWidget)
270             {
271                 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
272                 gtk_widget_show(hbox);
273                 gtk_box_pack_start(GTK_BOX(m_mainWidget), hbox, true, true, 0);
274                 g_object_ref(m_wxwindow);
275                 gtk_container_remove(GTK_CONTAINER(m_mainWidget), m_wxwindow);
276                 gtk_box_pack_start(GTK_BOX(hbox), m_wxwindow, true, true, 0);
277                 g_object_unref(m_wxwindow);
278             }
279             gtk_box_pack_start(GTK_BOX(hbox), toolbar->m_widget, false, false, 0);
280 
281             int pos = 0;  // left
282             if (toolbar->HasFlag(wxTB_RIGHT))
283                 pos = 1;  // right
284             gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
285         }
286         else
287         {
288             // Horizontal toolbar goes into vbox (m_mainWidget)
289             gtk_box_pack_start(GTK_BOX(m_mainWidget), toolbar->m_widget, false, false, 0);
290 
291             int pos = 0;  // top
292             if (m_frameMenuBar)
293                 pos = 1;  // below menubar
294             if (toolbar->HasFlag(wxTB_BOTTOM))
295                 pos += 2;  // below client area (m_wxwindow)
296             gtk_box_reorder_child(
297                 GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
298         }
299         // reset size request to allow native sizing to work
300         gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
301     }
302     // make sure next size_allocate causes a wxSizeEvent
303     m_useCachedClientSize = false;
304     m_clientWidth = 0;
305 }
306 
307 #endif // wxUSE_TOOLBAR
308 
309 #if wxUSE_STATUSBAR
310 
SetStatusBar(wxStatusBar * statbar)311 void wxFrame::SetStatusBar(wxStatusBar *statbar)
312 {
313     m_frameStatusBar = statbar;
314     if (statbar)
315     {
316         // statusbar goes into bottom of vbox (m_mainWidget)
317         gtk_container_remove(
318             GTK_CONTAINER(gtk_widget_get_parent(statbar->m_widget)), statbar->m_widget);
319         gtk_box_pack_end(GTK_BOX(m_mainWidget), statbar->m_widget, false, false, 0);
320         // make sure next size_allocate on statusbar causes a size event
321         statbar->m_useCachedClientSize = false;
322         statbar->m_clientWidth = 0;
323         int h = -1;
324         if (statbar->m_wxwindow)
325         {
326             // statusbar is not a native widget, need to set height request
327             h = statbar->m_height;
328         }
329         gtk_widget_set_size_request(statbar->m_widget, -1, h);
330     }
331     // make sure next size_allocate causes a wxSizeEvent
332     m_useCachedClientSize = false;
333     m_clientWidth = 0;
334 }
335 #endif // wxUSE_STATUSBAR
336