1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "frame.h"
15 #include "wx/dialog.h"
16 #include "wx/control.h"
19 #include "wx/toolbar.h"
20 #include "wx/statusbr.h"
21 #include "wx/dcclient.h"
26 #include "wx/gtk/win_gtk.h"
28 //-----------------------------------------------------------------------------
30 //-----------------------------------------------------------------------------
32 const int wxMENU_HEIGHT
= 27;
33 const int wxSTATUS_HEIGHT
= 25;
34 const int wxPLACE_HOLDER
= 0;
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
40 extern wxList wxPendingDelete
;
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
48 if (!win
->HasVMT()) return;
51 printf( "OnFrameResize from " );
52 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
53 printf( win->GetClassInfo()->GetClassName() );
57 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
59 win
->m_sizeSet
= FALSE
;
60 win
->m_width
= alloc
->width
;
61 win
->m_height
= alloc
->height
;
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
72 printf( "OnDelete from " );
73 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
74 printf( win->GetClassInfo()->GetClassName() );
83 //-----------------------------------------------------------------------------
84 // "child_attached" of menu bar
85 //-----------------------------------------------------------------------------
87 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
89 if (!win
->HasVMT()) return;
91 win
->m_menuBarDetached
= FALSE
;
92 win
->m_sizeSet
= FALSE
;
95 //-----------------------------------------------------------------------------
96 // "child_detached" of menu bar
97 //-----------------------------------------------------------------------------
99 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
101 if (!win
->HasVMT()) return;
103 win
->m_menuBarDetached
= TRUE
;
104 win
->m_sizeSet
= FALSE
;
107 //-----------------------------------------------------------------------------
108 // "child_attached" of tool bar
109 //-----------------------------------------------------------------------------
111 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
113 if (!win
->HasVMT()) return;
115 win
->m_toolBarDetached
= FALSE
;
116 win
->m_sizeSet
= FALSE
;
119 //-----------------------------------------------------------------------------
120 // "child_detached" of tool bar
121 //-----------------------------------------------------------------------------
123 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
125 if (!win
->HasVMT()) return;
127 win
->m_toolBarDetached
= TRUE
;
128 win
->m_sizeSet
= FALSE
;
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
135 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
137 if (!win
->HasVMT()) return FALSE
;
142 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
143 mevent
.SetEventObject( win
);
144 win
->GetEventHandler()->ProcessEvent( mevent
);
149 //-----------------------------------------------------------------------------
150 // InsertChild for wxFrame
151 //-----------------------------------------------------------------------------
153 /* Callback for wxFrame. This very strange beast has to be used because
154 * C++ has no virtual methods in a constructor. We have to emulate a
155 * virtual function here as wxWindows requires different ways to insert
156 * a child in container classes. */
158 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
160 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
162 /* actually, menubars are never inserted here, but this
163 may change one day */
165 /* these are outside the client area */
166 wxFrame
* frame
= (wxFrame
*) parent
;
167 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
168 GTK_WIDGET(child
->m_widget
),
172 /* we connect to these events for recalculating the client area
173 space when the toolbar is floating */
174 if (wxIS_KIND_OF(child
,wxToolBar
))
176 wxToolBar
*toolBar
= (wxToolBar
*) child
;
177 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
179 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
180 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
182 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
183 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
189 /* these are inside the client area */
190 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
191 GTK_WIDGET(child
->m_widget
),
196 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
200 /* resize on OnInternalIdle */
201 parent
->m_sizeSet
= FALSE
;
203 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
205 /* we now allow a window to get the focus as long as it
206 doesn't have any children. */
207 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
211 //-----------------------------------------------------------------------------
213 //-----------------------------------------------------------------------------
215 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
216 EVT_SIZE(wxFrame::OnSize
)
217 EVT_CLOSE(wxFrame::OnCloseWindow
)
218 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
221 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
225 m_frameMenuBar
= (wxMenuBar
*) NULL
;
226 m_frameStatusBar
= (wxStatusBar
*) NULL
;
227 m_frameToolBar
= (wxToolBar
*) NULL
;
231 m_mainWidget
= (GtkWidget
*) NULL
;
232 m_menuBarDetached
= FALSE
;
233 m_toolBarDetached
= FALSE
;
236 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
237 const wxPoint
&pos
, const wxSize
&size
,
238 long style
, const wxString
&name
)
240 m_frameMenuBar
= (wxMenuBar
*) NULL
;
241 m_frameStatusBar
= (wxStatusBar
*) NULL
;
242 m_frameToolBar
= (wxToolBar
*) NULL
;
246 m_mainWidget
= (GtkWidget
*) NULL
;
247 m_menuBarDetached
= FALSE
;
248 m_toolBarDetached
= FALSE
;
249 Create( parent
, id
, title
, pos
, size
, style
, name
);
252 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
253 const wxPoint
&pos
, const wxSize
&size
,
254 long style
, const wxString
&name
)
256 wxTopLevelWindows
.Append( this );
258 m_needParent
= FALSE
;
260 PreCreation( parent
, id
, pos
, size
, style
, name
);
264 m_insertCallback
= wxInsertChildInFrame
;
266 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
267 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
269 m_widget
= gtk_window_new( win_type
);
271 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
272 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
275 gtk_window_set_policy( GTK_WINDOW(m_widget
), 1, 1, 0 );
277 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
278 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
280 /* m_mainWidget holds the toolbar, the menubar and the client area */
281 m_mainWidget
= gtk_myfixed_new();
282 gtk_widget_show( m_mainWidget
);
283 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
284 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
285 gtk_widget_realize( m_mainWidget
);
287 /* m_wxwindow only represents the client area without toolbar and menubar */
288 m_wxwindow
= gtk_myfixed_new();
289 gtk_widget_show( m_wxwindow
);
290 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
291 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
293 if (m_parent
) m_parent
->AddChild( this );
297 gtk_widget_realize( m_widget
);
299 /* all this is for Motif Window Manager "hints" and is supposed to be
300 recognized by other WM as well. not tested. */
301 long decor
= (long) GDK_DECOR_ALL
;
302 long func
= (long) GDK_FUNC_ALL
;
304 if ((m_windowStyle
& wxCAPTION
) == 0)
305 decor
|= GDK_DECOR_TITLE
;
306 /* if ((m_windowStyle & wxMINIMIZE) == 0)
307 func |= GDK_FUNC_MINIMIZE;
308 if ((m_windowStyle & wxMAXIMIZE) == 0)
309 func |= GDK_FUNC_MAXIMIZE; */
310 if ((m_windowStyle
& wxSYSTEM_MENU
) == 0)
311 decor
|= GDK_DECOR_MENU
;
312 if ((m_windowStyle
& wxMINIMIZE_BOX
) == 0)
313 decor
|= GDK_DECOR_MINIMIZE
;
314 if ((m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
315 decor
|= GDK_DECOR_MAXIMIZE
;
316 if ((m_windowStyle
& wxRESIZE_BORDER
) == 0)
317 func
|= GDK_FUNC_RESIZE
;
319 gdk_window_set_decorations(m_widget
->window
, (GdkWMDecoration
)decor
);
320 gdk_window_set_functions(m_widget
->window
, (GdkWMFunction
)func
);
322 /* the user resized the frame by dragging etc. */
323 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
324 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
326 /* the only way to get the window size is to connect to this event */
327 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
328 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
335 if (m_frameMenuBar
) delete m_frameMenuBar
;
336 m_frameMenuBar
= (wxMenuBar
*) NULL
;
338 if (m_frameStatusBar
) delete m_frameStatusBar
;
339 m_frameStatusBar
= (wxStatusBar
*) NULL
;
341 if (m_frameToolBar
) delete m_frameToolBar
;
342 m_frameToolBar
= (wxToolBar
*) NULL
;
344 wxTopLevelWindows
.DeleteObject( this );
346 if (wxTheApp
->GetTopWindow() == this)
347 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
349 if (wxTopLevelWindows
.Number() == 0)
350 wxTheApp
->ExitMainLoop();
353 bool wxFrame::Show( bool show
)
355 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
357 if (show
&& !m_sizeSet
)
359 /* by calling GtkOnSize here, we don't have to call
360 either after showing the frame, which would entail
361 much ugly flicker or from within the size_allocate
362 handler, because GTK 1.1.X forbids that. */
364 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
367 return wxWindow::Show( show
);
370 bool wxFrame::Destroy()
372 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
374 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
379 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
381 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
383 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
384 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
386 /* avoid recursions */
387 if (m_resizing
) return;
392 int old_width
= m_width
;
393 int old_height
= m_height
;
395 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
397 if (x
!= -1) m_x
= x
;
398 if (y
!= -1) m_y
= y
;
399 if (width
!= -1) m_width
= width
;
400 if (height
!= -1) m_height
= height
;
410 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
412 if (width
== -1) m_width
= 80;
415 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
417 if (height
== -1) m_height
= 26;
420 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
421 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
422 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
423 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
425 if ((m_x
!= -1) || (m_y
!= -1))
427 if ((m_x
!= old_x
) || (m_y
!= old_y
))
429 /* m_sizeSet = FALSE; */
430 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
434 if ((m_width
!= old_width
) || (m_height
!= old_height
))
436 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
437 done either directly before the frame is shown or in idle time
438 so that different calls to SetSize() don't lead to flicker. */
445 void wxFrame::Centre( int direction
)
447 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
452 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
453 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
458 void wxFrame::GetClientSize( int *width
, int *height
) const
460 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
462 wxWindow::GetClientSize( width
, height
);
468 if (!m_menuBarDetached
)
469 (*height
) -= wxMENU_HEIGHT
;
471 (*height
) -= wxPLACE_HOLDER
;
475 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
480 if (!m_toolBarDetached
)
483 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
487 (*height
) -= wxPLACE_HOLDER
;
491 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
495 (*width
) -= m_miniEdge
*2;
499 void wxFrame::DoSetClientSize( int width
, int height
)
501 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
506 if (!m_menuBarDetached
)
507 height
+= wxMENU_HEIGHT
;
509 height
+= wxPLACE_HOLDER
;
513 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
518 if (!m_toolBarDetached
)
521 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
525 height
+= wxPLACE_HOLDER
;
528 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
531 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
533 // due to a bug in gtk, x,y are always 0
537 /* avoid recursions */
538 if (m_resizing
) return;
541 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
542 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
547 /* space occupied by m_frameToolBar and m_frameMenuBar */
548 int client_area_y_offset
= 0;
550 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
551 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
552 set in wxFrame::Create so it is used to check what kind of frame we
553 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
554 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
555 importantly) m_mainWidget */
559 /* check if size is in legal range */
560 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
561 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
562 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
563 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
565 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
566 * menubar, the toolbar and the client area, which is represented by
568 * this hurts in the eye, but I don't want to call SetSize()
569 * because I don't want to call any non-native functions here. */
574 int yy
= m_miniEdge
+ m_miniTitle
;
575 int ww
= m_width
- 2*m_miniEdge
;
576 int hh
= wxMENU_HEIGHT
;
577 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
578 m_frameMenuBar
->m_x
= xx
;
579 m_frameMenuBar
->m_y
= yy
;
580 m_frameMenuBar
->m_width
= ww
;
581 m_frameMenuBar
->m_height
= hh
;
583 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
584 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
586 client_area_y_offset
+= hh
;
592 int yy
= m_miniEdge
+ m_miniTitle
;
595 if (!m_menuBarDetached
)
598 yy
+= wxPLACE_HOLDER
;
600 int ww
= m_width
- 2*m_miniEdge
;
601 int hh
= m_frameToolBar
->m_height
;
602 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
603 m_frameToolBar
->m_x
= xx
;
604 m_frameToolBar
->m_y
= yy
;
605 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
606 m_frameToolBar
->m_width
= ww
;
608 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
609 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
611 client_area_y_offset
+= hh
;
614 int client_x
= m_miniEdge
;
615 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
616 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
618 int client_w
= m_width
- 2*m_miniEdge
;
619 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
620 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
624 /* if there is no m_mainWidget between m_widget and m_wxwindow there
625 is no need to set the size or position of m_wxwindow. */
628 if (m_frameStatusBar
)
630 int xx
= 0 + m_miniEdge
;
631 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
632 int ww
= m_width
- 2*m_miniEdge
;
633 int hh
= wxSTATUS_HEIGHT
;
635 m_frameStatusBar
->m_x
= xx
;
636 m_frameStatusBar
->m_y
= yy
;
637 m_frameStatusBar
->m_width
= ww
;
638 m_frameStatusBar
->m_height
= hh
;
640 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
641 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
644 /* we actually set the size of a frame here and no-where else */
645 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
649 /* send size event to frame */
650 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
651 event
.SetEventObject( this );
652 GetEventHandler()->ProcessEvent( event
);
654 /* send size event to status bar */
655 if (m_frameStatusBar
)
657 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
658 event2
.SetEventObject( m_frameStatusBar
);
659 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
665 void wxFrame::OnInternalIdle()
668 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
673 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
678 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
680 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
688 // do we have exactly one child?
689 wxWindow
*child
= (wxWindow
*)NULL
;
690 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
692 wxWindow
*win
= (wxWindow
*)node
->Data();
693 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
697 // it's the second one: do nothing
705 // no children at all?
708 // yes: set it's size to fill all the frame
709 int client_x
, client_y
;
710 GetClientSize( &client_x
, &client_y
);
711 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
716 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
718 menu
->SetInvokingWindow( win
);
719 wxNode
*node
= menu
->GetItems().First();
722 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
723 if (menuitem
->IsSubMenu())
724 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
729 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
731 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
732 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
734 m_frameMenuBar
= menuBar
;
738 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
741 wxMenu
*menu
= (wxMenu
*)node
->Data();
742 SetInvokingWindow( menu
, this );
746 if (m_frameMenuBar
->m_parent
!= this)
748 m_frameMenuBar
->m_parent
= this;
749 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
750 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
752 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
754 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
755 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
757 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
758 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
766 wxMenuBar
*wxFrame::GetMenuBar() const
768 return m_frameMenuBar
;
771 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
775 // if no help string found, we will clear the status bar text
778 int menuId
= event
.GetMenuId();
781 wxMenuBar
*menuBar
= GetMenuBar();
784 helpString
= menuBar
->GetHelpString(menuId
);
788 SetStatusText(helpString
);
792 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
794 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
796 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
798 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
800 GetChildren().DeleteObject( m_frameToolBar
);
804 return m_frameToolBar
;
807 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
809 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
812 wxToolBar
*wxFrame::GetToolBar() const
814 return m_frameToolBar
;
817 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
819 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
821 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
823 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
827 return m_frameStatusBar
;
830 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
832 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
834 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
836 // Set the height according to the font and the border size
837 wxClientDC
dc(statusBar
);
838 dc
.SetFont( statusBar
->GetFont() );
841 dc
.GetTextExtent( "X", &x
, &y
);
843 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
845 statusBar
->SetSize( -1, -1, 100, height
);
847 statusBar
->SetFieldsCount( number
);
851 void wxFrame::Command( int id
)
853 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
854 commandEvent
.SetInt( id
);
855 commandEvent
.SetEventObject( this );
857 wxMenuBar
*bar
= GetMenuBar();
860 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
861 if (item
&& item
->IsCheckable())
863 bar
->Check(id
,!bar
->Checked(id
)) ;
866 wxEvtHandler
* evtHandler
= GetEventHandler();
868 evtHandler
->ProcessEvent(commandEvent
);
871 void wxFrame::SetStatusText(const wxString
& text
, int number
)
873 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
875 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
877 m_frameStatusBar
->SetStatusText(text
, number
);
880 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
882 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
884 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
886 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
889 wxStatusBar
*wxFrame::GetStatusBar() const
891 return m_frameStatusBar
;
894 void wxFrame::SetTitle( const wxString
&title
)
896 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
899 if (m_title
.IsNull()) m_title
= _T("");
900 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
903 void wxFrame::SetIcon( const wxIcon
&icon
)
905 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
908 if (!icon
.Ok()) return;
910 wxMask
*mask
= icon
.GetMask();
911 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
912 if (mask
) bm
= mask
->GetBitmap();
914 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);