/Extras/wxWidgets-2.9.0/src/gtk/frame.cpp
C++ | 412 lines | 303 code | 61 blank | 48 comment | 59 complexity | 6e94438b3635d02d0c93e70fc86a2d5b MD5 | raw file
- /////////////////////////////////////////////////////////////////////////////
- // Name: src/gtk/frame.cpp
- // Purpose:
- // Author: Robert Roebling
- // Id: $Id: frame.cpp 58246 2009-01-20 18:33:33Z VZ $
- // Copyright: (c) 1998 Robert Roebling
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- // For compilers that support precompilation, includes "wx.h".
- #include "wx/wxprec.h"
- #include "wx/frame.h"
- #ifndef WX_PRECOMP
- #include "wx/menu.h"
- #include "wx/toolbar.h"
- #include "wx/statusbr.h"
- #endif // WX_PRECOMP
- #include <gtk/gtk.h>
- #if wxUSE_LIBHILDON
- #include <hildon-widgets/hildon-window.h>
- #endif // wxUSE_LIBHILDON
- // ----------------------------------------------------------------------------
- // event tables
- // ----------------------------------------------------------------------------
- IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
- // ============================================================================
- // implementation
- // ============================================================================
- // ----------------------------------------------------------------------------
- // wxFrame creation
- // ----------------------------------------------------------------------------
- void wxFrame::Init()
- {
- m_fsSaveFlag = 0;
- }
- bool wxFrame::Create( wxWindow *parent,
- wxWindowID id,
- const wxString& title,
- const wxPoint& pos,
- const wxSize& sizeOrig,
- long style,
- const wxString &name )
- {
- return wxFrameBase::Create(parent, id, title, pos, sizeOrig, style, name);
- }
- wxFrame::~wxFrame()
- {
- SendDestroyEvent();
- DeleteAllBars();
- }
- // ----------------------------------------------------------------------------
- // overridden wxWindow methods
- // ----------------------------------------------------------------------------
- void wxFrame::DoGetClientSize( int *width, int *height ) const
- {
- wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
- wxFrameBase::DoGetClientSize(width, height);
- if (height)
- {
- #if wxUSE_MENUS_NATIVE
- // menu bar
- if (m_frameMenuBar && m_frameMenuBar->IsShown())
- {
- GtkRequisition req;
- gtk_widget_size_request(m_frameMenuBar->m_widget, &req);
- *height -= req.height;
- }
- #endif // wxUSE_MENUS_NATIVE
- #if wxUSE_STATUSBAR
- // status bar
- if (m_frameStatusBar && m_frameStatusBar->IsShown())
- *height -= m_frameStatusBar->m_height;
- #endif // wxUSE_STATUSBAR
- }
- #if wxUSE_TOOLBAR
- // tool bar
- if (m_frameToolBar && m_frameToolBar->IsShown())
- {
- GtkRequisition req;
- gtk_widget_size_request(m_frameToolBar->m_widget, &req);
- if (m_frameToolBar->IsVertical())
- {
- if (width)
- *width -= req.width;
- }
- else
- {
- if (height)
- *height -= req.height;
- }
- }
- #endif // wxUSE_TOOLBAR
- if (width != NULL && *width < 0)
- *width = 0;
- if (height != NULL && *height < 0)
- *height = 0;
- }
- #if wxUSE_MENUS && wxUSE_ACCEL
- // Helper for wxCreateAcceleratorTableForMenuBar
- static void wxAddAccelerators(wxList& accelEntries, wxMenu* menu)
- {
- size_t i;
- for (i = 0; i < menu->GetMenuItems().GetCount(); i++)
- {
- wxMenuItem* item = (wxMenuItem*) menu->GetMenuItems().Item(i)->GetData();
- if (item->GetSubMenu())
- {
- wxAddAccelerators(accelEntries, item->GetSubMenu());
- }
- else if (!item->GetItemLabel().IsEmpty())
- {
- wxAcceleratorEntry* entry = wxAcceleratorEntry::Create(item->GetItemLabel());
- if (entry)
- {
- entry->Set(entry->GetFlags(), entry->GetKeyCode(), item->GetId());
- accelEntries.Append((wxObject*) entry);
- }
- }
- }
- }
- // Create an accelerator table consisting of all the accelerators
- // from the menubar in the given menus
- static wxAcceleratorTable wxCreateAcceleratorTableForMenuBar(wxMenuBar* menuBar)
- {
- wxList accelEntries;
- size_t i;
- for (i = 0; i < menuBar->GetMenuCount(); i++)
- {
- wxAddAccelerators(accelEntries, menuBar->GetMenu(i));
- }
- size_t n = accelEntries.GetCount();
- if (n == 0)
- return wxAcceleratorTable();
- wxAcceleratorEntry* entries = new wxAcceleratorEntry[n];
- for (i = 0; i < accelEntries.GetCount(); i++)
- {
- wxAcceleratorEntry* entry = (wxAcceleratorEntry*) accelEntries.Item(i)->GetData();
- entries[i] = (*entry);
- delete entry;
-
- }
- wxAcceleratorTable table(n, entries);
- delete[] entries;
- return table;
- }
- #endif // wxUSE_MENUS && wxUSE_ACCEL
- bool wxFrame::ShowFullScreen(bool show, long style)
- {
- if (!wxFrameBase::ShowFullScreen(show, style))
- return false;
- #if wxUSE_MENUS && wxUSE_ACCEL
- if (show && GetMenuBar())
- {
- wxAcceleratorTable table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
- if (table.IsOk())
- SetAcceleratorTable(table);
- }
- #endif // wxUSE_MENUS && wxUSE_ACCEL
- wxWindow* const bar[] = {
- #if wxUSE_MENUS
- m_frameMenuBar,
- #else
- NULL,
- #endif
- #if wxUSE_TOOLBAR
- m_frameToolBar,
- #else
- NULL,
- #endif
- #if wxUSE_STATUSBAR
- m_frameStatusBar,
- #else
- NULL,
- #endif
- };
- const long fsNoBar[] = {
- wxFULLSCREEN_NOMENUBAR, wxFULLSCREEN_NOTOOLBAR, wxFULLSCREEN_NOSTATUSBAR
- };
- for (int i = 0; i < 3; i++)
- {
- if (show)
- {
- if (bar[i] && (style & fsNoBar[i]))
- {
- if (bar[i]->IsShown())
- bar[i]->Show(false);
- else
- style &= ~fsNoBar[i];
- }
- }
- else
- {
- if (bar[i] && (m_fsSaveFlag & fsNoBar[i]))
- bar[i]->Show(true);
- }
- }
- if (show)
- m_fsSaveFlag = style;
- return true;
- }
- void wxFrame::OnInternalIdle()
- {
- wxFrameBase::OnInternalIdle();
- #if wxUSE_MENUS_NATIVE
- if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
- #endif // wxUSE_MENUS_NATIVE
- #if wxUSE_TOOLBAR
- if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
- #endif
- #if wxUSE_STATUSBAR
- if (m_frameStatusBar)
- {
- m_frameStatusBar->OnInternalIdle();
- // There may be controls in the status bar that
- // need to be updated
- for ( wxWindowList::compatibility_iterator node = m_frameStatusBar->GetChildren().GetFirst();
- node;
- node = node->GetNext() )
- {
- wxWindow *child = node->GetData();
- child->OnInternalIdle();
- }
- }
- #endif
- }
- // ----------------------------------------------------------------------------
- // menu/tool/status bar stuff
- // ----------------------------------------------------------------------------
- #if wxUSE_MENUS_NATIVE
- void wxFrame::DetachMenuBar()
- {
- wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
- wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
- if ( m_frameMenuBar )
- {
- #if wxUSE_LIBHILDON
- hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
- #else // !wxUSE_LIBHILDON
- m_frameMenuBar->UnsetInvokingWindow( this );
- gtk_widget_ref( m_frameMenuBar->m_widget );
- gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
- #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
- }
- wxFrameBase::DetachMenuBar();
- // make sure next size_allocate causes a wxSizeEvent
- m_oldClientWidth = 0;
- }
- void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
- {
- wxFrameBase::AttachMenuBar(menuBar);
- if (m_frameMenuBar)
- {
- #if wxUSE_LIBHILDON
- hildon_window_set_menu(HILDON_WINDOW(m_widget),
- GTK_MENU(m_frameMenuBar->m_menubar));
- #else // !wxUSE_LIBHILDON
- m_frameMenuBar->SetInvokingWindow( this );
- m_frameMenuBar->SetParent(this);
- // menubar goes into top of vbox (m_mainWidget)
- gtk_box_pack_start(
- GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
- gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
- // disconnect wxWindowGTK "size_request" handler,
- // it interferes with sizing of detached GtkHandleBox
- gulong handler_id = g_signal_handler_find(
- menuBar->m_widget,
- GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
- g_signal_lookup("size_request", GTK_TYPE_WIDGET),
- 0, NULL, NULL, menuBar);
- if (handler_id != 0)
- g_signal_handler_disconnect(menuBar->m_widget, handler_id);
- // reset size request to allow native sizing to work
- gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
- gtk_widget_show( m_frameMenuBar->m_widget );
- #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
- }
- // make sure next size_allocate causes a wxSizeEvent
- m_oldClientWidth = 0;
- }
- #endif // wxUSE_MENUS_NATIVE
- #if wxUSE_TOOLBAR
- void wxFrame::SetToolBar(wxToolBar *toolbar)
- {
- m_frameToolBar = toolbar;
- if (toolbar)
- {
- if (toolbar->IsVertical())
- {
- // Vertical toolbar and m_wxwindow go into an hbox, inside the
- // vbox (m_mainWidget). hbox is created on demand.
- GtkWidget* hbox = m_wxwindow->parent;
- if (!GTK_IS_HBOX(hbox))
- {
- hbox = gtk_hbox_new(false, 0);
- gtk_widget_show(hbox);
- gtk_container_add(GTK_CONTAINER(m_mainWidget), hbox);
- gtk_widget_reparent(m_wxwindow, hbox);
- }
- gtk_widget_reparent(toolbar->m_widget, hbox);
- gtk_box_set_child_packing(GTK_BOX(hbox),
- toolbar->m_widget, false, false, 0, GTK_PACK_START);
- int pos = 0; // left
- if (toolbar->HasFlag(wxTB_RIGHT))
- pos = 1; // right
- gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
- }
- else
- {
- // Horizontal toolbar goes into vbox (m_mainWidget)
- gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
- gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
- toolbar->m_widget, false, false, 0, GTK_PACK_START);
- int pos = 0; // top
- if (m_frameMenuBar)
- pos = 1; // below menubar
- if (toolbar->HasFlag(wxTB_BOTTOM))
- pos += 2; // below client area (m_wxwindow)
- gtk_box_reorder_child(
- GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
- }
- // disconnect wxWindowGTK "size_request" handler,
- // it interferes with sizing of detached GtkHandleBox
- gulong handler_id = g_signal_handler_find(
- toolbar->m_widget,
- GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
- g_signal_lookup("size_request", GTK_TYPE_WIDGET),
- 0, NULL, NULL, toolbar);
- if (handler_id != 0)
- g_signal_handler_disconnect(toolbar->m_widget, handler_id);
- // reset size request to allow native sizing to work
- gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
- }
- // make sure next size_allocate causes a wxSizeEvent
- m_oldClientWidth = 0;
- }
- #endif // wxUSE_TOOLBAR
- #if wxUSE_STATUSBAR
- void wxFrame::SetStatusBar(wxStatusBar *statbar)
- {
- m_frameStatusBar = statbar;
- if (statbar)
- {
- // statusbar goes into bottom of vbox (m_mainWidget)
- gtk_widget_reparent(statbar->m_widget, m_mainWidget);
- gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
- statbar->m_widget, false, false, 0, GTK_PACK_END);
- // make sure next size_allocate on statusbar causes a size event
- statbar->m_oldClientWidth = 0;
- }
- // make sure next size_allocate causes a wxSizeEvent
- m_oldClientWidth = 0;
- }
- #endif // wxUSE_STATUSBAR