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
);
198 /* by calling GtkOnSize here, we don't have to call
199 either after showing the frame, which would entail
200 much ugly flicker or from within the size_allocate
201 handler, because GTK 1.1.X forbids that. */
203 win
->GtkOnSize( win
->m_x
, win
->m_y
, win
->m_width
, win
->m_height
);
209 //-----------------------------------------------------------------------------
210 // InsertChild for wxFrame
211 //-----------------------------------------------------------------------------
213 /* Callback for wxFrame. This very strange beast has to be used because
214 * C++ has no virtual methods in a constructor. We have to emulate a
215 * virtual function here as wxWindows requires different ways to insert
216 * a child in container classes. */
218 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
220 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
222 /* actually, menubars are never inserted here, but this
223 may change one day */
225 /* these are outside the client area */
226 wxFrame
* frame
= (wxFrame
*) parent
;
227 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
228 GTK_WIDGET(child
->m_widget
),
232 /* we connect to these events for recalculating the client area
233 space when the toolbar is floating */
234 if (wxIS_KIND_OF(child
,wxToolBar
))
236 wxToolBar
*toolBar
= (wxToolBar
*) child
;
237 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
239 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
240 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
242 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
243 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
249 /* these are inside the client area */
250 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
251 GTK_WIDGET(child
->m_widget
),
256 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
260 /* resize on OnInternalIdle */
261 parent
->m_sizeSet
= FALSE
;
264 //-----------------------------------------------------------------------------
266 //-----------------------------------------------------------------------------
268 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
269 EVT_SIZE(wxFrame::OnSize
)
270 EVT_CLOSE(wxFrame::OnCloseWindow
)
271 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
274 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
278 m_frameMenuBar
= (wxMenuBar
*) NULL
;
279 m_frameStatusBar
= (wxStatusBar
*) NULL
;
280 m_frameToolBar
= (wxToolBar
*) NULL
;
284 m_mainWidget
= (GtkWidget
*) NULL
;
285 m_menuBarDetached
= FALSE
;
286 m_toolBarDetached
= FALSE
;
287 m_insertCallback
= wxInsertChildInFrame
;
290 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
291 const wxPoint
&pos
, const wxSize
&size
,
292 long style
, const wxString
&name
)
294 m_frameMenuBar
= (wxMenuBar
*) NULL
;
295 m_frameStatusBar
= (wxStatusBar
*) NULL
;
296 m_frameToolBar
= (wxToolBar
*) NULL
;
300 m_mainWidget
= (GtkWidget
*) NULL
;
301 m_menuBarDetached
= FALSE
;
302 m_toolBarDetached
= FALSE
;
303 m_insertCallback
= wxInsertChildInFrame
;
304 Create( parent
, id
, title
, pos
, size
, style
, name
);
307 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
308 const wxPoint
&pos
, const wxSize
&size
,
309 long style
, const wxString
&name
)
311 wxTopLevelWindows
.Append( this );
313 m_needParent
= FALSE
;
315 PreCreation( parent
, id
, pos
, size
, style
, name
);
319 m_insertCallback
= wxInsertChildInFrame
;
321 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
322 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
324 m_widget
= gtk_window_new( win_type
);
326 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
327 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
329 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
330 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
332 /* m_mainWidget holds the toolbar, the menubar and the client area */
333 m_mainWidget
= gtk_myfixed_new();
334 gtk_widget_show( m_mainWidget
);
335 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
336 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
338 /* m_wxwindow only represents the client area without toolbar and menubar */
339 m_wxwindow
= gtk_myfixed_new();
340 gtk_widget_show( m_wxwindow
);
341 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
343 /* we allow the frame to get the focus as otherwise no
344 key events will get sent to it. the point with this is
345 that the menu's key accelerators work by interceting
347 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
348 gtk_widget_grab_focus( m_wxwindow
);
350 if (m_parent
) m_parent
->AddChild( this );
354 /* we cannot set MWM hints and icons before the widget has
355 been realized, so we do this directly after realization */
356 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
357 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
359 /* the user resized the frame by dragging etc. */
360 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
361 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
363 /* the only way to get the window size is to connect to this event */
364 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
365 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
372 if (m_frameMenuBar
) delete m_frameMenuBar
;
373 m_frameMenuBar
= (wxMenuBar
*) NULL
;
375 if (m_frameStatusBar
) delete m_frameStatusBar
;
376 m_frameStatusBar
= (wxStatusBar
*) NULL
;
378 if (m_frameToolBar
) delete m_frameToolBar
;
379 m_frameToolBar
= (wxToolBar
*) NULL
;
381 wxTopLevelWindows
.DeleteObject( this );
383 if (wxTheApp
->GetTopWindow() == this)
384 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
386 if (wxTopLevelWindows
.Number() == 0)
387 wxTheApp
->ExitMainLoop();
390 bool wxFrame::Show( bool show
)
392 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
395 if (show
&& !m_sizeSet
)
397 /* by calling GtkOnSize here, we don't have to call
398 either after showing the frame, which would entail
399 much ugly flicker or from within the size_allocate
400 handler, because GTK 1.1.X forbids that. */
402 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
406 return wxWindow::Show( show
);
409 bool wxFrame::Destroy()
411 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
413 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
418 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
420 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
422 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
423 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
425 /* avoid recursions */
426 if (m_resizing
) return;
431 int old_width
= m_width
;
432 int old_height
= m_height
;
434 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
436 if (x
!= -1) m_x
= x
;
437 if (y
!= -1) m_y
= y
;
438 if (width
!= -1) m_width
= width
;
439 if (height
!= -1) m_height
= height
;
449 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
451 if (width
== -1) m_width
= 80;
454 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
456 if (height
== -1) m_height
= 26;
459 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
460 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
461 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
462 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
464 if ((m_x
!= -1) || (m_y
!= -1))
466 if ((m_x
!= old_x
) || (m_y
!= old_y
))
468 /* m_sizeSet = FALSE; */
469 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
473 if ((m_width
!= old_width
) || (m_height
!= old_height
))
475 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
476 done either directly before the frame is shown or in idle time
477 so that different calls to SetSize() don't lead to flicker. */
484 void wxFrame::Centre( int direction
)
486 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
491 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
492 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
497 void wxFrame::GetClientSize( int *width
, int *height
) const
499 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
501 wxWindow::GetClientSize( width
, height
);
507 if (!m_menuBarDetached
)
508 (*height
) -= wxMENU_HEIGHT
;
510 (*height
) -= wxPLACE_HOLDER
;
514 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
519 if (!m_toolBarDetached
)
522 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
526 (*height
) -= wxPLACE_HOLDER
;
530 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
534 (*width
) -= m_miniEdge
*2;
538 void wxFrame::DoSetClientSize( int width
, int height
)
540 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
545 if (!m_menuBarDetached
)
546 height
+= wxMENU_HEIGHT
;
548 height
+= wxPLACE_HOLDER
;
552 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
557 if (!m_toolBarDetached
)
560 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
564 height
+= wxPLACE_HOLDER
;
567 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
570 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
572 // due to a bug in gtk, x,y are always 0
576 /* avoid recursions */
577 if (m_resizing
) return;
580 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
581 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
586 /* space occupied by m_frameToolBar and m_frameMenuBar */
587 int client_area_y_offset
= 0;
589 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
590 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
591 set in wxFrame::Create so it is used to check what kind of frame we
592 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
593 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
594 importantly) m_mainWidget */
598 /* check if size is in legal range */
599 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
600 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
601 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
602 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
604 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
605 * menubar, the toolbar and the client area, which is represented by
607 * this hurts in the eye, but I don't want to call SetSize()
608 * because I don't want to call any non-native functions here. */
613 int yy
= m_miniEdge
+ m_miniTitle
;
614 int ww
= m_width
- 2*m_miniEdge
;
615 int hh
= wxMENU_HEIGHT
;
616 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
617 m_frameMenuBar
->m_x
= xx
;
618 m_frameMenuBar
->m_y
= yy
;
619 m_frameMenuBar
->m_width
= ww
;
620 m_frameMenuBar
->m_height
= hh
;
622 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
623 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
625 client_area_y_offset
+= hh
;
631 int yy
= m_miniEdge
+ m_miniTitle
;
634 if (!m_menuBarDetached
)
637 yy
+= wxPLACE_HOLDER
;
639 int ww
= m_width
- 2*m_miniEdge
;
640 int hh
= m_frameToolBar
->m_height
;
641 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
642 m_frameToolBar
->m_x
= xx
;
643 m_frameToolBar
->m_y
= yy
;
644 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
645 m_frameToolBar
->m_width
= ww
;
647 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
648 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
650 client_area_y_offset
+= hh
;
653 int client_x
= m_miniEdge
;
654 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
655 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
657 int client_w
= m_width
- 2*m_miniEdge
;
658 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
659 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
663 /* if there is no m_mainWidget between m_widget and m_wxwindow there
664 is no need to set the size or position of m_wxwindow. */
667 if (m_frameStatusBar
)
669 int xx
= 0 + m_miniEdge
;
670 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
671 int ww
= m_width
- 2*m_miniEdge
;
672 int hh
= wxSTATUS_HEIGHT
;
674 m_frameStatusBar
->m_x
= xx
;
675 m_frameStatusBar
->m_y
= yy
;
676 m_frameStatusBar
->m_width
= ww
;
677 m_frameStatusBar
->m_height
= hh
;
679 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
680 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
683 /* we actually set the size of a frame here and no-where else */
684 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
688 /* send size event to frame */
689 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
690 event
.SetEventObject( this );
691 GetEventHandler()->ProcessEvent( event
);
693 /* send size event to status bar */
694 if (m_frameStatusBar
)
696 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
697 event2
.SetEventObject( m_frameStatusBar
);
698 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
704 void wxFrame::OnInternalIdle()
707 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
712 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
717 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
719 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
727 // do we have exactly one child?
728 wxWindow
*child
= (wxWindow
*)NULL
;
729 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
731 wxWindow
*win
= (wxWindow
*)node
->Data();
732 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
736 // it's the second one: do nothing
744 // no children at all?
747 // yes: set it's size to fill all the frame
748 int client_x
, client_y
;
749 GetClientSize( &client_x
, &client_y
);
750 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
755 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
757 menu
->SetInvokingWindow( win
);
758 wxNode
*node
= menu
->GetItems().First();
761 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
762 if (menuitem
->IsSubMenu())
763 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
768 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
770 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
771 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
773 m_frameMenuBar
= menuBar
;
777 /* support for native key accelerators indicated by underscroes */
778 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
779 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
782 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
785 wxMenu
*menu
= (wxMenu
*)node
->Data();
786 SetInvokingWindow( menu
, this );
790 if (m_frameMenuBar
->m_parent
!= this)
792 m_frameMenuBar
->m_parent
= this;
793 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
794 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
796 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
798 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
799 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
801 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
802 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
807 /* resize window in OnInternalIdle */
811 wxMenuBar
*wxFrame::GetMenuBar() const
813 return m_frameMenuBar
;
816 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
820 // if no help string found, we will clear the status bar text
823 int menuId
= event
.GetMenuId();
826 wxMenuBar
*menuBar
= GetMenuBar();
829 helpString
= menuBar
->GetHelpString(menuId
);
833 SetStatusText(helpString
);
837 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
839 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
841 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
843 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
845 GetChildren().DeleteObject( m_frameToolBar
);
849 return m_frameToolBar
;
852 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
854 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
857 wxToolBar
*wxFrame::GetToolBar() const
859 return m_frameToolBar
;
862 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
864 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
866 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
868 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
872 return m_frameStatusBar
;
875 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
877 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
879 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
881 // Set the height according to the font and the border size
882 wxClientDC
dc(statusBar
);
883 dc
.SetFont( statusBar
->GetFont() );
886 dc
.GetTextExtent( "X", &x
, &y
);
888 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
890 statusBar
->SetSize( -1, -1, 100, height
);
892 statusBar
->SetFieldsCount( number
);
896 void wxFrame::Command( int id
)
898 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
899 commandEvent
.SetInt( id
);
900 commandEvent
.SetEventObject( this );
902 wxMenuBar
*bar
= GetMenuBar();
905 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
906 if (item
&& item
->IsCheckable())
908 bar
->Check(id
,!bar
->Checked(id
)) ;
911 wxEvtHandler
* evtHandler
= GetEventHandler();
913 evtHandler
->ProcessEvent(commandEvent
);
916 void wxFrame::SetStatusText(const wxString
& text
, int number
)
918 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
920 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
922 m_frameStatusBar
->SetStatusText(text
, number
);
925 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
927 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
929 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
931 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
934 wxStatusBar
*wxFrame::GetStatusBar() const
936 return m_frameStatusBar
;
939 void wxFrame::SetTitle( const wxString
&title
)
941 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
944 if (m_title
.IsNull()) m_title
= _T("");
945 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
948 void wxFrame::SetIcon( const wxIcon
&icon
)
950 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
953 if (!icon
.Ok()) return;
955 if (!m_widget
->window
) return;
957 wxMask
*mask
= icon
.GetMask();
958 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
959 if (mask
) bm
= mask
->GetBitmap();
961 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);