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"
33 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
37 const int wxMENU_HEIGHT
= 27;
38 const int wxSTATUS_HEIGHT
= 25;
39 const int wxPLACE_HOLDER
= 0;
41 //-----------------------------------------------------------------------------
43 //-----------------------------------------------------------------------------
45 extern void wxapp_install_idle_handler();
48 //-----------------------------------------------------------------------------
50 //-----------------------------------------------------------------------------
52 extern wxList wxPendingDelete
;
54 //-----------------------------------------------------------------------------
56 //-----------------------------------------------------------------------------
60 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
64 //-----------------------------------------------------------------------------
66 //-----------------------------------------------------------------------------
68 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
71 wxapp_install_idle_handler();
73 if (!win
->m_hasVMT
) return;
75 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
77 win
->m_width
= alloc
->width
;
78 win
->m_height
= alloc
->height
;
83 //-----------------------------------------------------------------------------
85 //-----------------------------------------------------------------------------
87 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
90 wxapp_install_idle_handler();
97 //-----------------------------------------------------------------------------
98 // "child_attached" of menu bar
99 //-----------------------------------------------------------------------------
101 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
103 if (!win
->m_hasVMT
) return;
105 win
->m_menuBarDetached
= FALSE
;
109 //-----------------------------------------------------------------------------
110 // "child_detached" of menu bar
111 //-----------------------------------------------------------------------------
113 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
115 if (!win
->m_hasVMT
) return;
117 win
->m_menuBarDetached
= TRUE
;
122 //-----------------------------------------------------------------------------
123 // "child_attached" of tool bar
124 //-----------------------------------------------------------------------------
126 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
128 if (!win
->m_hasVMT
) return;
130 win
->m_toolBarDetached
= FALSE
;
135 //-----------------------------------------------------------------------------
136 // "child_detached" of tool bar
137 //-----------------------------------------------------------------------------
139 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
142 wxapp_install_idle_handler();
144 if (!win
->m_hasVMT
) return;
146 win
->m_toolBarDetached
= TRUE
;
149 #endif // wxUSE_TOOLBAR
151 //-----------------------------------------------------------------------------
153 //-----------------------------------------------------------------------------
155 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
158 wxapp_install_idle_handler();
160 if (!win
->m_hasVMT
) return FALSE
;
164 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
169 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
170 mevent
.SetEventObject( win
);
171 win
->GetEventHandler()->ProcessEvent( mevent
);
176 //-----------------------------------------------------------------------------
177 // "realize" from m_widget
178 //-----------------------------------------------------------------------------
180 /* we cannot MWM hints and icons before the widget has been realized,
181 so we do this directly after realization */
184 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
187 wxapp_install_idle_handler();
189 /* all this is for Motif Window Manager "hints" and is supposed to be
190 recognized by other WM as well. not tested. */
191 long decor
= (long) GDK_DECOR_BORDER
;
192 long func
= (long) GDK_FUNC_MOVE
;
194 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
195 decor
|= GDK_DECOR_TITLE
;
196 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
198 decor
|= GDK_DECOR_MENU
;
199 func
|= GDK_FUNC_CLOSE
;
201 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
203 func
|= GDK_FUNC_MINIMIZE
;
204 decor
|= GDK_DECOR_MINIMIZE
;
206 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
208 func
|= GDK_FUNC_MAXIMIZE
;
209 decor
|= GDK_DECOR_MAXIMIZE
;
211 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
213 func
|= GDK_FUNC_RESIZE
;
214 decor
|= GDK_DECOR_RESIZEH
;
218 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
219 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
221 /* GTK's shrinking/growing policy */
222 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
223 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
225 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
228 if (win
->m_icon
!= wxNullIcon
)
230 wxIcon
icon( win
->m_icon
);
231 win
->m_icon
= wxNullIcon
;
232 win
->SetIcon( icon
);
235 /* we set the focus to the child that accepts the focus. this
236 doesn't really have to be done in "realize" but why not? */
237 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
240 wxWindow
*child
= node
->GetData();
241 if (child
->AcceptsFocus())
247 node
= node
->GetNext();
253 //-----------------------------------------------------------------------------
254 // InsertChild for wxFrame
255 //-----------------------------------------------------------------------------
257 /* Callback for wxFrame. This very strange beast has to be used because
258 * C++ has no virtual methods in a constructor. We have to emulate a
259 * virtual function here as wxWindows requires different ways to insert
260 * a child in container classes. */
262 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
264 if (!parent
->m_insertInClientArea
)
266 /* these are outside the client area */
267 wxFrame
* frame
= (wxFrame
*) parent
;
268 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
269 GTK_WIDGET(child
->m_widget
),
276 /* we connect to these events for recalculating the client area
277 space when the toolbar is floating */
278 if (wxIS_KIND_OF(child
,wxToolBar
))
280 wxToolBar
*toolBar
= (wxToolBar
*) child
;
281 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
283 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
284 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
286 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
287 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
290 #endif // wxUSE_TOOLBAR
294 /* these are inside the client area */
295 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
296 GTK_WIDGET(child
->m_widget
),
303 /* resize on OnInternalIdle */
304 parent
->UpdateSize();
307 //-----------------------------------------------------------------------------
309 //-----------------------------------------------------------------------------
311 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
312 EVT_SIZE(wxFrame::OnSize
)
313 EVT_CLOSE(wxFrame::OnCloseWindow
)
314 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
317 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
321 m_frameMenuBar
= (wxMenuBar
*) NULL
;
323 m_frameStatusBar
= (wxStatusBar
*) NULL
;
324 #endif // wxUSE_STATUSBAR
326 m_frameToolBar
= (wxToolBar
*) NULL
;
327 #endif // wxUSE_TOOLBAR
331 m_mainWidget
= (GtkWidget
*) NULL
;
332 m_menuBarDetached
= FALSE
;
333 m_toolBarDetached
= FALSE
;
334 m_insertInClientArea
= TRUE
;
337 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
338 const wxPoint
&pos
, const wxSize
&size
,
339 long style
, const wxString
&name
)
343 Create( parent
, id
, title
, pos
, size
, style
, name
);
346 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
347 const wxPoint
&pos
, const wxSize
&size
,
348 long style
, const wxString
&name
)
350 wxTopLevelWindows
.Append( this );
352 m_needParent
= FALSE
;
354 PreCreation( parent
, id
, pos
, size
, style
, name
);
358 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
360 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
361 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
363 m_widget
= gtk_window_new( win_type
);
366 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
369 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
372 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
373 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
375 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
376 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
378 /* m_mainWidget holds the toolbar, the menubar and the client area */
379 m_mainWidget
= gtk_myfixed_new();
380 gtk_widget_show( m_mainWidget
);
381 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
382 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
385 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
388 /* m_wxwindow only represents the client area without toolbar and menubar */
389 m_wxwindow
= gtk_myfixed_new();
390 gtk_widget_show( m_wxwindow
);
391 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
394 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
397 /* we donm't allow the frame to get the focus as otherwise
398 the frame will grabit at arbitrary fcous changes. */
399 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
401 if (m_parent
) m_parent
->AddChild( this );
405 /* we cannot set MWM hints and icons before the widget has
406 been realized, so we do this directly after realization */
407 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
408 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
410 /* the user resized the frame by dragging etc. */
411 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
412 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
414 /* the only way to get the window size is to connect to this event */
415 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
416 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
423 m_isBeingDeleted
= TRUE
;
425 if (m_frameMenuBar
) delete m_frameMenuBar
;
426 m_frameMenuBar
= (wxMenuBar
*) NULL
;
429 if (m_frameStatusBar
) delete m_frameStatusBar
;
430 m_frameStatusBar
= (wxStatusBar
*) NULL
;
431 #endif // wxUSE_STATUSBAR
434 if (m_frameToolBar
) delete m_frameToolBar
;
435 m_frameToolBar
= (wxToolBar
*) NULL
;
436 #endif // wxUSE_TOOLBAR
438 wxTopLevelWindows
.DeleteObject( this );
440 if (wxTheApp
->GetTopWindow() == this)
441 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
443 if (wxTopLevelWindows
.Number() == 0)
444 wxTheApp
->ExitMainLoop();
447 bool wxFrame::Show( bool show
)
449 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
451 if (show
&& !m_sizeSet
)
453 /* by calling GtkOnSize here, we don't have to call
454 either after showing the frame, which would entail
455 much ugly flicker or from within the size_allocate
456 handler, because GTK 1.1.X forbids that. */
458 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
461 return wxWindow::Show( show
);
464 bool wxFrame::Destroy()
466 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
468 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
473 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
475 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
477 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
478 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
480 /* avoid recursions */
481 if (m_resizing
) return;
486 int old_width
= m_width
;
487 int old_height
= m_height
;
489 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
491 if (x
!= -1) m_x
= x
;
492 if (y
!= -1) m_y
= y
;
493 if (width
!= -1) m_width
= width
;
494 if (height
!= -1) m_height
= height
;
504 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
506 if (width
== -1) m_width
= 80;
509 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
511 if (height
== -1) m_height
= 26;
514 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
515 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
516 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
517 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
519 if ((m_x
!= -1) || (m_y
!= -1))
521 if ((m_x
!= old_x
) || (m_y
!= old_y
))
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::DoGetClientSize( int *width
, int *height
) const
553 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
555 wxWindow::DoGetClientSize( width
, height
);
561 if (!m_menuBarDetached
)
562 (*height
) -= wxMENU_HEIGHT
;
564 (*height
) -= wxPLACE_HOLDER
;
569 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
576 if (!m_toolBarDetached
)
579 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
583 (*height
) -= wxPLACE_HOLDER
;
588 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
592 (*width
) -= m_miniEdge
*2;
596 void wxFrame::DoSetClientSize( int width
, int height
)
598 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
603 if (!m_menuBarDetached
)
604 height
+= wxMENU_HEIGHT
;
606 height
+= wxPLACE_HOLDER
;
611 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
618 if (!m_toolBarDetached
)
621 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
625 height
+= wxPLACE_HOLDER
;
629 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
632 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
634 // due to a bug in gtk, x,y are always 0
638 /* avoid recursions */
639 if (m_resizing
) return;
642 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
643 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
648 /* space occupied by m_frameToolBar and m_frameMenuBar */
649 int client_area_y_offset
= 0;
651 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
652 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
653 set in wxFrame::Create so it is used to check what kind of frame we
654 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
655 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
656 importantly) m_mainWidget */
660 /* check if size is in legal range */
661 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
662 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
663 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
664 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
666 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
667 * menubar, the toolbar and the client area, which is represented by
669 * this hurts in the eye, but I don't want to call SetSize()
670 * because I don't want to call any non-native functions here. */
675 int yy
= m_miniEdge
+ m_miniTitle
;
676 int ww
= m_width
- 2*m_miniEdge
;
677 int hh
= wxMENU_HEIGHT
;
678 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
679 m_frameMenuBar
->m_x
= xx
;
680 m_frameMenuBar
->m_y
= yy
;
681 m_frameMenuBar
->m_width
= ww
;
682 m_frameMenuBar
->m_height
= hh
;
683 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
684 m_frameMenuBar
->m_widget
,
686 client_area_y_offset
+= hh
;
693 int yy
= m_miniEdge
+ m_miniTitle
;
696 if (!m_menuBarDetached
)
699 yy
+= wxPLACE_HOLDER
;
701 int ww
= m_width
- 2*m_miniEdge
;
702 int hh
= m_frameToolBar
->m_height
;
703 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
704 m_frameToolBar
->m_x
= xx
;
705 m_frameToolBar
->m_y
= yy
;
706 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
707 m_frameToolBar
->m_width
= ww
;
708 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
709 m_frameToolBar
->m_widget
,
711 client_area_y_offset
+= hh
;
715 int client_x
= m_miniEdge
;
716 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
717 int client_w
= m_width
- 2*m_miniEdge
;
718 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
719 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
721 client_x
, client_y
, client_w
, client_h
);
725 /* if there is no m_mainWidget between m_widget and m_wxwindow there
726 is no need to set the size or position of m_wxwindow. */
730 if (m_frameStatusBar
)
732 int xx
= 0 + m_miniEdge
;
733 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
734 int ww
= m_width
- 2*m_miniEdge
;
735 int hh
= wxSTATUS_HEIGHT
;
736 m_frameStatusBar
->m_x
= xx
;
737 m_frameStatusBar
->m_y
= yy
;
738 m_frameStatusBar
->m_width
= ww
;
739 m_frameStatusBar
->m_height
= hh
;
740 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
741 m_frameStatusBar
->m_widget
,
746 /* we actually set the size of a frame here and no-where else */
747 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
751 /* send size event to frame */
752 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
753 event
.SetEventObject( this );
754 GetEventHandler()->ProcessEvent( event
);
756 /* send size event to status bar */
757 if (m_frameStatusBar
)
759 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
760 event2
.SetEventObject( m_frameStatusBar
);
761 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
767 void wxFrame::MakeModal( bool modal
)
770 gtk_grab_add( m_widget
);
772 gtk_grab_remove( m_widget
);
775 void wxFrame::OnInternalIdle()
777 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
778 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
782 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
784 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
787 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
791 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
796 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
798 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
800 #if wxUSE_CONSTRAINTS
806 #endif // wxUSE_CONSTRAINTS
808 /* do we have exactly one child? */
809 wxWindow
*child
= (wxWindow
*)NULL
;
810 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
812 wxWindow
*win
= (wxWindow
*)node
->Data();
813 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
817 /* it's the second one: do nothing */
825 /* no children at all? */
828 /* yes: set it's size to fill all the frame */
829 int client_x
, client_y
;
830 DoGetClientSize( &client_x
, &client_y
);
831 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
836 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
838 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
839 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
841 m_frameMenuBar
= menuBar
;
845 m_frameMenuBar
->SetInvokingWindow( this );
847 if (m_frameMenuBar
->GetParent() != this)
849 m_frameMenuBar
->SetParent(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
->GetWindowStyle() & 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 );
866 m_frameMenuBar
->Show( TRUE
);
870 /* resize window in OnInternalIdle */
874 wxMenuBar
*wxFrame::GetMenuBar() const
876 return m_frameMenuBar
;
879 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
884 // if no help string found, we will clear the status bar text
887 int menuId
= event
.GetMenuId();
890 wxMenuBar
*menuBar
= GetMenuBar();
893 helpString
= menuBar
->GetHelpString(menuId
);
897 SetStatusText(helpString
);
899 #endif // wxUSE_STATUSBAR
903 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
905 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
907 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
909 m_insertInClientArea
= FALSE
;
911 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
913 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
915 m_insertInClientArea
= TRUE
;
919 return m_frameToolBar
;
922 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
924 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
927 wxToolBar
*wxFrame::GetToolBar() const
929 return m_frameToolBar
;
931 #endif // wxUSE_TOOLBAR
934 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
936 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
938 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
940 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
944 return m_frameStatusBar
;
947 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
949 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
951 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
953 // Set the height according to the font and the border size
954 wxClientDC
dc(statusBar
);
955 dc
.SetFont( statusBar
->GetFont() );
958 dc
.GetTextExtent( "X", &x
, &y
);
960 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
962 statusBar
->SetSize( -1, -1, 100, height
);
964 statusBar
->SetFieldsCount( number
);
968 wxStatusBar
*wxFrame::GetStatusBar() const
970 return m_frameStatusBar
;
973 void wxFrame::SetStatusText(const wxString
& text
, int number
)
975 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
977 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
979 m_frameStatusBar
->SetStatusText(text
, number
);
982 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
984 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
986 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
988 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
990 #endif // wxUSE_STATUSBAR
992 void wxFrame::Command( int id
)
994 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
995 commandEvent
.SetInt( id
);
996 commandEvent
.SetEventObject( this );
998 wxMenuBar
*bar
= GetMenuBar();
1001 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1002 if (item
&& item
->IsCheckable())
1004 bar
->Check(id
,!bar
->Checked(id
)) ;
1007 wxEvtHandler
* evtHandler
= GetEventHandler();
1009 evtHandler
->ProcessEvent(commandEvent
);
1012 void wxFrame::SetTitle( const wxString
&title
)
1014 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1017 if (m_title
.IsNull()) m_title
= _T("");
1018 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1021 void wxFrame::SetIcon( const wxIcon
&icon
)
1023 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1026 if (!icon
.Ok()) return;
1028 if (!m_widget
->window
) return;
1030 wxMask
*mask
= icon
.GetMask();
1031 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1032 if (mask
) bm
= mask
->GetBitmap();
1034 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);