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
*widget
, wxFrame
*win
)
208 wxapp_install_idle_handler();
210 /* I haven't been able to set the position of
211 the dialog before it is shown, so I set the
212 position in "realize" */
213 printf( "%d %d\n", win
->m_x
, win
->m_y
);
214 gtk_window_reposition( GTK_WINDOW(widget
), win
->m_x
, win
->m_y
);
216 /* all this is for Motif Window Manager "hints" and is supposed to be
217 recognized by other WM as well. not tested. */
218 long decor
= (long) GDK_DECOR_BORDER
;
219 long func
= (long) GDK_FUNC_MOVE
;
221 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
222 decor
|= GDK_DECOR_TITLE
;
223 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
225 decor
|= GDK_DECOR_MENU
;
226 func
|= GDK_FUNC_CLOSE
;
228 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
230 func
|= GDK_FUNC_MINIMIZE
;
231 decor
|= GDK_DECOR_MINIMIZE
;
233 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
235 func
|= GDK_FUNC_MAXIMIZE
;
236 decor
|= GDK_DECOR_MAXIMIZE
;
238 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
240 func
|= GDK_FUNC_RESIZE
;
241 decor
|= GDK_DECOR_RESIZEH
;
244 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
245 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
247 /* GTK's shrinking/growing policy */
248 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
249 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
251 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
254 gint flag
= GDK_HINT_POS
;
255 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
256 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
259 gdk_window_set_hints( win
->m_widget
->window
,
261 win
->GetMinWidth(), win
->GetMinHeight(),
262 win
->GetMaxWidth(), win
->GetMaxHeight(),
267 if (win
->m_icon
!= wxNullIcon
)
269 wxIcon
icon( win
->m_icon
);
270 win
->m_icon
= wxNullIcon
;
271 win
->SetIcon( icon
);
274 /* we set the focus to the child that accepts the focus. this
275 doesn't really have to be done in "realize" but why not? */
276 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
279 wxWindow
*child
= node
->GetData();
280 if (child
->AcceptsFocus())
286 node
= node
->GetNext();
292 //-----------------------------------------------------------------------------
293 // InsertChild for wxFrame
294 //-----------------------------------------------------------------------------
296 /* Callback for wxFrame. This very strange beast has to be used because
297 * C++ has no virtual methods in a constructor. We have to emulate a
298 * virtual function here as wxWindows requires different ways to insert
299 * a child in container classes. */
301 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
303 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
305 if (!parent
->m_insertInClientArea
)
307 /* these are outside the client area */
308 wxFrame
* frame
= (wxFrame
*) parent
;
309 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
310 GTK_WIDGET(child
->m_widget
),
317 /* we connect to these events for recalculating the client area
318 space when the toolbar is floating */
319 if (wxIS_KIND_OF(child
,wxToolBar
))
321 wxToolBar
*toolBar
= (wxToolBar
*) child
;
322 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
324 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
325 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
327 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
328 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
331 #endif // wxUSE_TOOLBAR
335 /* these are inside the client area */
336 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
337 GTK_WIDGET(child
->m_widget
),
344 /* resize on OnInternalIdle */
345 parent
->UpdateSize();
348 //-----------------------------------------------------------------------------
350 //-----------------------------------------------------------------------------
352 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
353 EVT_SIZE(wxFrame::OnSize
)
354 EVT_IDLE(wxFrame::OnIdle
)
355 EVT_CLOSE(wxFrame::OnCloseWindow
)
356 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
359 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
363 m_frameMenuBar
= (wxMenuBar
*) NULL
;
365 m_frameStatusBar
= (wxStatusBar
*) NULL
;
366 #endif // wxUSE_STATUSBAR
368 m_frameToolBar
= (wxToolBar
*) NULL
;
369 #endif // wxUSE_TOOLBAR
373 m_mainWidget
= (GtkWidget
*) NULL
;
374 m_menuBarDetached
= FALSE
;
375 m_toolBarDetached
= FALSE
;
376 m_insertInClientArea
= TRUE
;
380 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
381 const wxPoint
&pos
, const wxSize
&size
,
382 long style
, const wxString
&name
)
386 Create( parent
, id
, title
, pos
, size
, style
, name
);
389 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
390 const wxPoint
&pos
, const wxSize
&size
,
391 long style
, const wxString
&name
)
393 wxTopLevelWindows
.Append( this );
395 m_needParent
= FALSE
;
397 if (!PreCreation( parent
, pos
, size
) ||
398 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
400 wxFAIL_MSG( wxT("wxFrame creation failed") );
406 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
408 GtkWindowType win_type
= GTK_WINDOW_DIALOG
; // this makes window placement work
409 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
411 m_widget
= gtk_window_new( win_type
);
414 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
417 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
420 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
421 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
423 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
424 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
426 /* m_mainWidget holds the toolbar, the menubar and the client area */
427 m_mainWidget
= gtk_pizza_new();
428 gtk_widget_show( m_mainWidget
);
429 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
430 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
433 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
436 /* m_wxwindow only represents the client area without toolbar and menubar */
437 m_wxwindow
= gtk_pizza_new();
438 gtk_widget_show( m_wxwindow
);
439 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
442 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
445 /* we donm't allow the frame to get the focus as otherwise
446 the frame will grabit at arbitrary fcous changes. */
447 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
449 if (m_parent
) m_parent
->AddChild( this );
451 /* the user resized the frame by dragging etc. */
452 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
453 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
457 /* we cannot set MWM hints and icons before the widget has
458 been realized, so we do this directly after realization */
459 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
460 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
462 /* the only way to get the window size is to connect to this event */
463 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
464 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
471 m_isBeingDeleted
= TRUE
;
473 if (m_frameMenuBar
) delete m_frameMenuBar
;
474 m_frameMenuBar
= (wxMenuBar
*) NULL
;
477 if (m_frameStatusBar
) delete m_frameStatusBar
;
478 m_frameStatusBar
= (wxStatusBar
*) NULL
;
479 #endif // wxUSE_STATUSBAR
482 if (m_frameToolBar
) delete m_frameToolBar
;
483 m_frameToolBar
= (wxToolBar
*) NULL
;
484 #endif // wxUSE_TOOLBAR
486 wxTopLevelWindows
.DeleteObject( this );
488 if (wxTheApp
->GetTopWindow() == this)
489 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
491 if (wxTopLevelWindows
.Number() == 0)
492 wxTheApp
->ExitMainLoop();
495 bool wxFrame::Show( bool show
)
497 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
499 if (show
&& !m_sizeSet
)
501 /* by calling GtkOnSize here, we don't have to call
502 either after showing the frame, which would entail
503 much ugly flicker or from within the size_allocate
504 handler, because GTK 1.1.X forbids that. */
506 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
509 return wxWindow::Show( show
);
512 bool wxFrame::Destroy()
514 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
516 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
521 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
523 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
525 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
526 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
528 /* avoid recursions */
529 if (m_resizing
) return;
534 int old_width
= m_width
;
535 int old_height
= m_height
;
537 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
539 if (x
!= -1) m_x
= x
;
540 if (y
!= -1) m_y
= y
;
541 if (width
!= -1) m_width
= width
;
542 if (height
!= -1) m_height
= height
;
553 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
555 if (width == -1) m_width = 80;
558 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
560 if (height == -1) m_height = 26;
564 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
565 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
566 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
567 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
569 if ((m_x
!= -1) || (m_y
!= -1))
571 if ((m_x
!= old_x
) || (m_y
!= old_y
))
573 gtk_window_reposition( GTK_WINDOW(m_widget
), m_x
, m_y
);
577 if ((m_width
!= old_width
) || (m_height
!= old_height
))
579 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
580 done either directly before the frame is shown or in idle time
581 so that different calls to SetSize() don't lead to flicker. */
588 void wxFrame::Centre( int direction
)
590 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
595 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
596 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
601 void wxFrame::DoGetClientSize( int *width
, int *height
) const
603 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
605 wxWindow::DoGetClientSize( width
, height
);
611 if (!m_menuBarDetached
)
612 (*height
) -= wxMENU_HEIGHT
;
614 (*height
) -= wxPLACE_HOLDER
;
619 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
626 if (!m_toolBarDetached
)
629 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
633 (*height
) -= wxPLACE_HOLDER
;
638 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
642 (*width
) -= m_miniEdge
*2;
646 void wxFrame::DoSetClientSize( int width
, int height
)
648 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
650 printf( "set size %d %d\n", width
, height
);
655 if (!m_menuBarDetached
)
656 height
+= wxMENU_HEIGHT
;
658 height
+= wxPLACE_HOLDER
;
663 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
670 if (!m_toolBarDetached
)
673 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
677 height
+= wxPLACE_HOLDER
;
681 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
684 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
686 // due to a bug in gtk, x,y are always 0
690 /* avoid recursions */
691 if (m_resizing
) return;
694 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
695 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
700 /* space occupied by m_frameToolBar and m_frameMenuBar */
701 int client_area_y_offset
= 0;
703 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
704 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
705 set in wxFrame::Create so it is used to check what kind of frame we
706 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
707 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
708 importantly) m_mainWidget */
712 /* check if size is in legal range */
713 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
714 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
715 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
716 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
718 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
719 * menubar, the toolbar and the client area, which is represented by
721 * this hurts in the eye, but I don't want to call SetSize()
722 * because I don't want to call any non-native functions here. */
727 int yy
= m_miniEdge
+ m_miniTitle
;
728 int ww
= m_width
- 2*m_miniEdge
;
729 int hh
= wxMENU_HEIGHT
;
730 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
731 m_frameMenuBar
->m_x
= xx
;
732 m_frameMenuBar
->m_y
= yy
;
733 m_frameMenuBar
->m_width
= ww
;
734 m_frameMenuBar
->m_height
= hh
;
735 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
736 m_frameMenuBar
->m_widget
,
738 client_area_y_offset
+= hh
;
742 if ((m_frameToolBar
) &&
743 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
746 int yy
= m_miniEdge
+ m_miniTitle
;
749 if (!m_menuBarDetached
)
752 yy
+= wxPLACE_HOLDER
;
754 int ww
= m_width
- 2*m_miniEdge
;
755 int hh
= m_frameToolBar
->m_height
;
756 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
757 m_frameToolBar
->m_x
= xx
;
758 m_frameToolBar
->m_y
= yy
;
759 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
760 m_frameToolBar->m_width = ww; */
761 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
762 m_frameToolBar
->m_widget
,
764 client_area_y_offset
+= hh
;
768 int client_x
= m_miniEdge
;
769 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
770 int client_w
= m_width
- 2*m_miniEdge
;
771 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
772 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
774 client_x
, client_y
, client_w
, client_h
);
778 /* if there is no m_mainWidget between m_widget and m_wxwindow there
779 is no need to set the size or position of m_wxwindow. */
783 if (m_frameStatusBar
)
785 int xx
= 0 + m_miniEdge
;
786 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
787 int ww
= m_width
- 2*m_miniEdge
;
788 int hh
= wxSTATUS_HEIGHT
;
789 m_frameStatusBar
->m_x
= xx
;
790 m_frameStatusBar
->m_y
= yy
;
791 m_frameStatusBar
->m_width
= ww
;
792 m_frameStatusBar
->m_height
= hh
;
793 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
794 m_frameStatusBar
->m_widget
,
799 /* we actually set the size of a frame here and no-where else */
800 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
805 // send size event to frame
806 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
807 event
.SetEventObject( this );
808 GetEventHandler()->ProcessEvent( event
);
810 // send size event to status bar
811 if (m_frameStatusBar
)
813 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
814 event2
.SetEventObject( m_frameStatusBar
);
815 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
821 void wxFrame::MakeModal( bool modal
)
824 gtk_grab_add( m_widget
);
826 gtk_grab_remove( m_widget
);
829 void wxFrame::OnInternalIdle()
831 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
833 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
835 // we'll come back later
837 wxapp_install_idle_handler();
841 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
843 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
846 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
849 wxWindow::OnInternalIdle();
852 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
857 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
859 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
861 #if wxUSE_CONSTRAINTS
867 #endif // wxUSE_CONSTRAINTS
869 /* do we have exactly one child? */
870 wxWindow
*child
= (wxWindow
*)NULL
;
871 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
873 wxWindow
*win
= (wxWindow
*)node
->Data();
874 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
878 /* it's the second one: do nothing */
886 /* no children at all? */
889 /* yes: set it's size to fill all the frame */
890 int client_x
, client_y
;
891 DoGetClientSize( &client_x
, &client_y
);
892 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
897 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
899 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
900 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
902 m_frameMenuBar
= menuBar
;
906 m_frameMenuBar
->SetInvokingWindow( this );
908 if (m_frameMenuBar
->GetParent() != this)
910 m_frameMenuBar
->SetParent(this);
911 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
912 m_frameMenuBar
->m_widget
,
915 m_frameMenuBar
->m_width
,
916 m_frameMenuBar
->m_height
);
918 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
920 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
921 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
923 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
924 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
927 m_frameMenuBar
->Show( TRUE
);
931 /* resize window in OnInternalIdle */
935 wxMenuBar
*wxFrame::GetMenuBar() const
937 return m_frameMenuBar
;
940 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
945 // if no help string found, we will clear the status bar text
948 int menuId
= event
.GetMenuId();
949 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
951 wxMenuBar
*menuBar
= GetMenuBar();
954 // it's ok if we don't find the item because it might belong to
956 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
958 helpString
= item
->GetHelp();
962 SetStatusText(helpString
);
964 #endif // wxUSE_STATUSBAR
968 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
970 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
972 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
974 m_insertInClientArea
= FALSE
;
976 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
978 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
980 m_insertInClientArea
= TRUE
;
984 return m_frameToolBar
;
987 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
989 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
992 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
994 m_frameToolBar
= toolbar
;
997 /* insert into toolbar area if not already there */
998 if ((m_frameToolBar
->m_widget
->parent
) &&
999 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1001 GetChildren().DeleteObject( m_frameToolBar
);
1003 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1009 wxToolBar
*wxFrame::GetToolBar() const
1011 return m_frameToolBar
;
1013 #endif // wxUSE_TOOLBAR
1016 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1018 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1020 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1022 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1026 return m_frameStatusBar
;
1029 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1031 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1033 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1035 // Set the height according to the font and the border size
1036 wxClientDC
dc(statusBar
);
1037 dc
.SetFont( statusBar
->GetFont() );
1040 dc
.GetTextExtent( "X", &x
, &y
);
1042 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1044 statusBar
->SetSize( -1, -1, 100, height
);
1046 statusBar
->SetFieldsCount( number
);
1050 wxStatusBar
*wxFrame::GetStatusBar() const
1052 return m_frameStatusBar
;
1055 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1057 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1059 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1061 m_frameStatusBar
->SetStatusText(text
, number
);
1064 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1066 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1068 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1070 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1072 #endif // wxUSE_STATUSBAR
1074 void wxFrame::Command( int id
)
1076 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1077 commandEvent
.SetInt( id
);
1078 commandEvent
.SetEventObject( this );
1080 wxMenuBar
*bar
= GetMenuBar();
1083 wxMenuItem
*item
= bar
->FindItem(id
) ;
1084 if (item
&& item
->IsCheckable())
1086 bar
->Check(id
, !bar
->IsChecked(id
)) ;
1089 wxEvtHandler
* evtHandler
= GetEventHandler();
1091 evtHandler
->ProcessEvent(commandEvent
);
1094 void wxFrame::SetTitle( const wxString
&title
)
1096 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1099 if (m_title
.IsNull()) m_title
= wxT("");
1100 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1103 void wxFrame::SetIcon( const wxIcon
&icon
)
1105 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1108 if (!icon
.Ok()) return;
1110 if (!m_widget
->window
) return;
1112 wxMask
*mask
= icon
.GetMask();
1113 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1114 if (mask
) bm
= mask
->GetBitmap();
1116 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1119 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1123 void wxFrame::Restore()
1127 void wxFrame::Iconize( bool iconize
)
1131 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1132 GDK_WINDOW_XWINDOW( m_widget
->window
),
1133 DefaultScreen( GDK_DISPLAY() ) );
1137 bool wxFrame::IsIconized() const