]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/frame.cpp
6c94bcb55f52df477b413b91f185b06c95c78fca
[wxWidgets.git] / src / gtk1 / frame.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: frame.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "frame.h"
12 #endif
13
14 #include "wx/frame.h"
15 #include "wx/dialog.h"
16 #include "wx/control.h"
17 #include "wx/app.h"
18 #include "wx/menu.h"
19 #include "wx/toolbar.h"
20 #include "wx/statusbr.h"
21 #include "wx/dcclient.h"
22
23 #include "glib.h"
24 #include "gdk/gdk.h"
25 #include "gtk/gtk.h"
26 #include "wx/gtk/win_gtk.h"
27
28 //-----------------------------------------------------------------------------
29 // constants
30 //-----------------------------------------------------------------------------
31
32 const int wxMENU_HEIGHT = 27;
33 const int wxSTATUS_HEIGHT = 25;
34
35 //-----------------------------------------------------------------------------
36 // data
37 //-----------------------------------------------------------------------------
38
39 extern wxList wxPendingDelete;
40
41 //-----------------------------------------------------------------------------
42 // "size_allocate"
43 //-----------------------------------------------------------------------------
44
45 static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrame *win )
46 {
47 if (!win->HasVMT()) return;
48
49 /*
50 printf( "OnFrameResize from " );
51 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
52 printf( win->GetClassInfo()->GetClassName() );
53 printf( ".\n" );
54 */
55
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 }
62 }
63
64 //-----------------------------------------------------------------------------
65 // "delete_event"
66 //-----------------------------------------------------------------------------
67
68 static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrame *win )
69 {
70 /*
71 printf( "OnDelete from " );
72 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
73 printf( win->GetClassInfo()->GetClassName() );
74 printf( ".\n" );
75 */
76
77 win->Close();
78
79 return TRUE;
80 }
81
82 //-----------------------------------------------------------------------------
83 // "configure_event"
84 //-----------------------------------------------------------------------------
85
86 static gint gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrame *win )
87 {
88 if (!win->HasVMT()) return FALSE;
89
90 win->m_x = event->x;
91 win->m_y = event->y;
92
93 wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
94 mevent.SetEventObject( win );
95 win->GetEventHandler()->ProcessEvent( mevent );
96
97 return FALSE;
98 }
99
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
109 static 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
144 //-----------------------------------------------------------------------------
145 // wxFrame
146 //-----------------------------------------------------------------------------
147
148 BEGIN_EVENT_TABLE(wxFrame, wxWindow)
149 EVT_SIZE(wxFrame::OnSize)
150 EVT_CLOSE(wxFrame::OnCloseWindow)
151 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
152 END_EVENT_TABLE()
153
154 IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow)
155
156 wxFrame::wxFrame()
157 {
158 m_frameMenuBar = (wxMenuBar *) NULL;
159 m_mdiMenuBar = (wxMenuBar *) NULL;
160 m_frameStatusBar = (wxStatusBar *) NULL;
161 m_frameToolBar = (wxToolBar *) NULL;
162 m_sizeSet = FALSE;
163 m_miniEdge = 0;
164 m_miniTitle = 0;
165 m_mainWidget = (GtkWidget*) NULL;
166 }
167
168 wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title,
169 const wxPoint &pos, const wxSize &size,
170 long style, const wxString &name )
171 {
172 m_frameMenuBar = (wxMenuBar *) NULL;
173 m_mdiMenuBar = (wxMenuBar *) NULL;
174 m_frameStatusBar = (wxStatusBar *) NULL;
175 m_frameToolBar = (wxToolBar *) NULL;
176 m_sizeSet = FALSE;
177 m_miniEdge = 0;
178 m_miniTitle = 0;
179 m_mainWidget = (GtkWidget*) NULL;
180 Create( parent, id, title, pos, size, style, name );
181 }
182
183 bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title,
184 const wxPoint &pos, const wxSize &size,
185 long style, const wxString &name )
186 {
187 wxTopLevelWindows.Append( this );
188
189 m_needParent = FALSE;
190
191 PreCreation( parent, id, pos, size, style, name );
192
193 m_title = title;
194
195 m_insertCallback = wxInsertChildInFrame;
196
197 GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
198 if (style & wxSIMPLE_BORDER) win_type = GTK_WINDOW_POPUP;
199
200 m_widget = gtk_window_new( win_type );
201
202 gtk_window_set_title( GTK_WINDOW(m_widget), title );
203 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
204
205 /* needed ? */
206 gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 );
207
208 gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
209 GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
210
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 */
219 m_wxwindow = gtk_myfixed_new();
220 gtk_widget_show( m_wxwindow );
221 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
222 gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
223
224 if (m_parent) m_parent->AddChild( this );
225
226 PostCreation();
227
228 gtk_widget_realize( m_widget );
229
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)
235 decor |= GDK_DECOR_TITLE;
236 /*
237 if ((m_windowStyle & wxMINIMIZE) == 0)
238 func |= GDK_FUNC_MINIMIZE;
239 if ((m_windowStyle & wxMAXIMIZE) == 0)
240 func |= GDK_FUNC_MAXIMIZE;
241 */
242 if ((m_windowStyle & wxSYSTEM_MENU) == 0)
243 decor |= GDK_DECOR_MENU;
244 if ((m_windowStyle & wxMINIMIZE_BOX) == 0)
245 decor |= GDK_DECOR_MINIMIZE;
246 if ((m_windowStyle & wxMAXIMIZE_BOX) == 0)
247 decor |= GDK_DECOR_MAXIMIZE;
248 if ((m_windowStyle & wxRESIZE_BORDER) == 0)
249 func |= GDK_FUNC_RESIZE;
250 gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor);
251 gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
252
253 /* the user resized the frame by dragging etc. */
254 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
255 GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
256
257 /* the only way to get the window size is to connect to this event */
258 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
259 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
260
261 return TRUE;
262 }
263
264 wxFrame::~wxFrame()
265 {
266 if (m_frameMenuBar) delete m_frameMenuBar;
267 m_frameMenuBar = (wxMenuBar *) NULL;
268
269 if (m_frameStatusBar) delete m_frameStatusBar;
270 m_frameStatusBar = (wxStatusBar *) NULL;
271
272 if (m_frameToolBar) delete m_frameToolBar;
273 m_frameToolBar = (wxToolBar *) NULL;
274
275 wxTopLevelWindows.DeleteObject( this );
276
277 if (wxTheApp->GetTopWindow() == this)
278 {
279 wxTheApp->SetTopWindow( (wxWindow*) NULL );
280 }
281
282 if (wxTopLevelWindows.Number() == 0)
283 {
284 wxTheApp->ExitMainLoop();
285 }
286 }
287
288 bool wxFrame::Show( bool show )
289 {
290 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
291
292 if (show && !m_sizeSet)
293 {
294 /* by calling GtkOnSize here, we don't have to call
295 either after showing the frame, which would entail
296 much ugly flicker or from within the size_allocate
297 handler, because GTK 1.1.X forbids that. */
298
299 GtkOnSize( m_x, m_y, m_width, m_height );
300 }
301
302 return wxWindow::Show( show );
303 }
304
305 bool wxFrame::Destroy()
306 {
307 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
308
309 if (!wxPendingDelete.Member(this)) wxPendingDelete.Append(this);
310
311 return TRUE;
312 }
313
314 void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
315 {
316 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
317
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;
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;
329
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 }
354
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;
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;
359
360 if ((m_x != -1) || (m_y != -1))
361 {
362 if ((m_x != old_x) || (m_y != old_y))
363 {
364 /* m_sizeSet = FALSE; */
365 gtk_widget_set_uposition( m_widget, m_x, m_y );
366 }
367 }
368
369 if ((m_width != old_width) || (m_height != old_height))
370 {
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. */
374 m_sizeSet = FALSE;
375 }
376
377 m_resizing = FALSE;
378 }
379
380 void wxFrame::Centre( int direction )
381 {
382 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
383
384 int x = 0;
385 int y = 0;
386
387 if ((direction & wxHORIZONTAL) == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
388 if ((direction & wxVERTICAL) == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
389
390 Move( x, y );
391 }
392
393 void wxFrame::GetClientSize( int *width, int *height ) const
394 {
395 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
396
397 wxWindow::GetClientSize( width, height );
398 if (height)
399 {
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 }
408 (*height) -= m_miniEdge*2 + m_miniTitle;
409 }
410 if (width)
411 {
412 (*width) -= m_miniEdge*2;
413 }
414 }
415
416 void wxFrame::DoSetClientSize( int width, int height )
417 {
418 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
419
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 }
429 wxWindow::DoSetClientSize( width + m_miniEdge*2, h + m_miniEdge*2 + m_miniTitle );
430 }
431
432 void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height )
433 {
434 // due to a bug in gtk, x,y are always 0
435 // m_x = x;
436 // m_y = y;
437
438 /* avoid recursions */
439 if (m_resizing) return;
440 m_resizing = TRUE;
441
442 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
443 wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" );
444
445 m_width = width;
446 m_height = height;
447
448 /* space occupied by m_frameToolBar and m_frameMenuBar */
449 int client_area_y_offset = 0;
450
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)
459 {
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 );
485
486 client_area_y_offset += hh;
487 }
488
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 );
504
505 client_area_y_offset += hh;
506 }
507
508 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset );
509 }
510
511 gtk_widget_set_usize( m_wxwindow, m_width, m_height-client_area_y_offset );
512
513 if (m_frameStatusBar)
514 {
515 int xx = 0 + m_miniEdge;
516 int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset;
517 int ww = m_width - 2*m_miniEdge;
518 int hh = wxSTATUS_HEIGHT;
519
520 m_frameStatusBar->m_x = xx;
521 m_frameStatusBar->m_y = yy;
522 m_frameStatusBar->m_width = ww;
523 m_frameStatusBar->m_height = hh;
524
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 );
527 }
528
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
532 m_sizeSet = TRUE;
533
534 /* send size event to frame */
535 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
536 event.SetEventObject( this );
537 GetEventHandler()->ProcessEvent( event );
538
539 /* send size event to status bar */
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 }
546
547 m_resizing = FALSE;
548 }
549
550 void wxFrame::OnInternalIdle()
551 {
552 if (!m_sizeSet)
553 GtkOnSize( m_x, m_y, m_width, m_height );
554
555 DoMenuUpdates();
556 }
557
558 void wxFrame::OnCloseWindow( wxCloseEvent& event )
559 {
560 Destroy();
561 }
562
563 void wxFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
564 {
565 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
566
567 if (GetAutoLayout())
568 {
569 Layout();
570 }
571 else
572 {
573 // do we have exactly one child?
574 wxWindow *child = (wxWindow *)NULL;
575 for ( wxNode *node = GetChildren().First(); node; node = node->Next() )
576 {
577 wxWindow *win = (wxWindow *)node->Data();
578 if ( !wxIS_KIND_OF(win,wxFrame) && !wxIS_KIND_OF(win,wxDialog) )
579 {
580 if ( child )
581 {
582 // it's the second one: do nothing
583 return;
584 }
585
586 child = win;
587 }
588 }
589
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 }
598 }
599 }
600
601 static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
602 {
603 menu->SetInvokingWindow( win );
604 wxNode *node = menu->GetItems().First();
605 while (node)
606 {
607 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
608 if (menuitem->IsSubMenu())
609 SetInvokingWindow( menuitem->GetSubMenu(), win );
610 node = node->Next();
611 }
612 }
613
614 void wxFrame::SetMenuBar( wxMenuBar *menuBar )
615 {
616 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
617 wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" );
618
619 m_frameMenuBar = menuBar;
620
621 if (m_frameMenuBar)
622 {
623 wxNode *node = m_frameMenuBar->GetMenus().First();
624 while (node)
625 {
626 wxMenu *menu = (wxMenu*)node->Data();
627 SetInvokingWindow( menu, this );
628 node = node->Next();
629 }
630
631 if (m_frameMenuBar->m_parent != this)
632 {
633 m_frameMenuBar->m_parent = this;
634 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget),
635 m_frameMenuBar->m_widget, m_frameMenuBar->m_x, m_frameMenuBar->m_y );
636
637 /* an mdi child menu bar might be underneath */
638 if (m_mdiMenuBar)
639 m_frameMenuBar->Show( FALSE );
640 }
641 }
642
643 m_sizeSet = FALSE;
644 }
645
646 wxMenuBar *wxFrame::GetMenuBar() const
647 {
648 return m_frameMenuBar;
649 }
650
651 void wxFrame::OnMenuHighlight(wxMenuEvent& event)
652 {
653 if (GetStatusBar())
654 {
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 )
660 {
661 wxMenuBar *menuBar = GetMenuBar();
662 if (menuBar)
663 {
664 helpString = menuBar->GetHelpString(menuId);
665 }
666 }
667
668 SetStatusText(helpString);
669 }
670 }
671
672 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
673 {
674 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
675
676 wxCHECK_MSG( m_frameToolBar == NULL, FALSE, "recreating toolbar in wxFrame" );
677
678 m_frameToolBar = OnCreateToolBar( style, id, name );
679
680 GetChildren().DeleteObject( m_frameToolBar );
681
682 m_sizeSet = FALSE;
683
684 return m_frameToolBar;
685 }
686
687 wxToolBar* wxFrame::OnCreateToolBar( long style, wxWindowID id, const wxString& name )
688 {
689 return new wxToolBar( this, id, wxDefaultPosition, wxDefaultSize, style, name );
690 }
691
692 wxToolBar *wxFrame::GetToolBar() const
693 {
694 return m_frameToolBar;
695 }
696
697 wxStatusBar* wxFrame::CreateStatusBar( int number, long style, wxWindowID id, const wxString& name )
698 {
699 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
700
701 wxCHECK_MSG( m_frameStatusBar == NULL, FALSE, "recreating status bar in wxFrame" );
702
703 m_frameStatusBar = OnCreateStatusBar( number, style, id, name );
704
705 m_sizeSet = FALSE;
706
707 return m_frameStatusBar;
708 }
709
710 wxStatusBar *wxFrame::OnCreateStatusBar( int number, long style, wxWindowID id, const wxString& name )
711 {
712 wxStatusBar *statusBar = (wxStatusBar *) NULL;
713
714 statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20), style, name);
715
716 // Set the height according to the font and the border size
717 wxClientDC dc(statusBar);
718 dc.SetFont( statusBar->GetFont() );
719
720 long x, y;
721 dc.GetTextExtent( "X", &x, &y );
722
723 int height = (int)( (y * 1.1) + 2* statusBar->GetBorderY());
724
725 statusBar->SetSize( -1, -1, 100, height );
726
727 statusBar->SetFieldsCount( number );
728 return statusBar;
729 }
730
731 void 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 }
745
746 wxEvtHandler* evtHandler = GetEventHandler();
747
748 evtHandler->ProcessEvent(commandEvent);
749 }
750
751 void wxFrame::SetStatusText(const wxString& text, int number)
752 {
753 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
754
755 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set text for" );
756
757 m_frameStatusBar->SetStatusText(text, number);
758 }
759
760 void wxFrame::SetStatusWidths(int n, const int widths_field[] )
761 {
762 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
763
764 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set widths for" );
765
766 m_frameStatusBar->SetStatusWidths(n, widths_field);
767 }
768
769 wxStatusBar *wxFrame::GetStatusBar() const
770 {
771 return m_frameStatusBar;
772 }
773
774 void wxFrame::SetTitle( const wxString &title )
775 {
776 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
777
778 m_title = title;
779 if (m_title.IsNull()) m_title = "";
780 gtk_window_set_title( GTK_WINDOW(m_widget), title );
781 }
782
783 void wxFrame::SetIcon( const wxIcon &icon )
784 {
785 wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
786
787 m_icon = icon;
788 if (!icon.Ok()) return;
789
790 wxMask *mask = icon.GetMask();
791 GdkBitmap *bm = (GdkBitmap *) NULL;
792 if (mask) bm = mask->GetBitmap();
793
794 gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
795 }
796