Add support for HiDPI bitmaps to wxDataViewBitmapRenderer with GTK3
This commit is contained in:
@@ -2464,28 +2464,126 @@ GtkCellRendererText *wxDataViewTextRenderer::GtkGetTextRenderer() const
|
|||||||
// wxDataViewBitmapRenderer
|
// wxDataViewBitmapRenderer
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
namespace
|
#ifdef __WXGTK3__
|
||||||
{
|
// Derive a type from GtkCellRendererPixbuf to allow drawing HiDPI bitmaps
|
||||||
|
|
||||||
// set "pixbuf" property on the given renderer
|
extern "C" {
|
||||||
void SetPixbufProp(GtkCellRenderer *renderer, GdkPixbuf *pixbuf)
|
static void wxCellRendererPixbufClassInit(void* g_class, void* class_data);
|
||||||
{
|
|
||||||
GValue gvalue = G_VALUE_INIT;
|
|
||||||
g_value_init( &gvalue, G_TYPE_OBJECT );
|
|
||||||
g_value_set_object( &gvalue, pixbuf );
|
|
||||||
g_object_set_property( G_OBJECT(renderer), "pixbuf", &gvalue );
|
|
||||||
g_value_unset( &gvalue );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WX_CELL_RENDERER_PIXBUF(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, wxCellRendererPixbuf::Type(), wxCellRendererPixbuf)
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class wxCellRendererPixbuf: GtkCellRendererPixbuf
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static GType Type();
|
||||||
|
static GtkCellRenderer* New();
|
||||||
|
void Set(const wxBitmap& bitmap);
|
||||||
|
|
||||||
|
wxBitmap* m_bitmap;
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxCellRendererPixbuf);
|
||||||
|
wxCellRendererPixbuf() wxMEMBER_DELETE;
|
||||||
|
~wxCellRendererPixbuf() wxMEMBER_DELETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
GtkCellRendererClass* wxCellRendererPixbufParentClass;
|
||||||
|
|
||||||
|
GType wxCellRendererPixbuf::Type()
|
||||||
|
{
|
||||||
|
static GType type;
|
||||||
|
if (type == 0)
|
||||||
|
{
|
||||||
|
type = g_type_register_static_simple(
|
||||||
|
GTK_TYPE_CELL_RENDERER_PIXBUF,
|
||||||
|
"wxCellRendererPixbuf",
|
||||||
|
sizeof(GtkCellRendererPixbufClass),
|
||||||
|
wxCellRendererPixbufClassInit,
|
||||||
|
sizeof(wxCellRendererPixbuf),
|
||||||
|
NULL, GTypeFlags(0));
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkCellRenderer* wxCellRendererPixbuf::New()
|
||||||
|
{
|
||||||
|
wxCellRendererPixbuf* crp = WX_CELL_RENDERER_PIXBUF(g_object_new(Type(), NULL));
|
||||||
|
crp->m_bitmap = new wxBitmap;
|
||||||
|
return GTK_CELL_RENDERER(crp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCellRendererPixbuf::Set(const wxBitmap& bitmap)
|
||||||
|
{
|
||||||
|
*m_bitmap = bitmap;
|
||||||
|
|
||||||
|
GdkPixbuf* pixbuf = NULL;
|
||||||
|
GdkPixbuf* pixbufNew = NULL;
|
||||||
|
if (bitmap.IsOk())
|
||||||
|
{
|
||||||
|
if (bitmap.GetScaleFactor() <= 1)
|
||||||
|
{
|
||||||
|
pixbuf = bitmap.GetPixbuf();
|
||||||
|
m_bitmap->UnRef();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pixbufNew =
|
||||||
|
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8,
|
||||||
|
int(bitmap.GetScaledWidth()), int(bitmap.GetScaledHeight()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_object_set(G_OBJECT(this), "pixbuf", pixbuf, NULL);
|
||||||
|
if (pixbufNew)
|
||||||
|
g_object_unref(pixbufNew);
|
||||||
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static void
|
||||||
|
wxCellRendererPixbufRender(GtkCellRenderer* cell, cairo_t* cr, GtkWidget* widget,
|
||||||
|
const GdkRectangle* background_area, const GdkRectangle* cell_area, GtkCellRendererState flags)
|
||||||
|
{
|
||||||
|
const wxBitmap& bitmap = *WX_CELL_RENDERER_PIXBUF(cell)->m_bitmap;
|
||||||
|
if (!bitmap.IsOk())
|
||||||
|
wxCellRendererPixbufParentClass->render(cell, cr, widget, background_area, cell_area, flags);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int x = (cell_area->width - int(bitmap.GetScaledWidth() )) / 2;
|
||||||
|
const int y = (cell_area->height - int(bitmap.GetScaledHeight())) / 2;
|
||||||
|
bitmap.Draw(cr, cell_area->x + x, cell_area->y + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wxCellRendererPixbufFinalize(GObject* object)
|
||||||
|
{
|
||||||
|
wxCellRendererPixbuf* crp = WX_CELL_RENDERER_PIXBUF(object);
|
||||||
|
delete crp->m_bitmap;
|
||||||
|
crp->m_bitmap = NULL;
|
||||||
|
G_OBJECT_CLASS(wxCellRendererPixbufParentClass)->finalize(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wxCellRendererPixbufClassInit(void* g_class, void* /*class_data*/)
|
||||||
|
{
|
||||||
|
GTK_CELL_RENDERER_CLASS(g_class)->render = wxCellRendererPixbufRender;
|
||||||
|
G_OBJECT_CLASS(g_class)->finalize = wxCellRendererPixbufFinalize;
|
||||||
|
wxCellRendererPixbufParentClass = GTK_CELL_RENDERER_CLASS(g_type_class_peek_parent(g_class));
|
||||||
|
}
|
||||||
|
} // extern "C"
|
||||||
|
#endif // __WXGTK3__
|
||||||
|
|
||||||
wxIMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer);
|
wxIMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer);
|
||||||
|
|
||||||
wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode,
|
wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode,
|
||||||
int align ) :
|
int align ) :
|
||||||
wxDataViewRenderer( varianttype, mode, align )
|
wxDataViewRenderer( varianttype, mode, align )
|
||||||
{
|
{
|
||||||
|
#ifdef __WXGTK3__
|
||||||
|
m_renderer = wxCellRendererPixbuf::New();
|
||||||
|
#else
|
||||||
m_renderer = gtk_cell_renderer_pixbuf_new();
|
m_renderer = gtk_cell_renderer_pixbuf_new();
|
||||||
|
#endif
|
||||||
|
|
||||||
SetMode(mode);
|
SetMode(mode);
|
||||||
SetAlignment(align);
|
SetAlignment(align);
|
||||||
@@ -2493,26 +2591,15 @@ wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype,
|
|||||||
|
|
||||||
bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value )
|
bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value )
|
||||||
{
|
{
|
||||||
if (value.GetType() == wxT("wxBitmap"))
|
wxBitmap bitmap;
|
||||||
{
|
if (value.GetType() == wxS("wxBitmap") || value.GetType() == wxS("wxIcon"))
|
||||||
wxBitmap bitmap;
|
|
||||||
bitmap << value;
|
bitmap << value;
|
||||||
|
|
||||||
// GetPixbuf() may create a Pixbuf representation in the wxBitmap
|
#ifdef __WXGTK3__
|
||||||
// object (and it will stay there and remain owned by wxBitmap)
|
WX_CELL_RENDERER_PIXBUF(m_renderer)->Set(bitmap);
|
||||||
SetPixbufProp(m_renderer, bitmap.IsOk() ? bitmap.GetPixbuf() : NULL);
|
#else
|
||||||
}
|
g_object_set(G_OBJECT(m_renderer), "pixbuf", bitmap.IsOk() ? bitmap.GetPixbuf() : NULL, NULL);
|
||||||
else if (value.GetType() == wxT("wxIcon"))
|
#endif
|
||||||
{
|
|
||||||
wxIcon icon;
|
|
||||||
icon << value;
|
|
||||||
|
|
||||||
SetPixbufProp(m_renderer, icon.IsOk() ? icon.GetPixbuf() : NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetPixbufProp(m_renderer, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3033,7 +3120,11 @@ wxDataViewIconTextRenderer::wxDataViewIconTextRenderer
|
|||||||
)
|
)
|
||||||
: wxDataViewTextRenderer(varianttype, mode, align)
|
: wxDataViewTextRenderer(varianttype, mode, align)
|
||||||
{
|
{
|
||||||
|
#ifdef __WXGTK3__
|
||||||
|
m_rendererIcon = wxCellRendererPixbuf::New();
|
||||||
|
#else
|
||||||
m_rendererIcon = gtk_cell_renderer_pixbuf_new();
|
m_rendererIcon = gtk_cell_renderer_pixbuf_new();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer()
|
wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer()
|
||||||
@@ -3056,7 +3147,11 @@ bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value )
|
|||||||
SetTextValue(m_value.GetText());
|
SetTextValue(m_value.GetText());
|
||||||
|
|
||||||
const wxIcon& icon = m_value.GetIcon();
|
const wxIcon& icon = m_value.GetIcon();
|
||||||
SetPixbufProp(m_rendererIcon, icon.IsOk() ? icon.GetPixbuf() : NULL);
|
#ifdef __WXGTK3__
|
||||||
|
WX_CELL_RENDERER_PIXBUF(m_rendererIcon)->Set(icon);
|
||||||
|
#else
|
||||||
|
g_object_set(G_OBJECT(m_rendererIcon), "pixbuf", icon.IsOk() ? icon.GetPixbuf() : NULL, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user