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
)
65 if (g_isIdle
) wxapp_install_idle_handler();
67 if (!win
->HasVMT()) return;
70 printf( "OnFrameResize from " );
71 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
72 printf( win->GetClassInfo()->GetClassName() );
76 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
78 win
->m_sizeSet
= FALSE
;
79 win
->m_width
= alloc
->width
;
80 win
->m_height
= alloc
->height
;
84 //-----------------------------------------------------------------------------
86 //-----------------------------------------------------------------------------
88 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
90 if (g_isIdle
) wxapp_install_idle_handler();
93 printf( "OnDelete from " );
94 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
95 printf( win->GetClassInfo()->GetClassName() );
104 //-----------------------------------------------------------------------------
105 // "child_attached" of menu bar
106 //-----------------------------------------------------------------------------
108 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
110 if (g_isIdle
) wxapp_install_idle_handler();
112 if (!win
->HasVMT()) return;
114 win
->m_menuBarDetached
= FALSE
;
115 win
->m_sizeSet
= FALSE
;
118 //-----------------------------------------------------------------------------
119 // "child_detached" of menu bar
120 //-----------------------------------------------------------------------------
122 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
124 if (g_isIdle
) wxapp_install_idle_handler();
126 if (!win
->HasVMT()) return;
128 win
->m_menuBarDetached
= TRUE
;
129 win
->m_sizeSet
= FALSE
;
132 //-----------------------------------------------------------------------------
133 // "child_attached" of tool bar
134 //-----------------------------------------------------------------------------
136 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
138 if (g_isIdle
) wxapp_install_idle_handler();
140 if (!win
->HasVMT()) return;
142 win
->m_toolBarDetached
= FALSE
;
143 win
->m_sizeSet
= FALSE
;
146 //-----------------------------------------------------------------------------
147 // "child_detached" of tool bar
148 //-----------------------------------------------------------------------------
150 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
152 if (g_isIdle
) wxapp_install_idle_handler();
154 if (!win
->HasVMT()) return;
156 win
->m_toolBarDetached
= TRUE
;
157 win
->m_sizeSet
= FALSE
;
160 //-----------------------------------------------------------------------------
162 //-----------------------------------------------------------------------------
164 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
166 if (g_isIdle
) wxapp_install_idle_handler();
168 if (!win
->HasVMT()) return FALSE
;
173 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
174 mevent
.SetEventObject( win
);
175 win
->GetEventHandler()->ProcessEvent( mevent
);
180 //-----------------------------------------------------------------------------
181 // "realize" from m_widget
182 //-----------------------------------------------------------------------------
184 /* we cannot MWM hints and icons before the widget has been realized,
185 so we do this directly after realization */
188 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
190 if (g_isIdle
) wxapp_install_idle_handler();
192 /* all this is for Motif Window Manager "hints" and is supposed to be
193 recognized by other WM as well. not tested. */
194 long decor
= (long) GDK_DECOR_BORDER
;
195 long func
= (long) GDK_FUNC_MOVE
;
197 if ((win
->m_windowStyle
& wxCAPTION
) != 0)
198 decor
|= GDK_DECOR_TITLE
;
199 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) != 0)
201 decor
|= GDK_DECOR_MENU
;
202 func
|= GDK_FUNC_CLOSE
;
204 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) != 0)
206 func
|= GDK_FUNC_MINIMIZE
;
207 decor
|= GDK_DECOR_MINIMIZE
;
209 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) != 0)
211 func
|= GDK_FUNC_MAXIMIZE
;
212 decor
|= GDK_DECOR_MAXIMIZE
;
214 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) != 0)
216 func
|= GDK_FUNC_RESIZE
;
217 decor
|= GDK_DECOR_RESIZEH
;
221 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
222 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
224 /* GTK's shrinking/growing policy */
225 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
226 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
228 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
231 if (win
->m_icon
!= wxNullIcon
)
233 wxIcon
icon( win
->m_icon
);
234 win
->m_icon
= wxNullIcon
;
235 win
->SetIcon( icon
);
238 /* we set the focus to the child that accepts the focus. this
239 doesn't really have to be done in "realize" but why not? */
240 wxNode
*node
= win
->m_children
.First();
243 wxWindow
*child
= (wxWindow
*) node
->Data();
244 if (child
->AcceptsFocus())
256 //-----------------------------------------------------------------------------
257 // InsertChild for wxFrame
258 //-----------------------------------------------------------------------------
260 /* Callback for wxFrame. This very strange beast has to be used because
261 * C++ has no virtual methods in a constructor. We have to emulate a
262 * virtual function here as wxWindows requires different ways to insert
263 * a child in container classes. */
265 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
267 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
269 /* actually, menubars are never inserted here, but this
270 may change one day */
272 /* these are outside the client area */
273 wxFrame
* frame
= (wxFrame
*) parent
;
274 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
275 GTK_WIDGET(child
->m_widget
),
281 /* we connect to these events for recalculating the client area
282 space when the toolbar is floating */
283 if (wxIS_KIND_OF(child
,wxToolBar
))
285 wxToolBar
*toolBar
= (wxToolBar
*) child
;
286 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
288 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
289 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
291 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
292 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
298 /* these are inside the client area */
299 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
300 GTK_WIDGET(child
->m_widget
),
307 /* resize on OnInternalIdle */
308 parent
->m_sizeSet
= FALSE
;
311 //-----------------------------------------------------------------------------
313 //-----------------------------------------------------------------------------
315 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
316 EVT_SIZE(wxFrame::OnSize
)
317 EVT_CLOSE(wxFrame::OnCloseWindow
)
318 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
321 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
325 m_frameMenuBar
= (wxMenuBar
*) NULL
;
326 m_frameStatusBar
= (wxStatusBar
*) NULL
;
327 m_frameToolBar
= (wxToolBar
*) NULL
;
331 m_mainWidget
= (GtkWidget
*) NULL
;
332 m_menuBarDetached
= FALSE
;
333 m_toolBarDetached
= FALSE
;
334 m_insertCallback
= wxInsertChildInFrame
;
337 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
338 const wxPoint
&pos
, const wxSize
&size
,
339 long style
, const wxString
&name
)
341 m_frameMenuBar
= (wxMenuBar
*) NULL
;
342 m_frameStatusBar
= (wxStatusBar
*) NULL
;
343 m_frameToolBar
= (wxToolBar
*) NULL
;
347 m_mainWidget
= (GtkWidget
*) NULL
;
348 m_menuBarDetached
= FALSE
;
349 m_toolBarDetached
= FALSE
;
350 m_insertCallback
= wxInsertChildInFrame
;
351 Create( parent
, id
, title
, pos
, size
, style
, name
);
354 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
355 const wxPoint
&pos
, const wxSize
&size
,
356 long style
, const wxString
&name
)
358 wxTopLevelWindows
.Append( this );
360 m_needParent
= FALSE
;
362 PreCreation( parent
, id
, pos
, size
, style
, name
);
366 m_insertCallback
= wxInsertChildInFrame
;
368 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
369 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
371 m_widget
= gtk_window_new( win_type
);
374 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
377 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
378 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
380 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
381 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
383 /* m_mainWidget holds the toolbar, the menubar and the client area */
384 m_mainWidget
= gtk_myfixed_new();
385 gtk_widget_show( m_mainWidget
);
386 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
387 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
390 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
393 /* m_wxwindow only represents the client area without toolbar and menubar */
394 m_wxwindow
= gtk_myfixed_new();
395 gtk_widget_show( m_wxwindow
);
396 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
399 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
402 /* we donm't allow the frame to get the focus as otherwise
403 the frame will grabit at arbitrary fcous changes. */
404 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
406 if (m_parent
) m_parent
->AddChild( this );
410 /* we cannot set MWM hints and icons before the widget has
411 been realized, so we do this directly after realization */
412 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
413 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
415 /* the user resized the frame by dragging etc. */
416 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
417 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
419 /* the only way to get the window size is to connect to this event */
420 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
421 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
428 if (m_frameMenuBar
) delete m_frameMenuBar
;
429 m_frameMenuBar
= (wxMenuBar
*) NULL
;
431 if (m_frameStatusBar
) delete m_frameStatusBar
;
432 m_frameStatusBar
= (wxStatusBar
*) NULL
;
434 if (m_frameToolBar
) delete m_frameToolBar
;
435 m_frameToolBar
= (wxToolBar
*) NULL
;
437 wxTopLevelWindows
.DeleteObject( this );
439 if (wxTheApp
->GetTopWindow() == this)
440 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
442 if (wxTopLevelWindows
.Number() == 0)
443 wxTheApp
->ExitMainLoop();
446 bool wxFrame::Show( bool show
)
448 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
450 if (show
&& !m_sizeSet
)
452 /* by calling GtkOnSize here, we don't have to call
453 either after showing the frame, which would entail
454 much ugly flicker or from within the size_allocate
455 handler, because GTK 1.1.X forbids that. */
457 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
460 return wxWindow::Show( show
);
463 bool wxFrame::Destroy()
465 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
467 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
472 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
474 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
476 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
477 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
479 /* avoid recursions */
480 if (m_resizing
) return;
485 int old_width
= m_width
;
486 int old_height
= m_height
;
488 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
490 if (x
!= -1) m_x
= x
;
491 if (y
!= -1) m_y
= y
;
492 if (width
!= -1) m_width
= width
;
493 if (height
!= -1) m_height
= height
;
503 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
505 if (width
== -1) m_width
= 80;
508 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
510 if (height
== -1) m_height
= 26;
513 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
514 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
515 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
516 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
518 if ((m_x
!= -1) || (m_y
!= -1))
520 if ((m_x
!= old_x
) || (m_y
!= old_y
))
522 /* we set the size here and in gtk_frame_map_callback */
523 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
527 if ((m_width
!= old_width
) || (m_height
!= old_height
))
529 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
530 done either directly before the frame is shown or in idle time
531 so that different calls to SetSize() don't lead to flicker. */
538 void wxFrame::Centre( int direction
)
540 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
545 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
546 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
551 void wxFrame::GetClientSize( int *width
, int *height
) const
553 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
555 wxWindow::GetClientSize( width
, height
);
561 if (!m_menuBarDetached
)
562 (*height
) -= wxMENU_HEIGHT
;
564 (*height
) -= wxPLACE_HOLDER
;
568 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
573 if (!m_toolBarDetached
)
576 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
580 (*height
) -= wxPLACE_HOLDER
;
584 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
588 (*width
) -= m_miniEdge
*2;
592 void wxFrame::DoSetClientSize( int width
, int height
)
594 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
599 if (!m_menuBarDetached
)
600 height
+= wxMENU_HEIGHT
;
602 height
+= wxPLACE_HOLDER
;
606 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
611 if (!m_toolBarDetached
)
614 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
618 height
+= wxPLACE_HOLDER
;
621 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
624 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
626 // due to a bug in gtk, x,y are always 0
630 /* avoid recursions */
631 if (m_resizing
) return;
634 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
635 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
640 /* space occupied by m_frameToolBar and m_frameMenuBar */
641 int client_area_y_offset
= 0;
643 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
644 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
645 set in wxFrame::Create so it is used to check what kind of frame we
646 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
647 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
648 importantly) m_mainWidget */
652 /* check if size is in legal range */
653 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
654 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
655 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
656 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
658 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
659 * menubar, the toolbar and the client area, which is represented by
661 * this hurts in the eye, but I don't want to call SetSize()
662 * because I don't want to call any non-native functions here. */
667 int yy
= m_miniEdge
+ m_miniTitle
;
668 int ww
= m_width
- 2*m_miniEdge
;
669 int hh
= wxMENU_HEIGHT
;
670 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
671 m_frameMenuBar
->m_x
= xx
;
672 m_frameMenuBar
->m_y
= yy
;
673 m_frameMenuBar
->m_width
= ww
;
674 m_frameMenuBar
->m_height
= hh
;
675 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
676 m_frameMenuBar
->m_widget
,
678 client_area_y_offset
+= hh
;
684 int yy
= m_miniEdge
+ m_miniTitle
;
687 if (!m_menuBarDetached
)
690 yy
+= wxPLACE_HOLDER
;
692 int ww
= m_width
- 2*m_miniEdge
;
693 int hh
= m_frameToolBar
->m_height
;
694 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
695 m_frameToolBar
->m_x
= xx
;
696 m_frameToolBar
->m_y
= yy
;
697 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
698 m_frameToolBar
->m_width
= ww
;
699 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
700 m_frameToolBar
->m_widget
,
702 client_area_y_offset
+= hh
;
705 int client_x
= m_miniEdge
;
706 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
707 int client_w
= m_width
- 2*m_miniEdge
;
708 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
709 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
711 client_x
, client_y
, client_w
, client_h
);
715 /* if there is no m_mainWidget between m_widget and m_wxwindow there
716 is no need to set the size or position of m_wxwindow. */
719 if (m_frameStatusBar
)
721 int xx
= 0 + m_miniEdge
;
722 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
723 int ww
= m_width
- 2*m_miniEdge
;
724 int hh
= wxSTATUS_HEIGHT
;
725 m_frameStatusBar
->m_x
= xx
;
726 m_frameStatusBar
->m_y
= yy
;
727 m_frameStatusBar
->m_width
= ww
;
728 m_frameStatusBar
->m_height
= hh
;
729 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
730 m_frameStatusBar
->m_widget
,
734 /* we actually set the size of a frame here and no-where else */
735 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
739 /* send size event to frame */
740 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
741 event
.SetEventObject( this );
742 GetEventHandler()->ProcessEvent( event
);
744 /* send size event to status bar */
745 if (m_frameStatusBar
)
747 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
748 event2
.SetEventObject( m_frameStatusBar
);
749 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
755 void wxFrame::OnInternalIdle()
757 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
758 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
763 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
768 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
770 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
778 /* do we have exactly one child? */
779 wxWindow
*child
= (wxWindow
*)NULL
;
780 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
782 wxWindow
*win
= (wxWindow
*)node
->Data();
783 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
787 /* it's the second one: do nothing */
795 /* no children at all? */
798 /* yes: set it's size to fill all the frame */
799 int client_x
, client_y
;
800 GetClientSize( &client_x
, &client_y
);
801 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
806 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
808 menu
->SetInvokingWindow( win
);
810 #if (GTK_MINOR_VERSION > 0)
811 /* support for native hot keys */
812 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
815 wxNode
*node
= menu
->GetItems().First();
818 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
819 if (menuitem
->IsSubMenu())
820 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
825 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
827 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
828 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
830 m_frameMenuBar
= menuBar
;
834 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
835 /* support for native key accelerators indicated by underscroes */
836 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
839 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
842 wxMenu
*menu
= (wxMenu
*)node
->Data();
843 SetInvokingWindow( menu
, this );
847 if (m_frameMenuBar
->m_parent
!= this)
849 m_frameMenuBar
->m_parent
= this;
850 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
851 m_frameMenuBar
->m_widget
,
854 m_frameMenuBar
->m_width
,
855 m_frameMenuBar
->m_height
);
857 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
859 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
860 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
862 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
863 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
868 /* resize window in OnInternalIdle */
872 wxMenuBar
*wxFrame::GetMenuBar() const
874 return m_frameMenuBar
;
877 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
881 // if no help string found, we will clear the status bar text
884 int menuId
= event
.GetMenuId();
887 wxMenuBar
*menuBar
= GetMenuBar();
890 helpString
= menuBar
->GetHelpString(menuId
);
894 SetStatusText(helpString
);
898 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
900 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
902 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
904 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
906 GetChildren().DeleteObject( m_frameToolBar
);
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
);