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
;
451 m_isIconized
= FALSE
;
452 m_fsIsShowing
= FALSE
;
453 m_themeEnabled
= TRUE
;
456 bool wxFrame::Create( wxWindow
*parent
,
458 const wxString
&title
,
462 const wxString
&name
)
464 wxTopLevelWindows
.Append( this );
466 m_needParent
= FALSE
;
468 if (!PreCreation( parent
, pos
, size
) ||
469 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
471 wxFAIL_MSG( wxT("wxFrame creation failed") );
477 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
479 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
481 if (style
& wxFRAME_TOOL_WINDOW
)
482 win_type
= GTK_WINDOW_POPUP
;
484 m_widget
= gtk_window_new( win_type
);
486 if ((m_parent
) && (HasFlag(wxFRAME_FLOAT_ON_PARENT
)) && (GTK_IS_WINDOW(m_parent
->m_widget
)))
487 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
490 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
493 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
496 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
497 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
499 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
500 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
502 /* m_mainWidget holds the toolbar, the menubar and the client area */
503 m_mainWidget
= gtk_pizza_new();
504 gtk_widget_show( m_mainWidget
);
505 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
506 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
508 /* for m_mainWidget themes */
509 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
510 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
511 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
512 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
515 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
518 /* m_wxwindow only represents the client area without toolbar and menubar */
519 m_wxwindow
= gtk_pizza_new();
520 gtk_widget_show( m_wxwindow
);
521 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
524 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
527 /* we donm't allow the frame to get the focus as otherwise
528 the frame will grabit at arbitrary fcous changes. */
529 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
531 if (m_parent
) m_parent
->AddChild( this );
533 /* the user resized the frame by dragging etc. */
534 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
535 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
539 if ((m_x
!= -1) || (m_y
!= -1))
540 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
541 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
543 /* we cannot set MWM hints and icons before the widget has
544 been realized, so we do this directly after realization */
545 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
546 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
548 /* the only way to get the window size is to connect to this event */
549 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
550 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
552 /* map and unmap for iconized state */
553 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
554 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
555 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
556 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
558 /* the only way to get the window size is to connect to this event */
559 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
560 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
562 /* disable native tab traversal */
563 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
564 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
571 m_isBeingDeleted
= TRUE
;
575 wxTopLevelWindows
.DeleteObject( this );
577 if (wxTheApp
->GetTopWindow() == this)
578 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
580 if ((wxTopLevelWindows
.Number() == 0) &&
581 (wxTheApp
->GetExitOnFrameDelete()))
583 wxTheApp
->ExitMainLoop();
587 bool wxFrame::ShowFullScreen(bool show
, long style
)
589 if (show
== m_fsIsShowing
) return FALSE
; // return what?
591 m_fsIsShowing
= show
;
595 m_fsSaveStyle
= m_windowStyle
;
596 m_fsSaveFlag
= style
;
597 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
598 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
600 gtk_widget_hide( m_widget
);
601 gtk_widget_unrealize( m_widget
);
603 m_windowStyle
= wxSIMPLE_BORDER
;
607 wxDisplaySize( &x
, &y
);
608 SetSize( 0, 0, x
, y
);
610 gtk_widget_realize( m_widget
);
611 gtk_widget_show( m_widget
);
615 gtk_widget_hide( m_widget
);
616 gtk_widget_unrealize( m_widget
);
618 m_windowStyle
= m_fsSaveStyle
;
620 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
622 gtk_widget_realize( m_widget
);
623 gtk_widget_show( m_widget
);
629 // ----------------------------------------------------------------------------
630 // overridden wxWindow methods
631 // ----------------------------------------------------------------------------
633 bool wxFrame::Show( bool show
)
635 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
637 if (show
&& !m_sizeSet
)
639 /* by calling GtkOnSize here, we don't have to call
640 either after showing the frame, which would entail
641 much ugly flicker or from within the size_allocate
642 handler, because GTK 1.1.X forbids that. */
644 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
647 return wxWindow::Show( show
);
650 void wxFrame::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
652 wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
655 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
657 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
659 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
660 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
662 /* avoid recursions */
670 int old_width
= m_width
;
671 int old_height
= m_height
;
673 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
675 if (x
!= -1) m_x
= x
;
676 if (y
!= -1) m_y
= y
;
677 if (width
!= -1) m_width
= width
;
678 if (height
!= -1) m_height
= height
;
689 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
691 if (width == -1) m_width = 80;
694 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
696 if (height == -1) m_height = 26;
700 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
701 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
702 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
703 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
705 if ((m_x
!= -1) || (m_y
!= -1))
707 if ((m_x
!= old_x
) || (m_y
!= old_y
))
709 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
713 if ((m_width
!= old_width
) || (m_height
!= old_height
))
715 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
717 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
718 done either directly before the frame is shown or in idle time
719 so that different calls to SetSize() don't lead to flicker. */
726 void wxFrame::DoGetClientSize( int *width
, int *height
) const
728 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
730 wxWindow::DoGetClientSize( width
, height
);
736 if (!m_menuBarDetached
)
737 (*height
) -= wxMENU_HEIGHT
;
739 (*height
) -= wxPLACE_HOLDER
;
744 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) (*height
) -= wxSTATUS_HEIGHT
;
745 #endif // wxUSE_STATUSBAR
749 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
751 if (m_toolBarDetached
)
753 *height
-= wxPLACE_HOLDER
;
758 m_frameToolBar
->GetSize( &x
, &y
);
759 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
769 #endif // wxUSE_TOOLBAR
772 *height
-= m_miniEdge
*2 + m_miniTitle
;
776 *width
-= m_miniEdge
*2;
780 void wxFrame::DoSetClientSize( int width
, int height
)
782 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
787 if (!m_menuBarDetached
)
788 height
+= wxMENU_HEIGHT
;
790 height
+= wxPLACE_HOLDER
;
795 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) height
+= wxSTATUS_HEIGHT
;
800 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
802 if (m_toolBarDetached
)
804 height
+= wxPLACE_HOLDER
;
809 m_frameToolBar
->GetSize( &x
, &y
);
810 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
822 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
825 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
826 int width
, int height
)
828 // due to a bug in gtk, x,y are always 0
832 /* avoid recursions */
833 if (m_resizing
) return;
836 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
837 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
842 /* space occupied by m_frameToolBar and m_frameMenuBar */
843 int client_area_x_offset
= 0,
844 client_area_y_offset
= 0;
846 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
847 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
848 set in wxFrame::Create so it is used to check what kind of frame we
849 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
850 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
851 importantly) m_mainWidget */
853 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
854 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
855 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
856 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
861 gint flag
= 0; // GDK_HINT_POS;
862 if ((m_minWidth
!= -1) || (m_minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
863 if ((m_maxWidth
!= -1) || (m_maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
865 geom
.min_width
= m_minWidth
;
866 geom
.min_height
= m_minHeight
;
867 geom
.max_width
= m_maxWidth
;
868 geom
.max_height
= m_maxHeight
;
869 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
872 (GdkWindowHints
) flag
);
874 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
875 * menubar, the toolbar and the client area, which is represented by
877 * this hurts in the eye, but I don't want to call SetSize()
878 * because I don't want to call any non-native functions here. */
883 int yy
= m_miniEdge
+ m_miniTitle
;
884 int ww
= m_width
- 2*m_miniEdge
;
885 int hh
= wxMENU_HEIGHT
;
886 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
887 m_frameMenuBar
->m_x
= xx
;
888 m_frameMenuBar
->m_y
= yy
;
889 m_frameMenuBar
->m_width
= ww
;
890 m_frameMenuBar
->m_height
= hh
;
891 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
892 m_frameMenuBar
->m_widget
,
894 client_area_y_offset
+= hh
;
898 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
899 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
902 int yy
= m_miniEdge
+ m_miniTitle
;
905 if (!m_menuBarDetached
)
908 yy
+= wxPLACE_HOLDER
;
911 m_frameToolBar
->m_x
= xx
;
912 m_frameToolBar
->m_y
= yy
;
914 /* don't change the toolbar's reported height/width */
916 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
918 ww
= m_toolBarDetached
? wxPLACE_HOLDER
919 : m_frameToolBar
->m_width
;
920 hh
= m_height
- 2*m_miniEdge
;
922 client_area_x_offset
+= ww
;
926 ww
= m_width
- 2*m_miniEdge
;
927 hh
= m_toolBarDetached
? wxPLACE_HOLDER
928 : m_frameToolBar
->m_height
;
930 client_area_y_offset
+= hh
;
933 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
934 m_frameToolBar
->m_widget
,
937 #endif // wxUSE_TOOLBAR
939 int client_x
= client_area_x_offset
+ m_miniEdge
;
940 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
941 int client_w
= m_width
- client_area_x_offset
- 2*m_miniEdge
;
942 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
943 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
945 client_x
, client_y
, client_w
, client_h
);
949 /* if there is no m_mainWidget between m_widget and m_wxwindow there
950 is no need to set the size or position of m_wxwindow. */
954 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
956 int xx
= 0 + m_miniEdge
;
957 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
958 int ww
= m_width
- 2*m_miniEdge
;
959 int hh
= wxSTATUS_HEIGHT
;
960 m_frameStatusBar
->m_x
= xx
;
961 m_frameStatusBar
->m_y
= yy
;
962 m_frameStatusBar
->m_width
= ww
;
963 m_frameStatusBar
->m_height
= hh
;
964 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
965 m_frameStatusBar
->m_widget
,
967 gtk_widget_draw( m_frameStatusBar
->m_widget
, (GdkRectangle
*) NULL
);
973 // send size event to frame
974 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
975 event
.SetEventObject( this );
976 GetEventHandler()->ProcessEvent( event
);
978 // send size event to status bar
979 if (m_frameStatusBar
)
981 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
982 event2
.SetEventObject( m_frameStatusBar
);
983 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
989 void wxFrame::MakeModal( bool modal
)
992 gtk_grab_add( m_widget
);
994 gtk_grab_remove( m_widget
);
997 void wxFrame::OnInternalIdle()
999 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
1001 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
1003 // we'll come back later
1005 wxapp_install_idle_handler();
1009 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
1011 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
1014 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
1017 wxWindow::OnInternalIdle();
1020 // ----------------------------------------------------------------------------
1021 // menu/tool/status bar stuff
1022 // ----------------------------------------------------------------------------
1024 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
1026 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1027 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
1029 if (menuBar
== m_frameMenuBar
)
1034 m_frameMenuBar
->UnsetInvokingWindow( this );
1036 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1038 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1039 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1041 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1042 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1045 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
1046 gtk_widget_ref( m_frameMenuBar
->m_widget
);
1047 gtk_widget_unparent( m_frameMenuBar
->m_widget
);
1050 m_frameMenuBar
= menuBar
;
1054 m_frameMenuBar
->SetInvokingWindow( this );
1056 m_frameMenuBar
->SetParent(this);
1057 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
1058 m_frameMenuBar
->m_widget
,
1059 m_frameMenuBar
->m_x
,
1060 m_frameMenuBar
->m_y
,
1061 m_frameMenuBar
->m_width
,
1062 m_frameMenuBar
->m_height
);
1064 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1066 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
1067 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1069 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
1070 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1073 m_frameMenuBar
->Show( TRUE
);
1076 /* resize window in OnInternalIdle */
1081 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1083 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1085 m_insertInClientArea
= FALSE
;
1087 m_frameToolBar
= wxFrameBase::CreateToolBar( style
, id
, name
);
1089 m_insertInClientArea
= TRUE
;
1093 return m_frameToolBar
;
1096 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1098 wxFrameBase::SetToolBar(toolbar
);
1102 /* insert into toolbar area if not already there */
1103 if ((m_frameToolBar
->m_widget
->parent
) &&
1104 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1106 GetChildren().DeleteObject( m_frameToolBar
);
1108 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1114 #endif // wxUSE_TOOLBAR
1118 wxStatusBar
* wxFrame::CreateStatusBar(int number
,
1121 const wxString
& name
)
1123 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1125 // because it will change when toolbar is added
1128 return wxFrameBase::CreateStatusBar( number
, style
, id
, name
);
1131 void wxFrame::PositionStatusBar()
1133 if ( !m_frameStatusBar
)
1138 #endif // wxUSE_STATUSBAR
1140 // ----------------------------------------------------------------------------
1142 // ----------------------------------------------------------------------------
1144 void wxFrame::SetTitle( const wxString
&title
)
1146 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1149 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1152 void wxFrame::SetIcon( const wxIcon
&icon
)
1154 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1156 wxFrameBase::SetIcon(icon
);
1161 if (!m_widget
->window
)
1164 wxMask
*mask
= icon
.GetMask();
1165 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1166 if (mask
) bm
= mask
->GetBitmap();
1168 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1171 // ----------------------------------------------------------------------------
1172 // frame state: maximized/iconized/normal
1173 // ----------------------------------------------------------------------------
1175 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1177 wxFAIL_MSG( _T("not implemented") );
1180 bool wxFrame::IsMaximized() const
1182 // wxFAIL_MSG( _T("not implemented") );
1184 // This is an approximation
1188 void wxFrame::Restore()
1190 wxFAIL_MSG( _T("not implemented") );
1193 void wxFrame::Iconize( bool iconize
)
1197 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1198 GDK_WINDOW_XWINDOW( m_widget
->window
),
1199 DefaultScreen( GDK_DISPLAY() ) );
1203 bool wxFrame::IsIconized() const
1205 return m_isIconized
;