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 <[email protected]> AuthorDate: Sun Jun 27 19:40:50 2021 +0100 Commit: Caolán McNamara <[email protected]> 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 <[email protected]> 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: */ _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
