Merge branch 'dvc-bitmap-renderer-bundle'

Allow using wxBitmapBundle with wxDataViewBitmapRenderer.

See #22411.
This commit is contained in:
Vadim Zeitlin
2022-05-23 22:22:53 +01:00
14 changed files with 242 additions and 28 deletions

View File

@@ -108,6 +108,9 @@ public:
// Check if bitmap bundle is non-empty.
bool IsOk() const { return m_impl.get() != NULL; }
// Clear the bundle contents, IsOk() will return false after doing this.
void Clear() { m_impl.reset(NULL); }
// Get the size of the bitmap represented by this bundle when using the
// default DPI, i.e. 100% scaling. Returns invalid size for empty bundle.
wxSize GetDefaultSize() const;
@@ -242,4 +245,19 @@ public:
virtual wxBitmap GetBitmap(const wxSize& size) = 0;
};
// ----------------------------------------------------------------------------
// Allow using wxBitmapBundle in wxVariant
// ----------------------------------------------------------------------------
#if wxUSE_VARIANT
class WXDLLIMPEXP_FWD_BASE wxVariant;
WXDLLIMPEXP_CORE
wxBitmapBundle& operator<<(wxBitmapBundle& value, const wxVariant& variant);
WXDLLIMPEXP_CORE
wxVariant& operator<<(wxVariant& variant, const wxBitmapBundle& value);
#endif // wxUSE_VARIANT
#endif // _WX_BMPBNDL_H_

View File

@@ -155,6 +155,15 @@ public:
wxString GetVariantType() const { return m_variantType; }
// Check if the given variant type is compatible with the type expected by
// this renderer: by default, just compare it with GetVariantType(), but
// can be overridden to accept other types that can be converted to the
// type needed by the renderer.
virtual bool IsCompatibleVariantType(const wxString& variantType) const
{
return variantType == GetVariantType();
}
// Prepare for rendering the value of the corresponding item in the given
// column taken from the provided non-null model.
//
@@ -163,8 +172,9 @@ public:
// it and should probably be removed in the future.
//
// Return true if this cell is non-empty or false otherwise (and also if
// the model returned a value of the wrong, i.e. different from our
// GetVariantType(), type, in which case a debug error is also logged).
// the model returned a value of the wrong type, i.e. such that our
// IsCompatibleVariantType() returned false for it, in which case a debug
// error is also logged).
bool PrepareForItem(const wxDataViewModel *model,
const wxDataViewItem& item,
unsigned column);

View File

