X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cbab1556578ae39b1f00e0c4f6ca8016ac8124ac..af6da66ce3c22b083d4f8b8f7d8e5b34bda18db0:/src/common/wincmn.cpp diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 6b8a69a150..63bc0450f6 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -73,6 +73,11 @@ #endif #include "wx/platinfo.h" +#include "wx/private/window.h" + +#ifdef __WXMSW__ + #include "wx/msw/wrapwin.h" +#endif // Windows List WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows; @@ -359,8 +364,7 @@ wxWindowBase::~wxWindowBase() // This removes any dangling pointers to this window in other windows' // constraintsInvolvedIn lists. UnsetConstraints(m_constraints); - delete m_constraints; - m_constraints = NULL; + wxDELETE(m_constraints); } #endif // wxUSE_CONSTRAINTS @@ -732,17 +736,14 @@ wxSize wxWindowBase::GetEffectiveMinSize() const wxSize wxWindowBase::DoGetBorderSize() const { - // there is one case in which we can implement it for all ports easily: - // do it as some classes used by both wxUniv and native ports (e.g. - // wxGenericStaticText) do override DoGetBestClientSize() and so this - // method must work for them and that ensures that it does, at least in - // the default case) + // there is one case in which we can implement it for all ports easily if ( GetBorder() == wxBORDER_NONE ) return wxSize(0, 0); - wxFAIL_MSG( "must be overridden if called" ); - - return wxDefaultSize; + // otherwise use the difference between the real size and the client size + // as a fallback: notice that this is incorrect in general as client size + // also doesn't take the scrollbars into account + return GetSize() - GetClientSize(); } wxSize wxWindowBase::GetBestSize() const @@ -835,18 +836,15 @@ void wxWindowBase::DoSetWindowVariant( wxWindowVariant variant ) break; case wxWINDOW_VARIANT_SMALL: - size *= 3; - size /= 4; + size = wxRound(size * 3.0 / 4.0); break; case wxWINDOW_VARIANT_MINI: - size *= 2; - size /= 3; + size = wxRound(size * 2.0 / 3.0); break; case wxWINDOW_VARIANT_LARGE: - size *= 5; - size /= 4; + size = wxRound(size * 5.0 / 4.0); break; default: @@ -1249,8 +1247,7 @@ wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler) if ( deleteHandler ) { - delete firstHandler; - firstHandler = NULL; + wxDELETE(firstHandler); } return firstHandler; @@ -1270,7 +1267,7 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handlerToRemove) // NOTE: the wxWindow event handler list is always terminated with "this" handler wxEvtHandler *handlerCur = GetEventHandler()->GetNextHandler(); - while ( handlerCur != this ) + while ( handlerCur != this && handlerCur ) { wxEvtHandler *handlerNext = handlerCur->GetNextHandler(); @@ -2071,8 +2068,7 @@ void wxWindowBase::DeleteRelatedConstraints() node = next; } - delete m_constraintsInvolvedIn; - m_constraintsInvolvedIn = NULL; + wxDELETE(m_constraintsInvolvedIn); } } @@ -2292,7 +2288,9 @@ void wxWindowBase::SetConstraintSizes(bool recurse) if ( (constr->width.GetRelationship() != wxAsIs ) || (constr->height.GetRelationship() != wxAsIs) ) { - SetSize(x, y, w, h); + // We really shouldn't set negative sizes for the windows so make + // them at least of 1*1 size + SetSize(x, y, w > 0 ? w : 1, h > 0 ? h : 1); } else { @@ -2461,28 +2459,57 @@ void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event) // dialog units translations // ---------------------------------------------------------------------------- -wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) +// Windows' computes dialog units using average character width over upper- +// and lower-case ASCII alphabet and not using the average character width +// metadata stored in the font; see +// http://support.microsoft.com/default.aspx/kb/145994 for detailed discussion. +// It's important that we perform the conversion in identical way, because +// dialog units natively exist only on Windows and Windows HIG is expressed +// using them. +wxSize wxWindowBase::GetDlgUnitBase() const { - int charWidth = GetCharWidth(); - int charHeight = GetCharHeight(); + const wxWindow *parent = wxGetTopLevelParent((wxWindow*)this); + + if ( !parent->m_font.IsOk() ) + { + // Default GUI font is used. This is the most common case, so + // cache the results. + static wxSize s_defFontSize; + if ( s_defFontSize.x == 0 ) + s_defFontSize = wxPrivate::GetAverageASCIILetterSize(*parent); + return s_defFontSize; + } + else + { + // Custom font, we always need to compute the result + return wxPrivate::GetAverageASCIILetterSize(*parent); + } +} + +wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) const +{ + const wxSize base = GetDlgUnitBase(); + + // NB: wxMulDivInt32() is used, because it correctly rounds the result + wxPoint pt2 = wxDefaultPosition; if (pt.x != wxDefaultCoord) - pt2.x = (int) ((pt.x * 4) / charWidth); + pt2.x = wxMulDivInt32(pt.x, 4, base.x); if (pt.y != wxDefaultCoord) - pt2.y = (int) ((pt.y * 8) / charHeight); + pt2.y = wxMulDivInt32(pt.y, 8, base.y); return pt2; } -wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) +wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) const { - int charWidth = GetCharWidth(); - int charHeight = GetCharHeight(); + const wxSize base = GetDlgUnitBase(); + wxPoint pt2 = wxDefaultPosition; if (pt.x != wxDefaultCoord) - pt2.x = (int) ((pt.x * charWidth) / 4); + pt2.x = wxMulDivInt32(pt.x, base.x, 4); if (pt.y != wxDefaultCoord) - pt2.y = (int) ((pt.y * charHeight) / 8); + pt2.y = wxMulDivInt32(pt.y, base.y, 8); return pt2; } @@ -2533,6 +2560,9 @@ bool wxWindowBase::PopupMenu(wxMenu *menu, int x, int y) { wxCHECK_MSG( menu, false, "can't popup NULL menu" ); + wxMenuInvokingWindowSetter + setInvokingWin(*menu, static_cast(this)); + wxCurrentPopupMenu = menu; const bool rc = DoPopupMenu(menu, x, y); wxCurrentPopupMenu = NULL; @@ -2946,7 +2976,7 @@ bool wxWindowBase::TryBefore(wxEvent& event) if ( event.GetEventObject() == this ) { wxValidator * const validator = GetValidator(); - if ( validator && validator->ProcessEventHere(event) ) + if ( validator && validator->ProcessEventLocally(event) ) { return true; }