Add wxRendererNative::DrawItemText() for list-like controls

Add a new method that should be used for drawing the elements of list-like
controls (i.e. wx{List,Tree,DataView}Ctrl and similar).

Implement it for wxMSW natively and provide a straightforward generic fallback
for the other ports.

See #16414.
This commit is contained in:
Tobias Taschner
2015-09-17 14:38:03 +02:00
committed by Vadim Zeitlin
parent ba4bfc5414
commit b7a89f8746
8 changed files with 189 additions and 0 deletions

View File

@@ -97,6 +97,7 @@ All (GUI):
- Add support for sorting wxDataViewCtrl by multiple columns (Trigve). - Add support for sorting wxDataViewCtrl by multiple columns (Trigve).
- Allow dropping data on wxDataViewCtrl background (Laurent Poujoulat). - Allow dropping data on wxDataViewCtrl background (Laurent Poujoulat).
- Add wxRendererNative::DrawGauge() (Tobias Taschner). - Add wxRendererNative::DrawGauge() (Tobias Taschner).
- Add wxRendererNative::DrawItemText() (Tobias Taschner).
- Add wxHtmlWindow::SetDefaultHTMLCursor() (Jeff A. Marr). - Add wxHtmlWindow::SetDefaultHTMLCursor() (Jeff A. Marr).
- Add default ctor and Create() to wxContextHelpButton (Hanmac). - Add default ctor and Create() to wxContextHelpButton (Hanmac).
- Send events when toggling wxPropertyGrid nodes from keyboard (Armel Asselin). - Send events when toggling wxPropertyGrid nodes from keyboard (Armel Asselin).

View File

@@ -84,10 +84,32 @@ private:
wxDECLARE_NO_COPY_CLASS(wxUxThemeFont); wxDECLARE_NO_COPY_CLASS(wxUxThemeFont);
}; };
typedef int(__stdcall *DTT_CALLBACK_PROC)(HDC hdc, const wchar_t * pszText, int cchText, RECT * prc, unsigned int dwFlags, WXLPARAM lParam);
typedef struct _DTTOPTS
{
DWORD dwSize;
DWORD dwFlags;
COLORREF crText;
COLORREF crBorder;
COLORREF crShadow;
int iTextShadowType;
POINT ptShadowOffset;
int iBorderSize;
int iFontPropId;
int iColorPropId;
int iStateId;
BOOL fApplyOverlay;
int iGlowSize;
DTT_CALLBACK_PROC pfnDrawTextCallback;
WXLPARAM lParam;
} DTTOPTS, *PDTTOPTS;
typedef HTHEME (__stdcall *PFNWXUOPENTHEMEDATA)(HWND, const wchar_t *); typedef HTHEME (__stdcall *PFNWXUOPENTHEMEDATA)(HWND, const wchar_t *);
typedef HRESULT (__stdcall *PFNWXUCLOSETHEMEDATA)(HTHEME); typedef HRESULT (__stdcall *PFNWXUCLOSETHEMEDATA)(HTHEME);
typedef HRESULT (__stdcall *PFNWXUDRAWTHEMEBACKGROUND)(HTHEME, HDC, int, int, const RECT *, const RECT *); typedef HRESULT (__stdcall *PFNWXUDRAWTHEMEBACKGROUND)(HTHEME, HDC, int, int, const RECT *, const RECT *);
typedef HRESULT (__stdcall *PFNWXUDRAWTHEMETEXT)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, DWORD, const RECT *); typedef HRESULT (__stdcall *PFNWXUDRAWTHEMETEXT)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, DWORD, const RECT *);
typedef HRESULT (__stdcall *PFNWXUDRAWTHEMETEXTEX)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, RECT *, const DTTOPTS *);
typedef HRESULT (__stdcall *PFNWXUGETTHEMEBACKGROUNDCONTENTRECT)(HTHEME, HDC, int, int, const RECT *, RECT *); typedef HRESULT (__stdcall *PFNWXUGETTHEMEBACKGROUNDCONTENTRECT)(HTHEME, HDC, int, int, const RECT *, RECT *);
typedef HRESULT (__stdcall *PFNWXUGETTHEMEBACKGROUNDEXTENT)(HTHEME, HDC, int, int, const RECT *, RECT *); typedef HRESULT (__stdcall *PFNWXUGETTHEMEBACKGROUNDEXTENT)(HTHEME, HDC, int, int, const RECT *, RECT *);
typedef HRESULT (__stdcall *PFNWXUGETTHEMEPARTSIZE)(HTHEME, HDC, int, int, const RECT *, /* enum */ THEMESIZE, SIZE *); typedef HRESULT (__stdcall *PFNWXUGETTHEMEPARTSIZE)(HTHEME, HDC, int, int, const RECT *, /* enum */ THEMESIZE, SIZE *);
@@ -161,6 +183,7 @@ public:
wxUX_THEME_DECLARE(PFNWXUCLOSETHEMEDATA, CloseThemeData) wxUX_THEME_DECLARE(PFNWXUCLOSETHEMEDATA, CloseThemeData)
wxUX_THEME_DECLARE(PFNWXUDRAWTHEMEBACKGROUND, DrawThemeBackground) wxUX_THEME_DECLARE(PFNWXUDRAWTHEMEBACKGROUND, DrawThemeBackground)
wxUX_THEME_DECLARE(PFNWXUDRAWTHEMETEXT, DrawThemeText) wxUX_THEME_DECLARE(PFNWXUDRAWTHEMETEXT, DrawThemeText)
wxUX_THEME_DECLARE(PFNWXUDRAWTHEMETEXTEX, DrawThemeTextEx)
wxUX_THEME_DECLARE(PFNWXUGETTHEMEBACKGROUNDCONTENTRECT, GetThemeBackgroundContentRect) wxUX_THEME_DECLARE(PFNWXUGETTHEMEBACKGROUNDCONTENTRECT, GetThemeBackgroundContentRect)
wxUX_THEME_DECLARE(PFNWXUGETTHEMEBACKGROUNDEXTENT, GetThemeBackgroundExtent) wxUX_THEME_DECLARE(PFNWXUGETTHEMEBACKGROUNDEXTENT, GetThemeBackgroundExtent)
wxUX_THEME_DECLARE(PFNWXUGETTHEMEPARTSIZE, GetThemePartSize) wxUX_THEME_DECLARE(PFNWXUGETTHEMEPARTSIZE, GetThemePartSize)

