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 /* we set the size here and in gtk_frame_map_callback */
514 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
518 if ((m_width
!= old_width
) || (m_height
!= old_height
))
520 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
521 done either directly before the frame is shown or in idle time
522 so that different calls to SetSize() don't lead to flicker. */
529 void wxFrame::Centre( int direction
)
531 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
536 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
537 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
542 void wxFrame::DoGetClientSize( int *width
, int *height
) const
544 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
546 wxWindow::DoGetClientSize( width
, height
);
552 if (!m_menuBarDetached
)
553 (*height
) -= wxMENU_HEIGHT
;
555 (*height
) -= wxPLACE_HOLDER
;
559 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
564 if (!m_toolBarDetached
)
567 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
571 (*height
) -= wxPLACE_HOLDER
;
575 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
579 (*width
) -= m_miniEdge
*2;
583 void wxFrame::DoSetClientSize( int width
, int height
)
585 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
590 if (!m_menuBarDetached
)
591 height
+= wxMENU_HEIGHT
;
593 height
+= wxPLACE_HOLDER
;
597 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
602 if (!m_toolBarDetached
)
605 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
609 height
+= wxPLACE_HOLDER
;
612 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
615 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
617 // due to a bug in gtk, x,y are always 0
621 /* avoid recursions */
622 if (m_resizing
) return;
625 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
626 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
631 /* space occupied by m_frameToolBar and m_frameMenuBar */
632 int client_area_y_offset
= 0;
634 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
635 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
636 set in wxFrame::Create so it is used to check what kind of frame we
637 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
638 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
639 importantly) m_mainWidget */
643 /* check if size is in legal range */
644 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
645 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
646 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
647 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
649 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
650 * menubar, the toolbar and the client area, which is represented by
652 * this hurts in the eye, but I don't want to call SetSize()
653 * because I don't want to call any non-native functions here. */
658 int yy
= m_miniEdge
+ m_miniTitle
;
659 int ww
= m_width
- 2*m_miniEdge
;
660 int hh
= wxMENU_HEIGHT
;
661 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
662 m_frameMenuBar
->m_x
= xx
;
663 m_frameMenuBar
->m_y
= yy
;
664 m_frameMenuBar
->m_width
= ww
;
665 m_frameMenuBar
->m_height
= hh
;
666 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
667 m_frameMenuBar
->m_widget
,
669 client_area_y_offset
+= hh
;
675 int yy
= m_miniEdge
+ m_miniTitle
;
678 if (!m_menuBarDetached
)
681 yy
+= wxPLACE_HOLDER
;
683 int ww
= m_width
- 2*m_miniEdge
;
684 int hh
= m_frameToolBar
->m_height
;
685 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
686 m_frameToolBar
->m_x
= xx
;
687 m_frameToolBar
->m_y
= yy
;
688 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
689 m_frameToolBar
->m_width
= ww
;
690 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
691 m_frameToolBar
->m_widget
,
693 client_area_y_offset
+= hh
;
696 int client_x
= m_miniEdge
;
697 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
698 int client_w
= m_width
- 2*m_miniEdge
;
699 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
700 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
702 client_x
, client_y
, client_w
, client_h
);
706 /* if there is no m_mainWidget between m_widget and m_wxwindow there
707 is no need to set the size or position of m_wxwindow. */
710 if (m_frameStatusBar
)
712 int xx
= 0 + m_miniEdge
;
713 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
714 int ww
= m_width
- 2*m_miniEdge
;
715 int hh
= wxSTATUS_HEIGHT
;
716 m_frameStatusBar
->m_x
= xx
;
717 m_frameStatusBar
->m_y
= yy
;
718 m_frameStatusBar
->m_width
= ww
;
719 m_frameStatusBar
->m_height
= hh
;
720 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
721 m_frameStatusBar
->m_widget
,
725 /* we actually set the size of a frame here and no-where else */
726 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
730 /* send size event to frame */
731 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
732 event
.SetEventObject( this );
733 GetEventHandler()->ProcessEvent( event
);
735 /* send size event to status bar */
736 if (m_frameStatusBar
)
738 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
739 event2
.SetEventObject( m_frameStatusBar
);
740 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
746 void wxFrame::OnInternalIdle()
748 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
749 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
753 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
754 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
755 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
758 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
763 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
765 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
773 /* do we have exactly one child? */
774 wxWindow
*child
= (wxWindow
*)NULL
;
775 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
777 wxWindow
*win
= (wxWindow
*)node
->Data();
778 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
782 /* it's the second one: do nothing */
790 /* no children at all? */
793 /* yes: set it's size to fill all the frame */
794 int client_x
, client_y
;
795 DoGetClientSize( &client_x
, &client_y
);
796 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
801 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
803 menu
->SetInvokingWindow( win
);
805 #if (GTK_MINOR_VERSION > 0)
806 /* support for native hot keys */
807 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
810 wxNode
*node
= menu
->GetItems().First();
813 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
814 if (menuitem
->IsSubMenu())
815 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
820 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
822 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
823 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
825 m_frameMenuBar
= menuBar
;
829 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
830 /* support for native key accelerators indicated by underscroes */
831 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
834 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
837 wxMenu
*menu
= (wxMenu
*)node
->Data();
838 SetInvokingWindow( menu
, this );
842 if (m_frameMenuBar
->GetParent() != this)
844 m_frameMenuBar
->SetParent(this);
845 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
846 m_frameMenuBar
->m_widget
,
849 m_frameMenuBar
->m_width
,
850 m_frameMenuBar
->m_height
);
852 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
854 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
855 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
857 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
858 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
863 /* resize window in OnInternalIdle */
867 wxMenuBar
*wxFrame::GetMenuBar() const
869 return m_frameMenuBar
;
872 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
876 // if no help string found, we will clear the status bar text
879 int menuId
= event
.GetMenuId();
882 wxMenuBar
*menuBar
= GetMenuBar();
885 helpString
= menuBar
->GetHelpString(menuId
);
889 SetStatusText(helpString
);
893 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
895 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
897 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
899 m_insertInClientArea
= FALSE
;
901 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
903 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
905 m_insertInClientArea
= TRUE
;
909 return m_frameToolBar
;
912 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
914 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
917 wxToolBar
*wxFrame::GetToolBar() const
919 return m_frameToolBar
;
922 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
924 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
926 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
928 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
932 return m_frameStatusBar
;
935 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
937 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
939 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
941 // Set the height according to the font and the border size
942 wxClientDC
dc(statusBar
);
943 dc
.SetFont( statusBar
->GetFont() );
946 dc
.GetTextExtent( "X", &x
, &y
);
948 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
950 statusBar
->SetSize( -1, -1, 100, height
);
952 statusBar
->SetFieldsCount( number
);
956 void wxFrame::Command( int id
)
958 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
959 commandEvent
.SetInt( id
);
960 commandEvent
.SetEventObject( this );
962 wxMenuBar
*bar
= GetMenuBar();
965 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
966 if (item
&& item
->IsCheckable())
968 bar
->Check(id
,!bar
->Checked(id
)) ;
971 wxEvtHandler
* evtHandler
= GetEventHandler();
973 evtHandler
->ProcessEvent(commandEvent
);
976 void wxFrame::SetStatusText(const wxString
& text
, int number
)
978 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
980 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
982 m_frameStatusBar
->SetStatusText(text
, number
);
985 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
987 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
989 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
991 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
994 wxStatusBar
*wxFrame::GetStatusBar() const
996 return m_frameStatusBar
;
999 void wxFrame::SetTitle( const wxString
&title
)
1001 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1004 if (m_title
.IsNull()) m_title
= _T("");
1005 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1008 void wxFrame::SetIcon( const wxIcon
&icon
)
1010 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1013 if (!icon
.Ok()) return;
1015 if (!m_widget
->window
) return;
1017 wxMask
*mask
= icon
.GetMask();
1018 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1019 if (mask
) bm
= mask
->GetBitmap();
1021 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);