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 //-----------------------------------------------------------------------------
55 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
59 //-----------------------------------------------------------------------------
61 //-----------------------------------------------------------------------------
63 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
65 if (g_isIdle
) wxapp_install_idle_handler();
67 if (!win
->HasVMT()) return;
70 printf( "OnFrameResize from " );
71 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
72 printf( win->GetClassInfo()->GetClassName() );
76 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
78 win
->m_sizeSet
= FALSE
;
79 win
->m_width
= alloc
->width
;
80 win
->m_height
= alloc
->height
;
84 //-----------------------------------------------------------------------------
86 //-----------------------------------------------------------------------------
88 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
90 if (g_isIdle
) wxapp_install_idle_handler();
93 printf( "OnDelete from " );
94 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
95 printf( win->GetClassInfo()->GetClassName() );
104 //-----------------------------------------------------------------------------
105 // "child_attached" of menu bar
106 //-----------------------------------------------------------------------------
108 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
110 if (g_isIdle
) wxapp_install_idle_handler();
112 if (!win
->HasVMT()) return;
114 win
->m_menuBarDetached
= FALSE
;
115 win
->m_sizeSet
= FALSE
;
118 //-----------------------------------------------------------------------------
119 // "child_detached" of menu bar
120 //-----------------------------------------------------------------------------
122 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
124 if (g_isIdle
) wxapp_install_idle_handler();
126 if (!win
->HasVMT()) return;
128 win
->m_menuBarDetached
= TRUE
;
129 win
->m_sizeSet
= FALSE
;
132 //-----------------------------------------------------------------------------
133 // "child_attached" of tool bar
134 //-----------------------------------------------------------------------------
136 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
138 if (g_isIdle
) wxapp_install_idle_handler();
140 if (!win
->HasVMT()) return;
142 win
->m_toolBarDetached
= FALSE
;
143 win
->m_sizeSet
= FALSE
;
146 //-----------------------------------------------------------------------------
147 // "child_detached" of tool bar
148 //-----------------------------------------------------------------------------
150 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
152 if (g_isIdle
) wxapp_install_idle_handler();
154 if (!win
->HasVMT()) return;
156 win
->m_toolBarDetached
= TRUE
;
157 win
->m_sizeSet
= FALSE
;
160 //-----------------------------------------------------------------------------
162 //-----------------------------------------------------------------------------
164 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
166 if (g_isIdle
) wxapp_install_idle_handler();
168 if (!win
->HasVMT()) return FALSE
;
173 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
174 mevent
.SetEventObject( win
);
175 win
->GetEventHandler()->ProcessEvent( mevent
);
180 //-----------------------------------------------------------------------------
181 // "realize" from m_widget
182 //-----------------------------------------------------------------------------
184 /* we cannot MWM hints and icons before the widget has been realized,
185 so we do this directly after realization */
188 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
190 if (g_isIdle
) wxapp_install_idle_handler();
192 /* all this is for Motif Window Manager "hints" and is supposed to be
193 recognized by other WM as well. not tested. */
194 long decor
= (long) GDK_DECOR_ALL
;
195 long func
= (long) GDK_FUNC_ALL
;
197 if ((win
->m_windowStyle
& wxCAPTION
) == 0)
198 decor
|= GDK_DECOR_TITLE
;
199 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) == 0)
200 decor
|= GDK_DECOR_MENU
;
201 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) == 0)
203 func
|= GDK_FUNC_MINIMIZE
;
204 decor
|= GDK_DECOR_MINIMIZE
;
206 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
208 func
|= GDK_FUNC_MAXIMIZE
;
209 decor
|= GDK_DECOR_MAXIMIZE
;
211 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
212 func
|= GDK_FUNC_RESIZE
;
214 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
215 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
217 /* GTK's shrinking/growing policy */
218 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
219 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
221 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
224 if (win
->m_icon
!= wxNullIcon
)
226 wxIcon
icon( win
->m_icon
);
227 win
->m_icon
= wxNullIcon
;
228 win
->SetIcon( icon
);
231 /* we set the focus to the child that accepts the focus. this
232 doesn't really have to be done in "realize" but why not? */
233 wxNode
*node
= win
->m_children
.First();
236 wxWindow
*child
= (wxWindow
*) node
->Data();
237 if (child
->AcceptsFocus())
249 //-----------------------------------------------------------------------------
250 // InsertChild for wxFrame
251 //-----------------------------------------------------------------------------
253 /* Callback for wxFrame. This very strange beast has to be used because
254 * C++ has no virtual methods in a constructor. We have to emulate a
255 * virtual function here as wxWindows requires different ways to insert
256 * a child in container classes. */
258 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
260 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
262 /* actually, menubars are never inserted here, but this
263 may change one day */
265 /* these are outside the client area */
266 wxFrame
* frame
= (wxFrame
*) parent
;
267 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
268 GTK_WIDGET(child
->m_widget
),
272 /* we connect to these events for recalculating the client area
273 space when the toolbar is floating */
274 if (wxIS_KIND_OF(child
,wxToolBar
))
276 wxToolBar
*toolBar
= (wxToolBar
*) child
;
277 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
279 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
280 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
282 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
283 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
289 /* these are inside the client area */
290 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
291 GTK_WIDGET(child
->m_widget
),
296 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
300 /* resize on OnInternalIdle */
301 parent
->m_sizeSet
= FALSE
;
304 //-----------------------------------------------------------------------------
306 //-----------------------------------------------------------------------------
308 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
309 EVT_SIZE(wxFrame::OnSize
)
310 EVT_CLOSE(wxFrame::OnCloseWindow
)
311 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
314 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
318 m_frameMenuBar
= (wxMenuBar
*) NULL
;
319 m_frameStatusBar
= (wxStatusBar
*) NULL
;
320 m_frameToolBar
= (wxToolBar
*) NULL
;
324 m_mainWidget
= (GtkWidget
*) NULL
;
325 m_menuBarDetached
= FALSE
;
326 m_toolBarDetached
= FALSE
;
327 m_insertCallback
= wxInsertChildInFrame
;
330 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
331 const wxPoint
&pos
, const wxSize
&size
,
332 long style
, const wxString
&name
)
334 m_frameMenuBar
= (wxMenuBar
*) NULL
;
335 m_frameStatusBar
= (wxStatusBar
*) NULL
;
336 m_frameToolBar
= (wxToolBar
*) NULL
;
340 m_mainWidget
= (GtkWidget
*) NULL
;
341 m_menuBarDetached
= FALSE
;
342 m_toolBarDetached
= FALSE
;
343 m_insertCallback
= wxInsertChildInFrame
;
344 Create( parent
, id
, title
, pos
, size
, style
, name
);
347 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
348 const wxPoint
&pos
, const wxSize
&size
,
349 long style
, const wxString
&name
)
351 wxTopLevelWindows
.Append( this );
353 m_needParent
= FALSE
;
355 PreCreation( parent
, id
, pos
, size
, style
, name
);
359 m_insertCallback
= wxInsertChildInFrame
;
361 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
362 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
364 m_widget
= gtk_window_new( win_type
);
367 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
370 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
371 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
373 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
374 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
376 /* m_mainWidget holds the toolbar, the menubar and the client area */
377 m_mainWidget
= gtk_myfixed_new();
378 gtk_widget_show( m_mainWidget
);
379 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
380 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
383 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
386 /* m_wxwindow only represents the client area without toolbar and menubar */
387 m_wxwindow
= gtk_myfixed_new();
388 gtk_widget_show( m_wxwindow
);
389 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
392 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
395 /* we donm't allow the frame to get the focus as otherwise
396 the frame will grabit at arbitrary fcous changes. */
397 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
399 if (m_parent
) m_parent
->AddChild( this );
403 /* we cannot set MWM hints and icons before the widget has
404 been realized, so we do this directly after realization */
405 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
406 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
408 /* the user resized the frame by dragging etc. */
409 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
410 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
412 /* the only way to get the window size is to connect to this event */
413 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
414 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
421 if (m_frameMenuBar
) delete m_frameMenuBar
;
422 m_frameMenuBar
= (wxMenuBar
*) NULL
;
424 if (m_frameStatusBar
) delete m_frameStatusBar
;
425 m_frameStatusBar
= (wxStatusBar
*) NULL
;
427 if (m_frameToolBar
) delete m_frameToolBar
;
428 m_frameToolBar
= (wxToolBar
*) NULL
;
430 wxTopLevelWindows
.DeleteObject( this );
432 if (wxTheApp
->GetTopWindow() == this)
433 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
435 if (wxTopLevelWindows
.Number() == 0)
436 wxTheApp
->ExitMainLoop();
439 bool wxFrame::Show( bool show
)
441 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
443 if (show
&& !m_sizeSet
)
445 /* by calling GtkOnSize here, we don't have to call
446 either after showing the frame, which would entail
447 much ugly flicker or from within the size_allocate
448 handler, because GTK 1.1.X forbids that. */
450 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
453 return wxWindow::Show( show
);
456 bool wxFrame::Destroy()
458 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
460 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
465 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
467 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
469 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
470 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
472 /* avoid recursions */
473 if (m_resizing
) return;
478 int old_width
= m_width
;
479 int old_height
= m_height
;
481 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
483 if (x
!= -1) m_x
= x
;
484 if (y
!= -1) m_y
= y
;
485 if (width
!= -1) m_width
= width
;
486 if (height
!= -1) m_height
= height
;
496 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
498 if (width
== -1) m_width
= 80;
501 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
503 if (height
== -1) m_height
= 26;
506 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
507 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
508 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
509 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
511 if ((m_x
!= -1) || (m_y
!= -1))
513 if ((m_x
!= old_x
) || (m_y
!= old_y
))
515 /* we set the size here and in gtk_frame_map_callback */
516 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
520 if ((m_width
!= old_width
) || (m_height
!= old_height
))
522 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
523 done either directly before the frame is shown or in idle time
524 so that different calls to SetSize() don't lead to flicker. */
531 void wxFrame::Centre( int direction
)
533 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
538 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
539 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
544 void wxFrame::GetClientSize( int *width
, int *height
) const
546 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
548 wxWindow::GetClientSize( width
, height
);
554 if (!m_menuBarDetached
)
555 (*height
) -= wxMENU_HEIGHT
;
557 (*height
) -= wxPLACE_HOLDER
;
561 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
566 if (!m_toolBarDetached
)
569 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
573 (*height
) -= wxPLACE_HOLDER
;
577 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
581 (*width
) -= m_miniEdge
*2;
585 void wxFrame::DoSetClientSize( int width
, int height
)
587 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
592 if (!m_menuBarDetached
)
593 height
+= wxMENU_HEIGHT
;
595 height
+= wxPLACE_HOLDER
;
599 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
604 if (!m_toolBarDetached
)
607 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
611 height
+= wxPLACE_HOLDER
;
614 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
617 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
619 // due to a bug in gtk, x,y are always 0
623 /* avoid recursions */
624 if (m_resizing
) return;
627 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
628 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
633 /* space occupied by m_frameToolBar and m_frameMenuBar */
634 int client_area_y_offset
= 0;
636 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
637 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
638 set in wxFrame::Create so it is used to check what kind of frame we
639 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
640 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
641 importantly) m_mainWidget */
645 /* check if size is in legal range */
646 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
647 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
648 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
649 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
651 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
652 * menubar, the toolbar and the client area, which is represented by
654 * this hurts in the eye, but I don't want to call SetSize()
655 * because I don't want to call any non-native functions here. */
660 int yy
= m_miniEdge
+ m_miniTitle
;
661 int ww
= m_width
- 2*m_miniEdge
;
662 int hh
= wxMENU_HEIGHT
;
663 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
664 m_frameMenuBar
->m_x
= xx
;
665 m_frameMenuBar
->m_y
= yy
;
666 m_frameMenuBar
->m_width
= ww
;
667 m_frameMenuBar
->m_height
= hh
;
669 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
671 // m_frameMenuBar->m_widget->requisition.width = ww;
672 // m_frameMenuBar->m_widget->requisition.height = hh;
673 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
675 client_area_y_offset
+= hh
;
681 int yy
= m_miniEdge
+ m_miniTitle
;
684 if (!m_menuBarDetached
)
687 yy
+= wxPLACE_HOLDER
;
689 int ww
= m_width
- 2*m_miniEdge
;
690 int hh
= m_frameToolBar
->m_height
;
691 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
692 m_frameToolBar
->m_x
= xx
;
693 m_frameToolBar
->m_y
= yy
;
694 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
695 m_frameToolBar
->m_width
= ww
;
697 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
699 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
701 client_area_y_offset
+= hh
;
704 int client_x
= m_miniEdge
;
705 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
706 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
708 int client_w
= m_width
- 2*m_miniEdge
;
709 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
710 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
712 alloc
.x
= client_x
; alloc
.y
= client_y
; alloc
.width
= client_w
; alloc
.height
= client_h
;
713 gtk_widget_size_allocate( m_wxwindow
, &alloc
);
717 /* if there is no m_mainWidget between m_widget and m_wxwindow there
718 is no need to set the size or position of m_wxwindow. */
721 if (m_frameStatusBar
)
723 int xx
= 0 + m_miniEdge
;
724 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
725 int ww
= m_width
- 2*m_miniEdge
;
726 int hh
= wxSTATUS_HEIGHT
;
728 m_frameStatusBar
->m_x
= xx
;
729 m_frameStatusBar
->m_y
= yy
;
730 m_frameStatusBar
->m_width
= ww
;
731 m_frameStatusBar
->m_height
= hh
;
733 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
735 // m_frameStatusBar->m_widget->requisition.width = ww;
736 // m_frameStatusBar->m_widget->requisition.height = hh;
737 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
740 /* we actually set the size of a frame here and no-where else */
741 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
745 /* send size event to frame */
746 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
747 event
.SetEventObject( this );
748 GetEventHandler()->ProcessEvent( event
);
750 /* send size event to status bar */
751 if (m_frameStatusBar
)
753 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
754 event2
.SetEventObject( m_frameStatusBar
);
755 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
761 void wxFrame::OnInternalIdle()
763 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
764 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
769 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
774 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
776 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
784 /* do we have exactly one child? */
785 wxWindow
*child
= (wxWindow
*)NULL
;
786 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
788 wxWindow
*win
= (wxWindow
*)node
->Data();
789 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
793 /* it's the second one: do nothing */
801 /* no children at all? */
804 /* yes: set it's size to fill all the frame */
805 int client_x
, client_y
;
806 GetClientSize( &client_x
, &client_y
);
807 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
812 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
814 menu
->SetInvokingWindow( win
);
816 #if (GTK_MINOR_VERSION > 0)
817 /* support for native hot keys */
818 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
821 wxNode
*node
= menu
->GetItems().First();
824 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
825 if (menuitem
->IsSubMenu())
826 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
831 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
833 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
834 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
836 m_frameMenuBar
= menuBar
;
840 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
841 /* support for native key accelerators indicated by underscroes */
842 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
845 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
848 wxMenu
*menu
= (wxMenu
*)node
->Data();
849 SetInvokingWindow( menu
, this );
853 if (m_frameMenuBar
->m_parent
!= this)
855 m_frameMenuBar
->m_parent
= this;
856 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
857 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
859 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
861 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
862 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
864 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
865 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
870 /* resize window in OnInternalIdle */
874 wxMenuBar
*wxFrame::GetMenuBar() const
876 return m_frameMenuBar
;
879 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
883 // if no help string found, we will clear the status bar text
886 int menuId
= event
.GetMenuId();
889 wxMenuBar
*menuBar
= GetMenuBar();
892 helpString
= menuBar
->GetHelpString(menuId
);
896 SetStatusText(helpString
);
900 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
902 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
904 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
906 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
908 GetChildren().DeleteObject( m_frameToolBar
);
912 return m_frameToolBar
;
915 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
917 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
920 wxToolBar
*wxFrame::GetToolBar() const
922 return m_frameToolBar
;
925 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
927 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
929 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
931 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
935 return m_frameStatusBar
;
938 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
940 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
942 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
944 // Set the height according to the font and the border size
945 wxClientDC
dc(statusBar
);
946 dc
.SetFont( statusBar
->GetFont() );
949 dc
.GetTextExtent( "X", &x
, &y
);
951 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
953 statusBar
->SetSize( -1, -1, 100, height
);
955 statusBar
->SetFieldsCount( number
);
959 void wxFrame::Command( int id
)
961 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
962 commandEvent
.SetInt( id
);
963 commandEvent
.SetEventObject( this );
965 wxMenuBar
*bar
= GetMenuBar();
968 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
969 if (item
&& item
->IsCheckable())
971 bar
->Check(id
,!bar
->Checked(id
)) ;
974 wxEvtHandler
* evtHandler
= GetEventHandler();
976 evtHandler
->ProcessEvent(commandEvent
);
979 void wxFrame::SetStatusText(const wxString
& text
, int number
)
981 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
983 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
985 m_frameStatusBar
->SetStatusText(text
, number
);
988 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
990 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
992 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
994 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
997 wxStatusBar
*wxFrame::GetStatusBar() const
999 return m_frameStatusBar
;
1002 void wxFrame::SetTitle( const wxString
&title
)
1004 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1007 if (m_title
.IsNull()) m_title
= _T("");
1008 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1011 void wxFrame::SetIcon( const wxIcon
&icon
)
1013 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1016 if (!icon
.Ok()) return;
1018 if (!m_widget
->window
) return;
1020 wxMask
*mask
= icon
.GetMask();
1021 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1022 if (mask
) bm
= mask
->GetBitmap();
1024 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);