X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7a5a5718592cb0873374e6ebc66d12a153d5acea..133506215101bd8cffbf81e6c36944f7d5e2f8db:/src/msw/stattext.cpp diff --git a/src/msw/stattext.cpp b/src/msw/stattext.cpp index 12b7403018..1309628465 100644 --- a/src/msw/stattext.cpp +++ b/src/msw/stattext.cpp @@ -9,10 +9,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "stattext.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -22,15 +18,17 @@ #if wxUSE_STATTEXT +#include "wx/stattext.h" + #ifndef WX_PRECOMP -#include "wx/event.h" -#include "wx/app.h" -#include "wx/brush.h" + #include "wx/event.h" + #include "wx/app.h" + #include "wx/brush.h" + #include "wx/dcclient.h" + #include "wx/settings.h" #endif -#include "wx/stattext.h" #include "wx/msw/private.h" -#include #if wxUSE_EXTENDED_RTTI WX_DEFINE_FLAGS( wxStaticTextStyle ) @@ -44,7 +42,7 @@ wxBEGIN_FLAGS( wxStaticTextStyle ) wxFLAGS_MEMBER(wxBORDER_RAISED) wxFLAGS_MEMBER(wxBORDER_STATIC) wxFLAGS_MEMBER(wxBORDER_NONE) - + // old style border flags wxFLAGS_MEMBER(wxSIMPLE_BORDER) wxFLAGS_MEMBER(wxSUNKEN_BORDER) @@ -73,14 +71,14 @@ wxEND_FLAGS( wxStaticTextStyle ) IMPLEMENT_DYNAMIC_CLASS_XTI(wxStaticText, wxControl,"wx/stattext.h") wxBEGIN_PROPERTIES_TABLE(wxStaticText) - wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) + wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) wxPROPERTY_FLAGS( WindowStyle , wxStaticTextStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style wxEND_PROPERTIES_TABLE() wxBEGIN_HANDLERS_TABLE(wxStaticText) wxEND_HANDLERS_TABLE() -wxCONSTRUCTOR_6( wxStaticText , wxWindow* , Parent , wxWindowID , Id , wxString , Label , wxPoint , Position , wxSize , Size , long , WindowStyle ) +wxCONSTRUCTOR_6( wxStaticText , wxWindow* , Parent , wxWindowID , Id , wxString , Label , wxPoint , Position , wxSize , Size , long , WindowStyle ) #else IMPLEMENT_DYNAMIC_CLASS(wxStaticText, wxControl) #endif @@ -94,17 +92,26 @@ bool wxStaticText::Create(wxWindow *parent, const wxString& name) { if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) ) - return FALSE; + return false; - if ( !MSWCreateControl(wxT("STATIC"), label, pos, size) ) - return FALSE; + if ( !MSWCreateControl(wxT("STATIC"), wxEmptyString, pos, size) ) + return false; - return TRUE; -} + // we set the label here and not through MSWCreateControl() because we + // need to do many operation on it for ellipsization&markup support + SetLabel(label); -wxBorder wxStaticText::GetDefaultBorder() const -{ - return wxBORDER_NONE; + // as we didn't pass the correct label to MSWCreateControl(), it didn't set + // the initial size correctly -- do it now + InvalidateBestSize(); + SetInitialSize(size); + + // NOTE: if the label contains ampersand characters which are interpreted as + // accelerators, they will be rendered (at least on WinXP) only if the + // static text is placed inside a window class which correctly handles + // focusing by TAB traversal (e.g. wxPanel). + + return true; } WXDWORD wxStaticText::MSWGetStyle(long style, WXDWORD *exstyle) const @@ -122,118 +129,140 @@ WXDWORD wxStaticText::MSWGetStyle(long style, WXDWORD *exstyle) const else msStyle |= SS_LEFT; +#ifdef SS_ENDELLIPSIS + // this style is necessary to receive mouse events + // Win NT and later have the SS_ENDELLIPSIS style which is useful to us: + if (wxGetOsVersion() == wxOS_WINDOWS_NT) + { + // for now, add the SS_ENDELLIPSIS style if wxST_ELLIPSIZE_END is given; + // we may need to remove it later in ::SetLabel() if the given label + // has newlines + if ( style & wxST_ELLIPSIZE_END ) + msStyle |= SS_ENDELLIPSIS; + } +#endif // SS_ENDELLIPSIS + + msStyle |= SS_NOTIFY; + return msStyle; } -wxSize wxStaticText::DoGetBestSize() const +wxSize wxStaticText::DoGetBestClientSize() const { - wxString text(wxGetWindowText(GetHWND())); + wxClientDC dc(const_cast(this)); + wxFont font(GetFont()); + if (!font.Ok()) + font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - int widthTextMax = 0, widthLine, - heightTextTotal = 0, heightLineDefault = 0, heightLine = 0; + dc.SetFont(font); - bool lastWasAmpersand = FALSE; + wxCoord widthTextMax, heightTextTotal; + dc.GetMultiLineTextExtent(GetLabelText(), &widthTextMax, &heightTextTotal); - wxString curLine; - for ( const wxChar *pc = text; ; pc++ ) - { - if ( *pc == wxT('\n') || *pc == wxT('\0') ) - { - if ( !curLine ) - { - // we can't use GetTextExtent - it will return 0 for both width - // and height and an empty line should count in height - // calculation - if ( !heightLineDefault ) - heightLineDefault = heightLine; - if ( !heightLineDefault ) - GetTextExtent(_T("W"), NULL, &heightLineDefault); - - heightTextTotal += heightLineDefault; - } - else - { - GetTextExtent(curLine, &widthLine, &heightLine); - if ( widthLine > widthTextMax ) - widthTextMax = widthLine; - heightTextTotal += heightLine; - } - - if ( *pc == wxT('\n') ) - { - curLine.Empty(); - } - else - { - // the end of string - break; - } - } - else - { - // we shouldn't take into account the '&' which just introduces the - // mnemonic characters and so are not shown on the screen -- except - // when it is preceded by another '&' in which case it stands for a - // literal ampersand - if ( *pc == _T('&') ) - { - if ( !lastWasAmpersand ) - { - lastWasAmpersand = TRUE; - - // skip the statement adding pc to curLine below - continue; - } - - // it is a literal ampersand - lastWasAmpersand = FALSE; - } - - curLine += *pc; - } - } #ifdef __WXWINCE__ - if(widthTextMax) widthTextMax += 2; -#endif + if ( widthTextMax ) + widthTextMax += 2; +#endif // __WXWINCE__ + return wxSize(widthTextMax, heightTextTotal); } void wxStaticText::DoSetSize(int x, int y, int w, int h, int sizeFlags) { - // we need to refresh the window after changing its size as the standard - // control doesn't always update itself properly + // note: we first need to set the size and _then_ call UpdateLabel wxStaticTextBase::DoSetSize(x, y, w, h, sizeFlags); +#ifdef SS_ENDELLIPSIS + // do we need to ellipsize the contents? + long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE); + if ( !(styleReal & SS_ENDELLIPSIS) ) + { + // we don't have SS_ENDELLIPSIS style: + // we need to (eventually) do ellipsization ourselves + UpdateLabel(); + } + //else: we don't or the OS will do it for us +#endif // SS_ENDELLIPSIS + + // we need to refresh the window after changing its size as the standard + // control doesn't always update itself properly Refresh(); } void wxStaticText::SetLabel(const wxString& label) { - wxStaticTextBase::SetLabel(label); +#ifdef SS_ENDELLIPSIS + long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE); + if ( HasFlag(wxST_ELLIPSIZE_END) && + wxGetOsVersion() == wxOS_WINDOWS_NT ) + { + // adding SS_ENDELLIPSIS or SS_ENDELLIPSIS "disables" the correct + // newline handling in static texts: the newlines in the labels are + // shown as square. Thus we don't use it even on newer OS when + // the static label contains a newline. + if ( label.Contains(wxT('\n')) ) + styleReal &= ~SS_ENDELLIPSIS; + else + styleReal |= SS_ENDELLIPSIS; + + ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal); + } + else // style not supported natively + { + styleReal &= ~SS_ENDELLIPSIS; + ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal); + } +#endif // SS_ENDELLIPSIS + + // save the label in m_labelOrig with both the markup (if any) and + // the mnemonics characters (if any) + m_labelOrig = label; + +#ifdef SS_ENDELLIPSIS + if ( styleReal & SS_ENDELLIPSIS ) + DoSetLabel(GetLabelWithoutMarkup()); + else +#endif // SS_ENDELLIPSIS + DoSetLabel(GetEllipsizedLabelWithoutMarkup()); // adjust the size of the window to fit to the label unless autoresizing is // disabled - if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) ) + if ( !HasFlag(wxST_NO_AUTORESIZE) && + !IsEllipsized() ) // if ellipsize is ON, then we don't want to get resized! { - DoSetSize(-1, -1, -1, -1, wxSIZE_AUTO_WIDTH | wxSIZE_AUTO_HEIGHT); - SetSizeHints(GetSize()); + InvalidateBestSize(); + DoSetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, + wxSIZE_AUTO_WIDTH | wxSIZE_AUTO_HEIGHT); } } - bool wxStaticText::SetFont(const wxFont& font) { bool ret = wxControl::SetFont(font); // adjust the size of the window to fit to the label unless autoresizing is // disabled - if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) ) + if ( !HasFlag(wxST_NO_AUTORESIZE) ) { - DoSetSize(-1, -1, -1, -1, wxSIZE_AUTO_WIDTH | wxSIZE_AUTO_HEIGHT); - SetSizeHints(GetSize()); + InvalidateBestSize(); + DoSetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, + wxSIZE_AUTO_WIDTH | wxSIZE_AUTO_HEIGHT); } return ret; } +// for wxST_ELLIPSIZE_* support: + +wxString wxStaticText::DoGetLabel() const +{ + return wxGetWindowText(GetHwnd()); +} + +void wxStaticText::DoSetLabel(const wxString& str) +{ + SetWindowText(GetHwnd(), str.c_str()); +} + + #endif // wxUSE_STATTEXT