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"
20 #include "wx/toolbar.h"
23 #include "wx/statusbr.h"
25 #include "wx/dcclient.h"
30 #include "wx/gtk/win_gtk.h"
31 #include "gdk/gdkkeysyms.h"
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 const int wxMENU_HEIGHT
= 27;
39 const int wxSTATUS_HEIGHT
= 25;
40 const int wxPLACE_HOLDER
= 0;
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 extern void wxapp_install_idle_handler();
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
53 extern wxList wxPendingDelete
;
55 //-----------------------------------------------------------------------------
57 //-----------------------------------------------------------------------------
61 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
72 wxapp_install_idle_handler();
74 if (!win
->m_hasVMT
) return;
76 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
78 win
->m_width
= alloc
->width
;
79 win
->m_height
= alloc
->height
;
84 //-----------------------------------------------------------------------------
86 //-----------------------------------------------------------------------------
88 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
91 wxapp_install_idle_handler();
98 //-----------------------------------------------------------------------------
99 // "child_attached" of menu bar
100 //-----------------------------------------------------------------------------
102 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
104 if (!win
->m_hasVMT
) return;
106 win
->m_menuBarDetached
= FALSE
;
110 //-----------------------------------------------------------------------------
111 // "child_detached" of menu bar
112 //-----------------------------------------------------------------------------
114 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
116 if (!win
->m_hasVMT
) return;
118 win
->m_menuBarDetached
= TRUE
;
123 //-----------------------------------------------------------------------------
124 // "child_attached" of tool bar
125 //-----------------------------------------------------------------------------
127 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
129 if (!win
->m_hasVMT
) return;
131 win
->m_toolBarDetached
= FALSE
;
136 //-----------------------------------------------------------------------------
137 // "child_detached" of tool bar
138 //-----------------------------------------------------------------------------
140 static void gtk_toolbar_detached_callback( GtkWidget
*widget
, GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
143 wxapp_install_idle_handler();
145 if (!win
->m_hasVMT
) return;
147 win
->m_toolBarDetached
= TRUE
;
150 #endif // wxUSE_TOOLBAR
152 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
157 #if (GTK_MINOR_VERSON > 0)
158 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
160 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
164 wxapp_install_idle_handler();
166 if (!win
->m_hasVMT
) return FALSE
;
168 #if (GTK_MINOR_VERSON > 0)
171 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
179 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
180 mevent
.SetEventObject( win
);
181 win
->GetEventHandler()->ProcessEvent( mevent
);
186 //-----------------------------------------------------------------------------
187 // "realize" from m_widget
188 //-----------------------------------------------------------------------------
190 /* we cannot MWM hints and icons before the widget has been realized,
191 so we do this directly after realization */
194 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
197 wxapp_install_idle_handler();
199 /* all this is for Motif Window Manager "hints" and is supposed to be
200 recognized by other WM as well. not tested. */
201 long decor
= (long) GDK_DECOR_BORDER
;
202 long func
= (long) GDK_FUNC_MOVE
;
204 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
205 decor
|= GDK_DECOR_TITLE
;
206 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
208 decor
|= GDK_DECOR_MENU
;
209 func
|= GDK_FUNC_CLOSE
;
211 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
213 func
|= GDK_FUNC_MINIMIZE
;
214 decor
|= GDK_DECOR_MINIMIZE
;
216 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
218 func
|= GDK_FUNC_MAXIMIZE
;
219 decor
|= GDK_DECOR_MAXIMIZE
;
221 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
223 func
|= GDK_FUNC_RESIZE
;
224 decor
|= GDK_DECOR_RESIZEH
;
227 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
228 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
230 /* GTK's shrinking/growing policy */
231 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
232 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
234 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
237 if (win
->m_icon
!= wxNullIcon
)
239 wxIcon
icon( win
->m_icon
);
240 win
->m_icon
= wxNullIcon
;
241 win
->SetIcon( icon
);
244 /* we set the focus to the child that accepts the focus. this
245 doesn't really have to be done in "realize" but why not? */
246 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
249 wxWindow
*child
= node
->GetData();
250 if (child
->AcceptsFocus())
256 node
= node
->GetNext();
262 //-----------------------------------------------------------------------------
263 // InsertChild for wxFrame
264 //-----------------------------------------------------------------------------
266 /* Callback for wxFrame. This very strange beast has to be used because
267 * C++ has no virtual methods in a constructor. We have to emulate a
268 * virtual function here as wxWindows requires different ways to insert
269 * a child in container classes. */
271 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
273 if (!parent
->m_insertInClientArea
)
275 /* these are outside the client area */
276 wxFrame
* frame
= (wxFrame
*) parent
;
277 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
278 GTK_WIDGET(child
->m_widget
),
285 /* we connect to these events for recalculating the client area
286 space when the toolbar is floating */
287 if (wxIS_KIND_OF(child
,wxToolBar
))
289 wxToolBar
*toolBar
= (wxToolBar
*) child
;
290 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
292 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
293 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
295 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
296 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
299 #endif // wxUSE_TOOLBAR
303 /* these are inside the client area */
304 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
305 GTK_WIDGET(child
->m_widget
),
312 /* resize on OnInternalIdle */
313 parent
->UpdateSize();
316 //-----------------------------------------------------------------------------
318 //-----------------------------------------------------------------------------
320 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
321 EVT_SIZE(wxFrame::OnSize
)
322 EVT_CLOSE(wxFrame::OnCloseWindow
)
323 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
326 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
330 m_frameMenuBar
= (wxMenuBar
*) NULL
;
332 m_frameStatusBar
= (wxStatusBar
*) NULL
;
333 #endif // wxUSE_STATUSBAR
335 m_frameToolBar
= (wxToolBar
*) NULL
;
336 #endif // wxUSE_TOOLBAR
340 m_mainWidget
= (GtkWidget
*) NULL
;
341 m_menuBarDetached
= FALSE
;
342 m_toolBarDetached
= FALSE
;
343 m_insertInClientArea
= TRUE
;
346 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
347 const wxPoint
&pos
, const wxSize
&size
,
348 long style
, const wxString
&name
)
352 Create( parent
, id
, title
, pos
, size
, style
, name
);
355 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
356 const wxPoint
&pos
, const wxSize
&size
,
357 long style
, const wxString
&name
)
359 wxTopLevelWindows
.Append( this );
361 m_needParent
= FALSE
;
363 if (!PreCreation( parent
, pos
, size
) ||
364 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
366 wxFAIL_MSG( _T("wxFrame creation failed") );
372 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
374 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
375 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
377 m_widget
= gtk_window_new( win_type
);
380 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
383 debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name
);
386 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
387 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
389 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
390 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
392 /* m_mainWidget holds the toolbar, the menubar and the client area */
393 m_mainWidget
= gtk_myfixed_new();
394 gtk_widget_show( m_mainWidget
);
395 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
396 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
399 debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name
);
402 /* m_wxwindow only represents the client area without toolbar and menubar */
403 m_wxwindow
= gtk_myfixed_new();
404 gtk_widget_show( m_wxwindow
);
405 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
408 debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name
);
411 /* we donm't allow the frame to get the focus as otherwise
412 the frame will grabit at arbitrary fcous changes. */
413 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
415 if (m_parent
) m_parent
->AddChild( this );
419 /* we cannot set MWM hints and icons before the widget has
420 been realized, so we do this directly after realization */
421 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
422 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
424 /* the user resized the frame by dragging etc. */
425 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
426 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
428 /* the only way to get the window size is to connect to this event */
429 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
430 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
437 m_isBeingDeleted
= TRUE
;
439 if (m_frameMenuBar
) delete m_frameMenuBar
;
440 m_frameMenuBar
= (wxMenuBar
*) NULL
;
443 if (m_frameStatusBar
) delete m_frameStatusBar
;
444 m_frameStatusBar
= (wxStatusBar
*) NULL
;
445 #endif // wxUSE_STATUSBAR
448 if (m_frameToolBar
) delete m_frameToolBar
;
449 m_frameToolBar
= (wxToolBar
*) NULL
;
450 #endif // wxUSE_TOOLBAR
452 wxTopLevelWindows
.DeleteObject( this );
454 if (wxTheApp
->GetTopWindow() == this)
455 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
457 if (wxTopLevelWindows
.Number() == 0)
458 wxTheApp
->ExitMainLoop();
461 bool wxFrame::Show( bool show
)
463 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
465 if (show
&& !m_sizeSet
)
467 /* by calling GtkOnSize here, we don't have to call
468 either after showing the frame, which would entail
469 much ugly flicker or from within the size_allocate
470 handler, because GTK 1.1.X forbids that. */
472 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
475 return wxWindow::Show( show
);
478 bool wxFrame::Destroy()
480 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
482 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
487 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
489 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
491 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
492 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
494 /* avoid recursions */
495 if (m_resizing
) return;
500 int old_width
= m_width
;
501 int old_height
= m_height
;
503 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
505 if (x
!= -1) m_x
= x
;
506 if (y
!= -1) m_y
= y
;
507 if (width
!= -1) m_width
= width
;
508 if (height
!= -1) m_height
= height
;
518 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
520 if (width
== -1) m_width
= 80;
523 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
525 if (height
== -1) m_height
= 26;
528 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
529 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
530 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
531 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
533 if ((m_x
!= -1) || (m_y
!= -1))
535 if ((m_x
!= old_x
) || (m_y
!= old_y
))
537 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
541 if ((m_width
!= old_width
) || (m_height
!= old_height
))
543 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
544 done either directly before the frame is shown or in idle time
545 so that different calls to SetSize() don't lead to flicker. */
552 void wxFrame::Centre( int direction
)
554 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
559 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
560 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
565 void wxFrame::DoGetClientSize( int *width
, int *height
) const
567 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
569 wxWindow::DoGetClientSize( width
, height
);
575 if (!m_menuBarDetached
)
576 (*height
) -= wxMENU_HEIGHT
;
578 (*height
) -= wxPLACE_HOLDER
;
583 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
590 if (!m_toolBarDetached
)
593 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
597 (*height
) -= wxPLACE_HOLDER
;
602 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
606 (*width
) -= m_miniEdge
*2;
610 void wxFrame::DoSetClientSize( int width
, int height
)
612 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
617 if (!m_menuBarDetached
)
618 height
+= wxMENU_HEIGHT
;
620 height
+= wxPLACE_HOLDER
;
625 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
632 if (!m_toolBarDetached
)
635 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
639 height
+= wxPLACE_HOLDER
;
643 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
646 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
648 // due to a bug in gtk, x,y are always 0
652 /* avoid recursions */
653 if (m_resizing
) return;
656 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
657 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
662 /* space occupied by m_frameToolBar and m_frameMenuBar */
663 int client_area_y_offset
= 0;
665 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
666 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
667 set in wxFrame::Create so it is used to check what kind of frame we
668 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
669 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
670 importantly) m_mainWidget */
674 /* check if size is in legal range */
675 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
676 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
677 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
678 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
680 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
681 * menubar, the toolbar and the client area, which is represented by
683 * this hurts in the eye, but I don't want to call SetSize()
684 * because I don't want to call any non-native functions here. */
689 int yy
= m_miniEdge
+ m_miniTitle
;
690 int ww
= m_width
- 2*m_miniEdge
;
691 int hh
= wxMENU_HEIGHT
;
692 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
693 m_frameMenuBar
->m_x
= xx
;
694 m_frameMenuBar
->m_y
= yy
;
695 m_frameMenuBar
->m_width
= ww
;
696 m_frameMenuBar
->m_height
= hh
;
697 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
698 m_frameMenuBar
->m_widget
,
700 client_area_y_offset
+= hh
;
707 int yy
= m_miniEdge
+ m_miniTitle
;
710 if (!m_menuBarDetached
)
713 yy
+= wxPLACE_HOLDER
;
715 int ww
= m_width
- 2*m_miniEdge
;
716 int hh
= m_frameToolBar
->m_height
;
717 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
718 m_frameToolBar
->m_x
= xx
;
719 m_frameToolBar
->m_y
= yy
;
720 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
721 m_frameToolBar
->m_width
= ww
;
722 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
723 m_frameToolBar
->m_widget
,
725 client_area_y_offset
+= hh
;
729 int client_x
= m_miniEdge
;
730 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
731 int client_w
= m_width
- 2*m_miniEdge
;
732 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
733 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
735 client_x
, client_y
, client_w
, client_h
);
739 /* if there is no m_mainWidget between m_widget and m_wxwindow there
740 is no need to set the size or position of m_wxwindow. */
744 if (m_frameStatusBar
)
746 int xx
= 0 + m_miniEdge
;
747 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
748 int ww
= m_width
- 2*m_miniEdge
;
749 int hh
= wxSTATUS_HEIGHT
;
750 m_frameStatusBar
->m_x
= xx
;
751 m_frameStatusBar
->m_y
= yy
;
752 m_frameStatusBar
->m_width
= ww
;
753 m_frameStatusBar
->m_height
= hh
;
754 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
755 m_frameStatusBar
->m_widget
,
760 /* we actually set the size of a frame here and no-where else */
761 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
765 /* send size event to frame */
766 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
767 event
.SetEventObject( this );
768 GetEventHandler()->ProcessEvent( event
);
770 /* send size event to status bar */
771 if (m_frameStatusBar
)
773 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
774 event2
.SetEventObject( m_frameStatusBar
);
775 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
781 void wxFrame::MakeModal( bool modal
)
784 gtk_grab_add( m_widget
);
786 gtk_grab_remove( m_widget
);
789 void wxFrame::OnInternalIdle()
791 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
792 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
796 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
798 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
801 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
805 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
810 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
812 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
814 #if wxUSE_CONSTRAINTS
820 #endif // wxUSE_CONSTRAINTS
822 /* do we have exactly one child? */
823 wxWindow
*child
= (wxWindow
*)NULL
;
824 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
826 wxWindow
*win
= (wxWindow
*)node
->Data();
827 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
831 /* it's the second one: do nothing */
839 /* no children at all? */
842 /* yes: set it's size to fill all the frame */
843 int client_x
, client_y
;
844 DoGetClientSize( &client_x
, &client_y
);
845 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
850 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
852 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
853 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
855 m_frameMenuBar
= menuBar
;
859 m_frameMenuBar
->SetInvokingWindow( this );
861 if (m_frameMenuBar
->GetParent() != this)
863 m_frameMenuBar
->SetParent(this);
864 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
865 m_frameMenuBar
->m_widget
,
868 m_frameMenuBar
->m_width
,
869 m_frameMenuBar
->m_height
);
871 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
873 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
874 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
876 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
877 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
880 m_frameMenuBar
->Show( TRUE
);
884 /* resize window in OnInternalIdle */
888 wxMenuBar
*wxFrame::GetMenuBar() const
890 return m_frameMenuBar
;
893 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
898 // if no help string found, we will clear the status bar text
901 int menuId
= event
.GetMenuId();
904 wxMenuBar
*menuBar
= GetMenuBar();
907 helpString
= menuBar
->GetHelpString(menuId
);
911 SetStatusText(helpString
);
913 #endif // wxUSE_STATUSBAR
917 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
919 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
921 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
923 m_insertInClientArea
= FALSE
;
925 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
927 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
929 m_insertInClientArea
= TRUE
;
933 return m_frameToolBar
;
936 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
938 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
941 wxToolBar
*wxFrame::GetToolBar() const
943 return m_frameToolBar
;
945 #endif // wxUSE_TOOLBAR
948 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
950 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
952 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
954 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
958 return m_frameStatusBar
;
961 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
963 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
965 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
967 // Set the height according to the font and the border size
968 wxClientDC
dc(statusBar
);
969 dc
.SetFont( statusBar
->GetFont() );
972 dc
.GetTextExtent( "X", &x
, &y
);
974 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
976 statusBar
->SetSize( -1, -1, 100, height
);
978 statusBar
->SetFieldsCount( number
);
982 wxStatusBar
*wxFrame::GetStatusBar() const
984 return m_frameStatusBar
;
987 void wxFrame::SetStatusText(const wxString
& text
, int number
)
989 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
991 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
993 m_frameStatusBar
->SetStatusText(text
, number
);
996 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
998 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1000 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
1002 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1004 #endif // wxUSE_STATUSBAR
1006 void wxFrame::Command( int id
)
1008 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1009 commandEvent
.SetInt( id
);
1010 commandEvent
.SetEventObject( this );
1012 wxMenuBar
*bar
= GetMenuBar();
1015 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1016 if (item
&& item
->IsCheckable())
1018 bar
->Check(id
,!bar
->Checked(id
)) ;
1021 wxEvtHandler
* evtHandler
= GetEventHandler();
1023 evtHandler
->ProcessEvent(commandEvent
);
1026 void wxFrame::SetTitle( const wxString
&title
)
1028 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1031 if (m_title
.IsNull()) m_title
= _T("");
1032 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1035 void wxFrame::SetIcon( const wxIcon
&icon
)
1037 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1040 if (!icon
.Ok()) return;
1042 if (!m_widget
->window
) return;
1044 wxMask
*mask
= icon
.GetMask();
1045 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1046 if (mask
) bm
= mask
->GetBitmap();
1048 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1051 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1055 void wxFrame::Restore()
1059 void wxFrame::Iconize( bool iconize
)
1063 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1064 GDK_WINDOW_XWINDOW( m_widget
->window
),
1065 DefaultScreen( GDK_DISPLAY() ) );
1069 bool wxFrame::IsIconized() const