1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/frame.cpp
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #include "wx/toolbar.h"
18 #include "wx/statusbr.h"
22 #include "wx/gtk/win_gtk.h"
24 // ----------------------------------------------------------------------------
26 // ----------------------------------------------------------------------------
28 static const int wxSTATUS_HEIGHT
= 25;
29 static const int wxPLACE_HOLDER
= 0;
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
35 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxTopLevelWindow
)
37 // ============================================================================
39 // ============================================================================
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 #if wxUSE_MENUS_NATIVE
47 //-----------------------------------------------------------------------------
48 // "child_attached" of menu bar
49 //-----------------------------------------------------------------------------
52 static void gtk_menu_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
54 if (!win
->m_hasVMT
) return;
56 win
->m_menuBarDetached
= false;
61 //-----------------------------------------------------------------------------
62 // "child_detached" of menu bar
63 //-----------------------------------------------------------------------------
66 static void gtk_menu_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
68 if (!win
->m_hasVMT
) return;
70 // Raise the client area area
71 gdk_window_raise( win
->m_wxwindow
->window
);
73 win
->m_menuBarDetached
= true;
78 #endif // wxUSE_MENUS_NATIVE
81 //-----------------------------------------------------------------------------
82 // "child_attached" of tool bar
83 //-----------------------------------------------------------------------------
86 static void gtk_toolbar_attached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
88 if (!win
->m_hasVMT
) return;
90 win
->m_toolBarDetached
= false;
95 //-----------------------------------------------------------------------------
96 // "child_detached" of tool bar
97 //-----------------------------------------------------------------------------
100 static void gtk_toolbar_detached_callback( GtkWidget
*WXUNUSED(widget
), GtkWidget
*WXUNUSED(child
), wxFrame
*win
)
102 if (!win
->m_hasVMT
) return;
104 // Raise the client area area
105 gdk_window_raise( win
->m_wxwindow
->window
);
107 win
->m_toolBarDetached
= true;
108 win
->GtkUpdateSize();
111 #endif // wxUSE_TOOLBAR
113 // ----------------------------------------------------------------------------
115 // ----------------------------------------------------------------------------
119 m_menuBarDetached
= false;
120 m_toolBarDetached
= false;
125 bool wxFrame::Create( wxWindow
*parent
,
127 const wxString
& title
,
129 const wxSize
& sizeOrig
,
131 const wxString
&name
)
133 return wxFrameBase::Create(parent
, id
, title
, pos
, sizeOrig
, style
, name
);
138 m_isBeingDeleted
= true;
142 // ----------------------------------------------------------------------------
143 // overridden wxWindow methods
144 // ----------------------------------------------------------------------------
146 void wxFrame::DoGetClientSize( int *width
, int *height
) const
148 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
150 wxFrameBase::DoGetClientSize(width
, height
);
154 #if wxUSE_MENUS_NATIVE
156 if (HasVisibleMenubar() && !m_menuBarDetached
)
158 *height
-= m_menuBarHeight
;
160 #endif // wxUSE_MENUS_NATIVE
164 if (m_frameStatusBar
&& GTK_WIDGET_VISIBLE(m_frameStatusBar
->m_widget
))
165 *height
-= wxSTATUS_HEIGHT
;
166 #endif // wxUSE_STATUSBAR
171 if (m_frameToolBar
&&
172 GTK_WIDGET_VISIBLE(m_frameToolBar
->m_widget
) && !m_toolBarDetached
)
174 if (m_frameToolBar
->IsVertical())
177 *width
-= m_frameToolBar
->GetSize().x
;
182 *height
-= m_frameToolBar
->GetSize().y
;
185 #endif // wxUSE_TOOLBAR
187 if (width
!= NULL
&& *width
< 0)
189 if (height
!= NULL
&& *height
< 0)
193 bool wxFrame::ShowFullScreen(bool show
, long style
)
195 if (!wxFrameBase::ShowFullScreen(show
, style
))
198 wxWindow
* const bar
[] = {
215 const long fsNoBar
[] = {
216 wxFULLSCREEN_NOMENUBAR
, wxFULLSCREEN_NOTOOLBAR
, wxFULLSCREEN_NOSTATUSBAR
218 for (int i
= 0; i
< 3; i
++)
222 if (bar
[i
] && (style
& fsNoBar
[i
]))
224 if (bar
[i
]->IsShown())
227 style
&= ~fsNoBar
[i
];
232 if (bar
[i
] && (m_fsSaveFlag
& fsNoBar
[i
]))
237 m_fsSaveFlag
= style
;
242 void wxFrame::GtkOnSize()
245 if (m_resizing
) return;
248 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
249 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
251 // space occupied by m_frameToolBar and m_frameMenuBar
252 int client_area_x_offset
= 0,
253 client_area_y_offset
= 0;
255 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
256 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
257 set in wxFrame::Create so it is used to check what kind of frame we
258 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
259 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
260 importantly) m_mainWidget */
265 GTKDoGetSize(&width
, &height
);
270 // Rewrite this terrible code to using GtkVBox
272 // m_mainWidget holds the menubar, the toolbar and the client
273 // area, which is represented by m_wxwindow.
275 #if wxUSE_MENUS_NATIVE
276 int menubarHeight
= 0;
279 #if wxUSE_MENUS_NATIVE
280 if (HasVisibleMenubar())
283 int yy
= m_miniEdge
+ m_miniTitle
;
284 int ww
= width
- 2*m_miniEdge
;
287 menubarHeight
= m_menuBarHeight
;
288 if (m_menuBarDetached
) menubarHeight
= wxPLACE_HOLDER
;
289 m_frameMenuBar
->m_x
= xx
;
290 m_frameMenuBar
->m_y
= yy
;
291 m_frameMenuBar
->m_width
= ww
;
292 m_frameMenuBar
->m_height
= menubarHeight
;
293 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
294 m_frameMenuBar
->m_widget
,
295 xx
, yy
, ww
, menubarHeight
);
296 client_area_y_offset
+= menubarHeight
;
298 #endif // wxUSE_MENUS_NATIVE
301 if ((m_frameToolBar
) && m_frameToolBar
->IsShown() &&
302 (m_frameToolBar
->m_widget
->parent
== m_mainWidget
))
305 int yy
= m_miniEdge
+ m_miniTitle
306 #if wxUSE_MENUS_NATIVE
311 m_frameToolBar
->m_x
= xx
;
312 m_frameToolBar
->m_y
= yy
;
314 // don't change the toolbar's reported height/width
316 if ( m_frameToolBar
->GetWindowStyle() & wxTB_VERTICAL
)
318 ww
= m_toolBarDetached
? wxPLACE_HOLDER
319 : m_frameToolBar
->m_width
;
320 hh
= height
- 2*m_miniEdge
;
322 client_area_x_offset
+= ww
;
324 else if( m_frameToolBar
->HasFlag(wxTB_RIGHT
) )
327 ww
= m_toolBarDetached
? wxPLACE_HOLDER
328 : m_frameToolBar
->m_width
;
329 xx
= GetClientSize().x
- 1;
330 hh
= height
- 2*m_miniEdge
;
335 else if( m_frameToolBar
->GetWindowStyle() & wxTB_BOTTOM
)
338 yy
= GetClientSize().y
;
339 #if wxUSE_MENUS_NATIVE
340 yy
+= m_menuBarHeight
;
341 #endif // wxUSE_MENUS_NATIVE
342 m_frameToolBar
->m_x
= xx
;
343 m_frameToolBar
->m_y
= yy
;
344 ww
= width
- 2*m_miniEdge
;
345 hh
= m_toolBarDetached
? wxPLACE_HOLDER
346 : m_frameToolBar
->m_height
;
350 ww
= width
- 2*m_miniEdge
;
351 hh
= m_toolBarDetached
? wxPLACE_HOLDER
352 : m_frameToolBar
->m_height
;
354 client_area_y_offset
+= hh
;
361 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
362 m_frameToolBar
->m_widget
,
365 #endif // wxUSE_TOOLBAR
367 int client_x
= client_area_x_offset
+ m_miniEdge
;
368 int client_y
= client_area_y_offset
+ m_miniEdge
+ m_miniTitle
;
369 int client_w
= width
- client_area_x_offset
- 2*m_miniEdge
;
370 int client_h
= height
- client_area_y_offset
- 2*m_miniEdge
- m_miniTitle
;
375 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
377 client_x
, client_y
, client_w
, client_h
);
381 // If there is no m_mainWidget between m_widget and m_wxwindow there
382 // is no need to set the size or position of m_wxwindow.
386 if (m_frameStatusBar
&& m_frameStatusBar
->IsShown())
388 int xx
= 0 + m_miniEdge
;
389 int yy
= height
- wxSTATUS_HEIGHT
- m_miniEdge
- client_area_y_offset
;
390 int ww
= width
- 2*m_miniEdge
;
393 int hh
= wxSTATUS_HEIGHT
;
394 m_frameStatusBar
->m_x
= xx
;
395 m_frameStatusBar
->m_y
= yy
;
396 m_frameStatusBar
->m_width
= ww
;
397 m_frameStatusBar
->m_height
= hh
;
398 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
),
399 m_frameStatusBar
->m_widget
,
402 #endif // wxUSE_STATUSBAR
406 // send size event to frame
407 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
408 event
.SetEventObject( this );
409 GetEventHandler()->ProcessEvent( event
);
412 // send size event to status bar
413 if (m_frameStatusBar
)
415 wxSizeEvent
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() );
416 event2
.SetEventObject( m_frameStatusBar
);
417 m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2
);
419 #endif // wxUSE_STATUSBAR
424 void wxFrame::OnInternalIdle()
426 wxFrameBase::OnInternalIdle();
428 #if wxUSE_MENUS_NATIVE
429 if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle();
430 #endif // wxUSE_MENUS_NATIVE
432 if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle();
435 if (m_frameStatusBar
)
437 m_frameStatusBar
->OnInternalIdle();
439 // There may be controls in the status bar that
440 // need to be updated
441 for ( wxWindowList::compatibility_iterator node
= m_frameStatusBar
->GetChildren().GetFirst();
443 node
= node
->GetNext() )
445 wxWindow
*child
= node
->GetData();
446 child
->OnInternalIdle();
452 // ----------------------------------------------------------------------------
453 // menu/tool/status bar stuff
454 // ----------------------------------------------------------------------------
456 #if wxUSE_MENUS_NATIVE
458 void wxFrame::DetachMenuBar()
460 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
461 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
463 if ( m_frameMenuBar
)
465 m_frameMenuBar
->UnsetInvokingWindow( this );
467 if (m_frameMenuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
469 g_signal_handlers_disconnect_by_func (m_frameMenuBar
->m_widget
,
470 (gpointer
) gtk_menu_attached_callback
,
473 g_signal_handlers_disconnect_by_func (m_frameMenuBar
->m_widget
,
474 (gpointer
) gtk_menu_detached_callback
,
478 gtk_widget_ref( m_frameMenuBar
->m_widget
);
480 gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget
);
483 wxFrameBase::DetachMenuBar();
486 void wxFrame::AttachMenuBar( wxMenuBar
*menuBar
)
488 wxFrameBase::AttachMenuBar(menuBar
);
492 m_frameMenuBar
->SetInvokingWindow( this );
494 m_frameMenuBar
->SetParent(this);
495 gtk_pizza_put( GTK_PIZZA(m_mainWidget
),
496 m_frameMenuBar
->m_widget
,
499 m_frameMenuBar
->m_width
,
500 m_frameMenuBar
->m_height
);
502 if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
)
504 g_signal_connect (menuBar
->m_widget
, "child_attached",
505 G_CALLBACK (gtk_menu_attached_callback
),
507 g_signal_connect (menuBar
->m_widget
, "child_detached",
508 G_CALLBACK (gtk_menu_detached_callback
),
512 gtk_widget_show( m_frameMenuBar
->m_widget
);
519 GtkUpdateSize(); // resize window in OnInternalIdle
523 void wxFrame::UpdateMenuBarSize()
527 // this is called after Remove with a NULL m_frameMenuBar
528 if ( m_frameMenuBar
)
531 gtk_widget_ensure_style(m_frameMenuBar
->m_widget
);
532 // have to call class method directly because
533 // "size_request" signal is overridden by wx
534 GTK_WIDGET_GET_CLASS(m_frameMenuBar
->m_widget
)->size_request(
535 m_frameMenuBar
->m_widget
, &req
);
537 m_menuBarHeight
= req
.height
;
540 // resize window in OnInternalIdle
544 bool wxFrame::HasVisibleMenubar() const
546 return m_frameMenuBar
&& m_frameMenuBar
->IsShown();
548 #endif // wxUSE_MENUS_NATIVE
552 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
554 wxFrameBase::SetToolBar(toolbar
);
556 if ( m_frameToolBar
)
558 // insert into toolbar area if not already there
559 if ((m_frameToolBar
->m_widget
->parent
) &&
560 (m_frameToolBar
->m_widget
->parent
!= m_mainWidget
))
562 GetChildren().DeleteObject( m_frameToolBar
);
564 gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget
);
566 #if wxUSE_TOOLBAR_NATIVE
567 if (m_frameToolBar
->HasFlag(wxTB_DOCKABLE
))
569 g_signal_connect(m_frameToolBar
->m_widget
, "child_attached",
570 G_CALLBACK(gtk_toolbar_attached_callback
), this);
571 g_signal_connect(m_frameToolBar
->m_widget
, "child_detached",
572 G_CALLBACK(gtk_toolbar_detached_callback
), this);
574 #endif // wxUSE_TOOLBAR_NATIVE
580 #endif // wxUSE_TOOLBAR
584 void wxFrame::SetStatusBar(wxStatusBar
*statbar
)
586 wxFrameBase::SetStatusBar(statbar
);
589 #endif // wxUSE_STATUSBAR