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" 
  24     #include <hildon-widgets/hildon-window.h> 
  25 #endif // wxUSE_LIBHILDON 
  28     #include <hildon/hildon.h> 
  29 #endif // wxUSE_LIBHILDON2 
  31 // ---------------------------------------------------------------------------- 
  33 // ---------------------------------------------------------------------------- 
  35 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxTopLevelWindow
) 
  37 // ============================================================================ 
  39 // ============================================================================ 
  41 // ---------------------------------------------------------------------------- 
  43 // ---------------------------------------------------------------------------- 
  50 bool wxFrame::Create( wxWindow 
*parent
, 
  52                       const wxString
& title
, 
  54                       const wxSize
& sizeOrig
, 
  56                       const wxString 
&name 
) 
  58     return wxFrameBase::Create(parent
, id
, title
, pos
, sizeOrig
, style
, name
); 
  68 // ---------------------------------------------------------------------------- 
  69 // overridden wxWindow methods 
  70 // ---------------------------------------------------------------------------- 
  72 void wxFrame::DoGetClientSize( int *width
, int *height 
) const 
  74     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
  76     wxFrameBase::DoGetClientSize(width
, height
); 
  80 #if wxUSE_MENUS_NATIVE 
  82         if (m_frameMenuBar 
&& m_frameMenuBar
->IsShown()) 
  85             gtk_widget_size_request(m_frameMenuBar
->m_widget
, &req
); 
  86 #if !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2 
  87             *height 
-= req
.height
; 
  90 #endif // wxUSE_MENUS_NATIVE 
  94         if (m_frameStatusBar 
&& m_frameStatusBar
->IsShown()) 
  95             *height 
-= m_frameStatusBar
->m_height
; 
  96 #endif // wxUSE_STATUSBAR 
 101     if (m_frameToolBar 
&& m_frameToolBar
->IsShown()) 
 104         gtk_widget_size_request(m_frameToolBar
->m_widget
, &req
); 
 105         if (m_frameToolBar
->IsVertical()) 
 113                 *height 
-= req
.height
; 
 116 #endif // wxUSE_TOOLBAR 
 118     if (width 
!= NULL 
&& *width 
< 0) 
 120     if (height 
!= NULL 
&& *height 
< 0) 
 124 #if wxUSE_MENUS && wxUSE_ACCEL 
 125 // Helper for wxCreateAcceleratorTableForMenuBar 
 126 static void wxAddAccelerators(wxList
& accelEntries
, wxMenu
* menu
) 
 129     for (i 
= 0; i 
< menu
->GetMenuItems().GetCount(); i
++) 
 131         wxMenuItem
* item 
= (wxMenuItem
*) menu
->GetMenuItems().Item(i
)->GetData(); 
 132         if (item
->GetSubMenu()) 
 134             wxAddAccelerators(accelEntries
, item
->GetSubMenu()); 
 136         else if (!item
->GetItemLabel().IsEmpty()) 
 138             wxAcceleratorEntry
* entry 
= wxAcceleratorEntry::Create(item
->GetItemLabel()); 
 141                 entry
->Set(entry
->GetFlags(), entry
->GetKeyCode(), item
->GetId()); 
 142                 accelEntries
.Append((wxObject
*) entry
); 
 148 // Create an accelerator table consisting of all the accelerators 
 149 // from the menubar in the given menus 
 150 static wxAcceleratorTable 
wxCreateAcceleratorTableForMenuBar(wxMenuBar
* menuBar
) 
 155     for (i 
= 0; i 
< menuBar
->GetMenuCount(); i
++) 
 157         wxAddAccelerators(accelEntries
, menuBar
->GetMenu(i
)); 
 160     size_t n 
= accelEntries
.GetCount(); 
 163         return wxAcceleratorTable(); 
 165     wxAcceleratorEntry
* entries 
= new wxAcceleratorEntry
[n
]; 
 167     for (i 
= 0; i 
< accelEntries
.GetCount(); i
++) 
 169         wxAcceleratorEntry
* entry 
= (wxAcceleratorEntry
*) accelEntries
.Item(i
)->GetData(); 
 170         entries
