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 //-----------------------------------------------------------------------------
351 // "expose_event" of m_client
352 //-----------------------------------------------------------------------------
354 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
356 GtkPizza
*pizza
= GTK_PIZZA(widget
);
358 gtk_paint_flat_box (win
->m_widget
->style
, pizza
->bin_window
, GTK_STATE_NORMAL
,
359 GTK_SHADOW_NONE
, &gdk_event
->area
, win
->m_widget
, "base", 0, 0, -1, -1);
364 //-----------------------------------------------------------------------------
365 // "draw" of m_client
366 //-----------------------------------------------------------------------------
369 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
371 GtkPizza
*pizza
= GTK_PIZZA(widget
);
373 gtk_paint_flat_box (win
->m_widget
->style
, pizza
->bin_window
, GTK_STATE_NORMAL
,
374 GTK_SHADOW_NONE
, rect
, win
->m_widget
, "base", 0, 0, -1, -1);
377 // ----------------------------------------------------------------------------
379 // ----------------------------------------------------------------------------
381 //-----------------------------------------------------------------------------
382 // InsertChild for wxFrame
383 //-----------------------------------------------------------------------------
385 /* Callback for wxFrame. This very strange beast has to be used because
386 * C++ has no virtual methods in a constructor. We have to emulate a
387 * virtual function here as wxWindows requires different ways to insert
388 * a child in container classes. */
390 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
392 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
394 if (!parent
->m_insertInClientArea
)
396 /* these are outside the client area */
397 wxFrame
* frame
= (wxFrame
*) parent
;
398 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
399 GTK_WIDGET(child
->m_widget
),
405 #if wxUSE_TOOLBAR_NATIVE
406 /* we connect to these events for recalculating the client area
407 space when the toolbar is floating */
408 if (wxIS_KIND_OF(child
,wxToolBar
))
410 wxToolBar
*toolBar
= (wxToolBar
*) child
;
411 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
413 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
414 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
416 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
417 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
420 #endif // wxUSE_TOOLBAR
424 /* these are inside the client area */
425 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
426 GTK_WIDGET(child
->m_widget
),
433 /* resize on OnInternalIdle */
434 parent
->GtkUpdateSize();
437 // ----------------------------------------------------------------------------
439 // ----------------------------------------------------------------------------
446 m_mainWidget
= (GtkWidget
*) NULL
;
447 m_menuBarDetached
= FALSE
;
448 m_toolBarDetached
= FALSE
;
449 m_insertInClientArea
= TRUE
;
450 m_isIconized
= FALSE
;
451 m_fsIsShowing
= FALSE
;
452 m_themeEnabled
= TRUE
;
455 bool wxFrame::Create( wxWindow
*parent
,
457 const wxString
&title
,
461 const wxString
&name
)
463 wxTopLevelWindows
.Append( this );
465 m_needParent
= FALSE
;
467 if (!PreCreation( parent
, pos
, size
) ||
468 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
470 wxFAIL_MSG( wxT("wxFrame creation failed") );
476 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
478 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
480 if (style
& wxFRAME_TOOL_WINDOW
)
481 win_type
= GTK_WINDOW_POPUP
;
483 m_widget
= gtk_window_new( win_type
);
485 if ((m_parent
) && (HasFlag(wxFRAME_FLOAT_ON_PARENT
)) && (GTK_IS_WINDOW(m_parent
->m_widget
)))
486 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
489 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
492 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
495 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
496 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
498 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
499 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
501 /* m_mainWidget holds the toolbar, the menubar and the client area */
502 m_mainWidget
= gtk_pizza_new();
503 gtk_widget_show( m_mainWidget
);
504 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
505 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
507 /* for m_mainWidget themes */
508 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
509 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
510 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
511 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
514 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
517 /* m_wxwindow only represents the client area without toolbar and menubar */
518 m_wxwindow
= gtk_pizza_new();
519 gtk_widget_show( m_wxwindow
);
520 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
523 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
526 /* we donm't allow the frame to get the focus as otherwise
527 the frame will grabit at arbitrary fcous changes. */
528 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
530 if (m_parent
) m_parent
->AddChild( this );
532 /* the user resized the frame by dragging etc. */
533 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
534 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
538 if ((m_x
!= -1) || (m_y
!= -1))
539 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
540 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
542 /* we cannot set MWM hints and icons before the widget has
543 been realized, so we do this directly after realization */
544 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
545 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
547 /* the only way to get the window size is to connect to this event */
548 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
549 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
551 /* map and unmap for iconized state */
552 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
553 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
554 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
555 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
557 /* the only way to get the window size is to connect to this event */
558 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
559 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
561 /* disable native tab traversal */
562 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
563 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
570 m_isBeingDeleted
= TRUE
;
574 wxTopLevelWindows
.DeleteObject( this );
576 if (wxTheApp
->GetTopWindow() == this)
577 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
579 if ((wxTopLevelWindows
.Number() == 0) &&
580 (wxTheApp
->GetExitOnFrameDelete()))
582 wxTheApp
->ExitMainLoop();
586 bool wxFrame::ShowFullScreen(bool show
, long style
)
588 if (show
== m_fsIsShowing
) return FALSE
; // return what?
590 m_fsIsShowing
= show
;
594 m_fsSaveStyle
= m_windowStyle
;
595 m_fsSaveFlag
= style
;
596 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
597 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
599 gtk_widget_hide( m_widget
);
600 gtk_widget_unrealize( m_widget
);
602 m_windowStyle
= wxSIMPLE_BORDER
;
606 wxDisplaySize( &x
, &y
);
607 SetSize( 0, 0, x
, y
);
609 gtk_widget_realize( m_widget
);
610 gtk_widget_show( m_widget
);
614 gtk_widget_hide( m_widget
);
615 gtk_widget_unrealize( m_widget
);
617 m_windowStyle
= m_fsSaveStyle
;
619 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
621 gtk_widget_realize( m_widget
);
622 gtk_widget_show( m_widget
);
628 // ----------------------------------------------------------------------------
629 // overridden wxWindow methods
630 // ----------------------------------------------------------------------------
632 bool wxFrame::Show( bool show
)
634 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
636 if (show
&& !m_sizeSet
)
638 /* by calling GtkOnSize here, we don't have to call
639 either after showing the frame, which would entail
640 much ugly flicker or from within the size_allocate
641 handler, because GTK 1.1.X forbids that. */
643 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
646 return wxWindow::Show( show
);
649 void wxFrame::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
651 wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
654 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
656 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
658 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
659 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
661 /* avoid recursions */
669 int old_width
= m_width
;
670 int old_height
= m_height
;
672 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
674 if (x
!= -1) m_x
= x
;
675 if (y
!= -1) m_y
= y
;
676 if (width
!= -1) m_width
= width
;
677 if (height
!= -1) m_height
= height
;
688 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
690 if (width == -1) m_width = 80;
693 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
695 if (height == -1) m_height = 26;
699 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
700 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
701 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
702 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
704 if ((m_x
!= -1) || (m_y
!= -1))
706 if ((m_x
!= old_x
) || (m_y
!= old_y
))
708 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
712 if ((m_width
!= old_width
) || (m_height
!= old_height
))
714 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
716 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
717 done either directly before the frame is shown or in idle time
718 so that different calls to SetSize() don't lead to flicker. */
725 void wxFrame::DoGetClientSize( int *width
, int *height
) const
727 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
729 wxWindow::DoGetClientSize( width
, height
);
735 if (!m_menuBarDetached
)
736 (*height
) -= wxMENU_HEIGHT
;
738 (*height
) -= wxPLACE_HOLDER
;
743 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) (*height
) -= wxSTATUS_HEIGHT
;
744 #endif // wxUSE_STATUSBAR
748 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
750 if (m_toolBarDetached
)
752 *height
-= wxPLACE_HOLDER
;
757 m_frameToolBar
->GetSize( &x
, &y
);
758 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
768 #endif // wxUSE_TOOLBAR
771 *height
-= m_miniEdge
*2 + m_miniTitle
;
775 *width
-= m_miniEdge
*2;
779 void wxFrame::DoSetClientSize( int width
, int height
)
781 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
786 if (!m_menuBarDetached
)
787 height
+= wxMENU_HEIGHT
;
789 height
+= wxPLACE_HOLDER
;
794 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) height
+= wxSTATUS_HEIGHT
;
799 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
801 if (m_toolBarDetached
)
803 height
+= wxPLACE_HOLDER
;
808 m_frameToolBar
->GetSize( &x
, &y
);
809 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
821 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
824 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
825 int width
, int height
)
827 // due to a bug in gtk, x,y are always 0
831 /* avoid recursions */
832 if (m_resizing
) return;
835 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
836 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
841 /* space occupied by m_frameToolBar and m_frameMenuBar */
842 int client_area_x_offset
= 0,
843 client_area_y_offset
= 0;
845 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
846 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
847 set in wxFrame::Create so it is used to check what kind of frame we
848 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
849 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
850 importantly) m_mainWidget */
852 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
853 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
854 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
855 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
860 gint flag
= 0; // GDK_HINT_POS;
861 if ((m_minWidth
!= -1) || (m_minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
862 if ((m_maxWidth
!= -1) || (m_maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
864 geom
.min_width
= m_minWidth
;
865 geom
.min_height
= m_minHeight
;
866 geom
.max_width
= m_maxWidth
;
867 geom
.max_height
= m_maxHeight
;
868 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
871 (GdkWindowHints
) flag
);
873 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
874 * menubar, the toolbar and the client area, which is represented by
876 * this hurts in the eye, but I don't want to call SetSize()
877 * because I don't want to call any non-native functions here. */
882 int yy
= m_miniEdge
+ m_miniTitle
;
883 int ww
= m_width
- 2*m_miniEdge
;
884 int hh
= wxMENU_HEIGHT
;
885 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
886 m_frameMenuBar
->m_x
= xx
;
887 m_frameMenuBar
->m_y
= yy
;
888 m_frameMenuBar
->m_width
= ww
;
889 m_frameMenuBar
->m_height
= hh
;
890 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
891 m_frameMenuBar
->m_widget
,
893 client_area_y_offset
+= hh
;
897 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
898 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
901 int yy
= m_miniEdge
+ m_miniTitle
;
904 if (!m_menuBarDetached
)
907 yy
+= wxPLACE_HOLDER
;
910 m_frameToolBar
->m_x
= xx
;
911 m_frameToolBar
->m_y
= yy
;
913 /* don't change the toolbar's reported height/width */
915 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
917 ww
= m_toolBarDetached
? wxPLACE_HOLDER
918 : m_frameToolBar
->m_width
;
919 hh
= m_height
- 2*m_miniEdge
;
921 client_area_x_offset
+= ww
;
925 ww
= m_width
- 2*m_miniEdge
;
926 hh
= m_toolBarDetached
? wxPLACE_HOLDER
927 : m_frameToolBar
->m_height
;
929 client_area_y_offset
+= hh
;
932 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
933 m_frameToolBar
->m_widget
,
936 #endif // wxUSE_TOOLBAR
938 int client_x
= client_area_x_offset
+ m_miniEdge
;
939 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
940 int client_w
= m_width
- client_area_x_offset
- 2*m_miniEdge
;
941 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
942 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
944 client_x
, client_y
, client_w
, client_h
);
948 /* if there is no m_mainWidget between m_widget and m_wxwindow there
949 is no need to set the size or position of m_wxwindow. */
953 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
955 int xx
= 0 + m_miniEdge
;
956 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
957 int ww
= m_width
- 2*m_miniEdge
;
958 int hh
= wxSTATUS_HEIGHT
;
959 m_frameStatusBar
->m_x
= xx
;
960 m_frameStatusBar
->m_y
= yy
;
961 m_frameStatusBar
->m_width
= ww
;
962 m_frameStatusBar
->m_height
= hh
;
963 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
964 m_frameStatusBar
->m_widget
,
966 gtk_widget_draw( m_frameStatusBar
->m_widget
, (GdkRectangle
*) NULL
);
972 // send size event to frame
973 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
974 event
.SetEventObject( this );
975 GetEventHandler()->ProcessEvent( event
);
977 // send size event to status bar
978 if (m_frameStatusBar
)
980 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
981 event2
.SetEventObject( m_frameStatusBar
);
982 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
988 void wxFrame::MakeModal( bool modal
)
991 gtk_grab_add( m_widget
);
993 gtk_grab_remove( m_widget
);
996 void wxFrame::OnInternalIdle()
998 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
1000 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
1002 // we'll come back later
1004 wxapp_install_idle_handler();
1008 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
1010 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
1013 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
1016 wxWindow::OnInternalIdle();
1019 // ----------------------------------------------------------------------------
1020 // menu/tool/status bar stuff
1021 // ----------------------------------------------------------------------------
1023 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
1025 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1026 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
1028 if (menuBar
== m_frameMenuBar
)
1033 m_frameMenuBar
->UnsetInvokingWindow( this );
1035 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1037 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1038 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1040 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1041 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1044 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
1045 gtk_widget_ref( m_frameMenuBar
->m_widget
);
1046 gtk_widget_unparent( m_frameMenuBar
->m_widget
);
1049 m_frameMenuBar
= menuBar
;
1053 m_frameMenuBar
->SetInvokingWindow( this );
1055 m_frameMenuBar
->SetParent(this);
1056 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
1057 m_frameMenuBar
->m_widget
,
1058 m_frameMenuBar
->m_x
,
1059 m_frameMenuBar
->m_y
,
1060 m_frameMenuBar
->m_width
,
1061 m_frameMenuBar
->m_height
);
1063 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1065 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
1066 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1068 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
1069 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1072 m_frameMenuBar
->Show( TRUE
);
1075 /* resize window in OnInternalIdle */
1080 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1082 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1084 m_insertInClientArea
= FALSE
;
1086 m_frameToolBar
= wxFrameBase::CreateToolBar( style
, id
, name
);
1088 m_insertInClientArea
= TRUE
;
1092 return m_frameToolBar
;
1095 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1097 wxFrameBase::SetToolBar(toolbar
);
1101 /* insert into toolbar area if not already there */
1102 if ((m_frameToolBar
->m_widget
->parent
) &&
1103 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1105 GetChildren().DeleteObject( m_frameToolBar
);
1107 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1113 #endif // wxUSE_TOOLBAR
1117 wxStatusBar
* wxFrame::CreateStatusBar(int number
,
1120 const wxString
& name
)
1122 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1124 // because it will change when toolbar is added
1127 return wxFrameBase::CreateStatusBar( number
, style
, id
, name
);
1130 void wxFrame::PositionStatusBar()
1132 if ( !m_frameStatusBar
)
1137 #endif // wxUSE_STATUSBAR
1139 // ----------------------------------------------------------------------------
1141 // ----------------------------------------------------------------------------
1143 void wxFrame::SetTitle( const wxString
&title
)
1145 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1148 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1151 void wxFrame::SetIcon( const wxIcon
&icon
)
1153 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1155 wxFrameBase::SetIcon(icon
);
1160 if (!m_widget
->window
)
1163 wxMask
*mask
= icon
.GetMask();
1164 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1165 if (mask
) bm
= mask
->GetBitmap();
1167 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1170 // ----------------------------------------------------------------------------
1171 // frame state: maximized/iconized/normal
1172 // ----------------------------------------------------------------------------
1174 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1176 wxFAIL_MSG( _T("not implemented") );
1179 bool wxFrame::IsMaximized() const
1181 // wxFAIL_MSG( _T("not implemented") );
1183 // This is an approximation
1187 void wxFrame::Restore()
1189 wxFAIL_MSG( _T("not implemented") );
1192 void wxFrame::Iconize( bool iconize
)
1196 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1197 GDK_WINDOW_XWINDOW( m_widget
->window
),
1198 DefaultScreen( GDK_DISPLAY() ) );
1202 bool wxFrame::IsIconized() const
1204 return m_isIconized
;