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 wxList wxPendingDelete
;
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
48 if (!win
->HasVMT()) return;
51 printf( "OnFrameResize from " );
52 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
53 printf( win->GetClassInfo()->GetClassName() );
57 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
59 win
->m_sizeSet
= FALSE
;
60 win
->m_width
= alloc
->width
;
61 win
->m_height
= alloc
->height
;
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
72 printf( "OnDelete from " );
73 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
74 printf( win->GetClassInfo()->GetClassName() );
83 //-----------------------------------------------------------------------------
84 // "child_attached" of menu bar
85 //-----------------------------------------------------------------------------
87 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
89 if (!win
->HasVMT()) return;
91 win
->m_menuBarDetached
= FALSE
;
92 win
->m_sizeSet
= FALSE
;
95 //-----------------------------------------------------------------------------
96 // "child_detached" of menu bar
97 //-----------------------------------------------------------------------------
99 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
101 if (!win
->HasVMT()) return;
103 win
->m_menuBarDetached
= TRUE
;
104 win
->m_sizeSet
= FALSE
;
107 //-----------------------------------------------------------------------------
108 // "child_attached" of tool bar
109 //-----------------------------------------------------------------------------
111 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
113 if (!win
->HasVMT()) return;
115 win
->m_toolBarDetached
= FALSE
;
116 win
->m_sizeSet
= FALSE
;
119 //-----------------------------------------------------------------------------
120 // "child_detached" of tool bar
121 //-----------------------------------------------------------------------------
123 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
125 if (!win
->HasVMT()) return;
127 win
->m_toolBarDetached
= TRUE
;
128 win
->m_sizeSet
= FALSE
;
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
135 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
137 if (!win
->HasVMT()) return FALSE
;
142 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
143 mevent
.SetEventObject( win
);
144 win
->GetEventHandler()->ProcessEvent( mevent
);
149 //-----------------------------------------------------------------------------
150 // "realize" from m_widget
151 //-----------------------------------------------------------------------------
153 /* we cannot MWM hints and icons before the widget has been realized,
154 so we do this directly after realization */
157 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
159 /* all this is for Motif Window Manager "hints" and is supposed to be
160 recognized by other WM as well. not tested. */
161 long decor
= (long) GDK_DECOR_ALL
;
162 long func
= (long) GDK_FUNC_ALL
;
164 if ((win
->m_windowStyle
& wxCAPTION
) == 0)
165 decor
|= GDK_DECOR_TITLE
;
166 /* if ((win->m_windowStyle & wxMINIMIZE) == 0)
167 func |= GDK_FUNC_MINIMIZE;
168 if ((win->m_windowStyle & wxMAXIMIZE) == 0)
169 func |= GDK_FUNC_MAXIMIZE; */
170 if ((win
->m_windowStyle
& wxSYSTEM_MENU
) == 0)
171 decor
|= GDK_DECOR_MENU
;
172 if ((win
->m_windowStyle
& wxMINIMIZE_BOX
) == 0)
173 decor
|= GDK_DECOR_MINIMIZE
;
174 if ((win
->m_windowStyle
& wxMAXIMIZE_BOX
) == 0)
175 decor
|= GDK_DECOR_MAXIMIZE
;
176 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
177 func
|= GDK_FUNC_RESIZE
;
179 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
180 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
182 /* GTK's shrinking/growing policy */
183 if ((win
->m_windowStyle
& wxRESIZE_BORDER
) == 0)
184 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
186 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
189 if (win
->m_icon
!= wxNullIcon
)
191 wxIcon
icon( win
->m_icon
);
192 win
->m_icon
= wxNullIcon
;
193 win
->SetIcon( icon
);
199 //-----------------------------------------------------------------------------
200 // InsertChild for wxFrame
201 //-----------------------------------------------------------------------------
203 /* Callback for wxFrame. This very strange beast has to be used because
204 * C++ has no virtual methods in a constructor. We have to emulate a
205 * virtual function here as wxWindows requires different ways to insert
206 * a child in container classes. */
208 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
210 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
212 /* actually, menubars are never inserted here, but this
213 may change one day */
215 /* these are outside the client area */
216 wxFrame
* frame
= (wxFrame
*) parent
;
217 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
218 GTK_WIDGET(child
->m_widget
),
222 /* we connect to these events for recalculating the client area
223 space when the toolbar is floating */
224 if (wxIS_KIND_OF(child
,wxToolBar
))
226 wxToolBar
*toolBar
= (wxToolBar
*) child
;
227 if (toolBar
->m_windowStyle
& wxTB_DOCKABLE
)
229 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
230 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
232 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
233 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
239 /* these are inside the client area */
240 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
241 GTK_WIDGET(child
->m_widget
),
246 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
250 /* resize on OnInternalIdle */
251 parent
->m_sizeSet
= FALSE
;
253 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
255 /* we now allow a window to get the focus as long as it
256 doesn't have any children. */
257 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
261 //-----------------------------------------------------------------------------
263 //-----------------------------------------------------------------------------
265 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
266 EVT_SIZE(wxFrame::OnSize
)
267 EVT_CLOSE(wxFrame::OnCloseWindow
)
268 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
271 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
275 m_frameMenuBar
= (wxMenuBar
*) NULL
;
276 m_frameStatusBar
= (wxStatusBar
*) NULL
;
277 m_frameToolBar
= (wxToolBar
*) NULL
;
281 m_mainWidget
= (GtkWidget
*) NULL
;
282 m_menuBarDetached
= FALSE
;
283 m_toolBarDetached
= FALSE
;
284 m_insertCallback
= wxInsertChildInFrame
;
287 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
288 const wxPoint
&pos
, const wxSize
&size
,
289 long style
, const wxString
&name
)
291 m_frameMenuBar
= (wxMenuBar
*) NULL
;
292 m_frameStatusBar
= (wxStatusBar
*) NULL
;
293 m_frameToolBar
= (wxToolBar
*) NULL
;
297 m_mainWidget
= (GtkWidget
*) NULL
;
298 m_menuBarDetached
= FALSE
;
299 m_toolBarDetached
= FALSE
;
300 m_insertCallback
= wxInsertChildInFrame
;
301 Create( parent
, id
, title
, pos
, size
, style
, name
);
304 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
305 const wxPoint
&pos
, const wxSize
&size
,
306 long style
, const wxString
&name
)
308 wxTopLevelWindows
.Append( this );
310 m_needParent
= FALSE
;
312 PreCreation( parent
, id
, pos
, size
, style
, name
);
316 m_insertCallback
= wxInsertChildInFrame
;
318 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
319 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
321 m_widget
= gtk_window_new( win_type
);
323 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
324 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
326 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
327 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
329 /* m_mainWidget holds the toolbar, the menubar and the client area */
330 m_mainWidget
= gtk_myfixed_new();
331 gtk_widget_show( m_mainWidget
);
332 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
333 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
335 /* m_wxwindow only represents the client area without toolbar and menubar */
336 m_wxwindow
= gtk_myfixed_new();
337 gtk_widget_show( m_wxwindow
);
338 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
339 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
341 if (m_parent
) m_parent
->AddChild( this );
345 /* we cannot set MWM hints and icons before the widget has
346 been realized, so we do this directly after realization */
347 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
348 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
350 /* the user resized the frame by dragging etc. */
351 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
352 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
354 /* the only way to get the window size is to connect to this event */
355 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
356 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
363 if (m_frameMenuBar
) delete m_frameMenuBar
;
364 m_frameMenuBar
= (wxMenuBar
*) NULL
;
366 if (m_frameStatusBar
) delete m_frameStatusBar
;
367 m_frameStatusBar
= (wxStatusBar
*) NULL
;
369 if (m_frameToolBar
) delete m_frameToolBar
;
370 m_frameToolBar
= (wxToolBar
*) NULL
;
372 wxTopLevelWindows
.DeleteObject( this );
374 if (wxTheApp
->GetTopWindow() == this)
375 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
377 if (wxTopLevelWindows
.Number() == 0)
378 wxTheApp
->ExitMainLoop();
381 bool wxFrame::Show( bool show
)
383 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
385 if (show
&& !m_sizeSet
)
387 /* by calling GtkOnSize here, we don't have to call
388 either after showing the frame, which would entail
389 much ugly flicker or from within the size_allocate
390 handler, because GTK 1.1.X forbids that. */
392 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
395 return wxWindow::Show( show
);
398 bool wxFrame::Destroy()
400 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
402 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
407 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
409 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
411 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
412 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
414 /* avoid recursions */
415 if (m_resizing
) return;
420 int old_width
= m_width
;
421 int old_height
= m_height
;
423 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
425 if (x
!= -1) m_x
= x
;
426 if (y
!= -1) m_y
= y
;
427 if (width
!= -1) m_width
= width
;
428 if (height
!= -1) m_height
= height
;
438 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
440 if (width
== -1) m_width
= 80;
443 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
445 if (height
== -1) m_height
= 26;
448 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
449 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
450 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
451 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
453 if ((m_x
!= -1) || (m_y
!= -1))
455 if ((m_x
!= old_x
) || (m_y
!= old_y
))
457 /* m_sizeSet = FALSE; */
458 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
462 if ((m_width
!= old_width
) || (m_height
!= old_height
))
464 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
465 done either directly before the frame is shown or in idle time
466 so that different calls to SetSize() don't lead to flicker. */
473 void wxFrame::Centre( int direction
)
475 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
480 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
481 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
486 void wxFrame::GetClientSize( int *width
, int *height
) const
488 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
490 wxWindow::GetClientSize( width
, height
);
496 if (!m_menuBarDetached
)
497 (*height
) -= wxMENU_HEIGHT
;
499 (*height
) -= wxPLACE_HOLDER
;
503 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
508 if (!m_toolBarDetached
)
511 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
515 (*height
) -= wxPLACE_HOLDER
;
519 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
523 (*width
) -= m_miniEdge
*2;
527 void wxFrame::DoSetClientSize( int width
, int height
)
529 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
534 if (!m_menuBarDetached
)
535 height
+= wxMENU_HEIGHT
;
537 height
+= wxPLACE_HOLDER
;
541 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
546 if (!m_toolBarDetached
)
549 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
553 height
+= wxPLACE_HOLDER
;
556 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
559 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
561 // due to a bug in gtk, x,y are always 0
565 /* avoid recursions */
566 if (m_resizing
) return;
569 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
570 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
575 /* space occupied by m_frameToolBar and m_frameMenuBar */
576 int client_area_y_offset
= 0;
578 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
579 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
580 set in wxFrame::Create so it is used to check what kind of frame we
581 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
582 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
583 importantly) m_mainWidget */
587 /* check if size is in legal range */
588 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
589 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
590 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
591 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
593 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
594 * menubar, the toolbar and the client area, which is represented by
596 * this hurts in the eye, but I don't want to call SetSize()
597 * because I don't want to call any non-native functions here. */
602 int yy
= m_miniEdge
+ m_miniTitle
;
603 int ww
= m_width
- 2*m_miniEdge
;
604 int hh
= wxMENU_HEIGHT
;
605 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
606 m_frameMenuBar
->m_x
= xx
;
607 m_frameMenuBar
->m_y
= yy
;
608 m_frameMenuBar
->m_width
= ww
;
609 m_frameMenuBar
->m_height
= hh
;
611 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameMenuBar
->m_widget
, xx
, yy
);
612 gtk_widget_set_usize( m_frameMenuBar
->m_widget
, ww
, hh
);
614 client_area_y_offset
+= hh
;
620 int yy
= m_miniEdge
+ m_miniTitle
;
623 if (!m_menuBarDetached
)
626 yy
+= wxPLACE_HOLDER
;
628 int ww
= m_width
- 2*m_miniEdge
;
629 int hh
= m_frameToolBar
->m_height
;
630 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
631 m_frameToolBar
->m_x
= xx
;
632 m_frameToolBar
->m_y
= yy
;
633 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
634 m_frameToolBar
->m_width
= ww
;
636 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_frameToolBar
->m_widget
, xx
, yy
);
637 gtk_widget_set_usize( m_frameToolBar
->m_widget
, ww
, hh
);
639 client_area_y_offset
+= hh
;
642 int client_x
= m_miniEdge
;
643 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
644 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget
), m_wxwindow
, client_x
, client_y
);
646 int client_w
= m_width
- 2*m_miniEdge
;
647 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
648 gtk_widget_set_usize( m_wxwindow
, client_w
, client_h
);
652 /* if there is no m_mainWidget between m_widget and m_wxwindow there
653 is no need to set the size or position of m_wxwindow. */
656 if (m_frameStatusBar
)
658 int xx
= 0 + m_miniEdge
;
659 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
660 int ww
= m_width
- 2*m_miniEdge
;
661 int hh
= wxSTATUS_HEIGHT
;
663 m_frameStatusBar
->m_x
= xx
;
664 m_frameStatusBar
->m_y
= yy
;
665 m_frameStatusBar
->m_width
= ww
;
666 m_frameStatusBar
->m_height
= hh
;
668 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow
), m_frameStatusBar
->m_widget
, xx
, yy
);
669 gtk_widget_set_usize( m_frameStatusBar
->m_widget
, ww
, hh
);
672 /* we actually set the size of a frame here and no-where else */
673 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
677 /* send size event to frame */
678 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
679 event
.SetEventObject( this );
680 GetEventHandler()->ProcessEvent( event
);
682 /* send size event to status bar */
683 if (m_frameStatusBar
)
685 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
686 event2
.SetEventObject( m_frameStatusBar
);
687 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
693 void wxFrame::OnInternalIdle()
696 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
701 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
706 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
708 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
716 // do we have exactly one child?
717 wxWindow
*child
= (wxWindow
*)NULL
;
718 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
720 wxWindow
*win
= (wxWindow
*)node
->Data();
721 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
725 // it's the second one: do nothing
733 // no children at all?
736 // yes: set it's size to fill all the frame
737 int client_x
, client_y
;
738 GetClientSize( &client_x
, &client_y
);
739 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
744 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
746 menu
->SetInvokingWindow( win
);
747 wxNode
*node
= menu
->GetItems().First();
750 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
751 if (menuitem
->IsSubMenu())
752 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
757 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
759 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
760 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
762 m_frameMenuBar
= menuBar
;
766 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
769 wxMenu
*menu
= (wxMenu
*)node
->Data();
770 SetInvokingWindow( menu
, this );
774 if (m_frameMenuBar
->m_parent
!= this)
776 m_frameMenuBar
->m_parent
= this;
777 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
778 m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y
);
780 if (menuBar
->m_windowStyle
& wxMB_DOCKABLE
)
782 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
783 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
785 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
786 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
794 wxMenuBar
*wxFrame::GetMenuBar() const
796 return m_frameMenuBar
;
799 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
803 // if no help string found, we will clear the status bar text
806 int menuId
= event
.GetMenuId();
809 wxMenuBar
*menuBar
= GetMenuBar();
812 helpString
= menuBar
->GetHelpString(menuId
);
816 SetStatusText(helpString
);
820 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
822 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
824 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
826 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
828 GetChildren().DeleteObject( m_frameToolBar
);
832 return m_frameToolBar
;
835 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
837 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
840 wxToolBar
*wxFrame::GetToolBar() const
842 return m_frameToolBar
;
845 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
847 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
849 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
851 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
855 return m_frameStatusBar
;
858 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
860 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
862 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
864 // Set the height according to the font and the border size
865 wxClientDC
dc(statusBar
);
866 dc
.SetFont( statusBar
->GetFont() );
869 dc
.GetTextExtent( "X", &x
, &y
);
871 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
873 statusBar
->SetSize( -1, -1, 100, height
);
875 statusBar
->SetFieldsCount( number
);
879 void wxFrame::Command( int id
)
881 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
882 commandEvent
.SetInt( id
);
883 commandEvent
.SetEventObject( this );
885 wxMenuBar
*bar
= GetMenuBar();
888 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
889 if (item
&& item
->IsCheckable())
891 bar
->Check(id
,!bar
->Checked(id
)) ;
894 wxEvtHandler
* evtHandler
= GetEventHandler();
896 evtHandler
->ProcessEvent(commandEvent
);
899 void wxFrame::SetStatusText(const wxString
& text
, int number
)
901 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
903 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
905 m_frameStatusBar
->SetStatusText(text
, number
);
908 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
910 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
912 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
914 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
917 wxStatusBar
*wxFrame::GetStatusBar() const
919 return m_frameStatusBar
;
922 void wxFrame::SetTitle( const wxString
&title
)
924 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
927 if (m_title
.IsNull()) m_title
= _T("");
928 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
931 void wxFrame::SetIcon( const wxIcon
&icon
)
933 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
936 if (!icon
.Ok()) return;
938 if (!m_widget
->window
) return;
940 wxMask
*mask
= icon
.GetMask();
941 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
942 if (mask
) bm
= mask
->GetBitmap();
944 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);