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"
27 #include "gdk/gdkkeysyms.h"
29 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
33 const int wxMENU_HEIGHT
= 27;
34 const int wxSTATUS_HEIGHT
= 25;
35 const int wxPLACE_HOLDER
= 0;
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 extern void wxapp_install_idle_handler();
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
48 extern wxList wxPendingDelete
;
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
56 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
60 //-----------------------------------------------------------------------------
62 //-----------------------------------------------------------------------------
64 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
67 wxapp_install_idle_handler();
69 if (!win
->m_hasVMT
) return;
71 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
73 win
->m_width
= alloc
->width
;
74 win
->m_height
= alloc
->height
;
79 //-----------------------------------------------------------------------------
81 //-----------------------------------------------------------------------------
83 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
86 wxapp_install_idle_handler();
93 //-----------------------------------------------------------------------------
94 // "child_attached" of menu bar
95 //-----------------------------------------------------------------------------
97 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
99 if (!win
->m_hasVMT
) return;
101 win
->m_menuBarDetached
= FALSE
;
105 //-----------------------------------------------------------------------------
106 // "child_detached" of menu bar
107 //-----------------------------------------------------------------------------
109 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
111 if (!win
->m_hasVMT
) return;
113 win
->m_menuBarDetached
= TRUE
;
117 //-----------------------------------------------------------------------------
118 // "child_attached" of tool bar
119 //-----------------------------------------------------------------------------
121 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
123 if (!win
->m_hasVMT
) return;
125 win
->m_toolBarDetached
= FALSE
;
130 //-----------------------------------------------------------------------------
131 // "child_detached" of tool bar
132 //-----------------------------------------------------------------------------
134 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
137 wxapp_install_idle_handler();
139 if (!win
->m_hasVMT
) return;
141 win
->m_toolBarDetached
= TRUE
;
145 //-----------------------------------------------------------------------------
147 //-----------------------------------------------------------------------------
149 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
152 wxapp_install_idle_handler();
154 if (!win
->m_hasVMT
) return FALSE
;
159 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
160 mevent
.SetEventObject( win
);
161 win
->GetEventHandler()->ProcessEvent( mevent
);
166 //-----------------------------------------------------------------------------
167 // "realize" from m_widget
168 //-----------------------------------------------------------------------------
170 /* we cannot MWM hints and icons before the widget has been realized,
171 so we do this directly after realization */
174 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
177 wxapp_install_idle_handler();
179 /* all this is for Motif Window Manager "hints" and is supposed to be
180 recognized by other WM as well. not tested. */
181 long decor
= (long) GDK_DECOR_BORDER
;
182 long func
= (long) GDK_FUNC_MOVE
;
184 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
185 decor
|= GDK_DECOR_TITLE
;
186 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
188 decor
|= GDK_DECOR_MENU
;
189 func
|= GDK_FUNC_CLOSE
;
191 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
193 func
|= GDK_FUNC_MINIMIZE
;
194 decor
|= GDK_DECOR_MINIMIZE
;
196 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
198 func
|= GDK_FUNC_MAXIMIZE
;
199 decor
|= GDK_DECOR_MAXIMIZE
;
201 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
203 func
|= GDK_FUNC_RESIZE
;
204 decor
|= GDK_DECOR_RESIZEH
;
208 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
209 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
211 /* GTK's shrinking/growing policy */
212 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
213 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
215 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
218 if (win
->m_icon
!= wxNullIcon
)
220 wxIcon
icon( win
->m_icon
);
221 win
->m_icon
= wxNullIcon
;
222 win
->SetIcon( icon
);
225 /* we set the focus to the child that accepts the focus. this
226 doesn't really have to be done in "realize" but why not? */
227 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
230 wxWindow
*child
= node
->GetData();
231 if (child
->AcceptsFocus())
237 node
= node
->GetNext();
243 //-----------------------------------------------------------------------------
244 // InsertChild for wxFrame
245 //-----------------------------------------------------------------------------
247 /* Callback for wxFrame. This very strange beast has to be used because
248 * C++ has no virtual methods in a constructor. We have to emulate a
249 * virtual function here as wxWindows requires different ways to insert
250 * a child in container classes. */
252 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
254 if (!parent
->m_insertInClientArea
)
256 /* these are outside the client area */
257 wxFrame
* frame
= (wxFrame
*) parent
;
258 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
259 GTK_WIDGET(child
->m_widget
),
265 /* we connect to these events for recalculating the client area
266 space when the toolbar is floating */
267 if (wxIS_KIND_OF(child
,wxToolBar
))
269 wxToolBar
*toolBar
= (wxToolBar
*) child
;
270 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
272 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
273 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
275 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
276 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
282 /* these are inside the client area */
283 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
284 GTK_WIDGET(child
->m_widget
),
291 /* resize on OnInternalIdle */
292 parent
->UpdateSize();
295 //-----------------------------------------------------------------------------
297 //-----------------------------------------------------------------------------
299 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
300 EVT_SIZE(wxFrame::OnSize
)
301 EVT_CLOSE(wxFrame::OnCloseWindow
)
302 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
305 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
309 m_frameMenuBar
= (wxMenuBar
*) NULL
;
310 m_frameStatusBar
= (wxStatusBar
*) NULL
;
311 m_frameToolBar
= (wxToolBar
*) NULL
;
315 m_mainWidget
= (GtkWidget
*) NULL
;
316 m_menuBarDetached
= FALSE
;
317 m_toolBarDetached
= FALSE
;
318 m_insertInClientArea
= TRUE
;
321 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
322 const wxPoint
&pos
, const wxSize
&size
,
323 long style
, const wxString
&name
)
327 Create( parent
, id
, title
, pos
, size
, style
, name
);
330 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
331 const wxPoint
&pos
, const wxSize
&size
,
332 long style
, const wxString
&name
)
334 wxTopLevelWindows
.Append( this );
336 m_needParent
= FALSE
;
338 PreCreation( parent
, id
, pos
, size
, style
, name
);
342 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
344 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
345 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
347 m_widget
= gtk_window_new( win_type
);
350 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
353 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
356 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
357 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
359 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
360 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
362 /* m_mainWidget holds the toolbar, the menubar and the client area */
363 m_mainWidget
= gtk_myfixed_new();
364 gtk_widget_show( m_mainWidget
);
365 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
366 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
369 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
372 /* m_wxwindow only represents the client area without toolbar and menubar */
373 m_wxwindow
= gtk_myfixed_new();
374 gtk_widget_show( m_wxwindow
);
375 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
378 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
381 /* we donm't allow the frame to get the focus as otherwise
382 the frame will grabit at arbitrary fcous changes. */
383 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
385 if (m_parent
) m_parent
->AddChild( this );
389 /* we cannot set MWM hints and icons before the widget has
390 been realized, so we do this directly after realization */
391 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
392 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
394 /* the user resized the frame by dragging etc. */
395 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
396 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
398 /* the only way to get the window size is to connect to this event */
399 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
400 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
407 m_isBeingDeleted
= TRUE
;
409 if (m_frameMenuBar
) delete m_frameMenuBar
;
410 m_frameMenuBar
= (wxMenuBar
*) NULL
;
412 if (m_frameStatusBar
) delete m_frameStatusBar
;
413 m_frameStatusBar
= (wxStatusBar
*) NULL
;
415 if (m_frameToolBar
) delete m_frameToolBar
;
416 m_frameToolBar
= (wxToolBar
*) NULL
;
418 wxTopLevelWindows
.DeleteObject( this );
420 if (wxTheApp
->GetTopWindow() == this)
421 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
423 if (wxTopLevelWindows
.Number() == 0)
424 wxTheApp
->ExitMainLoop();
427 bool wxFrame::Show( bool show
)
429 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
431 if (show
&& !m_sizeSet
)
433 /* by calling GtkOnSize here, we don't have to call
434 either after showing the frame, which would entail
435 much ugly flicker or from within the size_allocate
436 handler, because GTK 1.1.X forbids that. */
438 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
441 return wxWindow::Show( show
);
444 bool wxFrame::Destroy()
446 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
448 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
453 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
455 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
457 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
458 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
460 /* avoid recursions */
461 if (m_resizing
) return;
466 int old_width
= m_width
;
467 int old_height
= m_height
;
469 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
471 if (x
!= -1) m_x
= x
;
472 if (y
!= -1) m_y
= y
;
473 if (width
!= -1) m_width
= width
;
474 if (height
!= -1) m_height
= height
;
484 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
486 if (width
== -1) m_width
= 80;
489 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
491 if (height
== -1) m_height
= 26;
494 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
495 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
496 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
497 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
499 if ((m_x
!= -1) || (m_y
!= -1))
501 if ((m_x
!= old_x
) || (m_y
!= old_y
))
503 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
507 if ((m_width
!= old_width
) || (m_height
!= old_height
))
509 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
510 done either directly before the frame is shown or in idle time
511 so that different calls to SetSize() don't lead to flicker. */
518 void wxFrame::Centre( int direction
)
520 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
525 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
526 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
531 void wxFrame::DoGetClientSize( int *width
, int *height
) const
533 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
535 wxWindow::DoGetClientSize( width
, height
);
541 if (!m_menuBarDetached
)
542 (*height
) -= wxMENU_HEIGHT
;
544 (*height
) -= wxPLACE_HOLDER
;
548 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
553 if (!m_toolBarDetached
)
556 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
560 (*height
) -= wxPLACE_HOLDER
;
564 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
568 (*width
) -= m_miniEdge
*2;
572 void wxFrame::DoSetClientSize( int width
, int height
)
574 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
579 if (!m_menuBarDetached
)
580 height
+= wxMENU_HEIGHT
;
582 height
+= wxPLACE_HOLDER
;
586 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
591 if (!m_toolBarDetached
)
594 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
598 height
+= wxPLACE_HOLDER
;
601 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
604 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
606 // due to a bug in gtk, x,y are always 0
610 /* avoid recursions */
611 if (m_resizing
) return;
614 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
615 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
620 /* space occupied by m_frameToolBar and m_frameMenuBar */
621 int client_area_y_offset
= 0;
623 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
624 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
625 set in wxFrame::Create so it is used to check what kind of frame we
626 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
627 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
628 importantly) m_mainWidget */
632 /* check if size is in legal range */
633 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
634 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
635 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
636 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
638 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
639 * menubar, the toolbar and the client area, which is represented by
641 * this hurts in the eye, but I don't want to call SetSize()
642 * because I don't want to call any non-native functions here. */
647 int yy
= m_miniEdge
+ m_miniTitle
;
648 int ww
= m_width
- 2*m_miniEdge
;
649 int hh
= wxMENU_HEIGHT
;
650 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
651 m_frameMenuBar
->m_x
= xx
;
652 m_frameMenuBar
->m_y
= yy
;
653 m_frameMenuBar
->m_width
= ww
;
654 m_frameMenuBar
->m_height
= hh
;
655 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
656 m_frameMenuBar
->m_widget
,
658 client_area_y_offset
+= hh
;
664 int yy
= m_miniEdge
+ m_miniTitle
;
667 if (!m_menuBarDetached
)
670 yy
+= wxPLACE_HOLDER
;
672 int ww
= m_width
- 2*m_miniEdge
;
673 int hh
= m_frameToolBar
->m_height
;
674 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
675 m_frameToolBar
->m_x
= xx
;
676 m_frameToolBar
->m_y
= yy
;
677 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
678 m_frameToolBar
->m_width
= ww
;
679 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
680 m_frameToolBar
->m_widget
,
682 client_area_y_offset
+= hh
;
685 int client_x
= m_miniEdge
;
686 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
687 int client_w
= m_width
- 2*m_miniEdge
;
688 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
689 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
691 client_x
, client_y
, client_w
, client_h
);
695 /* if there is no m_mainWidget between m_widget and m_wxwindow there
696 is no need to set the size or position of m_wxwindow. */
699 if (m_frameStatusBar
)
701 int xx
= 0 + m_miniEdge
;
702 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
703 int ww
= m_width
- 2*m_miniEdge
;
704 int hh
= wxSTATUS_HEIGHT
;
705 m_frameStatusBar
->m_x
= xx
;
706 m_frameStatusBar
->m_y
= yy
;
707 m_frameStatusBar
->m_width
= ww
;
708 m_frameStatusBar
->m_height
= hh
;
709 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
710 m_frameStatusBar
->m_widget
,
714 /* we actually set the size of a frame here and no-where else */
715 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
719 /* send size event to frame */
720 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
721 event
.SetEventObject( this );
722 GetEventHandler()->ProcessEvent( event
);
724 /* send size event to status bar */
725 if (m_frameStatusBar
)
727 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
728 event2
.SetEventObject( m_frameStatusBar
);
729 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
735 void wxFrame::MakeModal( bool modal
)
738 gtk_grab_add( m_widget
);
740 gtk_grab_remove( m_widget
);
743 void wxFrame::OnInternalIdle()
745 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
746 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
750 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
751 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
752 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
755 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
760 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
762 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
770 /* do we have exactly one child? */
771 wxWindow
*child
= (wxWindow
*)NULL
;
772 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
774 wxWindow
*win
= (wxWindow
*)node
->Data();
775 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
779 /* it's the second one: do nothing */
787 /* no children at all? */
790 /* yes: set it's size to fill all the frame */
791 int client_x
, client_y
;
792 DoGetClientSize( &client_x
, &client_y
);
793 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
798 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
800 menu
->SetInvokingWindow( win
);
802 #if (GTK_MINOR_VERSION > 0)
803 /* support for native hot keys */
804 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
807 wxNode
*node
= menu
->GetItems().First();
810 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
811 if (menuitem
->IsSubMenu())
812 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
817 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
819 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
820 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
822 m_frameMenuBar
= menuBar
;
826 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
827 /* support for native key accelerators indicated by underscroes */
828 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
831 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
834 wxMenu
*menu
= (wxMenu
*)node
->Data();
835 SetInvokingWindow( menu
, this );
839 if (m_frameMenuBar
->GetParent() != this)
841 m_frameMenuBar
->SetParent(this);
842 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
843 m_frameMenuBar
->m_widget
,
846 m_frameMenuBar
->m_width
,
847 m_frameMenuBar
->m_height
);
849 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
851 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
852 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
854 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
855 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
860 /* resize window in OnInternalIdle */
864 wxMenuBar
*wxFrame::GetMenuBar() const
866 return m_frameMenuBar
;
869 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
873 // if no help string found, we will clear the status bar text
876 int menuId
= event
.GetMenuId();
879 wxMenuBar
*menuBar
= GetMenuBar();
882 helpString
= menuBar
->GetHelpString(menuId
);
886 SetStatusText(helpString
);
890 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
892 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
894 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
896 m_insertInClientArea
= FALSE
;
898 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
900 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
902 m_insertInClientArea
= TRUE
;
906 return m_frameToolBar
;
909 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
911 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
914 wxToolBar
*wxFrame::GetToolBar() const
916 return m_frameToolBar
;
919 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
921 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
923 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
925 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
929 return m_frameStatusBar
;
932 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
934 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
936 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
938 // Set the height according to the font and the border size
939 wxClientDC
dc(statusBar
);
940 dc
.SetFont( statusBar
->GetFont() );
943 dc
.GetTextExtent( "X", &x
, &y
);
945 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
947 statusBar
->SetSize( -1, -1, 100, height
);
949 statusBar
->SetFieldsCount( number
);
953 void wxFrame::Command( int id
)
955 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
956 commandEvent
.SetInt( id
);
957 commandEvent
.SetEventObject( this );
959 wxMenuBar
*bar
= GetMenuBar();
962 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
963 if (item
&& item
->IsCheckable())
965 bar
->Check(id
,!bar
->Checked(id
)) ;
968 wxEvtHandler
* evtHandler
= GetEventHandler();
970 evtHandler
->ProcessEvent(commandEvent
);
973 void wxFrame::SetStatusText(const wxString
& text
, int number
)
975 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
977 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
979 m_frameStatusBar
->SetStatusText(text
, number
);
982 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
984 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
986 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
988 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
991 wxStatusBar
*wxFrame::GetStatusBar() const
993 return m_frameStatusBar
;
996 void wxFrame::SetTitle( const wxString
&title
)
998 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1001 if (m_title
.IsNull()) m_title
= _T("");
1002 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1005 void wxFrame::SetIcon( const wxIcon
&icon
)
1007 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1010 if (!icon
.Ok()) return;
1012 if (!m_widget
->window
) return;
1014 wxMask
*mask
= icon
.GetMask();
1015 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1016 if (mask
) bm
= mask
->GetBitmap();
1018 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);