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"
28 //-----------------------------------------------------------------------------
30 //-----------------------------------------------------------------------------
32 const int wxMENU_HEIGHT
= 27;
33 const int wxSTATUS_HEIGHT
= 25;
34 const int wxPLACE_HOLDER
= 0;
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
40 extern wxList wxPendingDelete
;
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
48 if (!win
->HasVMT()) return;
51 printf( "OnFrameResize from " );
52 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
53 printf( win->GetClassInfo()->GetClassName() );
57 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
59 win
->m_sizeSet
= FALSE
;
60 win
->m_width
= alloc
->width
;
61 win
->m_height
= alloc
->height
;
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
72 printf( "OnDelete from " );
73 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
74 printf( win->GetClassInfo()->GetClassName() );
83 //-----------------------------------------------------------------------------
84 // "child_attached" of menu bar
85 //-----------------------------------------------------------------------------
87 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
89 if (!win
->HasVMT()) return;
91 win
->m_menuBarDetached
= FALSE
;
92 win
->m_sizeSet
= FALSE
;
95 //-----------------------------------------------------------------------------
96 // "child_detached" of menu bar
97 //-----------------------------------------------------------------------------
99 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
101 if (!win
->HasVMT()) return;
103 win
->m_menuBarDetached
= TRUE
;
104 win
->m_sizeSet
= FALSE
;
107 //-----------------------------------------------------------------------------
108 // "child_attached" of tool bar
109 //-----------------------------------------------------------------------------
111 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
113 if (!win
->HasVMT()) return;
115 win
->m_toolBarDetached
= FALSE
;
116 win
->m_sizeSet
= FALSE
;
119 //-----------------------------------------------------------------------------
120 // "child_detached" of tool bar
121 //-----------------------------------------------------------------------------
123 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
125 if (!win
->HasVMT()) return;
127 win
->m_toolBarDetached
= TRUE
;
128 win
->m_sizeSet
= FALSE
;
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
135 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
137 if (!win
->HasVMT()) return FALSE
;
142 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
143 mevent
.SetEventObject( win
);
144 win
->GetEventHandler()->ProcessEvent( mevent
);
149 //-----------------------------------------------------------------------------
150 // "realize" from m_widget
151 //-----------------------------------------------------------------------------
153 /* we cannot MWM hints and icons before the widget has been realized,
154 so we do this directly after realization */
157 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
159 /* all this is for Motif Window Manager "hints" and is supposed to be
160 recognized by other WM as well. not tested. */
161 long decor
= (long) GDK_DECOR_ALL
;
162 long func
= (long) GDK_FUNC_ALL
;
164 if ((win
->m_windowStyle
& wxCAPTION
) == 0)
165 decor
|= GDK_DECOR_TITLE
;
166 /* if ((win->m_windowStyle & wxMINIMIZE) == 0)
167 func |= GDK_FUNC_MINIMIZE;
168 if ((win->m_windowStyle & wxMAXIMIZE) == 0)
169 func |= GDK_FUNC_MAXIMIZE; */
170 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) == 0)
171 decor
|= GDK_DECOR_MENU
;
172 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) == 0)
173 decor
|= GDK_DECOR_MINIMIZE
;
174 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
175 decor
|= GDK_DECOR_MAXIMIZE
;
176 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
177 func
|= GDK_FUNC_RESIZE
;
179 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
180 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
182 /* GTK's shrinking/growing policy */
183 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
184 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
186 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
189 if (win
->m_icon
!= wxNullIcon
)
191 wxIcon
icon( win
->m_icon
);
192 win
->m_icon
= wxNullIcon
;
193 win
->SetIcon( icon
);
199 //-----------------------------------------------------------------------------
200 // "map" from m_widget
201 //-----------------------------------------------------------------------------
204 gtk_frame_map_callback( GtkWidget
*widget
, wxFrame
*win
)
206 gtk_widget_set_uposition( widget
, win
->m_x
, win
->m_y
);
211 //-----------------------------------------------------------------------------
212 // InsertChild for wxFrame
213 //-----------------------------------------------------------------------------
215 /* Callback for wxFrame. This very strange beast has to be used because
216 * C++ has no virtual methods in a constructor. We have to emulate a
217 * virtual function here as wxWindows requires different ways to insert
218 * a child in container classes. */
220 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
222 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
224 /* actually, menubars are never inserted here, but this
225 may change one day */
227 /* these are outside the client area */
228 wxFrame
* frame
= (wxFrame
*) parent
;
229 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
230 GTK_WIDGET(child
->m_widget
),
234 /* we connect to these events for recalculating the client area
235 space when the toolbar is floating */
236 if (wxIS_KIND_OF(child
,wxToolBar
))
238 wxToolBar
*toolBar
= (wxToolBar
*) child
;
239 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
241 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
242 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
244 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
245 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
251 /* these are inside the client area */
252 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
253 GTK_WIDGET(child
->m_widget
),
258 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
262 /* resize on OnInternalIdle */
263 parent
->m_sizeSet
= FALSE
;
266 //-----------------------------------------------------------------------------
268 //-----------------------------------------------------------------------------
270 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
271 EVT_SIZE(wxFrame::OnSize
)
272 EVT_CLOSE(wxFrame::OnCloseWindow
)
273 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
276 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
280 m_frameMenuBar
= (wxMenuBar
*) NULL
;
281 m_frameStatusBar
= (wxStatusBar
*) NULL
;
282 m_frameToolBar
= (wxToolBar
*) NULL
;
286 m_mainWidget
= (GtkWidget
*) NULL
;
287 m_menuBarDetached
= FALSE
;
288 m_toolBarDetached
= FALSE
;
289 m_insertCallback
= wxInsertChildInFrame
;
292 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
293 const wxPoint
&pos
, const wxSize
&size
,
294 long style
, const wxString
&name
)
296 m_frameMenuBar
= (wxMenuBar
*) NULL
;
297 m_frameStatusBar
= (wxStatusBar
*) NULL
;
298 m_frameToolBar
= (wxToolBar
*) NULL
;
302 m_mainWidget
= (GtkWidget
*) NULL
;
303 m_menuBarDetached
= FALSE
;
304 m_toolBarDetached
= FALSE
;
305 m_insertCallback
= wxInsertChildInFrame
;
306 Create( parent
, id
, title
, pos
, size
, style
, name
);
309 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
310 const wxPoint
&pos
, const wxSize
&size
,
311 long style
, const wxString
&name
)
313 wxTopLevelWindows
.Append( this );
315 m_needParent
= FALSE
;
317 PreCreation( parent
, id
, pos
, size
, style
, name
);
321 m_insertCallback
= wxInsertChildInFrame
;
323 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
324 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
326 m_widget
= gtk_window_new( win_type
);
328 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
329 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
331 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
332 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
334 /* m_mainWidget holds the toolbar, the menubar and the client area */
335 m_mainWidget
= gtk_myfixed_new();
336 gtk_widget_show( m_mainWidget
);
337 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
338 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
340 /* m_wxwindow only represents the client area without toolbar and menubar */
341 m_wxwindow
= gtk_myfixed_new();
342 gtk_widget_show( m_wxwindow
);
343 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
345 /* we allow the frame to get the focus as otherwise no
346 key events will get sent to it. the point with this is
347 that the menu's key accelerators work by interceting
349 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
350 gtk_widget_grab_focus( m_wxwindow
);
352 if (m_parent
) m_parent
->AddChild( this );
356 /* we cannot set MWM hints and icons before the widget has
357 been realized, so we do this directly after realization */
358 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
359 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
361 /* we set the position of the window after the map event. setting it
362 before has no effect (with KWM) */
363 gtk_signal_connect( GTK_OBJECT(m_widget
), "map",
364 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
) this );
366 /* the user resized the frame by dragging etc. */
367 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
368 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
370 /* the only way to get the window size is to connect to this event */
371 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
372 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
379 if (m_frameMenuBar
) delete m_frameMenuBar
;
380 m_frameMenuBar
= (wxMenuBar
*) NULL
;
382 if (m_frameStatusBar
) delete m_frameStatusBar
;
383 m_frameStatusBar
= (wxStatusBar
*) NULL
;
385 if (m_frameToolBar
) delete m_frameToolBar
;
386 m_frameToolBar
= (wxToolBar
*) NULL
;
388 wxTopLevelWindows
.DeleteObject( this );
390 if (wxTheApp
->GetTopWindow() == this)
391 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
393 if (wxTopLevelWindows
.Number() == 0)
394 wxTheApp
->ExitMainLoop();
397 bool wxFrame::Show( bool show
)
399 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
401 if (show
&& !m_sizeSet
)
403 /* by calling GtkOnSize here, we don't have to call
404 either after showing the frame, which would entail
405 much ugly flicker or from within the size_allocate
406 handler, because GTK 1.1.X forbids that. */
408 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
411 return wxWindow::Show( show
);
414 bool wxFrame::Destroy()
416 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
418 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
423 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
425 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
427 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
428 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
430 /* avoid recursions */
431 if (m_resizing
) return;
436 int old_width
= m_width
;
437 int old_height
= m_height
;
439 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
441 if (x
!= -1) m_x
= x
;
442 if (y
!= -1) m_y
= y
;
443 if (width
!= -1) m_width
= width
;
444 if (height
!= -1) m_height
= height
;
454 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
456 if (width
== -1) m_width
= 80;
459 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
461 if (height
== -1) m_height
= 26;
464 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
465 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
466 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
467 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
469 if ((m_x
!= -1) || (m_y
!= -1))
471 if ((m_x
!= old_x
) || (m_y
!= old_y
))
473 /* we set the size here and in gtk_frame_map_callback */
474 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
478 if ((m_width
!= old_width
) || (m_height
!= old_height
))
480 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
481 done either directly before the frame is shown or in idle time
482 so that different calls to SetSize() don't lead to flicker. */
489 void wxFrame::Centre( int direction
)
491 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
496 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
497 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
502 void wxFrame::GetClientSize( int *width
, int *height
) const
504 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
506 wxWindow::GetClientSize( width
, height
);
512 if (!m_menuBarDetached
)
513 (*height
) -= wxMENU_HEIGHT
;
515 (*height
) -= wxPLACE_HOLDER
;
519 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
524 if (!m_toolBarDetached
)
527 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
531 (*height
) -= wxPLACE_HOLDER
;
535 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
539 (*width
) -= m_miniEdge
*2;
543 void wxFrame::DoSetClientSize( int width
, int height
)
545 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
550 if (!m_menuBarDetached
)
551 height
+= wxMENU_HEIGHT
;
553 height
+= wxPLACE_HOLDER
;
557 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
562 if (!m_toolBarDetached
)
565 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
569 height
+= wxPLACE_HOLDER
;
572 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
575 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
577 // due to a bug in gtk, x,y are always 0
581 /* avoid recursions */
582 if (m_resizing
) return;
585 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
586 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
591 /* space occupied by m_frameToolBar and m_frameMenuBar */
592 int client_area_y_offset
= 0;
594 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
595 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
596 set in wxFrame::Create so it is used to check what kind of frame we
597 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
598 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
599 importantly) m_mainWidget */
603 /* check if size is in legal range */
604 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
605 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
606 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
607 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
609 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
610 * menubar, the toolbar and the client area, which is represented by
612 * this hurts in the eye, but I don't want to call SetSize()
613 * because I don't want to call any non-native functions here. */
618 int yy
= m_miniEdge
+ m_miniTitle
;
619 int ww
= m_width
- 2*m_miniEdge
;
620 int hh
= wxMENU_HEIGHT
;
621 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
622 m_frameMenuBar
->m_x
= xx
;
623 m_frameMenuBar
->m_y
= yy
;
624 m_frameMenuBar
->m_width
= ww
;
625 m_frameMenuBar
->m_height
= hh
;
627 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
628 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
630 client_area_y_offset
+= hh
;
636 int yy
= m_miniEdge
+ m_miniTitle
;
639 if (!m_menuBarDetached
)
642 yy
+= wxPLACE_HOLDER
;
644 int ww
= m_width
- 2*m_miniEdge
;
645 int hh
= m_frameToolBar
->m_height
;
646 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
647 m_frameToolBar
->m_x
= xx
;
648 m_frameToolBar
->m_y
= yy
;
649 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
650 m_frameToolBar
->m_width
= ww
;
652 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
653 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
655 client_area_y_offset
+= hh
;
658 int client_x
= m_miniEdge
;
659 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
660 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
662 int client_w
= m_width
- 2*m_miniEdge
;
663 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
664 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
668 /* if there is no m_mainWidget between m_widget and m_wxwindow there
669 is no need to set the size or position of m_wxwindow. */
672 if (m_frameStatusBar
)
674 int xx
= 0 + m_miniEdge
;
675 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
676 int ww
= m_width
- 2*m_miniEdge
;
677 int hh
= wxSTATUS_HEIGHT
;
679 m_frameStatusBar
->m_x
= xx
;
680 m_frameStatusBar
->m_y
= yy
;
681 m_frameStatusBar
->m_width
= ww
;
682 m_frameStatusBar
->m_height
= hh
;
684 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
685 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
688 /* we actually set the size of a frame here and no-where else */
689 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
693 /* send size event to frame */
694 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
695 event
.SetEventObject( this );
696 GetEventHandler()->ProcessEvent( event
);
698 /* send size event to status bar */
699 if (m_frameStatusBar
)
701 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
702 event2
.SetEventObject( m_frameStatusBar
);
703 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
709 void wxFrame::OnInternalIdle()
712 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
717 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
722 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
724 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
732 // do we have exactly one child?
733 wxWindow
*child
= (wxWindow
*)NULL
;
734 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
736 wxWindow
*win
= (wxWindow
*)node
->Data();
737 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
741 // it's the second one: do nothing
749 // no children at all?
752 // yes: set it's size to fill all the frame
753 int client_x
, client_y
;
754 GetClientSize( &client_x
, &client_y
);
755 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
760 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
762 menu
->SetInvokingWindow( win
);
763 wxNode
*node
= menu
->GetItems().First();
766 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
767 if (menuitem
->IsSubMenu())
768 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
773 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
775 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
776 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
778 m_frameMenuBar
= menuBar
;
782 /* support for native key accelerators indicated by underscroes */
783 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
784 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
787 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
790 wxMenu
*menu
= (wxMenu
*)node
->Data();
791 SetInvokingWindow( menu
, this );
795 if (m_frameMenuBar
->m_parent
!= this)
797 m_frameMenuBar
->m_parent
= this;
798 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
799 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
801 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
803 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
804 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
806 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
807 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
812 /* resize window in OnInternalIdle */
816 wxMenuBar
*wxFrame::GetMenuBar() const
818 return m_frameMenuBar
;
821 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
825 // if no help string found, we will clear the status bar text
828 int menuId
= event
.GetMenuId();
831 wxMenuBar
*menuBar
= GetMenuBar();
834 helpString
= menuBar
->GetHelpString(menuId
);
838 SetStatusText(helpString
);
842 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
844 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
846 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
848 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
850 GetChildren().DeleteObject( m_frameToolBar
);
854 return m_frameToolBar
;
857 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
859 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
862 wxToolBar
*wxFrame::GetToolBar() const
864 return m_frameToolBar
;
867 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
869 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
871 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
873 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
877 return m_frameStatusBar
;
880 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
882 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
884 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
886 // Set the height according to the font and the border size
887 wxClientDC
dc(statusBar
);
888 dc
.SetFont( statusBar
->GetFont() );
891 dc
.GetTextExtent( "X", &x
, &y
);
893 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
895 statusBar
->SetSize( -1, -1, 100, height
);
897 statusBar
->SetFieldsCount( number
);
901 void wxFrame::Command( int id
)
903 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
904 commandEvent
.SetInt( id
);
905 commandEvent
.SetEventObject( this );
907 wxMenuBar
*bar
= GetMenuBar();
910 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
911 if (item
&& item
->IsCheckable())
913 bar
->Check(id
,!bar
->Checked(id
)) ;
916 wxEvtHandler
* evtHandler
= GetEventHandler();
918 evtHandler
->ProcessEvent(commandEvent
);
921 void wxFrame::SetStatusText(const wxString
& text
, int number
)
923 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
925 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
927 m_frameStatusBar
->SetStatusText(text
, number
);
930 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
932 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
934 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
936 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
939 wxStatusBar
*wxFrame::GetStatusBar() const
941 return m_frameStatusBar
;
944 void wxFrame::SetTitle( const wxString
&title
)
946 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
949 if (m_title
.IsNull()) m_title
= _T("");
950 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
953 void wxFrame::SetIcon( const wxIcon
&icon
)
955 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
958 if (!icon
.Ok()) return;
960 if (!m_widget
->window
) return;
962 wxMask
*mask
= icon
.GetMask();
963 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
964 if (mask
) bm
= mask
->GetBitmap();
966 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);