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
);
799 // send size event to status bar
800 if (m_frameStatusBar)
802 wxSizeEvent event2( wxSize(m_frameStatusBar->m_width,m_frameStatusBar->m_height), m_frameStatusBar->GetId() );
803 event2.SetEventObject( m_frameStatusBar );
804 m_frameStatusBar->GetEventHandler()->ProcessEvent( event2 );
811 void wxFrame::MakeModal( bool modal
)
814 gtk_grab_add( m_widget
);
816 gtk_grab_remove( m_widget
);
819 void wxFrame::OnInternalIdle()
821 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
823 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
825 // we'll come back later
827 wxapp_install_idle_handler();
831 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
833 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
836 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
839 wxWindow::OnInternalIdle();
842 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
847 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
849 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
851 #if wxUSE_CONSTRAINTS
857 #endif // wxUSE_CONSTRAINTS
859 /* do we have exactly one child? */
860 wxWindow
*child
= (wxWindow
*)NULL
;
861 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
863 wxWindow
*win
= (wxWindow
*)node
->Data();
864 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
868 /* it's the second one: do nothing */
876 /* no children at all? */
879 /* yes: set it's size to fill all the frame */
880 int client_x
, client_y
;
881 DoGetClientSize( &client_x
, &client_y
);
882 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
887 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
889 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
890 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
892 m_frameMenuBar
= menuBar
;
896 m_frameMenuBar
->SetInvokingWindow( this );
898 if (m_frameMenuBar
->GetParent() != this)
900 m_frameMenuBar
->SetParent(this);
901 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
902 m_frameMenuBar
->m_widget
,
905 m_frameMenuBar
->m_width
,
906 m_frameMenuBar
->m_height
);
908 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
910 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
911 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
913 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
914 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
917 m_frameMenuBar
->Show( TRUE
);
921 /* resize window in OnInternalIdle */
925 wxMenuBar
*wxFrame::GetMenuBar() const
927 return m_frameMenuBar
;
930 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
935 // if no help string found, we will clear the status bar text
938 int menuId
= event
.GetMenuId();
941 wxMenuBar
*menuBar
= GetMenuBar();
944 helpString
= menuBar
->GetHelpString(menuId
);
948 SetStatusText(helpString
);
950 #endif // wxUSE_STATUSBAR
954 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
956 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
958 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
960 m_insertInClientArea
= FALSE
;
962 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
964 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
966 m_insertInClientArea
= TRUE
;
970 return m_frameToolBar
;
973 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
975 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
978 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
980 m_frameToolBar
= toolbar
;
983 /* insert into toolbar area if not already there */
984 if (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
)
986 gtk_widget_ref( m_frameToolBar
->m_widget
);
987 gtk_widget_unparent( m_frameToolBar
->m_widget
);
989 m_insertInClientArea
= TRUE
;
990 wxInsertChildInFrame( this, m_frameToolBar
);
991 m_insertInClientArea
= FALSE
;
993 gtk_widget_unref( m_frameToolBar
->m_widget
);
998 wxToolBar
*wxFrame::GetToolBar() const
1000 return m_frameToolBar
;
1002 #endif // wxUSE_TOOLBAR
1005 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1007 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1009 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1011 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1015 return m_frameStatusBar
;
1018 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1020 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1022 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1024 // Set the height according to the font and the border size
1025 wxClientDC
dc(statusBar
);
1026 dc
.SetFont( statusBar
->GetFont() );
1029 dc
.GetTextExtent( "X", &x
, &y
);
1031 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1033 statusBar
->SetSize( -1, -1, 100, height
);
1035 statusBar
->SetFieldsCount( number
);
1039 wxStatusBar
*wxFrame::GetStatusBar() const
1041 return m_frameStatusBar
;
1044 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1046 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1048 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1050 m_frameStatusBar
->SetStatusText(text
, number
);
1053 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1055 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1057 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1059 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1061 #endif // wxUSE_STATUSBAR
1063 void wxFrame::Command( int id
)
1065 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1066 commandEvent
.SetInt( id
);
1067 commandEvent
.SetEventObject( this );
1069 wxMenuBar
*bar
= GetMenuBar();
1072 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1073 if (item
&& item
->IsCheckable())
1075 bar
->Check(id
,!bar
->Checked(id
)) ;
1078 wxEvtHandler
* evtHandler
= GetEventHandler();
1080 evtHandler
->ProcessEvent(commandEvent
);
1083 void wxFrame::SetTitle( const wxString
&title
)
1085 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1088 if (m_title
.IsNull()) m_title
= wxT("");
1089 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1092 void wxFrame::SetIcon( const wxIcon
&icon
)
1094 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1097 if (!icon
.Ok()) return;
1099 if (!m_widget
->window
) return;
1101 wxMask
*mask
= icon
.GetMask();
1102 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1103 if (mask
) bm
= mask
->GetBitmap();
1105 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1108 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1112 void wxFrame::Restore()
1116 void wxFrame::Iconize( bool iconize
)
1120 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1121 GDK_WINDOW_XWINDOW( m_widget
->window
),
1122 DefaultScreen( GDK_DISPLAY() ) );
1126 bool wxFrame::IsIconized() const