Related: tdf#152301 cache color widget width

Change-Id: I0030980e2259715aa1fa624eb0ee82d5dfc51810
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143778
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/source/options/optcolor.cxx b/cui/source/options/optcolor.cxx
index 4b5e4b30..42c299d 100644
--- a/cui/source/options/optcolor.cxx
+++ b/cui/source/options/optcolor.cxx
@@ -212,7 +212,7 @@ private:
    {
    public:
        Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const char* pTextWidget, const char* pColorWidget,
              const Color& rColor, int nCheckBoxLabelOffset, bool bCheckBox, bool bShow);
              const Color& rColor, int nCheckBoxLabelOffset, int* pColorWidthRequest, bool bCheckBox, bool bShow);
    public:
        void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
        int get_height_request() const
@@ -284,9 +284,10 @@ ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const char* pL
// ColorConfigWindow_Impl::Entry
ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
                                     const char* pTextWidget, const char* pColorWidget,
                                     const Color& rColor,
                                     int nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
    : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), [pTopLevel]{ return pTopLevel; }))
                                     const Color& rColor, int nCheckBoxLabelOffset,
                                     int* pColorWidthRequestCache, bool bCheckBox, bool bShow)
    : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget),
                                    [pTopLevel]{ return pTopLevel; }, pColorWidthRequestCache))
    , m_aDefaultColor(rColor)
{
    if (bCheckBox)
@@ -404,6 +405,8 @@ void ColorConfigWindow_Impl::CreateEntries()
        m_nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
    }

    int nColorWidthRequestCache = -1;

    // creating entries
    vEntries.reserve(ColorConfigEntryCount);
    for (size_t i = 0; i < std::size(vEntryInfo); ++i)
@@ -411,7 +414,7 @@ void ColorConfigWindow_Impl::CreateEntries()
        vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
            vEntryInfo[i].pText, vEntryInfo[i].pColor,
            ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
            m_nCheckBoxLabelOffset,
            m_nCheckBoxLabelOffset, &nColorWidthRequestCache,
            vEntryInfo[i].bCheckBox,
            aModulesInstalled[vEntryInfo[i].eGroup]));
    }
@@ -445,7 +448,7 @@ void ColorConfigWindow_Impl::CreateEntries()
                aExtConfig.GetComponentColorConfigValue(sComponentName, i);
            vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
                "label", "button", aColorEntry.getDefaultColor(),
                m_nCheckBoxLabelOffset, false, true));
                m_nCheckBoxLabelOffset, &nColorWidthRequestCache, false, true));
            vEntries.back()->SetText(aColorEntry.getDisplayName());
        }
    }
diff --git a/include/svx/colorbox.hxx b/include/svx/colorbox.hxx
index ff635c9..887edb9 100644
--- a/include/svx/colorbox.hxx
+++ b/include/svx/colorbox.hxx
@@ -45,7 +45,8 @@ private:

    void Selected(const svx::NamedThemedColor& rNamedColor);
    void createColorWindow();
    void LockWidthRequest();
    void LockWidthRequest(int nWidthRequest);
    int CalcBestWidthRequest();
    ColorWindow* getColorWindow() const;

    DECL_DLLPRIVATE_LINK(ToggleHdl, weld::Toggleable&, void);
@@ -53,7 +54,7 @@ private:
public:
    // rTopLevelParentFunction will be used to get parent for any color picker dialog created
    ColorListBox(std::unique_ptr<weld::MenuButton> pControl,
                 TopLevelParentFunction aTopLevelParentFunction);
                 TopLevelParentFunction aTopLevelParentFunction, int* pWidthRequestCache = nullptr);
    ~ColorListBox();

    void SetSelectHdl(const Link<ColorListBox&, void>& rLink) { m_aSelectedLink = rLink; }
diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 173d6b3..7dd2e7e 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -4227,7 +4227,9 @@ void ColorListBox::SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton)
    createColorWindow();
}

ColorListBox::ColorListBox(std::unique_ptr<weld::MenuButton> pControl, TopLevelParentFunction aTopLevelParentFunction)
ColorListBox::ColorListBox(std::unique_ptr<weld::MenuButton> pControl,
                           TopLevelParentFunction aTopLevelParentFunction,
                           int* pWidthRequestCache)
    : m_xButton(std::move(pControl))
    , m_aColorWrapper(this)
    , m_aAutoDisplayColor(Application::GetSettings().GetStyleSettings().GetDialogColor())
@@ -4237,7 +4239,12 @@ ColorListBox::ColorListBox(std::unique_ptr<weld::MenuButton> pControl, TopLevelP
{
    m_xButton->connect_toggled(LINK(this, ColorListBox, ToggleHdl));
    m_aSelectedColor = svx::NamedThemedColor::FromNamedColor(GetAutoColor(m_nSlotId));
    LockWidthRequest();
    int nWidthRequest = pWidthRequestCache ? *pWidthRequestCache : -1;
    if (nWidthRequest == -1)
        nWidthRequest = CalcBestWidthRequest();
    LockWidthRequest(nWidthRequest);
    if (pWidthRequestCache)
        *pWidthRequestCache = nWidthRequest;
    ShowPreview(m_aSelectedColor.ToNamedColor());
}

@@ -4319,7 +4326,7 @@ void ColorListBox::Selected(const svx::NamedThemedColor& rColor)
//to avoid the box resizing every time the color is changed to
//the optimal size of the individual color, get the longest
//standard color and stick with that as the size for all
void ColorListBox::LockWidthRequest()
int ColorListBox::CalcBestWidthRequest()
{
    NamedColor aLongestColor;
    tools::Long nMaxStandardColorTextWidth = 0;
@@ -4335,7 +4342,12 @@ void ColorListBox::LockWidthRequest()
        }
    }
    ShowPreview(aLongestColor);
    m_xButton->set_size_request(m_xButton->get_preferred_size().Width(), -1);
    return m_xButton->get_preferred_size().Width();
}

void ColorListBox::LockWidthRequest(int nWidth)
{
    m_xButton->set_size_request(nWidth, -1);
}

void ColorListBox::ShowPreview(const NamedColor &rColor)