1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "frame.h"
15 #include "wx/dialog.h"
16 #include "wx/control.h"
20 #include "wx/toolbar.h"
23 #include "wx/statusbr.h"
25 #include "wx/dcclient.h"
30 #include "wx/gtk/win_gtk.h"
31 #include "gdk/gdkkeysyms.h"
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 const int wxMENU_HEIGHT
= 27;
39 const int wxSTATUS_HEIGHT
= 25;
40 const int wxPLACE_HOLDER
= 0;
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 extern void wxapp_install_idle_handler();
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
53 extern wxList wxPendingDelete
;
55 //-----------------------------------------------------------------------------
57 //-----------------------------------------------------------------------------
61 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
);
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame
*win
)
72 wxapp_install_idle_handler();
77 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
80 wxPrintf( "OnSize from " );
81 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
82 wxPrintf( win->GetClassInfo()->GetClassName() );
83 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
89 win
->m_width
= alloc
->width
;
90 win
->m_height
= alloc
->height
;
95 //-----------------------------------------------------------------------------
97 //-----------------------------------------------------------------------------
99 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
102 wxapp_install_idle_handler();
109 //-----------------------------------------------------------------------------
110 // "child_attached" of menu bar
111 //-----------------------------------------------------------------------------
113 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
115 if (!win
->m_hasVMT
) return;
117 win
->m_menuBarDetached
= FALSE
;
121 //-----------------------------------------------------------------------------
122 // "child_detached" of menu bar
123 //-----------------------------------------------------------------------------
125 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
127 if (!win
->m_hasVMT
) return;
129 win
->m_menuBarDetached
= TRUE
;
134 //-----------------------------------------------------------------------------
135 // "child_attached" of tool bar
136 //-----------------------------------------------------------------------------
138 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
140 if (!win
->m_hasVMT
) return;
142 win
->m_toolBarDetached
= FALSE
;
147 //-----------------------------------------------------------------------------
148 // "child_detached" of tool bar
149 //-----------------------------------------------------------------------------
151 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
154 wxapp_install_idle_handler();
156 if (!win
->m_hasVMT
) return;
158 win
->m_toolBarDetached
= TRUE
;
161 #endif // wxUSE_TOOLBAR
163 //-----------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------
168 #if (GTK_MINOR_VERSON > 0)
169 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
171 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
175 wxapp_install_idle_handler();
177 if (!win
->m_hasVMT
) return FALSE
;
179 #if (GTK_MINOR_VERSON > 0)
182 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
190 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
191 mevent
.SetEventObject( win
);
192 win
->GetEventHandler()->ProcessEvent( mevent
);
197 //-----------------------------------------------------------------------------
198 // "realize" from m_widget
199 //-----------------------------------------------------------------------------
201 /* we cannot MWM hints and icons before the widget has been realized,
202 so we do this directly after realization */
205 gtk_frame_realized_callback( GtkWidget
*WXUNUSED(widget
), wxFrame
*win
)
208 wxapp_install_idle_handler();
210 /* all this is for Motif Window Manager "hints" and is supposed to be
211 recognized by other WM as well. not tested. */
212 long decor
= (long) GDK_DECOR_BORDER
;
213 long func
= (long) GDK_FUNC_MOVE
;
215 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
216 decor
|= GDK_DECOR_TITLE
;
217 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
219 decor
|= GDK_DECOR_MENU
;
220 func
|= GDK_FUNC_CLOSE
;
222 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
224 func
|= GDK_FUNC_MINIMIZE
;
225 decor
|= GDK_DECOR_MINIMIZE
;
227 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
229 func
|= GDK_FUNC_MAXIMIZE
;
230 decor
|= GDK_DECOR_MAXIMIZE
;
232 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
234 func
|= GDK_FUNC_RESIZE
;
235 decor
|= GDK_DECOR_RESIZEH
;
238 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
239 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
241 /* GTK's shrinking/growing policy */
242 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
243 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
245 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
248 gint flag
= GDK_HINT_POS
;
249 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
250 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
253 gdk_window_set_hints( win
->m_widget
->window
,
255 win
->GetMinWidth(), win
->GetMinHeight(),
256 win
->GetMaxWidth(), win
->GetMaxHeight(),
261 if (win
->m_icon
!= wxNullIcon
)
263 wxIcon
icon( win
->m_icon
);
264 win
->m_icon
= wxNullIcon
;
265 win
->SetIcon( icon
);
268 /* we set the focus to the child that accepts the focus. this
269 doesn't really have to be done in "realize" but why not? */
270 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
273 wxWindow
*child
= node
->GetData();
274 if (child
->AcceptsFocus())
280 node
= node
->GetNext();
286 //-----------------------------------------------------------------------------
287 // InsertChild for wxFrame
288 //-----------------------------------------------------------------------------
290 /* Callback for wxFrame. This very strange beast has to be used because
291 * C++ has no virtual methods in a constructor. We have to emulate a
292 * virtual function here as wxWindows requires different ways to insert
293 * a child in container classes. */
295 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
297 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
299 if (!parent
->m_insertInClientArea
)
301 /* these are outside the client area */
302 wxFrame
* frame
= (wxFrame
*) parent
;
303 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
304 GTK_WIDGET(child
->m_widget
),
311 /* we connect to these events for recalculating the client area
312 space when the toolbar is floating */
313 if (wxIS_KIND_OF(child
,wxToolBar
))
315 wxToolBar
*toolBar
= (wxToolBar
*) child
;
316 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
318 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
319 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
321 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
322 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
325 #endif // wxUSE_TOOLBAR
329 /* these are inside the client area */
330 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
331 GTK_WIDGET(child
->m_widget
),
338 /* resize on OnInternalIdle */
339 parent
->UpdateSize();
342 //-----------------------------------------------------------------------------
344 //-----------------------------------------------------------------------------
346 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
347 EVT_SIZE(wxFrame::OnSize
)
348 EVT_IDLE(wxFrame::OnIdle
)
349 EVT_CLOSE(wxFrame::OnCloseWindow
)
350 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
353 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
357 m_frameMenuBar
= (wxMenuBar
*) NULL
;
359 m_frameStatusBar
= (wxStatusBar
*) NULL
;
360 #endif // wxUSE_STATUSBAR
362 m_frameToolBar
= (wxToolBar
*) NULL
;
363 #endif // wxUSE_TOOLBAR
367 m_mainWidget
= (GtkWidget
*) NULL
;
368 m_menuBarDetached
= FALSE
;
369 m_toolBarDetached
= FALSE
;
370 m_insertInClientArea
= TRUE
;
374 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
375 const wxPoint
&pos
, const wxSize
&size
,
376 long style
, const wxString
&name
)
380 Create( parent
, id
, title
, pos
, size
, style
, name
);
383 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
384 const wxPoint
&pos
, const wxSize
&size
,
385 long style
, const wxString
&name
)
387 wxTopLevelWindows
.Append( this );
389 m_needParent
= FALSE
;
391 if (!PreCreation( parent
, pos
, size
) ||
392 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
394 wxFAIL_MSG( wxT("wxFrame creation failed") );
400 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
402 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
403 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
405 m_widget
= gtk_window_new( win_type
);
408 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
411 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
414 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
415 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
417 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
418 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
420 /* m_mainWidget holds the toolbar, the menubar and the client area */
421 m_mainWidget
= gtk_pizza_new();
422 gtk_widget_show( m_mainWidget
);
423 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
424 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
427 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
430 /* m_wxwindow only represents the client area without toolbar and menubar */
431 m_wxwindow
= gtk_pizza_new();
432 gtk_widget_show( m_wxwindow
);
433 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
436 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
439 /* we donm't allow the frame to get the focus as otherwise
440 the frame will grabit at arbitrary fcous changes. */
441 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
443 if (m_parent
) m_parent
->AddChild( this );
445 /* the user resized the frame by dragging etc. */
446 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
447 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
451 /* we cannot set MWM hints and icons before the widget has
452 been realized, so we do this directly after realization */
453 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
454 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
456 /* the only way to get the window size is to connect to this event */
457 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
458 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
465 m_isBeingDeleted
= TRUE
;
467 if (m_frameMenuBar
) delete m_frameMenuBar
;
468 m_frameMenuBar
= (wxMenuBar
*) NULL
;
471 if (m_frameStatusBar
) delete m_frameStatusBar
;
472 m_frameStatusBar
= (wxStatusBar
*) NULL
;
473 #endif // wxUSE_STATUSBAR
476 if (m_frameToolBar
) delete m_frameToolBar
;
477 m_frameToolBar
= (wxToolBar
*) NULL
;
478 #endif // wxUSE_TOOLBAR
480 wxTopLevelWindows
.DeleteObject( this );
482 if (wxTheApp
->GetTopWindow() == this)
483 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
485 if (wxTopLevelWindows
.Number() == 0)
486 wxTheApp
->ExitMainLoop();
489 bool wxFrame::Show( bool show
)
491 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
493 if (show
&& !m_sizeSet
)
495 /* by calling GtkOnSize here, we don't have to call
496 either after showing the frame, which would entail
497 much ugly flicker or from within the size_allocate
498 handler, because GTK 1.1.X forbids that. */
500 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
503 return wxWindow::Show( show
);
506 bool wxFrame::Destroy()
508 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
510 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
515 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
517 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
519 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
520 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
522 /* avoid recursions */
523 if (m_resizing
) return;
528 int old_width
= m_width
;
529 int old_height
= m_height
;
531 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
533 if (x
!= -1) m_x
= x
;
534 if (y
!= -1) m_y
= y
;
535 if (width
!= -1) m_width
= width
;
536 if (height
!= -1) m_height
= height
;
547 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
549 if (width == -1) m_width = 80;
552 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
554 if (height == -1) m_height = 26;
558 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
559 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
560 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
561 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
563 if ((m_x
!= -1) || (m_y
!= -1))
565 if ((m_x
!= old_x
) || (m_y
!= old_y
))
567 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
571 if ((m_width
!= old_width
) || (m_height
!= old_height
))
573 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
574 done either directly before the frame is shown or in idle time
575 so that different calls to SetSize() don't lead to flicker. */
582 void wxFrame::Centre( int direction
)
584 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
589 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
590 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
595 void wxFrame::DoGetClientSize( int *width
, int *height
) const
597 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
599 wxWindow::DoGetClientSize( width
, height
);
605 if (!m_menuBarDetached
)
606 (*height
) -= wxMENU_HEIGHT
;
608 (*height
) -= wxPLACE_HOLDER
;
613 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
620 if (!m_toolBarDetached
)
623 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
627 (*height
) -= wxPLACE_HOLDER
;
632 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
636 (*width
) -= m_miniEdge
*2;
640 void wxFrame::DoSetClientSize( int width
, int height
)
642 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
644 printf( "set size %d %d\n", width
, height
);
649 if (!m_menuBarDetached
)
650 height
+= wxMENU_HEIGHT
;
652 height
+= wxPLACE_HOLDER
;
657 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
664 if (!m_toolBarDetached
)
667 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
671 height
+= wxPLACE_HOLDER
;
675 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
678 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
680 // due to a bug in gtk, x,y are always 0
684 /* avoid recursions */
685 if (m_resizing
) return;
688 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
689 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
694 /* space occupied by m_frameToolBar and m_frameMenuBar */
695 int client_area_y_offset
= 0;
697 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
698 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
699 set in wxFrame::Create so it is used to check what kind of frame we
700 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
701 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
702 importantly) m_mainWidget */
706 /* check if size is in legal range */
707 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
708 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
709 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
710 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
712 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
713 * menubar, the toolbar and the client area, which is represented by
715 * this hurts in the eye, but I don't want to call SetSize()
716 * because I don't want to call any non-native functions here. */
721 int yy
= m_miniEdge
+ m_miniTitle
;
722 int ww
= m_width
- 2*m_miniEdge
;
723 int hh
= wxMENU_HEIGHT
;
724 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
725 m_frameMenuBar
->m_x
= xx
;
726 m_frameMenuBar
->m_y
= yy
;
727 m_frameMenuBar
->m_width
= ww
;
728 m_frameMenuBar
->m_height
= hh
;
729 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
730 m_frameMenuBar
->m_widget
,
732 client_area_y_offset
+= hh
;
736 if ((m_frameToolBar
) &&
737 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
740 int yy
= m_miniEdge
+ m_miniTitle
;
743 if (!m_menuBarDetached
)
746 yy
+= wxPLACE_HOLDER
;
748 int ww
= m_width
- 2*m_miniEdge
;
749 int hh
= m_frameToolBar
->m_height
;
750 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
751 m_frameToolBar
->m_x
= xx
;
752 m_frameToolBar
->m_y
= yy
;
753 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
754 m_frameToolBar->m_width = ww; */
755 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
756 m_frameToolBar
->m_widget
,
758 client_area_y_offset
+= hh
;
762 int client_x
= m_miniEdge
;
763 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
764 int client_w
= m_width
- 2*m_miniEdge
;
765 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
766 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
768 client_x
, client_y
, client_w
, client_h
);
772 /* if there is no m_mainWidget between m_widget and m_wxwindow there
773 is no need to set the size or position of m_wxwindow. */
777 if (m_frameStatusBar
)
779 int xx
= 0 + m_miniEdge
;
780 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
781 int ww
= m_width
- 2*m_miniEdge
;
782 int hh
= wxSTATUS_HEIGHT
;
783 m_frameStatusBar
->m_x
= xx
;
784 m_frameStatusBar
->m_y
= yy
;
785 m_frameStatusBar
->m_width
= ww
;
786 m_frameStatusBar
->m_height
= hh
;
787 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
788 m_frameStatusBar
->m_widget
,
793 /* we actually set the size of a frame here and no-where else */
794 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
799 // send size event to frame
800 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
801 event
.SetEventObject( this );
802 GetEventHandler()->ProcessEvent( event
);
804 // send size event to status bar
805 if (m_frameStatusBar
)
807 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
808 event2
.SetEventObject( m_frameStatusBar
);
809 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
815 void wxFrame::MakeModal( bool modal
)
818 gtk_grab_add( m_widget
);
820 gtk_grab_remove( m_widget
);
823 void wxFrame::OnInternalIdle()
825 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
827 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
829 // we'll come back later
831 wxapp_install_idle_handler();
835 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
837 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
840 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
843 wxWindow::OnInternalIdle();
846 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
851 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
853 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
855 #if wxUSE_CONSTRAINTS
861 #endif // wxUSE_CONSTRAINTS
863 /* do we have exactly one child? */
864 wxWindow
*child
= (wxWindow
*)NULL
;
865 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
867 wxWindow
*win
= (wxWindow
*)node
->Data();
868 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
872 /* it's the second one: do nothing */
880 /* no children at all? */
883 /* yes: set it's size to fill all the frame */
884 int client_x
, client_y
;
885 DoGetClientSize( &client_x
, &client_y
);
886 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
891 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
893 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
894 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
896 m_frameMenuBar
= menuBar
;
900 m_frameMenuBar
->SetInvokingWindow( this );
902 if (m_frameMenuBar
->GetParent() != this)
904 m_frameMenuBar
->SetParent(this);
905 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
906 m_frameMenuBar
->m_widget
,
909 m_frameMenuBar
->m_width
,
910 m_frameMenuBar
->m_height
);
912 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
914 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
915 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
917 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
918 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
921 m_frameMenuBar
->Show( TRUE
);
925 /* resize window in OnInternalIdle */
929 wxMenuBar
*wxFrame::GetMenuBar() const
931 return m_frameMenuBar
;
934 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
939 // if no help string found, we will clear the status bar text
942 int menuId
= event
.GetMenuId();
943 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
945 wxMenuBar
*menuBar
= GetMenuBar();
948 // it's ok if we don't find the item because it might belong to
950 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
952 helpString
= item
->GetHelp();
956 SetStatusText(helpString
);
958 #endif // wxUSE_STATUSBAR
962 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
964 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
966 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
968 m_insertInClientArea
= FALSE
;
970 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
972 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
974 m_insertInClientArea
= TRUE
;
978 return m_frameToolBar
;
981 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
983 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
986 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
988 m_frameToolBar
= toolbar
;
991 /* insert into toolbar area if not already there */
992 if ((m_frameToolBar
->m_widget
->parent
) &&
993 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
995 GetChildren().DeleteObject( m_frameToolBar
);
997 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1003 wxToolBar
*wxFrame::GetToolBar() const
1005 return m_frameToolBar
;
1007 #endif // wxUSE_TOOLBAR
1010 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1012 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1014 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1016 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1020 return m_frameStatusBar
;
1023 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1025 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1027 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1029 // Set the height according to the font and the border size
1030 wxClientDC
dc(statusBar
);
1031 dc
.SetFont( statusBar
->GetFont() );
1034 dc
.GetTextExtent( "X", &x
, &y
);
1036 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1038 statusBar
->SetSize( -1, -1, 100, height
);
1040 statusBar
->SetFieldsCount( number
);
1044 wxStatusBar
*wxFrame::GetStatusBar() const
1046 return m_frameStatusBar
;
1049 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1051 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1053 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1055 m_frameStatusBar
->SetStatusText(text
, number
);
1058 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1060 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1062 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1064 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1066 #endif // wxUSE_STATUSBAR
1068 void wxFrame::Command( int id
)
1070 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1071 commandEvent
.SetInt( id
);
1072 commandEvent
.SetEventObject( this );
1074 wxMenuBar
*bar
= GetMenuBar();
1077 wxMenuItem
*item
= bar
->FindItem(id
) ;
1078 if (item
&& item
->IsCheckable())
1080 bar
->Check(id
, !bar
->IsChecked(id
)) ;
1083 wxEvtHandler
* evtHandler
= GetEventHandler();
1085 evtHandler
->ProcessEvent(commandEvent
);
1088 void wxFrame::SetTitle( const wxString
&title
)
1090 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1093 if (m_title
.IsNull()) m_title
= wxT("");
1094 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1097 void wxFrame::SetIcon( const wxIcon
&icon
)
1099 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1102 if (!icon
.Ok()) return;
1104 if (!m_widget
->window
) return;
1106 wxMask
*mask
= icon
.GetMask();
1107 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1108 if (mask
) bm
= mask
->GetBitmap();
1110 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1113 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1117 void wxFrame::Restore()
1121 void wxFrame::Iconize( bool iconize
)
1125 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1126 GDK_WINDOW_XWINDOW( m_widget
->window
),
1127 DefaultScreen( GDK_DISPLAY() ) );
1131 bool wxFrame::IsIconized() const