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