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
;
454 bool wxFrame::Create( wxWindow
*parent
,
456 const wxString
&title
,
460 const wxString
&name
)
462 wxTopLevelWindows
.Append( this );
464 m_needParent
= FALSE
;
466 if (!PreCreation( parent
, pos
, size
) ||
467 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
469 wxFAIL_MSG( wxT("wxFrame creation failed") );
475 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
477 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
479 if (style
& wxFRAME_TOOL_WINDOW
)
480 win_type
= GTK_WINDOW_POPUP
;
482 m_widget
= gtk_window_new( win_type
);
484 if ((m_parent
) && (HasFlag(wxFRAME_FLOAT_ON_PARENT
)) && (GTK_IS_WINDOW(m_parent
->m_widget
)))
485 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
488 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
491 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
494 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
495 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
497 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
498 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
500 /* m_mainWidget holds the toolbar, the menubar and the client area */
501 m_mainWidget
= gtk_pizza_new();
502 gtk_widget_show( m_mainWidget
);
503 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
504 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
506 /* for m_mainWidget themes */
507 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
508 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
509 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
510 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
513 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
516 /* m_wxwindow only represents the client area without toolbar and menubar */
517 m_wxwindow
= gtk_pizza_new();
518 gtk_widget_show( m_wxwindow
);
519 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
522 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
525 /* we donm't allow the frame to get the focus as otherwise
526 the frame will grabit at arbitrary fcous changes. */
527 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
529 if (m_parent
) m_parent
->AddChild( this );
531 /* the user resized the frame by dragging etc. */
532 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
533 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
537 if ((m_x
!= -1) || (m_y
!= -1))
538 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
539 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
541 /* we cannot set MWM hints and icons before the widget has
542 been realized, so we do this directly after realization */
543 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
544 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
546 /* the only way to get the window size is to connect to this event */
547 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
548 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
550 /* map and unmap for iconized state */
551 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
552 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
553 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
554 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
556 /* the only way to get the window size is to connect to this event */
557 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
558 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
560 /* disable native tab traversal */
561 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
562 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
569 m_isBeingDeleted
= TRUE
;
573 wxTopLevelWindows
.DeleteObject( this );
575 if (wxTheApp
->GetTopWindow() == this)
576 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
578 if ((wxTopLevelWindows
.Number() == 0) &&
579 (wxTheApp
->GetExitOnFrameDelete()))
581 wxTheApp
->ExitMainLoop();
585 bool wxFrame::ShowFullScreen(bool show
, long style
)
587 if (show
== m_fsIsShowing
) return FALSE
; // return what?
589 m_fsIsShowing
= show
;
593 m_fsSaveStyle
= m_windowStyle
;
594 m_fsSaveFlag
= style
;
595 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
596 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
598 gtk_widget_hide( m_widget
);
599 gtk_widget_unrealize( m_widget
);
601 m_windowStyle
= wxSIMPLE_BORDER
;
605 wxDisplaySize( &x
, &y
);
606 SetSize( 0, 0, x
, y
);
608 gtk_widget_realize( m_widget
);
609 gtk_widget_show( m_widget
);
613 gtk_widget_hide( m_widget
);
614 gtk_widget_unrealize( m_widget
);
616 m_windowStyle
= m_fsSaveStyle
;
618 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
620 gtk_widget_realize( m_widget
);
621 gtk_widget_show( m_widget
);
627 // ----------------------------------------------------------------------------
628 // overridden wxWindow methods
629 // ----------------------------------------------------------------------------
631 bool wxFrame::Show( bool show
)
633 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
635 if (show
&& !m_sizeSet
)
637 /* by calling GtkOnSize here, we don't have to call
638 either after showing the frame, which would entail
639 much ugly flicker or from within the size_allocate
640 handler, because GTK 1.1.X forbids that. */
642 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
645 return wxWindow::Show( show
);
648 void wxFrame::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
650 wxFAIL_MSG( wxT("DoMoveWindow called for wxFrame") );
653 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
655 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
657 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
658 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
660 /* avoid recursions */
668 int old_width
= m_width
;
669 int old_height
= m_height
;
671 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
673 if (x
!= -1) m_x
= x
;
674 if (y
!= -1) m_y
= y
;
675 if (width
!= -1) m_width
= width
;
676 if (height
!= -1) m_height
= height
;
687 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
689 if (width == -1) m_width = 80;
692 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
694 if (height == -1) m_height = 26;
698 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
699 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
700 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
701 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
703 if ((m_x
!= -1) || (m_y
!= -1))
705 if ((m_x
!= old_x
) || (m_y
!= old_y
))
707 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
711 if ((m_width
!= old_width
) || (m_height
!= old_height
))
713 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
715 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
716 done either directly before the frame is shown or in idle time
717 so that different calls to SetSize() don't lead to flicker. */
724 void wxFrame::DoGetClientSize( int *width
, int *height
) const
726 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
728 wxWindow::DoGetClientSize( width
, height
);
734 if (!m_menuBarDetached
)
735 (*height
) -= wxMENU_HEIGHT
;
737 (*height
) -= wxPLACE_HOLDER
;
742 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) (*height
) -= wxSTATUS_HEIGHT
;
743 #endif // wxUSE_STATUSBAR
747 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
749 if (m_toolBarDetached
)
751 *height
-= wxPLACE_HOLDER
;
756 m_frameToolBar
->GetSize( &x
, &y
);
757 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
767 #endif // wxUSE_TOOLBAR
770 *height
-= m_miniEdge
*2 + m_miniTitle
;
774 *width
-= m_miniEdge
*2;
778 void wxFrame::DoSetClientSize( int width
, int height
)
780 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
785 if (!m_menuBarDetached
)
786 height
+= wxMENU_HEIGHT
;
788 height
+= wxPLACE_HOLDER
;
793 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown()) height
+= wxSTATUS_HEIGHT
;
798 if (m_frameToolBar
&& m_frameToolBar
->IsShown())
800 if (m_toolBarDetached
)
802 height
+= wxPLACE_HOLDER
;
807 m_frameToolBar
->GetSize( &x
, &y
);
808 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
820 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
823 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
824 int width
, int height
)
826 // due to a bug in gtk, x,y are always 0
830 /* avoid recursions */
831 if (m_resizing
) return;
834 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
835 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
840 /* space occupied by m_frameToolBar and m_frameMenuBar */
841 int client_area_x_offset
= 0,
842 client_area_y_offset
= 0;
844 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
845 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
846 set in wxFrame::Create so it is used to check what kind of frame we
847 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
848 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
849 importantly) m_mainWidget */
851 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
852 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
853 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
854 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
859 gint flag
= 0; // GDK_HINT_POS;
860 if ((m_minWidth
!= -1) || (m_minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
861 if ((m_maxWidth
!= -1) || (m_maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
863 geom
.min_width
= m_minWidth
;
864 geom
.min_height
= m_minHeight
;
865 geom
.max_width
= m_maxWidth
;
866 geom
.max_height
= m_maxHeight
;
867 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
870 (GdkWindowHints
) flag
);
872 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
873 * menubar, the toolbar and the client area, which is represented by
875 * this hurts in the eye, but I don't want to call SetSize()
876 * because I don't want to call any non-native functions here. */
881 int yy
= m_miniEdge
+ m_miniTitle
;
882 int ww
= m_width
- 2*m_miniEdge
;
883 int hh
= wxMENU_HEIGHT
;
884 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
885 m_frameMenuBar
->m_x
= xx
;
886 m_frameMenuBar
->m_y
= yy
;
887 m_frameMenuBar
->m_width
= ww
;
888 m_frameMenuBar
->m_height
= hh
;
889 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
890 m_frameMenuBar
->m_widget
,
892 client_area_y_offset
+= hh
;
896 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
897 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
900 int yy
= m_miniEdge
+ m_miniTitle
;
903 if (!m_menuBarDetached
)
906 yy
+= wxPLACE_HOLDER
;
909 m_frameToolBar
->m_x
= xx
;
910 m_frameToolBar
->m_y
= yy
;
912 /* don't change the toolbar's reported height/width */
914 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
916 ww
= m_toolBarDetached
? wxPLACE_HOLDER
917 : m_frameToolBar
->m_width
;
918 hh
= m_height
- 2*m_miniEdge
;
920 client_area_x_offset
+= ww
;
924 ww
= m_width
- 2*m_miniEdge
;
925 hh
= m_toolBarDetached
? wxPLACE_HOLDER
926 : m_frameToolBar
->m_height
;
928 client_area_y_offset
+= hh
;
931 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
932 m_frameToolBar
->m_widget
,
935 #endif // wxUSE_TOOLBAR
937 int client_x
= client_area_x_offset
+ m_miniEdge
;
938 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
939 int client_w
= m_width
- client_area_x_offset
- 2*m_miniEdge
;
940 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
941 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
943 client_x
, client_y
, client_w
, client_h
);
947 /* if there is no m_mainWidget between m_widget and m_wxwindow there
948 is no need to set the size or position of m_wxwindow. */
952 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
954 int xx
= 0 + m_miniEdge
;
955 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
956 int ww
= m_width
- 2*m_miniEdge
;
957 int hh
= wxSTATUS_HEIGHT
;
958 m_frameStatusBar
->m_x
= xx
;
959 m_frameStatusBar
->m_y
= yy
;
960 m_frameStatusBar
->m_width
= ww
;
961 m_frameStatusBar
->m_height
= hh
;
962 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
963 m_frameStatusBar
->m_widget
,
965 gtk_widget_draw( m_frameStatusBar
->m_widget
, (GdkRectangle
*) NULL
);
971 // send size event to frame
972 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
973 event
.SetEventObject( this );
974 GetEventHandler()->ProcessEvent( event
);
976 // send size event to status bar
977 if (m_frameStatusBar
)
979 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
980 event2
.SetEventObject( m_frameStatusBar
);
981 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
987 void wxFrame::MakeModal( bool modal
)
990 gtk_grab_add( m_widget
);
992 gtk_grab_remove( m_widget
);
995 void wxFrame::OnInternalIdle()
997 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
999 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
1001 // we'll come back later
1003 wxapp_install_idle_handler();
1007 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
1009 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
1012 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
1015 wxWindow::OnInternalIdle();
1018 // ----------------------------------------------------------------------------
1019 // menu/tool/status bar stuff
1020 // ----------------------------------------------------------------------------
1022 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
1024 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1025 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
1027 if (menuBar
== m_frameMenuBar
)
1032 m_frameMenuBar
->UnsetInvokingWindow( this );
1034 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1036 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1037 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1039 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar
->m_widget
),
1040 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1043 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
1044 gtk_widget_ref( m_frameMenuBar
->m_widget
);
1045 gtk_widget_unparent( m_frameMenuBar
->m_widget
);
1048 m_frameMenuBar
= menuBar
;
1052 m_frameMenuBar
->SetInvokingWindow( this );
1054 m_frameMenuBar
->SetParent(this);
1055 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
1056 m_frameMenuBar
->m_widget
,
1057 m_frameMenuBar
->m_x
,
1058 m_frameMenuBar
->m_y
,
1059 m_frameMenuBar
->m_width
,
1060 m_frameMenuBar
->m_height
);
1062 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
1064 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
1065 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
1067 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
1068 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
1071 m_frameMenuBar
->Show( TRUE
);
1074 /* resize window in OnInternalIdle */
1079 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
1081 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1083 m_insertInClientArea
= FALSE
;
1085 m_frameToolBar
= wxFrameBase::CreateToolBar( style
, id
, name
);
1087 m_insertInClientArea
= TRUE
;
1091 return m_frameToolBar
;
1094 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1096 wxFrameBase::SetToolBar(toolbar
);
1100 /* insert into toolbar area if not already there */
1101 if ((m_frameToolBar
->m_widget
->parent
) &&
1102 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1104 GetChildren().DeleteObject( m_frameToolBar
);
1106 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1112 #endif // wxUSE_TOOLBAR
1116 wxStatusBar
* wxFrame::CreateStatusBar(int number
,
1119 const wxString
& name
)
1121 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1123 // because it will change when toolbar is added
1126 return wxFrameBase::CreateStatusBar( number
, style
, id
, name
);
1129 void wxFrame::PositionStatusBar()
1131 if ( !m_frameStatusBar
)
1136 #endif // wxUSE_STATUSBAR
1138 // ----------------------------------------------------------------------------
1140 // ----------------------------------------------------------------------------
1142 void wxFrame::SetTitle( const wxString
&title
)
1144 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1147 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1150 void wxFrame::SetIcon( const wxIcon
&icon
)
1152 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1154 wxFrameBase::SetIcon(icon
);
1159 if (!m_widget
->window
)
1162 wxMask
*mask
= icon
.GetMask();
1163 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1164 if (mask
) bm
= mask
->GetBitmap();
1166 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1169 // ----------------------------------------------------------------------------
1170 // frame state: maximized/iconized/normal
1171 // ----------------------------------------------------------------------------
1173 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1175 wxFAIL_MSG( _T("not implemented") );
1178 bool wxFrame::IsMaximized() const
1180 wxFAIL_MSG( _T("not implemented") );
1185 void wxFrame::Restore()
1187 wxFAIL_MSG( _T("not implemented") );
1190 void wxFrame::Iconize( bool iconize
)
1194 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1195 GDK_WINDOW_XWINDOW( m_widget
->window
),
1196 DefaultScreen( GDK_DISPLAY() ) );
1200 bool wxFrame::IsIconized() const
1202 return m_isIconized
;