View File

@@ -329,6 +329,14 @@ public:
int max, int max,
int flags = 0) = 0; int flags = 0) = 0;
// Draw text using the appropriate color for normal and selected states.
virtual void DrawItemText(wxWindow* win,
wxDC& dc,
const wxString& text,
const wxRect& rect,
int align = wxALIGN_LEFT | wxALIGN_TOP,
int flags = 0) = 0;
// geometry functions // geometry functions
// ------------------ // ------------------
@@ -515,6 +523,14 @@ public:
int flags = 0) int flags = 0)
{ m_rendererNative.DrawGauge(win, dc, rect, value, max, flags); } { m_rendererNative.DrawGauge(win, dc, rect, value, max, flags); }
virtual void DrawItemText(wxWindow* win,
wxDC& dc,
const wxString& text,
const wxRect& rect,
int align = wxALIGN_LEFT | wxALIGN_TOP,
int flags = 0)
{ m_rendererNative.DrawItemText(win, dc, text, rect, align, flags); }
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win) virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win)
{ return m_rendererNative.GetSplitterParams(win); } { return m_rendererNative.GetSplitterParams(win); }

View File

@@ -405,10 +405,33 @@ public:
(otherwise the selection rectangle is e.g. often grey and not blue). (otherwise the selection rectangle is e.g. often grey and not blue).
This may be ignored by the renderer or deduced by the code directly from This may be ignored by the renderer or deduced by the code directly from
the @a win. the @a win.
@see DrawItemText()
*/ */
virtual void DrawItemSelectionRect(wxWindow* win, wxDC& dc, virtual void DrawItemSelectionRect(wxWindow* win, wxDC& dc,
const wxRect& rect, int flags = 0) = 0; const wxRect& rect, int flags = 0) = 0;
/**
Draw item text in the correct color based on selection status.
Background of the text should be painted with DrawItemSelectionRect().
The supported @a flags are @c wxCONTROL_SELECTED for items
which are selected.
@c wxCONTROL_FOCUSED may be used to indicate if the control has the focus.
@c wxCONTROL_DISABLED may be used to indicate if the control is disabled.
@since 3.1.0
@see DrawItemSelectionRect()
*/
virtual void DrawItemText(wxWindow* win,
wxDC& dc,
const wxString& text,
const wxRect& rect,
int align = wxALIGN_LEFT | wxALIGN_TOP,
int flags = 0) = 0;
/** /**
Draw a blank push button that looks very similar to wxButton. Draw a blank push button that looks very similar to wxButton.

View File

@@ -276,6 +276,18 @@ private:
wxRect(x2, y, widthGauge, heightGauge), 25, 100, m_flags); wxRect(x2, y, widthGauge, heightGauge), 25, 100, m_flags);
y += lineHeight + heightGauge; y += lineHeight + heightGauge;
const wxCoord heightListItem = 48;
const wxCoord widthListItem = 260;
dc.DrawText("DrawItemSelectionRect()", x1, y);
wxRendererNative::GetDefault().DrawItemSelectionRect(this, dc,
wxRect(x2, y, widthListItem, heightListItem), m_flags | wxCONTROL_SELECTED);
wxRendererNative::GetDefault().DrawItemText(this, dc, "DrawItemText()",
wxRect(x2, y, widthListItem, heightListItem).Inflate(-2, -2), m_align, m_flags | wxCONTROL_SELECTED);
y += lineHeight + heightListItem;
} }
int m_flags; int m_flags;

View File

@@ -138,6 +138,13 @@ public:
virtual void DrawGauge(wxWindow* win, wxDC& dc, const wxRect& rect, int value, int max, int flags = 0) wxOVERRIDE; virtual void DrawGauge(wxWindow* win, wxDC& dc, const wxRect& rect, int value, int max, int flags = 0) wxOVERRIDE;
virtual void DrawItemText(wxWindow* win,
wxDC& dc,
const wxString& text,
const wxRect& rect,
int align = wxALIGN_LEFT | wxALIGN_TOP,
int flags = 0) wxOVERRIDE;
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win) wxOVERRIDE; virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win) wxOVERRIDE;
virtual wxRendererVersion GetVersion() const wxOVERRIDE virtual wxRendererVersion GetVersion() const wxOVERRIDE
@@ -832,6 +839,46 @@ void wxRendererGeneric::DrawGauge(wxWindow* win,
dc.DrawRectangle(progRect); dc.DrawRectangle(progRect);
} }
void
wxRendererGeneric::DrawItemText(wxWindow* win,
wxDC& dc,
const wxString& text,
const wxRect& rect,
int align,
int flags)
{
// Determine text color
wxColour textColour;
if ( flags & wxCONTROL_SELECTED )
{
if ( flags & wxCONTROL_FOCUSED )
{
textColour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
}
else // !focused
{
textColour = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT);
}
}
else if ( flags & wxCONTROL_DISABLED )
{
textColour = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
}
else // enabled but not selected
{
textColour = win->GetForegroundColour();
}
const wxString paintText = wxControl::Ellipsize(text, dc,
wxELLIPSIZE_END,
rect.GetWidth());
// Draw text
dc.SetTextForeground(textColour);
dc.SetTextBackground(wxTransparentColour);
dc.DrawLabel(paintText, rect, align);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// A module to allow cleanup of generic renderer. // A module to allow cleanup of generic renderer.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -111,6 +111,9 @@
#define LISS_HOTSELECTED 6 #define LISS_HOTSELECTED 6
#define LVP_LISTITEM 1 #define LVP_LISTITEM 1
#define DTT_TEXTCOLOR (1UL << 0) // crText has been specified
#define DTT_STATEID (1UL << 8) // IStateId has been specified
#endif #endif
#if defined(__WXWINCE__) #if defined(__WXWINCE__)
@@ -323,6 +326,12 @@ public:
int max, int max,
int flags = 0); int flags = 0);
virtual void DrawItemText(wxWindow* win,
wxDC& dc,
const wxString& text,
const wxRect& rect,
int align = wxALIGN_LEFT | wxALIGN_TOP,
int flags = 0);
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win); virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
@@ -881,6 +890,63 @@ wxRendererXP::DrawItemSelectionRect(wxWindow *win,
} }
} }
void wxRendererXP::DrawItemText(wxWindow* win,
wxDC& dc,
const wxString& text,
const wxRect& rect,
int align,
int flags)
{
wxUxThemeHandle hTheme(win, L"LISTVIEW");
int itemState = LISS_NORMAL;
if ( flags & wxCONTROL_SELECTED )
itemState = LISS_SELECTED;
if ( !(flags & wxCONTROL_FOCUSED) )
itemState = LISS_SELECTEDNOTFOCUS;
if ( flags & wxCONTROL_DISABLED )
itemState |= LISS_DISABLED;
wxUxThemeEngine* te = wxUxThemeEngine::Get();
if ( te->IsThemePartDefined(hTheme, LVP_LISTITEM, itemState) )
{
RECT rc;
wxCopyRectToRECT(rect, rc);
DTTOPTS textOpts;
textOpts.dwSize = sizeof(textOpts);
textOpts.dwFlags = DTT_STATEID;
textOpts.iStateId = itemState;
if (flags & wxCONTROL_DISABLED)
{
textOpts.dwFlags |= DTT_TEXTCOLOR;
textOpts.crText = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT).GetPixel();
}
DWORD textFlags = DT_NOPREFIX | DT_END_ELLIPSIS;
if ( align & wxALIGN_CENTER )
textFlags |= DT_CENTER;
else if ( align & wxALIGN_RIGHT )
textFlags |= DT_RIGHT;
else
textFlags |= DT_LEFT;
if ( align & wxALIGN_BOTTOM )
textFlags |= DT_BOTTOM;
else if ( align & wxALIGN_CENTER_VERTICAL )
textFlags |= DT_VCENTER;
else
textFlags |= DT_TOP;
te->DrawThemeTextEx(hTheme, dc.GetHDC(), LVP_LISTITEM, itemState,
text.wchar_str(), -1, textFlags, &rc, &textOpts);
}
else
{
m_rendererNative.DrawItemText(win, dc, text, rect, align, flags);
}
}
// Uses the theme to draw the border and fill for something like a wxTextCtrl // Uses the theme to draw the border and fill for something like a wxTextCtrl
void wxRendererXP::DrawTextCtrl(wxWindow* win, void wxRendererXP::DrawTextCtrl(wxWindow* win,
wxDC& dc, wxDC& dc,

View File

@@ -124,6 +124,7 @@ bool wxUxThemeEngine::Initialize()
RESOLVE_UXTHEME_FUNCTION(PFNWXUCLOSETHEMEDATA, CloseThemeData); RESOLVE_UXTHEME_FUNCTION(PFNWXUCLOSETHEMEDATA, CloseThemeData);
RESOLVE_UXTHEME_FUNCTION(PFNWXUDRAWTHEMEBACKGROUND, DrawThemeBackground); RESOLVE_UXTHEME_FUNCTION(PFNWXUDRAWTHEMEBACKGROUND, DrawThemeBackground);
RESOLVE_UXTHEME_FUNCTION(PFNWXUDRAWTHEMETEXT, DrawThemeText); RESOLVE_UXTHEME_FUNCTION(PFNWXUDRAWTHEMETEXT, DrawThemeText);
RESOLVE_UXTHEME_FUNCTION(PFNWXUDRAWTHEMETEXTEX, DrawThemeTextEx);
RESOLVE_UXTHEME_FUNCTION(PFNWXUGETTHEMEBACKGROUNDCONTENTRECT, GetThemeBackgroundContentRect); RESOLVE_UXTHEME_FUNCTION(PFNWXUGETTHEMEBACKGROUNDCONTENTRECT, GetThemeBackgroundContentRect);
RESOLVE_UXTHEME_FUNCTION(PFNWXUGETTHEMEBACKGROUNDEXTENT, GetThemeBackgroundExtent); RESOLVE_UXTHEME_FUNCTION(PFNWXUGETTHEMEBACKGROUNDEXTENT, GetThemeBackgroundExtent);
RESOLVE_UXTHEME_FUNCTION(PFNWXUGETTHEMEPARTSIZE, GetThemePartSize); RESOLVE_UXTHEME_FUNCTION(PFNWXUGETTHEMEPARTSIZE, GetThemePartSize);