include/svx/dialog/ThemeDialog.hxx |    9 +---
 svx/source/dialog/ThemeDialog.cxx  |   81 +++++++++++++++++++++++++++----------
 svx/uiconfig/ui/themedialog.ui     |   33 +++++++++------
 3 files changed, 85 insertions(+), 38 deletions(-)

New commits:
commit 7f59741c939f37714f0e4cd8019b40d82ead1c0e
Author:     Parth Raiyani <parth.raiy...@collabora.com>
AuthorDate: Fri May 23 18:22:42 2025 +0530
Commit:     Szymon Kłos <szymon.k...@collabora.com>
CommitDate: Wed Jun 4 14:36:38 2025 +0200

    Switch to IconView in ThemeDialog for improved UI handling
    
    - Replaces ValueSet with IconView widget in the ThemeDialog.
    - Cleans up redundant code related to ValueSet and updates the themedialog 
UI file to support IconView.
    
    Change-Id: Ia36aa6174cde2756aadadcbde4c5bdba2201d1a1
    Signed-off-by: Parth Raiyani <parth.raiy...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185715
    Reviewed-by: Szymon Kłos <szymon.k...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/include/svx/dialog/ThemeDialog.hxx 
b/include/svx/dialog/ThemeDialog.hxx
index 5b534ea4785a..b252d18183c5 100644
--- a/include/svx/dialog/ThemeDialog.hxx
+++ b/include/svx/dialog/ThemeDialog.hxx
@@ -13,7 +13,6 @@
 #include <vcl/weld.hxx>
 #include <svx/svdpage.hxx>
 #include <svx/dialog/ThemeColorEditDialog.hxx>
