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
),
332 GdkEvent
* WXUNUSED(event
),
335 win
->m_isIconized
= FALSE
;
338 //-----------------------------------------------------------------------------
339 // "unmap_event" from m_widget
340 //-----------------------------------------------------------------------------
343 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
344 GdkEvent
* WXUNUSED(event
),
347 win
->m_isIconized
= TRUE
;
350 // ----------------------------------------------------------------------------
352 // ----------------------------------------------------------------------------
354 //-----------------------------------------------------------------------------
355 // InsertChild for wxFrame
356 //-----------------------------------------------------------------------------
358 /* Callback for wxFrame. This very strange beast has to be used because
359 * C++ has no virtual methods in a constructor. We have to emulate a
360 * virtual function here as wxWindows requires different ways to insert
361 * a child in container classes. */
363 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
365 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
367 if (!parent
->m_insertInClientArea
)
369 /* these are outside the client area */
370 wxFrame
* frame
= (wxFrame
*) parent
;
371 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
372 GTK_WIDGET(child
->m_widget
),
378 #if wxUSE_TOOLBAR_NATIVE
379 /* we connect to these events for recalculating the client area
380 space when the toolbar is floating */
381 if (wxIS_KIND_OF(child
,wxToolBar
))
383 wxToolBar
*toolBar
= (wxToolBar
*) child
;
384 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
386 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
387 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
389 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
390 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
393 #endif // wxUSE_TOOLBAR
397 /* these are inside the client area */
398 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
399 GTK_WIDGET(child
->m_widget
),
406 /* resize on OnInternalIdle */
407 parent
->GtkUpdateSize();
410 // ----------------------------------------------------------------------------
412 // ----------------------------------------------------------------------------
419 m_mainWidget
= (GtkWidget
*) NULL
;
420 m_menuBarDetached
= FALSE
;
421 m_toolBarDetached
= FALSE
;
422 m_insertInClientArea
= TRUE
;
423 m_isIconized
= FALSE
;
424 m_fsIsShowing
= FALSE
;
427 bool wxFrame::Create( wxWindow
*parent
,
429 const wxString
&title
,
433 const wxString
&name
)
435 wxTopLevelWindows
.Append( this );
437 m_needParent
= FALSE
;
439 if (!PreCreation( parent
, pos
, size
) ||
440 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
442 wxFAIL_MSG( wxT("wxFrame creation failed") );
448 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
450 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
452 if (style
& wxFRAME_TOOL_WINDOW
)
453 win_type
= GTK_WINDOW_POPUP
;
455 m_widget
= gtk_window_new( win_type
);
457 if ((m_parent
) && (HasFlag(wxFRAME_FLOAT_ON_PARENT
)) && (GTK_IS_WINDOW(m_parent
->m_widget
)))
458 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
461 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
464 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
467 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
468 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
470 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
471 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
473 /* m_mainWidget holds the toolbar, the menubar and the client area */
474 m_mainWidget
= gtk_pizza_new();
475 gtk_widget_show( m_mainWidget
);
476 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
477 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
480 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
483 /* m_wxwindow only represents the client area without toolbar and menubar */
484 m_wxwindow
= gtk_pizza_new();
485 gtk_widget_show( m_wxwindow
);
486 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
489 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
492 /* we donm't allow the frame to get the focus as otherwise
493 the frame will grabit at arbitrary fcous changes. */
494 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
496 if (m_parent
) m_parent
->AddChild( this );
498 /* the user resized the frame by dragging etc. */
499 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
500 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
504 if ((m_x
!= -1) || (m_y
!= -1))
505 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
506 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
508 /* we cannot set MWM hints and icons before the widget has
509 been realized, so we do this directly after realization */
510 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
511 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
513 /* the only way to get the window size is to connect to this event */
514 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
515 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
517 /* map and unmap for iconized state */
518 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
519 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
520 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
521 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
523 /* the only way to get the window size is to connect to this event */
524 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
525 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
527 /* disable native tab traversal */
528 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
529 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
536 m_isBeingDeleted
= TRUE
;
540 wxTopLevelWindows
.DeleteObject( this );
542 if (wxTheApp
->GetTopWindow() == this)
543 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
545 if ((wxTopLevelWindows
.Number() == 0) &&
546 (wxTheApp
->GetExitOnFrameDelete()))
548 wxTheApp
->ExitMainLoop();
552 bool wxFrame::ShowFullScreen(bool show
, long style
)
554 if (show
== m_fsIsShowing
) return FALSE
; // return what?
556 m_fsIsShowing
= show
;
560 m_fsSaveStyle
= m_windowStyle
;
561 m_fsSaveFlag
= style
;
562 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
563 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
565 gtk_widget_hide( m_widget
);
566 gtk_widget_unrealize( m_widget
);
568 m_windowStyle
= wxSIMPLE_BORDER
;
572 wxDisplaySize( &x
, &y
);
573 SetSize( 0, 0, x
, y
);
575 gtk_widget_realize( m_widget
);
576 gtk_widget_show( m_widget
);
580 gtk_widget_hide( m_widget
);
581 gtk_widget_unrealize( m_widget
);
583 m_windowStyle
= m_fsSaveStyle
;
585 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
587 gtk_widget_realize( m_widget
);
588 gtk_widget_show( m_widget
);
594 // ----------------------------------------------------------------------------
595 // overridden wxWindow methods
596 // ----------------------------------------------------------------------------
598 bool wxFrame::Show( bool show
)
600 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
602 if (show
&& !m_sizeSet
)
604 /* by calling GtkOnSize here, we don't have to call
605 either after showing the frame, which would entail
606 much ugly flicker or from within the size_allocate
607 handler, because GTK 1.1.X forbids that. */
609 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
612 return wxWindow::Show( show
);
615 void wxFrame::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
617 wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
620 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
622 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
624 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
625 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
627 /* avoid recursions */
635 int old_width
= m_width
;
636 int old_height
= m_height
;
638 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
640 if (x
!= -1) m_x
= x
;
641 if (y
!= -1) m_y
= y
;
642 if (width
!= -1) m_width
= width
;
643 if (height
!= -1) m_height
= height
;
654 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
656 if (width == -1) m_width = 80;
659 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
661 if (height == -1) m_height = 26;
665 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
666 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
667 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
668 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
670 if ((m_x
!= -1) || (m_y
!= -1))
672 if ((m_x
!= old_x
) || (m_y
!= old_y
))
674 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
678 if ((m_width
!= old_width
) || (m_height
!= old_height
))
680 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
682 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
683 done either directly before the frame is shown or in idle time
684 so that different calls to SetSize() don't lead to flicker. */
691 void wxFrame::DoGetClientSize( int *width
, int *height
) const
693 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
695 wxWindow::DoGetClientSize( width
, height
);
701 if (!m_menuBarDetached
)
702 (*height
) -= wxMENU_HEIGHT
;
704 (*height
) -= wxPLACE_HOLDER
;
709 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) (*height
) -= wxSTATUS_HEIGHT
;
710 #endif // wxUSE_STATUSBAR
714 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
716 if (m_toolBarDetached
)
718 *height
-= wxPLACE_HOLDER
;
723 m_frameToolBar
->GetSize( &x
, &y
);
724 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
734 #endif // wxUSE_TOOLBAR
737 *height
-= m_miniEdge
*2 + m_miniTitle
;
741 *width
-= m_miniEdge
*2;
745 void wxFrame::DoSetClientSize( int width
, int height
)
747 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
752 if (!m_menuBarDetached
)
753 height
+= wxMENU_HEIGHT
;
755 height
+= wxPLACE_HOLDER
;
760 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) height
+= wxSTATUS_HEIGHT
;
765 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
767 if (m_toolBarDetached
)
769 height
+= wxPLACE_HOLDER
;
774 m_frameToolBar
->GetSize( &x
, &y
);
775 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
787 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
790 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
791 int width
, int height
)
793 // due to a bug in gtk, x,y are always 0
797 /* avoid recursions */
798 if (m_resizing
) return;
801 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
802 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
807 /* space occupied by m_frameToolBar and m_frameMenuBar */
808 int client_area_x_offset
= 0,
809 client_area_y_offset
= 0;
811 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
812 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
813 set in wxFrame::Create so it is used to check what kind of frame we
814 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
815 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
816 importantly) m_mainWidget */
818 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
819 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
820 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
821 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
826 gint flag
= 0; // GDK_HINT_POS;
827 if ((m_minWidth
!= -1) || (m_minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
828 if ((m_maxWidth
!= -1) || (m_maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
830 geom
.min_width
= m_minWidth
;
831 geom
.min_height
= m_minHeight
;
832 geom
.max_width
= m_maxWidth
;
833 geom
.max_height
= m_maxHeight
;
834 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
837 (GdkWindowHints
) flag
);
839 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
840 * menubar, the toolbar and the client area, which is represented by
842 * this hurts in the eye, but I don't want to call SetSize()
843 * because I don't want to call any non-native functions here. */
848 int yy
= m_miniEdge
+ m_miniTitle
;
849 int ww
= m_width
- 2*m_miniEdge
;
850 int hh
= wxMENU_HEIGHT
;
851 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
852 m_frameMenuBar
->m_x
= xx
;
853 m_frameMenuBar
->m_y
= yy
;
854 m_frameMenuBar
->m_width
= ww
;
855 m_frameMenuBar
->m_height
= hh
;
856 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
857 m_frameMenuBar
->m_widget
,
859 client_area_y_offset
+= hh
;
863 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
864 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
867 int yy
= m_miniEdge
+ m_miniTitle
;
870 if (!m_menuBarDetached
)
873 yy
+= wxPLACE_HOLDER
;
876 m_frameToolBar
->m_x
= xx
;
877 m_frameToolBar
->m_y
= yy
;
879 /* don't change the toolbar's reported height/width */
881 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
883 ww
= m_toolBarDetached
? wxPLACE_HOLDER
884 : m_frameToolBar
->m_width
;
885 hh
= m_height
- 2*m_miniEdge
;
887 client_area_x_offset
+= ww
;
891 ww
= m_width
- 2*m_miniEdge
;
892 hh
= m_toolBarDetached
? wxPLACE_HOLDER
893 : m_frameToolBar
->m_height
;
895 client_area_y_offset
+= hh
;
898 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
899 m_frameToolBar
->m_widget
,
902 #endif // wxUSE_TOOLBAR
904 int client_x
= client_area_x_offset
+ m_miniEdge
;
905 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
906 int client_w
= m_width
- client_area_x_offset
- 2*m_miniEdge
;
907 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
908 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
910 client_x
, client_y
, client_w
, client_h
);
914 /* if there is no m_mainWidget between m_widget and m_wxwindow there
915 is no need to set the size or position of m_wxwindow. */
919 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
921 int xx
= 0 + m_miniEdge
;
922 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
923 int ww
= m_width
- 2*m_miniEdge
;
924 int hh
= wxSTATUS_HEIGHT
;
925 m_frameStatusBar
->m_x
= xx
;
926 m_frameStatusBar
->m_y
= yy
;
927 m_frameStatusBar
->m_width
= ww
;
928 m_frameStatusBar
->m_height
= hh
;
929 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
930 m_frameStatusBar
->m_widget
,
932 gtk_widget_draw( m_frameStatusBar
->m_widget
, (GdkRectangle
*) NULL
);
938 // send size event to frame
939 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
940 event
.SetEventObject( this );
941 GetEventHandler()->ProcessEvent( event
);
943 // send size event to status bar
944 if (m_frameStatusBar
)
946 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
947 event2
.SetEventObject( m_frameStatusBar
);
948 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
954 void wxFrame::MakeModal( bool modal
)
957 gtk_grab_add( m_widget
);
959 gtk_grab_remove( m_widget
);
962 void wxFrame::OnInternalIdle()
964 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
966 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
968 // we'll come back later
970 wxapp_install_idle_handler();
974 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
976 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
979 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
982 wxWindow::OnInternalIdle();
985 // ----------------------------------------------------------------------------
986 // menu/tool/status bar stuff
987 // ----------------------------------------------------------------------------
989 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
991 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
992 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
994 if (menuBar
== m_frameMenuBar
)
999 m_frameMenuBar
->UnsetInvokingWindow( this );
1001 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1003 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1004 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1006 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1007 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1010 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
1011 gtk_widget_ref( m_frameMenuBar
->m_widget
);
1012 gtk_widget_unparent( m_frameMenuBar
->m_widget
);
1015 m_frameMenuBar
= menuBar
;
1019 m_frameMenuBar
->SetInvokingWindow( this );
1021 m_frameMenuBar
->SetParent(this);
1022 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
1023 m_frameMenuBar
->m_widget
,
1024 m_frameMenuBar
->m_x
,
1025 m_frameMenuBar
->m_y
,
1026 m_frameMenuBar
->m_width
,
1027 m_frameMenuBar
->m_height
);
1029 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1031 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
1032 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1034 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
1035 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1038 m_frameMenuBar
->Show( TRUE
);
1041 /* resize window in OnInternalIdle */
1046 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1048 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1050 m_insertInClientArea
= FALSE
;
1052 m_frameToolBar
= wxFrameBase::CreateToolBar( style
, id
, name
);
1054 m_insertInClientArea
= TRUE
;
1058 return m_frameToolBar
;
1061 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1063 wxFrameBase::SetToolBar(toolbar
);
1067 /* insert into toolbar area if not already there */
1068 if ((m_frameToolBar
->m_widget
->parent
) &&
1069 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1071 GetChildren().DeleteObject( m_frameToolBar
);
1073 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1079 #endif // wxUSE_TOOLBAR
1083 wxStatusBar
* wxFrame::CreateStatusBar(int number
,
1086 const wxString
& name
)
1088 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1090 // because it will change when toolbar is added
1093 return wxFrameBase::CreateStatusBar( number
, style
, id
, name
);
1096 void wxFrame::PositionStatusBar()
1098 if ( !m_frameStatusBar
)
1103 #endif // wxUSE_STATUSBAR
1105 // ----------------------------------------------------------------------------
1107 // ----------------------------------------------------------------------------
1109 void wxFrame::SetTitle( const wxString
&title
)
1111 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1114 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1117 void wxFrame::SetIcon( const wxIcon
&icon
)
1119 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1121 wxFrameBase::SetIcon(icon
);
1126 if (!m_widget
->window
)
1129 wxMask
*mask
= icon
.GetMask();
1130 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1131 if (mask
) bm
= mask
->GetBitmap();
1133 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1136 // ----------------------------------------------------------------------------
1137 // frame state: maximized/iconized/normal
1138 // ----------------------------------------------------------------------------
1140 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1142 wxFAIL_MSG( _T("not implemented") );
1145 bool wxFrame::IsMaximized() const
1147 wxFAIL_MSG( _T("not implemented") );
1152 void wxFrame::Restore()
1154 wxFAIL_MSG( _T("not implemented") );
1157 void wxFrame::Iconize( bool iconize
)
1161 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1162 GDK_WINDOW_XWINDOW( m_widget
->window
),
1163 DefaultScreen( GDK_DISPLAY() ) );
1167 bool wxFrame::IsIconized() const
1169 return m_isIconized
;