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();
74 if (!win
->m_hasVMT
) return;
76 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
78 win
->m_width
= alloc
->width
;
79 win
->m_height
= alloc
->height
;
84 //-----------------------------------------------------------------------------
86 //-----------------------------------------------------------------------------
88 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxFrame
*win
)
91 wxapp_install_idle_handler();
98 //-----------------------------------------------------------------------------
99 // "child_attached" of menu bar
100 //-----------------------------------------------------------------------------
102 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
104 if (!win
->m_hasVMT
) return;
106 win
->m_menuBarDetached
= FALSE
;
110 //-----------------------------------------------------------------------------
111 // "child_detached" of menu bar
112 //-----------------------------------------------------------------------------
114 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
116 if (!win
->m_hasVMT
) return;
118 win
->m_menuBarDetached
= TRUE
;
123 //-----------------------------------------------------------------------------
124 // "child_attached" of tool bar
125 //-----------------------------------------------------------------------------
127 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
129 if (!win
->m_hasVMT
) return;
131 win
->m_toolBarDetached
= FALSE
;
136 //-----------------------------------------------------------------------------
137 // "child_detached" of tool bar
138 //-----------------------------------------------------------------------------
140 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
143 wxapp_install_idle_handler();
145 if (!win
->m_hasVMT
) return;
147 win
->m_toolBarDetached
= TRUE
;
150 #endif // wxUSE_TOOLBAR
152 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
157 #if (GTK_MINOR_VERSON > 0)
158 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxFrame
*win
)
160 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*event
, wxFrame
*win
)
164 wxapp_install_idle_handler();
166 if (!win
->m_hasVMT
) return FALSE
;
168 #if (GTK_MINOR_VERSON > 0)
171 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
179 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
180 mevent
.SetEventObject( win
);
181 win
->GetEventHandler()->ProcessEvent( mevent
);
186 //-----------------------------------------------------------------------------
187 // "realize" from m_widget
188 //-----------------------------------------------------------------------------
190 /* we cannot MWM hints and icons before the widget has been realized,
191 so we do this directly after realization */
194 gtk_frame_realized_callback( GtkWidget
*WXUNUSED(widget
), wxFrame
*win
)
197 wxapp_install_idle_handler();
199 /* all this is for Motif Window Manager "hints" and is supposed to be
200 recognized by other WM as well. not tested. */
201 long decor
= (long) GDK_DECOR_BORDER
;
202 long func
= (long) GDK_FUNC_MOVE
;
204 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
205 decor
|= GDK_DECOR_TITLE
;
206 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
208 decor
|= GDK_DECOR_MENU
;
209 func
|= GDK_FUNC_CLOSE
;
211 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
213 func
|= GDK_FUNC_MINIMIZE
;
214 decor
|= GDK_DECOR_MINIMIZE
;
216 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
218 func
|= GDK_FUNC_MAXIMIZE
;
219 decor
|= GDK_DECOR_MAXIMIZE
;
221 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
223 func
|= GDK_FUNC_RESIZE
;
224 decor
|= GDK_DECOR_RESIZEH
;
227 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
228 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
230 /* GTK's shrinking/growing policy */
231 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
232 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
234 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
237 gint flag
= GDK_HINT_POS
;
238 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
239 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
242 gdk_window_set_hints( win
->m_widget
->window
,
244 win
->GetMinWidth(), win
->GetMinHeight(),
245 win
->GetMaxWidth(), win
->GetMaxHeight(),
250 if (win
->m_icon
!= wxNullIcon
)
252 wxIcon
icon( win
->m_icon
);
253 win
->m_icon
= wxNullIcon
;
254 win
->SetIcon( icon
);
257 /* we set the focus to the child that accepts the focus. this
258 doesn't really have to be done in "realize" but why not? */
259 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
262 wxWindow
*child
= node
->GetData();
263 if (child
->AcceptsFocus())
269 node
= node
->GetNext();
275 //-----------------------------------------------------------------------------
276 // InsertChild for wxFrame
277 //-----------------------------------------------------------------------------
279 /* Callback for wxFrame. This very strange beast has to be used because
280 * C++ has no virtual methods in a constructor. We have to emulate a
281 * virtual function here as wxWindows requires different ways to insert
282 * a child in container classes. */
284 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
286 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
288 if (!parent
->m_insertInClientArea
)
290 /* these are outside the client area */
291 wxFrame
* frame
= (wxFrame
*) parent
;
292 gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
),
293 GTK_WIDGET(child
->m_widget
),
300 /* we connect to these events for recalculating the client area
301 space when the toolbar is floating */
302 if (wxIS_KIND_OF(child
,wxToolBar
))
304 wxToolBar
*toolBar
= (wxToolBar
*) child
;
305 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
307 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
308 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
310 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
311 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
314 #endif // wxUSE_TOOLBAR
318 /* these are inside the client area */
319 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
320 GTK_WIDGET(child
->m_widget
),
327 /* resize on OnInternalIdle */
328 parent
->UpdateSize();
331 //-----------------------------------------------------------------------------
333 //-----------------------------------------------------------------------------
335 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
336 EVT_SIZE(wxFrame::OnSize
)
337 EVT_CLOSE(wxFrame::OnCloseWindow
)
338 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
341 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
345 m_frameMenuBar
= (wxMenuBar
*) NULL
;
347 m_frameStatusBar
= (wxStatusBar
*) NULL
;
348 #endif // wxUSE_STATUSBAR
350 m_frameToolBar
= (wxToolBar
*) NULL
;
351 #endif // wxUSE_TOOLBAR
355 m_mainWidget
= (GtkWidget
*) NULL
;
356 m_menuBarDetached
= FALSE
;
357 m_toolBarDetached
= FALSE
;
358 m_insertInClientArea
= TRUE
;
361 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
362 const wxPoint
&pos
, const wxSize
&size
,
363 long style
, const wxString
&name
)
367 Create( parent
, id
, title
, pos
, size
, style
, name
);
370 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
371 const wxPoint
&pos
, const wxSize
&size
,
372 long style
, const wxString
&name
)
374 wxTopLevelWindows
.Append( this );
376 m_needParent
= FALSE
;
378 if (!PreCreation( parent
, pos
, size
) ||
379 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
381 wxFAIL_MSG( wxT("wxFrame creation failed") );
387 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
389 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
390 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
392 m_widget
= gtk_window_new( win_type
);
395 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
398 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
401 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
402 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
404 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
405 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
407 /* m_mainWidget holds the toolbar, the menubar and the client area */
408 m_mainWidget
= gtk_myfixed_new();
409 gtk_widget_show( m_mainWidget
);
410 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
411 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
414 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
417 /* m_wxwindow only represents the client area without toolbar and menubar */
418 m_wxwindow
= gtk_myfixed_new();
419 gtk_widget_show( m_wxwindow
);
420 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
423 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
426 /* we donm't allow the frame to get the focus as otherwise
427 the frame will grabit at arbitrary fcous changes. */
428 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
430 if (m_parent
) m_parent
->AddChild( this );
434 /* we cannot set MWM hints and icons before the widget has
435 been realized, so we do this directly after realization */
436 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
437 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
439 /* the user resized the frame by dragging etc. */
440 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
441 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
443 /* the only way to get the window size is to connect to this event */
444 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
445 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
452 m_isBeingDeleted
= TRUE
;
454 if (m_frameMenuBar
) delete m_frameMenuBar
;
455 m_frameMenuBar
= (wxMenuBar
*) NULL
;
458 if (m_frameStatusBar
) delete m_frameStatusBar
;
459 m_frameStatusBar
= (wxStatusBar
*) NULL
;
460 #endif // wxUSE_STATUSBAR
463 if (m_frameToolBar
) delete m_frameToolBar
;
464 m_frameToolBar
= (wxToolBar
*) NULL
;
465 #endif // wxUSE_TOOLBAR
467 wxTopLevelWindows
.DeleteObject( this );
469 if (wxTheApp
->GetTopWindow() == this)
470 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
472 if (wxTopLevelWindows
.Number() == 0)
473 wxTheApp
->ExitMainLoop();
476 bool wxFrame::Show( bool show
)
478 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
480 if (show
&& !m_sizeSet
)
482 /* by calling GtkOnSize here, we don't have to call
483 either after showing the frame, which would entail
484 much ugly flicker or from within the size_allocate
485 handler, because GTK 1.1.X forbids that. */
487 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
490 return wxWindow::Show( show
);
493 bool wxFrame::Destroy()
495 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
497 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
502 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
504 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
506 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
507 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
509 /* avoid recursions */
510 if (m_resizing
) return;
515 int old_width
= m_width
;
516 int old_height
= m_height
;
518 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
520 if (x
!= -1) m_x
= x
;
521 if (y
!= -1) m_y
= y
;
522 if (width
!= -1) m_width
= width
;
523 if (height
!= -1) m_height
= height
;
533 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
535 if (width
== -1) m_width
= 80;
538 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
540 if (height
== -1) m_height
= 26;
543 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
544 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
545 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
546 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
548 if ((m_x
!= -1) || (m_y
!= -1))
550 if ((m_x
!= old_x
) || (m_y
!= old_y
))
552 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
556 if ((m_width
!= old_width
) || (m_height
!= old_height
))
558 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
559 done either directly before the frame is shown or in idle time
560 so that different calls to SetSize() don't lead to flicker. */
567 void wxFrame::Centre( int direction
)
569 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
574 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
575 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
580 void wxFrame::DoGetClientSize( int *width
, int *height
) const
582 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
584 wxWindow::DoGetClientSize( width
, height
);
590 if (!m_menuBarDetached
)
591 (*height
) -= wxMENU_HEIGHT
;
593 (*height
) -= wxPLACE_HOLDER
;
598 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
605 if (!m_toolBarDetached
)
608 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
612 (*height
) -= wxPLACE_HOLDER
;
617 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
621 (*width
) -= m_miniEdge
*2;
625 void wxFrame::DoSetClientSize( int width
, int height
)
627 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
632 if (!m_menuBarDetached
)
633 height
+= wxMENU_HEIGHT
;
635 height
+= wxPLACE_HOLDER
;
640 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
647 if (!m_toolBarDetached
)
650 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
654 height
+= wxPLACE_HOLDER
;
658 wxWindow::DoSetClientSize( width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
);
661 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
663 // due to a bug in gtk, x,y are always 0
667 /* avoid recursions */
668 if (m_resizing
) return;
671 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
672 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
677 /* space occupied by m_frameToolBar and m_frameMenuBar */
678 int client_area_y_offset
= 0;
680 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
681 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
682 set in wxFrame::Create so it is used to check what kind of frame we
683 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
684 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
685 importantly) m_mainWidget */
689 /* check if size is in legal range */
690 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
691 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
692 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
693 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
695 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
696 * menubar, the toolbar and the client area, which is represented by
698 * this hurts in the eye, but I don't want to call SetSize()
699 * because I don't want to call any non-native functions here. */
704 int yy
= m_miniEdge
+ m_miniTitle
;
705 int ww
= m_width
- 2*m_miniEdge
;
706 int hh
= wxMENU_HEIGHT
;
707 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
708 m_frameMenuBar
->m_x
= xx
;
709 m_frameMenuBar
->m_y
= yy
;
710 m_frameMenuBar
->m_width
= ww
;
711 m_frameMenuBar
->m_height
= hh
;
712 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
713 m_frameMenuBar
->m_widget
,
715 client_area_y_offset
+= hh
;
722 int yy
= m_miniEdge
+ m_miniTitle
;
725 if (!m_menuBarDetached
)
728 yy
+= wxPLACE_HOLDER
;
730 int ww
= m_width
- 2*m_miniEdge
;
731 int hh
= m_frameToolBar
->m_height
;
732 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
733 m_frameToolBar
->m_x
= xx
;
734 m_frameToolBar
->m_y
= yy
;
735 /* m_frameToolBar->m_height = hh; don't change the toolbar's height */
736 m_frameToolBar
->m_width
= ww
;
737 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
738 m_frameToolBar
->m_widget
,
740 client_area_y_offset
+= hh
;
744 int client_x
= m_miniEdge
;
745 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
746 int client_w
= m_width
- 2*m_miniEdge
;
747 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
748 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
750 client_x
, client_y
, client_w
, client_h
);
754 /* if there is no m_mainWidget between m_widget and m_wxwindow there
755 is no need to set the size or position of m_wxwindow. */
759 if (m_frameStatusBar
)
761 int xx
= 0 + m_miniEdge
;
762 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
763 int ww
= m_width
- 2*m_miniEdge
;
764 int hh
= wxSTATUS_HEIGHT
;
765 m_frameStatusBar
->m_x
= xx
;
766 m_frameStatusBar
->m_y
= yy
;
767 m_frameStatusBar
->m_width
= ww
;
768 m_frameStatusBar
->m_height
= hh
;
769 gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),
770 m_frameStatusBar
->m_widget
,
775 /* we actually set the size of a frame here and no-where else */
776 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
780 /* send size event to frame */
781 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
782 event
.SetEventObject( this );
783 GetEventHandler()->ProcessEvent( event
);
785 /* send size event to status bar */
786 if (m_frameStatusBar
)
788 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
789 event2
.SetEventObject( m_frameStatusBar
);
790 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
796 void wxFrame::MakeModal( bool modal
)
799 gtk_grab_add( m_widget
);
801 gtk_grab_remove( m_widget
);
804 void wxFrame::OnInternalIdle()
806 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
807 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
811 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
813 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
816 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
819 wxWindow::OnInternalIdle();
822 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
827 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
829 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
831 #if wxUSE_CONSTRAINTS
837 #endif // wxUSE_CONSTRAINTS
839 /* do we have exactly one child? */
840 wxWindow
*child
= (wxWindow
*)NULL
;
841 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
843 wxWindow
*win
= (wxWindow
*)node
->Data();
844 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
848 /* it's the second one: do nothing */
856 /* no children at all? */
859 /* yes: set it's size to fill all the frame */
860 int client_x
, client_y
;
861 DoGetClientSize( &client_x
, &client_y
);
862 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
867 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
869 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
870 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
872 m_frameMenuBar
= menuBar
;
876 m_frameMenuBar
->SetInvokingWindow( this );
878 if (m_frameMenuBar
->GetParent() != this)
880 m_frameMenuBar
->SetParent(this);
881 gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
),
882 m_frameMenuBar
->m_widget
,
885 m_frameMenuBar
->m_width
,
886 m_frameMenuBar
->m_height
);
888 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
890 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
891 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
893 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
894 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
897 m_frameMenuBar
->Show( TRUE
);
901 /* resize window in OnInternalIdle */
905 wxMenuBar
*wxFrame::GetMenuBar() const
907 return m_frameMenuBar
;
910 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
915 // if no help string found, we will clear the status bar text
918 int menuId
= event
.GetMenuId();
921 wxMenuBar
*menuBar
= GetMenuBar();
924 helpString
= menuBar
->GetHelpString(menuId
);
928 SetStatusText(helpString
);
930 #endif // wxUSE_STATUSBAR
934 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
936 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
938 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
940 m_insertInClientArea
= FALSE
;
942 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
944 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
946 m_insertInClientArea
= TRUE
;
950 return m_frameToolBar
;
953 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
955 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
958 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
960 m_frameToolBar
= toolbar
;
963 /* insert into toolbar area if not already there */
964 if (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
)
966 gtk_widget_ref( m_frameToolBar
->m_widget
);
967 gtk_widget_unparent( m_frameToolBar
->m_widget
);
969 m_insertInClientArea
= TRUE
;
970 wxInsertChildInFrame( this, m_frameToolBar
);
971 m_insertInClientArea
= FALSE
;
973 gtk_widget_unref( m_frameToolBar
->m_widget
);
978 wxToolBar
*wxFrame::GetToolBar() const
980 return m_frameToolBar
;
982 #endif // wxUSE_TOOLBAR
985 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
987 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
989 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
991 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
995 return m_frameStatusBar
;
998 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1000 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1002 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1004 // Set the height according to the font and the border size
1005 wxClientDC
dc(statusBar
);
1006 dc
.SetFont( statusBar
->GetFont() );
1009 dc
.GetTextExtent( "X", &x
, &y
);
1011 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1013 statusBar
->SetSize( -1, -1, 100, height
);
1015 statusBar
->SetFieldsCount( number
);
1019 wxStatusBar
*wxFrame::GetStatusBar() const
1021 return m_frameStatusBar
;
1024 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1026 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1028 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1030 m_frameStatusBar
->SetStatusText(text
, number
);
1033 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1035 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1037 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1039 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1041 #endif // wxUSE_STATUSBAR
1043 void wxFrame::Command( int id
)
1045 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1046 commandEvent
.SetInt( id
);
1047 commandEvent
.SetEventObject( this );
1049 wxMenuBar
*bar
= GetMenuBar();
1052 wxMenuItem
*item
= bar
->FindItemForId(id
) ;
1053 if (item
&& item
->IsCheckable())
1055 bar
->Check(id
,!bar
->Checked(id
)) ;
1058 wxEvtHandler
* evtHandler
= GetEventHandler();
1060 evtHandler
->ProcessEvent(commandEvent
);
1063 void wxFrame::SetTitle( const wxString
&title
)
1065 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1068 if (m_title
.IsNull()) m_title
= wxT("");
1069 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1072 void wxFrame::SetIcon( const wxIcon
&icon
)
1074 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1077 if (!icon
.Ok()) return;
1079 if (!m_widget
->window
) return;
1081 wxMask
*mask
= icon
.GetMask();
1082 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1083 if (mask
) bm
= mask
->GetBitmap();
1085 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1088 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1092 void wxFrame::Restore()
1096 void wxFrame::Iconize( bool iconize
)
1100 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1101 GDK_WINDOW_XWINDOW( m_widget
->window
),
1102 DefaultScreen( GDK_DISPLAY() ) );
1106 bool wxFrame::IsIconized() const