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 // "realize" from m_widget
151 //-----------------------------------------------------------------------------
153 /* we cannot MWM hints before the widget has been realized,
154 so we do this directly after realization */
157 gtk_frame_realized_callback( GtkWidget
*widget
, wxWindow
*win
)
159 /* all this is for Motif Window Manager "hints" and is supposed to be
160 recognized by other WM as well. not tested. */
161 long decor
= (long) GDK_DECOR_ALL
;
162 long func
= (long) GDK_FUNC_ALL
;
164 if ((win
->m_windowStyle
& wxCAPTION
) == 0)
165 decor
|= GDK_DECOR_TITLE
;
166 /* if ((win->m_windowStyle & wxMINIMIZE) == 0)
167 func |= GDK_FUNC_MINIMIZE;
168 if ((win->m_windowStyle & wxMAXIMIZE) == 0)
169 func |= GDK_FUNC_MAXIMIZE; */
170 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) == 0)
171 decor
|= GDK_DECOR_MENU
;
172 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) == 0)
173 decor
|= GDK_DECOR_MINIMIZE
;
174 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
175 decor
|= GDK_DECOR_MAXIMIZE
;
176 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
177 func
|= GDK_FUNC_RESIZE
;
179 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
180 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
182 /* GTK's shrinking/growing policy */
183 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
184 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
186 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
191 //-----------------------------------------------------------------------------
192 // InsertChild for wxFrame
193 //-----------------------------------------------------------------------------
195 /* Callback for wxFrame. This very strange beast has to be used because
196 * C++ has no virtual methods in a constructor. We have to emulate a
197 * virtual function here as wxWindows requires different ways to insert
198 * a child in container classes. */
200 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
202 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
204 /* actually, menubars are never inserted here, but this
205 may change one day */
207 /* these are outside the client area */
208 wxFrame
* frame
= (wxFrame
*) parent
;
209 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
210 GTK_WIDGET(child
->m_widget
),
214 /* we connect to these events for recalculating the client area
215 space when the toolbar is floating */
216 if (wxIS_KIND_OF(child
,wxToolBar
))
218 wxToolBar
*toolBar
= (wxToolBar
*) child
;
219 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
221 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
222 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
224 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
225 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
231 /* these are inside the client area */
232 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
233 GTK_WIDGET(child
->m_widget
),
238 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
242 /* resize on OnInternalIdle */
243 parent
->m_sizeSet
= FALSE
;
245 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
247 /* we now allow a window to get the focus as long as it
248 doesn't have any children. */
249 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
253 //-----------------------------------------------------------------------------
255 //-----------------------------------------------------------------------------
257 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
258 EVT_SIZE(wxFrame::OnSize
)
259 EVT_CLOSE(wxFrame::OnCloseWindow
)
260 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
263 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
267 m_frameMenuBar
= (wxMenuBar
*) NULL
;
268 m_frameStatusBar
= (wxStatusBar
*) NULL
;
269 m_frameToolBar
= (wxToolBar
*) NULL
;
273 m_mainWidget
= (GtkWidget
*) NULL
;
274 m_menuBarDetached
= FALSE
;
275 m_toolBarDetached
= FALSE
;
276 m_insertCallback
= wxInsertChildInFrame
;
279 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
280 const wxPoint
&pos
, const wxSize
&size
,
281 long style
, const wxString
&name
)
283 m_frameMenuBar
= (wxMenuBar
*) NULL
;
284 m_frameStatusBar
= (wxStatusBar
*) NULL
;
285 m_frameToolBar
= (wxToolBar
*) NULL
;
289 m_mainWidget
= (GtkWidget
*) NULL
;
290 m_menuBarDetached
= FALSE
;
291 m_toolBarDetached
= FALSE
;
292 m_insertCallback
= wxInsertChildInFrame
;
293 Create( parent
, id
, title
, pos
, size
, style
, name
);
296 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
297 const wxPoint
&pos
, const wxSize
&size
,
298 long style
, const wxString
&name
)
300 wxTopLevelWindows
.Append( this );
302 m_needParent
= FALSE
;
304 PreCreation( parent
, id
, pos
, size
, style
, name
);
308 m_insertCallback
= wxInsertChildInFrame
;
310 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
311 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
313 m_widget
= gtk_window_new( win_type
);
315 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
316 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
318 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
319 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
321 /* m_mainWidget holds the toolbar, the menubar and the client area */
322 m_mainWidget
= gtk_myfixed_new();
323 gtk_widget_show( m_mainWidget
);
324 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
325 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
327 /* m_wxwindow only represents the client area without toolbar and menubar */
328 m_wxwindow
= gtk_myfixed_new();
329 gtk_widget_show( m_wxwindow
);
330 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
331 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
333 if (m_parent
) m_parent
->AddChild( this );
337 /* we cannot set MWM hints before the widget has
338 been realized, so we do this directly after realization */
339 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
340 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
342 /* the user resized the frame by dragging etc. */
343 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
344 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
346 /* the only way to get the window size is to connect to this event */
347 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
348 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
355 if (m_frameMenuBar
) delete m_frameMenuBar
;
356 m_frameMenuBar
= (wxMenuBar
*) NULL
;
358 if (m_frameStatusBar
) delete m_frameStatusBar
;
359 m_frameStatusBar
= (wxStatusBar
*) NULL
;
361 if (m_frameToolBar
) delete m_frameToolBar
;
362 m_frameToolBar
= (wxToolBar
*) NULL
;
364 wxTopLevelWindows
.DeleteObject( this );
366 if (wxTheApp
->GetTopWindow() == this)
367 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
369 if (wxTopLevelWindows
.Number() == 0)
370 wxTheApp
->ExitMainLoop();
373 bool wxFrame::Show( bool show
)
375 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
377 if (show
&& !m_sizeSet
)
379 /* by calling GtkOnSize here, we don't have to call
380 either after showing the frame, which would entail
381 much ugly flicker or from within the size_allocate
382 handler, because GTK 1.1.X forbids that. */
384 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
387 return wxWindow::Show( show
);
390 bool wxFrame::Destroy()
392 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
394 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
399 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
401 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
403 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
404 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
406 /* avoid recursions */
407 if (m_resizing
) return;
412 int old_width
= m_width
;
413 int old_height
= m_height
;
415 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
417 if (x
!= -1) m_x
= x
;
418 if (y
!= -1) m_y
= y
;
419 if (width
!= -1) m_width
= width
;
420 if (height
!= -1) m_height
= height
;
430 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
432 if (width
== -1) m_width
= 80;
435 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
437 if (height
== -1) m_height
= 26;
440 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
441 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
442 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
443 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
445 if ((m_x
!= -1) || (m_y
!= -1))
447 if ((m_x
!= old_x
) || (m_y
!= old_y
))
449 /* m_sizeSet = FALSE; */
450 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
454 if ((m_width
!= old_width
) || (m_height
!= old_height
))
456 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
457 done either directly before the frame is shown or in idle time
458 so that different calls to SetSize() don't lead to flicker. */
465 void wxFrame::Centre( int direction
)
467 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
472 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
473 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
478 void wxFrame::GetClientSize( int *width
, int *height
) const
480 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
482 wxWindow::GetClientSize( width
, height
);
488 if (!m_menuBarDetached
)
489 (*height
) -= wxMENU_HEIGHT
;
491 (*height
) -= wxPLACE_HOLDER
;
495 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
500 if (!m_toolBarDetached
)
503 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
507 (*height
) -= wxPLACE_HOLDER
;
511 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
515 (*width
) -= m_miniEdge
*2;
519 void wxFrame::DoSetClientSize( int width
, int height
)
521 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
526 if (!m_menuBarDetached
)
527 height
+= wxMENU_HEIGHT
;
529 height
+= wxPLACE_HOLDER
;
533 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
538 if (!m_toolBarDetached
)
541 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
545 height
+= wxPLACE_HOLDER
;
548 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
551 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
553 // due to a bug in gtk, x,y are always 0
557 /* avoid recursions */
558 if (m_resizing
) return;
561 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
562 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
567 /* space occupied by m_frameToolBar and m_frameMenuBar */
568 int client_area_y_offset
= 0;
570 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
571 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
572 set in wxFrame::Create so it is used to check what kind of frame we
573 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
574 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
575 importantly) m_mainWidget */
579 /* check if size is in legal range */
580 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
581 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
582 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
583 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
585 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
586 * menubar, the toolbar and the client area, which is represented by
588 * this hurts in the eye, but I don't want to call SetSize()
589 * because I don't want to call any non-native functions here. */
594 int yy
= m_miniEdge
+ m_miniTitle
;
595 int ww
= m_width
- 2*m_miniEdge
;
596 int hh
= wxMENU_HEIGHT
;
597 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
598 m_frameMenuBar
->m_x
= xx
;
599 m_frameMenuBar
->m_y
= yy
;
600 m_frameMenuBar
->m_width
= ww
;
601 m_frameMenuBar
->m_height
= hh
;
603 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
604 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
606 client_area_y_offset
+= hh
;
612 int yy
= m_miniEdge
+ m_miniTitle
;
615 if (!m_menuBarDetached
)
618 yy
+= wxPLACE_HOLDER
;
620 int ww
= m_width
- 2*m_miniEdge
;
621 int hh
= m_frameToolBar
->m_height
;
622 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
623 m_frameToolBar
->m_x
= xx
;
624 m_frameToolBar
->m_y
= yy
;
625 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
626 m_frameToolBar
->m_width
= ww
;
628 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
629 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
631 client_area_y_offset
+= hh
;
634 int client_x
= m_miniEdge
;
635 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
636 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
638 int client_w
= m_width
- 2*m_miniEdge
;
639 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
640 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
644 /* if there is no m_mainWidget between m_widget and m_wxwindow there
645 is no need to set the size or position of m_wxwindow. */
648 if (m_frameStatusBar
)
650 int xx
= 0 + m_miniEdge
;
651 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
652 int ww
= m_width
- 2*m_miniEdge
;
653 int hh
= wxSTATUS_HEIGHT
;
655 m_frameStatusBar
->m_x
= xx
;
656 m_frameStatusBar
->m_y
= yy
;
657 m_frameStatusBar
->m_width
= ww
;
658 m_frameStatusBar
->m_height
= hh
;
660 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
661 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
664 /* we actually set the size of a frame here and no-where else */
665 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
669 /* send size event to frame */
670 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
671 event
.SetEventObject( this );
672 GetEventHandler()->ProcessEvent( event
);
674 /* send size event to status bar */
675 if (m_frameStatusBar
)
677 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
678 event2
.SetEventObject( m_frameStatusBar
);
679 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
685 void wxFrame::OnInternalIdle()
688 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
693 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
698 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
700 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
708 // do we have exactly one child?
709 wxWindow
*child
= (wxWindow
*)NULL
;
710 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
712 wxWindow
*win
= (wxWindow
*)node
->Data();
713 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
717 // it's the second one: do nothing
725 // no children at all?
728 // yes: set it's size to fill all the frame
729 int client_x
, client_y
;
730 GetClientSize( &client_x
, &client_y
);
731 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
736 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
738 menu
->SetInvokingWindow( win
);
739 wxNode
*node
= menu
->GetItems().First();
742 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
743 if (menuitem
->IsSubMenu())
744 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
749 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
751 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
752 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
754 m_frameMenuBar
= menuBar
;
758 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
761 wxMenu
*menu
= (wxMenu
*)node
->Data();
762 SetInvokingWindow( menu
, this );
766 if (m_frameMenuBar
->m_parent
!= this)
768 m_frameMenuBar
->m_parent
= this;
769 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
770 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
772 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
774 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
775 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
777 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
778 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
786 wxMenuBar
*wxFrame::GetMenuBar() const
788 return m_frameMenuBar
;
791 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
795 // if no help string found, we will clear the status bar text
798 int menuId
= event
.GetMenuId();
801 wxMenuBar
*menuBar
= GetMenuBar();
804 helpString
= menuBar
->GetHelpString(menuId
);
808 SetStatusText(helpString
);
812 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
814 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
816 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
818 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
820 GetChildren().DeleteObject( m_frameToolBar
);
824 return m_frameToolBar
;
827 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
829 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
832 wxToolBar
*wxFrame::GetToolBar() const
834 return m_frameToolBar
;
837 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
839 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
841 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
843 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
847 return m_frameStatusBar
;
850 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
852 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
854 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
856 // Set the height according to the font and the border size
857 wxClientDC
dc(statusBar
);
858 dc
.SetFont( statusBar
->GetFont() );
861 dc
.GetTextExtent( "X", &x
, &y
);
863 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
865 statusBar
->SetSize( -1, -1, 100, height
);
867 statusBar
->SetFieldsCount( number
);
871 void wxFrame::Command( int id
)
873 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
874 commandEvent
.SetInt( id
);
875 commandEvent
.SetEventObject( this );
877 wxMenuBar
*bar
= GetMenuBar();
880 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
881 if (item
&& item
->IsCheckable())
883 bar
->Check(id
,!bar
->Checked(id
)) ;
886 wxEvtHandler
* evtHandler
= GetEventHandler();
888 evtHandler
->ProcessEvent(commandEvent
);
891 void wxFrame::SetStatusText(const wxString
& text
, int number
)
893 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
895 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
897 m_frameStatusBar
->SetStatusText(text
, number
);
900 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
902 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
904 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
906 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
909 wxStatusBar
*wxFrame::GetStatusBar() const
911 return m_frameStatusBar
;
914 void wxFrame::SetTitle( const wxString
&title
)
916 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
919 if (m_title
.IsNull()) m_title
= _T("");
920 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
923 void wxFrame::SetIcon( const wxIcon
&icon
)
925 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
928 if (!icon
.Ok()) return;
930 wxMask
*mask
= icon
.GetMask();
931 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
932 if (mask
) bm
= mask
->GetBitmap();
934 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);