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
*WXUNUSED(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
*WXUNUSED(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
;
227 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
228 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
230 /* GTK's shrinking/growing policy */
231 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
232 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
234 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
237 if (win
->m_icon
!= wxNullIcon
)
239 wxIcon
icon( win
->m_icon
);
240 win
->m_icon
= wxNullIcon
;
241 win
->SetIcon( icon
);
244 /* we set the focus to the child that accepts the focus. this
245 doesn't really have to be done in "realize" but why not? */
246 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
249 wxWindow
*child
= node
->GetData();
250 if (child
->AcceptsFocus())
256 node
= node
->GetNext();
262 //-----------------------------------------------------------------------------
263 // InsertChild for wxFrame
264 //-----------------------------------------------------------------------------
266 /* Callback for wxFrame. This very strange beast has to be used because
267 * C++ has no virtual methods in a constructor. We have to emulate a
268 * virtual function here as wxWindows requires different ways to insert
269 * a child in container classes. */
271 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
273 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
275 if (!parent
->m_insertInClientArea
)
277 /* these are outside the client area */
278 wxFrame
* frame
= (wxFrame
*) parent
;
279 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
280 GTK_WIDGET(child
->m_widget
),
287 /* we connect to these events for recalculating the client area
288 space when the toolbar is floating */
289 if (wxIS_KIND_OF(child
,wxToolBar
))
291 wxToolBar
*toolBar
= (wxToolBar
*) child
;
292 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
294 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
295 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
297 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
298 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
301 #endif // wxUSE_TOOLBAR
305 /* these are inside the client area */
306 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
307 GTK_WIDGET(child
->m_widget
),
314 /* resize on OnInternalIdle */
315 parent
->UpdateSize();
318 //-----------------------------------------------------------------------------
320 //-----------------------------------------------------------------------------
322 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
323 EVT_SIZE(wxFrame::OnSize
)
324 EVT_CLOSE(wxFrame::OnCloseWindow
)
325 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
328 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
332 m_frameMenuBar
= (wxMenuBar
*) NULL
;
334 m_frameStatusBar
= (wxStatusBar
*) NULL
;
335 #endif // wxUSE_STATUSBAR
337 m_frameToolBar
= (wxToolBar
*) NULL
;
338 #endif // wxUSE_TOOLBAR
342 m_mainWidget
= (GtkWidget
*) NULL
;
343 m_menuBarDetached
= FALSE
;
344 m_toolBarDetached
= FALSE
;
345 m_insertInClientArea
= TRUE
;
348 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
349 const wxPoint
&pos
, const wxSize
&size
,
350 long style
, const wxString
&name
)
354 Create( parent
, id
, title
, pos
, size
, style
, name
);
357 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
358 const wxPoint
&pos
, const wxSize
&size
,
359 long style
, const wxString
&name
)
361 wxTopLevelWindows
.Append( this );
363 m_needParent
= FALSE
;
365 if (!PreCreation( parent
, pos
, size
) ||
366 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
368 wxFAIL_MSG( T("wxFrame creation failed") );
374 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
376 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
377 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
379 m_widget
= gtk_window_new( win_type
);
382 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
385 debug_focus_in( m_widget
, T("wxFrame::m_widget"), name
);
388 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
389 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
391 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
392 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
394 /* m_mainWidget holds the toolbar, the menubar and the client area */
395 m_mainWidget
= gtk_myfixed_new();
396 gtk_widget_show( m_mainWidget
);
397 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
398 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
401 debug_focus_in( m_mainWidget
, T("wxFrame::m_mainWidget"), name
);
404 /* m_wxwindow only represents the client area without toolbar and menubar */
405 m_wxwindow
= gtk_myfixed_new();
406 gtk_widget_show( m_wxwindow
);
407 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
410 debug_focus_in( m_wxwindow
, T("wxFrame::m_wxwindow"), name
);
413 /* we donm't allow the frame to get the focus as otherwise
414 the frame will grabit at arbitrary fcous changes. */
415 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
417 if (m_parent
) m_parent
->AddChild( this );
421 /* we cannot set MWM hints and icons before the widget has
422 been realized, so we do this directly after realization */
423 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
424 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
426 /* the user resized the frame by dragging etc. */
427 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
428 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
430 /* the only way to get the window size is to connect to this event */
431 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
432 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
439 m_isBeingDeleted
= TRUE
;
441 if (m_frameMenuBar
) delete m_frameMenuBar
;
442 m_frameMenuBar
= (wxMenuBar
*) NULL
;
445 if (m_frameStatusBar
) delete m_frameStatusBar
;
446 m_frameStatusBar
= (wxStatusBar
*) NULL
;
447 #endif // wxUSE_STATUSBAR
450 if (m_frameToolBar
) delete m_frameToolBar
;
451 m_frameToolBar
= (wxToolBar
*) NULL
;
452 #endif // wxUSE_TOOLBAR
454 wxTopLevelWindows
.DeleteObject( this );
456 if (wxTheApp
->GetTopWindow() == this)
457 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
459 if (wxTopLevelWindows
.Number() == 0)
460 wxTheApp
->ExitMainLoop();
463 bool wxFrame::Show( bool show
)
465 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
467 if (show
&& !m_sizeSet
)
469 /* by calling GtkOnSize here, we don't have to call
470 either after showing the frame, which would entail
471 much ugly flicker or from within the size_allocate
472 handler, because GTK 1.1.X forbids that. */
474 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
477 return wxWindow::Show( show
);
480 bool wxFrame::Destroy()
482 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
484 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
489 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
491 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
493 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
494 wxASSERT_MSG( (m_wxwindow
!= NULL
), T("invalid frame") );
496 /* avoid recursions */
497 if (m_resizing
) return;
502 int old_width
= m_width
;
503 int old_height
= m_height
;
505 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
507 if (x
!= -1) m_x
= x
;
508 if (y
!= -1) m_y
= y
;
509 if (width
!= -1) m_width
= width
;
510 if (height
!= -1) m_height
= height
;
520 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
522 if (width
== -1) m_width
= 80;
525 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
527 if (height
== -1) m_height
= 26;
530 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
531 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
532 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
533 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
535 if ((m_x
!= -1) || (m_y
!= -1))
537 if ((m_x
!= old_x
) || (m_y
!= old_y
))
539 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
543 if ((m_width
!= old_width
) || (m_height
!= old_height
))
545 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
546 done either directly before the frame is shown or in idle time
547 so that different calls to SetSize() don't lead to flicker. */
554 void wxFrame::Centre( int direction
)
556 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
561 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
562 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
567 void wxFrame::DoGetClientSize( int *width
, int *height
) const
569 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
571 wxWindow::DoGetClientSize( width
, height
);
577 if (!m_menuBarDetached
)
578 (*height
) -= wxMENU_HEIGHT
;
580 (*height
) -= wxPLACE_HOLDER
;
585 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
592 if (!m_toolBarDetached
)
595 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
599 (*height
) -= wxPLACE_HOLDER
;
604 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
608 (*width
) -= m_miniEdge
*2;
612 void wxFrame::DoSetClientSize( int width
, int height
)
614 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
619 if (!m_menuBarDetached
)
620 height
+= wxMENU_HEIGHT
;
622 height
+= wxPLACE_HOLDER
;
627 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
634 if (!m_toolBarDetached
)
637 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
641 height
+= wxPLACE_HOLDER
;
645 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
648 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
650 // due to a bug in gtk, x,y are always 0
654 /* avoid recursions */
655 if (m_resizing
) return;
658 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
659 wxASSERT_MSG( (m_wxwindow
!= NULL
), T("invalid frame") );
664 /* space occupied by m_frameToolBar and m_frameMenuBar */
665 int client_area_y_offset
= 0;
667 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
668 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
669 set in wxFrame::Create so it is used to check what kind of frame we
670 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
671 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
672 importantly) m_mainWidget */
676 /* check if size is in legal range */
677 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
678 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
679 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
680 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
682 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
683 * menubar, the toolbar and the client area, which is represented by
685 * this hurts in the eye, but I don't want to call SetSize()
686 * because I don't want to call any non-native functions here. */
691 int yy
= m_miniEdge
+ m_miniTitle
;
692 int ww
= m_width
- 2*m_miniEdge
;
693 int hh
= wxMENU_HEIGHT
;
694 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
695 m_frameMenuBar
->m_x
= xx
;
696 m_frameMenuBar
->m_y
= yy
;
697 m_frameMenuBar
->m_width
= ww
;
698 m_frameMenuBar
->m_height
= hh
;
699 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
700 m_frameMenuBar
->m_widget
,
702 client_area_y_offset
+= hh
;
709 int yy
= m_miniEdge
+ m_miniTitle
;
712 if (!m_menuBarDetached
)
715 yy
+= wxPLACE_HOLDER
;
717 int ww
= m_width
- 2*m_miniEdge
;
718 int hh
= m_frameToolBar
->m_height
;
719 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
720 m_frameToolBar
->m_x
= xx
;
721 m_frameToolBar
->m_y
= yy
;
722 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
723 m_frameToolBar
->m_width
= ww
;
724 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
725 m_frameToolBar
->m_widget
,
727 client_area_y_offset
+= hh
;
731 int client_x
= m_miniEdge
;
732 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
733 int client_w
= m_width
- 2*m_miniEdge
;
734 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
735 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
737 client_x
, client_y
, client_w
, client_h
);
741 /* if there is no m_mainWidget between m_widget and m_wxwindow there
742 is no need to set the size or position of m_wxwindow. */
746 if (m_frameStatusBar
)
748 int xx
= 0 + m_miniEdge
;
749 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
750 int ww
= m_width
- 2*m_miniEdge
;
751 int hh
= wxSTATUS_HEIGHT
;
752 m_frameStatusBar
->m_x
= xx
;
753 m_frameStatusBar
->m_y
= yy
;
754 m_frameStatusBar
->m_width
= ww
;
755 m_frameStatusBar
->m_height
= hh
;
756 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
757 m_frameStatusBar
->m_widget
,
762 /* we actually set the size of a frame here and no-where else */
763 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
767 /* send size event to frame */
768 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
769 event
.SetEventObject( this );
770 GetEventHandler()->ProcessEvent( event
);
772 /* send size event to status bar */
773 if (m_frameStatusBar
)
775 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
776 event2
.SetEventObject( m_frameStatusBar
);
777 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
783 void wxFrame::MakeModal( bool modal
)
786 gtk_grab_add( m_widget
);
788 gtk_grab_remove( m_widget
);
791 void wxFrame::OnInternalIdle()
793 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
794 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
798 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
800 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
803 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
806 wxWindow::OnInternalIdle();
809 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
814 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
816 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
818 #if wxUSE_CONSTRAINTS
824 #endif // wxUSE_CONSTRAINTS
826 /* do we have exactly one child? */
827 wxWindow
*child
= (wxWindow
*)NULL
;
828 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
830 wxWindow
*win
= (wxWindow
*)node
->Data();
831 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
835 /* it's the second one: do nothing */
843 /* no children at all? */
846 /* yes: set it's size to fill all the frame */
847 int client_x
, client_y
;
848 DoGetClientSize( &client_x
, &client_y
);
849 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
854 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
856 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
857 wxASSERT_MSG( (m_wxwindow
!= NULL
), T("invalid frame") );
859 m_frameMenuBar
= menuBar
;
863 m_frameMenuBar
->SetInvokingWindow( this );
865 if (m_frameMenuBar
->GetParent() != this)
867 m_frameMenuBar
->SetParent(this);
868 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
869 m_frameMenuBar
->m_widget
,
872 m_frameMenuBar
->m_width
,
873 m_frameMenuBar
->m_height
);
875 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
877 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
878 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
880 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
881 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
884 m_frameMenuBar
->Show( TRUE
);
888 /* resize window in OnInternalIdle */
892 wxMenuBar
*wxFrame::GetMenuBar() const
894 return m_frameMenuBar
;
897 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
902 // if no help string found, we will clear the status bar text
905 int menuId
= event
.GetMenuId();
908 wxMenuBar
*menuBar
= GetMenuBar();
911 helpString
= menuBar
->GetHelpString(menuId
);
915 SetStatusText(helpString
);
917 #endif // wxUSE_STATUSBAR
921 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
923 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
925 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, T("recreating toolbar in wxFrame") );
927 m_insertInClientArea
= FALSE
;
929 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
931 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
933 m_insertInClientArea
= TRUE
;
937 return m_frameToolBar
;
940 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
942 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
945 wxToolBar
*wxFrame::GetToolBar() const
947 return m_frameToolBar
;
949 #endif // wxUSE_TOOLBAR
952 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
954 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
956 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, T("recreating status bar in wxFrame") );
958 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
962 return m_frameStatusBar
;
965 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
967 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
969 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
971 // Set the height according to the font and the border size
972 wxClientDC
dc(statusBar
);
973 dc
.SetFont( statusBar
->GetFont() );
976 dc
.GetTextExtent( "X", &x
, &y
);
978 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
980 statusBar
->SetSize( -1, -1, 100, height
);
982 statusBar
->SetFieldsCount( number
);
986 wxStatusBar
*wxFrame::GetStatusBar() const
988 return m_frameStatusBar
;
991 void wxFrame::SetStatusText(const wxString
& text
, int number
)
993 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
995 wxCHECK_RET( m_frameStatusBar
!= NULL
, T("no statusbar to set text for") );
997 m_frameStatusBar
->SetStatusText(text
, number
);
1000 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1002 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
1004 wxCHECK_RET( m_frameStatusBar
!= NULL
, T("no statusbar to set widths for") );
1006 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1008 #endif // wxUSE_STATUSBAR
1010 void wxFrame::Command( int id
)
1012 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1013 commandEvent
.SetInt( id
);
1014 commandEvent
.SetEventObject( this );
1016 wxMenuBar
*bar
= GetMenuBar();
1019 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1020 if (item
&& item
->IsCheckable())
1022 bar
->Check(id
,!bar
->Checked(id
)) ;
1025 wxEvtHandler
* evtHandler
= GetEventHandler();
1027 evtHandler
->ProcessEvent(commandEvent
);
1030 void wxFrame::SetTitle( const wxString
&title
)
1032 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
1035 if (m_title
.IsNull()) m_title
= T("");
1036 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1039 void wxFrame::SetIcon( const wxIcon
&icon
)
1041 wxASSERT_MSG( (m_widget
!= NULL
), T("invalid frame") );
1044 if (!icon
.Ok()) return;
1046 if (!m_widget
->window
) return;
1048 wxMask
*mask
= icon
.GetMask();
1049 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1050 if (mask
) bm
= mask
->GetBitmap();
1052 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1055 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1059 void wxFrame::Restore()
1063 void wxFrame::Iconize( bool iconize
)
1067 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1068 GDK_WINDOW_XWINDOW( m_widget
->window
),
1069 DefaultScreen( GDK_DISPLAY() ) );
1073 bool wxFrame::IsIconized() const