[Libreoffice-commits] core.git: compilerplugins/clang vcl/Library_vclplug_gtk3_kde5.mk vcl/Library_vclplug_gtk3.mk vcl/Library_vclplug_gtk4.mk vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Mon Jun 28 07:53:59 UTC 2021


 compilerplugins/clang/reservedid.cxx               |    2 
 vcl/Library_vclplug_gtk3.mk                        |    1 
 vcl/Library_vclplug_gtk3_kde5.mk                   |    1 
 vcl/Library_vclplug_gtk4.mk                        |    1 
 vcl/unx/gtk3/customcellrenderer.cxx                |  303 ++++++++++++++++++
 vcl/unx/gtk3/customcellrenderer.hxx                |   49 ++
 vcl/unx/gtk3/gtkinst.cxx                           |  352 +--------------------
 vcl/unx/gtk3_kde5/gtk3_kde5_customcellrenderer.cxx |   12 
 vcl/unx/gtk4/customcellrenderer.cxx                |   12 
 9 files changed, 402 insertions(+), 331 deletions(-)

New commits:
commit 879fc58cd4f54e72499fedce64d23bc969f943c0
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Jun 27 19:40:50 2021 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Mon Jun 28 09:53:28 2021 +0200

    split out customcellrenderer code
    
    Change-Id: Ia2803f6eab14ee7aeb697fb039f4e6dbdefa25e2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117958
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/compilerplugins/clang/reservedid.cxx b/compilerplugins/clang/reservedid.cxx
index eac62a5b9671..9f11ef5a9ced 100644
--- a/compilerplugins/clang/reservedid.cxx
+++ b/compilerplugins/clang/reservedid.cxx
@@ -197,6 +197,8 @@ bool ReservedId::VisitNamedDecl(NamedDecl const * decl) {
                 // connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
             && s != "_ADOUser"
                 // connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
+            && s != "_CustomCellRenderer" // vcl/unx/gtk3/customcellrenderer.hxx
+            && s != "_CustomCellRendererClass" // vcl/unx/gtk3/customcellrenderer.cxx
             && s != "_FcPattern" // vcl/inc/unx/fc_fontoptions.hxx
             && s != "_GdkDisplay"
                 // vcl/unx/gtk/xid_fullscreen_on_all_monitors.c
diff --git a/vcl/Library_vclplug_gtk3.mk b/vcl/Library_vclplug_gtk3.mk
index 4e7f838903a1..09374b635284 100644
--- a/vcl/Library_vclplug_gtk3.mk
+++ b/vcl/Library_vclplug_gtk3.mk
@@ -100,6 +100,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\
     vcl/unx/gtk3/fpicker/SalGtkFilePicker \
     vcl/unx/gtk3/fpicker/SalGtkFolderPicker \
     vcl/unx/gtk3/fpicker/SalGtkPicker \
+    vcl/unx/gtk3/customcellrenderer \
     vcl/unx/gtk3/gtkdata \
     vcl/unx/gtk3/gtkinst \
     vcl/unx/gtk3/gtksys \
diff --git a/vcl/Library_vclplug_gtk3_kde5.mk b/vcl/Library_vclplug_gtk3_kde5.mk
index ab804e76a697..45b046a72fda 100644
--- a/vcl/Library_vclplug_gtk3_kde5.mk
+++ b/vcl/Library_vclplug_gtk3_kde5.mk
@@ -102,6 +102,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3_kde5,\
 	vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkutil \
 	vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkvalue \
 	vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwrapper \
+	vcl/unx/gtk3_kde5/gtk3_kde5_customcellrenderer \
 	vcl/unx/gtk3_kde5/gtk3_kde5_gtkdata \
 	vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst \
 	vcl/unx/gtk3_kde5/gtk3_kde5_gtksys \
diff --git a/vcl/Library_vclplug_gtk4.mk b/vcl/Library_vclplug_gtk4.mk
index 8b2d55d9d944..09520c4dba9d 100644
--- a/vcl/Library_vclplug_gtk4.mk
+++ b/vcl/Library_vclplug_gtk4.mk
@@ -85,6 +85,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk4,\
     vcl/unx/gtk4/fpicker/SalGtkFolderPicker \
     vcl/unx/gtk4/fpicker/SalGtkPicker \
     vcl/unx/gtk4/convert3to4 \
+    vcl/unx/gtk4/customcellrenderer \
     vcl/unx/gtk4/gtkdata \
     vcl/unx/gtk4/gtkinst \
     vcl/unx/gtk4/gtksys \
diff --git a/vcl/unx/gtk3/customcellrenderer.cxx b/vcl/unx/gtk3/customcellrenderer.cxx
new file mode 100644
index 000000000000..43c6a6f03dc1
--- /dev/null
+++ b/vcl/unx/gtk3/customcellrenderer.cxx
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "customcellrenderer.hxx"
+#if !GTK_CHECK_VERSION(4, 0, 0)
+#include <gtk/gtk-a11y.h>
+#endif
+
+namespace
+{
+struct _CustomCellRendererClass : public GtkCellRendererTextClass
+{
+};
+
+enum
+{
+    PROP_ID = 10000,
+    PROP_INSTANCE_TREE_VIEW = 10001
+};
+}
+
+static gpointer custom_cell_renderer_parent_class;
+
+static void custom_cell_renderer_class_init(CustomCellRendererClass* klass);
+
+static void custom_cell_renderer_init(GTypeInstance* instance, gpointer)
+{
+    new (&CUSTOM_CELL_RENDERER(instance)->device) VclPtr<VirtualDevice>;
+}
+
+GType custom_cell_renderer_get_type()
+{
+    static GType type = 0;
+
+    if (!type)
+    {
+        static const GTypeInfo tinfo = {
+            sizeof(CustomCellRendererClass),
+            nullptr, /* base init */
+            nullptr, /* base finalize */
+            reinterpret_cast<GClassInitFunc>(custom_cell_renderer_class_init), /* class init */
+            nullptr, /* class finalize */
+            nullptr, /* class data */
+            sizeof(CustomCellRenderer), /* instance size */
+            0, /* nb preallocs */
+            &custom_cell_renderer_init, /* instance init */
+            nullptr /* value table */
+        };
+
+        // inherit from GtkCellRendererText so we can set the "text" property and get a11y support for that
+        type = g_type_register_static(GTK_TYPE_CELL_RENDERER_TEXT, "CustomCellRenderer", &tinfo,
+                                      GTypeFlags(0));
+    }
+
+    return type;
+}
+
+static void custom_cell_renderer_get_property(GObject* object, guint param_id, GValue* value,
+                                              GParamSpec* pspec)
+{
+    CustomCellRenderer* cellsurface = CUSTOM_CELL_RENDERER(object);
+
+    switch (param_id)
+    {
+        case PROP_ID:
+            g_value_set_string(value, cellsurface->id);
+            break;
+        case PROP_INSTANCE_TREE_VIEW:
+            g_value_set_pointer(value, cellsurface->instance);
+            break;
+        default:
+            G_OBJECT_CLASS(custom_cell_renderer_parent_class)
+                ->get_property(object, param_id, value, pspec);
+            break;
+    }
+}
+
+static void custom_cell_renderer_set_property(GObject* object, guint param_id, const GValue* value,
+                                              GParamSpec* pspec)
+{
+    CustomCellRenderer* cellsurface = CUSTOM_CELL_RENDERER(object);
+
+    switch (param_id)
+    {
+        case PROP_ID:
+            g_free(cellsurface->id);
+            cellsurface->id = g_value_dup_string(value);
+            break;
+        case PROP_INSTANCE_TREE_VIEW:
+            cellsurface->instance = g_value_get_pointer(value);
+            break;
+        default:
+            G_OBJECT_CLASS(custom_cell_renderer_parent_class)
+                ->set_property(object, param_id, value, pspec);
+            break;
+    }
+}
+
+static bool custom_cell_renderer_get_preferred_size(GtkCellRenderer* cell,
+                                                    GtkOrientation orientation, gint* minimum_size,
+                                                    gint* natural_size);
+
+#if !GTK_CHECK_VERSION(4, 0, 0)
+static void custom_cell_renderer_render(GtkCellRenderer* cell, cairo_t* cr, GtkWidget* widget,
+                                        const GdkRectangle* background_area,
+                                        const GdkRectangle* cell_area, GtkCellRendererState flags);
+#endif
+
+static void custom_cell_renderer_finalize(GObject* object)
+{
+    CustomCellRenderer* cellsurface = CUSTOM_CELL_RENDERER(object);
+
+    g_free(cellsurface->id);
+    cellsurface->device.disposeAndClear();
+    cellsurface->device.~VclPtr<VirtualDevice>();
+
+    G_OBJECT_CLASS(custom_cell_renderer_parent_class)->finalize(object);
+}
+
+static void custom_cell_renderer_get_preferred_width(GtkCellRenderer* cell, GtkWidget* widget,
+                                                     gint* minimum_size, gint* natural_size)
+{
+    if (!custom_cell_renderer_get_preferred_size(cell, GTK_ORIENTATION_HORIZONTAL, minimum_size,
+                                                 natural_size))
+    {
+        // fallback to parent if we're empty
+        GTK_CELL_RENDERER_CLASS(custom_cell_renderer_parent_class)
+            ->get_preferred_width(cell, widget, minimum_size, natural_size);
+    }
+}
+
+static void custom_cell_renderer_get_preferred_height(GtkCellRenderer* cell, GtkWidget* widget,
+                                                      gint* minimum_size, gint* natural_size)
+{
+    if (!custom_cell_renderer_get_preferred_size(cell, GTK_ORIENTATION_VERTICAL, minimum_size,
+                                                 natural_size))
+    {
+        // fallback to parent if we're empty
+        GTK_CELL_RENDERER_CLASS(custom_cell_renderer_parent_class)
+            ->get_preferred_height(cell, widget, minimum_size, natural_size);
+    }
+}
+
+static void custom_cell_renderer_get_preferred_height_for_width(GtkCellRenderer* cell,
+                                                                GtkWidget* widget, gint /*width*/,
+                                                                gint* minimum_height,
+                                                                gint* natural_height)
+{
+    gtk_cell_renderer_get_preferred_height(cell, widget, minimum_height, natural_height);
+}
+
+static void custom_cell_renderer_get_preferred_width_for_height(GtkCellRenderer* cell,
+                                                                GtkWidget* widget, gint /*height*/,
+                                                                gint* minimum_width,
+                                                                gint* natural_width)
+{
+    gtk_cell_renderer_get_preferred_width(cell, widget, minimum_width, natural_width);
+}
+
+void custom_cell_renderer_class_init(CustomCellRendererClass* klass)
+{
+    GtkCellRendererClass* cell_class = GTK_CELL_RENDERER_CLASS(klass);
+    GObjectClass* object_class = G_OBJECT_CLASS(klass);
+
+    /* Hook up functions to set and get our custom cell renderer properties */
+    object_class->get_property = custom_cell_renderer_get_property;
+    object_class->set_property = custom_cell_renderer_set_property;
+
+    custom_cell_renderer_parent_class = g_type_class_peek_parent(klass);
+    object_class->finalize = custom_cell_renderer_finalize;
+
+    cell_class->get_preferred_width = custom_cell_renderer_get_preferred_width;
+    cell_class->get_preferred_height = custom_cell_renderer_get_preferred_height;
+    cell_class->get_preferred_width_for_height
+        = custom_cell_renderer_get_preferred_width_for_height;
+    cell_class->get_preferred_height_for_width
+        = custom_cell_renderer_get_preferred_height_for_width;
+
+#if !GTK_CHECK_VERSION(4, 0, 0)
+    cell_class->render = custom_cell_renderer_render;
+#endif
+
+    g_object_class_install_property(
+        object_class, PROP_ID,
+        g_param_spec_string("id", "ID", "The ID of the custom data", nullptr, G_PARAM_READWRITE));
+
+    g_object_class_install_property(
+        object_class, PROP_INSTANCE_TREE_VIEW,
+        g_param_spec_pointer("instance", "Instance", "The GtkInstanceTreeView", G_PARAM_READWRITE));
+
+#if !GTK_CHECK_VERSION(4, 0, 0)
+    gtk_cell_renderer_class_set_accessible_type(cell_class, GTK_TYPE_TEXT_CELL_ACCESSIBLE);
+#endif
+}
+
+GtkCellRenderer* custom_cell_renderer_new()
+{
+    return GTK_CELL_RENDERER(g_object_new(CUSTOM_TYPE_CELL_RENDERER, nullptr));
+}
+
+bool custom_cell_renderer_get_preferred_size(GtkCellRenderer* cell, GtkOrientation orientation,
+                                             gint* minimum_size, gint* natural_size)
+{
+    GValue value = G_VALUE_INIT;
+    g_value_init(&value, G_TYPE_STRING);
+    g_object_get_property(G_OBJECT(cell), "id", &value);
+
+    const char* pStr = g_value_get_string(&value);
+
+    OUString sId(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+
+    value = G_VALUE_INIT;
+    g_value_init(&value, G_TYPE_POINTER);
+    g_object_get_property(G_OBJECT(cell), "instance", &value);
+
+    CustomCellRenderer* cellsurface = CUSTOM_CELL_RENDERER(cell);
+
+    Size aSize;
+
+    gpointer pWidget = g_value_get_pointer(&value);
+    if (pWidget)
+    {
+        custom_cell_renderer_ensure_device(cellsurface, pWidget);
+        aSize = custom_cell_renderer_get_size(*cellsurface->device, sId, pWidget);
+    }
+
+    if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+        if (minimum_size)
+            *minimum_size = aSize.Width();
+
+        if (natural_size)
+            *natural_size = aSize.Width();
+    }
+    else
+    {
+        if (minimum_size)
+            *minimum_size = aSize.Height();
+
+        if (natural_size)
+            *natural_size = aSize.Height();
+    }
+
+    return true;
+}
+
+#if !GTK_CHECK_VERSION(4, 0, 0)
+void custom_cell_renderer_render(GtkCellRenderer* cell, cairo_t* cr, GtkWidget* /*widget*/,
+                                 const GdkRectangle* /*background_area*/,
+                                 const GdkRectangle* cell_area, GtkCellRendererState flags)
+{
+    GValue value = G_VALUE_INIT;
+    g_value_init(&value, G_TYPE_STRING);
+    g_object_get_property(G_OBJECT(cell), "id", &value);
+
+    const char* pStr = g_value_get_string(&value);
+    OUString sId(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+
+    value = G_VALUE_INIT;
+    g_value_init(&value, G_TYPE_POINTER);
+    g_object_get_property(G_OBJECT(cell), "instance", &value);
+
+    CustomCellRenderer* cellsurface = CUSTOM_CELL_RENDERER(cell);
+
+    gpointer pWidget = g_value_get_pointer(&value);
+    if (!pWidget)
+        return;
+    custom_cell_renderer_ensure_device(cellsurface, pWidget);
+
+    Size aSize(cell_area->width, cell_area->height);
+    // false to not bother setting the bg on resize as we'll do that
+    // ourself via cairo
+    cellsurface->device->SetOutputSizePixel(aSize, false);
+
+    cairo_surface_t* pSurface = get_underlying_cairo_surface(*cellsurface->device);
+
+    // fill surface as transparent so it can be blended with the potentially
+    // selected background
+    cairo_t* tempcr = cairo_create(pSurface);
+    cairo_set_source_rgba(tempcr, 0, 0, 0, 0);
+    cairo_set_operator(tempcr, CAIRO_OPERATOR_SOURCE);
+    cairo_paint(tempcr);
+    cairo_destroy(tempcr);
+    cairo_surface_flush(pSurface);
+
+    custom_cell_renderer_render(*cellsurface->device, tools::Rectangle(Point(0, 0), aSize),
+                                static_cast<bool>(flags & GTK_CELL_RENDERER_SELECTED), sId,
+                                pWidget);
+
+    cairo_surface_mark_dirty(pSurface);
+
+    cairo_set_source_surface(cr, pSurface, cell_area->x, cell_area->y);
+    cairo_paint(cr);
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3/customcellrenderer.hxx b/vcl/unx/gtk3/customcellrenderer.hxx
new file mode 100644
index 000000000000..a4d847e7c29a
--- /dev/null
+++ b/vcl/unx/gtk3/customcellrenderer.hxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+#include <vcl/virdev.hxx>
+
+G_BEGIN_DECLS
+
+struct _CustomCellRenderer
+{
+    GtkCellRendererText parent;
+    VclPtr<VirtualDevice> device;
+    gchar* id;
+    gpointer instance;
+};
+
+/*
+   Provide a mechanism to support custom rendering of cells in a GtkTreeView/GtkComboBox
+*/
+
+G_DECLARE_FINAL_TYPE(CustomCellRenderer, custom_cell_renderer, CUSTOM, CELL_RENDERER,
+                     GtkCellRendererText)
+
+#define CUSTOM_TYPE_CELL_RENDERER (custom_cell_renderer_get_type())
+
+#define CUSTOM_CELL_RENDERER(obj)                                                                  \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj), CUSTOM_TYPE_CELL_RENDERER, CustomCellRenderer))
+
+#define CUSTOM_IS_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER))
+
+GtkCellRenderer* custom_cell_renderer_new();
+
+G_END_DECLS
+
+void custom_cell_renderer_ensure_device(CustomCellRenderer* cellsurface, gpointer user_data);
+Size custom_cell_renderer_get_size(VirtualDevice& rDevice, const OUString& rCellId,
+                                   gpointer user_data);
+void custom_cell_renderer_render(VirtualDevice& rDevice, const tools::Rectangle& rRect,
+                                 bool bSelected, const OUString& rId, gpointer user_data);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 9d82df343911..036fca44169c 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -86,6 +86,7 @@
 #include <vcl/virdev.hxx>
 #include <vcl/weld.hxx>
 #include <vcl/wrkwin.hxx>
+#include "customcellrenderer.hxx"
 #include <strings.hrc>
 #include <window.h>
 #include <numeric>
@@ -6983,230 +6984,6 @@ GType immobilized_viewport_get_type()
     return type;
 }
 
-#define CUSTOM_TYPE_CELL_RENDERER             (custom_cell_renderer_get_type())
-#define CUSTOM_CELL_RENDERER(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),  CUSTOM_TYPE_CELL_RENDERER, CustomCellRenderer))
-#define CUSTOM_IS_CELL_RENDERER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CUSTOM_TYPE_CELL_RENDERER))
-
-namespace {
-
-    struct CustomCellRenderer
-    {
-        GtkCellRendererText parent;
-        VclPtr<VirtualDevice> device;
-        gchar *id;
-        gpointer instance;
-    };
-
-    struct CustomCellRendererClass
-    {
-        GtkCellRendererTextClass parent_class;
-    };
-
-    enum
-    {
-        PROP_ID = 10000,
-        PROP_INSTANCE_TREE_VIEW = 10001
-    };
-}
-
-static gpointer custom_cell_renderer_parent_class;
-
-static GType custom_cell_renderer_get_type();
-static void custom_cell_renderer_class_init(CustomCellRendererClass *klass);
-
-static void custom_cell_renderer_init(GTypeInstance * instance, gpointer) {
-    new(&CUSTOM_CELL_RENDERER(instance)->device) VclPtr<VirtualDevice>;
-}
-
-GType custom_cell_renderer_get_type()
-{
-    static GType type = 0;
-
-    if (!type)
-    {
-        static const GTypeInfo tinfo =
-        {
-            sizeof (CustomCellRendererClass),
-            nullptr, /* base init */
-            nullptr, /* base finalize */
-            reinterpret_cast<GClassInitFunc>(custom_cell_renderer_class_init), /* class init */
-            nullptr, /* class finalize */
-            nullptr, /* class data */
-            sizeof (CustomCellRenderer), /* instance size */
-            0,       /* nb preallocs */
-            &custom_cell_renderer_init, /* instance init */
-            nullptr  /* value table */
-        };
-
-        // inherit from GtkCellRendererText so we can set the "text" property and get a11y support for that
-        type = g_type_register_static(GTK_TYPE_CELL_RENDERER_TEXT, "CustomCellRenderer",
-                                      &tinfo, GTypeFlags(0));
-    }
-
-    return type;
-}
-
-static void custom_cell_renderer_get_property(GObject *object,
-                                                      guint param_id,
-                                                      GValue *value,
-                                                      GParamSpec *pspec)
-{
-    CustomCellRenderer *cellsurface = CUSTOM_CELL_RENDERER(object);
-
-    switch (param_id)
-    {
-        case PROP_ID:
-            g_value_set_string(value, cellsurface->id);
-            break;
-        case PROP_INSTANCE_TREE_VIEW:
-            g_value_set_pointer(value, cellsurface->instance);
-            break;
-        default:
-            G_OBJECT_CLASS(custom_cell_renderer_parent_class)->get_property(object, param_id, value, pspec);
-            break;
-    }
-}
-
-static void custom_cell_renderer_set_property(GObject *object,
-                                                      guint param_id,
-                                                      const GValue *value,
-                                                      GParamSpec *pspec)
-{
-    CustomCellRenderer *cellsurface = CUSTOM_CELL_RENDERER(object);
-
-    switch (param_id)
-    {
-        case PROP_ID:
-            g_free(cellsurface->id);
-            cellsurface->id = g_value_dup_string(value);
-            break;
-        case PROP_INSTANCE_TREE_VIEW:
-            cellsurface->instance = g_value_get_pointer(value);
-            break;
-        default:
-            G_OBJECT_CLASS(custom_cell_renderer_parent_class)->set_property(object, param_id, value, pspec);
-            break;
-    }
-}
-
-static bool custom_cell_renderer_get_preferred_size(GtkCellRenderer *cell,
-                                                            GtkOrientation orientation,
-                                                            gint *minimum_size,
-                                                            gint *natural_size);
-
-#if !GTK_CHECK_VERSION(4, 0, 0)
-static void custom_cell_renderer_render(GtkCellRenderer* cell,
-                                                cairo_t* cr,
-                                                GtkWidget* widget,
-                                                const GdkRectangle* background_area,
-                                                const GdkRectangle* cell_area,
-                                                GtkCellRendererState flags);
-#endif
-
-static void custom_cell_renderer_finalize(GObject *object)
-{
-    CustomCellRenderer *cellsurface = CUSTOM_CELL_RENDERER(object);
-
-    g_free(cellsurface->id);
-    cellsurface->device.disposeAndClear();
-    cellsurface->device.~VclPtr<VirtualDevice>();
-
-    G_OBJECT_CLASS(custom_cell_renderer_parent_class)->finalize(object);
-}
-
-static void custom_cell_renderer_get_preferred_width(GtkCellRenderer *cell,
-                                                             GtkWidget *widget,
-                                                             gint *minimum_size,
-                                                             gint *natural_size)
-{
-    if (!custom_cell_renderer_get_preferred_size(cell, GTK_ORIENTATION_HORIZONTAL,
-                                                         minimum_size, natural_size))
-    {
-        // fallback to parent if we're empty
-        GTK_CELL_RENDERER_CLASS(custom_cell_renderer_parent_class)->get_preferred_width(cell,
-            widget, minimum_size, natural_size);
-    }
-}
-
-static void custom_cell_renderer_get_preferred_height(GtkCellRenderer *cell,
-                                                              GtkWidget *widget,
-                                                              gint *minimum_size,
-                                                              gint *natural_size)
-{
-    if (!custom_cell_renderer_get_preferred_size(cell, GTK_ORIENTATION_VERTICAL,
-                                                         minimum_size, natural_size))
-    {
-        // fallback to parent if we're empty
-        GTK_CELL_RENDERER_CLASS(custom_cell_renderer_parent_class)->get_preferred_height(cell,
-            widget, minimum_size, natural_size);
-    }
-
-}
-
-static void custom_cell_renderer_get_preferred_height_for_width(GtkCellRenderer *cell,
-                                                                        GtkWidget *widget,
-                                                                        gint /*width*/,
-                                                                        gint *minimum_height,
-                                                                        gint *natural_height)
-{
-    gtk_cell_renderer_get_preferred_height(cell, widget, minimum_height, natural_height);
-}
-
-static void custom_cell_renderer_get_preferred_width_for_height(GtkCellRenderer *cell,
-                                                                        GtkWidget *widget,
-                                                                        gint /*height*/,
-                                                                        gint *minimum_width,
-                                                                        gint *natural_width)
-{
-    gtk_cell_renderer_get_preferred_width(cell, widget, minimum_width, natural_width);
-}
-
-void custom_cell_renderer_class_init(CustomCellRendererClass *klass)
-{
-    GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(klass);
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
-    /* Hook up functions to set and get our custom cell renderer properties */
-    object_class->get_property = custom_cell_renderer_get_property;
-    object_class->set_property = custom_cell_renderer_set_property;
-
-    custom_cell_renderer_parent_class = g_type_class_peek_parent(klass);
-    object_class->finalize = custom_cell_renderer_finalize;
-
-    cell_class->get_preferred_width = custom_cell_renderer_get_preferred_width;
-    cell_class->get_preferred_height = custom_cell_renderer_get_preferred_height;
-    cell_class->get_preferred_width_for_height = custom_cell_renderer_get_preferred_width_for_height;
-    cell_class->get_preferred_height_for_width = custom_cell_renderer_get_preferred_height_for_width;
-
-#if !GTK_CHECK_VERSION(4, 0, 0)
-    cell_class->render = custom_cell_renderer_render;
-#endif
-
-    g_object_class_install_property(object_class,
-                                   PROP_ID,
-                                   g_param_spec_string("id",
-                                                       "ID",
-                                                       "The ID of the custom data",
-                                                       nullptr,
-                                                       G_PARAM_READWRITE));
-
-    g_object_class_install_property(object_class,
-                                   PROP_INSTANCE_TREE_VIEW,
-                                   g_param_spec_pointer("instance",
-                                                        "Instance",
-                                                        "The GtkInstanceTreeView",
-                                                        G_PARAM_READWRITE));
-
-#if !GTK_CHECK_VERSION(4, 0, 0)
-    gtk_cell_renderer_class_set_accessible_type(cell_class, GTK_TYPE_TEXT_CELL_ACCESSIBLE);
-#endif
-}
-
-static GtkCellRenderer* custom_cell_renderer_new()
-{
-    return GTK_CELL_RENDERER(g_object_new(CUSTOM_TYPE_CELL_RENDERER, nullptr));
-}
-
 static VclPolicyType GtkToVcl(GtkPolicyType eType)
 {
     VclPolicyType eRet(VclPolicyType::NEVER);
@@ -15104,17 +14881,6 @@ public:
     }
 };
 
-void ensure_device(CustomCellRenderer *cellsurface, weld::Widget* pWidget)
-{
-    if (!cellsurface->device)
-    {
-        cellsurface->device = VclPtr<VirtualDevice>::Create();
-        cellsurface->device->SetBackground(COL_TRANSPARENT);
-        // expand the point size of the desired font to the equivalent pixel size
-        weld::SetPointFont(*cellsurface->device, pWidget->get_font());
-    }
-}
-
 }
 
 IMPL_LINK_NOARG(GtkInstanceTreeView, async_signal_changed, void*, void)
