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