[i
] = (*entry
); 
 175     wxAcceleratorTable 
table(n
, entries
); 
 180 #endif // wxUSE_MENUS && wxUSE_ACCEL 
 182 bool wxFrame::ShowFullScreen(bool show
, long style
) 
 184     if (!wxFrameBase::ShowFullScreen(show
, style
)) 
 187 #if wxUSE_MENUS && wxUSE_ACCEL 
 188     if (show 
&& GetMenuBar()) 
 190         wxAcceleratorTable 
table(wxCreateAcceleratorTableForMenuBar(GetMenuBar())); 
 192             SetAcceleratorTable(table
); 
 194 #endif // wxUSE_MENUS && wxUSE_ACCEL 
 196     wxWindow
* const bar
[] = { 
 213     const long fsNoBar
[] = { 
 214         wxFULLSCREEN_NOMENUBAR
, wxFULLSCREEN_NOTOOLBAR
, wxFULLSCREEN_NOSTATUSBAR
 
 216     for (int i 
= 0; i 
< 3; i
++) 
 220             if (bar
[i
] && (style 
& fsNoBar
[i
])) 
 222                 if (bar
[i
]->IsShown()) 
 225                     style 
&= ~fsNoBar
[i
]; 
 230             if (bar
[i
] && (m_fsSaveFlag 
& fsNoBar
[i
])) 
 235         m_fsSaveFlag 
= style
; 
 240 void wxFrame::OnInternalIdle() 
 242     wxFrameBase::OnInternalIdle(); 
 244 #if wxUSE_MENUS_NATIVE 
 245     if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle(); 
 246 #endif // wxUSE_MENUS_NATIVE 
 248     if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle(); 
 251     if (m_frameStatusBar
) 
 253         m_frameStatusBar
->OnInternalIdle(); 
 255         // There may be controls in the status bar that 
 256         // need to be updated 
 257         for ( wxWindowList::compatibility_iterator node 
= m_frameStatusBar
->GetChildren().GetFirst(); 
 259           node 
= node
->GetNext() ) 
 261             wxWindow 
*child 
= node
->GetData(); 
 262             child
->OnInternalIdle(); 
 268 // ---------------------------------------------------------------------------- 
 269 // menu/tool/status bar stuff 
 270 // ---------------------------------------------------------------------------- 
 272 #if wxUSE_MENUS_NATIVE 
 274 void wxFrame::DetachMenuBar() 
 276     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 277     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 279     if ( m_frameMenuBar 
) 
 281 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 282         hildon_window_set_menu(HILDON_WINDOW(m_widget
), NULL
); 
 283 #else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2 
 284         gtk_widget_ref( m_frameMenuBar
->m_widget 
); 
 286         gtk_container_remove( GTK_CONTAINER(m_mainWidget
), m_frameMenuBar
->m_widget 
); 
 287 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2 
 290     wxFrameBase::DetachMenuBar(); 
 292     // make sure next size_allocate causes a wxSizeEvent 
 293     m_oldClientWidth 
= 0; 
 296 void wxFrame::AttachMenuBar( wxMenuBar 
*menuBar 
) 
 298     wxFrameBase::AttachMenuBar(menuBar
); 
 302 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 303         hildon_window_set_menu(HILDON_WINDOW(m_widget
), 
 304                                GTK_MENU(m_frameMenuBar
->m_menubar
)); 
 305 #else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2 
 306         m_frameMenuBar
->SetParent(this); 
 308         // menubar goes into top of vbox (m_mainWidget) 
 310             GTK_BOX(m_mainWidget
), menuBar
->m_widget
, false, false, 0); 
 311         gtk_box_reorder_child(GTK_BOX(m_mainWidget
), menuBar
->m_widget
, 0); 
 313         // disconnect wxWindowGTK "size_request" handler, 
 314         // it interferes with sizing of detached GtkHandleBox 
 315         gulong handler_id 
= g_signal_handler_find( 
 317             GSignalMatchType(G_SIGNAL_MATCH_ID 
| G_SIGNAL_MATCH_DATA
), 
 318             g_signal_lookup("size_request", GTK_TYPE_WIDGET
), 
 319             0, NULL
, NULL
, menuBar
); 
 321             g_signal_handler_disconnect(menuBar
->m_widget
, handler_id
); 
 323         // reset size request to allow native sizing to work 
 324         gtk_widget_set_size_request(menuBar
->m_widget
, -1, -1); 
 326         gtk_widget_show( m_frameMenuBar
->m_widget 
); 
 327 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2 
 329     // make sure next size_allocate causes a wxSizeEvent 
 330     m_oldClientWidth 
= 0; 
 332 #endif // wxUSE_MENUS_NATIVE 
 336 void wxFrame::SetToolBar(wxToolBar 
*toolbar
) 
 338     m_frameToolBar 
= toolbar
; 
 341         if (toolbar
->IsVertical()) 
 343             // Vertical toolbar and m_wxwindow go into an hbox, inside the 
 344             // vbox (m_mainWidget). hbox is created on demand. 
 345             GtkWidget
* hbox 
= m_wxwindow
->parent
; 
 346             if (!GTK_IS_HBOX(hbox
)) 
 348                 hbox 
= gtk_hbox_new(false, 0); 
 349                 gtk_widget_show(hbox
); 
 350                 gtk_container_add(GTK_CONTAINER(m_mainWidget
), hbox
); 
 351                 gtk_widget_reparent(m_wxwindow
, hbox
); 
 353             gtk_widget_reparent(toolbar
->m_widget
, hbox
); 
 354             gtk_box_set_child_packing(GTK_BOX(hbox
), 
 355                 toolbar
->m_widget
, false, false, 0, GTK_PACK_START
); 
 358             if (toolbar
->HasFlag(wxTB_RIGHT
)) 
 360             gtk_box_reorder_child(GTK_BOX(hbox
), toolbar
->m_widget
, pos
); 
 364             // Horizontal toolbar goes into vbox (m_mainWidget) 
 365             gtk_widget_reparent(toolbar
->m_widget
, m_mainWidget
); 
 366             gtk_box_set_child_packing(GTK_BOX(m_mainWidget
), 
 367                 toolbar
->m_widget
, false, false, 0, GTK_PACK_START
); 
 371                 pos 
= 1;  // below menubar 
 372             if (toolbar
->HasFlag(wxTB_BOTTOM
)) 
 373                 pos 
+= 2;  // below client area (m_wxwindow) 
 374             gtk_box_reorder_child( 
 375                 GTK_BOX(m_mainWidget
), toolbar
->m_widget
, pos
); 
 378         // disconnect wxWindowGTK "size_request" handler, 
 379         // it interferes with sizing of detached GtkHandleBox 
 380         gulong handler_id 
= g_signal_handler_find( 
 382             GSignalMatchType(G_SIGNAL_MATCH_ID 
| G_SIGNAL_MATCH_DATA
), 
 383             g_signal_lookup("size_request", GTK_TYPE_WIDGET
), 
 384             0, NULL
, NULL
, toolbar
); 
 386             g_signal_handler_disconnect(toolbar
->m_widget
, handler_id
); 
 388         // reset size request to allow native sizing to work 
 389         gtk_widget_set_size_request(toolbar
->m_widget
, -1, -1); 
 391     // make sure next size_allocate causes a wxSizeEvent 
 392     m_oldClientWidth 
= 0; 
 395 #endif // wxUSE_TOOLBAR 
 399 void wxFrame::SetStatusBar(wxStatusBar 
*statbar
) 
 401     m_frameStatusBar 
= statbar
; 
 404         // statusbar goes into bottom of vbox (m_mainWidget) 
 405         gtk_widget_reparent(statbar
->m_widget
, m_mainWidget
); 
 406         gtk_box_set_child_packing(GTK_BOX(m_mainWidget
), 
 407             statbar
->m_widget
, false, false, 0, GTK_PACK_END
); 
 408         // make sure next size_allocate on statusbar causes a size event 
 409         statbar
->m_oldClientWidth 
= 0; 
 411     // make sure next size_allocate causes a wxSizeEvent 
 412     m_oldClientWidth 
= 0; 
 414 #endif // wxUSE_STATUSBAR