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();
77 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
80 wxPrintf( "OnSize from " );
81 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
82 wxPrintf( win->GetClassInfo()->GetClassName() );
83 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
89 win
->m_width
= alloc
->width
;
90 win
->m_height
= alloc
->height
;
95 //-----------------------------------------------------------------------------
97 //-----------------------------------------------------------------------------
99 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
102 wxapp_install_idle_handler();
109 //-----------------------------------------------------------------------------
110 // "child_attached" of menu bar
111 //-----------------------------------------------------------------------------
113 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
115 if (!win
->m_hasVMT
) return;
117 win
->m_menuBarDetached
= FALSE
;
121 //-----------------------------------------------------------------------------
122 // "child_detached" of menu bar
123 //-----------------------------------------------------------------------------
125 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
127 if (!win
->m_hasVMT
) return;
129 win
->m_menuBarDetached
= TRUE
;
134 //-----------------------------------------------------------------------------
135 // "child_attached" of tool bar
136 //-----------------------------------------------------------------------------
138 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
140 if (!win
->m_hasVMT
) return;
142 win
->m_toolBarDetached
= FALSE
;
147 //-----------------------------------------------------------------------------
148 // "child_detached" of tool bar
149 //-----------------------------------------------------------------------------
151 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
154 wxapp_install_idle_handler();
156 if (!win
->m_hasVMT
) return;
158 win
->m_toolBarDetached
= TRUE
;
161 #endif // wxUSE_TOOLBAR
163 //-----------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------
168 #if (GTK_MINOR_VERSON > 0)
169 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
171 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
175 wxapp_install_idle_handler();
177 if (!win
->m_hasVMT
) return FALSE
;
179 #if (GTK_MINOR_VERSON > 0)
182 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
190 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
191 mevent
.SetEventObject( win
);
192 win
->GetEventHandler()->ProcessEvent( mevent
);
197 //-----------------------------------------------------------------------------
198 // "realize" from m_widget
199 //-----------------------------------------------------------------------------
201 /* we cannot MWM hints and icons before the widget has been realized,
202 so we do this directly after realization */
205 gtk_frame_realized_callback( GtkWidget
*widget
, wxFrame
*win
)
208 wxapp_install_idle_handler();
210 /* I haven't been able to set the position of
211 the dialog before it is shown, so I set the
212 position in "realize" */
213 gtk_widget_set_uposition( widget
, win
->m_x
, win
->m_y
);
215 /* all this is for Motif Window Manager "hints" and is supposed to be
216 recognized by other WM as well. not tested. */
217 long decor
= (long) GDK_DECOR_BORDER
;
218 long func
= (long) GDK_FUNC_MOVE
;
220 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
221 decor
|= GDK_DECOR_TITLE
;
222 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
224 decor
|= GDK_DECOR_MENU
;
225 func
|= GDK_FUNC_CLOSE
;
227 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
229 func
|= GDK_FUNC_MINIMIZE
;
230 decor
|= GDK_DECOR_MINIMIZE
;
232 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
234 func
|= GDK_FUNC_MAXIMIZE
;
235 decor
|= GDK_DECOR_MAXIMIZE
;
237 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
239 func
|= GDK_FUNC_RESIZE
;
240 decor
|= GDK_DECOR_RESIZEH
;
243 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
244 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
246 /* GTK's shrinking/growing policy */
247 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
248 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
250 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
253 gint flag
= 0; // GDK_HINT_POS;
254 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
255 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
258 gdk_window_set_hints( win
->m_widget
->window
,
260 win
->GetMinWidth(), win
->GetMinHeight(),
261 win
->GetMaxWidth(), win
->GetMaxHeight(),
266 if (win
->m_icon
!= wxNullIcon
)
268 wxIcon
icon( win
->m_icon
);
269 win
->m_icon
= wxNullIcon
;
270 win
->SetIcon( icon
);
273 /* we set the focus to the child that accepts the focus. this
274 doesn't really have to be done in "realize" but why not? */
275 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
278 wxWindow
*child
= node
->GetData();
279 if (child
->AcceptsFocus())
285 node
= node
->GetNext();
291 //-----------------------------------------------------------------------------
292 // InsertChild for wxFrame
293 //-----------------------------------------------------------------------------
295 /* Callback for wxFrame. This very strange beast has to be used because
296 * C++ has no virtual methods in a constructor. We have to emulate a
297 * virtual function here as wxWindows requires different ways to insert
298 * a child in container classes. */
300 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
302 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
304 if (!parent
->m_insertInClientArea
)
306 /* these are outside the client area */
307 wxFrame
* frame
= (wxFrame
*) parent
;
308 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
309 GTK_WIDGET(child
->m_widget
),
316 /* we connect to these events for recalculating the client area
317 space when the toolbar is floating */
318 if (wxIS_KIND_OF(child
,wxToolBar
))
320 wxToolBar
*toolBar
= (wxToolBar
*) child
;
321 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
323 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
324 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
326 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
327 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
330 #endif // wxUSE_TOOLBAR
334 /* these are inside the client area */
335 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
336 GTK_WIDGET(child
->m_widget
),
343 /* resize on OnInternalIdle */
344 parent
->UpdateSize();
347 //-----------------------------------------------------------------------------
349 //-----------------------------------------------------------------------------
351 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
352 EVT_SIZE(wxFrame::OnSize
)
353 EVT_IDLE(wxFrame::OnIdle
)
354 EVT_CLOSE(wxFrame::OnCloseWindow
)
355 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
358 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
362 m_frameMenuBar
= (wxMenuBar
*) NULL
;
364 m_frameStatusBar
= (wxStatusBar
*) NULL
;
365 #endif // wxUSE_STATUSBAR
367 m_frameToolBar
= (wxToolBar
*) NULL
;
368 #endif // wxUSE_TOOLBAR
372 m_mainWidget
= (GtkWidget
*) NULL
;
373 m_menuBarDetached
= FALSE
;
374 m_toolBarDetached
= FALSE
;
375 m_insertInClientArea
= TRUE
;
379 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
380 const wxPoint
&pos
, const wxSize
&size
,
381 long style
, const wxString
&name
)
385 Create( parent
, id
, title
, pos
, size
, style
, name
);
388 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
389 const wxPoint
&pos
, const wxSize
&size
,
390 long style
, const wxString
&name
)
392 wxTopLevelWindows
.Append( this );
394 m_needParent
= FALSE
;
396 if (!PreCreation( parent
, pos
, size
) ||
397 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
399 wxFAIL_MSG( wxT("wxFrame creation failed") );
405 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
407 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
408 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
410 m_widget
= gtk_window_new( win_type
);
413 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
416 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
419 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
420 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
422 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
423 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
425 /* m_mainWidget holds the toolbar, the menubar and the client area */
426 m_mainWidget
= gtk_pizza_new();
427 gtk_widget_show( m_mainWidget
);
428 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
429 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
432 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
435 /* m_wxwindow only represents the client area without toolbar and menubar */
436 m_wxwindow
= gtk_pizza_new();
437 gtk_widget_show( m_wxwindow
);
438 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
441 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
444 /* we donm't allow the frame to get the focus as otherwise
445 the frame will grabit at arbitrary fcous changes. */
446 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
448 if (m_parent
) m_parent
->AddChild( this );
450 /* the user resized the frame by dragging etc. */
451 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
452 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
456 /* we cannot set MWM hints and icons before the widget has
457 been realized, so we do this directly after realization */
458 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
459 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
461 /* the only way to get the window size is to connect to this event */
462 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
463 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
470 m_isBeingDeleted
= TRUE
;
472 if (m_frameMenuBar
) delete m_frameMenuBar
;
473 m_frameMenuBar
= (wxMenuBar
*) NULL
;
476 if (m_frameStatusBar
) delete m_frameStatusBar
;
477 m_frameStatusBar
= (wxStatusBar
*) NULL
;
478 #endif // wxUSE_STATUSBAR
481 if (m_frameToolBar
) delete m_frameToolBar
;
482 m_frameToolBar
= (wxToolBar
*) NULL
;
483 #endif // wxUSE_TOOLBAR
485 wxTopLevelWindows
.DeleteObject( this );
487 if (wxTheApp
->GetTopWindow() == this)
488 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
490 if (wxTopLevelWindows
.Number() == 0)
491 wxTheApp
->ExitMainLoop();
494 bool wxFrame::Show( bool show
)
496 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
498 if (show
&& !m_sizeSet
)
500 /* by calling GtkOnSize here, we don't have to call
501 either after showing the frame, which would entail
502 much ugly flicker or from within the size_allocate
503 handler, because GTK 1.1.X forbids that. */
505 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
508 return wxWindow::Show( show
);
511 bool wxFrame::Destroy()
513 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
515 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
520 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
522 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
524 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
525 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
527 /* avoid recursions */
528 if (m_resizing
) return;
534 int old_width
= m_width
;
535 int old_height
= m_height
;
537 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
539 if (x
!= -1) m_x
= x
;
540 if (y
!= -1) m_y
= y
;
541 if (width
!= -1) m_width
= width
;
542 if (height
!= -1) m_height
= height
;
553 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
555 if (width == -1) m_width = 80;
558 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
560 if (height == -1) m_height = 26;
564 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
565 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
566 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
567 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
569 if ((m_x
!= -1) || (m_y
!= -1))
571 if ((m_x
!= old_x
) || (m_y
!= old_y
))
573 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
577 if ((m_width
!= old_width
) || (m_height
!= old_height
))
579 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
580 done either directly before the frame is shown or in idle time
581 so that different calls to SetSize() don't lead to flicker. */
588 void wxFrame::Centre( int direction
)
590 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
595 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
596 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
601 void wxFrame::DoGetClientSize( int *width
, int *height
) const
603 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
605 wxWindow::DoGetClientSize( width
, height
);
611 if (!m_menuBarDetached
)
612 (*height
) -= wxMENU_HEIGHT
;
614 (*height
) -= wxPLACE_HOLDER
;
619 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
626 if (!m_toolBarDetached
)
629 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
633 (*height
) -= wxPLACE_HOLDER
;
638 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
642 (*width
) -= m_miniEdge
*2;
646 void wxFrame::DoSetClientSize( int width
, int height
)
648 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
653 if (!m_menuBarDetached
)
654 height
+= wxMENU_HEIGHT
;
656 height
+= wxPLACE_HOLDER
;
661 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
668 if (!m_toolBarDetached
)
671 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
675 height
+= wxPLACE_HOLDER
;
679 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
682 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
684 // due to a bug in gtk, x,y are always 0
688 /* avoid recursions */
689 if (m_resizing
) return;
692 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
693 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
698 /* space occupied by m_frameToolBar and m_frameMenuBar */
699 int client_area_y_offset
= 0;
701 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
702 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
703 set in wxFrame::Create so it is used to check what kind of frame we
704 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
705 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
706 importantly) m_mainWidget */
710 /* check if size is in legal range */
711 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
712 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
713 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
714 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
716 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
717 * menubar, the toolbar and the client area, which is represented by
719 * this hurts in the eye, but I don't want to call SetSize()
720 * because I don't want to call any non-native functions here. */
725 int yy
= m_miniEdge
+ m_miniTitle
;
726 int ww
= m_width
- 2*m_miniEdge
;
727 int hh
= wxMENU_HEIGHT
;
728 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
729 m_frameMenuBar
->m_x
= xx
;
730 m_frameMenuBar
->m_y
= yy
;
731 m_frameMenuBar
->m_width
= ww
;
732 m_frameMenuBar
->m_height
= hh
;
733 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
734 m_frameMenuBar
->m_widget
,
736 client_area_y_offset
+= hh
;
740 if ((m_frameToolBar
) &&
741 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
744 int yy
= m_miniEdge
+ m_miniTitle
;
747 if (!m_menuBarDetached
)
750 yy
+= wxPLACE_HOLDER
;
752 int ww
= m_width
- 2*m_miniEdge
;
753 int hh
= m_frameToolBar
->m_height
;
754 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
755 m_frameToolBar
->m_x
= xx
;
756 m_frameToolBar
->m_y
= yy
;
757 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
758 m_frameToolBar->m_width = ww; */
759 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
760 m_frameToolBar
->m_widget
,
762 client_area_y_offset
+= hh
;
766 int client_x
= m_miniEdge
;
767 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
768 int client_w
= m_width
- 2*m_miniEdge
;
769 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
770 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
772 client_x
, client_y
, client_w
, client_h
);
776 /* if there is no m_mainWidget between m_widget and m_wxwindow there
777 is no need to set the size or position of m_wxwindow. */
781 if (m_frameStatusBar
)
783 int xx
= 0 + m_miniEdge
;
784 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
785 int ww
= m_width
- 2*m_miniEdge
;
786 int hh
= wxSTATUS_HEIGHT
;
787 m_frameStatusBar
->m_x
= xx
;
788 m_frameStatusBar
->m_y
= yy
;
789 m_frameStatusBar
->m_width
= ww
;
790 m_frameStatusBar
->m_height
= hh
;
791 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
792 m_frameStatusBar
->m_widget
,
797 /* we actually set the size of a frame here and no-where else */
798 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
803 // send size event to frame
804 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
805 event
.SetEventObject( this );
806 GetEventHandler()->ProcessEvent( event
);
808 // send size event to status bar
809 if (m_frameStatusBar
)
811 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
812 event2
.SetEventObject( m_frameStatusBar
);
813 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
819 void wxFrame::MakeModal( bool modal
)
822 gtk_grab_add( m_widget
);
824 gtk_grab_remove( m_widget
);
827 void wxFrame::OnInternalIdle()
829 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
831 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
833 // we'll come back later
835 wxapp_install_idle_handler();
839 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
841 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
844 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
847 wxWindow::OnInternalIdle();
850 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
855 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
857 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
859 #if wxUSE_CONSTRAINTS
865 #endif // wxUSE_CONSTRAINTS
867 /* do we have exactly one child? */
868 wxWindow
*child
= (wxWindow
*)NULL
;
869 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
871 wxWindow
*win
= (wxWindow
*)node
->Data();
872 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
876 /* it's the second one: do nothing */
884 /* no children at all? */
887 /* yes: set it's size to fill all the frame */
888 int client_x
, client_y
;
889 DoGetClientSize( &client_x
, &client_y
);
890 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
895 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
897 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
898 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
900 m_frameMenuBar
= menuBar
;
904 m_frameMenuBar
->SetInvokingWindow( this );
906 if (m_frameMenuBar
->GetParent() != this)
908 m_frameMenuBar
->SetParent(this);
909 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
910 m_frameMenuBar
->m_widget
,
913 m_frameMenuBar
->m_width
,
914 m_frameMenuBar
->m_height
);
916 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
918 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
919 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
921 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
922 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
925 m_frameMenuBar
->Show( TRUE
);
929 /* resize window in OnInternalIdle */
933 wxMenuBar
*wxFrame::GetMenuBar() const
935 return m_frameMenuBar
;
938 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
943 // if no help string found, we will clear the status bar text
946 int menuId
= event
.GetMenuId();
947 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
949 wxMenuBar
*menuBar
= GetMenuBar();
952 // it's ok if we don't find the item because it might belong to
954 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
956 helpString
= item
->GetHelp();
960 SetStatusText(helpString
);
962 #endif // wxUSE_STATUSBAR
966 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
968 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
970 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
972 m_insertInClientArea
= FALSE
;
974 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
976 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
978 m_insertInClientArea
= TRUE
;
982 return m_frameToolBar
;
985 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
987 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
990 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
992 m_frameToolBar
= toolbar
;
995 /* insert into toolbar area if not already there */
996 if ((m_frameToolBar
->m_widget
->parent
) &&
997 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
999 GetChildren().DeleteObject( m_frameToolBar
);
1001 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1007 wxToolBar
*wxFrame::GetToolBar() const
1009 return m_frameToolBar
;
1011 #endif // wxUSE_TOOLBAR
1014 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1016 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1018 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1020 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1024 return m_frameStatusBar
;
1027 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1029 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1031 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1033 // Set the height according to the font and the border size
1034 wxClientDC
dc(statusBar
);
1035 dc
.SetFont( statusBar
->GetFont() );
1038 dc
.GetTextExtent( "X", &x
, &y
);
1040 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1042 statusBar
->SetSize( -1, -1, 100, height
);
1044 statusBar
->SetFieldsCount( number
);
1048 wxStatusBar
*wxFrame::GetStatusBar() const
1050 return m_frameStatusBar
;
1053 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1055 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1057 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1059 m_frameStatusBar
->SetStatusText(text
, number
);
1062 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1064 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1066 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1068 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1070 #endif // wxUSE_STATUSBAR
1072 void wxFrame::Command( int id
)
1074 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1075 commandEvent
.SetInt( id
);
1076 commandEvent
.SetEventObject( this );
1078 wxMenuBar
*bar
= GetMenuBar();
1081 wxMenuItem
*item
= bar
->FindItem(id
) ;
1082 if (item
&& item
->IsCheckable())
1084 bar
->Check(id
, !bar
->IsChecked(id
)) ;
1087 wxEvtHandler
* evtHandler
= GetEventHandler();
1089 evtHandler
->ProcessEvent(commandEvent
);
1092 void wxFrame::SetTitle( const wxString
&title
)
1094 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1097 if (m_title
.IsNull()) m_title
= wxT("");
1098 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1101 void wxFrame::SetIcon( const wxIcon
&icon
)
1103 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1106 if (!icon
.Ok()) return;
1108 if (!m_widget
->window
) return;
1110 wxMask
*mask
= icon
.GetMask();
1111 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1112 if (mask
) bm
= mask
->GetBitmap();
1114 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1117 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1121 void wxFrame::Restore()
1125 void wxFrame::Iconize( bool iconize
)
1129 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1130 GDK_WINDOW_XWINDOW( m_widget
->window
),
1131 DefaultScreen( GDK_DISPLAY() ) );
1135 bool wxFrame::IsIconized() const