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();
48 extern int g_openDialogs
;
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
54 extern wxList wxPendingDelete
;
56 //-----------------------------------------------------------------------------
58 //-----------------------------------------------------------------------------
62 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
66 //-----------------------------------------------------------------------------
68 //-----------------------------------------------------------------------------
70 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
73 wxapp_install_idle_handler();
78 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
81 wxPrintf( "OnSize from " );
82 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
83 wxPrintf( win->GetClassInfo()->GetClassName() );
84 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
90 win
->m_width
= alloc
->width
;
91 win
->m_height
= alloc
->height
;
96 //-----------------------------------------------------------------------------
98 //-----------------------------------------------------------------------------
100 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
103 wxapp_install_idle_handler();
105 if (g_openDialogs
== 0)
111 //-----------------------------------------------------------------------------
112 // "child_attached" of menu bar
113 //-----------------------------------------------------------------------------
115 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
117 if (!win
->m_hasVMT
) return;
119 win
->m_menuBarDetached
= FALSE
;
123 //-----------------------------------------------------------------------------
124 // "child_detached" of menu bar
125 //-----------------------------------------------------------------------------
127 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
129 if (!win
->m_hasVMT
) return;
131 win
->m_menuBarDetached
= TRUE
;
136 //-----------------------------------------------------------------------------
137 // "child_attached" of tool bar
138 //-----------------------------------------------------------------------------
140 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
142 if (!win
->m_hasVMT
) return;
144 win
->m_toolBarDetached
= FALSE
;
149 //-----------------------------------------------------------------------------
150 // "child_detached" of tool bar
151 //-----------------------------------------------------------------------------
153 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
156 wxapp_install_idle_handler();
158 if (!win
->m_hasVMT
) return;
160 win
->m_toolBarDetached
= TRUE
;
163 #endif // wxUSE_TOOLBAR
165 //-----------------------------------------------------------------------------
167 //-----------------------------------------------------------------------------
170 #if (GTK_MINOR_VERSION > 0)
171 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
173 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
177 wxapp_install_idle_handler();
182 #if (GTK_MINOR_VERSION > 0)
185 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
193 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
194 mevent
.SetEventObject( win
);
195 win
->GetEventHandler()->ProcessEvent( mevent
);
200 //-----------------------------------------------------------------------------
201 // "realize" from m_widget
202 //-----------------------------------------------------------------------------
204 /* we cannot MWM hints and icons before the widget has been realized,
205 so we do this directly after realization */
208 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
211 wxapp_install_idle_handler();
213 /* I haven't been able to set the position of
214 the dialog before it is shown, so I set the
215 position in "realize" */
216 gtk_widget_set_uposition( widget
, win
->m_x
, win
->m_y
);
218 /* all this is for Motif Window Manager "hints" and is supposed to be
219 recognized by other WM as well. not tested. */
220 long decor
= (long) GDK_DECOR_BORDER
;
221 long func
= (long) GDK_FUNC_MOVE
;
223 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
224 decor
|= GDK_DECOR_TITLE
;
225 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
227 decor
|= GDK_DECOR_MENU
;
228 func
|= GDK_FUNC_CLOSE
;
230 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
232 func
|= GDK_FUNC_MINIMIZE
;
233 decor
|= GDK_DECOR_MINIMIZE
;
235 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
237 func
|= GDK_FUNC_MAXIMIZE
;
238 decor
|= GDK_DECOR_MAXIMIZE
;
240 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
242 func
|= GDK_FUNC_RESIZE
;
243 decor
|= GDK_DECOR_RESIZEH
;
246 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
247 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
249 /* GTK's shrinking/growing policy */
250 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
251 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
253 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
256 gint flag
= 0; // GDK_HINT_POS;
257 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
258 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
261 gdk_window_set_hints( win
->m_widget
->window
,
263 win
->GetMinWidth(), win
->GetMinHeight(),
264 win
->GetMaxWidth(), win
->GetMaxHeight(),
269 if (win
->m_icon
!= wxNullIcon
)
271 wxIcon
icon( win
->m_icon
);
272 win
->m_icon
= wxNullIcon
;
273 win
->SetIcon( icon
);
276 /* we set the focus to the child that accepts the focus. this
277 doesn't really have to be done in "realize" but why not? */
278 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
281 wxWindow
*child
= node
->GetData();
282 if (child
->AcceptsFocus())
288 node
= node
->GetNext();
294 //-----------------------------------------------------------------------------
295 // InsertChild for wxFrame
296 //-----------------------------------------------------------------------------
298 /* Callback for wxFrame. This very strange beast has to be used because
299 * C++ has no virtual methods in a constructor. We have to emulate a
300 * virtual function here as wxWindows requires different ways to insert
301 * a child in container classes. */
303 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
305 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
307 if (!parent
->m_insertInClientArea
)
309 /* these are outside the client area */
310 wxFrame
* frame
= (wxFrame
*) parent
;
311 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
312 GTK_WIDGET(child
->m_widget
),
319 /* we connect to these events for recalculating the client area
320 space when the toolbar is floating */
321 if (wxIS_KIND_OF(child
,wxToolBar
))
323 wxToolBar
*toolBar
= (wxToolBar
*) child
;
324 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
326 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
327 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
329 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
330 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
333 #endif // wxUSE_TOOLBAR
337 /* these are inside the client area */
338 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
339 GTK_WIDGET(child
->m_widget
),
346 /* resize on OnInternalIdle */
347 parent
->UpdateSize();
350 //-----------------------------------------------------------------------------
352 //-----------------------------------------------------------------------------
354 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
355 EVT_SIZE(wxFrame::OnSize
)
356 EVT_IDLE(wxFrame::OnIdle
)
357 EVT_CLOSE(wxFrame::OnCloseWindow
)
358 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
361 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
365 m_frameMenuBar
= (wxMenuBar
*) NULL
;
367 m_frameStatusBar
= (wxStatusBar
*) NULL
;
368 #endif // wxUSE_STATUSBAR
370 m_frameToolBar
= (wxToolBar
*) NULL
;
371 #endif // wxUSE_TOOLBAR
375 m_mainWidget
= (GtkWidget
*) NULL
;
376 m_menuBarDetached
= FALSE
;
377 m_toolBarDetached
= FALSE
;
378 m_insertInClientArea
= TRUE
;
382 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
383 const wxPoint
&pos
, const wxSize
&size
,
384 long style
, const wxString
&name
)
388 Create( parent
, id
, title
, pos
, size
, style
, name
);
391 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
392 const wxPoint
&pos
, const wxSize
&size
,
393 long style
, const wxString
&name
)
395 wxTopLevelWindows
.Append( this );
397 m_needParent
= FALSE
;
399 if (!PreCreation( parent
, pos
, size
) ||
400 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
402 wxFAIL_MSG( wxT("wxFrame creation failed") );
408 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
410 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
411 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
413 m_widget
= gtk_window_new( win_type
);
416 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
419 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
422 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
423 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
425 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
426 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
428 /* m_mainWidget holds the toolbar, the menubar and the client area */
429 m_mainWidget
= gtk_pizza_new();
430 gtk_widget_show( m_mainWidget
);
431 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
432 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
435 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
438 /* m_wxwindow only represents the client area without toolbar and menubar */
439 m_wxwindow
= gtk_pizza_new();
440 gtk_widget_show( m_wxwindow
);
441 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
444 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
447 /* we donm't allow the frame to get the focus as otherwise
448 the frame will grabit at arbitrary fcous changes. */
449 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
451 if (m_parent
) m_parent
->AddChild( this );
453 /* the user resized the frame by dragging etc. */
454 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
455 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
459 /* we cannot set MWM hints and icons before the widget has
460 been realized, so we do this directly after realization */
461 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
462 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
464 /* the only way to get the window size is to connect to this event */
465 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
466 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
473 m_isBeingDeleted
= TRUE
;
475 if (m_frameMenuBar
) delete m_frameMenuBar
;
476 m_frameMenuBar
= (wxMenuBar
*) NULL
;
479 if (m_frameStatusBar
) delete m_frameStatusBar
;
480 m_frameStatusBar
= (wxStatusBar
*) NULL
;
481 #endif // wxUSE_STATUSBAR
484 if (m_frameToolBar
) delete m_frameToolBar
;
485 m_frameToolBar
= (wxToolBar
*) NULL
;
486 #endif // wxUSE_TOOLBAR
488 wxTopLevelWindows
.DeleteObject( this );
490 if (wxTheApp
->GetTopWindow() == this)
491 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
493 if (wxTopLevelWindows
.Number() == 0)
494 wxTheApp
->ExitMainLoop();
497 bool wxFrame::Show( bool show
)
499 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
501 if (show
&& !m_sizeSet
)
503 /* by calling GtkOnSize here, we don't have to call
504 either after showing the frame, which would entail
505 much ugly flicker or from within the size_allocate
506 handler, because GTK 1.1.X forbids that. */
508 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
511 return wxWindow::Show( show
);
514 bool wxFrame::Destroy()
516 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
518 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
523 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
525 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
527 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
528 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
530 /* avoid recursions */
531 if (m_resizing
) return;
537 int old_width
= m_width
;
538 int old_height
= m_height
;
540 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
542 if (x
!= -1) m_x
= x
;
543 if (y
!= -1) m_y
= y
;
544 if (width
!= -1) m_width
= width
;
545 if (height
!= -1) m_height
= height
;
556 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
558 if (width == -1) m_width = 80;
561 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
563 if (height == -1) m_height = 26;
567 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
568 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
569 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
570 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
572 if ((m_x
!= -1) || (m_y
!= -1))
574 if ((m_x
!= old_x
) || (m_y
!= old_y
))
576 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
580 if ((m_width
!= old_width
) || (m_height
!= old_height
))
582 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
583 done either directly before the frame is shown or in idle time
584 so that different calls to SetSize() don't lead to flicker. */
591 void wxFrame::Centre( int direction
)
593 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
598 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
599 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
604 void wxFrame::DoGetClientSize( int *width
, int *height
) const
606 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
608 wxWindow::DoGetClientSize( width
, height
);
614 if (!m_menuBarDetached
)
615 (*height
) -= wxMENU_HEIGHT
;
617 (*height
) -= wxPLACE_HOLDER
;
622 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
629 if (!m_toolBarDetached
)
632 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
636 (*height
) -= wxPLACE_HOLDER
;
641 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
645 (*width
) -= m_miniEdge
*2;
649 void wxFrame::DoSetClientSize( int width
, int height
)
651 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
656 if (!m_menuBarDetached
)
657 height
+= wxMENU_HEIGHT
;
659 height
+= wxPLACE_HOLDER
;
664 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
671 if (!m_toolBarDetached
)
674 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
678 height
+= wxPLACE_HOLDER
;
682 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
685 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
687 // due to a bug in gtk, x,y are always 0
691 /* avoid recursions */
692 if (m_resizing
) return;
695 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
696 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
701 /* space occupied by m_frameToolBar and m_frameMenuBar */
702 int client_area_y_offset
= 0;
704 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
705 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
706 set in wxFrame::Create so it is used to check what kind of frame we
707 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
708 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
709 importantly) m_mainWidget */
713 /* check if size is in legal range */
714 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
715 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
716 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
717 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
719 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
720 * menubar, the toolbar and the client area, which is represented by
722 * this hurts in the eye, but I don't want to call SetSize()
723 * because I don't want to call any non-native functions here. */
728 int yy
= m_miniEdge
+ m_miniTitle
;
729 int ww
= m_width
- 2*m_miniEdge
;
730 int hh
= wxMENU_HEIGHT
;
731 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
732 m_frameMenuBar
->m_x
= xx
;
733 m_frameMenuBar
->m_y
= yy
;
734 m_frameMenuBar
->m_width
= ww
;
735 m_frameMenuBar
->m_height
= hh
;
736 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
737 m_frameMenuBar
->m_widget
,
739 client_area_y_offset
+= hh
;
743 if ((m_frameToolBar
) &&
744 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
747 int yy
= m_miniEdge
+ m_miniTitle
;
750 if (!m_menuBarDetached
)
753 yy
+= wxPLACE_HOLDER
;
755 int ww
= m_width
- 2*m_miniEdge
;
756 int hh
= m_frameToolBar
->m_height
;
757 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
758 m_frameToolBar
->m_x
= xx
;
759 m_frameToolBar
->m_y
= yy
;
760 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
761 m_frameToolBar->m_width = ww; */
762 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
763 m_frameToolBar
->m_widget
,
765 client_area_y_offset
+= hh
;
769 int client_x
= m_miniEdge
;
770 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
771 int client_w
= m_width
- 2*m_miniEdge
;
772 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
773 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
775 client_x
, client_y
, client_w
, client_h
);
779 /* if there is no m_mainWidget between m_widget and m_wxwindow there
780 is no need to set the size or position of m_wxwindow. */
784 if (m_frameStatusBar
)
786 int xx
= 0 + m_miniEdge
;
787 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
788 int ww
= m_width
- 2*m_miniEdge
;
789 int hh
= wxSTATUS_HEIGHT
;
790 m_frameStatusBar
->m_x
= xx
;
791 m_frameStatusBar
->m_y
= yy
;
792 m_frameStatusBar
->m_width
= ww
;
793 m_frameStatusBar
->m_height
= hh
;
794 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
795 m_frameStatusBar
->m_widget
,
800 /* we actually set the size of a frame here and no-where else */
801 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
806 // send size event to frame
807 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
808 event
.SetEventObject( this );
809 GetEventHandler()->ProcessEvent( event
);
811 // send size event to status bar
812 if (m_frameStatusBar
)
814 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
815 event2
.SetEventObject( m_frameStatusBar
);
816 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
822 void wxFrame::MakeModal( bool modal
)
825 gtk_grab_add( m_widget
);
827 gtk_grab_remove( m_widget
);
830 void wxFrame::OnInternalIdle()
832 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
834 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
836 // we'll come back later
838 wxapp_install_idle_handler();
842 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
844 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
847 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
850 wxWindow::OnInternalIdle();
853 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
858 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
860 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
862 #if wxUSE_CONSTRAINTS
868 #endif // wxUSE_CONSTRAINTS
870 /* do we have exactly one child? */
871 wxWindow
*child
= (wxWindow
*)NULL
;
872 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
874 wxWindow
*win
= (wxWindow
*)node
->Data();
875 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
879 /* it's the second one: do nothing */
887 /* no children at all? */
890 /* yes: set it's size to fill all the frame */
891 int client_x
, client_y
;
892 DoGetClientSize( &client_x
, &client_y
);
893 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
898 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
900 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
901 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
903 m_frameMenuBar
= menuBar
;
907 m_frameMenuBar
->SetInvokingWindow( this );
909 if (m_frameMenuBar
->GetParent() != this)
911 m_frameMenuBar
->SetParent(this);
912 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
913 m_frameMenuBar
->m_widget
,
916 m_frameMenuBar
->m_width
,
917 m_frameMenuBar
->m_height
);
919 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
921 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
922 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
924 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
925 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
928 m_frameMenuBar
->Show( TRUE
);
932 /* resize window in OnInternalIdle */
936 wxMenuBar
*wxFrame::GetMenuBar() const
938 return m_frameMenuBar
;
941 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
946 // if no help string found, we will clear the status bar text
949 int menuId
= event
.GetMenuId();
950 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
952 wxMenuBar
*menuBar
= GetMenuBar();
955 // it's ok if we don't find the item because it might belong to
957 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
959 helpString
= item
->GetHelp();
963 SetStatusText(helpString
);
965 #endif // wxUSE_STATUSBAR
969 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
971 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
973 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
975 m_insertInClientArea
= FALSE
;
977 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
979 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
981 m_insertInClientArea
= TRUE
;
985 return m_frameToolBar
;
988 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
990 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
993 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
995 m_frameToolBar
= toolbar
;
998 /* insert into toolbar area if not already there */
999 if ((m_frameToolBar
->m_widget
->parent
) &&
1000 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1002 GetChildren().DeleteObject( m_frameToolBar
);
1004 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1010 wxToolBar
*wxFrame::GetToolBar() const
1012 return m_frameToolBar
;
1014 #endif // wxUSE_TOOLBAR
1017 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1019 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1021 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1023 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1027 return m_frameStatusBar
;
1030 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1032 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1034 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1036 // Set the height according to the font and the border size
1037 wxClientDC
dc(statusBar
);
1038 dc
.SetFont( statusBar
->GetFont() );
1041 dc
.GetTextExtent( "X", &x
, &y
);
1043 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1045 statusBar
->SetSize( -1, -1, 100, height
);
1047 statusBar
->SetFieldsCount( number
);
1051 wxStatusBar
*wxFrame::GetStatusBar() const
1053 return m_frameStatusBar
;
1056 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1058 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1060 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1062 m_frameStatusBar
->SetStatusText(text
, number
);
1065 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1067 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1069 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1071 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1073 #endif // wxUSE_STATUSBAR
1075 void wxFrame::Command( int id
)
1077 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1078 commandEvent
.SetInt( id
);
1079 commandEvent
.SetEventObject( this );
1081 wxMenuBar
*bar
= GetMenuBar();
1084 wxMenuItem
*item
= bar
->FindItem(id
) ;
1085 if (item
&& item
->IsCheckable())
1087 bar
->Check(id
, !bar
->IsChecked(id
)) ;
1090 wxEvtHandler
* evtHandler
= GetEventHandler();
1092 evtHandler
->ProcessEvent(commandEvent
);
1095 void wxFrame::SetTitle( const wxString
&title
)
1097 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1100 if (m_title
.IsNull()) m_title
= wxT("");
1101 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1104 void wxFrame::SetIcon( const wxIcon
&icon
)
1106 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1109 if (!icon
.Ok()) return;
1111 if (!m_widget
->window
) return;
1113 wxMask
*mask
= icon
.GetMask();
1114 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1115 if (mask
) bm
= mask
->GetBitmap();
1117 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1120 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1124 void wxFrame::Restore()
1128 void wxFrame::Iconize( bool iconize
)
1132 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1133 GDK_WINDOW_XWINDOW( m_widget
->window
),
1134 DefaultScreen( GDK_DISPLAY() ) );
1138 bool wxFrame::IsIconized() const