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
;
234 m_insertCallback
= wxInsertChildInFrame
;
237 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
238 const wxPoint
&pos
, const wxSize
&size
,
239 long style
, const wxString
&name
)
241 m_frameMenuBar
= (wxMenuBar
*) NULL
;
242 m_frameStatusBar
= (wxStatusBar
*) NULL
;
243 m_frameToolBar
= (wxToolBar
*) NULL
;
247 m_mainWidget
= (GtkWidget
*) NULL
;
248 m_menuBarDetached
= FALSE
;
249 m_toolBarDetached
= FALSE
;
250 m_insertCallback
= wxInsertChildInFrame
;
251 Create( parent
, id
, title
, pos
, size
, style
, name
);
254 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
255 const wxPoint
&pos
, const wxSize
&size
,
256 long style
, const wxString
&name
)
258 wxTopLevelWindows
.Append( this );
260 m_needParent
= FALSE
;
262 PreCreation( parent
, id
, pos
, size
, style
, name
);
266 m_insertCallback
= wxInsertChildInFrame
;
268 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
269 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
271 m_widget
= gtk_window_new( win_type
);
273 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
274 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
276 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
277 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
279 /* m_mainWidget holds the toolbar, the menubar and the client area */
280 m_mainWidget
= gtk_myfixed_new();
281 gtk_widget_show( m_mainWidget
);
282 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
283 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
284 gtk_widget_realize( m_mainWidget
);
286 /* m_wxwindow only represents the client area without toolbar and menubar */
287 m_wxwindow
= gtk_myfixed_new();
288 gtk_widget_show( m_wxwindow
);
289 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
290 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
292 if (m_parent
) m_parent
->AddChild( this );
296 gtk_widget_realize( m_widget
);
298 /* all this is for Motif Window Manager "hints" and is supposed to be
299 recognized by other WM as well. not tested. */
300 long decor
= (long) GDK_DECOR_ALL
;
301 long func
= (long) GDK_FUNC_ALL
;
303 if ((m_windowStyle
& wxCAPTION
) == 0)
304 decor
|= GDK_DECOR_TITLE
;
305 /* if ((m_windowStyle & wxMINIMIZE) == 0)
306 func |= GDK_FUNC_MINIMIZE;
307 if ((m_windowStyle & wxMAXIMIZE) == 0)
308 func |= GDK_FUNC_MAXIMIZE; */
309 if ((m_windowStyle
& wxSYSTEM_MENU
) == 0)
310 decor
|= GDK_DECOR_MENU
;
311 if ((m_windowStyle
& wxMINIMIZE_BOX
) == 0)
312 decor
|= GDK_DECOR_MINIMIZE
;
313 if ((m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
314 decor
|= GDK_DECOR_MAXIMIZE
;
315 if ((m_windowStyle
& wxRESIZE_BORDER
) == 0)
316 func
|= GDK_FUNC_RESIZE
;
318 gdk_window_set_decorations(m_widget
->window
, (GdkWMDecoration
)decor
);
319 gdk_window_set_functions(m_widget
->window
, (GdkWMFunction
)func
);
321 /* GTK's shrinking/growing policy */
322 if ((m_windowStyle
& wxRESIZE_BORDER
) == 0)
323 gtk_window_set_policy(GTK_WINDOW(m_widget
), 0, 0, 1);
325 gtk_window_set_policy(GTK_WINDOW(m_widget
), 1, 1, 1);
327 /* the user resized the frame by dragging etc. */
328 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
329 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
331 /* the only way to get the window size is to connect to this event */
332 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
333 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
340 if (m_frameMenuBar
) delete m_frameMenuBar
;
341 m_frameMenuBar
= (wxMenuBar
*) NULL
;
343 if (m_frameStatusBar
) delete m_frameStatusBar
;
344 m_frameStatusBar
= (wxStatusBar
*) NULL
;
346 if (m_frameToolBar
) delete m_frameToolBar
;
347 m_frameToolBar
= (wxToolBar
*) NULL
;
349 wxTopLevelWindows
.DeleteObject( this );
351 if (wxTheApp
->GetTopWindow() == this)
352 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
354 if (wxTopLevelWindows
.Number() == 0)
355 wxTheApp
->ExitMainLoop();
358 bool wxFrame::Show( bool show
)
360 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
362 if (show
&& !m_sizeSet
)
364 /* by calling GtkOnSize here, we don't have to call
365 either after showing the frame, which would entail
366 much ugly flicker or from within the size_allocate
367 handler, because GTK 1.1.X forbids that. */
369 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
372 return wxWindow::Show( show
);
375 bool wxFrame::Destroy()
377 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
379 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
384 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
386 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
388 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
389 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
391 /* avoid recursions */
392 if (m_resizing
) return;
397 int old_width
= m_width
;
398 int old_height
= m_height
;
400 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
402 if (x
!= -1) m_x
= x
;
403 if (y
!= -1) m_y
= y
;
404 if (width
!= -1) m_width
= width
;
405 if (height
!= -1) m_height
= height
;
415 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
417 if (width
== -1) m_width
= 80;
420 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
422 if (height
== -1) m_height
= 26;
425 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
426 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
427 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
428 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
430 if ((m_x
!= -1) || (m_y
!= -1))
432 if ((m_x
!= old_x
) || (m_y
!= old_y
))
434 /* m_sizeSet = FALSE; */
435 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
439 if ((m_width
!= old_width
) || (m_height
!= old_height
))
441 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
442 done either directly before the frame is shown or in idle time
443 so that different calls to SetSize() don't lead to flicker. */
450 void wxFrame::Centre( int direction
)
452 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
457 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
458 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
463 void wxFrame::GetClientSize( int *width
, int *height
) const
465 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
467 wxWindow::GetClientSize( width
, height
);
473 if (!m_menuBarDetached
)
474 (*height
) -= wxMENU_HEIGHT
;
476 (*height
) -= wxPLACE_HOLDER
;
480 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
485 if (!m_toolBarDetached
)
488 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
492 (*height
) -= wxPLACE_HOLDER
;
496 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
500 (*width
) -= m_miniEdge
*2;
504 void wxFrame::DoSetClientSize( int width
, int height
)
506 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
511 if (!m_menuBarDetached
)
512 height
+= wxMENU_HEIGHT
;
514 height
+= wxPLACE_HOLDER
;
518 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
523 if (!m_toolBarDetached
)
526 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
530 height
+= wxPLACE_HOLDER
;
533 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
536 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
538 // due to a bug in gtk, x,y are always 0
542 /* avoid recursions */
543 if (m_resizing
) return;
546 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
547 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
552 /* space occupied by m_frameToolBar and m_frameMenuBar */
553 int client_area_y_offset
= 0;
555 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
556 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
557 set in wxFrame::Create so it is used to check what kind of frame we
558 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
559 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
560 importantly) m_mainWidget */
564 /* check if size is in legal range */
565 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
566 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
567 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
568 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
570 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
571 * menubar, the toolbar and the client area, which is represented by
573 * this hurts in the eye, but I don't want to call SetSize()
574 * because I don't want to call any non-native functions here. */
579 int yy
= m_miniEdge
+ m_miniTitle
;
580 int ww
= m_width
- 2*m_miniEdge
;
581 int hh
= wxMENU_HEIGHT
;
582 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
583 m_frameMenuBar
->m_x
= xx
;
584 m_frameMenuBar
->m_y
= yy
;
585 m_frameMenuBar
->m_width
= ww
;
586 m_frameMenuBar
->m_height
= hh
;
588 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
589 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
591 client_area_y_offset
+= hh
;
597 int yy
= m_miniEdge
+ m_miniTitle
;
600 if (!m_menuBarDetached
)
603 yy
+= wxPLACE_HOLDER
;
605 int ww
= m_width
- 2*m_miniEdge
;
606 int hh
= m_frameToolBar
->m_height
;
607 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
608 m_frameToolBar
->m_x
= xx
;
609 m_frameToolBar
->m_y
= yy
;
610 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
611 m_frameToolBar
->m_width
= ww
;
613 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
614 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
616 client_area_y_offset
+= hh
;
619 int client_x
= m_miniEdge
;
620 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
621 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
623 int client_w
= m_width
- 2*m_miniEdge
;
624 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
625 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
629 /* if there is no m_mainWidget between m_widget and m_wxwindow there
630 is no need to set the size or position of m_wxwindow. */
633 if (m_frameStatusBar
)
635 int xx
= 0 + m_miniEdge
;
636 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
637 int ww
= m_width
- 2*m_miniEdge
;
638 int hh
= wxSTATUS_HEIGHT
;
640 m_frameStatusBar
->m_x
= xx
;
641 m_frameStatusBar
->m_y
= yy
;
642 m_frameStatusBar
->m_width
= ww
;
643 m_frameStatusBar
->m_height
= hh
;
645 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
646 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
649 /* we actually set the size of a frame here and no-where else */
650 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
654 /* send size event to frame */
655 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
656 event
.SetEventObject( this );
657 GetEventHandler()->ProcessEvent( event
);
659 /* send size event to status bar */
660 if (m_frameStatusBar
)
662 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
663 event2
.SetEventObject( m_frameStatusBar
);
664 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
670 void wxFrame::OnInternalIdle()
673 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
678 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
683 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
685 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
693 // do we have exactly one child?
694 wxWindow
*child
= (wxWindow
*)NULL
;
695 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
697 wxWindow
*win
= (wxWindow
*)node
->Data();
698 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
702 // it's the second one: do nothing
710 // no children at all?
713 // yes: set it's size to fill all the frame
714 int client_x
, client_y
;
715 GetClientSize( &client_x
, &client_y
);
716 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
721 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
723 menu
->SetInvokingWindow( win
);
724 wxNode
*node
= menu
->GetItems().First();
727 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
728 if (menuitem
->IsSubMenu())
729 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
734 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
736 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
737 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
739 m_frameMenuBar
= menuBar
;
743 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
746 wxMenu
*menu
= (wxMenu
*)node
->Data();
747 SetInvokingWindow( menu
, this );
751 if (m_frameMenuBar
->m_parent
!= this)
753 m_frameMenuBar
->m_parent
= this;
754 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
755 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
757 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
759 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
760 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
762 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
763 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
771 wxMenuBar
*wxFrame::GetMenuBar() const
773 return m_frameMenuBar
;
776 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
780 // if no help string found, we will clear the status bar text
783 int menuId
= event
.GetMenuId();
786 wxMenuBar
*menuBar
= GetMenuBar();
789 helpString
= menuBar
->GetHelpString(menuId
);
793 SetStatusText(helpString
);
797 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
799 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
801 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
803 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
805 GetChildren().DeleteObject( m_frameToolBar
);
809 return m_frameToolBar
;
812 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
814 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
817 wxToolBar
*wxFrame::GetToolBar() const
819 return m_frameToolBar
;
822 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
824 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
826 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
828 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
832 return m_frameStatusBar
;
835 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
837 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
839 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
841 // Set the height according to the font and the border size
842 wxClientDC
dc(statusBar
);
843 dc
.SetFont( statusBar
->GetFont() );
846 dc
.GetTextExtent( "X", &x
, &y
);
848 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
850 statusBar
->SetSize( -1, -1, 100, height
);
852 statusBar
->SetFieldsCount( number
);
856 void wxFrame::Command( int id
)
858 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
859 commandEvent
.SetInt( id
);
860 commandEvent
.SetEventObject( this );
862 wxMenuBar
*bar
= GetMenuBar();
865 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
866 if (item
&& item
->IsCheckable())
868 bar
->Check(id
,!bar
->Checked(id
)) ;
871 wxEvtHandler
* evtHandler
= GetEventHandler();
873 evtHandler
->ProcessEvent(commandEvent
);
876 void wxFrame::SetStatusText(const wxString
& text
, int number
)
878 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
880 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
882 m_frameStatusBar
->SetStatusText(text
, number
);
885 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
887 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
889 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
891 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
894 wxStatusBar
*wxFrame::GetStatusBar() const
896 return m_frameStatusBar
;
899 void wxFrame::SetTitle( const wxString
&title
)
901 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
904 if (m_title
.IsNull()) m_title
= _T("");
905 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
908 void wxFrame::SetIcon( const wxIcon
&icon
)
910 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
913 if (!icon
.Ok()) return;
915 wxMask
*mask
= icon
.GetMask();
916 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
917 if (mask
) bm
= mask
->GetBitmap();
919 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);