1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
19 #pragma implementation "frame.h"
23 #define XIconifyWindow XICONIFYWINDOW
27 #include "wx/dialog.h"
28 #include "wx/control.h"
32 #include "wx/toolbar.h"
35 #include "wx/statusbr.h"
37 #include "wx/dcclient.h"
42 #include <gdk/gdkkeysyms.h>
45 #include "wx/gtk/win_gtk.h"
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 const int wxMENU_HEIGHT
= 27;
52 const int wxSTATUS_HEIGHT
= 25;
53 const int wxPLACE_HOLDER
= 0;
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 extern void wxapp_install_idle_handler();
61 extern int g_openDialogs
;
63 // ----------------------------------------------------------------------------
65 // ----------------------------------------------------------------------------
67 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 extern wxList wxPendingDelete
;
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
81 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
85 // ============================================================================
87 // ============================================================================
89 // ----------------------------------------------------------------------------
91 // ----------------------------------------------------------------------------
93 //-----------------------------------------------------------------------------
94 // "focus" from m_window
95 //-----------------------------------------------------------------------------
97 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
100 wxapp_install_idle_handler();
102 // This disables GTK's tab traversal
103 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
107 //-----------------------------------------------------------------------------
109 //-----------------------------------------------------------------------------
111 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
114 wxapp_install_idle_handler();
119 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
122 wxPrintf( "OnSize from " );
123 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
124 wxPrintf( win->GetClassInfo()->GetClassName() );
125 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
128 (int)alloc->height );
131 win
->m_width
= alloc
->width
;
132 win
->m_height
= alloc
->height
;
133 win
->m_queuedFullRedraw
= TRUE
;
134 win
->GtkUpdateSize();
138 //-----------------------------------------------------------------------------
140 //-----------------------------------------------------------------------------
142 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
145 wxapp_install_idle_handler();
147 if ((g_openDialogs
== 0) && (win
->IsEnabled()))
153 //-----------------------------------------------------------------------------
154 // "child_attached" of menu bar
155 //-----------------------------------------------------------------------------
157 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
159 if (!win
->m_hasVMT
) return;
161 win
->m_menuBarDetached
= FALSE
;
162 win
->GtkUpdateSize();
165 //-----------------------------------------------------------------------------
166 // "child_detached" of menu bar
167 //-----------------------------------------------------------------------------
169 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
171 if (!win
->m_hasVMT
) return;
173 win
->m_menuBarDetached
= TRUE
;
174 win
->GtkUpdateSize();
178 //-----------------------------------------------------------------------------
179 // "child_attached" of tool bar
180 //-----------------------------------------------------------------------------
182 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
184 if (!win
->m_hasVMT
) return;
186 win
->m_toolBarDetached
= FALSE
;
188 win
->GtkUpdateSize();
191 //-----------------------------------------------------------------------------
192 // "child_detached" of tool bar
193 //-----------------------------------------------------------------------------
195 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
198 wxapp_install_idle_handler();
200 if (!win
->m_hasVMT
) return;
202 win
->m_toolBarDetached
= TRUE
;
203 win
->GtkUpdateSize();
205 #endif // wxUSE_TOOLBAR
207 //-----------------------------------------------------------------------------
209 //-----------------------------------------------------------------------------
212 #if (GTK_MINOR_VERSION > 0)
213 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
215 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
219 wxapp_install_idle_handler();
224 #if (GTK_MINOR_VERSION > 0)
227 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
235 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
236 mevent
.SetEventObject( win
);
237 win
->GetEventHandler()->ProcessEvent( mevent
);
242 //-----------------------------------------------------------------------------
243 // "realize" from m_widget
244 //-----------------------------------------------------------------------------
246 /* we cannot MWM hints and icons before the widget has been realized,
247 so we do this directly after realization */
250 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
), wxFrame
*win
)
253 wxapp_install_idle_handler();
255 if ((win
->m_miniEdge
> 0) || (win
->HasFlag(wxSIMPLE_BORDER
)))
257 /* This is a mini-frame or a borderless frame. */
258 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)0 );
259 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)0 );
263 /* All this is for Motif Window Manager "hints" and is supposed to be
264 recognized by other WM as well. Not tested. */
265 long decor
= (long) GDK_DECOR_BORDER
;
266 long func
= (long) GDK_FUNC_MOVE
;
268 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
269 decor
|= GDK_DECOR_TITLE
;
270 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
272 decor
|= GDK_DECOR_MENU
;
273 func
|= GDK_FUNC_CLOSE
;
275 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
277 func
|= GDK_FUNC_MINIMIZE
;
278 decor
|= GDK_DECOR_MINIMIZE
;
280 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
282 func
|= GDK_FUNC_MAXIMIZE
;
283 decor
|= GDK_DECOR_MAXIMIZE
;
285 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
287 func
|= GDK_FUNC_RESIZE
;
288 decor
|= GDK_DECOR_RESIZEH
;
291 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
292 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
295 /* GTK's shrinking/growing policy */
296 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
297 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
299 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
302 wxIcon iconOld
= win
->GetIcon();
303 if ( iconOld
!= wxNullIcon
)
305 wxIcon
icon( iconOld
);
306 win
->SetIcon( wxNullIcon
);
307 win
->SetIcon( icon
);
310 /* we set the focus to the child that accepts the focus. this
311 doesn't really have to be done in "realize" but why not? */
312 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
315 wxWindow
*child
= node
->GetData();
316 if (child
->AcceptsFocus())
322 node
= node
->GetNext();
328 // ----------------------------------------------------------------------------
330 // ----------------------------------------------------------------------------
332 //-----------------------------------------------------------------------------
333 // InsertChild for wxFrame
334 //-----------------------------------------------------------------------------
336 /* Callback for wxFrame. This very strange beast has to be used because
337 * C++ has no virtual methods in a constructor. We have to emulate a
338 * virtual function here as wxWindows requires different ways to insert
339 * a child in container classes. */
341 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
343 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
345 if (!parent
->m_insertInClientArea
)
347 /* these are outside the client area */
348 wxFrame
* frame
= (wxFrame
*) parent
;
349 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
350 GTK_WIDGET(child
->m_widget
),
356 #if wxUSE_TOOLBAR_NATIVE
357 /* we connect to these events for recalculating the client area
358 space when the toolbar is floating */
359 if (wxIS_KIND_OF(child
,wxToolBar
))
361 wxToolBar
*toolBar
= (wxToolBar
*) child
;
362 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
364 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
365 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
367 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
368 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
371 #endif // wxUSE_TOOLBAR
375 /* these are inside the client area */
376 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
377 GTK_WIDGET(child
->m_widget
),
384 /* resize on OnInternalIdle */
385 parent
->GtkUpdateSize();
388 // ----------------------------------------------------------------------------
390 // ----------------------------------------------------------------------------
397 m_mainWidget
= (GtkWidget
*) NULL
;
398 m_menuBarDetached
= FALSE
;
399 m_toolBarDetached
= FALSE
;
400 m_insertInClientArea
= TRUE
;
403 bool wxFrame::Create( wxWindow
*parent
,
405 const wxString
&title
,
409 const wxString
&name
)
411 wxTopLevelWindows
.Append( this );
413 m_needParent
= FALSE
;
414 m_fsIsShowing
= FALSE
;
416 if (!PreCreation( parent
, pos
, size
) ||
417 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
419 wxFAIL_MSG( wxT("wxFrame creation failed") );
425 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
427 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
429 m_widget
= gtk_window_new( win_type
);
431 if ((m_parent
) && (HasFlag(wxFRAME_FLOAT_ON_PARENT
)) && (GTK_IS_WINDOW(m_parent
->m_widget
)))
432 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
435 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
438 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
441 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
442 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
444 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
445 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
447 /* m_mainWidget holds the toolbar, the menubar and the client area */
448 m_mainWidget
= gtk_pizza_new();
449 gtk_widget_show( m_mainWidget
);
450 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
451 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
454 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
457 /* m_wxwindow only represents the client area without toolbar and menubar */
458 m_wxwindow
= gtk_pizza_new();
459 gtk_widget_show( m_wxwindow
);
460 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
463 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
466 /* we donm't allow the frame to get the focus as otherwise
467 the frame will grabit at arbitrary fcous changes. */
468 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
470 if (m_parent
) m_parent
->AddChild( this );
472 /* the user resized the frame by dragging etc. */
473 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
474 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
478 if ((m_x
!= -1) || (m_y
!= -1))
479 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
480 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
482 /* we cannot set MWM hints and icons before the widget has
483 been realized, so we do this directly after realization */
484 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
485 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
487 /* the only way to get the window size is to connect to this event */
488 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
489 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
491 /* disable native tab traversal */
492 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
493 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
500 m_isBeingDeleted
= TRUE
;
504 wxTopLevelWindows
.DeleteObject( this );
506 if (wxTheApp
->GetTopWindow() == this)
507 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
509 if ((wxTopLevelWindows
.Number() == 0) &&
510 (wxTheApp
->GetExitOnFrameDelete()))
512 wxTheApp
->ExitMainLoop();
516 bool wxFrame::ShowFullScreen(bool show
, long style
)
518 if (show
== m_fsIsShowing
) return FALSE
; // return what?
520 m_fsIsShowing
= show
;
524 m_fsSaveStyle
= m_windowStyle
;
525 m_fsSaveFlag
= style
;
526 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
527 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
529 gtk_widget_hide( m_widget
);
530 gtk_widget_unrealize( m_widget
);
532 m_windowStyle
= wxSIMPLE_BORDER
;
536 wxDisplaySize( &x
, &y
);
537 SetSize( 0, 0, x
, y
);
539 gtk_widget_realize( m_widget
);
540 gtk_widget_show( m_widget
);
544 gtk_widget_hide( m_widget
);
545 gtk_widget_unrealize( m_widget
);
547 m_windowStyle
= m_fsSaveStyle
;
549 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
551 gtk_widget_realize( m_widget
);
552 gtk_widget_show( m_widget
);
558 // ----------------------------------------------------------------------------
559 // overridden wxWindow methods
560 // ----------------------------------------------------------------------------
562 bool wxFrame::Show( bool show
)
564 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
566 if (show
&& !m_sizeSet
)
568 /* by calling GtkOnSize here, we don't have to call
569 either after showing the frame, which would entail
570 much ugly flicker or from within the size_allocate
571 handler, because GTK 1.1.X forbids that. */
573 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
576 return wxWindow::Show( show
);
579 void wxFrame::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
581 wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
584 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
586 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
588 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
589 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
591 /* avoid recursions */
599 int old_width
= m_width
;
600 int old_height
= m_height
;
602 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
604 if (x
!= -1) m_x
= x
;
605 if (y
!= -1) m_y
= y
;
606 if (width
!= -1) m_width
= width
;
607 if (height
!= -1) m_height
= height
;
618 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
620 if (width == -1) m_width = 80;
623 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
625 if (height == -1) m_height = 26;
629 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
630 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
631 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
632 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
634 if ((m_x
!= -1) || (m_y
!= -1))
636 if ((m_x
!= old_x
) || (m_y
!= old_y
))
638 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
642 if ((m_width
!= old_width
) || (m_height
!= old_height
))
644 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
646 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
647 done either directly before the frame is shown or in idle time
648 so that different calls to SetSize() don't lead to flicker. */
655 void wxFrame::DoGetClientSize( int *width
, int *height
) const
657 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
659 wxWindow::DoGetClientSize( width
, height
);
665 if (!m_menuBarDetached
)
666 (*height
) -= wxMENU_HEIGHT
;
668 (*height
) -= wxPLACE_HOLDER
;
673 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) (*height
) -= wxSTATUS_HEIGHT
;
674 #endif // wxUSE_STATUSBAR
678 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
680 if (m_toolBarDetached
)
682 *height
-= wxPLACE_HOLDER
;
687 m_frameToolBar
->GetSize( &x
, &y
);
688 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
698 #endif // wxUSE_TOOLBAR
701 *height
-= m_miniEdge
*2 + m_miniTitle
;
705 *width
-= m_miniEdge
*2;
709 void wxFrame::DoSetClientSize( int width
, int height
)
711 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
716 if (!m_menuBarDetached
)
717 height
+= wxMENU_HEIGHT
;
719 height
+= wxPLACE_HOLDER
;
724 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) height
+= wxSTATUS_HEIGHT
;
729 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
731 if (m_toolBarDetached
)
733 height
+= wxPLACE_HOLDER
;
738 m_frameToolBar
->GetSize( &x
, &y
);
739 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
751 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
754 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
755 int width
, int height
)
757 // due to a bug in gtk, x,y are always 0
761 /* avoid recursions */
762 if (m_resizing
) return;
765 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
766 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
771 /* space occupied by m_frameToolBar and m_frameMenuBar */
772 int client_area_x_offset
= 0,
773 client_area_y_offset
= 0;
775 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
776 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
777 set in wxFrame::Create so it is used to check what kind of frame we
778 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
779 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
780 importantly) m_mainWidget */
782 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
783 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
784 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
785 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
790 gint flag
= 0; // GDK_HINT_POS;
791 if ((m_minWidth
!= -1) || (m_minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
792 if ((m_maxWidth
!= -1) || (m_maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
794 geom
.min_width
= m_minWidth
;
795 geom
.min_height
= m_minHeight
;
796 geom
.max_width
= m_maxWidth
;
797 geom
.max_height
= m_maxHeight
;
798 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
801 (GdkWindowHints
) flag
);
803 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
804 * menubar, the toolbar and the client area, which is represented by
806 * this hurts in the eye, but I don't want to call SetSize()
807 * because I don't want to call any non-native functions here. */
812 int yy
= m_miniEdge
+ m_miniTitle
;
813 int ww
= m_width
- 2*m_miniEdge
;
814 int hh
= wxMENU_HEIGHT
;
815 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
816 m_frameMenuBar
->m_x
= xx
;
817 m_frameMenuBar
->m_y
= yy
;
818 m_frameMenuBar
->m_width
= ww
;
819 m_frameMenuBar
->m_height
= hh
;
820 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
821 m_frameMenuBar
->m_widget
,
823 client_area_y_offset
+= hh
;
827 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
828 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
831 int yy
= m_miniEdge
+ m_miniTitle
;
834 if (!m_menuBarDetached
)
837 yy
+= wxPLACE_HOLDER
;
840 m_frameToolBar
->m_x
= xx
;
841 m_frameToolBar
->m_y
= yy
;
843 /* don't change the toolbar's reported height/width */
845 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
847 ww
= m_toolBarDetached
? wxPLACE_HOLDER
848 : m_frameToolBar
->m_width
;
849 hh
= m_height
- 2*m_miniEdge
;
851 client_area_x_offset
+= ww
;
855 ww
= m_width
- 2*m_miniEdge
;
856 hh
= m_toolBarDetached
? wxPLACE_HOLDER
857 : m_frameToolBar
->m_height
;
859 client_area_y_offset
+= hh
;
862 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
863 m_frameToolBar
->m_widget
,
866 #endif // wxUSE_TOOLBAR
868 int client_x
= client_area_x_offset
+ m_miniEdge
;
869 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
870 int client_w
= m_width
- client_area_x_offset
- 2*m_miniEdge
;
871 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
872 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
874 client_x
, client_y
, client_w
, client_h
);
878 /* if there is no m_mainWidget between m_widget and m_wxwindow there
879 is no need to set the size or position of m_wxwindow. */
883 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
885 int xx
= 0 + m_miniEdge
;
886 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
887 int ww
= m_width
- 2*m_miniEdge
;
888 int hh
= wxSTATUS_HEIGHT
;
889 m_frameStatusBar
->m_x
= xx
;
890 m_frameStatusBar
->m_y
= yy
;
891 m_frameStatusBar
->m_width
= ww
;
892 m_frameStatusBar
->m_height
= hh
;
893 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
894 m_frameStatusBar
->m_widget
,
896 gtk_widget_draw( m_frameStatusBar
->m_widget
, (GdkRectangle
*) NULL
);
902 // send size event to frame
903 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
904 event
.SetEventObject( this );
905 GetEventHandler()->ProcessEvent( event
);
907 // send size event to status bar
908 if (m_frameStatusBar
)
910 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
911 event2
.SetEventObject( m_frameStatusBar
);
912 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
918 void wxFrame::MakeModal( bool modal
)
921 gtk_grab_add( m_widget
);
923 gtk_grab_remove( m_widget
);
926 void wxFrame::OnInternalIdle()
928 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
930 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
932 // we'll come back later
934 wxapp_install_idle_handler();
938 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
940 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
943 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
946 wxWindow::OnInternalIdle();
949 // ----------------------------------------------------------------------------
950 // menu/tool/status bar stuff
951 // ----------------------------------------------------------------------------
953 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
955 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
956 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
958 if (menuBar
== m_frameMenuBar
)
963 m_frameMenuBar
->UnsetInvokingWindow( this );
965 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
967 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
968 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
970 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
971 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
974 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
975 gtk_widget_ref( m_frameMenuBar
->m_widget
);
976 gtk_widget_unparent( m_frameMenuBar
->m_widget
);
979 m_frameMenuBar
= menuBar
;
983 m_frameMenuBar
->SetInvokingWindow( this );
985 m_frameMenuBar
->SetParent(this);
986 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
987 m_frameMenuBar
->m_widget
,
990 m_frameMenuBar
->m_width
,
991 m_frameMenuBar
->m_height
);
993 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
995 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
996 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
998 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
999 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1002 m_frameMenuBar
->Show( TRUE
);
1005 /* resize window in OnInternalIdle */
1010 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1012 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1014 m_insertInClientArea
= FALSE
;
1016 m_frameToolBar
= wxFrameBase::CreateToolBar( style
, id
, name
);
1018 m_insertInClientArea
= TRUE
;
1022 return m_frameToolBar
;
1025 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1027 wxFrameBase::SetToolBar(toolbar
);
1031 /* insert into toolbar area if not already there */
1032 if ((m_frameToolBar
->m_widget
->parent
) &&
1033 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1035 GetChildren().DeleteObject( m_frameToolBar
);
1037 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1043 #endif // wxUSE_TOOLBAR
1047 wxStatusBar
* wxFrame::CreateStatusBar(int number
,
1050 const wxString
& name
)
1052 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1054 // because it will change when toolbar is added
1057 return wxFrameBase::CreateStatusBar( number
, style
, id
, name
);
1060 void wxFrame::PositionStatusBar()
1062 if ( !m_frameStatusBar
)
1067 #endif // wxUSE_STATUSBAR
1069 // ----------------------------------------------------------------------------
1071 // ----------------------------------------------------------------------------
1073 void wxFrame::SetTitle( const wxString
&title
)
1075 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1078 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1081 void wxFrame::SetIcon( const wxIcon
&icon
)
1083 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1085 wxFrameBase::SetIcon(icon
);
1090 if (!m_widget
->window
)
1093 wxMask
*mask
= icon
.GetMask();
1094 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1095 if (mask
) bm
= mask
->GetBitmap();
1097 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1100 // ----------------------------------------------------------------------------
1101 // frame state: maximized/iconized/normal (TODO)
1102 // ----------------------------------------------------------------------------
1104 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1108 bool wxFrame::IsMaximized() const
1113 void wxFrame::Restore()
1117 void wxFrame::Iconize( bool iconize
)
1121 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1122 GDK_WINDOW_XWINDOW( m_widget
->window
),
1123 DefaultScreen( GDK_DISPLAY() ) );
1127 bool wxFrame::IsIconized() const