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 // FIXME I don't know when does it appear, but it's not in 1.2.2
211 #if GTK_CHECK_VERSION(1, 2, 3)
212 /* I haven't been able to set the position of
213 the dialog before it is shown, so I set the
214 position in "realize" */
215 wxLogDebug( "%d %d\n", win
->m_x
, win
->m_y
);
216 gtk_window_reposition( GTK_WINDOW(widget
), win
->m_x
, win
->m_y
);
217 #endif // GTK > 1.2.2
219 /* all this is for Motif Window Manager "hints" and is supposed to be
220 recognized by other WM as well. not tested. */
221 long decor
= (long) GDK_DECOR_BORDER
;
222 long func
= (long) GDK_FUNC_MOVE
;
224 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
225 decor
|= GDK_DECOR_TITLE
;
226 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
228 decor
|= GDK_DECOR_MENU
;
229 func
|= GDK_FUNC_CLOSE
;
231 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
233 func
|= GDK_FUNC_MINIMIZE
;
234 decor
|= GDK_DECOR_MINIMIZE
;
236 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
238 func
|= GDK_FUNC_MAXIMIZE
;
239 decor
|= GDK_DECOR_MAXIMIZE
;
241 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
243 func
|= GDK_FUNC_RESIZE
;
244 decor
|= GDK_DECOR_RESIZEH
;
247 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
248 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
250 /* GTK's shrinking/growing policy */
251 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
252 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
254 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
257 gint flag
= GDK_HINT_POS
;
258 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
259 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
262 gdk_window_set_hints( win
->m_widget
->window
,
264 win
->GetMinWidth(), win
->GetMinHeight(),
265 win
->GetMaxWidth(), win
->GetMaxHeight(),
270 if (win
->m_icon
!= wxNullIcon
)
272 wxIcon
icon( win
->m_icon
);
273 win
->m_icon
= wxNullIcon
;
274 win
->SetIcon( icon
);
277 /* we set the focus to the child that accepts the focus. this
278 doesn't really have to be done in "realize" but why not? */
279 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
282 wxWindow
*child
= node
->GetData();
283 if (child
->AcceptsFocus())
289 node
= node
->GetNext();
295 //-----------------------------------------------------------------------------
296 // InsertChild for wxFrame
297 //-----------------------------------------------------------------------------
299 /* Callback for wxFrame. This very strange beast has to be used because
300 * C++ has no virtual methods in a constructor. We have to emulate a
301 * virtual function here as wxWindows requires different ways to insert
302 * a child in container classes. */
304 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
306 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
308 if (!parent
->m_insertInClientArea
)
310 /* these are outside the client area */
311 wxFrame
* frame
= (wxFrame
*) parent
;
312 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
313 GTK_WIDGET(child
->m_widget
),
320 /* we connect to these events for recalculating the client area
321 space when the toolbar is floating */
322 if (wxIS_KIND_OF(child
,wxToolBar
))
324 wxToolBar
*toolBar
= (wxToolBar
*) child
;
325 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
327 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
328 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
330 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
331 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
334 #endif // wxUSE_TOOLBAR
338 /* these are inside the client area */
339 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
340 GTK_WIDGET(child
->m_widget
),
347 /* resize on OnInternalIdle */
348 parent
->UpdateSize();
351 //-----------------------------------------------------------------------------
353 //-----------------------------------------------------------------------------
355 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
356 EVT_SIZE(wxFrame::OnSize
)
357 EVT_IDLE(wxFrame::OnIdle
)
358 EVT_CLOSE(wxFrame::OnCloseWindow
)
359 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
362 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
366 m_frameMenuBar
= (wxMenuBar
*) NULL
;
368 m_frameStatusBar
= (wxStatusBar
*) NULL
;
369 #endif // wxUSE_STATUSBAR
371 m_frameToolBar
= (wxToolBar
*) NULL
;
372 #endif // wxUSE_TOOLBAR
376 m_mainWidget
= (GtkWidget
*) NULL
;
377 m_menuBarDetached
= FALSE
;
378 m_toolBarDetached
= FALSE
;
379 m_insertInClientArea
= TRUE
;
383 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
384 const wxPoint
&pos
, const wxSize
&size
,
385 long style
, const wxString
&name
)
389 Create( parent
, id
, title
, pos
, size
, style
, name
);
392 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
393 const wxPoint
&pos
, const wxSize
&size
,
394 long style
, const wxString
&name
)
396 wxTopLevelWindows
.Append( this );
398 m_needParent
= FALSE
;
400 if (!PreCreation( parent
, pos
, size
) ||
401 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
403 wxFAIL_MSG( wxT("wxFrame creation failed") );
409 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
411 GtkWindowType win_type
= GTK_WINDOW_DIALOG
; // this makes window placement work
412 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
414 m_widget
= gtk_window_new( win_type
);
417 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
420 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
423 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
424 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
426 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
427 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
429 /* m_mainWidget holds the toolbar, the menubar and the client area */
430 m_mainWidget
= gtk_pizza_new();
431 gtk_widget_show( m_mainWidget
);
432 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
433 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
436 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
439 /* m_wxwindow only represents the client area without toolbar and menubar */
440 m_wxwindow
= gtk_pizza_new();
441 gtk_widget_show( m_wxwindow
);
442 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
445 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
448 /* we donm't allow the frame to get the focus as otherwise
449 the frame will grabit at arbitrary fcous changes. */
450 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
452 if (m_parent
) m_parent
->AddChild( this );
454 /* the user resized the frame by dragging etc. */
455 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
456 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
460 /* we cannot set MWM hints and icons before the widget has
461 been realized, so we do this directly after realization */
462 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
463 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
465 /* the only way to get the window size is to connect to this event */
466 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
467 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
474 m_isBeingDeleted
= TRUE
;
476 if (m_frameMenuBar
) delete m_frameMenuBar
;
477 m_frameMenuBar
= (wxMenuBar
*) NULL
;
480 if (m_frameStatusBar
) delete m_frameStatusBar
;
481 m_frameStatusBar
= (wxStatusBar
*) NULL
;
482 #endif // wxUSE_STATUSBAR
485 if (m_frameToolBar
) delete m_frameToolBar
;
486 m_frameToolBar
= (wxToolBar
*) NULL
;
487 #endif // wxUSE_TOOLBAR
489 wxTopLevelWindows
.DeleteObject( this );
491 if (wxTheApp
->GetTopWindow() == this)
492 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
494 if (wxTopLevelWindows
.Number() == 0)
495 wxTheApp
->ExitMainLoop();
498 bool wxFrame::Show( bool show
)
500 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
502 if (show
&& !m_sizeSet
)
504 /* by calling GtkOnSize here, we don't have to call
505 either after showing the frame, which would entail
506 much ugly flicker or from within the size_allocate
507 handler, because GTK 1.1.X forbids that. */
509 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
512 return wxWindow::Show( show
);
515 bool wxFrame::Destroy()
517 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
519 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
524 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
526 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
528 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
529 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
531 /* avoid recursions */
532 if (m_resizing
) return;
537 int old_width
= m_width
;
538 int old_height
= m_height
;
540 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
542 if (x
!= -1) m_x
= x
;
543 if (y
!= -1) m_y
= y
;
544 if (width
!= -1) m_width
= width
;
545 if (height
!= -1) m_height
= height
;
556 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
558 if (width == -1) m_width = 80;
561 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
563 if (height == -1) m_height = 26;
567 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
568 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
569 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
570 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
572 // FIXME I don't know when does it appear, but it's not in 1.2.2
573 #if GTK_CHECK_VERSION(1, 2, 3)
574 if ((m_x
!= -1) || (m_y
!= -1))
576 if ((m_x
!= old_x
) || (m_y
!= old_y
))
578 gtk_window_reposition( GTK_WINDOW(m_widget
), m_x
, m_y
);
581 #endif // GTK > 1.2.2
583 if ((m_width
!= old_width
) || (m_height
!= old_height
))
585 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
586 done either directly before the frame is shown or in idle time
587 so that different calls to SetSize() don't lead to flicker. */
594 void wxFrame::Centre( int direction
)
596 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
601 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
602 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
607 void wxFrame::DoGetClientSize( int *width
, int *height
) const
609 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
611 wxWindow::DoGetClientSize( width
, height
);
617 if (!m_menuBarDetached
)
618 (*height
) -= wxMENU_HEIGHT
;
620 (*height
) -= wxPLACE_HOLDER
;
625 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
632 if (!m_toolBarDetached
)
635 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
639 (*height
) -= wxPLACE_HOLDER
;
644 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
648 (*width
) -= m_miniEdge
*2;
652 void wxFrame::DoSetClientSize( int width
, int height
)
654 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
656 printf( "set size %d %d\n", width
, height
);
661 if (!m_menuBarDetached
)
662 height
+= wxMENU_HEIGHT
;
664 height
+= wxPLACE_HOLDER
;
669 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
676 if (!m_toolBarDetached
)
679 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
683 height
+= wxPLACE_HOLDER
;
687 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
690 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
692 // due to a bug in gtk, x,y are always 0
696 /* avoid recursions */
697 if (m_resizing
) return;
700 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
701 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
706 /* space occupied by m_frameToolBar and m_frameMenuBar */
707 int client_area_y_offset
= 0;
709 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
710 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
711 set in wxFrame::Create so it is used to check what kind of frame we
712 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
713 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
714 importantly) m_mainWidget */
718 /* check if size is in legal range */
719 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
720 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
721 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
722 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
724 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
725 * menubar, the toolbar and the client area, which is represented by
727 * this hurts in the eye, but I don't want to call SetSize()
728 * because I don't want to call any non-native functions here. */
733 int yy
= m_miniEdge
+ m_miniTitle
;
734 int ww
= m_width
- 2*m_miniEdge
;
735 int hh
= wxMENU_HEIGHT
;
736 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
737 m_frameMenuBar
->m_x
= xx
;
738 m_frameMenuBar
->m_y
= yy
;
739 m_frameMenuBar
->m_width
= ww
;
740 m_frameMenuBar
->m_height
= hh
;
741 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
742 m_frameMenuBar
->m_widget
,
744 client_area_y_offset
+= hh
;
748 if ((m_frameToolBar
) &&
749 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
752 int yy
= m_miniEdge
+ m_miniTitle
;
755 if (!m_menuBarDetached
)
758 yy
+= wxPLACE_HOLDER
;
760 int ww
= m_width
- 2*m_miniEdge
;
761 int hh
= m_frameToolBar
->m_height
;
762 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
763 m_frameToolBar
->m_x
= xx
;
764 m_frameToolBar
->m_y
= yy
;
765 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
766 m_frameToolBar->m_width = ww; */
767 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
768 m_frameToolBar
->m_widget
,
770 client_area_y_offset
+= hh
;
774 int client_x
= m_miniEdge
;
775 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
776 int client_w
= m_width
- 2*m_miniEdge
;
777 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
778 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
780 client_x
, client_y
, client_w
, client_h
);
784 /* if there is no m_mainWidget between m_widget and m_wxwindow there
785 is no need to set the size or position of m_wxwindow. */
789 if (m_frameStatusBar
)
791 int xx
= 0 + m_miniEdge
;
792 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
793 int ww
= m_width
- 2*m_miniEdge
;
794 int hh
= wxSTATUS_HEIGHT
;
795 m_frameStatusBar
->m_x
= xx
;
796 m_frameStatusBar
->m_y
= yy
;
797 m_frameStatusBar
->m_width
= ww
;
798 m_frameStatusBar
->m_height
= hh
;
799 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
800 m_frameStatusBar
->m_widget
,
805 /* we actually set the size of a frame here and no-where else */
806 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
811 // send size event to frame
812 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
813 event
.SetEventObject( this );
814 GetEventHandler()->ProcessEvent( event
);
816 // send size event to status bar
817 if (m_frameStatusBar
)
819 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
820 event2
.SetEventObject( m_frameStatusBar
);
821 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
827 void wxFrame::MakeModal( bool modal
)
830 gtk_grab_add( m_widget
);
832 gtk_grab_remove( m_widget
);
835 void wxFrame::OnInternalIdle()
837 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
839 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
841 // we'll come back later
843 wxapp_install_idle_handler();
847 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
849 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
852 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
855 wxWindow::OnInternalIdle();
858 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
863 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
865 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
867 #if wxUSE_CONSTRAINTS
873 #endif // wxUSE_CONSTRAINTS
875 /* do we have exactly one child? */
876 wxWindow
*child
= (wxWindow
*)NULL
;
877 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
879 wxWindow
*win
= (wxWindow
*)node
->Data();
880 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
884 /* it's the second one: do nothing */
892 /* no children at all? */
895 /* yes: set it's size to fill all the frame */
896 int client_x
, client_y
;
897 DoGetClientSize( &client_x
, &client_y
);
898 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
903 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
905 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
906 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
908 m_frameMenuBar
= menuBar
;
912 m_frameMenuBar
->SetInvokingWindow( this );
914 if (m_frameMenuBar
->GetParent() != this)
916 m_frameMenuBar
->SetParent(this);
917 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
918 m_frameMenuBar
->m_widget
,
921 m_frameMenuBar
->m_width
,
922 m_frameMenuBar
->m_height
);
924 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
926 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
927 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
929 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
930 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
933 m_frameMenuBar
->Show( TRUE
);
937 /* resize window in OnInternalIdle */
941 wxMenuBar
*wxFrame::GetMenuBar() const
943 return m_frameMenuBar
;
946 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
951 // if no help string found, we will clear the status bar text
954 int menuId
= event
.GetMenuId();
955 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
957 wxMenuBar
*menuBar
= GetMenuBar();
960 // it's ok if we don't find the item because it might belong to
962 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
964 helpString
= item
->GetHelp();
968 SetStatusText(helpString
);
970 #endif // wxUSE_STATUSBAR
974 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
976 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
978 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
980 m_insertInClientArea
= FALSE
;
982 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
984 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
986 m_insertInClientArea
= TRUE
;
990 return m_frameToolBar
;
993 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
995 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
998 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
1000 m_frameToolBar
= toolbar
;
1003 /* insert into toolbar area if not already there */
1004 if ((m_frameToolBar
->m_widget
->parent
) &&
1005 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1007 GetChildren().DeleteObject( m_frameToolBar
);
1009 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1015 wxToolBar
*wxFrame::GetToolBar() const
1017 return m_frameToolBar
;
1019 #endif // wxUSE_TOOLBAR
1022 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1024 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1026 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1028 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1032 return m_frameStatusBar
;
1035 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1037 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1039 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1041 // Set the height according to the font and the border size
1042 wxClientDC
dc(statusBar
);
1043 dc
.SetFont( statusBar
->GetFont() );
1046 dc
.GetTextExtent( "X", &x
, &y
);
1048 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1050 statusBar
->SetSize( -1, -1, 100, height
);
1052 statusBar
->SetFieldsCount( number
);
1056 wxStatusBar
*wxFrame::GetStatusBar() const
1058 return m_frameStatusBar
;
1061 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1063 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1065 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1067 m_frameStatusBar
->SetStatusText(text
, number
);
1070 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1072 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1074 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1076 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1078 #endif // wxUSE_STATUSBAR
1080 void wxFrame::Command( int id
)
1082 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1083 commandEvent
.SetInt( id
);
1084 commandEvent
.SetEventObject( this );
1086 wxMenuBar
*bar
= GetMenuBar();
1089 wxMenuItem
*item
= bar
->FindItem(id
) ;
1090 if (item
&& item
->IsCheckable())
1092 bar
->Check(id
, !bar
->IsChecked(id
)) ;
1095 wxEvtHandler
* evtHandler
= GetEventHandler();
1097 evtHandler
->ProcessEvent(commandEvent
);
1100 void wxFrame::SetTitle( const wxString
&title
)
1102 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1105 if (m_title
.IsNull()) m_title
= wxT("");
1106 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1109 void wxFrame::SetIcon( const wxIcon
&icon
)
1111 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1114 if (!icon
.Ok()) return;
1116 if (!m_widget
->window
) return;
1118 wxMask
*mask
= icon
.GetMask();
1119 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1120 if (mask
) bm
= mask
->GetBitmap();
1122 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1125 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1129 void wxFrame::Restore()
1133 void wxFrame::Iconize( bool iconize
)
1137 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1138 GDK_WINDOW_XWINDOW( m_widget
->window
),
1139 DefaultScreen( GDK_DISPLAY() ) );
1143 bool wxFrame::IsIconized() const