From c0721600c294ebc46217477a80a8eea34609e4bc Mon Sep 17 00:00:00 2001 From: Michael Weghorn Date: Fri, 25 Jul 2025 14:55:34 +0200 Subject: [PATCH] tdf#167669 gtk: Use native GtkColorChooserDialog Following Change-Id: I29380607cdf3abe739a245aeb25526f643dfa537 Author: Michael Weghorn Date: Fri Jul 25 14:26:06 2025 +0200 tdf#167669 weld: Introduce weld::ColorChooserDialog , switch the GTK implementation to use a native GtkColorChooserDialog [1] for the weld::ColorChooserDialog implementation instead of using LibreOffice's custom GtkColorChooserDialog. Set GtkColorChooserDialog::show-editor [2] to true in order to not show a set of preselected colors on start, but show the more advanced control (that can otherwise be opened by clicking the "+" button) right away. This one is more similar to the LO one, and e.g. the "Font Color" popup in the Writer Formatting toolbar already provides a set of predefined colors to select from, so not showing another set when clicking the "Custom Color" button seems reasonable. Besides providing a more uniform experience across applications, using the native GtkColorChooserDialog also provides a color picker to select a color from a pixel on screen, which the custom LO implementation doesn't have. In the ColorDialog ctor, explicitly set the dialog to modal. This is already the case for the custom dialog used so far (and still used by anything except gtk3/gtk4 after this commit) as defined in the .ui file (cui/uiconfig/ui/colorpickerdialog.ui), but it's not the case for GtkColorChooserDialog by default. [1] https://docs.gtk.org/gtk3/class.ColorChooserDialog.html [2] https://docs.gtk.org/gtk3/property.ColorChooserDialog.show-editor.html Change-Id: If5bfb453b55c905ffe332707e2fb261a48664c31 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188344 Reviewed-by: Michael Weghorn Tested-by: Jenkins --- vcl/inc/strings.hrc | 2 ++ vcl/source/app/ColorDialog.cxx | 1 + vcl/unx/gtk3/gtkinst.cxx | 41 ++++++++++++++++++++++------------ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/vcl/inc/strings.hrc b/vcl/inc/strings.hrc index d8363504fb73..20693a71c617 100644 --- a/vcl/inc/strings.hrc +++ b/vcl/inc/strings.hrc @@ -135,4 +135,6 @@ #define RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL NC_("RID_STR_ACC_SCROLLBAR_NAME_HORIZONTAL", "Horizontal scroll bar") #define RID_STR_ACC_PANEL_DESCRIPTION NC_("RID_STR_ACC_PANEL_DESCRIPTION", "Please press enter to go into child control for more operations") +#define RID_STR_PICK_COLOR NC_("RID_STR_PICK_COLOR", "Pick a Color") + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/ColorDialog.cxx b/vcl/source/app/ColorDialog.cxx index 32042bec9e5c..589af550dc88 100644 --- a/vcl/source/app/ColorDialog.cxx +++ b/vcl/source/app/ColorDialog.cxx @@ -29,6 +29,7 @@ ColorDialog::ColorDialog(weld::Window* pParent, vcl::ColorPickerMode eMode) std::unique_ptr pDialog = GetSalInstance()->CreateColorChooserDialog(pParent, eMode); assert(pDialog); + pDialog->set_modal(true); m_pColorChooserDialogController = std::make_shared(std::move(pDialog)); } diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 2b8c4b539182..d90e834bd5e6 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -4489,6 +4489,11 @@ namespace return aColor; } + Color toVclColor(const GdkRGBA& rColor) + { + return Color(rColor.red * 255, rColor.green * 255, rColor.blue * 255); + } + OUString get_label(GtkLabel* pLabel) { const gchar* pStr = gtk_label_get_label(pLabel); @@ -7957,23 +7962,32 @@ public: class GtkInstanceColorChooserDialog : public GtkInstanceDialog, public virtual weld::ColorChooserDialog { - ScopedVclPtr m_pAbstractColorPickerDialog; + GtkColorChooserDialog* m_pColorChooserDialog; public: - GtkInstanceColorChooserDialog(AbstractColorPickerDialog* pColorDialog) - : GtkInstanceDialog( - dynamic_cast(pColorDialog->GetDialog())->getWindow(), nullptr, - false) - , m_pAbstractColorPickerDialog(pColorDialog) + GtkInstanceColorChooserDialog(GtkColorChooserDialog* pColorChooserDialog) + : GtkInstanceDialog(GTK_WINDOW(pColorChooserDialog), nullptr, true) + , m_pColorChooserDialog(pColorChooserDialog) { + assert(m_pColorChooserDialog); + gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(m_pColorChooserDialog), false); + + // directly show the advanced color editor + g_object_set(G_OBJECT(m_pColorChooserDialog), "show-editor", true, nullptr); } virtual void set_color(const Color& rColor) override { - m_pAbstractColorPickerDialog->SetColor(rColor); + GdkRGBA aColor = toGdkColor(rColor); + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(m_pColorChooserDialog), &aColor); } - virtual Color get_color() const override { return m_pAbstractColorPickerDialog->GetColor(); } + virtual Color get_color() const override + { + GdkRGBA aColor; + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(m_pColorChooserDialog), &aColor); + return toVclColor(aColor); + } }; } @@ -25160,13 +25174,12 @@ weld::MessageDialog* GtkInstance::CreateMessageDialog(weld::Widget* pParent, Vcl } std::unique_ptr -GtkInstance::CreateColorChooserDialog(weld::Window* pParent, vcl::ColorPickerMode eMode) +GtkInstance::CreateColorChooserDialog(weld::Window* pParent, vcl::ColorPickerMode) { - VclAbstractDialogFactory* pFact = VclAbstractDialogFactory::Create(); - assert(pFact); - VclPtr pDialog - = pFact->CreateColorPickerDialog(pParent, COL_BLACK, eMode); - assert(pDialog); + GtkInstanceWindow* pWindow = dynamic_cast(pParent); + GtkWindow* pGtkParent = pWindow ? pWindow->getWindow() : nullptr; + GtkColorChooserDialog* pDialog = GTK_COLOR_CHOOSER_DIALOG( + gtk_color_chooser_dialog_new(VclResId(RID_STR_PICK_COLOR).toUtf8().getStr(), pGtkParent)); return std::make_unique(pDialog); }