@@ -96,7 +96,7 @@ private:
class WXDLLIMPEXP_ADV wxDataViewBitmapRenderer: public wxDataViewRenderer
{
public:
static wxString GetDefaultType() { return wxS("wxBitmap"); }
static wxString GetDefaultType() { return wxS("wxBitmapBundle"); }
wxDataViewBitmapRenderer( const wxString &varianttype = GetDefaultType(),
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
@@ -104,6 +104,10 @@ public:
virtual bool SetValue( const wxVariant &value ) wxOVERRIDE;
virtual bool GetValue( wxVariant &value ) const wxOVERRIDE;
virtual
bool IsCompatibleVariantType(const wxString& variantType) const wxOVERRIDE;
#if wxUSE_ACCESSIBILITY
virtual wxString GetAccessibleDescription() const wxOVERRIDE;
#endif // wxUSE_ACCESSIBILITY
@@ -112,8 +116,7 @@ public:
virtual wxSize GetSize() const wxOVERRIDE;
private:
wxIcon m_icon;
wxBitmap m_bitmap;
wxBitmapBundle m_bitmapBundle;
protected:
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewBitmapRenderer);

View File

@@ -81,7 +81,7 @@ protected:
class WXDLLIMPEXP_ADV wxDataViewBitmapRenderer: public wxDataViewRenderer
{
public:
static wxString GetDefaultType() { return wxS("wxBitmap"); }
static wxString GetDefaultType() { return wxS("wxBitmapBundle"); }
wxDataViewBitmapRenderer( const wxString &varianttype = GetDefaultType(),
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
@@ -90,6 +90,9 @@ public:
bool SetValue( const wxVariant &value ) wxOVERRIDE;
bool GetValue( wxVariant &value ) const wxOVERRIDE;
virtual
bool IsCompatibleVariantType(const wxString& variantType) const wxOVERRIDE;
protected:
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewBitmapRenderer);
};

View File

@@ -104,12 +104,15 @@ private:
class WXDLLIMPEXP_ADV wxDataViewBitmapRenderer: public wxDataViewRenderer
{
public:
static wxString GetDefaultType() { return wxS("wxBitmap"); }
static wxString GetDefaultType() { return wxS("wxBitmapBundle"); }
wxDataViewBitmapRenderer(const wxString& varianttype = GetDefaultType(),
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
int align = wxDVR_DEFAULT_ALIGNMENT);
virtual
bool IsCompatibleVariantType(const wxString& variantType) const wxOVERRIDE;
virtual bool MacRender() wxOVERRIDE;
private:

View File

@@ -34,7 +34,7 @@ public:
class WXDLLIMPEXP_ADV wxDataViewBitmapRenderer: public wxDataViewRenderer
{
public:
static wxString GetDefaultType() { return wxS("wxBitmap"); }
static wxString GetDefaultType() { return wxS("wxBitmapBundle"); }
wxDataViewBitmapRenderer( const wxString &varianttype = GetDefaultType(),
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
@@ -42,6 +42,8 @@ public:
bool SetValue( const wxVariant &value );
bool GetValue( wxVariant &value ) const;
bool IsCompatibleVariantType(const wxString& variantType) const;
};
// ---------------------------------------------------------

View File

@@ -288,6 +288,18 @@ public:
*/
static wxBitmapBundle FromSVGResource(const wxString& name, const wxSize& sizeDef);
/**
Clear the existing bundle contents.
After calling this function IsOk() returns @false.
This is the same as assigning a default-constructed bitmap bundle to
this object but slightly more explicit.
@since 3.1.7
*/
void Clear();
/**
Check if bitmap bundle is non-empty.

View File

@@ -1981,6 +1981,15 @@ class wxDataViewRenderer : public wxObject
public:
/**
Constructor.
The @a varianttype parameter is the main type of wxVariant objects
supported by this renderer, i.e. those that can be passed to its
SetValue(), e.g. "string" for wxDataViewTextRenderer. The value of this
parameter is returned by GetVariantType().
When deriving a custom renderer, either an existing variant type or a
new custom one can be used, see wxVariant documentation for more
details.
*/
wxDataViewRenderer(const wxString& varianttype,
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
@@ -2061,9 +2070,27 @@ public:
/**
Returns a string with the type of the wxVariant supported by this renderer.
Note that a renderer may support more than one variant type, in which
case it needs to override IsCompatibleVariantType() to return @a true
for all types it supports. But by default only the type returned by
this function is supported.
*/
wxString GetVariantType() const;
/**
Check if the given variant type is compatible with the type expected by
this renderer.
The base class implementation just compares @a variantType with the
value returned by GetVariantType(), but this function can be overridden
to accept other types that can be converted to the type needed by the
renderer.
@since 3.1.7
*/
virtual bool IsCompatibleVariantType(const wxString& variantType) const;
/**
Sets the alignment of the renderer's content.
The default value of @c wxDVR_DEFAULT_ALIGNMENT indicates that the content
@@ -2717,7 +2744,12 @@ protected:
/**
@class wxDataViewBitmapRenderer
This class is used by wxDataViewCtrl to render bitmap controls.
This class is used by wxDataViewCtrl to render bitmaps.
This renderer accepts wxVariant objects storing wxBitmap, wxIcon or
wxBitmapBundle inside them, with the latter being preferred as it allows
the renderer to automatically select the bitmap of the best matching size
depending on the current DPI.
@library{wxcore}
@category{dvc}
@@ -2728,6 +2760,11 @@ public:
/**
Returns the wxVariant type used with this renderer.
Note that the value returned by this function has changed from
"wxBitmap" to "wxBitmapBundle" in wxWidgets 3.1.7, however the exact
value shouldn't matter, as it is only supposed to be used as the value
for the first constructor argument.
@since 3.1.0
*/
static wxString GetDefaultType();

View File

@@ -36,6 +36,71 @@
#include "wx/osx/private.h"
#endif
#if wxUSE_VARIANT
#include "wx/variant.h"
// We can't use the macros from wx/variant.h because they only work for
// wxObject-derived classes, so define our own wxVariantData.
class wxBitmapBundleVariantData: public wxVariantData
{
public:
explicit wxBitmapBundleVariantData(const wxBitmapBundle& value)
: m_value(value)
{
}
virtual bool Eq(wxVariantData& data) const wxOVERRIDE
{
// We're only called with the objects of the same type, so the cast is
// safe.
return static_cast<wxBitmapBundleVariantData&>(data).m_value.IsSameAs(m_value);
}
virtual wxString GetType() const wxOVERRIDE
{
return wxASCII_STR("wxBitmapBundle");
}
virtual wxClassInfo* GetValueClassInfo() wxOVERRIDE
{
return NULL;
}
virtual wxVariantData* Clone() const wxOVERRIDE
{
return new wxBitmapBundleVariantData(m_value);
}
wxBitmapBundle m_value;
DECLARE_WXANY_CONVERSION()
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxBitmapBundle, wxBitmapBundleVariantData)
WXDLLIMPEXP_CORE
wxBitmapBundle& operator<<(wxBitmapBundle& value, const wxVariant& variant)
{
wxASSERT( variant.GetType() == wxASCII_STR("wxBitmapBundle") );
wxBitmapBundleVariantData* const
data = static_cast<wxBitmapBundleVariantData*>(variant.GetData());
value = data->m_value;
return value;
}
WXDLLIMPEXP_CORE
wxVariant& operator<<(wxVariant& variant, const wxBitmapBundle& value)
{
variant.SetData(new wxBitmapBundleVariantData(value));
return variant;
}
#endif // wxUSE_VARIANT
// ----------------------------------------------------------------------------
// private helpers
// ----------------------------------------------------------------------------

View File

@@ -861,7 +861,7 @@ wxDataViewRendererBase::CheckedGetValue(const wxDataViewModel* model,
// We always allow the cell to be null, regardless of the renderer type.
if ( !value.IsNull() )
{
if ( value.GetType() != GetVariantType() )
if ( !IsCompatibleVariantType(value.GetType()) )
{
// If you're seeing this message, this indicates that either your
// renderer is using the wrong type, or your model returns values

View File

@@ -1317,18 +1317,25 @@ wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype,
bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value )
{
if (value.GetType() == wxT("wxBitmap"))
if (value.GetType() == wxT("wxBitmapBundle"))
{
m_bitmap << value;
m_bitmapBundle << value;
}
else if (value.GetType() == wxT("wxBitmap"))
{
wxBitmap bitmap;
bitmap << value;
m_bitmapBundle = wxBitmapBundle(bitmap);
}
else if (value.GetType() == wxT("wxIcon"))
{
m_icon << value;
wxIcon icon;
icon << value;
m_bitmapBundle = wxBitmapBundle(icon);
}
else
{
m_icon = wxNullIcon;
m_bitmap = wxNullBitmap;
m_bitmapBundle.Clear();
}
return true;
@@ -1339,6 +1346,15 @@ bool wxDataViewBitmapRenderer::GetValue( wxVariant& WXUNUSED(value) ) const
return false;
}
bool
wxDataViewBitmapRenderer::IsCompatibleVariantType(const wxString& variantType) const
{
// We can accept values of any types checked by SetValue().
return variantType == wxS("wxBitmapBundle")
|| variantType == wxS("wxBitmap")
|| variantType == wxS("wxIcon");
}
#if wxUSE_ACCESSIBILITY
wxString wxDataViewBitmapRenderer::GetAccessibleDescription() const
{
@@ -1348,20 +1364,20 @@ wxString wxDataViewBitmapRenderer::GetAccessibleDescription() const
bool wxDataViewBitmapRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) )
{
if (m_bitmap.IsOk())
dc->DrawBitmap( m_bitmap, cell.x, cell.y, true /* use mask */ );
else if (m_icon.IsOk())
dc->DrawIcon( m_icon, cell.x, cell.y );
if (m_bitmapBundle.IsOk())
{
dc->DrawBitmap( m_bitmapBundle.GetBitmapFor(GetView()),
cell.x, cell.y,
true /* use mask */ );
}
return true;
}
wxSize wxDataViewBitmapRenderer::GetSize() const
{
if (m_bitmap.IsOk())
return wxSize( m_bitmap.GetWidth(), m_bitmap.GetHeight() );
else if (m_icon.IsOk())
return wxSize( m_icon.GetWidth(), m_icon.GetHeight() );
if (m_bitmapBundle.IsOk())
return m_bitmapBundle.GetPreferredBitmapSizeFor(GetView());
return GetView()->FromDIP(wxSize(wxDVC_DEFAULT_RENDERER_SIZE,
wxDVC_DEFAULT_RENDERER_SIZE));

View File

@@ -2569,22 +2569,32 @@ wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype,
bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value )
{
wxBitmap bitmap;
if (value.GetType() == wxS("wxBitmap"))
wxBitmapBundle bitmapBundle;
if (value.GetType() == wxS("wxBitmapBundle"))
{
bitmapBundle << value;
}
else if (value.GetType() == wxS("wxBitmap"))
{
wxBitmap bitmap;
bitmap << value;
bitmapBundle = wxBitmapBundle(bitmap);
}
else if (value.GetType() == wxS("wxIcon"))
{
wxIcon icon;
icon << value;
bitmap.CopyFromIcon(icon);
bitmapBundle = wxBitmapBundle(icon);
}
#ifdef __WXGTK3__
WX_CELL_RENDERER_PIXBUF(m_renderer)->Set(bitmap);
WX_CELL_RENDERER_PIXBUF(m_renderer)->Set(bitmapBundle);
#else
g_object_set(G_OBJECT(m_renderer), "pixbuf", bitmap.IsOk() ? bitmap.GetPixbuf() : NULL, NULL);
g_object_set(G_OBJECT(m_renderer),
"pixbuf",
bitmapBundle.IsOk() ? bitmapBundle.GetBitmap(wxDefaultSize).GetPixbuf()
: NULL,
NULL);
#endif
return true;
@@ -2595,6 +2605,15 @@ bool wxDataViewBitmapRenderer::GetValue( wxVariant &WXUNUSED(value) ) const
return false;
}
bool
wxDataViewBitmapRenderer::IsCompatibleVariantType(const wxString& variantType) const
{
// We can accept values of any types checked by SetValue().
return variantType == wxS("wxBitmapBundle")
|| variantType == wxS("wxBitmap")
|| variantType == wxS("wxIcon");
}
// ---------------------------------------------------------
// wxDataViewToggleRenderer
// ---------------------------------------------------------

View File

@@ -28,6 +28,9 @@
#include "wx/osx/private/available.h"
#include "wx/osx/private/datatransfer.h"
#include "wx/osx/cocoa/dataview.h"
#include "wx/private/bmpbndl.h"
#include "wx/renderer.h"
#include "wx/stopwatch.h"
#include "wx/dcgraph.h"
@@ -2983,6 +2986,13 @@ wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(const wxString& varianttype,
bool wxDataViewBitmapRenderer::MacRender()
{
if (GetValue().GetType() == wxS("wxBitmap"))
{
wxBitmapBundle bundle;
bundle << GetValue();
if (bundle.IsOk())
[GetNativeData()->GetItemCell() setObjectValue:wxOSXGetImageFromBundle(bundle)];
}
else if (GetValue().GetType() == wxS("wxBitmap"))
{
wxBitmap bitmap;
bitmap << GetValue();
@@ -2999,6 +3009,15 @@ bool wxDataViewBitmapRenderer::MacRender()
return true;
}
bool
wxDataViewBitmapRenderer::IsCompatibleVariantType(const wxString& variantType) const
{
// We can accept values of any types checked by SetValue().
return variantType == wxS("wxBitmapBundle")
|| variantType == wxS("wxBitmap")
|| variantType == wxS("wxIcon");
}
wxIMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer);
// -------------------------------------

View File

@@ -54,6 +54,13 @@ bool wxDataViewBitmapRenderer::GetValue( wxVariant &value ) const
return false;
}
bool
wxDataViewBitmapRenderer::IsCompatibleVariantType(const wxString& variantType) const
{
return variantType == wxS("wxBitmap")
|| variantType == wxS("wxIcon");
}
//==============================================================================
wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &variantType, wxDataViewCellMode mode,