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"
20 #include "wx/toolbar.h"
23 #include "wx/statusbr.h"
25 #include "wx/dcclient.h"
30 #include "wx/gtk/win_gtk.h"
31 #include "gdk/gdkkeysyms.h"
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 const int wxMENU_HEIGHT
= 27;
39 const int wxSTATUS_HEIGHT
= 25;
40 const int wxPLACE_HOLDER
= 0;
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 extern void wxapp_install_idle_handler();
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
53 extern wxList wxPendingDelete
;
55 //-----------------------------------------------------------------------------
57 //-----------------------------------------------------------------------------
61 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
72 wxapp_install_idle_handler();
74 if (!win
->m_hasVMT
) return;
76 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
78 win
->m_width
= alloc
->width
;
79 win
->m_height
= alloc
->height
;
84 //-----------------------------------------------------------------------------
86 //-----------------------------------------------------------------------------
88 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
91 wxapp_install_idle_handler();
98 //-----------------------------------------------------------------------------
99 // "child_attached" of menu bar
100 //-----------------------------------------------------------------------------
102 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
104 if (!win
->m_hasVMT
) return;
106 win
->m_menuBarDetached
= FALSE
;
110 //-----------------------------------------------------------------------------
111 // "child_detached" of menu bar
112 //-----------------------------------------------------------------------------
114 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
116 if (!win
->m_hasVMT
) return;
118 win
->m_menuBarDetached
= TRUE
;
123 //-----------------------------------------------------------------------------
124 // "child_attached" of tool bar
125 //-----------------------------------------------------------------------------
127 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
129 if (!win
->m_hasVMT
) return;
131 win
->m_toolBarDetached
= FALSE
;
136 //-----------------------------------------------------------------------------
137 // "child_detached" of tool bar
138 //-----------------------------------------------------------------------------
140 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
143 wxapp_install_idle_handler();
145 if (!win
->m_hasVMT
) return;
147 win
->m_toolBarDetached
= TRUE
;
150 #endif // wxUSE_TOOLBAR
152 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
157 #if (GTK_MINOR_VERSON > 0)
158 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
160 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
164 wxapp_install_idle_handler();
166 if (!win
->m_hasVMT
) return FALSE
;
168 #if (GTK_MINOR_VERSON > 0)
171 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
179 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
180 mevent
.SetEventObject( win
);
181 win
->GetEventHandler()->ProcessEvent( mevent
);
186 //-----------------------------------------------------------------------------
187 // "realize" from m_widget
188 //-----------------------------------------------------------------------------
190 /* we cannot MWM hints and icons before the widget has been realized,
191 so we do this directly after realization */
194 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
197 wxapp_install_idle_handler();
199 /* all this is for Motif Window Manager "hints" and is supposed to be
200 recognized by other WM as well. not tested. */
201 long decor
= (long) GDK_DECOR_BORDER
;
202 long func
= (long) GDK_FUNC_MOVE
;
204 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
205 decor
|= GDK_DECOR_TITLE
;
206 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
208 decor
|= GDK_DECOR_MENU
;
209 func
|= GDK_FUNC_CLOSE
;
211 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
213 func
|= GDK_FUNC_MINIMIZE
;
214 decor
|= GDK_DECOR_MINIMIZE
;
216 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
218 func
|= GDK_FUNC_MAXIMIZE
;
219 decor
|= GDK_DECOR_MAXIMIZE
;
221 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
223 func
|= GDK_FUNC_RESIZE
;
224 decor
|= GDK_DECOR_RESIZEH
;
228 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
229 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
231 /* GTK's shrinking/growing policy */
232 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
233 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
235 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
238 if (win
->m_icon
!= wxNullIcon
)
240 wxIcon
icon( win
->m_icon
);
241 win
->m_icon
= wxNullIcon
;
242 win
->SetIcon( icon
);
245 /* we set the focus to the child that accepts the focus. this
246 doesn't really have to be done in "realize" but why not? */
247 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
250 wxWindow
*child
= node
->GetData();
251 if (child
->AcceptsFocus())
257 node
= node
->GetNext();
263 //-----------------------------------------------------------------------------
264 // InsertChild for wxFrame
265 //-----------------------------------------------------------------------------
267 /* Callback for wxFrame. This very strange beast has to be used because
268 * C++ has no virtual methods in a constructor. We have to emulate a
269 * virtual function here as wxWindows requires different ways to insert
270 * a child in container classes. */
272 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
274 if (!parent
->m_insertInClientArea
)
276 /* these are outside the client area */
277 wxFrame
* frame
= (wxFrame
*) parent
;
278 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
279 GTK_WIDGET(child
->m_widget
),
286 /* we connect to these events for recalculating the client area
287 space when the toolbar is floating */
288 if (wxIS_KIND_OF(child
,wxToolBar
))
290 wxToolBar
*toolBar
= (wxToolBar
*) child
;
291 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
293 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
294 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
296 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
297 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
300 #endif // wxUSE_TOOLBAR
304 /* these are inside the client area */
305 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
306 GTK_WIDGET(child
->m_widget
),
313 /* resize on OnInternalIdle */
314 parent
->UpdateSize();
317 //-----------------------------------------------------------------------------
319 //-----------------------------------------------------------------------------
321 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
322 EVT_SIZE(wxFrame::OnSize
)
323 EVT_CLOSE(wxFrame::OnCloseWindow
)
324 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
327 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
331 m_frameMenuBar
= (wxMenuBar
*) NULL
;
333 m_frameStatusBar
= (wxStatusBar
*) NULL
;
334 #endif // wxUSE_STATUSBAR
336 m_frameToolBar
= (wxToolBar
*) NULL
;
337 #endif // wxUSE_TOOLBAR
341 m_mainWidget
= (GtkWidget
*) NULL
;
342 m_menuBarDetached
= FALSE
;
343 m_toolBarDetached
= FALSE
;
344 m_insertInClientArea
= TRUE
;
347 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
348 const wxPoint
&pos
, const wxSize
&size
,
349 long style
, const wxString
&name
)
353 Create( parent
, id
, title
, pos
, size
, style
, name
);
356 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
357 const wxPoint
&pos
, const wxSize
&size
,
358 long style
, const wxString
&name
)
360 wxTopLevelWindows
.Append( this );
362 m_needParent
= FALSE
;
364 PreCreation( parent
, id
, pos
, size
, style
, name
);
368 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
370 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
371 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
373 m_widget
= gtk_window_new( win_type
);
376 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
379 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
382 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
383 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
385 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
386 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
388 /* m_mainWidget holds the toolbar, the menubar and the client area */
389 m_mainWidget
= gtk_myfixed_new();
390 gtk_widget_show( m_mainWidget
);
391 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
392 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
395 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
398 /* m_wxwindow only represents the client area without toolbar and menubar */
399 m_wxwindow
= gtk_myfixed_new();
400 gtk_widget_show( m_wxwindow
);
401 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
404 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
407 /* we donm't allow the frame to get the focus as otherwise
408 the frame will grabit at arbitrary fcous changes. */
409 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
411 if (m_parent
) m_parent
->AddChild( this );
415 /* we cannot set MWM hints and icons before the widget has
416 been realized, so we do this directly after realization */
417 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
418 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
420 /* the user resized the frame by dragging etc. */
421 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
422 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
424 /* the only way to get the window size is to connect to this event */
425 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
426 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
433 m_isBeingDeleted
= TRUE
;
435 if (m_frameMenuBar
) delete m_frameMenuBar
;
436 m_frameMenuBar
= (wxMenuBar
*) NULL
;
439 if (m_frameStatusBar
) delete m_frameStatusBar
;
440 m_frameStatusBar
= (wxStatusBar
*) NULL
;
441 #endif // wxUSE_STATUSBAR
444 if (m_frameToolBar
) delete m_frameToolBar
;
445 m_frameToolBar
= (wxToolBar
*) NULL
;
446 #endif // wxUSE_TOOLBAR
448 wxTopLevelWindows
.DeleteObject( this );
450 if (wxTheApp
->GetTopWindow() == this)
451 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
453 if (wxTopLevelWindows
.Number() == 0)
454 wxTheApp
->ExitMainLoop();
457 bool wxFrame::Show( bool show
)
459 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
461 if (show
&& !m_sizeSet
)
463 /* by calling GtkOnSize here, we don't have to call
464 either after showing the frame, which would entail
465 much ugly flicker or from within the size_allocate
466 handler, because GTK 1.1.X forbids that. */
468 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
471 return wxWindow::Show( show
);
474 bool wxFrame::Destroy()
476 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
478 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
483 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
485 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
487 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
488 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
490 /* avoid recursions */
491 if (m_resizing
) return;
496 int old_width
= m_width
;
497 int old_height
= m_height
;
499 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
501 if (x
!= -1) m_x
= x
;
502 if (y
!= -1) m_y
= y
;
503 if (width
!= -1) m_width
= width
;
504 if (height
!= -1) m_height
= height
;
514 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
516 if (width
== -1) m_width
= 80;
519 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
521 if (height
== -1) m_height
= 26;
524 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
525 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
526 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
527 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
529 if ((m_x
!= -1) || (m_y
!= -1))
531 if ((m_x
!= old_x
) || (m_y
!= old_y
))
533 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
537 if ((m_width
!= old_width
) || (m_height
!= old_height
))
539 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
540 done either directly before the frame is shown or in idle time
541 so that different calls to SetSize() don't lead to flicker. */
548 void wxFrame::Centre( int direction
)
550 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
555 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
556 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
561 void wxFrame::DoGetClientSize( int *width
, int *height
) const
563 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
565 wxWindow::DoGetClientSize( width
, height
);
571 if (!m_menuBarDetached
)
572 (*height
) -= wxMENU_HEIGHT
;
574 (*height
) -= wxPLACE_HOLDER
;
579 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
586 if (!m_toolBarDetached
)
589 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
593 (*height
) -= wxPLACE_HOLDER
;
598 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
602 (*width
) -= m_miniEdge
*2;
606 void wxFrame::DoSetClientSize( int width
, int height
)
608 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
613 if (!m_menuBarDetached
)
614 height
+= wxMENU_HEIGHT
;
616 height
+= wxPLACE_HOLDER
;
621 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
628 if (!m_toolBarDetached
)
631 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
635 height
+= wxPLACE_HOLDER
;
639 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
642 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
644 // due to a bug in gtk, x,y are always 0
648 /* avoid recursions */
649 if (m_resizing
) return;
652 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
653 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
658 /* space occupied by m_frameToolBar and m_frameMenuBar */
659 int client_area_y_offset
= 0;
661 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
662 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
663 set in wxFrame::Create so it is used to check what kind of frame we
664 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
665 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
666 importantly) m_mainWidget */
670 /* check if size is in legal range */
671 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
672 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
673 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
674 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
676 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
677 * menubar, the toolbar and the client area, which is represented by
679 * this hurts in the eye, but I don't want to call SetSize()
680 * because I don't want to call any non-native functions here. */
685 int yy
= m_miniEdge
+ m_miniTitle
;
686 int ww
= m_width
- 2*m_miniEdge
;
687 int hh
= wxMENU_HEIGHT
;
688 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
689 m_frameMenuBar
->m_x
= xx
;
690 m_frameMenuBar
->m_y
= yy
;
691 m_frameMenuBar
->m_width
= ww
;
692 m_frameMenuBar
->m_height
= hh
;
693 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
694 m_frameMenuBar
->m_widget
,
696 client_area_y_offset
+= hh
;
703 int yy
= m_miniEdge
+ m_miniTitle
;
706 if (!m_menuBarDetached
)
709 yy
+= wxPLACE_HOLDER
;
711 int ww
= m_width
- 2*m_miniEdge
;
712 int hh
= m_frameToolBar
->m_height
;
713 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
714 m_frameToolBar
->m_x
= xx
;
715 m_frameToolBar
->m_y
= yy
;
716 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
717 m_frameToolBar
->m_width
= ww
;
718 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
719 m_frameToolBar
->m_widget
,
721 client_area_y_offset
+= hh
;
725 int client_x
= m_miniEdge
;
726 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
727 int client_w
= m_width
- 2*m_miniEdge
;
728 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
729 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
731 client_x
, client_y
, client_w
, client_h
);
735 /* if there is no m_mainWidget between m_widget and m_wxwindow there
736 is no need to set the size or position of m_wxwindow. */
740 if (m_frameStatusBar
)
742 int xx
= 0 + m_miniEdge
;
743 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
744 int ww
= m_width
- 2*m_miniEdge
;
745 int hh
= wxSTATUS_HEIGHT
;
746 m_frameStatusBar
->m_x
= xx
;
747 m_frameStatusBar
->m_y
= yy
;
748 m_frameStatusBar
->m_width
= ww
;
749 m_frameStatusBar
->m_height
= hh
;
750 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
751 m_frameStatusBar
->m_widget
,
756 /* we actually set the size of a frame here and no-where else */
757 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
761 /* send size event to frame */
762 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
763 event
.SetEventObject( this );
764 GetEventHandler()->ProcessEvent( event
);
766 /* send size event to status bar */
767 if (m_frameStatusBar
)
769 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
770 event2
.SetEventObject( m_frameStatusBar
);
771 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
777 void wxFrame::MakeModal( bool modal
)
780 gtk_grab_add( m_widget
);
782 gtk_grab_remove( m_widget
);
785 void wxFrame::OnInternalIdle()
787 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
788 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
792 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
794 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
797 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
801 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
806 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
808 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
810 #if wxUSE_CONSTRAINTS
816 #endif // wxUSE_CONSTRAINTS
818 /* do we have exactly one child? */
819 wxWindow
*child
= (wxWindow
*)NULL
;
820 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
822 wxWindow
*win
= (wxWindow
*)node
->Data();
823 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
827 /* it's the second one: do nothing */
835 /* no children at all? */
838 /* yes: set it's size to fill all the frame */
839 int client_x
, client_y
;
840 DoGetClientSize( &client_x
, &client_y
);
841 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
846 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
848 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
849 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
851 m_frameMenuBar
= menuBar
;
855 m_frameMenuBar
->SetInvokingWindow( this );
857 if (m_frameMenuBar
->GetParent() != this)
859 m_frameMenuBar
->SetParent(this);
860 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
861 m_frameMenuBar
->m_widget
,
864 m_frameMenuBar
->m_width
,
865 m_frameMenuBar
->m_height
);
867 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
869 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
870 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
872 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
873 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
876 m_frameMenuBar
->Show( TRUE
);
880 /* resize window in OnInternalIdle */
884 wxMenuBar
*wxFrame::GetMenuBar() const
886 return m_frameMenuBar
;
889 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
894 // if no help string found, we will clear the status bar text
897 int menuId
= event
.GetMenuId();
900 wxMenuBar
*menuBar
= GetMenuBar();
903 helpString
= menuBar
->GetHelpString(menuId
);
907 SetStatusText(helpString
);
909 #endif // wxUSE_STATUSBAR
913 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
915 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
917 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
919 m_insertInClientArea
= FALSE
;
921 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
923 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
925 m_insertInClientArea
= TRUE
;
929 return m_frameToolBar
;
932 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
934 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
937 wxToolBar
*wxFrame::GetToolBar() const
939 return m_frameToolBar
;
941 #endif // wxUSE_TOOLBAR
944 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
946 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
948 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
950 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
954 return m_frameStatusBar
;
957 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
959 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
961 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
963 // Set the height according to the font and the border size
964 wxClientDC
dc(statusBar
);
965 dc
.SetFont( statusBar
->GetFont() );
968 dc
.GetTextExtent( "X", &x
, &y
);
970 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
972 statusBar
->SetSize( -1, -1, 100, height
);
974 statusBar
->SetFieldsCount( number
);
978 wxStatusBar
*wxFrame::GetStatusBar() const
980 return m_frameStatusBar
;
983 void wxFrame::SetStatusText(const wxString
& text
, int number
)
985 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
987 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
989 m_frameStatusBar
->SetStatusText(text
, number
);
992 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
994 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
996 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
998 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1000 #endif // wxUSE_STATUSBAR
1002 void wxFrame::Command( int id
)
1004 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1005 commandEvent
.SetInt( id
);
1006 commandEvent
.SetEventObject( this );
1008 wxMenuBar
*bar
= GetMenuBar();
1011 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1012 if (item
&& item
->IsCheckable())
1014 bar
->Check(id
,!bar
->Checked(id
)) ;
1017 wxEvtHandler
* evtHandler
= GetEventHandler();
1019 evtHandler
->ProcessEvent(commandEvent
);
1022 void wxFrame::SetTitle( const wxString
&title
)
1024 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1027 if (m_title
.IsNull()) m_title
= _T("");
1028 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1031 void wxFrame::SetIcon( const wxIcon
&icon
)
1033 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1036 if (!icon
.Ok()) return;
1038 if (!m_widget
->window
) return;
1040 wxMask
*mask
= icon
.GetMask();
1041 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1042 if (mask
) bm
= mask
->GetBitmap();
1044 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1047 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1051 void wxFrame::Restore()
1055 void wxFrame::Iconize( bool iconize
)
1059 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1060 GDK_WINDOW_XWINDOW( m_widget
->window
),
1061 DefaultScreen( GDK_DISPLAY() ) );
1065 bool wxFrame::IsIconized() const