@@ -20628,112 +20394,36 @@ public:
 
 }
 
-bool custom_cell_renderer_get_preferred_size(GtkCellRenderer *cell,
-                                                     GtkOrientation orientation,
-                                                     gint *minimum_size,
-                                                     gint *natural_size)
+void custom_cell_renderer_ensure_device(CustomCellRenderer *cellsurface, gpointer user_data)
 {
-    GValue value = G_VALUE_INIT;
-    g_value_init(&value, G_TYPE_STRING);
-    g_object_get_property(G_OBJECT(cell), "id", &value);
-
-    const char* pStr = g_value_get_string(&value);
-
-    OUString sId(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
-
-    value = G_VALUE_INIT;
-    g_value_init(&value, G_TYPE_POINTER);
-    g_object_get_property(G_OBJECT(cell), "instance", &value);
-
-    CustomCellRenderer *cellsurface = CUSTOM_CELL_RENDERER(cell);
-
-    GtkInstanceWidget* pWidget = static_cast<GtkInstanceWidget*>(g_value_get_pointer(&value));
-
-    Size aSize;
-
-    if (pWidget)
-    {
-        ensure_device(cellsurface, pWidget);
-        if (GtkInstanceTreeView* pTreeView = dynamic_cast<GtkInstanceTreeView*>(pWidget))
-            aSize = pTreeView->call_signal_custom_get_size(*cellsurface->device, sId);
-        else if (GtkInstanceComboBox* pComboBox = dynamic_cast<GtkInstanceComboBox*>(pWidget))
-            aSize = pComboBox->call_signal_custom_get_size(*cellsurface->device);
-    }
-
-    if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    {
-        if (minimum_size)
-            *minimum_size = aSize.Width();
-
-        if (natural_size)
-            *natural_size = aSize.Width();
-    }
-    else
+    if (!cellsurface->device)
     {
-        if (minimum_size)
-            *minimum_size = aSize.Height();
-
-        if (natural_size)
-            *natural_size = aSize.Height();
+        cellsurface->device = VclPtr<VirtualDevice>::Create();
+        cellsurface->device->SetBackground(COL_TRANSPARENT);
+        GtkInstanceWidget* pWidget = static_cast<GtkInstanceWidget*>(user_data);
+        // expand the point size of the desired font to the equivalent pixel size
+        weld::SetPointFont(*cellsurface->device, pWidget->get_font());
     }
-
-    return true;
 }
 
-#if !GTK_CHECK_VERSION(4, 0, 0)
-void custom_cell_renderer_render(GtkCellRenderer* cell,
-                                         cairo_t* cr,
-                                         GtkWidget* /*widget*/,
-                                         const GdkRectangle* /*background_area*/,
-                                         const GdkRectangle* cell_area,
-                                         GtkCellRendererState flags)
+Size custom_cell_renderer_get_size(VirtualDevice& rDevice, const OUString& rCellId, gpointer user_data)
 {
-    GValue value = G_VALUE_INIT;
-    g_value_init(&value, G_TYPE_STRING);
-    g_object_get_property(G_OBJECT(cell), "id", &value);
-
-    const char* pStr = g_value_get_string(&value);
-    OUString sId(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
-
-    value = G_VALUE_INIT;
-    g_value_init(&value, G_TYPE_POINTER);
-    g_object_get_property(G_OBJECT(cell), "instance", &value);
-
-    CustomCellRenderer *cellsurface = CUSTOM_CELL_RENDERER(cell);
-
-    GtkInstanceWidget* pWidget = static_cast<GtkInstanceWidget*>(g_value_get_pointer(&value));
-
-    if (!pWidget)
-        return;
-
-    ensure_device(cellsurface, pWidget);
-
-    Size aSize(cell_area->width, cell_area->height);
-    // false to not bother setting the bg on resize as we'll do that
-    // ourself via cairo
-    cellsurface->device->SetOutputSizePixel(aSize, false);
-
-    cairo_surface_t* pSurface = get_underlying_cairo_surface(*cellsurface->device);
-
-    // fill surface as transparent so it can be blended with the potentially
-    // selected background
-    cairo_t* tempcr = cairo_create(pSurface);
-    cairo_set_source_rgba(tempcr, 0, 0, 0, 0);
-    cairo_set_operator(tempcr, CAIRO_OPERATOR_SOURCE);
-    cairo_paint(tempcr);
-    cairo_destroy(tempcr);
-    cairo_surface_flush(pSurface);
-
+    GtkInstanceWidget* pWidget = static_cast<GtkInstanceWidget*>(user_data);
     if (GtkInstanceTreeView* pTreeView = dynamic_cast<GtkInstanceTreeView*>(pWidget))
-        pTreeView->call_signal_custom_render(*cellsurface->device, tools::Rectangle(Point(0, 0), aSize), flags & GTK_CELL_RENDERER_SELECTED, sId);
+        return pTreeView->call_signal_custom_get_size(rDevice, rCellId);
     else if (GtkInstanceComboBox* pComboBox = dynamic_cast<GtkInstanceComboBox*>(pWidget))
-        pComboBox->call_signal_custom_render(*cellsurface->device, tools::Rectangle(Point(0, 0), aSize), flags & GTK_CELL_RENDERER_SELECTED, sId);
-    cairo_surface_mark_dirty(pSurface);
+        return pComboBox->call_signal_custom_get_size(rDevice);
+    return Size();
+}
 
-    cairo_set_source_surface(cr, pSurface, cell_area->x, cell_area->y);
-    cairo_paint(cr);
+void custom_cell_renderer_render(VirtualDevice& rDevice, const tools::Rectangle& rRect, bool bSelected, const OUString& rCellId, gpointer user_data)
+{
+    GtkInstanceWidget* pWidget = static_cast<GtkInstanceWidget*>(user_data);
+    if (GtkInstanceTreeView* pTreeView = dynamic_cast<GtkInstanceTreeView*>(pWidget))
+        pTreeView->call_signal_custom_render(rDevice, rRect, bSelected, rCellId);
+    else if (GtkInstanceComboBox* pComboBox = dynamic_cast<GtkInstanceComboBox*>(pWidget))
+        pComboBox->call_signal_custom_render(rDevice, rRect, bSelected, rCellId);
 }
-#endif
 
 namespace {
 
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_customcellrenderer.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_customcellrenderer.cxx
new file mode 100644
index 000000000000..aebe2c89ed6b
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_customcellrenderer.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "../gtk3/customcellrenderer.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/vcl/unx/gtk4/customcellrenderer.cxx b/vcl/unx/gtk4/customcellrenderer.cxx
new file mode 100644
index 000000000000..aebe2c89ed6b
--- /dev/null
+++ b/vcl/unx/gtk4/customcellrenderer.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "../gtk3/customcellrenderer.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */


More information about the Libreoffice-commits mailing list