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( wxWindow
* parent
, wxWindow
* child
)
254 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
256 /* actually, menubars are never inserted here, but this
257 may change one day */
259 /* these are outside the client area */
260 wxFrame
* frame
= (wxFrame
*) parent
;
261 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
262 GTK_WIDGET(child
->m_widget
),
268 /* we connect to these events for recalculating the client area
269 space when the toolbar is floating */
270 if (wxIS_KIND_OF(child
,wxToolBar
))
272 wxToolBar
*toolBar
= (wxToolBar
*) child
;
273 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
275 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
276 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
278 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
279 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
285 /* these are inside the client area */
286 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
287 GTK_WIDGET(child
->m_widget
),
294 /* resize on OnInternalIdle */
295 parent
->UpdateSize();
298 //-----------------------------------------------------------------------------
300 //-----------------------------------------------------------------------------
302 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
303 EVT_SIZE(wxFrame::OnSize
)
304 EVT_CLOSE(wxFrame::OnCloseWindow
)
305 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
308 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
312 m_frameMenuBar
= (wxMenuBar
*) NULL
;
313 m_frameStatusBar
= (wxStatusBar
*) NULL
;
314 m_frameToolBar
= (wxToolBar
*) NULL
;
318 m_mainWidget
= (GtkWidget
*) NULL
;
319 m_menuBarDetached
= FALSE
;
320 m_toolBarDetached
= FALSE
;
321 m_insertCallback
= wxInsertChildInFrame
;
324 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
325 const wxPoint
&pos
, const wxSize
&size
,
326 long style
, const wxString
&name
)
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
;
338 Create( parent
, id
, title
, pos
, size
, style
, name
);
341 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
342 const wxPoint
&pos
, const wxSize
&size
,
343 long style
, const wxString
&name
)
345 wxTopLevelWindows
.Append( this );
347 m_needParent
= FALSE
;
349 PreCreation( parent
, id
, pos
, size
, style
, name
);
353 m_insertCallback
= wxInsertChildInFrame
;
355 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
356 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
358 m_widget
= gtk_window_new( win_type
);
361 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
364 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
367 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
368 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
370 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
371 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
373 /* m_mainWidget holds the toolbar, the menubar and the client area */
374 m_mainWidget
= gtk_myfixed_new();
375 gtk_widget_show( m_mainWidget
);
376 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
377 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
380 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
383 /* m_wxwindow only represents the client area without toolbar and menubar */
384 m_wxwindow
= gtk_myfixed_new();
385 gtk_widget_show( m_wxwindow
);
386 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
389 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
392 /* we donm't allow the frame to get the focus as otherwise
393 the frame will grabit at arbitrary fcous changes. */
394 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
396 if (m_parent
) m_parent
->AddChild( this );
400 /* we cannot set MWM hints and icons before the widget has
401 been realized, so we do this directly after realization */
402 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
403 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
405 /* the user resized the frame by dragging etc. */
406 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
407 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
409 /* the only way to get the window size is to connect to this event */
410 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
411 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
418 m_isBeingDeleted
= TRUE
;
420 if (m_frameMenuBar
) delete m_frameMenuBar
;
421 m_frameMenuBar
= (wxMenuBar
*) NULL
;
423 if (m_frameStatusBar
) delete m_frameStatusBar
;
424 m_frameStatusBar
= (wxStatusBar
*) NULL
;
426 if (m_frameToolBar
) delete m_frameToolBar
;
427 m_frameToolBar
= (wxToolBar
*) NULL
;
429 wxTopLevelWindows
.DeleteObject( this );
431 if (wxTheApp
->GetTopWindow() == this)
432 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
434 if (wxTopLevelWindows
.Number() == 0)
435 wxTheApp
->ExitMainLoop();
438 bool wxFrame::Show( bool show
)
440 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
442 if (show
&& !m_sizeSet
)
444 /* by calling GtkOnSize here, we don't have to call
445 either after showing the frame, which would entail
446 much ugly flicker or from within the size_allocate
447 handler, because GTK 1.1.X forbids that. */
449 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
452 return wxWindow::Show( show
);
455 bool wxFrame::Destroy()
457 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
459 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
464 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
466 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
468 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
469 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
471 /* avoid recursions */
472 if (m_resizing
) return;
477 int old_width
= m_width
;
478 int old_height
= m_height
;
480 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
482 if (x
!= -1) m_x
= x
;
483 if (y
!= -1) m_y
= y
;
484 if (width
!= -1) m_width
= width
;
485 if (height
!= -1) m_height
= height
;
495 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
497 if (width
== -1) m_width
= 80;
500 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
502 if (height
== -1) m_height
= 26;
505 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
506 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
507 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
508 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
510 if ((m_x
!= -1) || (m_y
!= -1))
512 if ((m_x
!= old_x
) || (m_y
!= old_y
))
514 /* we set the size here and in gtk_frame_map_callback */
515 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
519 if ((m_width
!= old_width
) || (m_height
!= old_height
))
521 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
522 done either directly before the frame is shown or in idle time
523 so that different calls to SetSize() don't lead to flicker. */
530 void wxFrame::Centre( int direction
)
532 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
537 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
538 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
543 void wxFrame::DoGetClientSize( int *width
, int *height
) const
545 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
547 wxWindow::DoGetClientSize( width
, height
);
553 if (!m_menuBarDetached
)
554 (*height
) -= wxMENU_HEIGHT
;
556 (*height
) -= wxPLACE_HOLDER
;
560 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
565 if (!m_toolBarDetached
)
568 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
572 (*height
) -= wxPLACE_HOLDER
;
576 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
580 (*width
) -= m_miniEdge
*2;
584 void wxFrame::DoSetClientSize( int width
, int height
)
586 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
591 if (!m_menuBarDetached
)
592 height
+= wxMENU_HEIGHT
;
594 height
+= wxPLACE_HOLDER
;
598 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
603 if (!m_toolBarDetached
)
606 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
610 height
+= wxPLACE_HOLDER
;
613 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
616 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
618 // due to a bug in gtk, x,y are always 0
622 /* avoid recursions */
623 if (m_resizing
) return;
626 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
627 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
632 /* space occupied by m_frameToolBar and m_frameMenuBar */
633 int client_area_y_offset
= 0;
635 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
636 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
637 set in wxFrame::Create so it is used to check what kind of frame we
638 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
639 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
640 importantly) m_mainWidget */
644 /* check if size is in legal range */
645 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
646 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
647 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
648 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
650 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
651 * menubar, the toolbar and the client area, which is represented by
653 * this hurts in the eye, but I don't want to call SetSize()
654 * because I don't want to call any non-native functions here. */
659 int yy
= m_miniEdge
+ m_miniTitle
;
660 int ww
= m_width
- 2*m_miniEdge
;
661 int hh
= wxMENU_HEIGHT
;
662 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
663 m_frameMenuBar
->m_x
= xx
;
664 m_frameMenuBar
->m_y
= yy
;
665 m_frameMenuBar
->m_width
= ww
;
666 m_frameMenuBar
->m_height
= hh
;
667 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
668 m_frameMenuBar
->m_widget
,
670 client_area_y_offset
+= hh
;
676 int yy
= m_miniEdge
+ m_miniTitle
;
679 if (!m_menuBarDetached
)
682 yy
+= wxPLACE_HOLDER
;
684 int ww
= m_width
- 2*m_miniEdge
;
685 int hh
= m_frameToolBar
->m_height
;
686 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
687 m_frameToolBar
->m_x
= xx
;
688 m_frameToolBar
->m_y
= yy
;
689 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
690 m_frameToolBar
->m_width
= ww
;
691 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
692 m_frameToolBar
->m_widget
,
694 client_area_y_offset
+= hh
;
697 int client_x
= m_miniEdge
;
698 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
699 int client_w
= m_width
- 2*m_miniEdge
;
700 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
701 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
703 client_x
, client_y
, client_w
, client_h
);
707 /* if there is no m_mainWidget between m_widget and m_wxwindow there
708 is no need to set the size or position of m_wxwindow. */
711 if (m_frameStatusBar
)
713 int xx
= 0 + m_miniEdge
;
714 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
715 int ww
= m_width
- 2*m_miniEdge
;
716 int hh
= wxSTATUS_HEIGHT
;
717 m_frameStatusBar
->m_x
= xx
;
718 m_frameStatusBar
->m_y
= yy
;
719 m_frameStatusBar
->m_width
= ww
;
720 m_frameStatusBar
->m_height
= hh
;
721 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
722 m_frameStatusBar
->m_widget
,
726 /* we actually set the size of a frame here and no-where else */
727 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
731 /* send size event to frame */
732 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
733 event
.SetEventObject( this );
734 GetEventHandler()->ProcessEvent( event
);
736 /* send size event to status bar */
737 if (m_frameStatusBar
)
739 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
740 event2
.SetEventObject( m_frameStatusBar
);
741 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
747 void wxFrame::OnInternalIdle()
749 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
750 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
755 void wxFrame::OnCloseWindow( wxCloseEvent
& 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 GetClientSize( &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_frameToolBar
= OnCreateToolBar( style
, id
, name
);
898 GetChildren().DeleteObject( m_frameToolBar
);
902 return m_frameToolBar
;
905 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
907 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
910 wxToolBar
*wxFrame::GetToolBar() const
912 return m_frameToolBar
;
915 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
917 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
919 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
921 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
925 return m_frameStatusBar
;
928 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
930 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
932 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
934 // Set the height according to the font and the border size
935 wxClientDC
dc(statusBar
);
936 dc
.SetFont( statusBar
->GetFont() );
939 dc
.GetTextExtent( "X", &x
, &y
);
941 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
943 statusBar
->SetSize( -1, -1, 100, height
);
945 statusBar
->SetFieldsCount( number
);
949 void wxFrame::Command( int id
)
951 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
952 commandEvent
.SetInt( id
);
953 commandEvent
.SetEventObject( this );
955 wxMenuBar
*bar
= GetMenuBar();
958 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
959 if (item
&& item
->IsCheckable())
961 bar
->Check(id
,!bar
->Checked(id
)) ;
964 wxEvtHandler
* evtHandler
= GetEventHandler();
966 evtHandler
->ProcessEvent(commandEvent
);
969 void wxFrame::SetStatusText(const wxString
& text
, int number
)
971 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
973 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
975 m_frameStatusBar
->SetStatusText(text
, number
);
978 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
980 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
982 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
984 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
987 wxStatusBar
*wxFrame::GetStatusBar() const
989 return m_frameStatusBar
;
992 void wxFrame::SetTitle( const wxString
&title
)
994 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
997 if (m_title
.IsNull()) m_title
= _T("");
998 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1001 void wxFrame::SetIcon( const wxIcon
&icon
)
1003 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1006 if (!icon
.Ok()) return;
1008 if (!m_widget
->window
) return;
1010 wxMask
*mask
= icon
.GetMask();
1011 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1012 if (mask
) bm
= mask
->GetBitmap();
1014 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);