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 //-----------------------------------------------------------------------------
156 #if (GTK_MINOR_VERSON > 0)
157 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
159 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
163 wxapp_install_idle_handler();
165 if (!win
->m_hasVMT
) return FALSE
;
167 #if (GTK_MINOR_VERSON > 0)
170 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
178 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
179 mevent
.SetEventObject( win
);
180 win
->GetEventHandler()->ProcessEvent( mevent
);
185 //-----------------------------------------------------------------------------
186 // "realize" from m_widget
187 //-----------------------------------------------------------------------------
189 /* we cannot MWM hints and icons before the widget has been realized,
190 so we do this directly after realization */
193 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
196 wxapp_install_idle_handler();
198 /* all this is for Motif Window Manager "hints" and is supposed to be
199 recognized by other WM as well. not tested. */
200 long decor
= (long) GDK_DECOR_BORDER
;
201 long func
= (long) GDK_FUNC_MOVE
;
203 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
204 decor
|= GDK_DECOR_TITLE
;
205 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
207 decor
|= GDK_DECOR_MENU
;
208 func
|= GDK_FUNC_CLOSE
;
210 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
212 func
|= GDK_FUNC_MINIMIZE
;
213 decor
|= GDK_DECOR_MINIMIZE
;
215 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
217 func
|= GDK_FUNC_MAXIMIZE
;
218 decor
|= GDK_DECOR_MAXIMIZE
;
220 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
222 func
|= GDK_FUNC_RESIZE
;
223 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 if (!parent
->m_insertInClientArea
)
275 /* these are outside the client area */
276 wxFrame
* frame
= (wxFrame
*) parent
;
277 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
278 GTK_WIDGET(child
->m_widget
),
285 /* we connect to these events for recalculating the client area
286 space when the toolbar is floating */
287 if (wxIS_KIND_OF(child
,wxToolBar
))
289 wxToolBar
*toolBar
= (wxToolBar
*) child
;
290 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
292 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
293 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
295 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
296 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
299 #endif // wxUSE_TOOLBAR
303 /* these are inside the client area */
304 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
305 GTK_WIDGET(child
->m_widget
),
312 /* resize on OnInternalIdle */
313 parent
->UpdateSize();
316 //-----------------------------------------------------------------------------
318 //-----------------------------------------------------------------------------
320 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
321 EVT_SIZE(wxFrame::OnSize
)
322 EVT_CLOSE(wxFrame::OnCloseWindow
)
323 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
326 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
330 m_frameMenuBar
= (wxMenuBar
*) NULL
;
332 m_frameStatusBar
= (wxStatusBar
*) NULL
;
333 #endif // wxUSE_STATUSBAR
335 m_frameToolBar
= (wxToolBar
*) NULL
;
336 #endif // wxUSE_TOOLBAR
340 m_mainWidget
= (GtkWidget
*) NULL
;
341 m_menuBarDetached
= FALSE
;
342 m_toolBarDetached
= FALSE
;
343 m_insertInClientArea
= TRUE
;
346 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
347 const wxPoint
&pos
, const wxSize
&size
,
348 long style
, const wxString
&name
)
352 Create( parent
, id
, title
, pos
, size
, style
, name
);
355 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
356 const wxPoint
&pos
, const wxSize
&size
,
357 long style
, const wxString
&name
)
359 wxTopLevelWindows
.Append( this );
361 m_needParent
= FALSE
;
363 PreCreation( parent
, id
, pos
, size
, style
, name
);
367 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
369 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
370 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
372 m_widget
= gtk_window_new( win_type
);
375 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
378 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
381 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
382 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
384 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
385 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
387 /* m_mainWidget holds the toolbar, the menubar and the client area */
388 m_mainWidget
= gtk_myfixed_new();
389 gtk_widget_show( m_mainWidget
);
390 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
391 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
394 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
397 /* m_wxwindow only represents the client area without toolbar and menubar */
398 m_wxwindow
= gtk_myfixed_new();
399 gtk_widget_show( m_wxwindow
);
400 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
403 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
406 /* we donm't allow the frame to get the focus as otherwise
407 the frame will grabit at arbitrary fcous changes. */
408 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
410 if (m_parent
) m_parent
->AddChild( this );
414 /* we cannot set MWM hints and icons before the widget has
415 been realized, so we do this directly after realization */
416 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
417 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
419 /* the user resized the frame by dragging etc. */
420 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
421 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
423 /* the only way to get the window size is to connect to this event */
424 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
425 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
432 m_isBeingDeleted
= TRUE
;
434 if (m_frameMenuBar
) delete m_frameMenuBar
;
435 m_frameMenuBar
= (wxMenuBar
*) NULL
;
438 if (m_frameStatusBar
) delete m_frameStatusBar
;
439 m_frameStatusBar
= (wxStatusBar
*) NULL
;
440 #endif // wxUSE_STATUSBAR
443 if (m_frameToolBar
) delete m_frameToolBar
;
444 m_frameToolBar
= (wxToolBar
*) NULL
;
445 #endif // wxUSE_TOOLBAR
447 wxTopLevelWindows
.DeleteObject( this );
449 if (wxTheApp
->GetTopWindow() == this)
450 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
452 if (wxTopLevelWindows
.Number() == 0)
453 wxTheApp
->ExitMainLoop();
456 bool wxFrame::Show( bool show
)
458 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
460 if (show
&& !m_sizeSet
)
462 /* by calling GtkOnSize here, we don't have to call
463 either after showing the frame, which would entail
464 much ugly flicker or from within the size_allocate
465 handler, because GTK 1.1.X forbids that. */
467 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
470 return wxWindow::Show( show
);
473 bool wxFrame::Destroy()
475 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
477 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
482 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
484 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
486 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
487 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
489 /* avoid recursions */
490 if (m_resizing
) return;
495 int old_width
= m_width
;
496 int old_height
= m_height
;
498 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
500 if (x
!= -1) m_x
= x
;
501 if (y
!= -1) m_y
= y
;
502 if (width
!= -1) m_width
= width
;
503 if (height
!= -1) m_height
= height
;
513 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
515 if (width
== -1) m_width
= 80;
518 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
520 if (height
== -1) m_height
= 26;
523 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
524 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
525 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
526 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
528 if ((m_x
!= -1) || (m_y
!= -1))
530 if ((m_x
!= old_x
) || (m_y
!= old_y
))
532 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
536 if ((m_width
!= old_width
) || (m_height
!= old_height
))
538 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
539 done either directly before the frame is shown or in idle time
540 so that different calls to SetSize() don't lead to flicker. */
547 void wxFrame::Centre( int direction
)
549 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
554 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
555 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
560 void wxFrame::DoGetClientSize( int *width
, int *height
) const
562 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
564 wxWindow::DoGetClientSize( width
, height
);
570 if (!m_menuBarDetached
)
571 (*height
) -= wxMENU_HEIGHT
;
573 (*height
) -= wxPLACE_HOLDER
;
578 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
585 if (!m_toolBarDetached
)
588 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
592 (*height
) -= wxPLACE_HOLDER
;
597 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
601 (*width
) -= m_miniEdge
*2;
605 void wxFrame::DoSetClientSize( int width
, int height
)
607 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
612 if (!m_menuBarDetached
)
613 height
+= wxMENU_HEIGHT
;
615 height
+= wxPLACE_HOLDER
;
620 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
627 if (!m_toolBarDetached
)
630 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
634 height
+= wxPLACE_HOLDER
;
638 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
641 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
643 // due to a bug in gtk, x,y are always 0
647 /* avoid recursions */
648 if (m_resizing
) return;
651 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
652 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
657 /* space occupied by m_frameToolBar and m_frameMenuBar */
658 int client_area_y_offset
= 0;
660 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
661 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
662 set in wxFrame::Create so it is used to check what kind of frame we
663 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
664 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
665 importantly) m_mainWidget */
669 /* check if size is in legal range */
670 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
671 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
672 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
673 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
675 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
676 * menubar, the toolbar and the client area, which is represented by
678 * this hurts in the eye, but I don't want to call SetSize()
679 * because I don't want to call any non-native functions here. */
684 int yy
= m_miniEdge
+ m_miniTitle
;
685 int ww
= m_width
- 2*m_miniEdge
;
686 int hh
= wxMENU_HEIGHT
;
687 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
688 m_frameMenuBar
->m_x
= xx
;
689 m_frameMenuBar
->m_y
= yy
;
690 m_frameMenuBar
->m_width
= ww
;
691 m_frameMenuBar
->m_height
= hh
;
692 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
693 m_frameMenuBar
->m_widget
,
695 client_area_y_offset
+= hh
;
702 int yy
= m_miniEdge
+ m_miniTitle
;
705 if (!m_menuBarDetached
)
708 yy
+= wxPLACE_HOLDER
;
710 int ww
= m_width
- 2*m_miniEdge
;
711 int hh
= m_frameToolBar
->m_height
;
712 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
713 m_frameToolBar
->m_x
= xx
;
714 m_frameToolBar
->m_y
= yy
;
715 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
716 m_frameToolBar
->m_width
= ww
;
717 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
718 m_frameToolBar
->m_widget
,
720 client_area_y_offset
+= hh
;
724 int client_x
= m_miniEdge
;
725 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
726 int client_w
= m_width
- 2*m_miniEdge
;
727 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
728 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
730 client_x
, client_y
, client_w
, client_h
);
734 /* if there is no m_mainWidget between m_widget and m_wxwindow there
735 is no need to set the size or position of m_wxwindow. */
739 if (m_frameStatusBar
)
741 int xx
= 0 + m_miniEdge
;
742 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
743 int ww
= m_width
- 2*m_miniEdge
;
744 int hh
= wxSTATUS_HEIGHT
;
745 m_frameStatusBar
->m_x
= xx
;
746 m_frameStatusBar
->m_y
= yy
;
747 m_frameStatusBar
->m_width
= ww
;
748 m_frameStatusBar
->m_height
= hh
;
749 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
750 m_frameStatusBar
->m_widget
,
755 /* we actually set the size of a frame here and no-where else */
756 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
760 /* send size event to frame */
761 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
762 event
.SetEventObject( this );
763 GetEventHandler()->ProcessEvent( event
);
765 /* send size event to status bar */
766 if (m_frameStatusBar
)
768 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
769 event2
.SetEventObject( m_frameStatusBar
);
770 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
776 void wxFrame::MakeModal( bool modal
)
779 gtk_grab_add( m_widget
);
781 gtk_grab_remove( m_widget
);
784 void wxFrame::OnInternalIdle()
786 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
787 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
791 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
793 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
796 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
800 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
805 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
807 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
809 #if wxUSE_CONSTRAINTS
815 #endif // wxUSE_CONSTRAINTS
817 /* do we have exactly one child? */
818 wxWindow
*child
= (wxWindow
*)NULL
;
819 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
821 wxWindow
*win
= (wxWindow
*)node
->Data();
822 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
826 /* it's the second one: do nothing */
834 /* no children at all? */
837 /* yes: set it's size to fill all the frame */
838 int client_x
, client_y
;
839 DoGetClientSize( &client_x
, &client_y
);
840 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
845 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
847 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
848 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
850 m_frameMenuBar
= menuBar
;
854 m_frameMenuBar
->SetInvokingWindow( this );
856 if (m_frameMenuBar
->GetParent() != this)
858 m_frameMenuBar
->SetParent(this);
859 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
860 m_frameMenuBar
->m_widget
,
863 m_frameMenuBar
->m_width
,
864 m_frameMenuBar
->m_height
);
866 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
868 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
869 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
871 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
872 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
875 m_frameMenuBar
->Show( TRUE
);
879 /* resize window in OnInternalIdle */
883 wxMenuBar
*wxFrame::GetMenuBar() const
885 return m_frameMenuBar
;
888 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
893 // if no help string found, we will clear the status bar text
896 int menuId
= event
.GetMenuId();
899 wxMenuBar
*menuBar
= GetMenuBar();
902 helpString
= menuBar
->GetHelpString(menuId
);
906 SetStatusText(helpString
);
908 #endif // wxUSE_STATUSBAR
912 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
914 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
916 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
918 m_insertInClientArea
= FALSE
;
920 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
922 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
924 m_insertInClientArea
= TRUE
;
928 return m_frameToolBar
;
931 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
933 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
936 wxToolBar
*wxFrame::GetToolBar() const
938 return m_frameToolBar
;
940 #endif // wxUSE_TOOLBAR
943 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
945 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
947 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
949 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
953 return m_frameStatusBar
;
956 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
958 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
960 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
962 // Set the height according to the font and the border size
963 wxClientDC
dc(statusBar
);
964 dc
.SetFont( statusBar
->GetFont() );
967 dc
.GetTextExtent( "X", &x
, &y
);
969 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
971 statusBar
->SetSize( -1, -1, 100, height
);
973 statusBar
->SetFieldsCount( number
);
977 wxStatusBar
*wxFrame::GetStatusBar() const
979 return m_frameStatusBar
;
982 void wxFrame::SetStatusText(const wxString
& text
, int number
)
984 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
986 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
988 m_frameStatusBar
->SetStatusText(text
, number
);
991 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
993 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
995 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
997 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
999 #endif // wxUSE_STATUSBAR
1001 void wxFrame::Command( int id
)
1003 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1004 commandEvent
.SetInt( id
);
1005 commandEvent
.SetEventObject( this );
1007 wxMenuBar
*bar
= GetMenuBar();
1010 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1011 if (item
&& item
->IsCheckable())
1013 bar
->Check(id
,!bar
->Checked(id
)) ;
1016 wxEvtHandler
* evtHandler
= GetEventHandler();
1018 evtHandler
->ProcessEvent(commandEvent
);
1021 void wxFrame::SetTitle( const wxString
&title
)
1023 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1026 if (m_title
.IsNull()) m_title
= _T("");
1027 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1030 void wxFrame::SetIcon( const wxIcon
&icon
)
1032 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1035 if (!icon
.Ok()) return;
1037 if (!m_widget
->window
) return;
1039 wxMask
*mask
= icon
.GetMask();
1040 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1041 if (mask
) bm
= mask
->GetBitmap();
1043 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);