X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7c78e7c70271608b076b1dbed201b1204e6898d4..399b60a0ad232265cd74ce8bf6a53a1f2cc57ff2:/src/qt/frame.cpp diff --git a/src/qt/frame.cpp b/src/qt/frame.cpp index 132a11bf55..8807b62f89 100644 --- a/src/qt/frame.cpp +++ b/src/qt/frame.cpp @@ -1,10 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// // Name: frame.cpp -// Purpose: -// Author: Robert Roebling -// Created: 01/02/97 -// Id: -// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem +// Purpose: wxFrame +// Author: AUTHOR +// Modified by: +// Created: ??/??/98 +// RCS-ID: $Id$ +// Copyright: (c) AUTHOR // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -13,240 +14,520 @@ #endif #include "wx/frame.h" -#include "wx/dialog.h" -#include "wx/control.h" -#include "wx/app.h" -#include "wx/menu.h" -#include "wx/toolbar.h" #include "wx/statusbr.h" -#include "wx/mdi.h" - -const wxMENU_HEIGHT = 28; -const wxSTATUS_HEIGHT = 25; +#include "wx/toolbar.h" +#include "wx/menuitem.h" -extern wxList wxTopLevelWindows; +extern wxList wxModelessWindows; extern wxList wxPendingDelete; -//----------------------------------------------------------------------------- -// wxFrame -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- - BEGIN_EVENT_TABLE(wxFrame, wxWindow) EVT_SIZE(wxFrame::OnSize) - EVT_CLOSE(wxFrame::OnCloseWindow) + EVT_ACTIVATE(wxFrame::OnActivate) + EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight) + EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged) EVT_IDLE(wxFrame::OnIdle) + EVT_CLOSE(wxFrame::OnCloseWindow) END_EVENT_TABLE() -IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow) +IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow) + +#if wxUSE_NATIVE_STATUSBAR +bool wxFrame::m_useNativeStatusBar = TRUE; +#else +bool wxFrame::m_useNativeStatusBar = FALSE; +#endif wxFrame::wxFrame() { - wxTopLevelWindows.Insert( this ); -}; + m_frameToolBar = NULL ; + m_frameMenuBar = NULL; + m_frameStatusBar = NULL; -wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title, - const wxPoint &pos, const wxSize &size, - long style, const wxString &name ) -{ - Create( parent, id, title, pos, size, style, name ); - wxTopLevelWindows.Insert( this ); -}; + m_windowParent = NULL; + m_iconized = FALSE; +} -bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, - const wxPoint &pos, const wxSize &size, - long style, const wxString &name ) +bool wxFrame::Create(wxWindow *parent, + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { - m_title = title; + if (!parent) + wxTopLevelWindows.Append(this); - return TRUE; -}; + SetName(name); + m_windowStyle = style; + m_frameMenuBar = NULL; + m_frameToolBar = NULL ; + m_frameStatusBar = NULL; + + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE)); + + if ( id > -1 ) + m_windowId = id; + else + m_windowId = (int)NewControlId(); + + if (parent) parent->AddChild(this); + + wxModelessWindows.Append(this); + + // TODO: create frame. + + return FALSE; +} wxFrame::~wxFrame() { - if (m_frameMenuBar) delete m_frameMenuBar; - if (m_frameStatusBar) delete m_frameStatusBar; + wxTopLevelWindows.DeleteObject(this); + + if (m_frameStatusBar) + delete m_frameStatusBar; + if (m_frameMenuBar) + delete m_frameMenuBar; + +/* Check if it's the last top-level window */ + + if (wxTheApp && (wxTopLevelWindows.Number() == 0)) + { + wxTheApp->SetTopWindow(NULL); + + if (wxTheApp->GetExitOnFrameDelete()) + { + // TODO signal to the app that we're going to close + } + } + + wxModelessWindows.DeleteObject(this); +} + +// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. +void wxFrame::GetClientSize(int *x, int *y) const +{ + // TODO +} + +// Set the client size (i.e. leave the calculation of borders etc. +// to wxWindows) +void wxFrame::SetClientSize(int width, int height) +{ + // TODO +} + +void wxFrame::GetSize(int *width, int *height) const +{ + // TODO +} + +void wxFrame::GetPosition(int *x, int *y) const +{ + // TODO +} + +void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags) +{ + // TODO +} + +bool wxFrame::Show(bool show) +{ + // TODO + return FALSE; +} + +void wxFrame::Iconize(bool iconize) +{ + // TODO +} + +// Equivalent to maximize/restore in Windows +void wxFrame::Maximize(bool maximize) +{ + // TODO +} + +bool wxFrame::IsIconized() const +{ + // TODO + return FALSE; +} - wxTopLevelWindows.DeleteObject( this ); - if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop(); -}; +void wxFrame::SetTitle(const wxString& title) +{ + // TODO +} -bool wxFrame::Show( bool show ) +wxString wxFrame::GetTitle() const { - if (show) + // TODO + return wxString(""); +} + +void wxFrame::SetIcon(const wxIcon& icon) +{ + m_icon = icon; + // TODO +} + +void wxFrame::SetAcceleratorTable(const wxAcceleratorTable& accel) +{ + m_acceleratorTable = accel; +} + +wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id, + const wxString& name) +{ + wxStatusBar *statusBar = NULL; + + statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20), + style, name); + + // Set the height according to the font and the border size + wxClientDC dc(statusBar); + dc.SetFont(* statusBar->GetFont()); + + long x, y; + dc.GetTextExtent("X", &x, &y); + + int height = (int)( (y * 1.1) + 2* statusBar->GetBorderY()); + + statusBar->SetSize(-1, -1, 100, height); + + statusBar->SetFieldsCount(number); + return statusBar; +} + +wxStatusBar* wxFrame::CreateStatusBar(int number, long style, wxWindowID id, + const wxString& name) +{ + // Calling CreateStatusBar twice is an error. + wxCHECK_MSG( m_frameStatusBar == NULL, FALSE, + "recreating status bar in wxFrame" ); + + m_frameStatusBar = OnCreateStatusBar(number, style, id, + name); + if ( m_frameStatusBar ) { - wxSizeEvent event( wxSize(m_width,m_height), GetId() ); - ProcessEvent( event ); - }; - return wxWindow::Show( show ); -}; + PositionStatusBar(); + return m_frameStatusBar; + } + else + return NULL; +} -void wxFrame::Enable( bool enable ) +void wxFrame::SetStatusText(const wxString& text, int number) { - wxWindow::Enable( enable ); -}; + wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set text for" ); + + m_frameStatusBar->SetStatusText(text, number); +} -void wxFrame::OnCloseWindow( wxCloseEvent &event ) +void wxFrame::SetStatusWidths(int n, const int widths_field[]) { - if ( GetEventHandler()->OnClose() || event.GetForce()) + wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set widths for" ); + + m_frameStatusBar->SetStatusWidths(n, widths_field); + PositionStatusBar(); +} + +void wxFrame::PositionStatusBar() +{ + int w, h; + GetClientSize(&w, &h); + int sw, sh; + m_frameStatusBar->GetSize(&sw, &sh); + + // Since we wish the status bar to be directly under the client area, + // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. + m_frameStatusBar->SetSize(0, h, w, sh); +} + +void wxFrame::SetMenuBar(wxMenuBar *menuBar) +{ + if (!menuBar) { - this->Destroy(); + m_frameMenuBar = NULL; + return; } -}; + + m_frameMenuBar = menuBar; -bool wxFrame::Destroy() + // TODO +} + +void wxFrame::Fit() { - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); + // Work out max. size + wxNode *node = GetChildren()->First(); + int max_width = 0; + int max_height = 0; + while (node) + { + // Find a child that's a subwindow, but not a dialog box. + wxWindow *win = (wxWindow *)node->Data(); - return TRUE; + if (!win->IsKindOf(CLASSINFO(wxFrame)) && + !win->IsKindOf(CLASSINFO(wxDialog))) + { + int width, height; + int x, y; + win->GetSize(&width, &height); + win->GetPosition(&x, &y); + + if ((x + width) > max_width) + max_width = x + width; + if ((y + height) > max_height) + max_height = y + height; + } + node = node->Next(); + } + SetClientSize(max_width, max_height); } -void wxFrame::GetClientSize( int *width, int *height ) const +// Responds to colour changes, and passes event on to children. +void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) { - wxWindow::GetClientSize( width, height ); - if (height) - { - if (m_frameMenuBar) (*height) -= wxMENU_HEIGHT; - if (m_frameStatusBar) (*height) -= wxSTATUS_HEIGHT; - if (m_frameToolBar) + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE)); + Refresh(); + + if ( m_frameStatusBar ) { - int y = 0; - m_frameToolBar->GetSize( NULL, &y ); - (*height) -= y; + wxSysColourChangedEvent event2; + event2.SetEventObject( m_frameStatusBar ); + m_frameStatusBar->ProcessEvent(event2); } - }; -}; + // Propagate the event to the non-top-level children + wxWindow::OnSysColourChanged(event); +} -void wxFrame::OnSize( wxSizeEvent &WXUNUSED(event) ) +// Default resizing behaviour - if only ONE subwindow, +// resize to client rectangle size +void wxFrame::OnSize(wxSizeEvent& event) { - if ( GetAutoLayout() ) - Layout(); - else { - // no child: go out ! - if (!GetChildren()->First()) + // if we're using constraints - do use them + #if wxUSE_CONSTRAINTS + if ( GetAutoLayout() ) { + Layout(); return; - - // do we have exactly one child? - wxWindow *child = NULL; - for(wxNode *node = GetChildren()->First(); node; node = node->Next()) + } + #endif + + // do we have _exactly_ one child? + wxWindow *child = NULL; + for ( wxNode *node = GetChildren()->First(); node; node = node->Next() ) + { + wxWindow *win = (wxWindow *)node->Data(); + if ( !win->IsKindOf(CLASSINFO(wxFrame)) && + !win->IsKindOf(CLASSINFO(wxDialog)) && + (win != GetStatusBar()) && + (win != GetToolBar()) ) { - wxWindow *win = (wxWindow *)node->Data(); - if (!IS_KIND_OF(win,wxFrame) && !IS_KIND_OF(win,wxDialog) -#if 0 // not in m_children anyway - && (win != m_frameMenuBar) && - (win != m_frameToolBar) && - (win != m_frameStatusBar) -#endif - ) - { - if ( child ) // it's the second one: do nothing - return; + if ( child ) + return; // it's our second subwindow - nothing to do + child = win; + } + } - child = win; - }; - }; + if ( child ) { + // we have exactly one child - set it's size to fill the whole frame + int clientW, clientH; + GetClientSize(&clientW, &clientH); - // yes: set it's size to fill all the frame - int client_x, client_y; - GetClientSize(&client_x, &client_y); - child->SetSize( 1, 1, client_x-2, client_y); + int x = 0; + int y = 0; + + child->SetSize(x, y, clientW, clientH); } -}; +} -static void SetInvokingWindow( wxMenu *menu, wxWindow *win ) +// Default activation behaviour - set the focus for the first child +// subwindow found. +void wxFrame::OnActivate(wxActivateEvent& event) { - menu->SetInvokingWindow( win ); - wxNode *node = menu->m_items.First(); - while (node) + for(wxNode *node = GetChildren()->First(); node; node = node->Next()) { - wxMenuItem *menuitem = (wxMenuItem*)node->Data(); - if (menuitem->IsSubMenu()) - SetInvokingWindow( menuitem->GetSubMenu(), win ); - node = node->Next(); - }; -}; + // Find a child that's a subwindow, but not a dialog box. + wxWindow *child = (wxWindow *)node->Data(); + if (!child->IsKindOf(CLASSINFO(wxFrame)) && + !child->IsKindOf(CLASSINFO(wxDialog))) + { +#if WXDEBUG > 1 + wxDebugMsg("wxFrame::OnActivate: about to set the child's focus.\n"); +#endif + child->SetFocus(); + return; + } + } +} -void wxFrame::SetMenuBar( wxMenuBar *menuBar ) +// The default implementation for the close window event. +void wxFrame::OnCloseWindow(wxCloseEvent& event) { - m_frameMenuBar = menuBar; - - if (m_frameMenuBar) + this->Destroy(); +} + +// Destroy the window (delayed, if a managed window) +bool wxFrame::Destroy() +{ + if (!wxPendingDelete.Member(this)) + wxPendingDelete.Append(this); + return TRUE; +} + +// Default menu selection behaviour - display a help string +void wxFrame::OnMenuHighlight(wxMenuEvent& event) +{ + if (GetStatusBar()) { - if (m_frameMenuBar->m_parent != this) + if (event.GetMenuId() == -1) + SetStatusText(""); + else { - wxNode *node = m_frameMenuBar->m_menus.First(); - while (node) + wxMenuBar *menuBar = GetMenuBar(); + if (menuBar) { - wxMenu *menu = (wxMenu*)node->Data(); - SetInvokingWindow( menu, this ); - node = node->Next(); - }; - + wxString helpString(menuBar->GetHelpString(event.GetMenuId())); + if (helpString != "") + SetStatusText(helpString); + } } } -}; +} -wxMenuBar *wxFrame::GetMenuBar(void) +wxMenuBar *wxFrame::GetMenuBar() const { return m_frameMenuBar; -}; +} -wxToolBar *wxFrame::CreateToolBar( long style , wxWindowID id, const wxString& name ) +void wxFrame::Centre(int direction) { - m_frameToolBar = new wxToolBar( this, id, wxDefaultPosition, wxDefaultSize, style, name ); - - return m_frameToolBar; -}; + int display_width, display_height, width, height, x, y; + wxDisplaySize(&display_width, &display_height); -wxToolBar *wxFrame::GetToolBar(void) + GetSize(&width, &height); + GetPosition(&x, &y); + + if (direction & wxHORIZONTAL) + x = (int)((display_width - width)/2); + if (direction & wxVERTICAL) + y = (int)((display_height - height)/2); + + SetSize(x, y, width, height); +} + +// Call this to simulate a menu command +void wxFrame::Command(int id) { - return m_frameToolBar; -}; + ProcessCommand(id); +} -wxStatusBar* wxFrame::CreateStatusBar( int number, long style, wxWindowID id, const wxString& name ) +void wxFrame::ProcessCommand(int id) { - if (m_frameStatusBar) - delete m_frameStatusBar; + wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, id); + commandEvent.SetInt( id ); + commandEvent.SetEventObject( this ); - m_frameStatusBar = new wxStatusBar( this, id, wxPoint(0,0), wxSize(100,20), style, name ); + wxMenuBar *bar = GetMenuBar() ; + if (!bar) + return; - m_frameStatusBar->SetFieldsCount( number ); - - return m_frameStatusBar; -}; +/* TODO: check the menu item if required + wxMenuItem *item = bar->FindItemForId(id) ; + if (item && item->IsCheckable()) + { + bar->Check(id,!bar->Checked(id)) ; + } +*/ -void wxFrame::SetStatusText( const wxString &text, int number ) -{ - if (m_frameStatusBar) m_frameStatusBar->SetStatusText( text, number ); -}; + GetEventHandler()->ProcessEvent(commandEvent); +} -void wxFrame::SetStatusWidths( int n, int *width ) +// Checks if there is a toolbar, and returns the first free client position +wxPoint wxFrame::GetClientAreaOrigin() const { - if (m_frameStatusBar) m_frameStatusBar->SetStatusWidths( n, width ); -}; + wxPoint pt(0, 0); + if (GetToolBar()) + { + int w, h; + GetToolBar()->GetSize(& w, & h); + + if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL) + { + pt.x += w; + } + else + { + pt.y += h; + } + } + return pt; +} -wxStatusBar *wxFrame::GetStatusBar(void) +wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name) { - return m_frameStatusBar; -}; + wxCHECK_MSG( m_frameToolBar == NULL, FALSE, + "recreating toolbar in wxFrame" ); -void wxFrame::SetTitle( const wxString &title ) -{ - m_title = title; -}; + wxToolBar* toolBar = OnCreateToolBar(style, id, name); + if (toolBar) + { + SetToolBar(toolBar); + PositionToolBar(); + return toolBar; + } + else + { + return NULL; + } +} -void wxFrame::SetSizeHints( int WXUNUSED(minW), int WXUNUSED(minH), - int WXUNUSED(maxW), int WXUNUSED(maxH), int WXUNUSED(incW) ) +wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name) { + return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name); } -void wxFrame::SetIcon( const wxIcon &icon ) +void wxFrame::PositionToolBar() { - m_icon = icon; - if (!icon.Ok()) return; - + int cw, ch; + + // TODO: we actually need to use the low-level client size, before + // the toolbar/status bar were added. + // So DEFINITELY replace the line below with something appropriate. + + wxCHECK_MSG( TRUE, FALSE, + "PositionToolBar not implemented properly, see frame.cpp" ); + + GetClientSize(& cw, &ch); + + if ( GetStatusBar() ) + { + int statusX, statusY; + GetStatusBar()->GetClientSize(&statusX, &statusY); + ch -= statusY; + } + + if (GetToolBar()) + { + int tw, th; + GetToolBar()->GetSize(& tw, & th); + + if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL) + { + // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS + // means, pretend we don't have toolbar/status bar, so we + // have the original client size. + GetToolBar()->SetSize(0, 0, tw, ch, wxSIZE_NO_ADJUSTMENTS); + } + else + { + // Use the 'real' position + GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS); + } + } }