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 //-----------------------------------------------------------------------------
67 // "focus" from m_window
68 //-----------------------------------------------------------------------------
70 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
73 wxapp_install_idle_handler();
75 // This disables GTK's tab traversal
76 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
80 //-----------------------------------------------------------------------------
82 //-----------------------------------------------------------------------------
84 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
87 wxapp_install_idle_handler();
92 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
95 wxPrintf( "OnSize from " );
96 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
97 wxPrintf( win->GetClassInfo()->GetClassName() );
98 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
101 (int)alloc->height );
104 win
->m_width
= alloc
->width
;
105 win
->m_height
= alloc
->height
;
110 //-----------------------------------------------------------------------------
112 //-----------------------------------------------------------------------------
114 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
117 wxapp_install_idle_handler();
119 if (g_openDialogs
== 0)
125 //-----------------------------------------------------------------------------
126 // "child_attached" of menu bar
127 //-----------------------------------------------------------------------------
129 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
131 if (!win
->m_hasVMT
) return;
133 win
->m_menuBarDetached
= FALSE
;
137 //-----------------------------------------------------------------------------
138 // "child_detached" of menu bar
139 //-----------------------------------------------------------------------------
141 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
143 if (!win
->m_hasVMT
) return;
145 win
->m_menuBarDetached
= TRUE
;
150 //-----------------------------------------------------------------------------
151 // "child_attached" of tool bar
152 //-----------------------------------------------------------------------------
154 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
156 if (!win
->m_hasVMT
) return;
158 win
->m_toolBarDetached
= FALSE
;
163 //-----------------------------------------------------------------------------
164 // "child_detached" of tool bar
165 //-----------------------------------------------------------------------------
167 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
170 wxapp_install_idle_handler();
172 if (!win
->m_hasVMT
) return;
174 win
->m_toolBarDetached
= TRUE
;
177 #endif // wxUSE_TOOLBAR
179 //-----------------------------------------------------------------------------
181 //-----------------------------------------------------------------------------
184 #if (GTK_MINOR_VERSION > 0)
185 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
187 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
191 wxapp_install_idle_handler();
196 #if (GTK_MINOR_VERSION > 0)
199 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
207 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
208 mevent
.SetEventObject( win
);
209 win
->GetEventHandler()->ProcessEvent( mevent
);
214 //-----------------------------------------------------------------------------
215 // "realize" from m_widget
216 //-----------------------------------------------------------------------------
218 /* we cannot MWM hints and icons before the widget has been realized,
219 so we do this directly after realization */
222 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
225 wxapp_install_idle_handler();
227 /* I haven't been able to set the position of
228 the dialog before it is shown, so I set the
229 position in "realize" */
230 gtk_widget_set_uposition( widget
, win
->m_x
, win
->m_y
);
232 /* all this is for Motif Window Manager "hints" and is supposed to be
233 recognized by other WM as well. not tested. */
234 long decor
= (long) GDK_DECOR_BORDER
;
235 long func
= (long) GDK_FUNC_MOVE
;
237 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
238 decor
|= GDK_DECOR_TITLE
;
239 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
241 decor
|= GDK_DECOR_MENU
;
242 func
|= GDK_FUNC_CLOSE
;
244 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
246 func
|= GDK_FUNC_MINIMIZE
;
247 decor
|= GDK_DECOR_MINIMIZE
;
249 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
251 func
|= GDK_FUNC_MAXIMIZE
;
252 decor
|= GDK_DECOR_MAXIMIZE
;
254 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
256 func
|= GDK_FUNC_RESIZE
;
257 decor
|= GDK_DECOR_RESIZEH
;
260 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
261 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
263 /* GTK's shrinking/growing policy */
264 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
265 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
267 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
270 gint flag
= 0; // GDK_HINT_POS;
271 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
272 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
275 gdk_window_set_hints( win
->m_widget
->window
,
277 win
->GetMinWidth(), win
->GetMinHeight(),
278 win
->GetMaxWidth(), win
->GetMaxHeight(),
283 if (win
->m_icon
!= wxNullIcon
)
285 wxIcon
icon( win
->m_icon
);
286 win
->m_icon
= wxNullIcon
;
287 win
->SetIcon( icon
);
290 /* we set the focus to the child that accepts the focus. this
291 doesn't really have to be done in "realize" but why not? */
292 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
295 wxWindow
*child
= node
->GetData();
296 if (child
->AcceptsFocus())
302 node
= node
->GetNext();
308 //-----------------------------------------------------------------------------
309 // InsertChild for wxFrame
310 //-----------------------------------------------------------------------------
312 /* Callback for wxFrame. This very strange beast has to be used because
313 * C++ has no virtual methods in a constructor. We have to emulate a
314 * virtual function here as wxWindows requires different ways to insert
315 * a child in container classes. */
317 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
319 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
321 if (!parent
->m_insertInClientArea
)
323 /* these are outside the client area */
324 wxFrame
* frame
= (wxFrame
*) parent
;
325 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
326 GTK_WIDGET(child
->m_widget
),
333 /* we connect to these events for recalculating the client area
334 space when the toolbar is floating */
335 if (wxIS_KIND_OF(child
,wxToolBar
))
337 wxToolBar
*toolBar
= (wxToolBar
*) child
;
338 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
340 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
341 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
343 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
344 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
347 #endif // wxUSE_TOOLBAR
351 /* these are inside the client area */
352 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
353 GTK_WIDGET(child
->m_widget
),
360 /* resize on OnInternalIdle */
361 parent
->UpdateSize();
364 //-----------------------------------------------------------------------------
366 //-----------------------------------------------------------------------------
368 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
369 EVT_SIZE(wxFrame::OnSize
)
370 EVT_IDLE(wxFrame::OnIdle
)
371 EVT_CLOSE(wxFrame::OnCloseWindow
)
372 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
375 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
379 m_frameMenuBar
= (wxMenuBar
*) NULL
;
381 m_frameStatusBar
= (wxStatusBar
*) NULL
;
382 #endif // wxUSE_STATUSBAR
384 m_frameToolBar
= (wxToolBar
*) NULL
;
385 #endif // wxUSE_TOOLBAR
389 m_mainWidget
= (GtkWidget
*) NULL
;
390 m_menuBarDetached
= FALSE
;
391 m_toolBarDetached
= FALSE
;
392 m_insertInClientArea
= TRUE
;
396 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
397 const wxPoint
&pos
, const wxSize
&size
,
398 long style
, const wxString
&name
)
402 Create( parent
, id
, title
, pos
, size
, style
, name
);
405 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
406 const wxPoint
&pos
, const wxSize
&size
,
407 long style
, const wxString
&name
)
409 wxTopLevelWindows
.Append( this );
411 m_needParent
= FALSE
;
413 if (!PreCreation( parent
, pos
, size
) ||
414 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
416 wxFAIL_MSG( wxT("wxFrame creation failed") );
422 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
424 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
425 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
427 m_widget
= gtk_window_new( win_type
);
430 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
433 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
436 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
437 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
439 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
440 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
442 /* m_mainWidget holds the toolbar, the menubar and the client area */
443 m_mainWidget
= gtk_pizza_new();
444 gtk_widget_show( m_mainWidget
);
445 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
446 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
449 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
452 /* m_wxwindow only represents the client area without toolbar and menubar */
453 m_wxwindow
= gtk_pizza_new();
454 gtk_widget_show( m_wxwindow
);
455 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
458 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
461 /* we donm't allow the frame to get the focus as otherwise
462 the frame will grabit at arbitrary fcous changes. */
463 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
465 if (m_parent
) m_parent
->AddChild( this );
467 /* the user resized the frame by dragging etc. */
468 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
469 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
473 /* we cannot set MWM hints and icons before the widget has
474 been realized, so we do this directly after realization */
475 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
476 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
478 /* the only way to get the window size is to connect to this event */
479 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
480 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
482 /* disable native tab traversal */
483 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
484 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
491 m_isBeingDeleted
= TRUE
;
493 if (m_frameMenuBar
) delete m_frameMenuBar
;
494 m_frameMenuBar
= (wxMenuBar
*) NULL
;
497 if (m_frameStatusBar
) delete m_frameStatusBar
;
498 m_frameStatusBar
= (wxStatusBar
*) NULL
;
499 #endif // wxUSE_STATUSBAR
502 if (m_frameToolBar
) delete m_frameToolBar
;
503 m_frameToolBar
= (wxToolBar
*) NULL
;
504 #endif // wxUSE_TOOLBAR
506 wxTopLevelWindows
.DeleteObject( this );
508 if (wxTheApp
->GetTopWindow() == this)
509 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
511 if (wxTopLevelWindows
.Number() == 0)
512 wxTheApp
->ExitMainLoop();
515 bool wxFrame::Show( bool show
)
517 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
519 if (show
&& !m_sizeSet
)
521 /* by calling GtkOnSize here, we don't have to call
522 either after showing the frame, which would entail
523 much ugly flicker or from within the size_allocate
524 handler, because GTK 1.1.X forbids that. */
526 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
529 return wxWindow::Show( show
);
532 bool wxFrame::Destroy()
534 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
536 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
541 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
543 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
545 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
546 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
548 /* avoid recursions */
549 if (m_resizing
) return;
555 int old_width
= m_width
;
556 int old_height
= m_height
;
558 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
560 if (x
!= -1) m_x
= x
;
561 if (y
!= -1) m_y
= y
;
562 if (width
!= -1) m_width
= width
;
563 if (height
!= -1) m_height
= height
;
574 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
576 if (width == -1) m_width = 80;
579 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
581 if (height == -1) m_height = 26;
585 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
586 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
587 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
588 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
590 if ((m_x
!= -1) || (m_y
!= -1))
592 if ((m_x
!= old_x
) || (m_y
!= old_y
))
594 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
598 if ((m_width
!= old_width
) || (m_height
!= old_height
))
600 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
601 done either directly before the frame is shown or in idle time
602 so that different calls to SetSize() don't lead to flicker. */
609 void wxFrame::Centre( int direction
)
611 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
616 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
617 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
622 void wxFrame::DoGetClientSize( int *width
, int *height
) const
624 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
626 wxWindow::DoGetClientSize( width
, height
);
632 if (!m_menuBarDetached
)
633 (*height
) -= wxMENU_HEIGHT
;
635 (*height
) -= wxPLACE_HOLDER
;
640 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
647 if (!m_toolBarDetached
)
650 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
654 (*height
) -= wxPLACE_HOLDER
;
659 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
663 (*width
) -= m_miniEdge
*2;
667 void wxFrame::DoSetClientSize( int width
, int height
)
669 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
674 if (!m_menuBarDetached
)
675 height
+= wxMENU_HEIGHT
;
677 height
+= wxPLACE_HOLDER
;
682 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
689 if (!m_toolBarDetached
)
692 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
696 height
+= wxPLACE_HOLDER
;
700 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
703 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
705 // due to a bug in gtk, x,y are always 0
709 /* avoid recursions */
710 if (m_resizing
) return;
713 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
714 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
719 /* space occupied by m_frameToolBar and m_frameMenuBar */
720 int client_area_y_offset
= 0;
722 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
723 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
724 set in wxFrame::Create so it is used to check what kind of frame we
725 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
726 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
727 importantly) m_mainWidget */
731 /* check if size is in legal range */
732 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
733 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
734 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
735 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
737 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
738 * menubar, the toolbar and the client area, which is represented by
740 * this hurts in the eye, but I don't want to call SetSize()
741 * because I don't want to call any non-native functions here. */
746 int yy
= m_miniEdge
+ m_miniTitle
;
747 int ww
= m_width
- 2*m_miniEdge
;
748 int hh
= wxMENU_HEIGHT
;
749 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
750 m_frameMenuBar
->m_x
= xx
;
751 m_frameMenuBar
->m_y
= yy
;
752 m_frameMenuBar
->m_width
= ww
;
753 m_frameMenuBar
->m_height
= hh
;
754 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
755 m_frameMenuBar
->m_widget
,
757 client_area_y_offset
+= hh
;
761 if ((m_frameToolBar
) &&
762 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
765 int yy
= m_miniEdge
+ m_miniTitle
;
768 if (!m_menuBarDetached
)
771 yy
+= wxPLACE_HOLDER
;
773 int ww
= m_width
- 2*m_miniEdge
;
774 int hh
= m_frameToolBar
->m_height
;
775 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
776 m_frameToolBar
->m_x
= xx
;
777 m_frameToolBar
->m_y
= yy
;
778 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
779 m_frameToolBar->m_width = ww; */
780 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
781 m_frameToolBar
->m_widget
,
783 client_area_y_offset
+= hh
;
787 int client_x
= m_miniEdge
;
788 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
789 int client_w
= m_width
- 2*m_miniEdge
;
790 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
791 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
793 client_x
, client_y
, client_w
, client_h
);
797 /* if there is no m_mainWidget between m_widget and m_wxwindow there
798 is no need to set the size or position of m_wxwindow. */
802 if (m_frameStatusBar
)
804 int xx
= 0 + m_miniEdge
;
805 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
806 int ww
= m_width
- 2*m_miniEdge
;
807 int hh
= wxSTATUS_HEIGHT
;
808 m_frameStatusBar
->m_x
= xx
;
809 m_frameStatusBar
->m_y
= yy
;
810 m_frameStatusBar
->m_width
= ww
;
811 m_frameStatusBar
->m_height
= hh
;
812 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
813 m_frameStatusBar
->m_widget
,
818 /* we actually set the size of a frame here and no-where else */
819 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
824 // send size event to frame
825 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
826 event
.SetEventObject( this );
827 GetEventHandler()->ProcessEvent( event
);
829 // send size event to status bar
830 if (m_frameStatusBar
)
832 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
833 event2
.SetEventObject( m_frameStatusBar
);
834 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
840 void wxFrame::MakeModal( bool modal
)
843 gtk_grab_add( m_widget
);
845 gtk_grab_remove( m_widget
);
848 void wxFrame::OnInternalIdle()
850 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
852 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
854 // we'll come back later
856 wxapp_install_idle_handler();
860 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
862 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
865 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
868 wxWindow::OnInternalIdle();
871 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
876 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
878 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
880 #if wxUSE_CONSTRAINTS
886 #endif // wxUSE_CONSTRAINTS
888 /* do we have exactly one child? */
889 wxWindow
*child
= (wxWindow
*)NULL
;
890 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
892 wxWindow
*win
= (wxWindow
*)node
->Data();
893 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
897 /* it's the second one: do nothing */
905 /* no children at all? */
908 /* yes: set it's size to fill all the frame */
909 int client_x
, client_y
;
910 DoGetClientSize( &client_x
, &client_y
);
911 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
916 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
918 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
919 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
921 m_frameMenuBar
= menuBar
;
925 m_frameMenuBar
->SetInvokingWindow( this );
927 if (m_frameMenuBar
->GetParent() != this)
929 m_frameMenuBar
->SetParent(this);
930 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
931 m_frameMenuBar
->m_widget
,
934 m_frameMenuBar
->m_width
,
935 m_frameMenuBar
->m_height
);
937 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
939 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
940 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
942 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
943 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
946 m_frameMenuBar
->Show( TRUE
);
950 /* resize window in OnInternalIdle */
954 wxMenuBar
*wxFrame::GetMenuBar() const
956 return m_frameMenuBar
;
959 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
964 // if no help string found, we will clear the status bar text
967 int menuId
= event
.GetMenuId();
968 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
970 wxMenuBar
*menuBar
= GetMenuBar();
973 // it's ok if we don't find the item because it might belong to
975 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
977 helpString
= item
->GetHelp();
981 SetStatusText(helpString
);
983 #endif // wxUSE_STATUSBAR
987 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
989 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
991 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
993 m_insertInClientArea
= FALSE
;
995 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
997 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
999 m_insertInClientArea
= TRUE
;
1003 return m_frameToolBar
;
1006 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1008 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
1011 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1013 m_frameToolBar
= toolbar
;
1016 /* insert into toolbar area if not already there */
1017 if ((m_frameToolBar
->m_widget
->parent
) &&
1018 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1020 GetChildren().DeleteObject( m_frameToolBar
);
1022 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1028 wxToolBar
*wxFrame::GetToolBar() const
1030 return m_frameToolBar
;
1032 #endif // wxUSE_TOOLBAR
1035 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1037 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1039 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1041 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1045 return m_frameStatusBar
;
1048 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1050 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1052 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1054 // Set the height according to the font and the border size
1055 wxClientDC
dc(statusBar
);
1056 dc
.SetFont( statusBar
->GetFont() );
1059 dc
.GetTextExtent( "X", &x
, &y
);
1061 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1063 statusBar
->SetSize( -1, -1, 100, height
);
1065 statusBar
->SetFieldsCount( number
);
1069 wxStatusBar
*wxFrame::GetStatusBar() const
1071 return m_frameStatusBar
;
1074 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1076 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1078 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1080 m_frameStatusBar
->SetStatusText(text
, number
);
1083 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1085 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1087 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1089 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1091 #endif // wxUSE_STATUSBAR
1093 void wxFrame::Command( int id
)
1095 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1096 commandEvent
.SetInt( id
);
1097 commandEvent
.SetEventObject( this );
1099 wxMenuBar
*bar
= GetMenuBar();
1102 wxMenuItem
*item
= bar
->FindItem(id
) ;
1103 if (item
&& item
->IsCheckable())
1105 bar
->Check(id
, !bar
->IsChecked(id
)) ;
1108 wxEvtHandler
* evtHandler
= GetEventHandler();
1110 evtHandler
->ProcessEvent(commandEvent
);
1113 void wxFrame::SetTitle( const wxString
&title
)
1115 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1118 if (m_title
.IsNull()) m_title
= wxT("");
1119 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1122 void wxFrame::SetIcon( const wxIcon
&icon
)
1124 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1127 if (!icon
.Ok()) return;
1129 if (!m_widget
->window
) return;
1131 wxMask
*mask
= icon
.GetMask();
1132 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1133 if (mask
) bm
= mask
->GetBitmap();
1135 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1138 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1142 void wxFrame::Restore()
1146 void wxFrame::Iconize( bool iconize
)
1150 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1151 GDK_WINDOW_XWINDOW( m_widget
->window
),
1152 DefaultScreen( GDK_DISPLAY() ) );
1156 bool wxFrame::IsIconized() const