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
->m_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
->InternalSetSize( alloc
->width
, alloc
->height
);
82 //-----------------------------------------------------------------------------
84 //-----------------------------------------------------------------------------
86 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
88 if (g_isIdle
) wxapp_install_idle_handler();
91 printf( "OnDelete from " );
92 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
93 printf( win->GetClassInfo()->GetClassName() );
102 //-----------------------------------------------------------------------------
103 // "child_attached" of menu bar
104 //-----------------------------------------------------------------------------
106 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
108 if (g_isIdle
) wxapp_install_idle_handler();
110 if (!win
->m_hasVMT
) return;
112 win
->m_menuBarDetached
= FALSE
;
116 //-----------------------------------------------------------------------------
117 // "child_detached" of menu bar
118 //-----------------------------------------------------------------------------
120 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
122 if (g_isIdle
) wxapp_install_idle_handler();
124 if (!win
->m_hasVMT
) return;
126 win
->m_menuBarDetached
= TRUE
;
130 //-----------------------------------------------------------------------------
131 // "child_attached" of tool bar
132 //-----------------------------------------------------------------------------
134 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
136 if (g_isIdle
) wxapp_install_idle_handler();
138 if (!win
->m_hasVMT
) return;
140 win
->m_toolBarDetached
= FALSE
;
144 //-----------------------------------------------------------------------------
145 // "child_detached" of tool bar
146 //-----------------------------------------------------------------------------
148 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
150 if (g_isIdle
) wxapp_install_idle_handler();
152 if (!win
->m_hasVMT
) return;
154 win
->m_toolBarDetached
= TRUE
;
158 //-----------------------------------------------------------------------------
160 //-----------------------------------------------------------------------------
162 static gint
gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
164 if (g_isIdle
) wxapp_install_idle_handler();
166 if (!win
->m_hasVMT
) return FALSE
;
168 win
->InternalSetPosition(event
->x
, event
->y
);
170 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
171 mevent
.SetEventObject( win
);
172 win
->GetEventHandler()->ProcessEvent( mevent
);
177 //-----------------------------------------------------------------------------
178 // "realize" from m_widget
179 //-----------------------------------------------------------------------------
181 /* we cannot MWM hints and icons before the widget has been realized,
182 so we do this directly after realization */
185 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
187 if (g_isIdle
) wxapp_install_idle_handler();
189 /* all this is for Motif Window Manager "hints" and is supposed to be
190 recognized by other WM as well. not tested. */
191 long decor
= (long) GDK_DECOR_BORDER
;
192 long func
= (long) GDK_FUNC_MOVE
;
194 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
195 decor
|= GDK_DECOR_TITLE
;
196 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
198 decor
|= GDK_DECOR_MENU
;
199 func
|= GDK_FUNC_CLOSE
;
201 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
203 func
|= GDK_FUNC_MINIMIZE
;
204 decor
|= GDK_DECOR_MINIMIZE
;
206 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
208 func
|= GDK_FUNC_MAXIMIZE
;
209 decor
|= GDK_DECOR_MAXIMIZE
;
211 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
213 func
|= GDK_FUNC_RESIZE
;
214 decor
|= GDK_DECOR_RESIZEH
;
218 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
219 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
221 /* GTK's shrinking/growing policy */
222 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
223 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
225 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
228 if (win
->m_icon
!= wxNullIcon
)
230 wxIcon
icon( win
->m_icon
);
231 win
->m_icon
= wxNullIcon
;
232 win
->SetIcon( icon
);
235 /* we set the focus to the child that accepts the focus. this
236 doesn't really have to be done in "realize" but why not? */
237 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
240 wxWindow
*child
= node
->GetData();
241 if (child
->AcceptsFocus())
247 node
= node
->GetNext();
253 //-----------------------------------------------------------------------------
254 // InsertChild for wxFrame
255 //-----------------------------------------------------------------------------
257 /* Callback for wxFrame. This very strange beast has to be used because
258 * C++ has no virtual methods in a constructor. We have to emulate a
259 * virtual function here as wxWindows requires different ways to insert
260 * a child in container classes. */
262 static void wxInsertChildInFrame( wxWindow
* parent
, wxWindow
* child
)
264 if (wxIS_KIND_OF(child
,wxToolBar
) || wxIS_KIND_OF(child
,wxMenuBar
))
266 /* actually, menubars are never inserted here, but this
267 may change one day */
269 /* these are outside the client area */
270 wxFrame
* frame
= (wxFrame
*) parent
;
271 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
272 GTK_WIDGET(child
->m_widget
),
278 /* we connect to these events for recalculating the client area
279 space when the toolbar is floating */
280 if (wxIS_KIND_OF(child
,wxToolBar
))
282 wxToolBar
*toolBar
= (wxToolBar
*) child
;
283 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
285 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
286 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
288 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
289 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
295 /* these are inside the client area */
296 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
297 GTK_WIDGET(child
->m_widget
),
304 /* resize on OnInternalIdle */
305 parent
->UpdateSize();
308 //-----------------------------------------------------------------------------
310 //-----------------------------------------------------------------------------
312 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
313 EVT_SIZE(wxFrame::OnSize
)
314 EVT_CLOSE(wxFrame::OnCloseWindow
)
315 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
318 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
322 m_frameMenuBar
= (wxMenuBar
*) NULL
;
323 m_frameStatusBar
= (wxStatusBar
*) NULL
;
324 m_frameToolBar
= (wxToolBar
*) NULL
;
328 m_mainWidget
= (GtkWidget
*) NULL
;
329 m_menuBarDetached
= FALSE
;
330 m_toolBarDetached
= FALSE
;
331 m_insertCallback
= wxInsertChildInFrame
;
334 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
335 const wxPoint
&pos
, const wxSize
&size
,
336 long style
, const wxString
&name
)
338 m_frameMenuBar
= (wxMenuBar
*) NULL
;
339 m_frameStatusBar
= (wxStatusBar
*) NULL
;
340 m_frameToolBar
= (wxToolBar
*) NULL
;
344 m_mainWidget
= (GtkWidget
*) NULL
;
345 m_menuBarDetached
= FALSE
;
346 m_toolBarDetached
= FALSE
;
347 m_insertCallback
= wxInsertChildInFrame
;
348 Create( parent
, id
, title
, pos
, size
, style
, name
);
351 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
352 const wxPoint
&pos
, const wxSize
&size
,
353 long style
, const wxString
&name
)
355 wxTopLevelWindows
.Append( this );
357 m_needParent
= FALSE
;
359 PreCreation( parent
, id
, pos
, size
, style
, name
);
363 m_insertCallback
= wxInsertChildInFrame
;
365 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
366 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
368 m_widget
= gtk_window_new( win_type
);
371 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
374 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
377 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
378 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
380 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
381 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
383 /* m_mainWidget holds the toolbar, the menubar and the client area */
384 m_mainWidget
= gtk_myfixed_new();
385 gtk_widget_show( m_mainWidget
);
386 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
387 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
390 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
393 /* m_wxwindow only represents the client area without toolbar and menubar */
394 m_wxwindow
= gtk_myfixed_new();
395 gtk_widget_show( m_wxwindow
);
396 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
399 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
402 /* we donm't allow the frame to get the focus as otherwise
403 the frame will grabit at arbitrary fcous changes. */
404 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
406 if (m_parent
) m_parent
->AddChild( this );
410 /* we cannot set MWM hints and icons before the widget has
411 been realized, so we do this directly after realization */
412 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
413 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
415 /* the user resized the frame by dragging etc. */
416 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
417 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
419 /* the only way to get the window size is to connect to this event */
420 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
421 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
428 if (m_frameMenuBar
) delete m_frameMenuBar
;
429 m_frameMenuBar
= (wxMenuBar
*) NULL
;
431 if (m_frameStatusBar
) delete m_frameStatusBar
;
432 m_frameStatusBar
= (wxStatusBar
*) NULL
;
434 if (m_frameToolBar
) delete m_frameToolBar
;
435 m_frameToolBar
= (wxToolBar
*) NULL
;
437 wxTopLevelWindows
.DeleteObject( this );
439 if (wxTheApp
->GetTopWindow() == this)
440 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
442 if (wxTopLevelWindows
.Number() == 0)
443 wxTheApp
->ExitMainLoop();
446 bool wxFrame::Show( bool show
)
448 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
450 if (show
&& !m_sizeSet
)
452 /* by calling GtkOnSize here, we don't have to call
453 either after showing the frame, which would entail
454 much ugly flicker or from within the size_allocate
455 handler, because GTK 1.1.X forbids that. */
457 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
460 return wxWindow::Show( show
);
463 bool wxFrame::Destroy()
465 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
467 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
472 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
474 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
476 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
477 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
479 /* avoid recursions */
480 if (m_resizing
) return;
485 int old_width
= m_width
;
486 int old_height
= m_height
;
488 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
490 if (x
!= -1) m_x
= x
;
491 if (y
!= -1) m_y
= y
;
492 if (width
!= -1) m_width
= width
;
493 if (height
!= -1) m_height
= height
;
503 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
505 if (width
== -1) m_width
= 80;
508 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
510 if (height
== -1) m_height
= 26;
513 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
514 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
515 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
516 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
518 if ((m_x
!= -1) || (m_y
!= -1))
520 if ((m_x
!= old_x
) || (m_y
!= old_y
))
522 /* we set the size here and in gtk_frame_map_callback */
523 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
527 if ((m_width
!= old_width
) || (m_height
!= old_height
))
529 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
530 done either directly before the frame is shown or in idle time
531 so that different calls to SetSize() don't lead to flicker. */
538 void wxFrame::Centre( int direction
)
540 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
545 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
546 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
551 void wxFrame::GetClientSize( int *width
, int *height
) const
553 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
555 wxWindow::GetClientSize( width
, height
);
561 if (!m_menuBarDetached
)
562 (*height
) -= wxMENU_HEIGHT
;
564 (*height
) -= wxPLACE_HOLDER
;
568 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
573 if (!m_toolBarDetached
)
576 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
580 (*height
) -= wxPLACE_HOLDER
;
584 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
588 (*width
) -= m_miniEdge
*2;
592 void wxFrame::DoSetClientSize( int width
, int height
)
594 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
599 if (!m_menuBarDetached
)
600 height
+= wxMENU_HEIGHT
;
602 height
+= wxPLACE_HOLDER
;
606 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
611 if (!m_toolBarDetached
)
614 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
618 height
+= wxPLACE_HOLDER
;
621 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
624 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
626 // due to a bug in gtk, x,y are always 0
630 /* avoid recursions */
631 if (m_resizing
) return;
634 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
635 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
640 /* space occupied by m_frameToolBar and m_frameMenuBar */
641 int client_area_y_offset
= 0;
643 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
644 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
645 set in wxFrame::Create so it is used to check what kind of frame we
646 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
647 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
648 importantly) m_mainWidget */
652 /* check if size is in legal range */
653 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
654 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
655 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
656 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
658 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
659 * menubar, the toolbar and the client area, which is represented by
661 * this hurts in the eye, but I don't want to call SetSize()
662 * because I don't want to call any non-native functions here. */
667 int yy
= m_miniEdge
+ m_miniTitle
;
668 int ww
= m_width
- 2*m_miniEdge
;
669 int hh
= wxMENU_HEIGHT
;
670 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
671 m_frameMenuBar
->InternalSetPosition(xx
, yy
);
672 m_frameMenuBar
->InternalSetSize(ww
, hh
);
673 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
674 m_frameMenuBar
->m_widget
,
676 client_area_y_offset
+= hh
;
682 int yy
= m_miniEdge
+ m_miniTitle
;
685 if (!m_menuBarDetached
)
688 yy
+= wxPLACE_HOLDER
;
690 int ww
= m_width
- 2*m_miniEdge
;
691 int hh
= m_frameToolBar
->m_height
;
692 // VZ: according to earlier comments in this file, the tbar height
693 // shouldn't be changed, so I comment out the next line
695 //if (m_toolBarDetached) hh = wxPLACE_HOLDER;
697 m_frameToolBar
->InternalSetPosition(xx
, yy
);
698 m_frameToolBar
->InternalSetSize(ww
, hh
);
700 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
701 m_frameToolBar
->m_widget
,
703 client_area_y_offset
+= hh
;
706 int client_x
= m_miniEdge
;
707 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
708 int client_w
= m_width
- 2*m_miniEdge
;
709 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
710 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
712 client_x
, client_y
, client_w
, client_h
);
716 /* if there is no m_mainWidget between m_widget and m_wxwindow there
717 is no need to set the size or position of m_wxwindow. */
720 if (m_frameStatusBar
)
722 int xx
= 0 + m_miniEdge
;
723 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
724 int ww
= m_width
- 2*m_miniEdge
;
725 int hh
= wxSTATUS_HEIGHT
;
726 m_frameStatusBar
->InternalSetPosition(xx
, yy
);
727 m_frameStatusBar
->InternalSetSize(ww
, hh
);
728 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
729 m_frameStatusBar
->m_widget
,
733 /* we actually set the size of a frame here and no-where else */
734 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
738 /* send size event to frame */
739 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
740 event
.SetEventObject( this );
741 GetEventHandler()->ProcessEvent( event
);
743 /* send size event to status bar */
744 if (m_frameStatusBar
)
746 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
747 event2
.SetEventObject( m_frameStatusBar
);
748 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
754 void wxFrame::OnInternalIdle()
756 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
757 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
762 void wxFrame::OnCloseWindow( wxCloseEvent
& event
)
767 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
769 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
777 /* do we have exactly one child? */
778 wxWindow
*child
= (wxWindow
*)NULL
;
779 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
781 wxWindow
*win
= (wxWindow
*)node
->Data();
782 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
786 /* it's the second one: do nothing */
794 /* no children at all? */
797 /* yes: set it's size to fill all the frame */
798 int client_x
, client_y
;
799 GetClientSize( &client_x
, &client_y
);
800 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
805 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
807 menu
->SetInvokingWindow( win
);
809 #if (GTK_MINOR_VERSION > 0)
810 /* support for native hot keys */
811 gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
));
814 wxNode
*node
= menu
->GetItems().First();
817 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
818 if (menuitem
->IsSubMenu())
819 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
824 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
826 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
827 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
829 m_frameMenuBar
= menuBar
;
833 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
834 /* support for native key accelerators indicated by underscroes */
835 gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
));
838 wxNode
*node
= m_frameMenuBar
->GetMenus().First();
841 wxMenu
*menu
= (wxMenu
*)node
->Data();
842 SetInvokingWindow( menu
, this );
846 if (m_frameMenuBar
->GetParent() != this)
848 m_frameMenuBar
->SetParent(this);
849 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
850 m_frameMenuBar
->m_widget
,
853 m_frameMenuBar
->m_width
,
854 m_frameMenuBar
->m_height
);
856 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
858 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
859 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
861 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
862 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
867 /* resize window in OnInternalIdle */
871 wxMenuBar
*wxFrame::GetMenuBar() const
873 return m_frameMenuBar
;
876 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
880 // if no help string found, we will clear the status bar text
883 int menuId
= event
.GetMenuId();
886 wxMenuBar
*menuBar
= GetMenuBar();
889 helpString
= menuBar
->GetHelpString(menuId
);
893 SetStatusText(helpString
);
897 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
)
899 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
901 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
903 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
905 GetChildren().DeleteObject( m_frameToolBar
);
909 return m_frameToolBar
;
912 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
914 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
917 wxToolBar
*wxFrame::GetToolBar() const
919 return m_frameToolBar
;
922 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
924 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
926 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
928 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
932 return m_frameStatusBar
;
935 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
937 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
939 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
941 // Set the height according to the font and the border size
942 wxClientDC
dc(statusBar
);
943 dc
.SetFont( statusBar
->GetFont() );
946 dc
.GetTextExtent( "X", &x
, &y
);
948 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
950 statusBar
->SetSize( -1, -1, 100, height
);
952 statusBar
->SetFieldsCount( number
);
956 void wxFrame::Command( int id
)
958 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
959 commandEvent
.SetInt( id
);
960 commandEvent
.SetEventObject( this );
962 wxMenuBar
*bar
= GetMenuBar();
965 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
966 if (item
&& item
->IsCheckable())
968 bar
->Check(id
,!bar
->Checked(id
)) ;
971 wxEvtHandler
* evtHandler
= GetEventHandler();
973 evtHandler
->ProcessEvent(commandEvent
);
976 void wxFrame::SetStatusText(const wxString
& text
, int number
)
978 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
980 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
982 m_frameStatusBar
->SetStatusText(text
, number
);
985 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
987 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
989 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
991 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
994 wxStatusBar
*wxFrame::GetStatusBar() const
996 return m_frameStatusBar
;
999 void wxFrame::SetTitle( const wxString
&title
)
1001 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1004 if (m_title
.IsNull()) m_title
= _T("");
1005 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1008 void wxFrame::SetIcon( const wxIcon
&icon
)
1010 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1013 if (!icon
.Ok()) return;
1015 if (!m_widget
->window
) return;
1017 wxMask
*mask
= icon
.GetMask();
1018 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1019 if (mask
) bm
= mask
->GetBitmap();
1021 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);