1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "frame.h"
15 #include "wx/dialog.h"
16 #include "wx/control.h"
19 #include "wx/toolbar.h"
20 #include "wx/statusbr.h"
21 #include "wx/dcclient.h"
26 #include "wx/gtk/win_gtk.h"
27 #include "gdk/gdkkeysyms.h"
29 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
33 const int wxMENU_HEIGHT
= 27;
34 const int wxSTATUS_HEIGHT
= 25;
35 const int wxPLACE_HOLDER
= 0;
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 extern void wxapp_install_idle_handler();
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
48 extern wxList wxPendingDelete
;
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
56 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
60 //-----------------------------------------------------------------------------
62 //-----------------------------------------------------------------------------
64 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
67 wxapp_install_idle_handler();
69 if (!win
->m_hasVMT
) return;
71 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
73 win
->m_width
= alloc
->width
;
74 win
->m_height
= alloc
->height
;
79 //-----------------------------------------------------------------------------
81 //-----------------------------------------------------------------------------
83 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
86 wxapp_install_idle_handler();
93 //-----------------------------------------------------------------------------
94 // "child_attached" of menu bar
95 //-----------------------------------------------------------------------------
97 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
99 if (!win
->m_hasVMT
) return;
101 win
->m_menuBarDetached
= FALSE
;
105 //-----------------------------------------------------------------------------
106 // "child_detached" of menu bar
107 //-----------------------------------------------------------------------------
109 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
111 if (!win
->m_hasVMT
) return;
113 win
->m_menuBarDetached
= TRUE
;
117 //-----------------------------------------------------------------------------
118 // "child_attached" of tool bar
119 //-----------------------------------------------------------------------------
121 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
123 if (!win
->m_hasVMT
) return;
125 win
->m_toolBarDetached
= FALSE
;
130 //-----------------------------------------------------------------------------
131 // "child_detached" of tool bar
132 //-----------------------------------------------------------------------------
134 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
137 wxapp_install_idle_handler();
139 if (!win
->m_hasVMT
) return;
141 win
->m_toolBarDetached
= TRUE
;
145 //-----------------------------------------------------------------------------
147 //-----------------------------------------------------------------------------
149 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
152 wxapp_install_idle_handler();
154 if (!win
->m_hasVMT
) return FALSE
;
159 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
160 mevent
.SetEventObject( win
);
161 win
->GetEventHandler()->ProcessEvent( mevent
);
166 //-----------------------------------------------------------------------------
167 // "realize" from m_widget
168 //-----------------------------------------------------------------------------
170 /* we cannot MWM hints and icons before the widget has been realized,
171 so we do this directly after realization */
174 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
177 wxapp_install_idle_handler();
179 /* all this is for Motif Window Manager "hints" and is supposed to be
180 recognized by other WM as well. not tested. */
181 long decor
= (long) GDK_DECOR_BORDER
;
182 long func
= (long) GDK_FUNC_MOVE
;
184 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
185 decor
|= GDK_DECOR_TITLE
;
186 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
188 decor
|= GDK_DECOR_MENU
;
189 func
|= GDK_FUNC_CLOSE
;
191 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
193 func
|= GDK_FUNC_MINIMIZE
;
194 decor
|= GDK_DECOR_MINIMIZE
;
196 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
198 func
|= GDK_FUNC_MAXIMIZE
;
199 decor
|= GDK_DECOR_MAXIMIZE
;
201 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
203 func
|= GDK_FUNC_RESIZE
;
204 decor
|= GDK_DECOR_RESIZEH
;
208 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
209 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
211 /* GTK's shrinking/growing policy */
212 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
213 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
215 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
218 if (win
->m_icon
!= wxNullIcon
)
220 wxIcon
icon( win
->m_icon
);
221 win
->m_icon
= wxNullIcon
;
222 win
->SetIcon( icon
);
225 /* we set the focus to the child that accepts the focus. this
226 doesn't really have to be done in "realize" but why not? */
227 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
230 wxWindow
*child
= node
->GetData();
231 if (child
->AcceptsFocus())
237 node
= node
->GetNext();
243 //-----------------------------------------------------------------------------
244 // InsertChild for wxFrame
245 //-----------------------------------------------------------------------------
247 /* Callback for wxFrame. This very strange beast has to be used because
248 * C++ has no virtual methods in a constructor. We have to emulate a
249 * virtual function here as wxWindows requires different ways to insert
250 * a child in container classes. */
252 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
254 if (!parent
->m_insertInClientArea
)
256 /* these are outside the client area */
257 wxFrame
* frame
= (wxFrame
*) parent
;
258 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
259 GTK_WIDGET(child
->m_widget
),
265 /* we connect to these events for recalculating the client area
266 space when the toolbar is floating */
267 if (wxIS_KIND_OF(child
,wxToolBar
))
269 wxToolBar
*toolBar
= (wxToolBar
*) child
;
270 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
272 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
273 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
275 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
276 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
282 /* these are inside the client area */
283 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
284 GTK_WIDGET(child
->m_widget
),
291 /* resize on OnInternalIdle */
292 parent
->UpdateSize();
295 //-----------------------------------------------------------------------------
297 //-----------------------------------------------------------------------------
299 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
300 EVT_SIZE(wxFrame::OnSize
)
301 EVT_CLOSE(wxFrame::OnCloseWindow
)
302 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
305 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
309 m_frameMenuBar
= (wxMenuBar
*) NULL
;
310 m_frameStatusBar
= (wxStatusBar
*) NULL
;
311 m_frameToolBar
= (wxToolBar
*) NULL
;
315 m_mainWidget
= (GtkWidget
*) NULL
;
316 m_menuBarDetached
= FALSE
;
317 m_toolBarDetached
= FALSE
;
318 m_insertCallback
= (wxInsertChildFunction
) NULL
;
319 m_insertInClientArea
= TRUE
;
322 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
323 const wxPoint
&pos
, const wxSize
&size
,
324 long style
, const wxString
&name
)
326 m_frameMenuBar
= (wxMenuBar
*) NULL
;
327 m_frameStatusBar
= (wxStatusBar
*) NULL
;
328 m_frameToolBar
= (wxToolBar
*) NULL
;
332 m_mainWidget
= (GtkWidget
*) NULL
;
333 m_menuBarDetached
= FALSE
;
334 m_toolBarDetached
= FALSE
;
335 m_insertCallback
= (wxInsertChildFunction
) NULL
;
336 m_insertInClientArea
= TRUE
;
337 Create( parent
, id
, title
, pos
, size
, style
, name
);
340 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
341 const wxPoint
&pos
, const wxSize
&size
,
342 long style
, const wxString
&name
)
344 wxTopLevelWindows
.Append( this );
346 m_needParent
= FALSE
;
348 PreCreation( parent
, id
, pos
, size
, style
, name
);
352 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
354 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
355 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
357 m_widget
= gtk_window_new( win_type
);
360 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
363 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
366 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
367 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
369 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
370 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
372 /* m_mainWidget holds the toolbar, the menubar and the client area */
373 m_mainWidget
= gtk_myfixed_new();
374 gtk_widget_show( m_mainWidget
);
375 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
376 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
379 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
382 /* m_wxwindow only represents the client area without toolbar and menubar */
383 m_wxwindow
= gtk_myfixed_new();
384 gtk_widget_show( m_wxwindow
);
385 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
388 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
391 /* we donm't allow the frame to get the focus as otherwise
392 the frame will grabit at arbitrary fcous changes. */
393 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
395 if (m_parent
) m_parent
->AddChild( this );
399 /* we cannot set MWM hints and icons before the widget has
400 been realized, so we do this directly after realization */
401 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
402 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
404 /* the user resized the frame by dragging etc. */
405 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
406 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
408 /* the only way to get the window size is to connect to this event */
409 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
410 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
417 m_isBeingDeleted
= TRUE
;
419 if (m_frameMenuBar
) delete m_frameMenuBar
;
420 m_frameMenuBar
= (wxMenuBar
*) NULL
;
422 if (m_frameStatusBar
) delete m_frameStatusBar
;
423 m_frameStatusBar
= (wxStatusBar
*) NULL
;
425 if (m_frameToolBar
) delete m_frameToolBar
;
426 m_frameToolBar
= (wxToolBar
*) NULL
;
428 wxTopLevelWindows
.DeleteObject( this );
430 if (wxTheApp
->GetTopWindow() == this)
431 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
433 if (wxTopLevelWindows
.Number() == 0)
434 wxTheApp
->ExitMainLoop();
437 bool wxFrame::Show( bool show
)
439 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
441 if (show
&& !m_sizeSet
)
443 /* by calling GtkOnSize here, we don't have to call
444 either after showing the frame, which would entail
445 much ugly flicker or from within the size_allocate
446 handler, because GTK 1.1.X forbids that. */
448 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
451 return wxWindow::Show( show
);
454 bool wxFrame::Destroy()
456 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
458 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
463 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
465 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
467 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
468 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
470 /* avoid recursions */
471 if (m_resizing
) return;
476 int old_width
= m_width
;
477 int old_height
= m_height
;
479 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
481 if (x
!= -1) m_x
= x
;
482 if (y
!= -1) m_y
= y
;
483 if (width
!= -1) m_width
= width
;
484 if (height
!= -1) m_height
= height
;
494 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
496 if (width
== -1) m_width
= 80;
499 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
501 if (height
== -1) m_height
= 26;
504 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
505 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
506 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
507 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
509 if ((m_x
!= -1) || (m_y
!= -1))
511 if ((m_x
!= old_x
) || (m_y
!= old_y
))
513 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
517 if ((m_width
!= old_width
) || (m_height
!= old_height
))
519 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
520 done either directly before the frame is shown or in idle time
521 so that different calls to SetSize() don't lead to flicker. */
528 void wxFrame::Centre( int direction
)
530 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
535 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
536 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
541 void wxFrame::DoGetClientSize( int *width
, int *height
) const
543 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
545 wxWindow::DoGetClientSize( width
, height
);
551 if (!m_menuBarDetached
)
552 (*height
) -= wxMENU_HEIGHT
;
554 (*height
) -= wxPLACE_HOLDER
;
558 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
563 if (!m_toolBarDetached
)
566 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
570 (*height
) -= wxPLACE_HOLDER
;
574 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
578 (*width
) -= m_miniEdge
*2;
582 void wxFrame::DoSetClientSize( int width
, int height
)
584 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
589 if (!m_menuBarDetached
)
590 height
+= wxMENU_HEIGHT
;
592 height
+= wxPLACE_HOLDER
;
596 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
601 if (!m_toolBarDetached
)
604 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
608 height
+= wxPLACE_HOLDER
;
611 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
614 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
616 // due to a bug in gtk, x,y are always 0
620 /* avoid recursions */
621 if (m_resizing
) return;
624 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
625 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
630 /* space occupied by m_frameToolBar and m_frameMenuBar */
631 int client_area_y_offset
= 0;
633 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
634 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
635 set in wxFrame::Create so it is used to check what kind of frame we
636 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
637 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
638 importantly) m_mainWidget */
642 /* check if size is in legal range */
643 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
644 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
645 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
646 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
648 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
649 * menubar, the toolbar and the client area, which is represented by
651 * this hurts in the eye, but I don't want to call SetSize()
652 * because I don't want to call any non-native functions here. */
657 int yy
= m_miniEdge
+ m_miniTitle
;
658 int ww
= m_width
- 2*m_miniEdge
;
659 int hh
= wxMENU_HEIGHT
;
660 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
661 m_frameMenuBar
->m_x
= xx
;
662 m_frameMenuBar
->m_y
= yy
;
663 m_frameMenuBar
->m_width
= ww
;
664 m_frameMenuBar
->m_height
= hh
;
665 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
666 m_frameMenuBar
->m_widget
,
668 client_area_y_offset
+= hh
;
674 int yy
= m_miniEdge
+ m_miniTitle
;
677 if (!m_menuBarDetached
)
680 yy
+= wxPLACE_HOLDER
;
682 int ww
= m_width
- 2*m_miniEdge
;
683 int hh
= m_frameToolBar
->m_height
;
684 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
685 m_frameToolBar
->m_x
= xx
;
686 m_frameToolBar
->m_y
= yy
;
687 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
688 m_frameToolBar
->m_width
= ww
;
689 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
690 m_frameToolBar
->m_widget
,
692 client_area_y_offset
+= hh
;
695 int client_x
= m_miniEdge
;
696 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
697 int client_w
= m_width
- 2*m_miniEdge
;
698 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
699 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
701 client_x
, client_y
, client_w
, client_h
);
705 /* if there is no m_mainWidget between m_widget and m_wxwindow there
706 is no need to set the size or position of m_wxwindow. */
709 if (m_frameStatusBar
)
711 int xx
= 0 + m_miniEdge
;
712 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
713 int ww
= m_width
- 2*m_miniEdge
;
714 int hh
= wxSTATUS_HEIGHT
;
715 m_frameStatusBar
->m_x
= xx
;
716 m_frameStatusBar
->m_y
= yy
;
717 m_frameStatusBar
->m_width
= ww
;
718 m_frameStatusBar
->m_height
= hh
;
719 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
720 m_frameStatusBar
->m_widget
,
724 /* we actually set the size of a frame here and no-where else */
725 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
729 /* send size event to frame */
730 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
731 event
.SetEventObject( this );
732 GetEventHandler()->ProcessEvent( event
);
734 /* send size event to status bar */
735 if (m_frameStatusBar
)
737 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
738 event2
.SetEventObject( m_frameStatusBar
);
739 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
745 void wxFrame::MakeModal( bool modal
)
748 gtk_grab_add( m_widget
);
750 gtk_grab_remove( m_widget
);
753 void wxFrame::OnInternalIdle()
755 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
756 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
760 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
761 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
762 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
765 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
770 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
772 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
780 /* do we have exactly one child? */
781 wxWindow
*child
= (wxWindow
*)NULL
;
782 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
784 wxWindow
*win
= (wxWindow
*)node
->Data();
785 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
789 /* it's the second one: do nothing */
797 /* no children at all? */
800 /* yes: set it's size to fill all the frame */
801 int client_x
, client_y
;
802 DoGetClientSize( &client_x
, &client_y
);
803 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
808 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
810 menu
->SetInvokingWindow( win
);
812 #if (GTK_MINOR_VERSION > 0)
813 /* support for native hot keys */
814 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
817 wxNode
*node
= menu
->GetItems().First();
820 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
821 if (menuitem
->IsSubMenu())
822 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
827 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
829 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
830 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
832 m_frameMenuBar
= menuBar
;
836 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
837 /* support for native key accelerators indicated by underscroes */
838 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
841 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
844 wxMenu
*menu
= (wxMenu
*)node
->Data();
845 SetInvokingWindow( menu
, this );
849 if (m_frameMenuBar
->GetParent() != this)
851 m_frameMenuBar
->SetParent(this);
852 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
853 m_frameMenuBar
->m_widget
,
856 m_frameMenuBar
->m_width
,
857 m_frameMenuBar
->m_height
);
859 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
861 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
862 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
864 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
865 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
870 /* resize window in OnInternalIdle */
874 wxMenuBar
*wxFrame::GetMenuBar() const
876 return m_frameMenuBar
;
879 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
883 // if no help string found, we will clear the status bar text
886 int menuId
= event
.GetMenuId();
889 wxMenuBar
*menuBar
= GetMenuBar();
892 helpString
= menuBar
->GetHelpString(menuId
);
896 SetStatusText(helpString
);
900 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
902 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
904 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
906 m_insertInClientArea
= FALSE
;
908 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
910 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
912 m_insertInClientArea
= TRUE
;
916 return m_frameToolBar
;
919 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
921 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
924 wxToolBar
*wxFrame::GetToolBar() const
926 return m_frameToolBar
;
929 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
931 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
933 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
935 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
939 return m_frameStatusBar
;
942 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
944 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
946 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
948 // Set the height according to the font and the border size
949 wxClientDC
dc(statusBar
);
950 dc
.SetFont( statusBar
->GetFont() );
953 dc
.GetTextExtent( "X", &x
, &y
);
955 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
957 statusBar
->SetSize( -1, -1, 100, height
);
959 statusBar
->SetFieldsCount( number
);
963 void wxFrame::Command( int id
)
965 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
966 commandEvent
.SetInt( id
);
967 commandEvent
.SetEventObject( this );
969 wxMenuBar
*bar
= GetMenuBar();
972 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
973 if (item
&& item
->IsCheckable())
975 bar
->Check(id
,!bar
->Checked(id
)) ;
978 wxEvtHandler
* evtHandler
= GetEventHandler();
980 evtHandler
->ProcessEvent(commandEvent
);
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
);
1001 wxStatusBar
*wxFrame::GetStatusBar() const
1003 return m_frameStatusBar
;
1006 void wxFrame::SetTitle( const wxString
&title
)
1008 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1011 if (m_title
.IsNull()) m_title
= _T("");
1012 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1015 void wxFrame::SetIcon( const wxIcon
&icon
)
1017 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1020 if (!icon
.Ok()) return;
1022 if (!m_widget
->window
) return;
1024 wxMask
*mask
= icon
.GetMask();
1025 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1026 if (mask
) bm
= mask
->GetBitmap();
1028 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);