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_ALL
;
195 long func
= (long) GDK_FUNC_ALL
;
197 if ((win
->m_windowStyle
& wxCAPTION
) == 0)
198 decor
|= GDK_DECOR_TITLE
;
199 /* if ((win->m_windowStyle & wxMINIMIZE) == 0)
200 func |= GDK_FUNC_MINIMIZE;
201 if ((win->m_windowStyle & wxMAXIMIZE) == 0)
202 func |= GDK_FUNC_MAXIMIZE; */
203 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) == 0)
204 decor
|= GDK_DECOR_MENU
;
205 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) == 0)
206 decor
|= GDK_DECOR_MINIMIZE
;
207 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
208 decor
|= GDK_DECOR_MAXIMIZE
;
209 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
210 func
|= GDK_FUNC_RESIZE
;
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
->m_windowStyle
& 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 wxNode
*node
= win
->m_children
.First();
234 wxWindow
*child
= (wxWindow
*) node
->Data();
235 if (child
->AcceptsFocus())
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( wxWindow
* parent
, wxWindow
* child
)
258 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
260 /* actually, menubars are never inserted here, but this
261 may change one day */
263 /* these are outside the client area */
264 wxFrame
* frame
= (wxFrame
*) parent
;
265 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
266 GTK_WIDGET(child
->m_widget
),
270 /* we connect to these events for recalculating the client area
271 space when the toolbar is floating */
272 if (wxIS_KIND_OF(child
,wxToolBar
))
274 wxToolBar
*toolBar
= (wxToolBar
*) child
;
275 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
277 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
278 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
280 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
281 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
287 /* these are inside the client area */
288 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
289 GTK_WIDGET(child
->m_widget
),
294 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
298 /* resize on OnInternalIdle */
299 parent
->m_sizeSet
= FALSE
;
302 //-----------------------------------------------------------------------------
304 //-----------------------------------------------------------------------------
306 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
307 EVT_SIZE(wxFrame::OnSize
)
308 EVT_CLOSE(wxFrame::OnCloseWindow
)
309 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
312 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
316 m_frameMenuBar
= (wxMenuBar
*) NULL
;
317 m_frameStatusBar
= (wxStatusBar
*) NULL
;
318 m_frameToolBar
= (wxToolBar
*) NULL
;
322 m_mainWidget
= (GtkWidget
*) NULL
;
323 m_menuBarDetached
= FALSE
;
324 m_toolBarDetached
= FALSE
;
325 m_insertCallback
= wxInsertChildInFrame
;
328 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
329 const wxPoint
&pos
, const wxSize
&size
,
330 long style
, const wxString
&name
)
332 m_frameMenuBar
= (wxMenuBar
*) NULL
;
333 m_frameStatusBar
= (wxStatusBar
*) NULL
;
334 m_frameToolBar
= (wxToolBar
*) NULL
;
338 m_mainWidget
= (GtkWidget
*) NULL
;
339 m_menuBarDetached
= FALSE
;
340 m_toolBarDetached
= FALSE
;
341 m_insertCallback
= wxInsertChildInFrame
;
342 Create( parent
, id
, title
, pos
, size
, style
, name
);
345 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
346 const wxPoint
&pos
, const wxSize
&size
,
347 long style
, const wxString
&name
)
349 wxTopLevelWindows
.Append( this );
351 m_needParent
= FALSE
;
353 PreCreation( parent
, id
, pos
, size
, style
, name
);
357 m_insertCallback
= wxInsertChildInFrame
;
359 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
360 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
362 m_widget
= gtk_window_new( win_type
);
365 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
368 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
369 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
371 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
372 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
374 /* m_mainWidget holds the toolbar, the menubar and the client area */
375 m_mainWidget
= gtk_myfixed_new();
376 gtk_widget_show( m_mainWidget
);
377 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
378 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
381 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
384 /* m_wxwindow only represents the client area without toolbar and menubar */
385 m_wxwindow
= gtk_myfixed_new();
386 gtk_widget_show( m_wxwindow
);
387 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
390 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
393 /* we donm't allow the frame to get the focus as otherwise
394 the frame will grabit at arbitrary fcous changes. */
395 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
397 if (m_parent
) m_parent
->AddChild( this );
401 /* we cannot set MWM hints and icons before the widget has
402 been realized, so we do this directly after realization */
403 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
404 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
406 /* the user resized the frame by dragging etc. */
407 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
408 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
410 /* the only way to get the window size is to connect to this event */
411 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
412 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
419 if (m_frameMenuBar
) delete m_frameMenuBar
;
420 m_frameMenuBar
= (wxMenuBar
*) NULL
;
422 if (m_frameStatusBar
) delete m_frameStatusBar
;
423 m_frameStatusBar
= (wxStatusBar
*) NULL
;
425 if (m_frameToolBar
) delete m_frameToolBar
;
426 m_frameToolBar
= (wxToolBar
*) NULL
;
428 wxTopLevelWindows
.DeleteObject( this );
430 if (wxTheApp
->GetTopWindow() == this)
431 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
433 if (wxTopLevelWindows
.Number() == 0)
434 wxTheApp
->ExitMainLoop();
437 bool wxFrame::Show( bool show
)
439 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
441 if (show
&& !m_sizeSet
)
443 /* by calling GtkOnSize here, we don't have to call
444 either after showing the frame, which would entail
445 much ugly flicker or from within the size_allocate
446 handler, because GTK 1.1.X forbids that. */
448 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
451 return wxWindow::Show( show
);
454 bool wxFrame::Destroy()
456 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
458 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
463 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
465 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
467 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
468 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
470 /* avoid recursions */
471 if (m_resizing
) return;
476 int old_width
= m_width
;
477 int old_height
= m_height
;
479 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
481 if (x
!= -1) m_x
= x
;
482 if (y
!= -1) m_y
= y
;
483 if (width
!= -1) m_width
= width
;
484 if (height
!= -1) m_height
= height
;
494 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
496 if (width
== -1) m_width
= 80;
499 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
501 if (height
== -1) m_height
= 26;
504 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
505 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
506 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
507 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
509 if ((m_x
!= -1) || (m_y
!= -1))
511 if ((m_x
!= old_x
) || (m_y
!= old_y
))
513 /* we set the size here and in gtk_frame_map_callback */
514 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
518 if ((m_width
!= old_width
) || (m_height
!= old_height
))
520 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
521 done either directly before the frame is shown or in idle time
522 so that different calls to SetSize() don't lead to flicker. */
529 void wxFrame::Centre( int direction
)
531 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
536 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
537 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
542 void wxFrame::GetClientSize( int *width
, int *height
) const
544 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
546 wxWindow::GetClientSize( width
, height
);
552 if (!m_menuBarDetached
)
553 (*height
) -= wxMENU_HEIGHT
;
555 (*height
) -= wxPLACE_HOLDER
;
559 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
564 if (!m_toolBarDetached
)
567 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
571 (*height
) -= wxPLACE_HOLDER
;
575 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
579 (*width
) -= m_miniEdge
*2;
583 void wxFrame::DoSetClientSize( int width
, int height
)
585 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
590 if (!m_menuBarDetached
)
591 height
+= wxMENU_HEIGHT
;
593 height
+= wxPLACE_HOLDER
;
597 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
602 if (!m_toolBarDetached
)
605 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
609 height
+= wxPLACE_HOLDER
;
612 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
615 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
617 // due to a bug in gtk, x,y are always 0
621 /* avoid recursions */
622 if (m_resizing
) return;
625 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
626 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
631 /* space occupied by m_frameToolBar and m_frameMenuBar */
632 int client_area_y_offset
= 0;
634 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
635 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
636 set in wxFrame::Create so it is used to check what kind of frame we
637 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
638 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
639 importantly) m_mainWidget */
643 /* check if size is in legal range */
644 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
645 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
646 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
647 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
649 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
650 * menubar, the toolbar and the client area, which is represented by
652 * this hurts in the eye, but I don't want to call SetSize()
653 * because I don't want to call any non-native functions here. */
658 int yy
= m_miniEdge
+ m_miniTitle
;
659 int ww
= m_width
- 2*m_miniEdge
;
660 int hh
= wxMENU_HEIGHT
;
661 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
662 m_frameMenuBar
->m_x
= xx
;
663 m_frameMenuBar
->m_y
= yy
;
664 m_frameMenuBar
->m_width
= ww
;
665 m_frameMenuBar
->m_height
= hh
;
667 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
668 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
670 client_area_y_offset
+= hh
;
676 int yy
= m_miniEdge
+ m_miniTitle
;
679 if (!m_menuBarDetached
)
682 yy
+= wxPLACE_HOLDER
;
684 int ww
= m_width
- 2*m_miniEdge
;
685 int hh
= m_frameToolBar
->m_height
;
686 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
687 m_frameToolBar
->m_x
= xx
;
688 m_frameToolBar
->m_y
= yy
;
689 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
690 m_frameToolBar
->m_width
= ww
;
692 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
693 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
695 client_area_y_offset
+= hh
;
698 int client_x
= m_miniEdge
;
699 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
700 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
702 int client_w
= m_width
- 2*m_miniEdge
;
703 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
704 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
708 /* if there is no m_mainWidget between m_widget and m_wxwindow there
709 is no need to set the size or position of m_wxwindow. */
712 if (m_frameStatusBar
)
714 int xx
= 0 + m_miniEdge
;
715 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
716 int ww
= m_width
- 2*m_miniEdge
;
717 int hh
= wxSTATUS_HEIGHT
;
719 m_frameStatusBar
->m_x
= xx
;
720 m_frameStatusBar
->m_y
= yy
;
721 m_frameStatusBar
->m_width
= ww
;
722 m_frameStatusBar
->m_height
= hh
;
724 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
725 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
728 /* we actually set the size of a frame here and no-where else */
729 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
733 /* send size event to frame */
734 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
735 event
.SetEventObject( this );
736 GetEventHandler()->ProcessEvent( event
);
738 /* send size event to status bar */
739 if (m_frameStatusBar
)
741 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
742 event2
.SetEventObject( m_frameStatusBar
);
743 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
749 void wxFrame::OnInternalIdle()
751 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
752 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
757 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
762 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
764 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
772 /* do we have exactly one child? */
773 wxWindow
*child
= (wxWindow
*)NULL
;
774 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
776 wxWindow
*win
= (wxWindow
*)node
->Data();
777 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
781 /* it's the second one: do nothing */
789 /* no children at all? */
792 /* yes: set it's size to fill all the frame */
793 int client_x
, client_y
;
794 GetClientSize( &client_x
, &client_y
);
795 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
800 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
802 menu
->SetInvokingWindow( win
);
804 #if (GTK_MINOR_VERSION > 0)
805 /* support for native hot keys */
806 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
809 wxNode
*node
= menu
->GetItems().First();
812 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
813 if (menuitem
->IsSubMenu())
814 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
819 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
821 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
822 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
824 m_frameMenuBar
= menuBar
;
828 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
829 /* support for native key accelerators indicated by underscroes */
830 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
833 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
836 wxMenu
*menu
= (wxMenu
*)node
->Data();
837 SetInvokingWindow( menu
, this );
841 if (m_frameMenuBar
->m_parent
!= this)
843 m_frameMenuBar
->m_parent
= this;
844 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
845 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
847 if (menuBar
->m_windowStyle
& 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
);