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();
804 wxWindow::OnInternalIdle();
807 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
812 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
814 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
816 #if wxUSE_CONSTRAINTS
822 #endif // wxUSE_CONSTRAINTS
824 /* do we have exactly one child? */
825 wxWindow
*child
= (wxWindow
*)NULL
;
826 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
828 wxWindow
*win
= (wxWindow
*)node
->Data();
829 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
833 /* it's the second one: do nothing */
841 /* no children at all? */
844 /* yes: set it's size to fill all the frame */
845 int client_x
, client_y
;
846 DoGetClientSize( &client_x
, &client_y
);
847 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
852 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
854 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
855 wxASSERT_MSG( (m_wxwindow
!= NULL
), _T("invalid frame") );
857 m_frameMenuBar
= menuBar
;
861 m_frameMenuBar
->SetInvokingWindow( this );
863 if (m_frameMenuBar
->GetParent() != this)
865 m_frameMenuBar
->SetParent(this);
866 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
867 m_frameMenuBar
->m_widget
,
870 m_frameMenuBar
->m_width
,
871 m_frameMenuBar
->m_height
);
873 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
875 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
876 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
878 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
879 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
882 m_frameMenuBar
->Show( TRUE
);
886 /* resize window in OnInternalIdle */
890 wxMenuBar
*wxFrame::GetMenuBar() const
892 return m_frameMenuBar
;
895 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
900 // if no help string found, we will clear the status bar text
903 int menuId
= event
.GetMenuId();
906 wxMenuBar
*menuBar
= GetMenuBar();
909 helpString
= menuBar
->GetHelpString(menuId
);
913 SetStatusText(helpString
);
915 #endif // wxUSE_STATUSBAR
919 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
921 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
923 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") );
925 m_insertInClientArea
= FALSE
;
927 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
929 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
931 m_insertInClientArea
= TRUE
;
935 return m_frameToolBar
;
938 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
940 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
943 wxToolBar
*wxFrame::GetToolBar() const
945 return m_frameToolBar
;
947 #endif // wxUSE_TOOLBAR
950 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
952 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
954 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, _T("recreating status bar in wxFrame") );
956 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
960 return m_frameStatusBar
;
963 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
965 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
967 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
969 // Set the height according to the font and the border size
970 wxClientDC
dc(statusBar
);
971 dc
.SetFont( statusBar
->GetFont() );
974 dc
.GetTextExtent( "X", &x
, &y
);
976 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
978 statusBar
->SetSize( -1, -1, 100, height
);
980 statusBar
->SetFieldsCount( number
);
984 wxStatusBar
*wxFrame::GetStatusBar() const
986 return m_frameStatusBar
;
989 void wxFrame::SetStatusText(const wxString
& text
, int number
)
991 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
993 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set text for") );
995 m_frameStatusBar
->SetStatusText(text
, number
);
998 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1000 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1002 wxCHECK_RET( m_frameStatusBar
!= NULL
, _T("no statusbar to set widths for") );
1004 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1006 #endif // wxUSE_STATUSBAR
1008 void wxFrame::Command( int id
)
1010 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1011 commandEvent
.SetInt( id
);
1012 commandEvent
.SetEventObject( this );
1014 wxMenuBar
*bar
= GetMenuBar();
1017 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1018 if (item
&& item
->IsCheckable())
1020 bar
->Check(id
,!bar
->Checked(id
)) ;
1023 wxEvtHandler
* evtHandler
= GetEventHandler();
1025 evtHandler
->ProcessEvent(commandEvent
);
1028 void wxFrame::SetTitle( const wxString
&title
)
1030 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1033 if (m_title
.IsNull()) m_title
= _T("");
1034 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1037 void wxFrame::SetIcon( const wxIcon
&icon
)
1039 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid frame") );
1042 if (!icon
.Ok()) return;
1044 if (!m_widget
->window
) return;
1046 wxMask
*mask
= icon
.GetMask();
1047 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1048 if (mask
) bm
= mask
->GetBitmap();
1050 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1053 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1057 void wxFrame::Restore()
1061 void wxFrame::Iconize( bool iconize
)
1065 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1066 GDK_WINDOW_XWINDOW( m_widget
->window
),
1067 DefaultScreen( GDK_DISPLAY() ) );
1071 bool wxFrame::IsIconized() const