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 void wxapp_install_idle_handler();
43 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
47 extern wxList wxPendingDelete
;
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
53 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
55 if (g_isIdle
) wxapp_install_idle_handler();
57 if (!win
->HasVMT()) return;
60 printf( "OnFrameResize from " );
61 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
62 printf( win->GetClassInfo()->GetClassName() );
66 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
68 win
->m_sizeSet
= FALSE
;
69 win
->m_width
= alloc
->width
;
70 win
->m_height
= alloc
->height
;
74 //-----------------------------------------------------------------------------
76 //-----------------------------------------------------------------------------
78 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
80 if (g_isIdle
) wxapp_install_idle_handler();
83 printf( "OnDelete from " );
84 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
85 printf( win->GetClassInfo()->GetClassName() );
94 //-----------------------------------------------------------------------------
95 // "child_attached" of menu bar
96 //-----------------------------------------------------------------------------
98 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
100 if (g_isIdle
) wxapp_install_idle_handler();
102 if (!win
->HasVMT()) return;
104 win
->m_menuBarDetached
= FALSE
;
105 win
->m_sizeSet
= FALSE
;
108 //-----------------------------------------------------------------------------
109 // "child_detached" of menu bar
110 //-----------------------------------------------------------------------------
112 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
114 if (g_isIdle
) wxapp_install_idle_handler();
116 if (!win
->HasVMT()) return;
118 win
->m_menuBarDetached
= TRUE
;
119 win
->m_sizeSet
= FALSE
;
122 //-----------------------------------------------------------------------------
123 // "child_attached" of tool bar
124 //-----------------------------------------------------------------------------
126 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
128 if (g_isIdle
) wxapp_install_idle_handler();
130 if (!win
->HasVMT()) return;
132 win
->m_toolBarDetached
= FALSE
;
133 win
->m_sizeSet
= FALSE
;
136 //-----------------------------------------------------------------------------
137 // "child_detached" of tool bar
138 //-----------------------------------------------------------------------------
140 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
142 if (g_isIdle
) wxapp_install_idle_handler();
144 if (!win
->HasVMT()) return;
146 win
->m_toolBarDetached
= TRUE
;
147 win
->m_sizeSet
= FALSE
;
150 //-----------------------------------------------------------------------------
152 //-----------------------------------------------------------------------------
154 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
156 if (g_isIdle
) wxapp_install_idle_handler();
158 if (!win
->HasVMT()) return FALSE
;
163 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
164 mevent
.SetEventObject( win
);
165 win
->GetEventHandler()->ProcessEvent( mevent
);
170 //-----------------------------------------------------------------------------
171 // "realize" from m_widget
172 //-----------------------------------------------------------------------------
174 /* we cannot MWM hints and icons before the widget has been realized,
175 so we do this directly after realization */
178 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
180 if (g_isIdle
) wxapp_install_idle_handler();
182 /* all this is for Motif Window Manager "hints" and is supposed to be
183 recognized by other WM as well. not tested. */
184 long decor
= (long) GDK_DECOR_ALL
;
185 long func
= (long) GDK_FUNC_ALL
;
187 if ((win
->m_windowStyle
& wxCAPTION
) == 0)
188 decor
|= GDK_DECOR_TITLE
;
189 /* if ((win->m_windowStyle & wxMINIMIZE) == 0)
190 func |= GDK_FUNC_MINIMIZE;
191 if ((win->m_windowStyle & wxMAXIMIZE) == 0)
192 func |= GDK_FUNC_MAXIMIZE; */
193 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) == 0)
194 decor
|= GDK_DECOR_MENU
;
195 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) == 0)
196 decor
|= GDK_DECOR_MINIMIZE
;
197 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
198 decor
|= GDK_DECOR_MAXIMIZE
;
199 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
200 func
|= GDK_FUNC_RESIZE
;
202 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
203 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
205 /* GTK's shrinking/growing policy */
206 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
207 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
209 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
212 if (win
->m_icon
!= wxNullIcon
)
214 wxIcon
icon( win
->m_icon
);
215 win
->m_icon
= wxNullIcon
;
216 win
->SetIcon( icon
);
222 //-----------------------------------------------------------------------------
223 // InsertChild for wxFrame
224 //-----------------------------------------------------------------------------
226 /* Callback for wxFrame. This very strange beast has to be used because
227 * C++ has no virtual methods in a constructor. We have to emulate a
228 * virtual function here as wxWindows requires different ways to insert
229 * a child in container classes. */
231 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
233 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
235 /* actually, menubars are never inserted here, but this
236 may change one day */
238 /* these are outside the client area */
239 wxFrame
* frame
= (wxFrame
*) parent
;
240 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
241 GTK_WIDGET(child
->m_widget
),
245 /* we connect to these events for recalculating the client area
246 space when the toolbar is floating */
247 if (wxIS_KIND_OF(child
,wxToolBar
))
249 wxToolBar
*toolBar
= (wxToolBar
*) child
;
250 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
252 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
253 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
255 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
256 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
262 /* these are inside the client area */
263 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
264 GTK_WIDGET(child
->m_widget
),
269 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
273 /* resize on OnInternalIdle */
274 parent
->m_sizeSet
= FALSE
;
277 //-----------------------------------------------------------------------------
279 //-----------------------------------------------------------------------------
281 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
282 EVT_SIZE(wxFrame::OnSize
)
283 EVT_CLOSE(wxFrame::OnCloseWindow
)
284 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
287 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
291 m_frameMenuBar
= (wxMenuBar
*) NULL
;
292 m_frameStatusBar
= (wxStatusBar
*) NULL
;
293 m_frameToolBar
= (wxToolBar
*) NULL
;
297 m_mainWidget
= (GtkWidget
*) NULL
;
298 m_menuBarDetached
= FALSE
;
299 m_toolBarDetached
= FALSE
;
300 m_insertCallback
= wxInsertChildInFrame
;
303 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
304 const wxPoint
&pos
, const wxSize
&size
,
305 long style
, const wxString
&name
)
307 m_frameMenuBar
= (wxMenuBar
*) NULL
;
308 m_frameStatusBar
= (wxStatusBar
*) NULL
;
309 m_frameToolBar
= (wxToolBar
*) NULL
;
313 m_mainWidget
= (GtkWidget
*) NULL
;
314 m_menuBarDetached
= FALSE
;
315 m_toolBarDetached
= FALSE
;
316 m_insertCallback
= wxInsertChildInFrame
;
317 Create( parent
, id
, title
, pos
, size
, style
, name
);
320 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
321 const wxPoint
&pos
, const wxSize
&size
,
322 long style
, const wxString
&name
)
324 wxTopLevelWindows
.Append( this );
326 m_needParent
= FALSE
;
328 PreCreation( parent
, id
, pos
, size
, style
, name
);
332 m_insertCallback
= wxInsertChildInFrame
;
334 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
335 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
337 m_widget
= gtk_window_new( win_type
);
339 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
340 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
342 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
343 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
345 /* m_mainWidget holds the toolbar, the menubar and the client area */
346 m_mainWidget
= gtk_myfixed_new();
347 gtk_widget_show( m_mainWidget
);
348 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
349 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
351 /* m_wxwindow only represents the client area without toolbar and menubar */
352 m_wxwindow
= gtk_myfixed_new();
353 gtk_widget_show( m_wxwindow
);
354 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
356 /* we allow the frame to get the focus as otherwise no
357 key events will get sent to it. the point with this is
358 that the menu's key accelerators work by interceting
360 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
361 gtk_widget_grab_focus( m_wxwindow
);
363 if (m_parent
) m_parent
->AddChild( this );
367 /* we cannot set MWM hints and icons before the widget has
368 been realized, so we do this directly after realization */
369 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
370 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
372 /* the user resized the frame by dragging etc. */
373 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
374 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
376 /* the only way to get the window size is to connect to this event */
377 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
378 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
385 if (m_frameMenuBar
) delete m_frameMenuBar
;
386 m_frameMenuBar
= (wxMenuBar
*) NULL
;
388 if (m_frameStatusBar
) delete m_frameStatusBar
;
389 m_frameStatusBar
= (wxStatusBar
*) NULL
;
391 if (m_frameToolBar
) delete m_frameToolBar
;
392 m_frameToolBar
= (wxToolBar
*) NULL
;
394 wxTopLevelWindows
.DeleteObject( this );
396 if (wxTheApp
->GetTopWindow() == this)
397 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
399 if (wxTopLevelWindows
.Number() == 0)
400 wxTheApp
->ExitMainLoop();
403 bool wxFrame::Show( bool show
)
405 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
407 if (show
&& !m_sizeSet
)
409 /* by calling GtkOnSize here, we don't have to call
410 either after showing the frame, which would entail
411 much ugly flicker or from within the size_allocate
412 handler, because GTK 1.1.X forbids that. */
414 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
417 return wxWindow::Show( show
);
420 bool wxFrame::Destroy()
422 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
424 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
429 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
431 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
433 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
434 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
436 /* avoid recursions */
437 if (m_resizing
) return;
442 int old_width
= m_width
;
443 int old_height
= m_height
;
445 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
447 if (x
!= -1) m_x
= x
;
448 if (y
!= -1) m_y
= y
;
449 if (width
!= -1) m_width
= width
;
450 if (height
!= -1) m_height
= height
;
460 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
462 if (width
== -1) m_width
= 80;
465 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
467 if (height
== -1) m_height
= 26;
470 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
471 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
472 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
473 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
475 if ((m_x
!= -1) || (m_y
!= -1))
477 if ((m_x
!= old_x
) || (m_y
!= old_y
))
479 /* we set the size here and in gtk_frame_map_callback */
480 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
484 if ((m_width
!= old_width
) || (m_height
!= old_height
))
486 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
487 done either directly before the frame is shown or in idle time
488 so that different calls to SetSize() don't lead to flicker. */
495 void wxFrame::Centre( int direction
)
497 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
502 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
503 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
508 void wxFrame::GetClientSize( int *width
, int *height
) const
510 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
512 wxWindow::GetClientSize( width
, height
);
518 if (!m_menuBarDetached
)
519 (*height
) -= wxMENU_HEIGHT
;
521 (*height
) -= wxPLACE_HOLDER
;
525 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
530 if (!m_toolBarDetached
)
533 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
537 (*height
) -= wxPLACE_HOLDER
;
541 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
545 (*width
) -= m_miniEdge
*2;
549 void wxFrame::DoSetClientSize( int width
, int height
)
551 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
556 if (!m_menuBarDetached
)
557 height
+= wxMENU_HEIGHT
;
559 height
+= wxPLACE_HOLDER
;
563 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
568 if (!m_toolBarDetached
)
571 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
575 height
+= wxPLACE_HOLDER
;
578 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
581 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
583 // due to a bug in gtk, x,y are always 0
587 /* avoid recursions */
588 if (m_resizing
) return;
591 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
592 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
597 /* space occupied by m_frameToolBar and m_frameMenuBar */
598 int client_area_y_offset
= 0;
600 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
601 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
602 set in wxFrame::Create so it is used to check what kind of frame we
603 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
604 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
605 importantly) m_mainWidget */
609 /* check if size is in legal range */
610 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
611 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
612 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
613 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
615 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
616 * menubar, the toolbar and the client area, which is represented by
618 * this hurts in the eye, but I don't want to call SetSize()
619 * because I don't want to call any non-native functions here. */
624 int yy
= m_miniEdge
+ m_miniTitle
;
625 int ww
= m_width
- 2*m_miniEdge
;
626 int hh
= wxMENU_HEIGHT
;
627 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
628 m_frameMenuBar
->m_x
= xx
;
629 m_frameMenuBar
->m_y
= yy
;
630 m_frameMenuBar
->m_width
= ww
;
631 m_frameMenuBar
->m_height
= hh
;
633 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
634 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
636 client_area_y_offset
+= hh
;
642 int yy
= m_miniEdge
+ m_miniTitle
;
645 if (!m_menuBarDetached
)
648 yy
+= wxPLACE_HOLDER
;
650 int ww
= m_width
- 2*m_miniEdge
;
651 int hh
= m_frameToolBar
->m_height
;
652 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
653 m_frameToolBar
->m_x
= xx
;
654 m_frameToolBar
->m_y
= yy
;
655 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
656 m_frameToolBar
->m_width
= ww
;
658 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
659 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
661 client_area_y_offset
+= hh
;
664 int client_x
= m_miniEdge
;
665 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
666 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
668 int client_w
= m_width
- 2*m_miniEdge
;
669 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
670 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
674 /* if there is no m_mainWidget between m_widget and m_wxwindow there
675 is no need to set the size or position of m_wxwindow. */
678 if (m_frameStatusBar
)
680 int xx
= 0 + m_miniEdge
;
681 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
682 int ww
= m_width
- 2*m_miniEdge
;
683 int hh
= wxSTATUS_HEIGHT
;
685 m_frameStatusBar
->m_x
= xx
;
686 m_frameStatusBar
->m_y
= yy
;
687 m_frameStatusBar
->m_width
= ww
;
688 m_frameStatusBar
->m_height
= hh
;
690 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
691 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
694 /* we actually set the size of a frame here and no-where else */
695 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
699 /* send size event to frame */
700 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
701 event
.SetEventObject( this );
702 GetEventHandler()->ProcessEvent( event
);
704 /* send size event to status bar */
705 if (m_frameStatusBar
)
707 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
708 event2
.SetEventObject( m_frameStatusBar
);
709 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
715 void wxFrame::OnInternalIdle()
717 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
718 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
723 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
728 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
730 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
738 // do we have exactly one child?
739 wxWindow
*child
= (wxWindow
*)NULL
;
740 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
742 wxWindow
*win
= (wxWindow
*)node
->Data();
743 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
747 // it's the second one: do nothing
755 // no children at all?
758 // yes: set it's size to fill all the frame
759 int client_x
, client_y
;
760 GetClientSize( &client_x
, &client_y
);
761 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
766 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
768 menu
->SetInvokingWindow( win
);
769 wxNode
*node
= menu
->GetItems().First();
772 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
773 if (menuitem
->IsSubMenu())
774 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
779 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
781 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
782 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
784 m_frameMenuBar
= menuBar
;
788 /* support for native key accelerators indicated by underscroes */
789 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
790 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
793 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
796 wxMenu
*menu
= (wxMenu
*)node
->Data();
797 SetInvokingWindow( menu
, this );
801 if (m_frameMenuBar
->m_parent
!= this)
803 m_frameMenuBar
->m_parent
= this;
804 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
805 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
807 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
809 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
810 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
812 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
813 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
818 /* resize window in OnInternalIdle */
822 wxMenuBar
*wxFrame::GetMenuBar() const
824 return m_frameMenuBar
;
827 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
831 // if no help string found, we will clear the status bar text
834 int menuId
= event
.GetMenuId();
837 wxMenuBar
*menuBar
= GetMenuBar();
840 helpString
= menuBar
->GetHelpString(menuId
);
844 SetStatusText(helpString
);
848 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
850 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
852 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
854 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
856 GetChildren().DeleteObject( m_frameToolBar
);
860 return m_frameToolBar
;
863 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
865 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
868 wxToolBar
*wxFrame::GetToolBar() const
870 return m_frameToolBar
;
873 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
875 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
877 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
879 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
883 return m_frameStatusBar
;
886 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
888 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
890 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
892 // Set the height according to the font and the border size
893 wxClientDC
dc(statusBar
);
894 dc
.SetFont( statusBar
->GetFont() );
897 dc
.GetTextExtent( "X", &x
, &y
);
899 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
901 statusBar
->SetSize( -1, -1, 100, height
);
903 statusBar
->SetFieldsCount( number
);
907 void wxFrame::Command( int id
)
909 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
910 commandEvent
.SetInt( id
);
911 commandEvent
.SetEventObject( this );
913 wxMenuBar
*bar
= GetMenuBar();
916 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
917 if (item
&& item
->IsCheckable())
919 bar
->Check(id
,!bar
->Checked(id
)) ;
922 wxEvtHandler
* evtHandler
= GetEventHandler();
924 evtHandler
->ProcessEvent(commandEvent
);
927 void wxFrame::SetStatusText(const wxString
& text
, int number
)
929 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
931 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
933 m_frameStatusBar
->SetStatusText(text
, number
);
936 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
938 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
940 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
942 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
945 wxStatusBar
*wxFrame::GetStatusBar() const
947 return m_frameStatusBar
;
950 void wxFrame::SetTitle( const wxString
&title
)
952 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
955 if (m_title
.IsNull()) m_title
= _T("");
956 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
959 void wxFrame::SetIcon( const wxIcon
&icon
)
961 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
964 if (!icon
.Ok()) return;
966 if (!m_widget
->window
) return;
968 wxMask
*mask
= icon
.GetMask();
969 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
970 if (mask
) bm
= mask
->GetBitmap();
972 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);