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 void wxapp_install_idle_handler();
43 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
47 extern wxList wxPendingDelete
;
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
55 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
59 //-----------------------------------------------------------------------------
61 //-----------------------------------------------------------------------------
63 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
66 wxapp_install_idle_handler();
68 if (!win
->m_hasVMT
) return;
70 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
72 win
->m_width
= alloc
->width
;
73 win
->m_height
= alloc
->height
;
78 //-----------------------------------------------------------------------------
80 //-----------------------------------------------------------------------------
82 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
85 wxapp_install_idle_handler();
92 //-----------------------------------------------------------------------------
93 // "child_attached" of menu bar
94 //-----------------------------------------------------------------------------
96 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
98 if (!win
->m_hasVMT
) return;
100 win
->m_menuBarDetached
= FALSE
;
104 //-----------------------------------------------------------------------------
105 // "child_detached" of menu bar
106 //-----------------------------------------------------------------------------
108 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
110 if (!win
->m_hasVMT
) return;
112 win
->m_menuBarDetached
= TRUE
;
116 //-----------------------------------------------------------------------------
117 // "child_attached" of tool bar
118 //-----------------------------------------------------------------------------
120 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
122 if (!win
->m_hasVMT
) return;
124 win
->m_toolBarDetached
= FALSE
;
129 //-----------------------------------------------------------------------------
130 // "child_detached" of tool bar
131 //-----------------------------------------------------------------------------
133 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
135 if (g_isIdle
) wxapp_install_idle_handler();
137 if (!win
->m_hasVMT
) return;
139 win
->m_toolBarDetached
= TRUE
;
143 //-----------------------------------------------------------------------------
145 //-----------------------------------------------------------------------------
147 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
150 wxapp_install_idle_handler();
152 if (!win
->m_hasVMT
) return FALSE
;
157 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
158 mevent
.SetEventObject( win
);
159 win
->GetEventHandler()->ProcessEvent( mevent
);
164 //-----------------------------------------------------------------------------
165 // "realize" from m_widget
166 //-----------------------------------------------------------------------------
168 /* we cannot MWM hints and icons before the widget has been realized,
169 so we do this directly after realization */
172 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
175 wxapp_install_idle_handler();
177 /* all this is for Motif Window Manager "hints" and is supposed to be
178 recognized by other WM as well. not tested. */
179 long decor
= (long) GDK_DECOR_BORDER
;
180 long func
= (long) GDK_FUNC_MOVE
;
182 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
183 decor
|= GDK_DECOR_TITLE
;
184 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
186 decor
|= GDK_DECOR_MENU
;
187 func
|= GDK_FUNC_CLOSE
;
189 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
191 func
|= GDK_FUNC_MINIMIZE
;
192 decor
|= GDK_DECOR_MINIMIZE
;
194 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
196 func
|= GDK_FUNC_MAXIMIZE
;
197 decor
|= GDK_DECOR_MAXIMIZE
;
199 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
201 func
|= GDK_FUNC_RESIZE
;
202 decor
|= GDK_DECOR_RESIZEH
;
206 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
207 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
209 /* GTK's shrinking/growing policy */
210 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
211 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
213 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
216 if (win
->m_icon
!= wxNullIcon
)
218 wxIcon
icon( win
->m_icon
);
219 win
->m_icon
= wxNullIcon
;
220 win
->SetIcon( icon
);
223 /* we set the focus to the child that accepts the focus. this
224 doesn't really have to be done in "realize" but why not? */
225 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
228 wxWindow
*child
= node
->GetData();
229 if (child
->AcceptsFocus())
235 node
= node
->GetNext();
241 //-----------------------------------------------------------------------------
242 // InsertChild for wxFrame
243 //-----------------------------------------------------------------------------
245 /* Callback for wxFrame. This very strange beast has to be used because
246 * C++ has no virtual methods in a constructor. We have to emulate a
247 * virtual function here as wxWindows requires different ways to insert
248 * a child in container classes. */
250 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
252 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
254 /* actually, menubars are never inserted here, but this
255 may change one day */
257 /* these are outside the client area */
258 wxFrame
* frame
= (wxFrame
*) parent
;
259 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
260 GTK_WIDGET(child
->m_widget
),
266 /* we connect to these events for recalculating the client area
267 space when the toolbar is floating */
268 if (wxIS_KIND_OF(child
,wxToolBar
))
270 wxToolBar
*toolBar
= (wxToolBar
*) child
;
271 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
273 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
274 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
276 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
277 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
283 /* these are inside the client area */
284 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
285 GTK_WIDGET(child
->m_widget
),
292 /* resize on OnInternalIdle */
293 parent
->UpdateSize();
296 //-----------------------------------------------------------------------------
298 //-----------------------------------------------------------------------------
300 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
301 EVT_SIZE(wxFrame::OnSize
)
302 EVT_CLOSE(wxFrame::OnCloseWindow
)
303 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
306 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
310 m_frameMenuBar
= (wxMenuBar
*) NULL
;
311 m_frameStatusBar
= (wxStatusBar
*) NULL
;
312 m_frameToolBar
= (wxToolBar
*) NULL
;
316 m_mainWidget
= (GtkWidget
*) NULL
;
317 m_menuBarDetached
= FALSE
;
318 m_toolBarDetached
= FALSE
;
319 m_insertCallback
= wxInsertChildInFrame
;
322 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
323 const wxPoint
&pos
, const wxSize
&size
,
324 long style
, const wxString
&name
)
326 m_frameMenuBar
= (wxMenuBar
*) NULL
;
327 m_frameStatusBar
= (wxStatusBar
*) NULL
;
328 m_frameToolBar
= (wxToolBar
*) NULL
;
332 m_mainWidget
= (GtkWidget
*) NULL
;
333 m_menuBarDetached
= FALSE
;
334 m_toolBarDetached
= FALSE
;
335 m_insertCallback
= wxInsertChildInFrame
;
336 Create( parent
, id
, title
, pos
, size
, style
, name
);
339 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
340 const wxPoint
&pos
, const wxSize
&size
,
341 long style
, const wxString
&name
)
343 wxTopLevelWindows
.Append( this );
345 m_needParent
= FALSE
;
347 PreCreation( parent
, id
, pos
, size
, style
, name
);
351 m_insertCallback
= wxInsertChildInFrame
;
353 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
354 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
356 m_widget
= gtk_window_new( win_type
);
359 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
362 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
365 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
366 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
368 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
369 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
371 /* m_mainWidget holds the toolbar, the menubar and the client area */
372 m_mainWidget
= gtk_myfixed_new();
373 gtk_widget_show( m_mainWidget
);
374 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
375 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
378 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
381 /* m_wxwindow only represents the client area without toolbar and menubar */
382 m_wxwindow
= gtk_myfixed_new();
383 gtk_widget_show( m_wxwindow
);
384 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
387 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
390 /* we donm't allow the frame to get the focus as otherwise
391 the frame will grabit at arbitrary fcous changes. */
392 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
394 if (m_parent
) m_parent
->AddChild( this );
398 /* we cannot set MWM hints and icons before the widget has
399 been realized, so we do this directly after realization */
400 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
401 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
403 /* the user resized the frame by dragging etc. */
404 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
405 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
407 /* the only way to get the window size is to connect to this event */
408 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
409 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
416 m_isBeingDeleted
= TRUE
;
418 if (m_frameMenuBar
) delete m_frameMenuBar
;
419 m_frameMenuBar
= (wxMenuBar
*) NULL
;
421 if (m_frameStatusBar
) delete m_frameStatusBar
;
422 m_frameStatusBar
= (wxStatusBar
*) NULL
;
424 if (m_frameToolBar
) delete m_frameToolBar
;
425 m_frameToolBar
= (wxToolBar
*) NULL
;
427 wxTopLevelWindows
.DeleteObject( this );
429 if (wxTheApp
->GetTopWindow() == this)
430 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
432 if (wxTopLevelWindows
.Number() == 0)
433 wxTheApp
->ExitMainLoop();
436 bool wxFrame::Show( bool show
)
438 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
440 if (show
&& !m_sizeSet
)
442 /* by calling GtkOnSize here, we don't have to call
443 either after showing the frame, which would entail
444 much ugly flicker or from within the size_allocate
445 handler, because GTK 1.1.X forbids that. */
447 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
450 return wxWindow::Show( show
);
453 bool wxFrame::Destroy()
455 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
457 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
462 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
464 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
466 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
467 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
469 /* avoid recursions */
470 if (m_resizing
) return;
475 int old_width
= m_width
;
476 int old_height
= m_height
;
478 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
480 if (x
!= -1) m_x
= x
;
481 if (y
!= -1) m_y
= y
;
482 if (width
!= -1) m_width
= width
;
483 if (height
!= -1) m_height
= height
;
493 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
495 if (width
== -1) m_width
= 80;
498 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
500 if (height
== -1) m_height
= 26;
503 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
504 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
505 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
506 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
508 if ((m_x
!= -1) || (m_y
!= -1))
510 if ((m_x
!= old_x
) || (m_y
!= old_y
))
512 /* we set the size here and in gtk_frame_map_callback */
513 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
517 if ((m_width
!= old_width
) || (m_height
!= old_height
))
519 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
520 done either directly before the frame is shown or in idle time
521 so that different calls to SetSize() don't lead to flicker. */
528 void wxFrame::Centre( int direction
)
530 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
535 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
536 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
541 void wxFrame::DoGetClientSize( int *width
, int *height
) const
543 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
545 wxWindow::DoGetClientSize( width
, height
);
551 if (!m_menuBarDetached
)
552 (*height
) -= wxMENU_HEIGHT
;
554 (*height
) -= wxPLACE_HOLDER
;
558 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
563 if (!m_toolBarDetached
)
566 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
570 (*height
) -= wxPLACE_HOLDER
;
574 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
578 (*width
) -= m_miniEdge
*2;
582 void wxFrame::DoSetClientSize( int width
, int height
)
584 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
589 if (!m_menuBarDetached
)
590 height
+= wxMENU_HEIGHT
;
592 height
+= wxPLACE_HOLDER
;
596 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
601 if (!m_toolBarDetached
)
604 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
608 height
+= wxPLACE_HOLDER
;
611 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
614 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
616 // due to a bug in gtk, x,y are always 0
620 /* avoid recursions */
621 if (m_resizing
) return;
624 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
625 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
630 /* space occupied by m_frameToolBar and m_frameMenuBar */
631 int client_area_y_offset
= 0;
633 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
634 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
635 set in wxFrame::Create so it is used to check what kind of frame we
636 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
637 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
638 importantly) m_mainWidget */
642 /* check if size is in legal range */
643 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
644 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
645 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
646 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
648 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
649 * menubar, the toolbar and the client area, which is represented by
651 * this hurts in the eye, but I don't want to call SetSize()
652 * because I don't want to call any non-native functions here. */
657 int yy
= m_miniEdge
+ m_miniTitle
;
658 int ww
= m_width
- 2*m_miniEdge
;
659 int hh
= wxMENU_HEIGHT
;
660 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
661 m_frameMenuBar
->m_x
= xx
;
662 m_frameMenuBar
->m_y
= yy
;
663 m_frameMenuBar
->m_width
= ww
;
664 m_frameMenuBar
->m_height
= hh
;
665 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
666 m_frameMenuBar
->m_widget
,
668 client_area_y_offset
+= hh
;
674 int yy
= m_miniEdge
+ m_miniTitle
;
677 if (!m_menuBarDetached
)
680 yy
+= wxPLACE_HOLDER
;
682 int ww
= m_width
- 2*m_miniEdge
;
683 int hh
= m_frameToolBar
->m_height
;
684 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
685 m_frameToolBar
->m_x
= xx
;
686 m_frameToolBar
->m_y
= yy
;
687 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
688 m_frameToolBar
->m_width
= ww
;
689 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
690 m_frameToolBar
->m_widget
,
692 client_area_y_offset
+= hh
;
695 int client_x
= m_miniEdge
;
696 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
697 int client_w
= m_width
- 2*m_miniEdge
;
698 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
699 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
701 client_x
, client_y
, client_w
, client_h
);
705 /* if there is no m_mainWidget between m_widget and m_wxwindow there
706 is no need to set the size or position of m_wxwindow. */
709 if (m_frameStatusBar
)
711 int xx
= 0 + m_miniEdge
;
712 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
713 int ww
= m_width
- 2*m_miniEdge
;
714 int hh
= wxSTATUS_HEIGHT
;
715 m_frameStatusBar
->m_x
= xx
;
716 m_frameStatusBar
->m_y
= yy
;
717 m_frameStatusBar
->m_width
= ww
;
718 m_frameStatusBar
->m_height
= hh
;
719 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
720 m_frameStatusBar
->m_widget
,
724 /* we actually set the size of a frame here and no-where else */
725 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
729 /* send size event to frame */
730 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
731 event
.SetEventObject( this );
732 GetEventHandler()->ProcessEvent( event
);
734 /* send size event to status bar */
735 if (m_frameStatusBar
)
737 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
738 event2
.SetEventObject( m_frameStatusBar
);
739 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
745 void wxFrame::OnInternalIdle()
747 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
748 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
753 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
758 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
760 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
768 /* do we have exactly one child? */
769 wxWindow
*child
= (wxWindow
*)NULL
;
770 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
772 wxWindow
*win
= (wxWindow
*)node
->Data();
773 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
777 /* it's the second one: do nothing */
785 /* no children at all? */
788 /* yes: set it's size to fill all the frame */
789 int client_x
, client_y
;
790 GetClientSize( &client_x
, &client_y
);
791 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
796 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
798 menu
->SetInvokingWindow( win
);
800 #if (GTK_MINOR_VERSION > 0)
801 /* support for native hot keys */
802 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
805 wxNode
*node
= menu
->GetItems().First();
808 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
809 if (menuitem
->IsSubMenu())
810 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
815 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
817 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
818 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
820 m_frameMenuBar
= menuBar
;
824 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
825 /* support for native key accelerators indicated by underscroes */
826 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
829 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
832 wxMenu
*menu
= (wxMenu
*)node
->Data();
833 SetInvokingWindow( menu
, this );
837 if (m_frameMenuBar
->GetParent() != this)
839 m_frameMenuBar
->SetParent(this);
840 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
841 m_frameMenuBar
->m_widget
,
844 m_frameMenuBar
->m_width
,
845 m_frameMenuBar
->m_height
);
847 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
849 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
850 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
852 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
853 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
858 /* resize window in OnInternalIdle */
862 wxMenuBar
*wxFrame::GetMenuBar() const
864 return m_frameMenuBar
;
867 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
871 // if no help string found, we will clear the status bar text
874 int menuId
= event
.GetMenuId();
877 wxMenuBar
*menuBar
= GetMenuBar();
880 helpString
= menuBar
->GetHelpString(menuId
);
884 SetStatusText(helpString
);
888 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
890 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
892 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
894 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
896 GetChildren().DeleteObject( m_frameToolBar
);
900 return m_frameToolBar
;
903 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
905 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
908 wxToolBar
*wxFrame::GetToolBar() const
910 return m_frameToolBar
;
913 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
915 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
917 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
919 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
923 return m_frameStatusBar
;
926 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
928 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
930 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
932 // Set the height according to the font and the border size
933 wxClientDC
dc(statusBar
);
934 dc
.SetFont( statusBar
->GetFont() );
937 dc
.GetTextExtent( "X", &x
, &y
);
939 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
941 statusBar
->SetSize( -1, -1, 100, height
);
943 statusBar
->SetFieldsCount( number
);
947 void wxFrame::Command( int id
)
949 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
950 commandEvent
.SetInt( id
);
951 commandEvent
.SetEventObject( this );
953 wxMenuBar
*bar
= GetMenuBar();
956 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
957 if (item
&& item
->IsCheckable())
959 bar
->Check(id
,!bar
->Checked(id
)) ;
962 wxEvtHandler
* evtHandler
= GetEventHandler();
964 evtHandler
->ProcessEvent(commandEvent
);
967 void wxFrame::SetStatusText(const wxString
& text
, int number
)
969 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
971 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
973 m_frameStatusBar
->SetStatusText(text
, number
);
976 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
978 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
980 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
982 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
985 wxStatusBar
*wxFrame::GetStatusBar() const
987 return m_frameStatusBar
;
990 void wxFrame::SetTitle( const wxString
&title
)
992 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
995 if (m_title
.IsNull()) m_title
= _T("");
996 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
999 void wxFrame::SetIcon( const wxIcon
&icon
)
1001 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1004 if (!icon
.Ok()) return;
1006 if (!m_widget
->window
) return;
1008 wxMask
*mask
= icon
.GetMask();
1009 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1010 if (mask
) bm
= mask
->GetBitmap();
1012 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);