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,
88 win
->m_width
= alloc
->width
;
89 win
->m_height
= alloc
->height
;
94 //-----------------------------------------------------------------------------
96 //-----------------------------------------------------------------------------
98 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
101 wxapp_install_idle_handler();
108 //-----------------------------------------------------------------------------
109 // "child_attached" of menu bar
110 //-----------------------------------------------------------------------------
112 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
114 if (!win
->m_hasVMT
) return;
116 win
->m_menuBarDetached
= FALSE
;
120 //-----------------------------------------------------------------------------
121 // "child_detached" of menu bar
122 //-----------------------------------------------------------------------------
124 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
126 if (!win
->m_hasVMT
) return;
128 win
->m_menuBarDetached
= TRUE
;
133 //-----------------------------------------------------------------------------
134 // "child_attached" of tool bar
135 //-----------------------------------------------------------------------------
137 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
139 if (!win
->m_hasVMT
) return;
141 win
->m_toolBarDetached
= FALSE
;
146 //-----------------------------------------------------------------------------
147 // "child_detached" of tool bar
148 //-----------------------------------------------------------------------------
150 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
153 wxapp_install_idle_handler();
155 if (!win
->m_hasVMT
) return;
157 win
->m_toolBarDetached
= TRUE
;
160 #endif // wxUSE_TOOLBAR
162 //-----------------------------------------------------------------------------
164 //-----------------------------------------------------------------------------
167 #if (GTK_MINOR_VERSON > 0)
168 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
170 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
174 wxapp_install_idle_handler();
176 if (!win
->m_hasVMT
) return FALSE
;
178 #if (GTK_MINOR_VERSON > 0)
181 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
189 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
190 mevent
.SetEventObject( win
);
191 win
->GetEventHandler()->ProcessEvent( mevent
);
196 //-----------------------------------------------------------------------------
197 // "realize" from m_widget
198 //-----------------------------------------------------------------------------
200 /* we cannot MWM hints and icons before the widget has been realized,
201 so we do this directly after realization */
204 gtk_frame_realized_callback( GtkWidget
*WXUNUSED(widget
), wxFrame
*win
)
207 wxapp_install_idle_handler();
209 /* all this is for Motif Window Manager "hints" and is supposed to be
210 recognized by other WM as well. not tested. */
211 long decor
= (long) GDK_DECOR_BORDER
;
212 long func
= (long) GDK_FUNC_MOVE
;
214 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
215 decor
|= GDK_DECOR_TITLE
;
216 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
218 decor
|= GDK_DECOR_MENU
;
219 func
|= GDK_FUNC_CLOSE
;
221 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
223 func
|= GDK_FUNC_MINIMIZE
;
224 decor
|= GDK_DECOR_MINIMIZE
;
226 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
228 func
|= GDK_FUNC_MAXIMIZE
;
229 decor
|= GDK_DECOR_MAXIMIZE
;
231 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
233 func
|= GDK_FUNC_RESIZE
;
234 decor
|= GDK_DECOR_RESIZEH
;
237 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
238 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
240 /* GTK's shrinking/growing policy */
241 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
242 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
244 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
247 gint flag
= GDK_HINT_POS
;
248 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
249 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
252 gdk_window_set_hints( win
->m_widget
->window
,
254 win
->GetMinWidth(), win
->GetMinHeight(),
255 win
->GetMaxWidth(), win
->GetMaxHeight(),
260 if (win
->m_icon
!= wxNullIcon
)
262 wxIcon
icon( win
->m_icon
);
263 win
->m_icon
= wxNullIcon
;
264 win
->SetIcon( icon
);
267 /* we set the focus to the child that accepts the focus. this
268 doesn't really have to be done in "realize" but why not? */
269 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
272 wxWindow
*child
= node
->GetData();
273 if (child
->AcceptsFocus())
279 node
= node
->GetNext();
285 //-----------------------------------------------------------------------------
286 // InsertChild for wxFrame
287 //-----------------------------------------------------------------------------
289 /* Callback for wxFrame. This very strange beast has to be used because
290 * C++ has no virtual methods in a constructor. We have to emulate a
291 * virtual function here as wxWindows requires different ways to insert
292 * a child in container classes. */
294 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
296 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
298 if (!parent
->m_insertInClientArea
)
300 /* these are outside the client area */
301 wxFrame
* frame
= (wxFrame
*) parent
;
302 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
303 GTK_WIDGET(child
->m_widget
),
310 /* we connect to these events for recalculating the client area
311 space when the toolbar is floating */
312 if (wxIS_KIND_OF(child
,wxToolBar
))
314 wxToolBar
*toolBar
= (wxToolBar
*) child
;
315 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
317 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
318 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
320 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
321 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
324 #endif // wxUSE_TOOLBAR
328 /* these are inside the client area */
329 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
330 GTK_WIDGET(child
->m_widget
),
337 /* resize on OnInternalIdle */
338 parent
->UpdateSize();
341 //-----------------------------------------------------------------------------
343 //-----------------------------------------------------------------------------
345 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
346 EVT_SIZE(wxFrame::OnSize
)
347 EVT_IDLE(wxFrame::OnIdle
)
348 EVT_CLOSE(wxFrame::OnCloseWindow
)
349 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
352 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
356 m_frameMenuBar
= (wxMenuBar
*) NULL
;
358 m_frameStatusBar
= (wxStatusBar
*) NULL
;
359 #endif // wxUSE_STATUSBAR
361 m_frameToolBar
= (wxToolBar
*) NULL
;
362 #endif // wxUSE_TOOLBAR
366 m_mainWidget
= (GtkWidget
*) NULL
;
367 m_menuBarDetached
= FALSE
;
368 m_toolBarDetached
= FALSE
;
369 m_insertInClientArea
= TRUE
;
373 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
374 const wxPoint
&pos
, const wxSize
&size
,
375 long style
, const wxString
&name
)
379 Create( parent
, id
, title
, pos
, size
, style
, name
);
382 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
383 const wxPoint
&pos
, const wxSize
&size
,
384 long style
, const wxString
&name
)
386 wxTopLevelWindows
.Append( this );
388 m_needParent
= FALSE
;
390 if (!PreCreation( parent
, pos
, size
) ||
391 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
393 wxFAIL_MSG( wxT("wxFrame creation failed") );
399 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
401 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
402 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
404 m_widget
= gtk_window_new( win_type
);
407 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
410 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
413 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
414 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
416 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
417 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
419 /* m_mainWidget holds the toolbar, the menubar and the client area */
420 m_mainWidget
= gtk_myfixed_new();
421 gtk_widget_show( m_mainWidget
);
422 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
423 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
426 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
429 /* m_wxwindow only represents the client area without toolbar and menubar */
430 m_wxwindow
= gtk_myfixed_new();
431 gtk_widget_show( m_wxwindow
);
432 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
435 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
438 /* we donm't allow the frame to get the focus as otherwise
439 the frame will grabit at arbitrary fcous changes. */
440 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
442 if (m_parent
) m_parent
->AddChild( this );
444 /* the user resized the frame by dragging etc. */
445 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
446 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
450 /* we cannot set MWM hints and icons before the widget has
451 been realized, so we do this directly after realization */
452 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
453 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
455 /* the only way to get the window size is to connect to this event */
456 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
457 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
464 m_isBeingDeleted
= TRUE
;
466 if (m_frameMenuBar
) delete m_frameMenuBar
;
467 m_frameMenuBar
= (wxMenuBar
*) NULL
;
470 if (m_frameStatusBar
) delete m_frameStatusBar
;
471 m_frameStatusBar
= (wxStatusBar
*) NULL
;
472 #endif // wxUSE_STATUSBAR
475 if (m_frameToolBar
) delete m_frameToolBar
;
476 m_frameToolBar
= (wxToolBar
*) NULL
;
477 #endif // wxUSE_TOOLBAR
479 wxTopLevelWindows
.DeleteObject( this );
481 if (wxTheApp
->GetTopWindow() == this)
482 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
484 if (wxTopLevelWindows
.Number() == 0)
485 wxTheApp
->ExitMainLoop();
488 bool wxFrame::Show( bool show
)
490 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
492 if (show
&& !m_sizeSet
)
494 /* by calling GtkOnSize here, we don't have to call
495 either after showing the frame, which would entail
496 much ugly flicker or from within the size_allocate
497 handler, because GTK 1.1.X forbids that. */
499 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
502 return wxWindow::Show( show
);
505 bool wxFrame::Destroy()
507 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
509 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
514 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
516 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
518 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
519 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
521 /* avoid recursions */
522 if (m_resizing
) return;
527 int old_width
= m_width
;
528 int old_height
= m_height
;
530 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
532 if (x
!= -1) m_x
= x
;
533 if (y
!= -1) m_y
= y
;
534 if (width
!= -1) m_width
= width
;
535 if (height
!= -1) m_height
= height
;
545 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
547 if (width
== -1) m_width
= 80;
550 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
552 if (height
== -1) m_height
= 26;
555 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
556 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
557 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
558 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
560 if ((m_x
!= -1) || (m_y
!= -1))
562 if ((m_x
!= old_x
) || (m_y
!= old_y
))
564 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
568 if ((m_width
!= old_width
) || (m_height
!= old_height
))
570 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
571 done either directly before the frame is shown or in idle time
572 so that different calls to SetSize() don't lead to flicker. */
579 void wxFrame::Centre( int direction
)
581 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
586 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
587 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
592 void wxFrame::DoGetClientSize( int *width
, int *height
) const
594 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
596 wxWindow::DoGetClientSize( width
, height
);
602 if (!m_menuBarDetached
)
603 (*height
) -= wxMENU_HEIGHT
;
605 (*height
) -= wxPLACE_HOLDER
;
610 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
617 if (!m_toolBarDetached
)
620 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
624 (*height
) -= wxPLACE_HOLDER
;
629 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
633 (*width
) -= m_miniEdge
*2;
637 void wxFrame::DoSetClientSize( int width
, int height
)
639 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
644 if (!m_menuBarDetached
)
645 height
+= wxMENU_HEIGHT
;
647 height
+= wxPLACE_HOLDER
;
652 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
659 if (!m_toolBarDetached
)
662 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
666 height
+= wxPLACE_HOLDER
;
670 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
673 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
675 // due to a bug in gtk, x,y are always 0
679 /* avoid recursions */
680 if (m_resizing
) return;
683 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
684 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
689 /* space occupied by m_frameToolBar and m_frameMenuBar */
690 int client_area_y_offset
= 0;
692 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
693 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
694 set in wxFrame::Create so it is used to check what kind of frame we
695 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
696 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
697 importantly) m_mainWidget */
701 /* check if size is in legal range */
702 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
703 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
704 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
705 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
707 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
708 * menubar, the toolbar and the client area, which is represented by
710 * this hurts in the eye, but I don't want to call SetSize()
711 * because I don't want to call any non-native functions here. */
716 int yy
= m_miniEdge
+ m_miniTitle
;
717 int ww
= m_width
- 2*m_miniEdge
;
718 int hh
= wxMENU_HEIGHT
;
719 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
720 m_frameMenuBar
->m_x
= xx
;
721 m_frameMenuBar
->m_y
= yy
;
722 m_frameMenuBar
->m_width
= ww
;
723 m_frameMenuBar
->m_height
= hh
;
724 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
725 m_frameMenuBar
->m_widget
,
727 client_area_y_offset
+= hh
;
734 int yy
= m_miniEdge
+ m_miniTitle
;
737 if (!m_menuBarDetached
)
740 yy
+= wxPLACE_HOLDER
;
742 int ww
= m_width
- 2*m_miniEdge
;
743 int hh
= m_frameToolBar
->m_height
;
744 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
745 m_frameToolBar
->m_x
= xx
;
746 m_frameToolBar
->m_y
= yy
;
747 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
748 m_frameToolBar
->m_width
= ww
;
749 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
750 m_frameToolBar
->m_widget
,
752 client_area_y_offset
+= hh
;
756 int client_x
= m_miniEdge
;
757 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
758 int client_w
= m_width
- 2*m_miniEdge
;
759 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
760 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
762 client_x
, client_y
, client_w
, client_h
);
766 /* if there is no m_mainWidget between m_widget and m_wxwindow there
767 is no need to set the size or position of m_wxwindow. */
771 if (m_frameStatusBar
)
773 int xx
= 0 + m_miniEdge
;
774 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
775 int ww
= m_width
- 2*m_miniEdge
;
776 int hh
= wxSTATUS_HEIGHT
;
777 m_frameStatusBar
->m_x
= xx
;
778 m_frameStatusBar
->m_y
= yy
;
779 m_frameStatusBar
->m_width
= ww
;
780 m_frameStatusBar
->m_height
= hh
;
781 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
782 m_frameStatusBar
->m_widget
,
787 /* we actually set the size of a frame here and no-where else */
788 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
793 // send size event to frame
794 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
795 event
.SetEventObject( this );
796 GetEventHandler()->ProcessEvent( event
);
798 // send size event to status bar
799 if (m_frameStatusBar
)
801 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
802 event2
.SetEventObject( m_frameStatusBar
);
803 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
809 void wxFrame::MakeModal( bool modal
)
812 gtk_grab_add( m_widget
);
814 gtk_grab_remove( m_widget
);
817 void wxFrame::OnInternalIdle()
819 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
821 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
823 // we'll come back later
825 wxapp_install_idle_handler();
829 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
831 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
834 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
837 wxWindow::OnInternalIdle();
840 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
845 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
847 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
849 #if wxUSE_CONSTRAINTS
855 #endif // wxUSE_CONSTRAINTS
857 /* do we have exactly one child? */
858 wxWindow
*child
= (wxWindow
*)NULL
;
859 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
861 wxWindow
*win
= (wxWindow
*)node
->Data();
862 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
866 /* it's the second one: do nothing */
874 /* no children at all? */
877 /* yes: set it's size to fill all the frame */
878 int client_x
, client_y
;
879 DoGetClientSize( &client_x
, &client_y
);
880 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
885 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
887 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
888 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
890 m_frameMenuBar
= menuBar
;
894 m_frameMenuBar
->SetInvokingWindow( this );
896 if (m_frameMenuBar
->GetParent() != this)
898 m_frameMenuBar
->SetParent(this);
899 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
900 m_frameMenuBar
->m_widget
,
903 m_frameMenuBar
->m_width
,
904 m_frameMenuBar
->m_height
);
906 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
908 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
909 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
911 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
912 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
915 m_frameMenuBar
->Show( TRUE
);
919 /* resize window in OnInternalIdle */
923 wxMenuBar
*wxFrame::GetMenuBar() const
925 return m_frameMenuBar
;
928 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
933 // if no help string found, we will clear the status bar text
936 int menuId
= event
.GetMenuId();
939 wxMenuBar
*menuBar
= GetMenuBar();
942 helpString
= menuBar
->GetHelpString(menuId
);
946 SetStatusText(helpString
);
948 #endif // wxUSE_STATUSBAR
952 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
954 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
956 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
958 m_insertInClientArea
= FALSE
;
960 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
962 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
964 m_insertInClientArea
= TRUE
;
968 return m_frameToolBar
;
971 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
973 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
976 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
978 m_frameToolBar
= toolbar
;
981 /* insert into toolbar area if not already there */
982 if (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
)
984 gtk_widget_ref( m_frameToolBar
->m_widget
);
985 gtk_widget_unparent( m_frameToolBar
->m_widget
);
987 m_insertInClientArea
= TRUE
;
988 wxInsertChildInFrame( this, m_frameToolBar
);
989 m_insertInClientArea
= FALSE
;
991 gtk_widget_unref( m_frameToolBar
->m_widget
);
996 wxToolBar
*wxFrame::GetToolBar() const
998 return m_frameToolBar
;
1000 #endif // wxUSE_TOOLBAR
1003 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1005 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1007 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1009 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1013 return m_frameStatusBar
;
1016 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1018 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1020 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1022 // Set the height according to the font and the border size
1023 wxClientDC
dc(statusBar
);
1024 dc
.SetFont( statusBar
->GetFont() );
1027 dc
.GetTextExtent( "X", &x
, &y
);
1029 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1031 statusBar
->SetSize( -1, -1, 100, height
);
1033 statusBar
->SetFieldsCount( number
);
1037 wxStatusBar
*wxFrame::GetStatusBar() const
1039 return m_frameStatusBar
;
1042 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1044 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1046 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1048 m_frameStatusBar
->SetStatusText(text
, number
);
1051 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1053 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1055 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1057 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1059 #endif // wxUSE_STATUSBAR
1061 void wxFrame::Command( int id
)
1063 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1064 commandEvent
.SetInt( id
);
1065 commandEvent
.SetEventObject( this );
1067 wxMenuBar
*bar
= GetMenuBar();
1070 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1071 if (item
&& item
->IsCheckable())
1073 bar
->Check(id
,!bar
->Checked(id
)) ;
1076 wxEvtHandler
* evtHandler
= GetEventHandler();
1078 evtHandler
->ProcessEvent(commandEvent
);
1081 void wxFrame::SetTitle( const wxString
&title
)
1083 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1086 if (m_title
.IsNull()) m_title
= wxT("");
1087 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1090 void wxFrame::SetIcon( const wxIcon
&icon
)
1092 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1095 if (!icon
.Ok()) return;
1097 if (!m_widget
->window
) return;
1099 wxMask
*mask
= icon
.GetMask();
1100 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1101 if (mask
) bm
= mask
->GetBitmap();
1103 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1106 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1110 void wxFrame::Restore()
1114 void wxFrame::Iconize( bool iconize
)
1118 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1119 GDK_WINDOW_XWINDOW( m_widget
->window
),
1120 DefaultScreen( GDK_DISPLAY() ) );
1124 bool wxFrame::IsIconized() const