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 // InsertChild for wxFrame
201 //-----------------------------------------------------------------------------
203 /* Callback for wxFrame. This very strange beast has to be used because
204 * C++ has no virtual methods in a constructor. We have to emulate a
205 * virtual function here as wxWindows requires different ways to insert
206 * a child in container classes. */
208 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
210 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
212 /* actually, menubars are never inserted here, but this
213 may change one day */
215 /* these are outside the client area */
216 wxFrame
* frame
= (wxFrame
*) parent
;
217 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
218 GTK_WIDGET(child
->m_widget
),
222 /* we connect to these events for recalculating the client area
223 space when the toolbar is floating */
224 if (wxIS_KIND_OF(child
,wxToolBar
))
226 wxToolBar
*toolBar
= (wxToolBar
*) child
;
227 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
229 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
230 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
232 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
233 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
239 /* these are inside the client area */
240 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
241 GTK_WIDGET(child
->m_widget
),
246 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
250 /* resize on OnInternalIdle */
251 parent
->m_sizeSet
= FALSE
;
254 //-----------------------------------------------------------------------------
256 //-----------------------------------------------------------------------------
258 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
259 EVT_SIZE(wxFrame::OnSize
)
260 EVT_CLOSE(wxFrame::OnCloseWindow
)
261 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
264 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
268 m_frameMenuBar
= (wxMenuBar
*) NULL
;
269 m_frameStatusBar
= (wxStatusBar
*) NULL
;
270 m_frameToolBar
= (wxToolBar
*) NULL
;
274 m_mainWidget
= (GtkWidget
*) NULL
;
275 m_menuBarDetached
= FALSE
;
276 m_toolBarDetached
= FALSE
;
277 m_insertCallback
= wxInsertChildInFrame
;
280 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
281 const wxPoint
&pos
, const wxSize
&size
,
282 long style
, const wxString
&name
)
284 m_frameMenuBar
= (wxMenuBar
*) NULL
;
285 m_frameStatusBar
= (wxStatusBar
*) NULL
;
286 m_frameToolBar
= (wxToolBar
*) NULL
;
290 m_mainWidget
= (GtkWidget
*) NULL
;
291 m_menuBarDetached
= FALSE
;
292 m_toolBarDetached
= FALSE
;
293 m_insertCallback
= wxInsertChildInFrame
;
294 Create( parent
, id
, title
, pos
, size
, style
, name
);
297 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
298 const wxPoint
&pos
, const wxSize
&size
,
299 long style
, const wxString
&name
)
301 wxTopLevelWindows
.Append( this );
303 m_needParent
= FALSE
;
305 PreCreation( parent
, id
, pos
, size
, style
, name
);
309 m_insertCallback
= wxInsertChildInFrame
;
311 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
312 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
314 m_widget
= gtk_window_new( win_type
);
316 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
317 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
319 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
320 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
322 /* m_mainWidget holds the toolbar, the menubar and the client area */
323 m_mainWidget
= gtk_myfixed_new();
324 gtk_widget_show( m_mainWidget
);
325 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
326 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
328 /* m_wxwindow only represents the client area without toolbar and menubar */
329 m_wxwindow
= gtk_myfixed_new();
330 gtk_widget_show( m_wxwindow
);
331 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
333 /* we allow the frame to get the focus as otherwise no
334 keye vents will get sent to it. the point with this is
335 that the menu's key accelerators work by interceting
337 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
338 GTK_WIDGET_SET_FLAGS (m_wxwindow
, GTK_HAS_FOCUS
);
340 if (m_parent
) m_parent
->AddChild( this );
344 /* we cannot set MWM hints and icons before the widget has
345 been realized, so we do this directly after realization */
346 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
347 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
349 /* the user resized the frame by dragging etc. */
350 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
351 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
353 /* the only way to get the window size is to connect to this event */
354 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
355 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
362 if (m_frameMenuBar
) delete m_frameMenuBar
;
363 m_frameMenuBar
= (wxMenuBar
*) NULL
;
365 if (m_frameStatusBar
) delete m_frameStatusBar
;
366 m_frameStatusBar
= (wxStatusBar
*) NULL
;
368 if (m_frameToolBar
) delete m_frameToolBar
;
369 m_frameToolBar
= (wxToolBar
*) NULL
;
371 wxTopLevelWindows
.DeleteObject( this );
373 if (wxTheApp
->GetTopWindow() == this)
374 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
376 if (wxTopLevelWindows
.Number() == 0)
377 wxTheApp
->ExitMainLoop();
380 bool wxFrame::Show( bool show
)
382 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
384 if (show
&& !m_sizeSet
)
386 /* by calling GtkOnSize here, we don't have to call
387 either after showing the frame, which would entail
388 much ugly flicker or from within the size_allocate
389 handler, because GTK 1.1.X forbids that. */
391 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
394 return wxWindow::Show( show
);
397 bool wxFrame::Destroy()
399 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
401 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
406 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
408 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
410 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
411 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
413 /* avoid recursions */
414 if (m_resizing
) return;
419 int old_width
= m_width
;
420 int old_height
= m_height
;
422 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
424 if (x
!= -1) m_x
= x
;
425 if (y
!= -1) m_y
= y
;
426 if (width
!= -1) m_width
= width
;
427 if (height
!= -1) m_height
= height
;
437 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
439 if (width
== -1) m_width
= 80;
442 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
444 if (height
== -1) m_height
= 26;
447 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
448 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
449 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
450 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
452 if ((m_x
!= -1) || (m_y
!= -1))
454 if ((m_x
!= old_x
) || (m_y
!= old_y
))
456 /* m_sizeSet = FALSE; */
457 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
461 if ((m_width
!= old_width
) || (m_height
!= old_height
))
463 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
464 done either directly before the frame is shown or in idle time
465 so that different calls to SetSize() don't lead to flicker. */
472 void wxFrame::Centre( int direction
)
474 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
479 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
480 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
485 void wxFrame::GetClientSize( int *width
, int *height
) const
487 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
489 wxWindow::GetClientSize( width
, height
);
495 if (!m_menuBarDetached
)
496 (*height
) -= wxMENU_HEIGHT
;
498 (*height
) -= wxPLACE_HOLDER
;
502 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
507 if (!m_toolBarDetached
)
510 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
514 (*height
) -= wxPLACE_HOLDER
;
518 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
522 (*width
) -= m_miniEdge
*2;
526 void wxFrame::DoSetClientSize( int width
, int height
)
528 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
533 if (!m_menuBarDetached
)
534 height
+= wxMENU_HEIGHT
;
536 height
+= wxPLACE_HOLDER
;
540 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
545 if (!m_toolBarDetached
)
548 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
552 height
+= wxPLACE_HOLDER
;
555 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
558 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
560 // due to a bug in gtk, x,y are always 0
564 /* avoid recursions */
565 if (m_resizing
) return;
568 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
569 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
574 /* space occupied by m_frameToolBar and m_frameMenuBar */
575 int client_area_y_offset
= 0;
577 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
578 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
579 set in wxFrame::Create so it is used to check what kind of frame we
580 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
581 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
582 importantly) m_mainWidget */
586 /* check if size is in legal range */
587 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
588 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
589 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
590 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
592 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
593 * menubar, the toolbar and the client area, which is represented by
595 * this hurts in the eye, but I don't want to call SetSize()
596 * because I don't want to call any non-native functions here. */
601 int yy
= m_miniEdge
+ m_miniTitle
;
602 int ww
= m_width
- 2*m_miniEdge
;
603 int hh
= wxMENU_HEIGHT
;
604 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
605 m_frameMenuBar
->m_x
= xx
;
606 m_frameMenuBar
->m_y
= yy
;
607 m_frameMenuBar
->m_width
= ww
;
608 m_frameMenuBar
->m_height
= hh
;
610 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
611 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
613 client_area_y_offset
+= hh
;
619 int yy
= m_miniEdge
+ m_miniTitle
;
622 if (!m_menuBarDetached
)
625 yy
+= wxPLACE_HOLDER
;
627 int ww
= m_width
- 2*m_miniEdge
;
628 int hh
= m_frameToolBar
->m_height
;
629 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
630 m_frameToolBar
->m_x
= xx
;
631 m_frameToolBar
->m_y
= yy
;
632 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
633 m_frameToolBar
->m_width
= ww
;
635 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
636 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
638 client_area_y_offset
+= hh
;
641 int client_x
= m_miniEdge
;
642 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
643 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
645 int client_w
= m_width
- 2*m_miniEdge
;
646 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
647 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
651 /* if there is no m_mainWidget between m_widget and m_wxwindow there
652 is no need to set the size or position of m_wxwindow. */
655 if (m_frameStatusBar
)
657 int xx
= 0 + m_miniEdge
;
658 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
659 int ww
= m_width
- 2*m_miniEdge
;
660 int hh
= wxSTATUS_HEIGHT
;
662 m_frameStatusBar
->m_x
= xx
;
663 m_frameStatusBar
->m_y
= yy
;
664 m_frameStatusBar
->m_width
= ww
;
665 m_frameStatusBar
->m_height
= hh
;
667 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
668 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
671 /* we actually set the size of a frame here and no-where else */
672 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
676 /* send size event to frame */
677 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
678 event
.SetEventObject( this );
679 GetEventHandler()->ProcessEvent( event
);
681 /* send size event to status bar */
682 if (m_frameStatusBar
)
684 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
685 event2
.SetEventObject( m_frameStatusBar
);
686 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
692 void wxFrame::OnInternalIdle()
695 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
700 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
705 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
707 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
715 // do we have exactly one child?
716 wxWindow
*child
= (wxWindow
*)NULL
;
717 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
719 wxWindow
*win
= (wxWindow
*)node
->Data();
720 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
724 // it's the second one: do nothing
732 // no children at all?
735 // yes: set it's size to fill all the frame
736 int client_x
, client_y
;
737 GetClientSize( &client_x
, &client_y
);
738 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
743 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
745 menu
->SetInvokingWindow( win
);
746 wxNode
*node
= menu
->GetItems().First();
749 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
750 if (menuitem
->IsSubMenu())
751 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
756 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
758 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
759 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
761 m_frameMenuBar
= menuBar
;
765 /* support for native key accelerators indicated by underscroes */
766 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
767 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_wxwindow
));
770 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
773 wxMenu
*menu
= (wxMenu
*)node
->Data();
774 SetInvokingWindow( menu
, this );
778 if (m_frameMenuBar
->m_parent
!= this)
780 m_frameMenuBar
->m_parent
= this;
781 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
782 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
784 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
786 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
787 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
789 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
790 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
795 /* resize window in OnInternalIdle */
799 wxMenuBar
*wxFrame::GetMenuBar() const
801 return m_frameMenuBar
;
804 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
808 // if no help string found, we will clear the status bar text
811 int menuId
= event
.GetMenuId();
814 wxMenuBar
*menuBar
= GetMenuBar();
817 helpString
= menuBar
->GetHelpString(menuId
);
821 SetStatusText(helpString
);
825 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
827 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
829 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
831 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
833 GetChildren().DeleteObject( m_frameToolBar
);
837 return m_frameToolBar
;
840 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
842 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
845 wxToolBar
*wxFrame::GetToolBar() const
847 return m_frameToolBar
;
850 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
852 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
854 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
856 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
860 return m_frameStatusBar
;
863 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
865 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
867 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
869 // Set the height according to the font and the border size
870 wxClientDC
dc(statusBar
);
871 dc
.SetFont( statusBar
->GetFont() );
874 dc
.GetTextExtent( "X", &x
, &y
);
876 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
878 statusBar
->SetSize( -1, -1, 100, height
);
880 statusBar
->SetFieldsCount( number
);
884 void wxFrame::Command( int id
)
886 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
887 commandEvent
.SetInt( id
);
888 commandEvent
.SetEventObject( this );
890 wxMenuBar
*bar
= GetMenuBar();
893 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
894 if (item
&& item
->IsCheckable())
896 bar
->Check(id
,!bar
->Checked(id
)) ;
899 wxEvtHandler
* evtHandler
= GetEventHandler();
901 evtHandler
->ProcessEvent(commandEvent
);
904 void wxFrame::SetStatusText(const wxString
& text
, int number
)
906 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
908 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
910 m_frameStatusBar
->SetStatusText(text
, number
);
913 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
915 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
917 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
919 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
922 wxStatusBar
*wxFrame::GetStatusBar() const
924 return m_frameStatusBar
;
927 void wxFrame::SetTitle( const wxString
&title
)
929 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
932 if (m_title
.IsNull()) m_title
= _T("");
933 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
936 void wxFrame::SetIcon( const wxIcon
&icon
)
938 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
941 if (!icon
.Ok()) return;
943 if (!m_widget
->window
) return;
945 wxMask
*mask
= icon
.GetMask();
946 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
947 if (mask
) bm
= mask
->GetBitmap();
949 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);