From 1ab3bacfc12baaa4307f2902568fdc671a0be5a7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 12 Dec 2024 20:33:46 +0100 Subject: [PATCH 1/4] Remove redundant wxMarkupText::SetMarkup() This does the same thing as the function inherited from the base class, so just remove it. --- include/wx/generic/private/markuptext.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/wx/generic/private/markuptext.h b/include/wx/generic/private/markuptext.h index 0fe10978f495..d4fa61f3f036 100644 --- a/include/wx/generic/private/markuptext.h +++ b/include/wx/generic/private/markuptext.h @@ -81,11 +81,6 @@ class WXDLLIMPEXP_CORE wxMarkupText : public wxMarkupTextBase // Default copy ctor, assignment operator and dtor are ok. - // Update the markup string. - // - // The same rules for mnemonics as in the ctor apply to this string. - void SetMarkup(const wxString& markup) { m_markup = markup; } - // Render the markup string into the given DC in the specified rectangle. // // Notice that while the function uses the provided rectangle for alignment From 6df975fdb23819a74cd8925c71e788cf5549bbb6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 12 Dec 2024 20:34:19 +0100 Subject: [PATCH 2/4] Allow to check if wxMarkupText has changed when setting it This can/will be used for avoidiing to do anything if the markup hasn't really changed. --- include/wx/generic/private/markuptext.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/wx/generic/private/markuptext.h b/include/wx/generic/private/markuptext.h index d4fa61f3f036..a0d5bfc8d167 100644 --- a/include/wx/generic/private/markuptext.h +++ b/include/wx/generic/private/markuptext.h @@ -27,8 +27,16 @@ class WXDLLIMPEXP_CORE wxMarkupTextBase public: virtual ~wxMarkupTextBase() = default; - // Update the markup string. - void SetMarkup(const wxString& markup) { m_markup = markup; } + // Update the markup string, return false if it didn't change. + bool SetMarkup(const wxString& markup) + { + if ( markup == m_markup ) + return false; + + m_markup = markup; + + return true; + } // Return the width and height required by the given string and optionally // the height of the visible part above the baseline (i.e. ascent minus From 79a45dd8d7188c6829e99dfda5eeb1ef73b408ab Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 12 Dec 2024 20:35:25 +0100 Subject: [PATCH 3/4] Avoid refreshing wxGenericStaticText if its markup didn't change For consistency with SetLabel(), and because this is generally more useful, don't do anything in SetLabelMarkup() if the markup didn't change. --- src/generic/stattextg.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/generic/stattextg.cpp b/src/generic/stattextg.cpp index 5e920cf1fad2..2d9eb4fb099f 100644 --- a/src/generic/stattextg.cpp +++ b/src/generic/stattextg.cpp @@ -124,10 +124,11 @@ bool wxGenericStaticText::DoSetLabelMarkup(const wxString& markup) if ( !wxStaticTextBase::DoSetLabelMarkup(markup) ) return false; + if ( m_markupText && !m_markupText->SetMarkup(markup) ) + return true; + if ( !m_markupText ) m_markupText = new wxMarkupText(markup); - else - m_markupText->SetMarkup(markup); AutoResizeIfNecessary(); From 9aedc796b2749a8703bae41a7f2c7e0eb870d12f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 12 Dec 2024 18:26:14 +0100 Subject: [PATCH 4/4] Implement support for markup in wxMSW wxStaticText Use generic-like implementation, i.e. simply draw the label ourselves in this case. --- include/wx/msw/stattext.h | 11 +++++ interface/wx/control.h | 7 ++- src/msw/stattext.cpp | 94 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/include/wx/msw/stattext.h b/include/wx/msw/stattext.h index 7c1b0ff08d30..2f1cf0a2767c 100644 --- a/include/wx/msw/stattext.h +++ b/include/wx/msw/stattext.h @@ -42,6 +42,10 @@ class WXDLLIMPEXP_CORE wxStaticText : public wxStaticTextBase protected: // implement/override some base class virtuals +#if wxUSE_MARKUP + virtual bool DoSetLabelMarkup(const wxString& markup) override; +#endif // wxUSE_MARKUP + virtual void DoSetSize(int x, int y, int w, int h, int sizeFlags = wxSIZE_AUTO) override; virtual wxSize DoGetBestClientSize() const override; @@ -54,6 +58,13 @@ class WXDLLIMPEXP_CORE wxStaticText : public wxStaticTextBase virtual wxString WXGetVisibleLabel() const override; virtual void WXSetVisibleLabel(const wxString& str) override; +#if wxUSE_MARKUP + class wxMarkupText* m_markupText = nullptr; + + // This is only used when m_markupText is non-null. + void WXOnPaint(wxPaintEvent& event); +#endif // wxUSE_MARKUP + wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticText); }; diff --git a/interface/wx/control.h b/interface/wx/control.h index 0441883ef933..e6eaf2741525 100644 --- a/interface/wx/control.h +++ b/interface/wx/control.h @@ -342,10 +342,9 @@ class wxControl : public wxWindow remains unchanged. - Currently wxButton supports markup in all major ports (wxMSW, wxGTK and - wxOSX/Cocoa) while wxStaticText supports it in wxGTK and wxOSX and its - generic version (which can be used under MSW if markup support is - required). Extending support to more controls is planned in the future. + Currently wxButton and wxStaticText support markup in all major ports + (wxMSW, wxGTK and wxOSX/Cocoa). Extending support to more controls is + planned in the future. @since 2.9.2 */ diff --git a/src/msw/stattext.cpp b/src/msw/stattext.cpp index bac32bc1836a..13c41a5bede3 100644 --- a/src/msw/stattext.cpp +++ b/src/msw/stattext.cpp @@ -27,6 +27,10 @@ #include "wx/msw/private/darkmode.h" #include "wx/msw/private/winstyle.h" +#if wxUSE_MARKUP + #include "wx/generic/private/markuptext.h" +#endif // wxUSE_MARKUP + bool wxStaticText::Create(wxWindow *parent, wxWindowID id, const wxString& label, @@ -163,8 +167,12 @@ wxStaticText::MSWHandleMessage(WXLRESULT *result, switch ( message ) { case WM_PAINT: - // We only customize drawing of disabled labels in dark mode. - if ( ::IsWindowEnabled(GetHwnd()) || !wxMSWDarkMode::IsActive() ) + // We only customize drawing of disabled plain labels in dark mode. + if ( ::IsWindowEnabled(GetHwnd()) || +#if wxUSE_MARKUP + m_markupText || +#endif // wxUSE_MARKUP + !wxMSWDarkMode::IsActive() ) break; // For them, the default "greying out" of the text for the disabled @@ -200,6 +208,16 @@ void wxStaticText::SetLabel(const wxString& label) if ( label == m_labelOrig ) return; +#if wxUSE_MARKUP + if ( m_markupText ) + { + Unbind(wxEVT_PAINT, &wxStaticText::WXOnPaint, this); + + delete m_markupText; + m_markupText = nullptr; + } +#endif // wxUSE_MARKUP + #ifdef SS_ENDELLIPSIS wxMSWWinStyleUpdater updateStyle(GetHwnd()); if ( HasFlag(wxST_ELLIPSIZE_END) ) @@ -256,5 +274,77 @@ void wxStaticText::WXSetVisibleLabel(const wxString& str) wxWindow::SetLabel(str); } +#if wxUSE_MARKUP + +bool wxStaticText::DoSetLabelMarkup(const wxString& markup) +{ + const wxString label = RemoveMarkup(markup); + if ( label.empty() && !markup.empty() ) + return false; + + m_labelOrig = label; + + // Don't do anything if the label didn't change. + if ( m_markupText && !m_markupText->SetMarkup(markup) ) + return true; + + if ( !m_markupText ) + { + Bind(wxEVT_PAINT, &wxStaticText::WXOnPaint, this); + + m_markupText = new wxMarkupText(markup); + } + + AutoResizeIfNecessary(); + + return true; +} + +void wxStaticText::WXOnPaint(wxPaintEvent& event) +{ + // We shouldn't normally be called in this case, but ensure we don't do + // anything if we are, somehow. + if ( !m_markupText ) + { + event.Skip(); + return; + } + + wxPaintDC dc(this); + + // TODO: support transparent background for static text with markup. + dc.Clear(); + + const wxRect rect = GetClientRect(); + if ( !IsThisEnabled() ) + { + if ( wxMSWDarkMode::IsActive() ) + { + wxDarkModeSettings darkModeSettings; + dc.SetTextForeground( + darkModeSettings.GetMenuColour(wxMenuColour::DisabledFg) + ); + } + else // Emulate traditional greyed out disabled look. + { + dc.SetTextForeground( + wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT) + ); + + wxRect rectShadow = rect; + rectShadow.Offset(1, 1); + + m_markupText->Render(dc, rectShadow, wxMarkupText::Render_ShowAccels); + + dc.SetTextForeground( + wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW) + ); + } + } + + m_markupText->Render(dc, rect, wxMarkupText::Render_ShowAccels); +} + +#endif // wxUSE_MARKUP #endif // wxUSE_STATTEXT