X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ed2fbeb835854c97d176f8bdfd6f06a84273f5d7..82c591d771cb651b7d54e1eada7c33da962e3831:/src/common/wincmn.cpp diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index b485672dcc..f67a25267f 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -83,6 +83,8 @@ extern const unsigned int gtk_micro_version; #endif +#include "wx/platinfo.h" + // Windows List WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows; @@ -198,6 +200,8 @@ wxWindowBase::wxWindowBase() m_virtualSize = wxDefaultSize; + m_scrollHelper = (wxScrollHelper *) NULL; + m_minVirtualWidth = m_maxVirtualWidth = wxDefaultCoord; m_minVirtualHeight = @@ -288,14 +292,21 @@ wxWindowBase::~wxWindowBase() wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") ); - // reset the dangling pointer our parent window may keep to us + // reset the top-level parent's default item if it is this widget if ( m_parent ) { - if ( m_parent->GetDefaultItem() == this ) - { - m_parent->SetDefaultItem(NULL); - } + wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent((wxWindow*)this), + wxTopLevelWindow); + + if ( tlw && tlw->GetDefaultItem() == this ) + tlw->SetDefaultItem(NULL); + if ( tlw && tlw->GetTmpDefaultItem() == this ) + tlw->SetTmpDefaultItem(NULL); + } + // reset the dangling pointer our parent window may keep to us + if ( m_parent ) + { m_parent->RemoveChild(this); } @@ -401,7 +412,7 @@ void wxWindowBase::Fit() { if ( !GetChildren().empty() ) { - SetClientSize(GetBestSize()); + SetSize(GetBestSize()); } //else: do nothing if we have no children } @@ -497,7 +508,8 @@ wxSize wxWindowBase::DoGetBestSize() const #endif ) { - // our minimal acceptable size is such that all our visible child windows fit inside + // our minimal acceptable size is such that all our visible child + // windows fit inside int maxX = 0, maxY = 0; @@ -506,9 +518,10 @@ wxSize wxWindowBase::DoGetBestSize() const node = node->GetNext() ) { wxWindow *win = node->GetData(); - if ( win->IsTopLevel() || ( ! win->IsShown() ) + if ( win->IsTopLevel() + || !win->IsShown() #if wxUSE_STATUSBAR - || wxDynamicCast(win, wxStatusBar) + || wxDynamicCast(win, wxStatusBar) #endif // wxUSE_STATUSBAR ) { @@ -535,11 +548,6 @@ wxSize wxWindowBase::DoGetBestSize() const maxY = wy + wh; } - // for compatibility with the old versions and because it really looks - // slightly more pretty like this, add a pad - maxX += 7; - maxY += 14; - best = wxSize(maxX, maxY); } else // ! has children @@ -572,7 +580,7 @@ wxSize wxWindowBase::DoGetBestSize() const } -wxSize wxWindowBase::GetBestFittingSize() const +wxSize wxWindowBase::GetEffectiveMinSize() const { // merge the best size with the min size, giving priority to the min size wxSize min = GetMinSize(); @@ -586,14 +594,14 @@ wxSize wxWindowBase::GetBestFittingSize() const } -void wxWindowBase::SetBestFittingSize(const wxSize& size) +void wxWindowBase::SetInitialSize(const wxSize& size) { // Set the min size to the size passed in. This will usually either be // wxDefaultSize or the size passed to this window's ctor/Create function. SetMinSize(size); // Merge the size with the best size if needed - wxSize best = GetBestFittingSize(); + wxSize best = GetEffectiveMinSize(); // If the current size doesn't match then change it if (GetSize() != best) @@ -607,23 +615,6 @@ wxPoint wxWindowBase::GetClientAreaOrigin() const return wxPoint(0,0); } -// set the min/max size of the window -void wxWindowBase::DoSetSizeHints(int minW, int minH, - int maxW, int maxH, - int WXUNUSED(incW), int WXUNUSED(incH)) -{ - // setting min width greater than max width leads to infinite loops under - // X11 and generally doesn't make any sense, so don't allow it - wxCHECK_RET( (minW == wxDefaultCoord || maxW == wxDefaultCoord || minW <= maxW) && - (minH == wxDefaultCoord || maxH == wxDefaultCoord || minH <= maxH), - _T("min width/height must be less than max width/height!") ); - - m_minWidth = minW; - m_maxWidth = maxW; - m_minHeight = minH; - m_maxHeight = maxH; -} - void wxWindowBase::SetWindowVariant( wxWindowVariant variant ) { if ( m_windowVariant != variant ) @@ -669,6 +660,21 @@ void wxWindowBase::DoSetWindowVariant( wxWindowVariant variant ) SetFont(font); } +void wxWindowBase::DoSetSizeHints( int minW, int minH, + int maxW, int maxH, + int WXUNUSED(incW), int WXUNUSED(incH) ) +{ + wxCHECK_RET( (minW == wxDefaultCoord || maxW == wxDefaultCoord || minW <= maxW) && + (minH == wxDefaultCoord || maxH == wxDefaultCoord || minH <= maxH), + _T("min width/height must be less than max width/height!") ); + + m_minWidth = minW; + m_maxWidth = maxW; + m_minHeight = minH; + m_maxHeight = maxH; +} + + void wxWindowBase::SetVirtualSizeHints( int minW, int minH, int maxW, int maxH ) { @@ -750,6 +756,13 @@ bool wxWindowBase::Enable(bool enable) return false; } } + +bool wxWindowBase::IsShownOnScreen() const +{ + return IsShown() && + (GetParent() == NULL || GetParent()->IsShownOnScreen()); +} + // ---------------------------------------------------------------------------- // RTTI // ---------------------------------------------------------------------------- @@ -1025,7 +1038,7 @@ bool wxWindowBase::SetCursor(const wxCursor& cursor) { // setting an invalid cursor is ok, it means that we don't have any special // cursor - if ( m_cursor == cursor ) + if ( m_cursor.IsSameAs(cursor) ) { // no change return false; @@ -1146,12 +1159,12 @@ wxRect wxWindowBase::GetUpdateClientRect() const return rectUpdate; } -bool wxWindowBase::IsExposed(int x, int y) const +bool wxWindowBase::DoIsExposed(int x, int y) const { return m_updateRegion.Contains(x, y) != wxOutRegion; } -bool wxWindowBase::IsExposed(int x, int y, int w, int h) const +bool wxWindowBase::DoIsExposed(int x, int y, int w, int h) const { return m_updateRegion.Contains(x, y, w, h) != wxOutRegion; } @@ -1469,7 +1482,10 @@ void wxWindowBase::SetHelpTextForId(const wxString& text) } // get the help string associated with this window (may be empty) -wxString wxWindowBase::GetHelpText() const +// default implementation forwards calls to the help provider +wxString +wxWindowBase::GetHelpTextAtPoint(const wxPoint & WXUNUSED(pt), + wxHelpEvent::Origin WXUNUSED(origin)) const { wxString text; wxHelpProvider *helpProvider = wxHelpProvider::Get(); @@ -1487,7 +1503,7 @@ void wxWindowBase::OnHelp(wxHelpEvent& event) wxHelpProvider *helpProvider = wxHelpProvider::Get(); if ( helpProvider ) { - if ( helpProvider->ShowHelp(this) ) + if ( helpProvider->ShowHelpAtPoint(this, event.GetPosition(), event.GetOrigin()) ) { // skip the event.Skip() below return; @@ -1653,12 +1669,21 @@ void wxWindowBase::SetSizer(wxSizer *sizer, bool deleteOld) if ( sizer == m_windowSizer) return; - if ( deleteOld ) - delete m_windowSizer; + if ( m_windowSizer ) + { + m_windowSizer->SetContainingWindow(NULL); + + if ( deleteOld ) + delete m_windowSizer; + } m_windowSizer = sizer; + if ( m_windowSizer ) + { + m_windowSizer->SetContainingWindow((wxWindow *)this); + } - SetAutoLayout( sizer != NULL ); + SetAutoLayout(m_windowSizer != NULL); } void wxWindowBase::SetSizerAndFit(wxSizer *sizer, bool deleteOld) @@ -2169,69 +2194,38 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event ) #endif // __WXDEBUG__ #if wxUSE_MSGDLG - // don't translate these strings - wxString port; - -#ifdef __WXUNIVERSAL__ - port = _T("Univ/"); -#endif // __WXUNIVERSAL__ - - switch ( wxGetOsVersion() ) - { - case wxMOTIF_X: port += _T("Motif"); break; - case wxMAC: - case wxMAC_DARWIN: port += _T("Mac"); break; - case wxBEOS: port += _T("BeOS"); break; - case wxGTK: - case wxGTK_WIN32: - case wxGTK_OS2: - case wxGTK_BEOS: port += _T("GTK"); break; - case wxWINDOWS: - case wxPENWINDOWS: - case wxWINDOWS_NT: - case wxWIN32S: - case wxWIN95: - case wxWIN386: port += _T("MS Windows"); break; - case wxMGL_UNIX: - case wxMGL_X: - case wxMGL_WIN32: - case wxMGL_OS2: port += _T("MGL"); break; - case wxWINDOWS_OS2: - case wxOS2_PM: port += _T("OS/2"); break; - case wxPALMOS: port += _T("Palm OS"); break; - case wxWINDOWS_CE: port += _T("Windows CE (generic)"); break; - case wxWINDOWS_POCKETPC: port += _T("Windows CE PocketPC"); break; - case wxWINDOWS_SMARTPHONE: port += _T("Windows CE Smartphone"); break; - default: port += _T("unknown"); break; - } - - wxMessageBox(wxString::Format( - _T( - " wxWidgets Library (%s port)\nVersion %d.%d.%d%s%s, compiled at %s %s%s\n Copyright (c) 1995-2006 wxWidgets team" - ), - port.c_str(), - wxMAJOR_VERSION, - wxMINOR_VERSION, - wxRELEASE_NUMBER, + // don't translate these strings, they're for diagnostics purposes only + wxString msg; + msg.Printf(_T("wxWidgets Library (%s port)\n") + _T("Version %d.%d.%d%s%s, compiled at %s %s\n") + _T("Runtime version of toolkit used is %d.%d.%s\n") + _T("Copyright (c) 1995-2006 wxWidgets team"), + wxPlatformInfo::Get().GetPortIdName().c_str(), + wxMAJOR_VERSION, + wxMINOR_VERSION, + wxRELEASE_NUMBER, #if wxUSE_UNICODE - L" (Unicode)", + L" (Unicode)", #else - "", + wxEmptyString, #endif #ifdef __WXDEBUG__ - _T(" Debug build"), + _T(" Debug build"), #else - wxEmptyString, + wxEmptyString, #endif - __TDATE__, - __TTIME__, + __TDATE__, + __TTIME__, + wxPlatformInfo::Get().GetToolkitMajorVersion(), + wxPlatformInfo::Get().GetToolkitMinorVersion(), #ifdef __WXGTK__ - wxString::Format(_T("\nagainst GTK+ %d.%d.%d. Runtime GTK+ version: %d.%d.%d"), GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION, gtk_major_version, gtk_minor_version, gtk_micro_version).c_str() + wxString::Format(_T("\nThe compile-time GTK+ version is %d.%d.%d."), GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION).c_str() #else - "" + wxEmptyString #endif - ), - _T("wxWidgets information"), + ); + + wxMessageBox(msg, _T("wxWidgets information"), wxICON_INFORMATION | wxOK, (wxWindow *)this); } @@ -2339,10 +2333,16 @@ struct WXDLLEXPORT wxWindowNext wxWindow *win; wxWindowNext *next; } *wxWindowBase::ms_winCaptureNext = NULL; +wxWindow *wxWindowBase::ms_winCaptureCurrent = NULL; +bool wxWindowBase::ms_winCaptureChanging = false; void wxWindowBase::CaptureMouse() { - wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), this); + wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), wx_static_cast(void*, this)); + + wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive CaptureMouse call?") ); + + ms_winCaptureChanging = true; wxWindow *winOld = GetCapture(); if ( winOld ) @@ -2358,19 +2358,28 @@ void wxWindowBase::CaptureMouse() //else: no mouse capture to save DoCaptureMouse(); + ms_winCaptureCurrent = (wxWindow*)this; + + ms_winCaptureChanging = false; } void wxWindowBase::ReleaseMouse() { - wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), this); + wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), wx_static_cast(void*, this)); + + wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive ReleaseMouse call?") ); wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") ); + ms_winCaptureChanging = true; + DoReleaseMouse(); + ms_winCaptureCurrent = NULL; if ( ms_winCaptureNext ) { ((wxWindowBase*)ms_winCaptureNext->win)->DoCaptureMouse(); + ms_winCaptureCurrent = ms_winCaptureNext->win; wxWindowNext *item = ms_winCaptureNext; ms_winCaptureNext = item->next; @@ -2378,9 +2387,49 @@ void wxWindowBase::ReleaseMouse() } //else: stack is empty, no previous capture + ms_winCaptureChanging = false; + wxLogTrace(_T("mousecapture"), (const wxChar *) _T("After ReleaseMouse() mouse is captured by %p"), - GetCapture()); + wx_static_cast(void*, GetCapture())); +} + +static void DoNotifyWindowAboutCaptureLost(wxWindow *win) +{ + wxMouseCaptureLostEvent event(win->GetId()); + event.SetEventObject(win); + if ( !win->GetEventHandler()->ProcessEvent(event) ) + { + wxFAIL_MSG( _T("window that captured the mouse didn't process wxEVT_MOUSE_CAPTURE_LOST") ); + } +} + +/* static */ +void wxWindowBase::NotifyCaptureLost() +{ + // don't do anything if capture lost was expected, i.e. resulted from + // a wx call to ReleaseMouse or CaptureMouse: + if ( ms_winCaptureChanging ) + return; + + // if the capture was lost unexpectedly, notify every window that has + // capture (on stack or current) about it and clear the stack: + + if ( ms_winCaptureCurrent ) + { + DoNotifyWindowAboutCaptureLost(ms_winCaptureCurrent); + ms_winCaptureCurrent = NULL; + } + + while ( ms_winCaptureNext ) + { + wxWindowNext *item = ms_winCaptureNext; + ms_winCaptureNext = item->next; + + DoNotifyWindowAboutCaptureLost(item->win); + + delete item; + } } #if wxUSE_HOTKEY @@ -2801,7 +2850,7 @@ wxAccStatus wxWindowAccessible::GetDescription(int WXUNUSED(childId), wxString* if (!GetWindow()) return wxACC_FAIL; - wxString ht(GetWindow()->GetHelpText()); + wxString ht(GetWindow()->GetHelpTextAtPoint(wxDefaultPosition, wxHelpEvent::Origin_Keyboard)); if (!ht.empty()) { *description = ht; @@ -2817,7 +2866,7 @@ wxAccStatus wxWindowAccessible::GetHelpText(int WXUNUSED(childId), wxString* hel if (!GetWindow()) return wxACC_FAIL; - wxString ht(GetWindow()->GetHelpText()); + wxString ht(GetWindow()->GetHelpTextAtPoint(wxDefaultPosition, wxHelpEvent::Origin_Keyboard)); if (!ht.empty()) { *helpText = ht; @@ -2935,6 +2984,7 @@ wxAccStatus wxWindowAccessible::GetFocus(int* WXUNUSED(childId), wxAccessible** return wxACC_NOT_IMPLEMENTED; } +#if wxUSE_VARIANT // Gets a variant representing the selected children // of this object. // Acceptable values: @@ -2951,5 +3001,24 @@ wxAccStatus wxWindowAccessible::GetSelections(wxVariant* WXUNUSED(selections)) return wxACC_NOT_IMPLEMENTED; } +#endif // wxUSE_VARIANT #endif // wxUSE_ACCESSIBILITY + +// ---------------------------------------------------------------------------- +// RTL support +// ---------------------------------------------------------------------------- + +wxCoord +wxWindowBase::AdjustForLayoutDirection(wxCoord x, + wxCoord width, + wxCoord widthTotal) const +{ + if ( GetLayoutDirection() == wxLayout_RightToLeft ) + { + x = widthTotal - x - width; + } + + return x; +} +