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 gtk_widget_set_uposition( widget
, win
->m_x
, win
->m_y
);
215 /* all this is for Motif Window Manager "hints" and is supposed to be
216 recognized by other WM as well. not tested. */
217 long decor
= (long) GDK_DECOR_BORDER
;
218 long func
= (long) GDK_FUNC_MOVE
;
220 if ((win
->GetWindowStyle() & wxCAPTION
) != 0)
221 decor
|= GDK_DECOR_TITLE
;
222 if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0)
224 decor
|= GDK_DECOR_MENU
;
225 func
|= GDK_FUNC_CLOSE
;
227 if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0)
229 func
|= GDK_FUNC_MINIMIZE
;
230 decor
|= GDK_DECOR_MINIMIZE
;
232 if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0)
234 func
|= GDK_FUNC_MAXIMIZE
;
235 decor
|= GDK_DECOR_MAXIMIZE
;
237 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0)
239 func
|= GDK_FUNC_RESIZE
;
240 decor
|= GDK_DECOR_RESIZEH
;
243 gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
);
244 gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
);
246 /* GTK's shrinking/growing policy */
247 if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0)
248 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
250 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
253 gint flag
= 0; // GDK_HINT_POS;
254 if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag
|= GDK_HINT_MIN_SIZE
;
255 if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag
|= GDK_HINT_MAX_SIZE
;
258 gdk_window_set_hints( win
->m_widget
->window
,
260 win
->GetMinWidth(), win
->GetMinHeight(),
261 win
->GetMaxWidth(), win
->GetMaxHeight(),
266 if (win
->m_icon
!= wxNullIcon
)
268 wxIcon
icon( win
->m_icon
);
269 win
->m_icon
= wxNullIcon
;
270 win
->SetIcon( icon
);
273 /* we set the focus to the child that accepts the focus. this
274 doesn't really have to be done in "realize" but why not? */
275 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
278 wxWindow
*child
= node
->GetData();
279 if (child
->AcceptsFocus())
285 node
= node
->GetNext();
291 //-----------------------------------------------------------------------------
292 // InsertChild for wxFrame
293 //-----------------------------------------------------------------------------
295 /* Callback for wxFrame. This very strange beast has to be used because
296 * C++ has no virtual methods in a constructor. We have to emulate a
297 * virtual function here as wxWindows requires different ways to insert
298 * a child in container classes. */
300 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child
)
302 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
304 if (!parent
->m_insertInClientArea
)
306 /* these are outside the client area */
307 wxFrame
* frame
= (wxFrame
*) parent
;
308 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
309 GTK_WIDGET(child
->m_widget
),
316 /* we connect to these events for recalculating the client area
317 space when the toolbar is floating */
318 if (wxIS_KIND_OF(child
,wxToolBar
))
320 wxToolBar
*toolBar
= (wxToolBar
*) child
;
321 if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
)
323 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached",
324 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent
);
326 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached",
327 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent
);
330 #endif // wxUSE_TOOLBAR
334 /* these are inside the client area */
335 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
336 GTK_WIDGET(child
->m_widget
),
343 /* resize on OnInternalIdle */
344 parent
->UpdateSize();
347 //-----------------------------------------------------------------------------
349 //-----------------------------------------------------------------------------
351 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
)
352 EVT_SIZE(wxFrame::OnSize
)
353 EVT_IDLE(wxFrame::OnIdle
)
354 EVT_CLOSE(wxFrame::OnCloseWindow
)
355 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
)
358 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
)
362 m_frameMenuBar
= (wxMenuBar
*) NULL
;
364 m_frameStatusBar
= (wxStatusBar
*) NULL
;
365 #endif // wxUSE_STATUSBAR
367 m_frameToolBar
= (wxToolBar
*) NULL
;
368 #endif // wxUSE_TOOLBAR
372 m_mainWidget
= (GtkWidget
*) NULL
;
373 m_menuBarDetached
= FALSE
;
374 m_toolBarDetached
= FALSE
;
375 m_insertInClientArea
= TRUE
;
379 wxFrame::wxFrame( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
380 const wxPoint
&pos
, const wxSize
&size
,
381 long style
, const wxString
&name
)
385 Create( parent
, id
, title
, pos
, size
, style
, name
);
388 bool wxFrame::Create( wxWindow
*parent
, wxWindowID id
, const wxString
&title
,
389 const wxPoint
&pos
, const wxSize
&size
,
390 long style
, const wxString
&name
)
392 wxTopLevelWindows
.Append( this );
394 m_needParent
= FALSE
;
396 if (!PreCreation( parent
, pos
, size
) ||
397 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
399 wxFAIL_MSG( wxT("wxFrame creation failed") );
405 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInFrame
;
407 GtkWindowType win_type
= GTK_WINDOW_DIALOG
; // this makes window placement work
408 if (style
& wxSIMPLE_BORDER
) win_type
= GTK_WINDOW_POPUP
;
410 m_widget
= gtk_window_new( win_type
);
413 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
416 debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name
);
419 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
420 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
422 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
423 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
425 /* m_mainWidget holds the toolbar, the menubar and the client area */
426 m_mainWidget
= gtk_pizza_new();
427 gtk_widget_show( m_mainWidget
);
428 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
429 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
432 debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name
);
435 /* m_wxwindow only represents the client area without toolbar and menubar */
436 m_wxwindow
= gtk_pizza_new();
437 gtk_widget_show( m_wxwindow
);
438 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
441 debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name
);
444 /* we donm't allow the frame to get the focus as otherwise
445 the frame will grabit at arbitrary fcous changes. */
446 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
448 if (m_parent
) m_parent
->AddChild( this );
450 /* the user resized the frame by dragging etc. */
451 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
452 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
456 /* we cannot set MWM hints and icons before the widget has
457 been realized, so we do this directly after realization */
458 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
459 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
461 /* the only way to get the window size is to connect to this event */
462 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
463 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
470 m_isBeingDeleted
= TRUE
;
472 if (m_frameMenuBar
) delete m_frameMenuBar
;
473 m_frameMenuBar
= (wxMenuBar
*) NULL
;
476 if (m_frameStatusBar
) delete m_frameStatusBar
;
477 m_frameStatusBar
= (wxStatusBar
*) NULL
;
478 #endif // wxUSE_STATUSBAR
481 if (m_frameToolBar
) delete m_frameToolBar
;
482 m_frameToolBar
= (wxToolBar
*) NULL
;
483 #endif // wxUSE_TOOLBAR
485 wxTopLevelWindows
.DeleteObject( this );
487 if (wxTheApp
->GetTopWindow() == this)
488 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
490 if (wxTopLevelWindows
.Number() == 0)
491 wxTheApp
->ExitMainLoop();
494 bool wxFrame::Show( bool show
)
496 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
498 if (show
&& !m_sizeSet
)
500 /* by calling GtkOnSize here, we don't have to call
501 either after showing the frame, which would entail
502 much ugly flicker or from within the size_allocate
503 handler, because GTK 1.1.X forbids that. */
505 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
508 return wxWindow::Show( show
);
511 bool wxFrame::Destroy()
513 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
515 if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this);
520 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
522 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
524 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
525 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
527 /* avoid recursions */
528 if (m_resizing
) return;
533 int old_width
= m_width
;
534 int old_height
= m_height
;
536 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
538 if (x
!= -1) m_x
= x
;
539 if (y
!= -1) m_y
= y
;
540 if (width
!= -1) m_width
= width
;
541 if (height
!= -1) m_height
= height
;
552 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
554 if (width == -1) m_width = 80;
557 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
559 if (height == -1) m_height = 26;
563 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
564 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
565 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
566 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
568 if ((m_x
!= -1) || (m_y
!= -1))
570 if ((m_x
!= old_x
) || (m_y
!= old_y
))
572 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
576 if ((m_width
!= old_width
) || (m_height
!= old_height
))
578 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
579 done either directly before the frame is shown or in idle time
580 so that different calls to SetSize() don't lead to flicker. */
587 void wxFrame::Centre( int direction
)
589 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
594 if ((direction
& wxHORIZONTAL
) == wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
595 if ((direction
& wxVERTICAL
) == wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
600 void wxFrame::DoGetClientSize( int *width
, int *height
) const
602 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
604 wxWindow::DoGetClientSize( width
, height
);
610 if (!m_menuBarDetached
)
611 (*height
) -= wxMENU_HEIGHT
;
613 (*height
) -= wxPLACE_HOLDER
;
618 if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
;
625 if (!m_toolBarDetached
)
628 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
632 (*height
) -= wxPLACE_HOLDER
;
637 (*height
) -= m_miniEdge
*2 + m_miniTitle
;
641 (*width
) -= m_miniEdge
*2;
645 void wxFrame::DoSetClientSize( int width
, int height
)
647 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
649 printf( "set size %d %d\n", width
, height
);
654 if (!m_menuBarDetached
)
655 height
+= wxMENU_HEIGHT
;
657 height
+= wxPLACE_HOLDER
;
662 if (m_frameStatusBar
) height
+= wxSTATUS_HEIGHT
;
669 if (!m_toolBarDetached
)
672 m_frameToolBar
->GetSize( (int *) NULL
, &y
);
676 height
+= wxPLACE_HOLDER
;
680 DoSetSize( -1, -1, width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0 );
683 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height
)
685 // due to a bug in gtk, x,y are always 0
689 /* avoid recursions */
690 if (m_resizing
) return;
693 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
694 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
699 /* space occupied by m_frameToolBar and m_frameMenuBar */
700 int client_area_y_offset
= 0;
702 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
703 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
704 set in wxFrame::Create so it is used to check what kind of frame we
705 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
706 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
707 importantly) m_mainWidget */
711 /* check if size is in legal range */
712 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
713 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
714 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
715 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
717 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
718 * menubar, the toolbar and the client area, which is represented by
720 * this hurts in the eye, but I don't want to call SetSize()
721 * because I don't want to call any non-native functions here. */
726 int yy
= m_miniEdge
+ m_miniTitle
;
727 int ww
= m_width
- 2*m_miniEdge
;
728 int hh
= wxMENU_HEIGHT
;
729 if (m_menuBarDetached
) hh
= wxPLACE_HOLDER
;
730 m_frameMenuBar
->m_x
= xx
;
731 m_frameMenuBar
->m_y
= yy
;
732 m_frameMenuBar
->m_width
= ww
;
733 m_frameMenuBar
->m_height
= hh
;
734 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
735 m_frameMenuBar
->m_widget
,
737 client_area_y_offset
+= hh
;
741 if ((m_frameToolBar
) &&
742 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
745 int yy
= m_miniEdge
+ m_miniTitle
;
748 if (!m_menuBarDetached
)
751 yy
+= wxPLACE_HOLDER
;
753 int ww
= m_width
- 2*m_miniEdge
;
754 int hh
= m_frameToolBar
->m_height
;
755 if (m_toolBarDetached
) hh
= wxPLACE_HOLDER
;
756 m_frameToolBar
->m_x
= xx
;
757 m_frameToolBar
->m_y
= yy
;
758 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
759 m_frameToolBar->m_width = ww; */
760 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
761 m_frameToolBar
->m_widget
,
763 client_area_y_offset
+= hh
;
767 int client_x
= m_miniEdge
;
768 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
769 int client_w
= m_width
- 2*m_miniEdge
;
770 int client_h
= m_height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
771 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
773 client_x
, client_y
, client_w
, client_h
);
777 /* if there is no m_mainWidget between m_widget and m_wxwindow there
778 is no need to set the size or position of m_wxwindow. */
782 if (m_frameStatusBar
)
784 int xx
= 0 + m_miniEdge
;
785 int yy
= m_height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
786 int ww
= m_width
- 2*m_miniEdge
;
787 int hh
= wxSTATUS_HEIGHT
;
788 m_frameStatusBar
->m_x
= xx
;
789 m_frameStatusBar
->m_y
= yy
;
790 m_frameStatusBar
->m_width
= ww
;
791 m_frameStatusBar
->m_height
= hh
;
792 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
793 m_frameStatusBar
->m_widget
,
798 /* we actually set the size of a frame here and no-where else */
799 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
804 // send size event to frame
805 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
806 event
.SetEventObject( this );
807 GetEventHandler()->ProcessEvent( event
);
809 // send size event to status bar
810 if (m_frameStatusBar
)
812 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
813 event2
.SetEventObject( m_frameStatusBar
);
814 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
820 void wxFrame::MakeModal( bool modal
)
823 gtk_grab_add( m_widget
);
825 gtk_grab_remove( m_widget
);
828 void wxFrame::OnInternalIdle()
830 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
832 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
834 // we'll come back later
836 wxapp_install_idle_handler();
840 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
842 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
845 if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle();
848 wxWindow::OnInternalIdle();
851 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) )
856 void wxFrame::OnSize( wxSizeEvent
&WXUNUSED(event
) )
858 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
860 #if wxUSE_CONSTRAINTS
866 #endif // wxUSE_CONSTRAINTS
868 /* do we have exactly one child? */
869 wxWindow
*child
= (wxWindow
*)NULL
;
870 for ( wxNode
*node
= GetChildren().First(); node
; node
= node
->Next() )
872 wxWindow
*win
= (wxWindow
*)node
->Data();
873 if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) )
877 /* it's the second one: do nothing */
885 /* no children at all? */
888 /* yes: set it's size to fill all the frame */
889 int client_x
, client_y
;
890 DoGetClientSize( &client_x
, &client_y
);
891 child
->SetSize( 1, 1, client_x
-2, client_y
-2 );
896 void wxFrame::SetMenuBar( wxMenuBar
*menuBar
)
898 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
899 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
901 m_frameMenuBar
= menuBar
;
905 m_frameMenuBar
->SetInvokingWindow( this );
907 if (m_frameMenuBar
->GetParent() != this)
909 m_frameMenuBar
->SetParent(this);
910 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
911 m_frameMenuBar
->m_widget
,
914 m_frameMenuBar
->m_width
,
915 m_frameMenuBar
->m_height
);
917 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
919 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached",
920 GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this );
922 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached",
923 GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this );
926 m_frameMenuBar
->Show( TRUE
);
930 /* resize window in OnInternalIdle */
934 wxMenuBar
*wxFrame::GetMenuBar() const
936 return m_frameMenuBar
;
939 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
)
944 // if no help string found, we will clear the status bar text
947 int menuId
= event
.GetMenuId();
948 if ( menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */ )
950 wxMenuBar
*menuBar
= GetMenuBar();
953 // it's ok if we don't find the item because it might belong to
955 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
957 helpString
= item
->GetHelp();
961 SetStatusText(helpString
);
963 #endif // wxUSE_STATUSBAR
967 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
969 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
971 wxCHECK_MSG( m_frameToolBar
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") );
973 m_insertInClientArea
= FALSE
;
975 m_frameToolBar
= OnCreateToolBar( style
, id
, name
);
977 if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar
);
979 m_insertInClientArea
= TRUE
;
983 return m_frameToolBar
;
986 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name
)
988 return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
);
991 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
993 m_frameToolBar
= toolbar
;
996 /* insert into toolbar area if not already there */
997 if ((m_frameToolBar
->m_widget
->parent
) &&
998 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
1000 GetChildren().DeleteObject( m_frameToolBar
);
1002 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
1008 wxToolBar
*wxFrame::GetToolBar() const
1010 return m_frameToolBar
;
1012 #endif // wxUSE_TOOLBAR
1015 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1017 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1019 wxCHECK_MSG( m_frameStatusBar
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") );
1021 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
1025 return m_frameStatusBar
;
1028 wxStatusBar
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name
)
1030 wxStatusBar
*statusBar
= (wxStatusBar
*) NULL
;
1032 statusBar
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
);
1034 // Set the height according to the font and the border size
1035 wxClientDC
dc(statusBar
);
1036 dc
.SetFont( statusBar
->GetFont() );
1039 dc
.GetTextExtent( "X", &x
, &y
);
1041 int height
= (int)( (y
* 1.1) + 2* statusBar
->GetBorderY());
1043 statusBar
->SetSize( -1, -1, 100, height
);
1045 statusBar
->SetFieldsCount( number
);
1049 wxStatusBar
*wxFrame::GetStatusBar() const
1051 return m_frameStatusBar
;
1054 void wxFrame::SetStatusText(const wxString
& text
, int number
)
1056 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1058 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
1060 m_frameStatusBar
->SetStatusText(text
, number
);
1063 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] )
1065 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1067 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
1069 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
1071 #endif // wxUSE_STATUSBAR
1073 void wxFrame::Command( int id
)
1075 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
1076 commandEvent
.SetInt( id
);
1077 commandEvent
.SetEventObject( this );
1079 wxMenuBar
*bar
= GetMenuBar();
1082 wxMenuItem
*item
= bar
->FindItem(id
) ;
1083 if (item
&& item
->IsCheckable())
1085 bar
->Check(id
, !bar
->IsChecked(id
)) ;
1088 wxEvtHandler
* evtHandler
= GetEventHandler();
1090 evtHandler
->ProcessEvent(commandEvent
);
1093 void wxFrame::SetTitle( const wxString
&title
)
1095 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1098 if (m_title
.IsNull()) m_title
= wxT("");
1099 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
1102 void wxFrame::SetIcon( const wxIcon
&icon
)
1104 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
1107 if (!icon
.Ok()) return;
1109 if (!m_widget
->window
) return;
1111 wxMask
*mask
= icon
.GetMask();
1112 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
1113 if (mask
) bm
= mask
->GetBitmap();
1115 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
1118 void wxFrame::Maximize(bool WXUNUSED(maximize
))
1122 void wxFrame::Restore()
1126 void wxFrame::Iconize( bool iconize
)
1130 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window
),
1131 GDK_WINDOW_XWINDOW( m_widget
->window
),
1132 DefaultScreen( GDK_DISPLAY() ) );
1136 bool wxFrame::IsIconized() const