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();
326 //-----------------------------------------------------------------------------
327 // "map_event" from m_widget
328 //-----------------------------------------------------------------------------
331 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
), wxFrame
*win
)
333 win
->m_isIconized
= FALSE
;
336 //-----------------------------------------------------------------------------
337 // "unmap_event" from m_widget
338 //-----------------------------------------------------------------------------
341 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
), wxFrame
*win
)
343 win
->m_isIconized
= TRUE
;
346 // ----------------------------------------------------------------------------
348 // ----------------------------------------------------------------------------
350 //-----------------------------------------------------------------------------
351 // InsertChild for wxFrame
352 //-----------------------------------------------------------------------------
354 /* Callback for wxFrame. This very strange beast has to be used because
355 * C++ has no virtual methods in a constructor. We have to emulate a
356 * virtual function here as wxWindows requires different ways to insert
357 * a child in container classes. */
359 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
361 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
363 if (!parent
->m_insertInClientArea
)
365 /* these are outside the client area */
366 wxFrame
* frame
= (wxFrame
*) parent
;
367 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
368 GTK_WIDGET(child
->m_widget
),
374 #if wxUSE_TOOLBAR_NATIVE
375 /* we connect to these events for recalculating the client area
376 space when the toolbar is floating */
377 if (wxIS_KIND_OF(child
,wxToolBar
))
379 wxToolBar
*toolBar
= (wxToolBar
*) child
;
380 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
382 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
383 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
385 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
386 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
389 #endif // wxUSE_TOOLBAR
393 /* these are inside the client area */
394 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
395 GTK_WIDGET(child
->m_widget
),
402 /* resize on OnInternalIdle */
403 parent
->GtkUpdateSize();
406 // ----------------------------------------------------------------------------
408 // ----------------------------------------------------------------------------
415 m_mainWidget
= (GtkWidget
*) NULL
;
416 m_menuBarDetached
= FALSE
;
417 m_toolBarDetached
= FALSE
;
418 m_insertInClientArea
= TRUE
;
419 m_isIconized
= FALSE
;
420 m_fsIsShowing
= FALSE
;
423 bool wxFrame::Create( wxWindow
*parent
,
425 const wxString
&title
,
429 const wxString
&name
)
431 wxTopLevelWindows
.Append( this );
433 m_needParent
= FALSE
;
435 if (!PreCreation( parent
, pos
, size
) ||
436 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
438 wxFAIL_MSG( wxT("wxFrame creation failed") );
444 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
446 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
448 if (style
& wxFRAME_TOOL_WINDOW
)
449 win_type
= GTK_WINDOW_POPUP
;
451 m_widget
= gtk_window_new( win_type
);
453 if ((m_parent
) && (HasFlag(wxFRAME_FLOAT_ON_PARENT
)) && (GTK_IS_WINDOW(m_parent
->m_widget
)))
454 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
457 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
460 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
463 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
464 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
466 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
467 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
469 /* m_mainWidget holds the toolbar, the menubar and the client area */
470 m_mainWidget
= gtk_pizza_new();
471 gtk_widget_show( m_mainWidget
);
472 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
473 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
476 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
479 /* m_wxwindow only represents the client area without toolbar and menubar */
480 m_wxwindow
= gtk_pizza_new();
481 gtk_widget_show( m_wxwindow
);
482 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
485 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
488 /* we donm't allow the frame to get the focus as otherwise
489 the frame will grabit at arbitrary fcous changes. */
490 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
492 if (m_parent
) m_parent
->AddChild( this );
494 /* the user resized the frame by dragging etc. */
495 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
496 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
500 if ((m_x
!= -1) || (m_y
!= -1))
501 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
502 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
504 /* we cannot set MWM hints and icons before the widget has
505 been realized, so we do this directly after realization */
506 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
507 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
509 /* the only way to get the window size is to connect to this event */
510 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
511 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
513 /* map and unmap for iconized state */
514 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
515 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
516 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
517 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
519 /* the only way to get the window size is to connect to this event */
520 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
521 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
523 /* disable native tab traversal */
524 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
525 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
532 m_isBeingDeleted
= TRUE
;
536 wxTopLevelWindows
.DeleteObject( this );
538 if (wxTheApp
->GetTopWindow() == this)
539 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
541 if ((wxTopLevelWindows
.Number() == 0) &&
542 (wxTheApp
->GetExitOnFrameDelete()))
544 wxTheApp
->ExitMainLoop();
548 bool wxFrame::ShowFullScreen(bool show
, long style
)
550 if (show
== m_fsIsShowing
) return FALSE
; // return what?
552 m_fsIsShowing
= show
;
556 m_fsSaveStyle
= m_windowStyle
;
557 m_fsSaveFlag
= style
;
558 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
559 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
561 gtk_widget_hide( m_widget
);
562 gtk_widget_unrealize( m_widget
);
564 m_windowStyle
= wxSIMPLE_BORDER
;
568 wxDisplaySize( &x
, &y
);
569 SetSize( 0, 0, x
, y
);
571 gtk_widget_realize( m_widget
);
572 gtk_widget_show( m_widget
);
576 gtk_widget_hide( m_widget
);
577 gtk_widget_unrealize( m_widget
);
579 m_windowStyle
= m_fsSaveStyle
;
581 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
583 gtk_widget_realize( m_widget
);
584 gtk_widget_show( m_widget
);
590 // ----------------------------------------------------------------------------
591 // overridden wxWindow methods
592 // ----------------------------------------------------------------------------
594 bool wxFrame::Show( bool show
)
596 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
598 if (show
&& !m_sizeSet
)
600 /* by calling GtkOnSize here, we don't have to call
601 either after showing the frame, which would entail
602 much ugly flicker or from within the size_allocate
603 handler, because GTK 1.1.X forbids that. */
605 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
608 return wxWindow::Show( show
);
611 void wxFrame::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
613 wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
616 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
618 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
620 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
621 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
623 /* avoid recursions */
631 int old_width
= m_width
;
632 int old_height
= m_height
;
634 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
636 if (x
!= -1) m_x
= x
;
637 if (y
!= -1) m_y
= y
;
638 if (width
!= -1) m_width
= width
;
639 if (height
!= -1) m_height
= height
;
650 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
652 if (width == -1) m_width = 80;
655 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
657 if (height == -1) m_height = 26;
661 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
662 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
663 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
664 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
666 if ((m_x
!= -1) || (m_y
!= -1))
668 if ((m_x
!= old_x
) || (m_y
!= old_y
))
670 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
674 if ((m_width
!= old_width
) || (m_height
!= old_height
))
676 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
678 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
679 done either directly before the frame is shown or in idle time
680 so that different calls to SetSize() don't lead to flicker. */
687 void wxFrame::DoGetClientSize( int *width
, int *height
) const
689 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
691 wxWindow::DoGetClientSize( width
, height
);
697 if (!m_menuBarDetached
)
698 (*height
) -= wxMENU_HEIGHT
;
700 (*height
) -= wxPLACE_HOLDER
;
705 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) (*height
) -= wxSTATUS_HEIGHT
;
706 #endif // wxUSE_STATUSBAR
710 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
712 if (m_toolBarDetached
)
714 *height
-= wxPLACE_HOLDER
;
719 m_frameToolBar
->GetSize( &x
, &y
);
720 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
730 #endif // wxUSE_TOOLBAR
733 *height
-= m_miniEdge
*2 + m_miniTitle
;
737 *width
-= m_miniEdge
*2;
741 void wxFrame::DoSetClientSize( int width
, int height
)
743 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
748 if (!m_menuBarDetached
)
749 height
+= wxMENU_HEIGHT
;
751 height
+= wxPLACE_HOLDER
;
756 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) height
+= wxSTATUS_HEIGHT
;
761 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
763 if (m_toolBarDetached
)
765 height
+= wxPLACE_HOLDER
;
770 m_frameToolBar
->GetSize( &x
, &y
);
771 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
783 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
786 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
787 int width
, int height
)
789 // due to a bug in gtk, x,y are always 0
793 /* avoid recursions */
794 if (m_resizing
) return;
797 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
798 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
803 /* space occupied by m_frameToolBar and m_frameMenuBar */
804 int client_area_x_offset
= 0,
805 client_area_y_offset
= 0;
807 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
808 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
809 set in wxFrame::Create so it is used to check what kind of frame we
810 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
811 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
812 importantly) m_mainWidget */
814 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
815 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
816 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
817 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
822 gint flag
= 0; // GDK_HINT_POS;
823 if ((m_minWidth
!= -1) || (m_minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
824 if ((m_maxWidth
!= -1) || (m_maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
826 geom
.min_width
= m_minWidth
;
827 geom
.min_height
= m_minHeight
;
828 geom
.max_width
= m_maxWidth
;
829 geom
.max_height
= m_maxHeight
;
830 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
833 (GdkWindowHints
) flag
);
835 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
836 * menubar, the toolbar and the client area, which is represented by
838 * this hurts in the eye, but I don't want to call SetSize()
839 * because I don't want to call any non-native functions here. */
844 int yy
= m_miniEdge
+ m_miniTitle
;
845 int ww
= m_width
- 2*m_miniEdge
;
846 int hh
= wxMENU_HEIGHT
;
847 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
848 m_frameMenuBar
->m_x
= xx
;
849 m_frameMenuBar
->m_y
= yy
;
850 m_frameMenuBar
->m_width
= ww
;
851 m_frameMenuBar
->m_height
= hh
;
852 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
853 m_frameMenuBar
->m_widget
,
855 client_area_y_offset
+= hh
;
859 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
860 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
863 int yy
= m_miniEdge
+ m_miniTitle
;
866 if (!m_menuBarDetached
)
869 yy
+= wxPLACE_HOLDER
;
872 m_frameToolBar
->m_x
= xx
;
873 m_frameToolBar
->m_y
= yy
;
875 /* don't change the toolbar's reported height/width */
877 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
879 ww
= m_toolBarDetached
? wxPLACE_HOLDER
880 : m_frameToolBar
->m_width
;
881 hh
= m_height
- 2*m_miniEdge
;
883 client_area_x_offset
+= ww
;
887 ww
= m_width
- 2*m_miniEdge
;
888 hh
= m_toolBarDetached
? wxPLACE_HOLDER
889 : m_frameToolBar
->m_height
;
891 client_area_y_offset
+= hh
;
894 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
895 m_frameToolBar
->m_widget
,
898 #endif // wxUSE_TOOLBAR
900 int client_x
= client_area_x_offset
+ m_miniEdge
;
901 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
902 int client_w
= m_width
- client_area_x_offset
- 2*m_miniEdge
;
903 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
904 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
906 client_x
, client_y
, client_w
, client_h
);
910 /* if there is no m_mainWidget between m_widget and m_wxwindow there
911 is no need to set the size or position of m_wxwindow. */
915 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
917 int xx
= 0 + m_miniEdge
;
918 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
919 int ww
= m_width
- 2*m_miniEdge
;
920 int hh
= wxSTATUS_HEIGHT
;
921 m_frameStatusBar
->m_x
= xx
;
922 m_frameStatusBar
->m_y
= yy
;
923 m_frameStatusBar
->m_width
= ww
;
924 m_frameStatusBar
->m_height
= hh
;
925 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
926 m_frameStatusBar
->m_widget
,
928 gtk_widget_draw( m_frameStatusBar
->m_widget
, (GdkRectangle
*) NULL
);
934 // send size event to frame
935 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
936 event
.SetEventObject( this );
937 GetEventHandler()->ProcessEvent( event
);
939 // send size event to status bar
940 if (m_frameStatusBar
)
942 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
943 event2
.SetEventObject( m_frameStatusBar
);
944 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
950 void wxFrame::MakeModal( bool modal
)
953 gtk_grab_add( m_widget
);
955 gtk_grab_remove( m_widget
);
958 void wxFrame::OnInternalIdle()
960 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
962 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
964 // we'll come back later
966 wxapp_install_idle_handler();
970 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
972 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
975 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
978 wxWindow::OnInternalIdle();
981 // ----------------------------------------------------------------------------
982 // menu/tool/status bar stuff
983 // ----------------------------------------------------------------------------
985 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
987 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
988 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
990 if (menuBar
== m_frameMenuBar
)
995 m_frameMenuBar
->UnsetInvokingWindow( this );
997 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
999 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1000 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1002 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1003 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1006 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
1007 gtk_widget_ref( m_frameMenuBar
->m_widget
);
1008 gtk_widget_unparent( m_frameMenuBar
->m_widget
);
1011 m_frameMenuBar
= menuBar
;
1015 m_frameMenuBar
->SetInvokingWindow( this );
1017 m_frameMenuBar
->SetParent(this);
1018 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
1019 m_frameMenuBar
->m_widget
,
1020 m_frameMenuBar
->m_x
,
1021 m_frameMenuBar
->m_y
,
1022 m_frameMenuBar
->m_width
,
1023 m_frameMenuBar
->m_height
);
1025 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1027 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
1028 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1030 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
1031 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1034 m_frameMenuBar
->Show( TRUE
);
1037 /* resize window in OnInternalIdle */
1042 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1044 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1046 m_insertInClientArea
= FALSE
;
1048 m_frameToolBar
= wxFrameBase::CreateToolBar( style
, id
, name
);
1050 m_insertInClientArea
= TRUE
;
1054 return m_frameToolBar
;
1057 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1059 wxFrameBase::SetToolBar(toolbar
);
1063 /* insert into toolbar area if not already there */
1064 if ((m_frameToolBar
->m_widget
->parent
) &&
1065 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1067 GetChildren().DeleteObject( m_frameToolBar
);
1069 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1075 #endif // wxUSE_TOOLBAR
1079 wxStatusBar
* wxFrame::CreateStatusBar(int number
,
1082 const wxString
& name
)
1084 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1086 // because it will change when toolbar is added
1089 return wxFrameBase::CreateStatusBar( number
, style
, id
, name
);
1092 void wxFrame::PositionStatusBar()
1094 if ( !m_frameStatusBar
)
1099 #endif // wxUSE_STATUSBAR
1101 // ----------------------------------------------------------------------------
1103 // ----------------------------------------------------------------------------
1105 void wxFrame::SetTitle( const wxString
&title
)
1107 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1110 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1113 void wxFrame::SetIcon( const wxIcon
&icon
)
1115 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1117 wxFrameBase::SetIcon(icon
);
1122 if (!m_widget
->window
)
1125 wxMask
*mask
= icon
.GetMask();
1126 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1127 if (mask
) bm
= mask
->GetBitmap();
1129 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1132 // ----------------------------------------------------------------------------
1133 // frame state: maximized/iconized/normal (TODO)
1134 // ----------------------------------------------------------------------------
1136 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1140 bool wxFrame::IsMaximized() const
1145 void wxFrame::Restore()
1149 void wxFrame::Iconize( bool iconize
)
1153 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1154 GDK_WINDOW_XWINDOW( m_widget
->window
),
1155 DefaultScreen( GDK_DISPLAY() ) );
1159 bool wxFrame::IsIconized() const
1161 return m_isIconized
;