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
)) || (win
->HasFlag(wxNO_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 if (style
& wxFRAME_TOOL_WINDOW
)
430 win_type
= GTK_WINDOW_POPUP
;
432 m_widget
= gtk_window_new( win_type
);
434 if ((m_parent
) && (HasFlag(wxFRAME_FLOAT_ON_PARENT
)) && (GTK_IS_WINDOW(m_parent
->m_widget
)))
435 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
438 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
441 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
444 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
445 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
447 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
448 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
450 /* m_mainWidget holds the toolbar, the menubar and the client area */
451 m_mainWidget
= gtk_pizza_new();
452 gtk_widget_show( m_mainWidget
);
453 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
454 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
457 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
460 /* m_wxwindow only represents the client area without toolbar and menubar */
461 m_wxwindow
= gtk_pizza_new();
462 gtk_widget_show( m_wxwindow
);
463 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
466 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
469 /* we donm't allow the frame to get the focus as otherwise
470 the frame will grabit at arbitrary fcous changes. */
471 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
473 if (m_parent
) m_parent
->AddChild( this );
475 /* the user resized the frame by dragging etc. */
476 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
477 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
481 if ((m_x
!= -1) || (m_y
!= -1))
482 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
483 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
485 /* we cannot set MWM hints and icons before the widget has
486 been realized, so we do this directly after realization */
487 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
488 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
490 /* the only way to get the window size is to connect to this event */
491 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
492 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
494 /* disable native tab traversal */
495 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
496 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
503 m_isBeingDeleted
= TRUE
;
507 wxTopLevelWindows
.DeleteObject( this );
509 if (wxTheApp
->GetTopWindow() == this)
510 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
512 if ((wxTopLevelWindows
.Number() == 0) &&
513 (wxTheApp
->GetExitOnFrameDelete()))
515 wxTheApp
->ExitMainLoop();
519 bool wxFrame::ShowFullScreen(bool show
, long style
)
521 if (show
== m_fsIsShowing
) return FALSE
; // return what?
523 m_fsIsShowing
= show
;
527 m_fsSaveStyle
= m_windowStyle
;
528 m_fsSaveFlag
= style
;
529 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
530 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
532 gtk_widget_hide( m_widget
);
533 gtk_widget_unrealize( m_widget
);
535 m_windowStyle
= wxSIMPLE_BORDER
;
539 wxDisplaySize( &x
, &y
);
540 SetSize( 0, 0, x
, y
);
542 gtk_widget_realize( m_widget
);
543 gtk_widget_show( m_widget
);
547 gtk_widget_hide( m_widget
);
548 gtk_widget_unrealize( m_widget
);
550 m_windowStyle
= m_fsSaveStyle
;
552 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
554 gtk_widget_realize( m_widget
);
555 gtk_widget_show( m_widget
);
561 // ----------------------------------------------------------------------------
562 // overridden wxWindow methods
563 // ----------------------------------------------------------------------------
565 bool wxFrame::Show( bool show
)
567 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
569 if (show
&& !m_sizeSet
)
571 /* by calling GtkOnSize here, we don't have to call
572 either after showing the frame, which would entail
573 much ugly flicker or from within the size_allocate
574 handler, because GTK 1.1.X forbids that. */
576 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
579 return wxWindow::Show( show
);
582 void wxFrame::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
584 wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
587 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
589 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
591 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
592 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
594 /* avoid recursions */
602 int old_width
= m_width
;
603 int old_height
= m_height
;
605 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
607 if (x
!= -1) m_x
= x
;
608 if (y
!= -1) m_y
= y
;
609 if (width
!= -1) m_width
= width
;
610 if (height
!= -1) m_height
= height
;
621 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
623 if (width == -1) m_width = 80;
626 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
628 if (height == -1) m_height = 26;
632 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
633 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
634 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
635 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
637 if ((m_x
!= -1) || (m_y
!= -1))
639 if ((m_x
!= old_x
) || (m_y
!= old_y
))
641 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
645 if ((m_width
!= old_width
) || (m_height
!= old_height
))
647 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
649 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
650 done either directly before the frame is shown or in idle time
651 so that different calls to SetSize() don't lead to flicker. */
658 void wxFrame::DoGetClientSize( int *width
, int *height
) const
660 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
662 wxWindow::DoGetClientSize( width
, height
);
668 if (!m_menuBarDetached
)
669 (*height
) -= wxMENU_HEIGHT
;
671 (*height
) -= wxPLACE_HOLDER
;
676 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) (*height
) -= wxSTATUS_HEIGHT
;
677 #endif // wxUSE_STATUSBAR
681 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
683 if (m_toolBarDetached
)
685 *height
-= wxPLACE_HOLDER
;
690 m_frameToolBar
->GetSize( &x
, &y
);
691 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
701 #endif // wxUSE_TOOLBAR
704 *height
-= m_miniEdge
*2 + m_miniTitle
;
708 *width
-= m_miniEdge
*2;
712 void wxFrame::DoSetClientSize( int width
, int height
)
714 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
719 if (!m_menuBarDetached
)
720 height
+= wxMENU_HEIGHT
;
722 height
+= wxPLACE_HOLDER
;
727 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) height
+= wxSTATUS_HEIGHT
;
732 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
734 if (m_toolBarDetached
)
736 height
+= wxPLACE_HOLDER
;
741 m_frameToolBar
->GetSize( &x
, &y
);
742 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
754 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
757 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
758 int width
, int height
)
760 // due to a bug in gtk, x,y are always 0
764 /* avoid recursions */
765 if (m_resizing
) return;
768 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
769 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
774 /* space occupied by m_frameToolBar and m_frameMenuBar */
775 int client_area_x_offset
= 0,
776 client_area_y_offset
= 0;
778 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
779 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
780 set in wxFrame::Create so it is used to check what kind of frame we
781 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
782 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
783 importantly) m_mainWidget */
785 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
786 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
787 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
788 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
793 gint flag
= 0; // GDK_HINT_POS;
794 if ((m_minWidth
!= -1) || (m_minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
795 if ((m_maxWidth
!= -1) || (m_maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
797 geom
.min_width
= m_minWidth
;
798 geom
.min_height
= m_minHeight
;
799 geom
.max_width
= m_maxWidth
;
800 geom
.max_height
= m_maxHeight
;
801 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
804 (GdkWindowHints
) flag
);
806 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
807 * menubar, the toolbar and the client area, which is represented by
809 * this hurts in the eye, but I don't want to call SetSize()
810 * because I don't want to call any non-native functions here. */
815 int yy
= m_miniEdge
+ m_miniTitle
;
816 int ww
= m_width
- 2*m_miniEdge
;
817 int hh
= wxMENU_HEIGHT
;
818 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
819 m_frameMenuBar
->m_x
= xx
;
820 m_frameMenuBar
->m_y
= yy
;
821 m_frameMenuBar
->m_width
= ww
;
822 m_frameMenuBar
->m_height
= hh
;
823 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
824 m_frameMenuBar
->m_widget
,
826 client_area_y_offset
+= hh
;
830 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
831 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
834 int yy
= m_miniEdge
+ m_miniTitle
;
837 if (!m_menuBarDetached
)
840 yy
+= wxPLACE_HOLDER
;
843 m_frameToolBar
->m_x
= xx
;
844 m_frameToolBar
->m_y
= yy
;
846 /* don't change the toolbar's reported height/width */
848 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
850 ww
= m_toolBarDetached
? wxPLACE_HOLDER
851 : m_frameToolBar
->m_width
;
852 hh
= m_height
- 2*m_miniEdge
;
854 client_area_x_offset
+= ww
;
858 ww
= m_width
- 2*m_miniEdge
;
859 hh
= m_toolBarDetached
? wxPLACE_HOLDER
860 : m_frameToolBar
->m_height
;
862 client_area_y_offset
+= hh
;
865 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
866 m_frameToolBar
->m_widget
,
869 #endif // wxUSE_TOOLBAR
871 int client_x
= client_area_x_offset
+ m_miniEdge
;
872 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
873 int client_w
= m_width
- client_area_x_offset
- 2*m_miniEdge
;
874 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
875 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
877 client_x
, client_y
, client_w
, client_h
);
881 /* if there is no m_mainWidget between m_widget and m_wxwindow there
882 is no need to set the size or position of m_wxwindow. */
886 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
888 int xx
= 0 + m_miniEdge
;
889 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
890 int ww
= m_width
- 2*m_miniEdge
;
891 int hh
= wxSTATUS_HEIGHT
;
892 m_frameStatusBar
->m_x
= xx
;
893 m_frameStatusBar
->m_y
= yy
;
894 m_frameStatusBar
->m_width
= ww
;
895 m_frameStatusBar
->m_height
= hh
;
896 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
897 m_frameStatusBar
->m_widget
,
899 gtk_widget_draw( m_frameStatusBar
->m_widget
, (GdkRectangle
*) NULL
);
905 // send size event to frame
906 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
907 event
.SetEventObject( this );
908 GetEventHandler()->ProcessEvent( event
);
910 // send size event to status bar
911 if (m_frameStatusBar
)
913 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
914 event2
.SetEventObject( m_frameStatusBar
);
915 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
921 void wxFrame::MakeModal( bool modal
)
924 gtk_grab_add( m_widget
);
926 gtk_grab_remove( m_widget
);
929 void wxFrame::OnInternalIdle()
931 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
933 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
935 // we'll come back later
937 wxapp_install_idle_handler();
941 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
943 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
946 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
949 wxWindow::OnInternalIdle();
952 // ----------------------------------------------------------------------------
953 // menu/tool/status bar stuff
954 // ----------------------------------------------------------------------------
956 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
958 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
959 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
961 if (menuBar
== m_frameMenuBar
)
966 m_frameMenuBar
->UnsetInvokingWindow( this );
968 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
970 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
971 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
973 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
974 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
977 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
978 gtk_widget_ref( m_frameMenuBar
->m_widget
);
979 gtk_widget_unparent( m_frameMenuBar
->m_widget
);
982 m_frameMenuBar
= menuBar
;
986 m_frameMenuBar
->SetInvokingWindow( this );
988 m_frameMenuBar
->SetParent(this);
989 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
990 m_frameMenuBar
->m_widget
,
993 m_frameMenuBar
->m_width
,
994 m_frameMenuBar
->m_height
);
996 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
998 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
999 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1001 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
1002 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1005 m_frameMenuBar
->Show( TRUE
);
1008 /* resize window in OnInternalIdle */
1013 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1015 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1017 m_insertInClientArea
= FALSE
;
1019 m_frameToolBar
= wxFrameBase::CreateToolBar( style
, id
, name
);
1021 m_insertInClientArea
= TRUE
;
1025 return m_frameToolBar
;
1028 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1030 wxFrameBase::SetToolBar(toolbar
);
1034 /* insert into toolbar area if not already there */
1035 if ((m_frameToolBar
->m_widget
->parent
) &&
1036 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1038 GetChildren().DeleteObject( m_frameToolBar
);
1040 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1046 #endif // wxUSE_TOOLBAR
1050 wxStatusBar
* wxFrame::CreateStatusBar(int number
,
1053 const wxString
& name
)
1055 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1057 // because it will change when toolbar is added
1060 return wxFrameBase::CreateStatusBar( number
, style
, id
, name
);
1063 void wxFrame::PositionStatusBar()
1065 if ( !m_frameStatusBar
)
1070 #endif // wxUSE_STATUSBAR
1072 // ----------------------------------------------------------------------------
1074 // ----------------------------------------------------------------------------
1076 void wxFrame::SetTitle( const wxString
&title
)
1078 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1081 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1084 void wxFrame::SetIcon( const wxIcon
&icon
)
1086 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1088 wxFrameBase::SetIcon(icon
);
1093 if (!m_widget
->window
)
1096 wxMask
*mask
= icon
.GetMask();
1097 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1098 if (mask
) bm
= mask
->GetBitmap();
1100 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1103 // ----------------------------------------------------------------------------
1104 // frame state: maximized/iconized/normal (TODO)
1105 // ----------------------------------------------------------------------------
1107 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1111 bool wxFrame::IsMaximized() const
1116 void wxFrame::Restore()
1120 void wxFrame::Iconize( bool iconize
)
1124 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1125 GDK_WINDOW_XWINDOW( m_widget
->window
),
1126 DefaultScreen( GDK_DISPLAY() ) );
1130 bool wxFrame::IsIconized() const