]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/frame.cpp
Added wxchar.cpp, which contains:
[wxWidgets.git] / src / gtk1 / frame.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: frame.cpp
3// Purpose:
4// Author: Robert Roebling
a81258be 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling
19717c50 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
fe4e9e6c 11 #pragma implementation "frame.h"
c801d85f
KB
12#endif
13
14#include "wx/frame.h"
15#include "wx/dialog.h"
16#include "wx/control.h"
17#include "wx/app.h"
cf4219e7
RR
18#include "wx/menu.h"
19#include "wx/toolbar.h"
20#include "wx/statusbr.h"
362c6693 21#include "wx/dcclient.h"
83624f79
RR
22
23#include "glib.h"
24#include "gdk/gdk.h"
25#include "gtk/gtk.h"
c801d85f
KB
26#include "wx/gtk/win_gtk.h"
27
2f2aa628
RR
28//-----------------------------------------------------------------------------
29// constants
30//-----------------------------------------------------------------------------
31
907789a0 32const int wxMENU_HEIGHT = 27;
c67daf87 33const int wxSTATUS_HEIGHT = 25;
c801d85f 34
2f2aa628
RR
35//-----------------------------------------------------------------------------
36// data
37//-----------------------------------------------------------------------------
38
c801d85f
KB
39extern wxList wxPendingDelete;
40
41//-----------------------------------------------------------------------------
2f2aa628 42// "size_allocate"
c801d85f 43//-----------------------------------------------------------------------------
c801d85f 44
2f2aa628 45static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrame *win )
ed7a557b 46{
fb1585ae 47 if (!win->HasVMT()) return;
8bbe427f 48
c801d85f 49/*
fb1585ae
RR
50 printf( "OnFrameResize from " );
51 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
52 printf( win->GetClassInfo()->GetClassName() );
53 printf( ".\n" );
c801d85f 54*/
8bbe427f 55
e52f60e6
RR
56 if ((win->m_width != alloc->width) || (win->m_height != alloc->height))
57 {
58 win->m_sizeSet = FALSE;
59 win->m_width = alloc->width;
60 win->m_height = alloc->height;
61 }
362c6693 62}
c801d85f
KB
63
64//-----------------------------------------------------------------------------
2f2aa628
RR
65// "delete_event"
66//-----------------------------------------------------------------------------
c801d85f 67
2f2aa628 68static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrame *win )
ed7a557b 69{
c801d85f 70/*
fb1585ae
RR
71 printf( "OnDelete from " );
72 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
73 printf( win->GetClassInfo()->GetClassName() );
74 printf( ".\n" );
c801d85f 75*/
ed7a557b 76
fb1585ae 77 win->Close();
c801d85f 78
fb1585ae 79 return TRUE;
362c6693 80}
c801d85f 81
47908e25 82//-----------------------------------------------------------------------------
2f2aa628
RR
83// "configure_event"
84//-----------------------------------------------------------------------------
47908e25 85
2f2aa628 86static gint gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrame *win )
47908e25 87{
fb1585ae 88 if (!win->HasVMT()) return FALSE;
8bbe427f 89
fb1585ae
RR
90 win->m_x = event->x;
91 win->m_y = event->y;
8bbe427f 92
36b3b54a
RR
93 wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
94 mevent.SetEventObject( win );
95 win->GetEventHandler()->ProcessEvent( mevent );
96
fb1585ae 97 return FALSE;
362c6693 98}
47908e25 99
f362b96d
RR
100//-----------------------------------------------------------------------------
101// InsertChild for wxFrame
102//-----------------------------------------------------------------------------
103
104/* Callback for wxFrame. This very strange beast has to be used because
105 * C++ has no virtual methods in a constructor. We have to emulate a
106 * virtual function here as wxWindows requires different ways to insert
107 * a child in container classes. */
108
109static void wxInsertChildInFrame( wxWindow* parent, wxWindow* child )
110{
111 if (wxIS_KIND_OF(child,wxToolBar) || wxIS_KIND_OF(child,wxMenuBar))
112 {
113 /* these are outside the client area */
114 wxFrame* frame = (wxFrame*) parent;
115 gtk_myfixed_put( GTK_MYFIXED(frame->m_mainWidget),
116 GTK_WIDGET(child->m_widget),
117 child->m_x,
118 child->m_y );
119 }
120 else
121 {
122 /* these are inside the client area */
123 gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
124 GTK_WIDGET(child->m_widget),
125 child->m_x,
126 child->m_y );
127 }
128
129 gtk_widget_set_usize( GTK_WIDGET(child->m_widget),
130 child->m_width,
131 child->m_height );
132
133 /* resize on OnInternalIdle */
134 parent->m_sizeSet = FALSE;
135
136 if (parent->m_windowStyle & wxTAB_TRAVERSAL)
137 {
138 /* we now allow a window to get the focus as long as it
139 doesn't have any children. */
140 GTK_WIDGET_UNSET_FLAGS( parent->m_wxwindow, GTK_CAN_FOCUS );
141 }
142}
143
2f2aa628
RR
144//-----------------------------------------------------------------------------
145// wxFrame
c801d85f
KB
146//-----------------------------------------------------------------------------
147
148BEGIN_EVENT_TABLE(wxFrame, wxWindow)
fb1585ae 149 EVT_SIZE(wxFrame::OnSize)
fe4e9e6c 150 EVT_CLOSE(wxFrame::OnCloseWindow)
342b6a2f 151 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
c801d85f
KB
152END_EVENT_TABLE()
153
154IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow)
155
19717c50 156wxFrame::wxFrame()
c801d85f 157{
fb1585ae 158 m_frameMenuBar = (wxMenuBar *) NULL;
e27ce4e9 159 m_mdiMenuBar = (wxMenuBar *) NULL;
fb1585ae
RR
160 m_frameStatusBar = (wxStatusBar *) NULL;
161 m_frameToolBar = (wxToolBar *) NULL;
162 m_sizeSet = FALSE;
b2b3ccc5
RR
163 m_miniEdge = 0;
164 m_miniTitle = 0;
ab2b3dd4 165 m_mainWidget = (GtkWidget*) NULL;
362c6693 166}
c801d85f 167
ed7a557b 168wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title,
debe6624
JS
169 const wxPoint &pos, const wxSize &size,
170 long style, const wxString &name )
c801d85f 171{
fb1585ae 172 m_frameMenuBar = (wxMenuBar *) NULL;
e27ce4e9 173 m_mdiMenuBar = (wxMenuBar *) NULL;
fb1585ae
RR
174 m_frameStatusBar = (wxStatusBar *) NULL;
175 m_frameToolBar = (wxToolBar *) NULL;
176 m_sizeSet = FALSE;
b2b3ccc5
RR
177 m_miniEdge = 0;
178 m_miniTitle = 0;
ab2b3dd4 179 m_mainWidget = (GtkWidget*) NULL;
fb1585ae 180 Create( parent, id, title, pos, size, style, name );
362c6693 181}
c801d85f 182
debe6624 183bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
c801d85f 184 const wxPoint &pos, const wxSize &size,
debe6624 185 long style, const wxString &name )
c801d85f 186{
a802c3a1 187 wxTopLevelWindows.Append( this );
8bbe427f 188
fb1585ae 189 m_needParent = FALSE;
ed7a557b 190
fb1585ae 191 PreCreation( parent, id, pos, size, style, name );
c801d85f 192
fb1585ae 193 m_title = title;
f362b96d
RR
194
195 m_insertCallback = wxInsertChildInFrame;
ed7a557b 196
fb1585ae
RR
197 GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
198 if (style & wxSIMPLE_BORDER) win_type = GTK_WINDOW_POPUP;
8bbe427f 199
fb1585ae 200 m_widget = gtk_window_new( win_type );
8bbe427f 201
fb1585ae
RR
202 gtk_window_set_title( GTK_WINDOW(m_widget), title );
203 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
ed7a557b 204
ab2b3dd4 205 /* needed ? */
f5eafd0e 206 gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 );
ed7a557b 207
fb1585ae
RR
208 gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
209 GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
ed7a557b 210
f362b96d
RR
211 /* m_mainWidget holds the toolbar, the menubar and the client area */
212 m_mainWidget = gtk_myfixed_new();
213 gtk_widget_show( m_mainWidget );
214 GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
215 gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
216 gtk_widget_realize( m_mainWidget );
217
218 /* m_wxwindow only represents the client area without toolbar and menubar */
fb1585ae
RR
219 m_wxwindow = gtk_myfixed_new();
220 gtk_widget_show( m_wxwindow );
221 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
f362b96d 222 gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
ed7a557b 223
de8113d9
RR
224 if (m_parent) m_parent->AddChild( this );
225
226 PostCreation();
227
228 gtk_widget_realize( m_widget );
229
ab2b3dd4
RR
230 /* all this is for Motif Window Manager "hints" and is supposed to be
231 recognized by other WM as well. not tested. */
232 long decor = (long) GDK_DECOR_ALL;
233 long func = (long) GDK_FUNC_ALL;
234 if ((m_windowStyle & wxCAPTION) == 0)
034be888 235 decor |= GDK_DECOR_TITLE;
ca35e608 236/*
ab2b3dd4 237 if ((m_windowStyle & wxMINIMIZE) == 0)
034be888 238 func |= GDK_FUNC_MINIMIZE;
ab2b3dd4 239 if ((m_windowStyle & wxMAXIMIZE) == 0)
034be888 240 func |= GDK_FUNC_MAXIMIZE;
ca35e608 241*/
ab2b3dd4 242 if ((m_windowStyle & wxSYSTEM_MENU) == 0)
034be888 243 decor |= GDK_DECOR_MENU;
ab2b3dd4 244 if ((m_windowStyle & wxMINIMIZE_BOX) == 0)
034be888 245 decor |= GDK_DECOR_MINIMIZE;
ab2b3dd4 246 if ((m_windowStyle & wxMAXIMIZE_BOX) == 0)
034be888 247 decor |= GDK_DECOR_MAXIMIZE;
ab2b3dd4 248 if ((m_windowStyle & wxRESIZE_BORDER) == 0)
034be888 249 func |= GDK_FUNC_RESIZE;
ab2b3dd4
RR
250 gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor);
251 gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
034be888 252
ab2b3dd4 253 /* the user resized the frame by dragging etc. */
fb1585ae
RR
254 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
255 GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
ed7a557b 256
ab2b3dd4 257 /* the only way to get the window size is to connect to this event */
fb1585ae
RR
258 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
259 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
8bbe427f 260
fb1585ae 261 return TRUE;
362c6693 262}
c801d85f 263
19717c50 264wxFrame::~wxFrame()
c801d85f 265{
fb1585ae 266 if (m_frameMenuBar) delete m_frameMenuBar;
e27ce4e9
RR
267 m_frameMenuBar = (wxMenuBar *) NULL;
268
fb1585ae 269 if (m_frameStatusBar) delete m_frameStatusBar;
e27ce4e9
RR
270 m_frameStatusBar = (wxStatusBar *) NULL;
271
fb1585ae 272 if (m_frameToolBar) delete m_frameToolBar;
e27ce4e9 273 m_frameToolBar = (wxToolBar *) NULL;
ed7a557b 274
fb1585ae 275 wxTopLevelWindows.DeleteObject( this );
2b854a32 276
0d2a2b60
RR
277 if (wxTheApp->GetTopWindow() == this)
278 {
279 wxTheApp->SetTopWindow( (wxWindow*) NULL );
280 }
2b854a32 281
0d2a2b60 282 if (wxTopLevelWindows.Number() == 0)
2b854a32 283 {
0d2a2b60
RR
284 wxTheApp->ExitMainLoop();
285 }
362c6693 286}
ed7a557b 287
debe6624 288bool wxFrame::Show( bool show )
c801d85f 289{
fb1585ae 290 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 291
35178437 292 if (show && !m_sizeSet)
fb1585ae 293 {
e27ce4e9
RR
294 /* by calling GtkOnSize here, we don't have to call
295 either after showing the frame, which would entail
f362b96d 296 much ugly flicker or from within the size_allocate
e27ce4e9 297 handler, because GTK 1.1.X forbids that. */
8bbe427f 298
35178437 299 GtkOnSize( m_x, m_y, m_width, m_height );
fb1585ae 300 }
8bbe427f 301
fb1585ae 302 return wxWindow::Show( show );
362c6693 303}
c801d85f 304
19717c50 305bool wxFrame::Destroy()
c801d85f 306{
fb1585ae 307 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 308
fb1585ae 309 if (!wxPendingDelete.Member(this)) wxPendingDelete.Append(this);
ed7a557b 310
fb1585ae 311 return TRUE;
c801d85f
KB
312}
313
bfc6fde4 314void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
903f689b 315{
de8113d9 316 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 317
ab2b3dd4
RR
318 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
319 wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" );
320
321 /* avoid recursions */
322 if (m_resizing) return;
fb1585ae
RR
323 m_resizing = TRUE;
324
325 int old_x = m_x;
326 int old_y = m_y;
327 int old_width = m_width;
328 int old_height = m_height;
8bbe427f 329
fb1585ae
RR
330 if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
331 {
332 if (x != -1) m_x = x;
333 if (y != -1) m_y = y;
334 if (width != -1) m_width = width;
335 if (height != -1) m_height = height;
336 }
337 else
338 {
339 m_x = x;
340 m_y = y;
341 m_width = width;
342 m_height = height;
343 }
344
345 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
346 {
347 if (width == -1) m_width = 80;
348 }
349
350 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
351 {
352 if (height == -1) m_height = 26;
353 }
8bbe427f 354
fb1585ae
RR
355 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
356 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
0c77152e
RR
357 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
358 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
fb1585ae
RR
359
360 if ((m_x != -1) || (m_y != -1))
361 {
8bbe427f 362 if ((m_x != old_x) || (m_y != old_y))
0138c2de 363 {
de8113d9 364 /* m_sizeSet = FALSE; */
0138c2de
VZ
365 gtk_widget_set_uposition( m_widget, m_x, m_y );
366 }
fb1585ae 367 }
8bbe427f 368
fb1585ae
RR
369 if ((m_width != old_width) || (m_height != old_height))
370 {
ab2b3dd4
RR
371 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
372 done either directly before the frame is shown or in idle time
373 so that different calls to SetSize() don't lead to flicker. */
de8113d9 374 m_sizeSet = FALSE;
fb1585ae 375 }
8bbe427f 376
fb1585ae 377 m_resizing = FALSE;
903f689b
RR
378}
379
380void wxFrame::Centre( int direction )
381{
fb1585ae 382 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 383
43a18898
RR
384 int x = 0;
385 int y = 0;
8bbe427f 386
f5eafd0e
RR
387 if ((direction & wxHORIZONTAL) == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
388 if ((direction & wxVERTICAL) == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
8bbe427f 389
fb1585ae 390 Move( x, y );
903f689b
RR
391}
392
c801d85f
KB
393void wxFrame::GetClientSize( int *width, int *height ) const
394{
fb1585ae 395 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 396
fb1585ae
RR
397 wxWindow::GetClientSize( width, height );
398 if (height)
46dc76ba 399 {
fb1585ae
RR
400 if (m_frameMenuBar) (*height) -= wxMENU_HEIGHT;
401 if (m_frameStatusBar) (*height) -= wxSTATUS_HEIGHT;
402 if (m_frameToolBar)
403 {
404 int y = 0;
405 m_frameToolBar->GetSize( (int *) NULL, &y );
406 (*height) -= y;
407 }
b2b3ccc5
RR
408 (*height) -= m_miniEdge*2 + m_miniTitle;
409 }
410 if (width)
411 {
412 (*width) -= m_miniEdge*2;
46dc76ba 413 }
362c6693 414}
c801d85f 415
bfc6fde4 416void wxFrame::DoSetClientSize( int width, int height )
b593568e 417{
f5368809 418 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 419
f5368809
RR
420 int h = height;
421 if (m_frameMenuBar) h += wxMENU_HEIGHT;
422 if (m_frameStatusBar) h += wxSTATUS_HEIGHT;
423 if (m_frameToolBar)
424 {
425 int y = 0;
426 m_frameToolBar->GetSize( (int *) NULL, &y );
427 h += y;
428 }
f76f940b 429 wxWindow::DoSetClientSize( width + m_miniEdge*2, h + m_miniEdge*2 + m_miniTitle );
362c6693 430}
b593568e 431
47908e25 432void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height )
c801d85f 433{
f5368809
RR
434 // due to a bug in gtk, x,y are always 0
435 // m_x = x;
436 // m_y = y;
437
ab2b3dd4 438 /* avoid recursions */
e52f60e6
RR
439 if (m_resizing) return;
440 m_resizing = TRUE;
8bbe427f 441
ab2b3dd4
RR
442 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
443 wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" );
444
f5368809
RR
445 m_width = width;
446 m_height = height;
8bbe427f 447
ab2b3dd4 448 /* space occupied by m_frameToolBar and m_frameMenuBar */
f362b96d 449 int client_area_y_offset = 0;
8bbe427f 450
ab2b3dd4
RR
451 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
452 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
453 set in wxFrame::Create so it is used to check what kind of frame we
454 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
455 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
456 importantly) m_mainWidget */
457
458 if (m_mainWidget)
f5368809 459 {
ab2b3dd4
RR
460 /* check if size is in legal range */
461 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
462 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
463 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
464 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
465
466 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
467 * menubar, the toolbar and the client area, which is represented by
468 * m_wxwindow.
469 * this hurts in the eye, but I don't want to call SetSize()
470 * because I don't want to call any non-native functions here. */
471
472 if (m_frameMenuBar)
473 {
474 int xx = m_miniEdge;
475 int yy = m_miniEdge + m_miniTitle;
476 int ww = m_width - 2*m_miniEdge;
477 int hh = wxMENU_HEIGHT;
478 m_frameMenuBar->m_x = xx;
479 m_frameMenuBar->m_y = yy;
480 m_frameMenuBar->m_width = ww;
481 m_frameMenuBar->m_height = hh;
482
483 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameMenuBar->m_widget, xx, yy );
484 gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh );
f362b96d 485
ab2b3dd4
RR
486 client_area_y_offset += hh;
487 }
e27ce4e9 488
ab2b3dd4
RR
489 if (m_frameToolBar)
490 {
491 int xx = m_miniEdge;
492 int yy = m_miniEdge + m_miniTitle;
493 if ((m_frameMenuBar) || (m_mdiMenuBar)) yy += wxMENU_HEIGHT;
494 int ww = m_width - 2*m_miniEdge;
495 int hh = m_frameToolBar->m_height;
496
497 m_frameToolBar->m_x = xx;
498 m_frameToolBar->m_y = yy;
499 m_frameToolBar->m_height = hh;
500 m_frameToolBar->m_width = ww;
501
502 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameToolBar->m_widget, xx, yy );
503 gtk_widget_set_usize( m_frameToolBar->m_widget, ww, hh );
f362b96d 504
ab2b3dd4
RR
505 client_area_y_offset += hh;
506 }
507
508 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset );
f5368809 509 }
f362b96d 510
f362b96d 511 gtk_widget_set_usize( m_wxwindow, m_width, m_height-client_area_y_offset );
8bbe427f 512
f5368809
RR
513 if (m_frameStatusBar)
514 {
b2b3ccc5 515 int xx = 0 + m_miniEdge;
f362b96d 516 int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset;
ac57418f
RR
517 int ww = m_width - 2*m_miniEdge;
518 int hh = wxSTATUS_HEIGHT;
8bbe427f 519
b2b3ccc5
RR
520 m_frameStatusBar->m_x = xx;
521 m_frameStatusBar->m_y = yy;
522 m_frameStatusBar->m_width = ww;
523 m_frameStatusBar->m_height = hh;
8bbe427f 524
b2b3ccc5
RR
525 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_frameStatusBar->m_widget, xx, yy );
526 gtk_widget_set_usize( m_frameStatusBar->m_widget, ww, hh );
f5368809 527 }
8bbe427f 528
de8113d9
RR
529 /* we actually set the size of a frame here and no-where else */
530 gtk_widget_set_usize( m_widget, m_width, m_height );
531
f5368809 532 m_sizeSet = TRUE;
8bbe427f 533
884470b1 534 /* send size event to frame */
43a18898
RR
535 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
536 event.SetEventObject( this );
e52f60e6 537 GetEventHandler()->ProcessEvent( event );
8bbe427f 538
884470b1 539 /* send size event to status bar */
5aa5e35a
RR
540 if (m_frameStatusBar)
541 {
542 wxSizeEvent event2( wxSize(m_frameStatusBar->m_width,m_frameStatusBar->m_height), m_frameStatusBar->GetId() );
543 event2.SetEventObject( m_frameStatusBar );
544 m_frameStatusBar->GetEventHandler()->ProcessEvent( event2 );
545 }
884470b1 546
e52f60e6
RR
547 m_resizing = FALSE;
548}
549
9390a202 550void wxFrame::OnInternalIdle()
e52f60e6
RR
551{
552 if (!m_sizeSet)
553 GtkOnSize( m_x, m_y, m_width, m_height );
8bbe427f 554
e52f60e6 555 DoMenuUpdates();
362c6693 556}
c801d85f 557
fe4e9e6c
VZ
558void wxFrame::OnCloseWindow( wxCloseEvent& event )
559{
e3065973 560 Destroy();
fe4e9e6c
VZ
561}
562
c801d85f
KB
563void wxFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
564{
f5368809 565 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 566
f5368809
RR
567 if (GetAutoLayout())
568 {
569 Layout();
570 }
8bbe427f 571 else
c801d85f 572 {
0138c2de
VZ
573 // do we have exactly one child?
574 wxWindow *child = (wxWindow *)NULL;
575 for ( wxNode *node = GetChildren().First(); node; node = node->Next() )
f5368809
RR
576 {
577 wxWindow *win = (wxWindow *)node->Data();
0138c2de 578 if ( !wxIS_KIND_OF(win,wxFrame) && !wxIS_KIND_OF(win,wxDialog) )
f5368809 579 {
0138c2de
VZ
580 if ( child )
581 {
582 // it's the second one: do nothing
583 return;
584 }
585
f5368809
RR
586 child = win;
587 }
588 }
ed7a557b 589
0138c2de
VZ
590 // no children at all?
591 if ( child )
592 {
593 // yes: set it's size to fill all the frame
594 int client_x, client_y;
595 GetClientSize( &client_x, &client_y );
596 child->SetSize( 1, 1, client_x-2, client_y-2 );
597 }
362c6693 598 }
362c6693 599}
c801d85f 600
716b7364 601static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
c801d85f 602{
f5368809 603 menu->SetInvokingWindow( win );
c626a8b7 604 wxNode *node = menu->GetItems().First();
f5368809
RR
605 while (node)
606 {
607 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
608 if (menuitem->IsSubMenu())
609 SetInvokingWindow( menuitem->GetSubMenu(), win );
610 node = node->Next();
611 }
362c6693 612}
c801d85f
KB
613
614void wxFrame::SetMenuBar( wxMenuBar *menuBar )
615{
f5368809
RR
616 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
617 wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" );
8bbe427f 618
f5368809 619 m_frameMenuBar = menuBar;
8bbe427f 620
f5368809 621 if (m_frameMenuBar)
30dea054 622 {
c626a8b7 623 wxNode *node = m_frameMenuBar->GetMenus().First();
f5368809
RR
624 while (node)
625 {
626 wxMenu *menu = (wxMenu*)node->Data();
627 SetInvokingWindow( menu, this );
628 node = node->Next();
629 }
8bbe427f 630
f5368809
RR
631 if (m_frameMenuBar->m_parent != this)
632 {
633 m_frameMenuBar->m_parent = this;
f362b96d 634 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget),
f5368809 635 m_frameMenuBar->m_widget, m_frameMenuBar->m_x, m_frameMenuBar->m_y );
e27ce4e9 636
0138c2de 637 /* an mdi child menu bar might be underneath */
c626a8b7
VZ
638 if (m_mdiMenuBar)
639 m_frameMenuBar->Show( FALSE );
f5368809 640 }
716b7364 641 }
8bbe427f 642
5b077d48 643 m_sizeSet = FALSE;
362c6693 644}
c801d85f 645
8bbe427f 646wxMenuBar *wxFrame::GetMenuBar() const
46dc76ba 647{
f5368809 648 return m_frameMenuBar;
362c6693 649}
46dc76ba 650
342b6a2f
RR
651void wxFrame::OnMenuHighlight(wxMenuEvent& event)
652{
653 if (GetStatusBar())
654 {
0138c2de
VZ
655 // if no help string found, we will clear the status bar text
656 wxString helpString;
657
658 int menuId = event.GetMenuId();
659 if ( menuId != -1 )
342b6a2f
RR
660 {
661 wxMenuBar *menuBar = GetMenuBar();
662 if (menuBar)
663 {
342b6a2f 664 helpString = menuBar->GetHelpString(menuId);
342b6a2f
RR
665 }
666 }
0138c2de
VZ
667
668 SetStatusText(helpString);
342b6a2f
RR
669 }
670}
671
362c6693 672wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
46dc76ba 673{
f5368809 674 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 675
f5368809 676 wxCHECK_MSG( m_frameToolBar == NULL, FALSE, "recreating toolbar in wxFrame" );
362c6693 677
f5368809 678 m_frameToolBar = OnCreateToolBar( style, id, name );
8bbe427f 679
db1b4961 680 GetChildren().DeleteObject( m_frameToolBar );
8bbe427f 681
5b077d48 682 m_sizeSet = FALSE;
8bbe427f 683
f5368809 684 return m_frameToolBar;
362c6693 685}
46dc76ba 686
362c6693 687wxToolBar* wxFrame::OnCreateToolBar( long style, wxWindowID id, const wxString& name )
46dc76ba 688{
f5368809 689 return new wxToolBar( this, id, wxDefaultPosition, wxDefaultSize, style, name );
362c6693
RR
690}
691
8bbe427f
VZ
692wxToolBar *wxFrame::GetToolBar() const
693{
694 return m_frameToolBar;
362c6693 695}
46dc76ba 696
e3e65dac 697wxStatusBar* wxFrame::CreateStatusBar( int number, long style, wxWindowID id, const wxString& name )
c801d85f 698{
f5368809 699 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 700
f5368809 701 wxCHECK_MSG( m_frameStatusBar == NULL, FALSE, "recreating status bar in wxFrame" );
c801d85f 702
f5368809 703 m_frameStatusBar = OnCreateStatusBar( number, style, id, name );
8bbe427f 704
5b077d48 705 m_sizeSet = FALSE;
8bbe427f 706
f5368809 707 return m_frameStatusBar;
362c6693
RR
708}
709
710wxStatusBar *wxFrame::OnCreateStatusBar( int number, long style, wxWindowID id, const wxString& name )
711{
f5368809 712 wxStatusBar *statusBar = (wxStatusBar *) NULL;
8bbe427f 713
f5368809 714 statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20), style, name);
8bbe427f 715
f5368809
RR
716 // Set the height according to the font and the border size
717 wxClientDC dc(statusBar);
8bbe427f 718 dc.SetFont( statusBar->GetFont() );
362c6693 719
f5368809
RR
720 long x, y;
721 dc.GetTextExtent( "X", &x, &y );
362c6693 722
f5368809 723 int height = (int)( (y * 1.1) + 2* statusBar->GetBorderY());
362c6693 724
f5368809 725 statusBar->SetSize( -1, -1, 100, height );
362c6693 726
f5368809
RR
727 statusBar->SetFieldsCount( number );
728 return statusBar;
362c6693 729}
c801d85f 730
30f1b5f3
RR
731void wxFrame::Command( int id )
732{
733 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
734 commandEvent.SetInt( id );
735 commandEvent.SetEventObject( this );
736
737 wxMenuBar *bar = GetMenuBar();
738 if (!bar) return;
739
740 wxMenuItem *item = bar->FindItemForId(id) ;
741 if (item && item->IsCheckable())
742 {
743 bar->Check(id,!bar->Checked(id)) ;
744 }
e702ff0f 745
6c41a418 746 wxEvtHandler* evtHandler = GetEventHandler();
e702ff0f
JS
747
748 evtHandler->ProcessEvent(commandEvent);
30f1b5f3
RR
749}
750
362c6693 751void wxFrame::SetStatusText(const wxString& text, int number)
c801d85f 752{
f5368809 753 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 754
f5368809 755 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set text for" );
c801d85f 756
f5368809 757 m_frameStatusBar->SetStatusText(text, number);
362c6693
RR
758}
759
760void wxFrame::SetStatusWidths(int n, const int widths_field[] )
c801d85f 761{
f5368809 762 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 763
f5368809 764 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set widths for" );
362c6693 765
f5368809 766 m_frameStatusBar->SetStatusWidths(n, widths_field);
362c6693 767}
c801d85f 768
8bbe427f 769wxStatusBar *wxFrame::GetStatusBar() const
c801d85f 770{
f5368809 771 return m_frameStatusBar;
362c6693 772}
c801d85f 773
c801d85f
KB
774void wxFrame::SetTitle( const wxString &title )
775{
f5368809 776 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 777
f5368809
RR
778 m_title = title;
779 if (m_title.IsNull()) m_title = "";
780 gtk_window_set_title( GTK_WINDOW(m_widget), title );
362c6693 781}
c801d85f 782
d355d3fe
RR
783void wxFrame::SetIcon( const wxIcon &icon )
784{
f5368809 785 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
8bbe427f 786
f5368809
RR
787 m_icon = icon;
788 if (!icon.Ok()) return;
8bbe427f 789
f5368809
RR
790 wxMask *mask = icon.GetMask();
791 GdkBitmap *bm = (GdkBitmap *) NULL;
792 if (mask) bm = mask->GetBitmap();
8bbe427f 793
f5368809 794 gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
d355d3fe 795}
b2b3ccc5 796