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) 0;
195 long func
= (long) GDK_FUNC_MOVE
|GDK_FUNC_CLOSE
;
197 if ((win
->m_windowStyle
& wxCAPTION
) != 0)
198 decor
|= GDK_DECOR_TITLE
;
199 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) != 0)
201 decor
|= GDK_DECOR_MENU
;
202 func
|= GDK_FUNC_CLOSE
;
204 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) != 0)
206 func
|= GDK_FUNC_MINIMIZE
;
207 decor
|= GDK_DECOR_MINIMIZE
;
208 decor
|= GDK_DECOR_BORDER
;
210 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) != 0)
212 func
|= GDK_FUNC_MAXIMIZE
;
213 decor
|= GDK_DECOR_MAXIMIZE
;
214 decor
|= GDK_DECOR_BORDER
;
216 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) != 0)
218 func
|= GDK_FUNC_RESIZE
;
219 decor
|= GDK_DECOR_RESIZEH
;
220 decor
|= GDK_DECOR_BORDER
;
224 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
225 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
227 /* GTK's shrinking/growing policy */
228 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
229 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
231 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
234 if (win
->m_icon
!= wxNullIcon
)
236 wxIcon
icon( win
->m_icon
);
237 win
->m_icon
= wxNullIcon
;
238 win
->SetIcon( icon
);
241 /* we set the focus to the child that accepts the focus. this
242 doesn't really have to be done in "realize" but why not? */
243 wxNode
*node
= win
->m_children
.First();
246 wxWindow
*child
= (wxWindow
*) node
->Data();
247 if (child
->AcceptsFocus())
259 //-----------------------------------------------------------------------------
260 // InsertChild for wxFrame
261 //-----------------------------------------------------------------------------
263 /* Callback for wxFrame. This very strange beast has to be used because
264 * C++ has no virtual methods in a constructor. We have to emulate a
265 * virtual function here as wxWindows requires different ways to insert
266 * a child in container classes. */
268 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
270 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
272 /* actually, menubars are never inserted here, but this
273 may change one day */
275 /* these are outside the client area */
276 wxFrame
* frame
= (wxFrame
*) parent
;
277 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
278 GTK_WIDGET(child
->m_widget
),
284 /* we connect to these events for recalculating the client area
285 space when the toolbar is floating */
286 if (wxIS_KIND_OF(child
,wxToolBar
))
288 wxToolBar
*toolBar
= (wxToolBar
*) child
;
289 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
291 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
292 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
294 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
295 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
301 /* these are inside the client area */
302 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
303 GTK_WIDGET(child
->m_widget
),
310 /* resize on OnInternalIdle */
311 parent
->m_sizeSet
= FALSE
;
314 //-----------------------------------------------------------------------------
316 //-----------------------------------------------------------------------------
318 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
319 EVT_SIZE(wxFrame::OnSize
)
320 EVT_CLOSE(wxFrame::OnCloseWindow
)
321 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
324 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
328 m_frameMenuBar
= (wxMenuBar
*) NULL
;
329 m_frameStatusBar
= (wxStatusBar
*) NULL
;
330 m_frameToolBar
= (wxToolBar
*) NULL
;
334 m_mainWidget
= (GtkWidget
*) NULL
;
335 m_menuBarDetached
= FALSE
;
336 m_toolBarDetached
= FALSE
;
337 m_insertCallback
= wxInsertChildInFrame
;
340 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
341 const wxPoint
&pos
, const wxSize
&size
,
342 long style
, const wxString
&name
)
344 m_frameMenuBar
= (wxMenuBar
*) NULL
;
345 m_frameStatusBar
= (wxStatusBar
*) NULL
;
346 m_frameToolBar
= (wxToolBar
*) NULL
;
350 m_mainWidget
= (GtkWidget
*) NULL
;
351 m_menuBarDetached
= FALSE
;
352 m_toolBarDetached
= FALSE
;
353 m_insertCallback
= wxInsertChildInFrame
;
354 Create( parent
, id
, title
, pos
, size
, style
, name
);
357 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
358 const wxPoint
&pos
, const wxSize
&size
,
359 long style
, const wxString
&name
)
361 wxTopLevelWindows
.Append( this );
363 m_needParent
= FALSE
;
365 PreCreation( parent
, id
, pos
, size
, style
, name
);
369 m_insertCallback
= wxInsertChildInFrame
;
371 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
372 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
374 m_widget
= gtk_window_new( win_type
);
377 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
380 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
381 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
383 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
384 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
386 /* m_mainWidget holds the toolbar, the menubar and the client area */
387 m_mainWidget
= gtk_myfixed_new();
388 gtk_widget_show( m_mainWidget
);
389 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
390 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
393 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
396 /* m_wxwindow only represents the client area without toolbar and menubar */
397 m_wxwindow
= gtk_myfixed_new();
398 gtk_widget_show( m_wxwindow
);
399 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
402 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
405 /* we donm't allow the frame to get the focus as otherwise
406 the frame will grabit at arbitrary fcous changes. */
407 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
409 if (m_parent
) m_parent
->AddChild( this );
413 /* we cannot set MWM hints and icons before the widget has
414 been realized, so we do this directly after realization */
415 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
416 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
418 /* the user resized the frame by dragging etc. */
419 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
420 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
422 /* the only way to get the window size is to connect to this event */
423 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
424 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
431 if (m_frameMenuBar
) delete m_frameMenuBar
;
432 m_frameMenuBar
= (wxMenuBar
*) NULL
;
434 if (m_frameStatusBar
) delete m_frameStatusBar
;
435 m_frameStatusBar
= (wxStatusBar
*) NULL
;
437 if (m_frameToolBar
) delete m_frameToolBar
;
438 m_frameToolBar
= (wxToolBar
*) NULL
;
440 wxTopLevelWindows
.DeleteObject( this );
442 if (wxTheApp
->GetTopWindow() == this)
443 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
445 if (wxTopLevelWindows
.Number() == 0)
446 wxTheApp
->ExitMainLoop();
449 bool wxFrame::Show( bool show
)
451 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
453 if (show
&& !m_sizeSet
)
455 /* by calling GtkOnSize here, we don't have to call
456 either after showing the frame, which would entail
457 much ugly flicker or from within the size_allocate
458 handler, because GTK 1.1.X forbids that. */
460 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
463 return wxWindow::Show( show
);
466 bool wxFrame::Destroy()
468 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
470 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
475 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
477 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
479 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
480 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
482 /* avoid recursions */
483 if (m_resizing
) return;
488 int old_width
= m_width
;
489 int old_height
= m_height
;
491 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
493 if (x
!= -1) m_x
= x
;
494 if (y
!= -1) m_y
= y
;
495 if (width
!= -1) m_width
= width
;
496 if (height
!= -1) m_height
= height
;
506 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
508 if (width
== -1) m_width
= 80;
511 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
513 if (height
== -1) m_height
= 26;
516 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
517 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
518 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
519 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
521 if ((m_x
!= -1) || (m_y
!= -1))
523 if ((m_x
!= old_x
) || (m_y
!= old_y
))
525 /* we set the size here and in gtk_frame_map_callback */
526 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
530 if ((m_width
!= old_width
) || (m_height
!= old_height
))
532 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
533 done either directly before the frame is shown or in idle time
534 so that different calls to SetSize() don't lead to flicker. */
541 void wxFrame::Centre( int direction
)
543 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
548 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
549 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
554 void wxFrame::GetClientSize( int *width
, int *height
) const
556 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
558 wxWindow::GetClientSize( width
, height
);
564 if (!m_menuBarDetached
)
565 (*height
) -= wxMENU_HEIGHT
;
567 (*height
) -= wxPLACE_HOLDER
;
571 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
576 if (!m_toolBarDetached
)
579 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
583 (*height
) -= wxPLACE_HOLDER
;
587 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
591 (*width
) -= m_miniEdge
*2;
595 void wxFrame::DoSetClientSize( int width
, int height
)
597 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
602 if (!m_menuBarDetached
)
603 height
+= wxMENU_HEIGHT
;
605 height
+= wxPLACE_HOLDER
;
609 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
614 if (!m_toolBarDetached
)
617 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
621 height
+= wxPLACE_HOLDER
;
624 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
627 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
629 // due to a bug in gtk, x,y are always 0
633 /* avoid recursions */
634 if (m_resizing
) return;
637 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
638 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
643 /* space occupied by m_frameToolBar and m_frameMenuBar */
644 int client_area_y_offset
= 0;
646 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
647 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
648 set in wxFrame::Create so it is used to check what kind of frame we
649 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
650 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
651 importantly) m_mainWidget */
655 /* check if size is in legal range */
656 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
657 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
658 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
659 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
661 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
662 * menubar, the toolbar and the client area, which is represented by
664 * this hurts in the eye, but I don't want to call SetSize()
665 * because I don't want to call any non-native functions here. */
670 int yy
= m_miniEdge
+ m_miniTitle
;
671 int ww
= m_width
- 2*m_miniEdge
;
672 int hh
= wxMENU_HEIGHT
;
673 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
674 m_frameMenuBar
->m_x
= xx
;
675 m_frameMenuBar
->m_y
= yy
;
676 m_frameMenuBar
->m_width
= ww
;
677 m_frameMenuBar
->m_height
= hh
;
678 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
679 m_frameMenuBar
->m_widget
,
681 client_area_y_offset
+= hh
;
687 int yy
= m_miniEdge
+ m_miniTitle
;
690 if (!m_menuBarDetached
)
693 yy
+= wxPLACE_HOLDER
;
695 int ww
= m_width
- 2*m_miniEdge
;
696 int hh
= m_frameToolBar
->m_height
;
697 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
698 m_frameToolBar
->m_x
= xx
;
699 m_frameToolBar
->m_y
= yy
;
700 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
701 m_frameToolBar
->m_width
= ww
;
702 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
703 m_frameToolBar
->m_widget
,
705 client_area_y_offset
+= hh
;
708 int client_x
= m_miniEdge
;
709 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
710 int client_w
= m_width
- 2*m_miniEdge
;
711 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
712 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
714 client_x
, client_y
, client_w
, client_h
);
718 /* if there is no m_mainWidget between m_widget and m_wxwindow there
719 is no need to set the size or position of m_wxwindow. */
722 if (m_frameStatusBar
)
724 int xx
= 0 + m_miniEdge
;
725 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
726 int ww
= m_width
- 2*m_miniEdge
;
727 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
;
732 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
733 m_frameStatusBar
->m_widget
,
737 /* we actually set the size of a frame here and no-where else */
738 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
742 /* send size event to frame */
743 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
744 event
.SetEventObject( this );
745 GetEventHandler()->ProcessEvent( event
);
747 /* send size event to status bar */
748 if (m_frameStatusBar
)
750 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
751 event2
.SetEventObject( m_frameStatusBar
);
752 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
758 void wxFrame::OnInternalIdle()
760 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
761 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
766 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
771 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
773 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
781 /* do we have exactly one child? */
782 wxWindow
*child
= (wxWindow
*)NULL
;
783 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
785 wxWindow
*win
= (wxWindow
*)node
->Data();
786 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
790 /* it's the second one: do nothing */
798 /* no children at all? */
801 /* yes: set it's size to fill all the frame */
802 int client_x
, client_y
;
803 GetClientSize( &client_x
, &client_y
);
804 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
809 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
811 menu
->SetInvokingWindow( win
);
813 #if (GTK_MINOR_VERSION > 0)
814 /* support for native hot keys */
815 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
818 wxNode
*node
= menu
->GetItems().First();
821 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
822 if (menuitem
->IsSubMenu())
823 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
828 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
830 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
831 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
833 m_frameMenuBar
= menuBar
;
837 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
838 /* support for native key accelerators indicated by underscroes */
839 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
842 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
845 wxMenu
*menu
= (wxMenu
*)node
->Data();
846 SetInvokingWindow( menu
, this );
850 if (m_frameMenuBar
->m_parent
!= this)
852 m_frameMenuBar
->m_parent
= this;
853 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
854 m_frameMenuBar
->m_widget
,
857 m_frameMenuBar
->m_width
,
858 m_frameMenuBar
->m_height
);
860 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
862 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
863 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
865 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
866 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
871 /* resize window in OnInternalIdle */
875 wxMenuBar
*wxFrame::GetMenuBar() const
877 return m_frameMenuBar
;
880 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
884 // if no help string found, we will clear the status bar text
887 int menuId
= event
.GetMenuId();
890 wxMenuBar
*menuBar
= GetMenuBar();
893 helpString
= menuBar
->GetHelpString(menuId
);
897 SetStatusText(helpString
);
901 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
903 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
905 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
907 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
909 GetChildren().DeleteObject( m_frameToolBar
);
913 return m_frameToolBar
;
916 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
918 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
921 wxToolBar
*wxFrame::GetToolBar() const
923 return m_frameToolBar
;
926 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
928 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
930 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
932 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
936 return m_frameStatusBar
;
939 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
941 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
943 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
945 // Set the height according to the font and the border size
946 wxClientDC
dc(statusBar
);
947 dc
.SetFont( statusBar
->GetFont() );
950 dc
.GetTextExtent( "X", &x
, &y
);
952 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
954 statusBar
->SetSize( -1, -1, 100, height
);
956 statusBar
->SetFieldsCount( number
);
960 void wxFrame::Command( int id
)
962 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
963 commandEvent
.SetInt( id
);
964 commandEvent
.SetEventObject( this );
966 wxMenuBar
*bar
= GetMenuBar();
969 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
970 if (item
&& item
->IsCheckable())
972 bar
->Check(id
,!bar
->Checked(id
)) ;
975 wxEvtHandler
* evtHandler
= GetEventHandler();
977 evtHandler
->ProcessEvent(commandEvent
);
980 void wxFrame::SetStatusText(const wxString
& text
, int number
)
982 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
984 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
986 m_frameStatusBar
->SetStatusText(text
, number
);
989 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
991 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
993 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
995 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
998 wxStatusBar
*wxFrame::GetStatusBar() const
1000 return m_frameStatusBar
;
1003 void wxFrame::SetTitle( const wxString
&title
)
1005 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1008 if (m_title
.IsNull()) m_title
= _T("");
1009 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1012 void wxFrame::SetIcon( const wxIcon
&icon
)
1014 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1017 if (!icon
.Ok()) return;
1019 if (!m_widget
->window
) return;
1021 wxMask
*mask
= icon
.GetMask();
1022 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1023 if (mask
) bm
= mask
->GetBitmap();
1025 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);