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
*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
);
274 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
275 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
277 /* m_mainWidget holds the toolbar, the menubar and the client area */
278 m_mainWidget
= gtk_myfixed_new();
279 gtk_widget_show( m_mainWidget
);
280 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
281 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
282 gtk_widget_realize( m_mainWidget
);
284 /* m_wxwindow only represents the client area without toolbar and menubar */
285 m_wxwindow
= gtk_myfixed_new();
286 gtk_widget_show( m_wxwindow
);
287 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
288 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
290 if (m_parent
) m_parent
->AddChild( this );
294 gtk_widget_realize( m_widget
);
296 /* all this is for Motif Window Manager "hints" and is supposed to be
297 recognized by other WM as well. not tested. */
298 long decor
= (long) GDK_DECOR_ALL
;
299 long func
= (long) GDK_FUNC_ALL
;
301 if ((m_windowStyle
& wxCAPTION
) == 0)
302 decor
|= GDK_DECOR_TITLE
;
303 /* if ((m_windowStyle & wxMINIMIZE) == 0)
304 func |= GDK_FUNC_MINIMIZE;
305 if ((m_windowStyle & wxMAXIMIZE) == 0)
306 func |= GDK_FUNC_MAXIMIZE; */
307 if ((m_windowStyle
& wxSYSTEM_MENU
) == 0)
308 decor
|= GDK_DECOR_MENU
;
309 if ((m_windowStyle
& wxMINIMIZE_BOX
) == 0)
310 decor
|= GDK_DECOR_MINIMIZE
;
311 if ((m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
312 decor
|= GDK_DECOR_MAXIMIZE
;
313 if ((m_windowStyle
& wxRESIZE_BORDER
) == 0)
314 func
|= GDK_FUNC_RESIZE
;
316 gdk_window_set_decorations(m_widget
->window
, (GdkWMDecoration
)decor
);
317 gdk_window_set_functions(m_widget
->window
, (GdkWMFunction
)func
);
319 /* GTK's shrinking/growing policy */
320 if ((m_windowStyle
& wxRESIZE_BORDER
) == 0)
321 gtk_window_set_policy(GTK_WINDOW(m_widget
), 0, 0, 1);
323 gtk_window_set_policy(GTK_WINDOW(m_widget
), 1, 1, 1);
325 /* the user resized the frame by dragging etc. */
326 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
327 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
329 /* the only way to get the window size is to connect to this event */
330 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
331 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
338 if (m_frameMenuBar
) delete m_frameMenuBar
;
339 m_frameMenuBar
= (wxMenuBar
*) NULL
;
341 if (m_frameStatusBar
) delete m_frameStatusBar
;
342 m_frameStatusBar
= (wxStatusBar
*) NULL
;
344 if (m_frameToolBar
) delete m_frameToolBar
;
345 m_frameToolBar
= (wxToolBar
*) NULL
;
347 wxTopLevelWindows
.DeleteObject( this );
349 if (wxTheApp
->GetTopWindow() == this)
350 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
352 if (wxTopLevelWindows
.Number() == 0)
353 wxTheApp
->ExitMainLoop();
356 bool wxFrame::Show( bool show
)
358 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
360 if (show
&& !m_sizeSet
)
362 /* by calling GtkOnSize here, we don't have to call
363 either after showing the frame, which would entail
364 much ugly flicker or from within the size_allocate
365 handler, because GTK 1.1.X forbids that. */
367 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
370 return wxWindow::Show( show
);
373 bool wxFrame::Destroy()
375 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
377 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
382 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
384 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
386 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
387 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
389 /* avoid recursions */
390 if (m_resizing
) return;
395 int old_width
= m_width
;
396 int old_height
= m_height
;
398 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
400 if (x
!= -1) m_x
= x
;
401 if (y
!= -1) m_y
= y
;
402 if (width
!= -1) m_width
= width
;
403 if (height
!= -1) m_height
= height
;
413 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
415 if (width
== -1) m_width
= 80;
418 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
420 if (height
== -1) m_height
= 26;
423 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
424 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
425 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
426 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
428 if ((m_x
!= -1) || (m_y
!= -1))
430 if ((m_x
!= old_x
) || (m_y
!= old_y
))
432 /* m_sizeSet = FALSE; */
433 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
437 if ((m_width
!= old_width
) || (m_height
!= old_height
))
439 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
440 done either directly before the frame is shown or in idle time
441 so that different calls to SetSize() don't lead to flicker. */
448 void wxFrame::Centre( int direction
)
450 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
455 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
456 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
461 void wxFrame::GetClientSize( int *width
, int *height
) const
463 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
465 wxWindow::GetClientSize( width
, height
);
471 if (!m_menuBarDetached
)
472 (*height
) -= wxMENU_HEIGHT
;
474 (*height
) -= wxPLACE_HOLDER
;
478 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
483 if (!m_toolBarDetached
)
486 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
490 (*height
) -= wxPLACE_HOLDER
;
494 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
498 (*width
) -= m_miniEdge
*2;
502 void wxFrame::DoSetClientSize( int width
, int height
)
504 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
509 if (!m_menuBarDetached
)
510 height
+= wxMENU_HEIGHT
;
512 height
+= wxPLACE_HOLDER
;
516 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
521 if (!m_toolBarDetached
)
524 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
528 height
+= wxPLACE_HOLDER
;
531 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
534 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
536 // due to a bug in gtk, x,y are always 0
540 /* avoid recursions */
541 if (m_resizing
) return;
544 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
545 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
550 /* space occupied by m_frameToolBar and m_frameMenuBar */
551 int client_area_y_offset
= 0;
553 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
554 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
555 set in wxFrame::Create so it is used to check what kind of frame we
556 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
557 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
558 importantly) m_mainWidget */
562 /* check if size is in legal range */
563 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
564 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
565 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
566 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
568 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
569 * menubar, the toolbar and the client area, which is represented by
571 * this hurts in the eye, but I don't want to call SetSize()
572 * because I don't want to call any non-native functions here. */
577 int yy
= m_miniEdge
+ m_miniTitle
;
578 int ww
= m_width
- 2*m_miniEdge
;
579 int hh
= wxMENU_HEIGHT
;
580 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
581 m_frameMenuBar
->m_x
= xx
;
582 m_frameMenuBar
->m_y
= yy
;
583 m_frameMenuBar
->m_width
= ww
;
584 m_frameMenuBar
->m_height
= hh
;
586 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
587 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
589 client_area_y_offset
+= hh
;
595 int yy
= m_miniEdge
+ m_miniTitle
;
598 if (!m_menuBarDetached
)
601 yy
+= wxPLACE_HOLDER
;
603 int ww
= m_width
- 2*m_miniEdge
;
604 int hh
= m_frameToolBar
->m_height
;
605 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
606 m_frameToolBar
->m_x
= xx
;
607 m_frameToolBar
->m_y
= yy
;
608 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
609 m_frameToolBar
->m_width
= ww
;
611 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
612 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
614 client_area_y_offset
+= hh
;
617 int client_x
= m_miniEdge
;
618 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
619 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
621 int client_w
= m_width
- 2*m_miniEdge
;
622 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
623 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
627 /* if there is no m_mainWidget between m_widget and m_wxwindow there
628 is no need to set the size or position of m_wxwindow. */
631 if (m_frameStatusBar
)
633 int xx
= 0 + m_miniEdge
;
634 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
635 int ww
= m_width
- 2*m_miniEdge
;
636 int hh
= wxSTATUS_HEIGHT
;
638 m_frameStatusBar
->m_x
= xx
;
639 m_frameStatusBar
->m_y
= yy
;
640 m_frameStatusBar
->m_width
= ww
;
641 m_frameStatusBar
->m_height
= hh
;
643 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
644 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
647 /* we actually set the size of a frame here and no-where else */
648 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
652 /* send size event to frame */
653 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
654 event
.SetEventObject( this );
655 GetEventHandler()->ProcessEvent( event
);
657 /* send size event to status bar */
658 if (m_frameStatusBar
)
660 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
661 event2
.SetEventObject( m_frameStatusBar
);
662 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
668 void wxFrame::OnInternalIdle()
671 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
676 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
681 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
683 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
691 // do we have exactly one child?
692 wxWindow
*child
= (wxWindow
*)NULL
;
693 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
695 wxWindow
*win
= (wxWindow
*)node
->Data();
696 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
700 // it's the second one: do nothing
708 // no children at all?
711 // yes: set it's size to fill all the frame
712 int client_x
, client_y
;
713 GetClientSize( &client_x
, &client_y
);
714 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
719 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
721 menu
->SetInvokingWindow( win
);
722 wxNode
*node
= menu
->GetItems().First();
725 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
726 if (menuitem
->IsSubMenu())
727 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
732 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
734 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
735 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
737 m_frameMenuBar
= menuBar
;
741 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
744 wxMenu
*menu
= (wxMenu
*)node
->Data();
745 SetInvokingWindow( menu
, this );
749 if (m_frameMenuBar
->m_parent
!= this)
751 m_frameMenuBar
->m_parent
= this;
752 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
753 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
755 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
757 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
758 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
760 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
761 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
769 wxMenuBar
*wxFrame::GetMenuBar() const
771 return m_frameMenuBar
;
774 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
778 // if no help string found, we will clear the status bar text
781 int menuId
= event
.GetMenuId();
784 wxMenuBar
*menuBar
= GetMenuBar();
787 helpString
= menuBar
->GetHelpString(menuId
);
791 SetStatusText(helpString
);
795 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
797 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
799 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
801 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
803 GetChildren().DeleteObject( m_frameToolBar
);
807 return m_frameToolBar
;
810 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
812 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
815 wxToolBar
*wxFrame::GetToolBar() const
817 return m_frameToolBar
;
820 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
822 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
824 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
826 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
830 return m_frameStatusBar
;
833 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
835 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
837 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
839 // Set the height according to the font and the border size
840 wxClientDC
dc(statusBar
);
841 dc
.SetFont( statusBar
->GetFont() );
844 dc
.GetTextExtent( "X", &x
, &y
);
846 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
848 statusBar
->SetSize( -1, -1, 100, height
);
850 statusBar
->SetFieldsCount( number
);
854 void wxFrame::Command( int id
)
856 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
857 commandEvent
.SetInt( id
);
858 commandEvent
.SetEventObject( this );
860 wxMenuBar
*bar
= GetMenuBar();
863 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
864 if (item
&& item
->IsCheckable())
866 bar
->Check(id
,!bar
->Checked(id
)) ;
869 wxEvtHandler
* evtHandler
= GetEventHandler();
871 evtHandler
->ProcessEvent(commandEvent
);
874 void wxFrame::SetStatusText(const wxString
& text
, int number
)
876 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
878 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
880 m_frameStatusBar
->SetStatusText(text
, number
);
883 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
885 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
887 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
889 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
892 wxStatusBar
*wxFrame::GetStatusBar() const
894 return m_frameStatusBar
;
897 void wxFrame::SetTitle( const wxString
&title
)
899 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
902 if (m_title
.IsNull()) m_title
= _T("");
903 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
906 void wxFrame::SetIcon( const wxIcon
&icon
)
908 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
911 if (!icon
.Ok()) return;
913 wxMask
*mask
= icon
.GetMask();
914 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
915 if (mask
) bm
= mask
->GetBitmap();
917 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);