-#include <svx/dialog/ThemeColorValueSet.hxx>
 
 namespace model
 {
@@ -32,21 +31,21 @@ private:
     std::shared_ptr<svx::ThemeColorEditDialog> mxSubDialog;
     std::vector<model::ColorSet> maColorSets;
 
-    std::unique_ptr<svx::ThemeColorValueSet> mxValueSetThemeColors;
-    std::unique_ptr<weld::CustomWeld> mxValueSetThemeColorsWindow;
+    std::unique_ptr<weld::IconView> mxIconViewThemeColors;
     std::unique_ptr<weld::Button> mxAdd;
 
     std::shared_ptr<model::ColorSet> mpCurrentColorSet;
 
     void runThemeColorEditDialog();
     void initColorSets();
+    static VclPtr<VirtualDevice> CreateColorSetPreview(const model::ColorSet& 
rColorSet);
 
 public:
     ThemeDialog(weld::Window* pParent, model::Theme* pTheme);
     virtual ~ThemeDialog() override;
 
-    DECL_LINK(DoubleClickValueSetHdl, ValueSet*, void);
-    DECL_LINK(SelectItem, ValueSet*, void);
+    DECL_LINK(ItemActivatedHdl, weld::IconView&, bool);
+    DECL_LINK(SelectionChangedHdl, weld::IconView&, void);
     DECL_LINK(ButtonClicked, weld::Button&, void);
 
     std::shared_ptr<model::ColorSet> const& getCurrentColorSet() { return 
mpCurrentColorSet; }
diff --git a/svx/source/dialog/ThemeDialog.cxx 
b/svx/source/dialog/ThemeDialog.cxx
index d20ce3be360b..cbc4248cb371 100644
--- a/svx/source/dialog/ThemeDialog.cxx
+++ b/svx/source/dialog/ThemeDialog.cxx
@@ -13,6 +13,7 @@
 #include <svx/ColorSets.hxx>
 #include <vcl/svapp.hxx>
 #include <comphelper/lok.hxx>
+#include <vcl/virdev.hxx>
 
 namespace svx
 {
@@ -20,16 +21,11 @@ ThemeDialog::ThemeDialog(weld::Window* pParent, 
model::Theme* pTheme)
     : GenericDialogController(pParent, u"svx/ui/themedialog.ui"_ustr, 
u"ThemeDialog"_ustr)
     , mpWindow(pParent)
     , mpTheme(pTheme)
-    , mxValueSetThemeColors(new svx::ThemeColorValueSet)
-    , mxValueSetThemeColorsWindow(
-          new weld::CustomWeld(*m_xBuilder, u"valueset_theme_colors"_ustr, 
*mxValueSetThemeColors))
+    , 
mxIconViewThemeColors(m_xBuilder->weld_icon_view(u"iconview_theme_colors"_ustr))
     , mxAdd(m_xBuilder->weld_button(u"button_add"_ustr))
 {
-    mxValueSetThemeColors->SetColCount(3);
-    mxValueSetThemeColors->SetLineCount(4);
-    
mxValueSetThemeColors->SetColor(Application::GetSettings().GetStyleSettings().GetFaceColor());
-    mxValueSetThemeColors->SetDoubleClickHdl(LINK(this, ThemeDialog, 
DoubleClickValueSetHdl));
-    mxValueSetThemeColors->SetSelectHdl(LINK(this, ThemeDialog, SelectItem));
+    mxIconViewThemeColors->connect_item_activated(LINK(this, ThemeDialog, 
ItemActivatedHdl));
+    mxIconViewThemeColors->connect_selection_changed(LINK(this, ThemeDialog, 
SelectionChangedHdl));
 
     mxAdd->connect_clicked(LINK(this, ThemeDialog, ButtonClicked));
 
@@ -37,7 +33,7 @@ ThemeDialog::ThemeDialog(weld::Window* pParent, model::Theme* 
pTheme)
 
     if (!maColorSets.empty())
     {
-        mxValueSetThemeColors->SelectItem(1); // ItemId 1, position 0
+        mxIconViewThemeColors->select(0);
         mpCurrentColorSet = std::make_shared<model::ColorSet>(maColorSets[0]);
     }
 }
@@ -56,28 +52,73 @@ void ThemeDialog::initColorSets()
     auto const& rColorSetVector = ColorSets::get().getColorSetVector();
     maColorSets.insert(maColorSets.end(), rColorSetVector.begin(), 
rColorSetVector.end());
 
-    for (auto const& rColorSet : maColorSets)
+    for (size_t i = 0; i < maColorSets.size(); ++i)
     {
-        mxValueSetThemeColors->insert(rColorSet);
+        auto const& rColorSet = maColorSets[i];
+        VclPtr<VirtualDevice> pVirDev = CreateColorSetPreview(rColorSet);
+
+        OUString sId = OUString::number(i);
+        OUString sName = rColorSet.getName();
+        mxIconViewThemeColors->insert(-1, &sName, &sId, pVirDev, nullptr);
     }
+}
+
+VclPtr<VirtualDevice> ThemeDialog::CreateColorSetPreview(const 
model::ColorSet& rColorSet)
+{
+    VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
+    const Size aSize(100, 50);
+    pVDev->SetOutputSizePixel(aSize);
+
+    const int nRows = 2;
+    const int nCols = 4;
+    const int nHorizontalPadding = 9;
+    const int nVerticalPadding = 3;
+    const int nMargin = 3;
+
+    const int nAvailableWidth = aSize.Width() - (2 * nHorizontalPadding);
+    const int nAvailableHeight = aSize.Height() - (2 * nVerticalPadding);
+
+    const int nColorCellHeight = (nAvailableHeight - ((nRows - 1) * nMargin)) 
/ nRows;
+    const int nColorCellWidth = (nAvailableWidth - ((nCols - 1) * nMargin)) / 
nCols;
 
-    mxValueSetThemeColors->SetOptimalSize();
+    // Draw border around entire color set
+    pVDev->SetLineColor(COL_LIGHTGRAY);
+    pVDev->DrawRect(tools::Rectangle(Point(0, 0), aSize));
+
+    for (int i = 0; i < 8; ++i)
+    {
+        const int nCol = i / 2;
+        const int nRow = i % 2;
+
+        const int nX = nHorizontalPadding + (nCol * (nColorCellWidth + 
nMargin));
+        const int nY = nVerticalPadding + (nRow * (nColorCellHeight + 
nMargin));
+
+        const tools::Rectangle aRect(Point(nX, nY), Size(nColorCellWidth, 
nColorCellHeight));
+
+        Color aColor = rColorSet.getColor(static_cast<model::ThemeColorType>(i 
+ 2));
+
+        pVDev->SetLineColor(COL_LIGHTGRAY);
+        pVDev->SetFillColor(aColor);
+        pVDev->DrawRect(aRect);
+    }
+    return pVDev;
 }
 
-IMPL_LINK_NOARG(ThemeDialog, DoubleClickValueSetHdl, ValueSet*, void)
+IMPL_LINK(ThemeDialog, ItemActivatedHdl, weld::IconView&, iter, bool)
 {
-    SelectItem(nullptr);
+    SelectionChangedHdl(iter);
     if (!comphelper::LibreOfficeKit::isActive())
         m_xDialog->response(RET_OK);
+    return true;
 }
 
-IMPL_LINK_NOARG(ThemeDialog, SelectItem, ValueSet*, void)
+IMPL_LINK_NOARG(ThemeDialog, SelectionChangedHdl, weld::IconView&, void)
 {
-    sal_uInt32 nItemId = mxValueSetThemeColors->GetSelectedItemId();
-    if (!nItemId)
+    OUString sId = mxIconViewThemeColors->get_selected_id();
+    if (sId.isEmpty())
         return;
 
-    sal_uInt32 nIndex = nItemId - 1;
+    sal_uInt32 nIndex = sId.toUInt32();
 
     if (nIndex >= maColorSets.size())
         return;
@@ -104,11 +145,11 @@ void ThemeDialog::runThemeColorEditDialog()
         {
             ColorSets::get().insert(aColorSet, 
ColorSets::IdenticalNameAction::AutoRename);
             maColorSets.clear();
-            mxValueSetThemeColors->Clear();
+            mxIconViewThemeColors->clear();
 
             initColorSets();
 
-            mxValueSetThemeColors->SelectItem(maColorSets.size() - 1);
+            mxIconViewThemeColors->select(maColorSets.size() - 1);
             mpCurrentColorSet
                 = 
std::make_shared<model::ColorSet>(maColorSets[maColorSets.size() - 1]);
         }
diff --git a/svx/uiconfig/ui/themedialog.ui b/svx/uiconfig/ui/themedialog.ui
index 20716a8b4d48..423d8a97059a 100644
--- a/svx/uiconfig/ui/themedialog.ui
+++ b/svx/uiconfig/ui/themedialog.ui
@@ -2,6 +2,16 @@
 <!-- Generated with glade 3.40.0 -->
 <interface domain="svx">
   <requires lib="gtk+" version="3.20"/>
+  <object class="GtkTreeStore" id="theme_colors_store">
+    <columns>
+      <!-- column-name pixbuf -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkDialog" id="ThemeDialog">
     <property name="can-focus">False</property>
     <property name="hexpand">True</property>
@@ -10,6 +20,8 @@
     <property name="title" translatable="yes" 
context="themedialog|Title">Theme</property>
     <property name="modal">True</property>
     <property name="type-hint">dialog</property>
+    <property name="default-width">405</property>
+    <property name="default-height">400</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialogBox1">
         <property name="can-focus">False</property>
@@ -91,22 +103,17 @@
                 <property name="margin-bottom">12</property>
                 <property name="hexpand">True</property>
                 <property name="vexpand">True</property>
-                <property name="hscrollbar-policy">never</property>
-                <property name="vscrollbar-policy">never</property>
                 <property name="shadow-type">in</property>
                 <child>
-                  <object class="GtkViewport">
+                  <object class="GtkIconView" id="iconview_theme_colors">
                     <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <child>
-                      <object class="GtkDrawingArea" 
id="valueset_theme_colors">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="events">GDK_BUTTON_PRESS_MASK | 
GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | 
GDK_STRUCTURE_MASK</property>
-                        <property name="hexpand">True</property>
-                        <property name="vexpand">True</property>
-                      </object>
-                    </child>
+                    <property name="can-focus">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="model">theme_colors_store</property>
+                    <property name="pixbuf-column">0</property>
+                    <property name="text-column">1</property>
+                    <property name="item-width">50</property>
                   </object>
                 </child>
               </object>

Reply via email to