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"
27 #include "gdk/gdkkeysyms.h"
29 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
33 const int wxMENU_HEIGHT
= 27;
34 const int wxSTATUS_HEIGHT
= 25;
35 const int wxPLACE_HOLDER
= 0;
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 extern void wxapp_install_idle_handler();
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
48 extern wxList wxPendingDelete
;
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
56 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
60 //-----------------------------------------------------------------------------
62 //-----------------------------------------------------------------------------
64 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
67 wxapp_install_idle_handler();
69 if (!win
->m_hasVMT
) return;
71 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
73 win
->m_width
= alloc
->width
;
74 win
->m_height
= alloc
->height
;
79 //-----------------------------------------------------------------------------
81 //-----------------------------------------------------------------------------
83 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
86 wxapp_install_idle_handler();
93 //-----------------------------------------------------------------------------
94 // "child_attached" of menu bar
95 //-----------------------------------------------------------------------------
97 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
99 if (!win
->m_hasVMT
) return;
101 win
->m_menuBarDetached
= FALSE
;
105 //-----------------------------------------------------------------------------
106 // "child_detached" of menu bar
107 //-----------------------------------------------------------------------------
109 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
111 if (!win
->m_hasVMT
) return;
113 win
->m_menuBarDetached
= TRUE
;
117 //-----------------------------------------------------------------------------
118 // "child_attached" of tool bar
119 //-----------------------------------------------------------------------------
121 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
123 if (!win
->m_hasVMT
) return;
125 win
->m_toolBarDetached
= FALSE
;
130 //-----------------------------------------------------------------------------
131 // "child_detached" of tool bar
132 //-----------------------------------------------------------------------------
134 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
137 wxapp_install_idle_handler();
139 if (!win
->m_hasVMT
) return;
141 win
->m_toolBarDetached
= TRUE
;
145 //-----------------------------------------------------------------------------
147 //-----------------------------------------------------------------------------
149 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
152 wxapp_install_idle_handler();
154 if (!win
->m_hasVMT
) return FALSE
;
158 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
163 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
164 mevent
.SetEventObject( win
);
165 win
->GetEventHandler()->ProcessEvent( mevent
);
170 //-----------------------------------------------------------------------------
171 // "realize" from m_widget
172 //-----------------------------------------------------------------------------
174 /* we cannot MWM hints and icons before the widget has been realized,
175 so we do this directly after realization */
178 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
181 wxapp_install_idle_handler();
183 /* all this is for Motif Window Manager "hints" and is supposed to be
184 recognized by other WM as well. not tested. */
185 long decor
= (long) GDK_DECOR_BORDER
;
186 long func
= (long) GDK_FUNC_MOVE
;
188 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
189 decor
|= GDK_DECOR_TITLE
;
190 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
192 decor
|= GDK_DECOR_MENU
;
193 func
|= GDK_FUNC_CLOSE
;
195 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
197 func
|= GDK_FUNC_MINIMIZE
;
198 decor
|= GDK_DECOR_MINIMIZE
;
200 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
202 func
|= GDK_FUNC_MAXIMIZE
;
203 decor
|= GDK_DECOR_MAXIMIZE
;
205 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
207 func
|= GDK_FUNC_RESIZE
;
208 decor
|= GDK_DECOR_RESIZEH
;
212 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
213 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
215 /* GTK's shrinking/growing policy */
216 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
217 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
219 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
222 if (win
->m_icon
!= wxNullIcon
)
224 wxIcon
icon( win
->m_icon
);
225 win
->m_icon
= wxNullIcon
;
226 win
->SetIcon( icon
);
229 /* we set the focus to the child that accepts the focus. this
230 doesn't really have to be done in "realize" but why not? */
231 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
234 wxWindow
*child
= node
->GetData();
235 if (child
->AcceptsFocus())
241 node
= node
->GetNext();
247 //-----------------------------------------------------------------------------
248 // InsertChild for wxFrame
249 //-----------------------------------------------------------------------------
251 /* Callback for wxFrame. This very strange beast has to be used because
252 * C++ has no virtual methods in a constructor. We have to emulate a
253 * virtual function here as wxWindows requires different ways to insert
254 * a child in container classes. */
256 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
258 if (!parent
->m_insertInClientArea
)
260 /* these are outside the client area */
261 wxFrame
* frame
= (wxFrame
*) parent
;
262 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
263 GTK_WIDGET(child
->m_widget
),
269 /* we connect to these events for recalculating the client area
270 space when the toolbar is floating */
271 if (wxIS_KIND_OF(child
,wxToolBar
))
273 wxToolBar
*toolBar
= (wxToolBar
*) child
;
274 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
276 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
277 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
279 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
280 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
286 /* these are inside the client area */
287 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
288 GTK_WIDGET(child
->m_widget
),
295 /* resize on OnInternalIdle */
296 parent
->UpdateSize();
299 //-----------------------------------------------------------------------------
301 //-----------------------------------------------------------------------------
303 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
304 EVT_SIZE(wxFrame::OnSize
)
305 EVT_CLOSE(wxFrame::OnCloseWindow
)
306 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
309 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
313 m_frameMenuBar
= (wxMenuBar
*) NULL
;
314 m_frameStatusBar
= (wxStatusBar
*) NULL
;
315 m_frameToolBar
= (wxToolBar
*) NULL
;
319 m_mainWidget
= (GtkWidget
*) NULL
;
320 m_menuBarDetached
= FALSE
;
321 m_toolBarDetached
= FALSE
;
322 m_insertInClientArea
= TRUE
;
325 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
326 const wxPoint
&pos
, const wxSize
&size
,
327 long style
, const wxString
&name
)
331 Create( parent
, id
, title
, pos
, size
, style
, name
);
334 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
335 const wxPoint
&pos
, const wxSize
&size
,
336 long style
, const wxString
&name
)
338 wxTopLevelWindows
.Append( this );
340 m_needParent
= FALSE
;
342 PreCreation( parent
, id
, pos
, size
, style
, name
);
346 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
348 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
349 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
351 m_widget
= gtk_window_new( win_type
);
354 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
357 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
360 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
361 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
363 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
364 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
366 /* m_mainWidget holds the toolbar, the menubar and the client area */
367 m_mainWidget
= gtk_myfixed_new();
368 gtk_widget_show( m_mainWidget
);
369 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
370 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
373 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
376 /* m_wxwindow only represents the client area without toolbar and menubar */
377 m_wxwindow
= gtk_myfixed_new();
378 gtk_widget_show( m_wxwindow
);
379 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
382 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
385 /* we donm't allow the frame to get the focus as otherwise
386 the frame will grabit at arbitrary fcous changes. */
387 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
389 if (m_parent
) m_parent
->AddChild( this );
393 /* we cannot set MWM hints and icons before the widget has
394 been realized, so we do this directly after realization */
395 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
396 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
398 /* the user resized the frame by dragging etc. */
399 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
400 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
402 /* the only way to get the window size is to connect to this event */
403 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
404 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
411 m_isBeingDeleted
= TRUE
;
413 if (m_frameMenuBar
) delete m_frameMenuBar
;
414 m_frameMenuBar
= (wxMenuBar
*) NULL
;
416 if (m_frameStatusBar
) delete m_frameStatusBar
;
417 m_frameStatusBar
= (wxStatusBar
*) NULL
;
419 if (m_frameToolBar
) delete m_frameToolBar
;
420 m_frameToolBar
= (wxToolBar
*) NULL
;
422 wxTopLevelWindows
.DeleteObject( this );
424 if (wxTheApp
->GetTopWindow() == this)
425 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
427 if (wxTopLevelWindows
.Number() == 0)
428 wxTheApp
->ExitMainLoop();
431 bool wxFrame::Show( bool show
)
433 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
435 if (show
&& !m_sizeSet
)
437 /* by calling GtkOnSize here, we don't have to call
438 either after showing the frame, which would entail
439 much ugly flicker or from within the size_allocate
440 handler, because GTK 1.1.X forbids that. */
442 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
445 return wxWindow::Show( show
);
448 bool wxFrame::Destroy()
450 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
452 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
457 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
459 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
461 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
462 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
464 /* avoid recursions */
465 if (m_resizing
) return;
470 int old_width
= m_width
;
471 int old_height
= m_height
;
473 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
475 if (x
!= -1) m_x
= x
;
476 if (y
!= -1) m_y
= y
;
477 if (width
!= -1) m_width
= width
;
478 if (height
!= -1) m_height
= height
;
488 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
490 if (width
== -1) m_width
= 80;
493 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
495 if (height
== -1) m_height
= 26;
498 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
499 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
500 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
501 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
503 if ((m_x
!= -1) || (m_y
!= -1))
505 if ((m_x
!= old_x
) || (m_y
!= old_y
))
507 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
511 if ((m_width
!= old_width
) || (m_height
!= old_height
))
513 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
514 done either directly before the frame is shown or in idle time
515 so that different calls to SetSize() don't lead to flicker. */
522 void wxFrame::Centre( int direction
)
524 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
529 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
530 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
535 void wxFrame::DoGetClientSize( int *width
, int *height
) const
537 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
539 wxWindow::DoGetClientSize( width
, height
);
545 if (!m_menuBarDetached
)
546 (*height
) -= wxMENU_HEIGHT
;
548 (*height
) -= wxPLACE_HOLDER
;
552 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
557 if (!m_toolBarDetached
)
560 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
564 (*height
) -= wxPLACE_HOLDER
;
568 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
572 (*width
) -= m_miniEdge
*2;
576 void wxFrame::DoSetClientSize( int width
, int height
)
578 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
583 if (!m_menuBarDetached
)
584 height
+= wxMENU_HEIGHT
;
586 height
+= wxPLACE_HOLDER
;
590 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
595 if (!m_toolBarDetached
)
598 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
602 height
+= wxPLACE_HOLDER
;
605 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
608 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
610 // due to a bug in gtk, x,y are always 0
614 /* avoid recursions */
615 if (m_resizing
) return;
618 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
619 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
624 /* space occupied by m_frameToolBar and m_frameMenuBar */
625 int client_area_y_offset
= 0;
627 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
628 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
629 set in wxFrame::Create so it is used to check what kind of frame we
630 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
631 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
632 importantly) m_mainWidget */
636 /* check if size is in legal range */
637 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
638 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
639 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
640 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
642 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
643 * menubar, the toolbar and the client area, which is represented by
645 * this hurts in the eye, but I don't want to call SetSize()
646 * because I don't want to call any non-native functions here. */
651 int yy
= m_miniEdge
+ m_miniTitle
;
652 int ww
= m_width
- 2*m_miniEdge
;
653 int hh
= wxMENU_HEIGHT
;
654 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
655 m_frameMenuBar
->m_x
= xx
;
656 m_frameMenuBar
->m_y
= yy
;
657 m_frameMenuBar
->m_width
= ww
;
658 m_frameMenuBar
->m_height
= hh
;
659 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
660 m_frameMenuBar
->m_widget
,
662 client_area_y_offset
+= hh
;
668 int yy
= m_miniEdge
+ m_miniTitle
;
671 if (!m_menuBarDetached
)
674 yy
+= wxPLACE_HOLDER
;
676 int ww
= m_width
- 2*m_miniEdge
;
677 int hh
= m_frameToolBar
->m_height
;
678 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
679 m_frameToolBar
->m_x
= xx
;
680 m_frameToolBar
->m_y
= yy
;
681 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
682 m_frameToolBar
->m_width
= ww
;
683 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
684 m_frameToolBar
->m_widget
,
686 client_area_y_offset
+= hh
;
689 int client_x
= m_miniEdge
;
690 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
691 int client_w
= m_width
- 2*m_miniEdge
;
692 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
693 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
695 client_x
, client_y
, client_w
, client_h
);
699 /* if there is no m_mainWidget between m_widget and m_wxwindow there
700 is no need to set the size or position of m_wxwindow. */
703 if (m_frameStatusBar
)
705 int xx
= 0 + m_miniEdge
;
706 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
707 int ww
= m_width
- 2*m_miniEdge
;
708 int hh
= wxSTATUS_HEIGHT
;
709 m_frameStatusBar
->m_x
= xx
;
710 m_frameStatusBar
->m_y
= yy
;
711 m_frameStatusBar
->m_width
= ww
;
712 m_frameStatusBar
->m_height
= hh
;
713 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
714 m_frameStatusBar
->m_widget
,
718 /* we actually set the size of a frame here and no-where else */
719 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
723 /* send size event to frame */
724 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
725 event
.SetEventObject( this );
726 GetEventHandler()->ProcessEvent( event
);
728 /* send size event to status bar */
729 if (m_frameStatusBar
)
731 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
732 event2
.SetEventObject( m_frameStatusBar
);
733 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
739 void wxFrame::MakeModal( bool modal
)
742 gtk_grab_add( m_widget
);
744 gtk_grab_remove( m_widget
);
747 void wxFrame::OnInternalIdle()
749 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
750 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
754 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
755 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
756 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
759 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
764 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
766 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
774 /* do we have exactly one child? */
775 wxWindow
*child
= (wxWindow
*)NULL
;
776 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
778 wxWindow
*win
= (wxWindow
*)node
->Data();
779 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
783 /* it's the second one: do nothing */
791 /* no children at all? */
794 /* yes: set it's size to fill all the frame */
795 int client_x
, client_y
;
796 DoGetClientSize( &client_x
, &client_y
);
797 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
802 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
804 menu
->SetInvokingWindow( win
);
806 #if (GTK_MINOR_VERSION > 0)
807 /* support for native hot keys */
808 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
811 wxNode
*node
= menu
->GetItems().First();
814 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
815 if (menuitem
->IsSubMenu())
816 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
821 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
823 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
824 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
826 m_frameMenuBar
= menuBar
;
830 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
831 /* support for native key accelerators indicated by underscroes */
832 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
835 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
838 wxMenu
*menu
= (wxMenu
*)node
->Data();
839 SetInvokingWindow( menu
, this );
843 if (m_frameMenuBar
->GetParent() != this)
845 m_frameMenuBar
->SetParent(this);
846 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
847 m_frameMenuBar
->m_widget
,
850 m_frameMenuBar
->m_width
,
851 m_frameMenuBar
->m_height
);
853 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
855 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
856 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
858 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
859 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
864 /* resize window in OnInternalIdle */
868 wxMenuBar
*wxFrame::GetMenuBar() const
870 return m_frameMenuBar
;
873 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
877 // if no help string found, we will clear the status bar text
880 int menuId
= event
.GetMenuId();
883 wxMenuBar
*menuBar
= GetMenuBar();
886 helpString
= menuBar
->GetHelpString(menuId
);
890 SetStatusText(helpString
);
894 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
896 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
898 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
900 m_insertInClientArea
= FALSE
;
902 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
904 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
906 m_insertInClientArea
= TRUE
;
910 return m_frameToolBar
;
913 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
915 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
918 wxToolBar
*wxFrame::GetToolBar() const
920 return m_frameToolBar
;
923 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
925 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
927 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
929 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
933 return m_frameStatusBar
;
936 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
938 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
940 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
942 // Set the height according to the font and the border size
943 wxClientDC
dc(statusBar
);
944 dc
.SetFont( statusBar
->GetFont() );
947 dc
.GetTextExtent( "X", &x
, &y
);
949 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
951 statusBar
->SetSize( -1, -1, 100, height
);
953 statusBar
->SetFieldsCount( number
);
957 void wxFrame::Command( int id
)
959 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
960 commandEvent
.SetInt( id
);
961 commandEvent
.SetEventObject( this );
963 wxMenuBar
*bar
= GetMenuBar();
966 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
967 if (item
&& item
->IsCheckable())
969 bar
->Check(id
,!bar
->Checked(id
)) ;
972 wxEvtHandler
* evtHandler
= GetEventHandler();
974 evtHandler
->ProcessEvent(commandEvent
);
977 void wxFrame::SetStatusText(const wxString
& text
, int number
)
979 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
981 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
983 m_frameStatusBar
->SetStatusText(text
, number
);
986 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
988 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
990 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
992 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
995 wxStatusBar
*wxFrame::GetStatusBar() const
997 return m_frameStatusBar
;
1000 void wxFrame::SetTitle( const wxString
&title
)
1002 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1005 if (m_title
.IsNull()) m_title
= _T("");
1006 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1009 void wxFrame::SetIcon( const wxIcon
&icon
)
1011 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1014 if (!icon
.Ok()) return;
1016 if (!m_widget
->window
) return;
1018 wxMask
*mask
= icon
.GetMask();
1019 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1020 if (mask
) bm
= mask
->GetBitmap();
1022 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);