weld SmElementsDockingWindow

Change-Id: Ieeaa1f1e0deb708ec6d3daf261384c61d2ade22b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87659
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/starmath/inc/AccessibleSmElement.hxx b/starmath/inc/AccessibleSmElement.hxx
index 9f63d16..202de66 100644
--- a/starmath/inc/AccessibleSmElement.hxx
+++ b/starmath/inc/AccessibleSmElement.hxx
@@ -40,7 +40,7 @@ typedef ::cppu::ImplHelper3<css::lang::XServiceInfo, css::accessibility::XAccess
class AccessibleSmElement final : public comphelper::OAccessibleComponentHelper,
                                  public AccessibleSmElement_BASE
{
    VclPtr<SmElementsControl> m_pSmElementsControl;
    SmElementsControl* m_pSmElementsControl;
    const sal_Int32 m_nIndexInParent; ///< index in the parent XAccessible
    const sal_uInt16 m_nItemId; ///< index in the SmElementsControl
    bool m_bHasFocus;
diff --git a/starmath/inc/AccessibleSmElementsControl.hxx b/starmath/inc/AccessibleSmElementsControl.hxx
index ac0b68a..66cbd80 100644
--- a/starmath/inc/AccessibleSmElementsControl.hxx
+++ b/starmath/inc/AccessibleSmElementsControl.hxx
@@ -38,7 +38,7 @@ class AccessibleSmElementsControl final : public comphelper::OAccessibleComponen
                                          public AccessibleSmElementsControl_BASE
{
    std::vector<rtl::Reference<AccessibleSmElement>> m_aAccessibleChildren;
    VclPtr<SmElementsControl> m_pControl;
    SmElementsControl* m_pControl;

    void UpdateFocus(sal_uInt16);
    inline void TestControl();
@@ -71,10 +71,6 @@ public:
    sal_Bool SAL_CALL containsPoint(const css::awt::Point& aPoint) override;
    css::uno::Reference<css::accessibility::XAccessible>
        SAL_CALL getAccessibleAtPoint(const css::awt::Point& aPoint) override;
    css::awt::Rectangle SAL_CALL getBounds() override;
    css::awt::Point SAL_CALL getLocation() override;
    css::awt::Point SAL_CALL getLocationOnScreen() override;
    css::awt::Size SAL_CALL getSize() override;
    void SAL_CALL grabFocus() override;
    sal_Int32 SAL_CALL getForeground() override;
    sal_Int32 SAL_CALL getBackground() override;
diff --git a/starmath/inc/ElementsDockingWindow.hxx b/starmath/inc/ElementsDockingWindow.hxx
index c5645b7..5a5a468 100644
--- a/starmath/inc/ElementsDockingWindow.hxx
+++ b/starmath/inc/ElementsDockingWindow.hxx
@@ -21,7 +21,8 @@
#define INCLUDED_STARMATH_INC_ELEMENTSDOCKINGWINDOW_HXX

#include <sfx2/dockwin.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/customweld.hxx>
#include <vcl/weld.hxx>

#include "format.hxx"
#include <memory>
@@ -63,7 +64,7 @@ public:

typedef std::pair<const char*, const char*> SmElementDescr;

class SmElementsControl : public Control
class SmElementsControl : public weld::CustomWidgetController
{
    friend class ElementSelectorUIObject;
    friend class ElementUIObject;
@@ -81,16 +82,14 @@ class SmElementsControl : public Control
    static const std::tuple<const char*, const SmElementDescr*, size_t> m_aCategories[];
    static const size_t m_aCategoriesSize;

    virtual void ApplySettings(vcl::RenderContext&) override;
    virtual void DataChanged(const DataChangedEvent&) override;
    virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
    virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
    virtual void MouseMove(const MouseEvent& rMEvt) override;
    virtual void RequestHelp(const HelpEvent& rHEvt) override;
    virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
    virtual bool MouseMove(const MouseEvent& rMEvt) override;
    virtual OUString RequestHelp(tools::Rectangle& rRect) override;
    virtual void Resize() override;
    virtual void GetFocus() override;
    virtual void LoseFocus() override;
    virtual void KeyInput(const KeyEvent& rKEvt) override;
    virtual bool KeyInput(const KeyEvent& rKEvt) override;
    css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;

    SmDocShell*   mpDocShell;
@@ -104,7 +103,7 @@ class SmElementsControl : public Control
    std::vector< std::unique_ptr<SmElement> > maElementList;
    Size          maMaxElementDimensions;
    bool          mbVerticalMode;
    VclPtr< ScrollBar > mxScroll;
    std::unique_ptr<weld::ScrolledWindow> mxScroll;
    bool m_bFirstPaintAfterLayout;
    rtl::Reference<AccessibleSmElementsControl> m_xAccessible;

@@ -122,14 +121,12 @@ class SmElementsControl : public Control

    void build();

    //if pContext is not NULL, then draw, otherwise
    //just layout
    void LayoutOrPaintContents(vcl::RenderContext *pContext = nullptr);
    //if bDraw is true, then draw, otherwise just layout
    void LayoutOrPaintContents(vcl::RenderContext& rContext, bool bDraw);

public:
    explicit SmElementsControl(vcl::Window *pParent);
    explicit SmElementsControl(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow);
    virtual ~SmElementsControl() override;
    virtual void dispose() override;

    static const auto& categories() { return m_aCategories; }
    static size_t categoriesSize() { return m_aCategoriesSize; }
@@ -148,28 +145,31 @@ public:
    bool itemTrigger(sal_uInt16);
    void setItemHighlighted(sal_uInt16);
    sal_uInt16 itemOffset() const { return m_nCurrentOffset; }
    css::uno::Reference<css::accessibility::XAccessible> scrollbarAccessible() const;

    Size GetOptimalSize() const override;
    virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;

    DECL_LINK( ScrollHdl, ScrollBar*, void );
    void DoScroll(long nDelta);
    DECL_LINK( ScrollHdl, weld::ScrolledWindow&, void );

    void SetSelectHdl(const Link<SmElement&,void>& rLink) { maSelectHdlLink = rLink; }

    rtl::Reference<AccessibleSmElementsControl> GetAccessible() const { return m_xAccessible; }
    static Color GetTextColor();
    static Color GetControlBackground();

    virtual FactoryFunction GetUITestFactory() const override;
};

class SmElementsDockingWindow final : public SfxDockingWindow
{
    VclPtr<SmElementsControl>  mpElementsControl;
    VclPtr<ListBox>            mpElementListBox;
    std::unique_ptr<SmElementsControl> mxElementsControl;
    std::unique_ptr<weld::CustomWeld> mxElementsControlWin;
    std::unique_ptr<weld::ComboBox> mxElementListBox;

    virtual void Resize() override;
    SmViewShell* GetView();

    DECL_LINK(SelectClickHandler, SmElement&, void);
    DECL_LINK(ElementSelectedHandle, ListBox&, void);
    DECL_LINK(ElementSelectedHandle, weld::ComboBox&, void);

public:

diff --git a/starmath/source/AccessibleSmElement.cxx b/starmath/source/AccessibleSmElement.cxx
index 551d0d3..9903ce7 100644
--- a/starmath/source/AccessibleSmElement.cxx
+++ b/starmath/source/AccessibleSmElement.cxx
@@ -140,7 +140,7 @@ uno::Reference<XAccessible> AccessibleSmElement::getAccessibleParent()
    OContextEntryGuard aGuard(this);
    uno::Reference<XAccessible> xParent;
    if (m_pSmElementsControl)
        xParent = m_pSmElementsControl->GetAccessible();
        xParent.set(m_pSmElementsControl->GetAccessible().get());
    return xParent;
}

@@ -229,9 +229,7 @@ sal_Int32 AccessibleSmElement::getForeground()
{
    OExternalLockGuard aGuard(this);

    Color nColor;
    if (m_pSmElementsControl)
        nColor = m_pSmElementsControl->GetControlForeground();
    Color nColor = SmElementsControl::GetTextColor();
    return sal_Int32(nColor);
}

@@ -239,9 +237,7 @@ sal_Int32 AccessibleSmElement::getBackground()
{
    OExternalLockGuard aGuard(this);

    Color nColor;
    if (m_pSmElementsControl)
        nColor = m_pSmElementsControl->GetControlBackground();
    Color nColor = SmElementsControl::GetControlBackground();
    return sal_Int32(nColor);
}

diff --git a/starmath/source/AccessibleSmElementsControl.cxx b/starmath/source/AccessibleSmElementsControl.cxx
index 5061d8c..29701ce 100644
--- a/starmath/source/AccessibleSmElementsControl.cxx
+++ b/starmath/source/AccessibleSmElementsControl.cxx
@@ -139,18 +139,14 @@ sal_Int32 AccessibleSmElementsControl::getForeground()
{
    SolarMutexGuard aGuard;

    if (!m_pControl)
        throw uno::RuntimeException();
    return static_cast<sal_Int32>(m_pControl->GetTextColor());
    return static_cast<sal_Int32>(SmElementsControl::GetTextColor());
}

sal_Int32 AccessibleSmElementsControl::getBackground()
{
    SolarMutexGuard aGuard;

    if (!m_pControl)
        throw uno::RuntimeException();
    Color nCol = m_pControl->GetControlBackground();
    Color nCol = SmElementsControl::GetControlBackground();
    return static_cast<sal_Int32>(nCol);
}

@@ -183,30 +179,17 @@ sal_Int32 AccessibleSmElementsControl::getAccessibleChildCount()
        nCount = m_pControl->itemCount();
        if (m_aAccessibleChildren.size() != sal_uInt16(nCount))
            m_aAccessibleChildren.resize(nCount);
        if (m_pControl->scrollbarAccessible().is())
            nCount++;
    }
    return nCount;
}

uno::Reference<XAccessible> AccessibleSmElementsControl::getAccessibleChild(sal_Int32 i)
uno::Reference<XAccessible> AccessibleSmElementsControl::getAccessibleChild(sal_Int32 c)
{
    comphelper::OExternalLockGuard aGuard(this);

    if (i < 0 || i >= getAccessibleChildCount())
    if (c < 0 || c >= getAccessibleChildCount())
        throw lang::IndexOutOfBoundsException();

    // first child may be the scrollbar
    sal_uInt16 c(i);
    uno::Reference<XAccessible> xScrollbar = m_pControl->scrollbarAccessible();
    if (xScrollbar.is())
    {
        if (c == 0)
            return xScrollbar;
        c--;
    }

    assert(c < m_aAccessibleChildren.size());
    rtl::Reference<AccessibleSmElement> xChild = m_aAccessibleChildren[c];
    const sal_uInt16 nItemId = m_pControl->itemOffset() + c;
    if (xChild.is() && xChild->itemId() != nItemId)
@@ -214,7 +197,7 @@ uno::Reference<XAccessible> AccessibleSmElementsControl::getAccessibleChild(sal_
    if (!xChild.is())
    {
        sal_uInt16 nHighlightItemId = m_pControl->itemHighlighted();
        AccessibleSmElement* pChild = new AccessibleSmElement(m_pControl, nItemId, i);
        AccessibleSmElement* pChild = new AccessibleSmElement(m_pControl, nItemId, c);
        if (pChild->itemId() == nHighlightItemId)
            pChild->SetFocus(true);
        m_aAccessibleChildren[c] = pChild;
@@ -229,9 +212,7 @@ uno::Reference<XAccessible> AccessibleSmElementsControl::getAccessibleParent()
    if (!m_pControl)
        throw uno::RuntimeException();

    vcl::Window* pAccParent = m_pControl->GetAccessibleParentWindow();
    assert(pAccParent);
    return pAccParent ? pAccParent->GetAccessible() : uno::Reference<XAccessible>();
    return m_pControl->GetDrawingArea()->get_accessible_parent();
}

uno::Reference<XAccessible>
@@ -325,100 +306,38 @@ void AccessibleSmElementsControl::deselectAccessibleChild(sal_Int32 nChildIndex)
    clearAccessibleSelection(); // there can be just one selected child
}

// XAccessibleComponent
static awt::Point lcl_GetLocationOnScreen(vcl::Window const* m_pControl)
{
    awt::Point aPos;
    if (m_pControl)
    {
        tools::Rectangle aRect = m_pControl->GetWindowExtentsRelative(nullptr);
        aPos.X = aRect.Left();
        aPos.Y = aRect.Top();
    }
    return aPos;
}

static awt::Rectangle lcl_GetBounds(vcl::Window const* m_pControl)
{
    // !! see VCLXAccessibleComponent::implGetBounds()

    //! the coordinates returned are relative to the parent window !
    //! Thus the top-left point may be different from (0, 0) !

    awt::Rectangle aBounds;
    if (m_pControl)
    {
        tools::Rectangle aRect = m_pControl->GetWindowExtentsRelative(nullptr);
        aBounds.X = aRect.Left();
        aBounds.Y = aRect.Top();
        aBounds.Width = aRect.GetWidth();
        aBounds.Height = aRect.GetHeight();

        vcl::Window* pParent = m_pControl->GetAccessibleParentWindow();
        if (pParent)
        {
            tools::Rectangle aParentRect = pParent->GetWindowExtentsRelative(nullptr);
            awt::Point aParentScreenLoc(aParentRect.Left(), aParentRect.Top());
            aBounds.X -= aParentScreenLoc.X;
            aBounds.Y -= aParentScreenLoc.Y;
        }
    }
    return aBounds;
}

void AccessibleSmElementsControl::TestControl()
{
    if (!m_pControl)
        throw uno::RuntimeException();
    assert(m_pControl->GetParent()->GetAccessible() == getAccessibleParent());
}

awt::Rectangle AccessibleSmElementsControl::implGetBounds()
{
    SolarMutexGuard aGuard;
    TestControl();
    return lcl_GetBounds(m_pControl);
}

awt::Rectangle AccessibleSmElementsControl::getBounds() { return implGetBounds(); }
    awt::Rectangle aRet;

    const Point aOutPos;
    Size aOutSize(m_pControl->GetOutputSizePixel());

    aRet.X = aOutPos.X();
    aRet.Y = aOutPos.Y();
    aRet.Width = aOutSize.Width();
    aRet.Height = aOutSize.Height();

    return aRet;
}

sal_Bool AccessibleSmElementsControl::containsPoint(const awt::Point& aPoint)
{
    SolarMutexGuard aGuard;
    TestControl();
    Size aSz(m_pControl->GetSizePixel());
    Size aSz(m_pControl->GetOutputSizePixel());
    return aPoint.X >= 0 && aPoint.Y >= 0 && aPoint.X < aSz.Width() && aPoint.Y < aSz.Height();
}

awt::Point AccessibleSmElementsControl::getLocation()
{
    SolarMutexGuard aGuard;
    TestControl();
    awt::Rectangle aRect(lcl_GetBounds(m_pControl));
    return awt::Point(aRect.X, aRect.Y);
}

awt::Point AccessibleSmElementsControl::getLocationOnScreen()
{
    SolarMutexGuard aGuard;
    TestControl();
    return lcl_GetLocationOnScreen(m_pControl);
}

awt::Size AccessibleSmElementsControl::getSize()
{
    SolarMutexGuard aGuard;
    TestControl();

    Size aSz(m_pControl->GetSizePixel());
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
    awt::Rectangle aRect(lcl_GetBounds(m_pControl));
    Size aSz2(aRect.Width, aRect.Height);
    assert(aSz == aSz2 && "mismatch in width");
#endif
    return awt::Size(aSz.Width(), aSz.Height());
}

uno::Reference<XAccessibleRelationSet> AccessibleSmElementsControl::getAccessibleRelationSet()
{
    uno::Reference<XAccessibleRelationSet> xRelSet = new utl::AccessibleRelationSetHelper();
@@ -446,7 +365,7 @@ uno::Reference<XAccessibleStateSet> AccessibleSmElementsControl::getAccessibleSt
            pStateSet->AddState(AccessibleStateType::SHOWING);
        if (m_pControl->IsReallyVisible())
            pStateSet->AddState(AccessibleStateType::VISIBLE);
        if (COL_TRANSPARENT != m_pControl->GetBackground().GetColor())
        if (COL_TRANSPARENT != SmElementsControl::GetControlBackground())
            pStateSet->AddState(AccessibleStateType::OPAQUE);
    }

diff --git a/starmath/source/ElementsDockingWindow.cxx b/starmath/source/ElementsDockingWindow.cxx
index 578851f..0289e78 100644
--- a/starmath/source/ElementsDockingWindow.cxx
+++ b/starmath/source/ElementsDockingWindow.cxx
@@ -260,37 +260,23 @@ const std::tuple<const char*, const SmElementDescr*, size_t> SmElementsControl::

const size_t SmElementsControl::m_aCategoriesSize = SAL_N_ELEMENTS(m_aCategories);

SmElementsControl::SmElementsControl(vcl::Window *pParent)
    : Control(pParent, WB_TABSTOP | WB_BORDER)
    , mpDocShell(new SmDocShell(SfxModelFlags::EMBEDDED_OBJECT))
SmElementsControl::SmElementsControl(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow)
    : mpDocShell(new SmDocShell(SfxModelFlags::EMBEDDED_OBJECT))
    , m_nCurrentElement(SAL_MAX_UINT16)
    , m_nCurrentRolloverElement(SAL_MAX_UINT16)
    , m_nCurrentOffset(1) // Default offset of 1 due to the ScrollBar child
    , mbVerticalMode(true)
    , mxScroll(VclPtr<ScrollBar>::Create(this, WB_VERT))
    , mxScroll(std::move(xScrolledWindow))
    , m_bFirstPaintAfterLayout(false)
{
    set_id("element_selector");
    SetMapMode( MapMode(MapUnit::Map100thMM) );
    SetDrawMode( DrawModeFlags::Default );
    SetLayoutMode( ComplexTextLayoutFlags::Default );
    SetDigitLanguage( LANGUAGE_ENGLISH );

    maFormat.SetBaseSize(PixelToLogic(Size(0, SmPtsTo100th_mm(12))));

    mxScroll->SetScrollHdl( LINK(this, SmElementsControl, ScrollHdl) );
    mxScroll->set_user_managed_scrolling();
    mxScroll->connect_hadjustment_changed( LINK(this, SmElementsControl, ScrollHdl) );
    mxScroll->connect_vadjustment_changed( LINK(this, SmElementsControl, ScrollHdl) );
}

SmElementsControl::~SmElementsControl()
{
    disposeOnce();
}

void SmElementsControl::dispose()
{
    mpDocShell->DoClose();
    mxScroll.disposeAndClear();
    Control::dispose();
}

void SmElementsControl::setVerticalMode(bool bVerticalMode)
@@ -298,11 +284,11 @@ void SmElementsControl::setVerticalMode(bool bVerticalMode)
    if (mbVerticalMode == bVerticalMode)
        return;
    mbVerticalMode = bVerticalMode;
    if (bVerticalMode)
        mxScroll->SetStyle((mxScroll->GetStyle() & ~WB_VERT) | WB_HORZ);
    else
        mxScroll->SetStyle((mxScroll->GetStyle() & ~WB_HORZ) | WB_VERT);
    LayoutOrPaintContents(nullptr);
    // turn off scrollbars, LayoutOrPaintContents will enable whichever one
    // might be needed
    mxScroll->set_vpolicy(VclPolicyType::NEVER);
    mxScroll->set_hpolicy(VclPolicyType::NEVER);
    LayoutOrPaintContents(GetDrawingArea()->get_ref_device(), false);
    Invalidate();
}

@@ -327,26 +313,48 @@ void SmElementsControl::setCurrentElement(sal_uInt16 nPos)
        m_xAccessible->AcquireFocus();
}

Color SmElementsControl::GetTextColor()
{
    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    return rStyleSettings.GetFieldTextColor();
}

Color SmElementsControl::GetControlBackground()
{
    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    return rStyleSettings.GetFieldColor();
}

/**
 * !pContext => layout only
 * !bDraw => layout only
 *
 * Layouting is always done without a scrollbar and will show or hide it.
 * The first paint (m_bFirstPaintAfterLayout) therefore needs to update a
 * visible scrollbar, because the layouting was wrong.
 **/
void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext *pContext)
void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext& rContext, bool bDraw)
{
    const sal_Int32 nScrollbarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
    const sal_Int32 nControlHeight = GetOutputSizePixel().Height()
                                    - (pContext && mbVerticalMode && mxScroll->IsVisible() ? nScrollbarSize : 0);
    const sal_Int32 nControlWidth = GetOutputSizePixel().Width()
                                    - (pContext && !mbVerticalMode && mxScroll->IsVisible() ? nScrollbarSize : 0);
    rContext.Push();

    rContext.SetMapMode( MapMode(MapUnit::Map100thMM) );
    rContext.SetDrawMode( DrawModeFlags::Default );
    rContext.SetLayoutMode( ComplexTextLayoutFlags::Default );
    rContext.SetDigitLanguage( LANGUAGE_ENGLISH );
    if (bDraw)
    {
        rContext.SetBackground(GetControlBackground());
        rContext.SetTextColor(GetTextColor());
        rContext.Erase();
    }

    const sal_Int32 nControlHeight = GetOutputSizePixel().Height();
    const sal_Int32 nControlWidth = GetOutputSizePixel().Width();

    sal_Int32 boxX = maMaxElementDimensions.Width()  + 10;
    sal_Int32 boxY = maMaxElementDimensions.Height() + 10;

    sal_Int32 x = mbVerticalMode ? -mxScroll->GetThumbPos() : 0;
    sal_Int32 y = !mbVerticalMode ? -mxScroll->GetThumbPos() : 0;
    sal_Int32 x = mbVerticalMode ? -mxScroll->hadjustment_get_value() : 0;
    sal_Int32 y = !mbVerticalMode ? -mxScroll->vadjustment_get_value() : 0;

    sal_Int32 perLine = 0;

@@ -379,8 +387,8 @@ void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext *pContext)
                tools::Rectangle aSelectionRectangle(x + 5 - 1, y + 5,
                                              x + 5 + 1, nControlHeight - 5);

                if (pContext)
                    pContext->DrawRect(PixelToLogic(aSelectionRectangle));
                if (bDraw)
                    rContext.DrawRect(rContext.PixelToLogic(aSelectionRectangle));
                x += 10;
            }
            else
@@ -394,8 +402,8 @@ void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext *pContext)
                tools::Rectangle aSelectionRectangle(x + 5, y + 5 - 1,
                                              nControlWidth - 5, y + 5 + 1);

                if (pContext)
                    pContext->DrawRect(PixelToLogic(aSelectionRectangle));
                if (bDraw)
                    rContext.DrawRect(rContext.PixelToLogic(aSelectionRectangle));
                y += 10;
            }
        }
@@ -421,24 +429,24 @@ void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext *pContext)
            element->mBoxLocation = Point(x,y);
            element->mBoxSize = Size(boxX, boxY);

            if (pContext)
            if (bDraw)
            {
                if (pCurrentElement == element)
                {
                    pContext->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
                    const StyleSettings& rStyleSettings = pContext->GetSettings().GetStyleSettings();
                    pContext->SetLineColor(rStyleSettings.GetHighlightColor());
                    pContext->SetFillColor(COL_TRANSPARENT);
                    pContext->DrawRect(PixelToLogic(tools::Rectangle(x + 1, y + 1, x + boxX - 1, y + boxY - 1)));
                    pContext->DrawRect(PixelToLogic(tools::Rectangle(x + 2, y + 2, x + boxX - 2, y + boxY - 2)));
                    pContext->Pop();
                    rContext.Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
                    const StyleSettings& rStyleSettings = rContext.GetSettings().GetStyleSettings();
                    rContext.SetLineColor(rStyleSettings.GetHighlightColor());
                    rContext.SetFillColor(COL_TRANSPARENT);
                    rContext.DrawRect(rContext.PixelToLogic(tools::Rectangle(x + 1, y + 1, x + boxX - 1, y + boxY - 1)));
                    rContext.DrawRect(rContext.PixelToLogic(tools::Rectangle(x + 2, y + 2, x + boxX - 2, y + boxY - 2)));
                    rContext.Pop();
                }

                Size aSizePixel = LogicToPixel(Size(element->getNode()->GetWidth(),
                Size aSizePixel = rContext.LogicToPixel(Size(element->getNode()->GetWidth(),
                                                    element->getNode()->GetHeight()));
                Point location(x + ((boxX - aSizePixel.Width()) / 2),
                               y + ((boxY - aSizePixel.Height()) / 2));
                SmDrawingVisitor(*pContext, PixelToLogic(location), element->getNode().get());
                SmDrawingVisitor(rContext, rContext.PixelToLogic(location), element->getNode().get());
            }

            if (mbVerticalMode)
@@ -448,10 +456,13 @@ void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext *pContext)
        }
    }

    if (pContext)
    if (bDraw)
    {
        if (!m_bFirstPaintAfterLayout || !mxScroll->IsVisible())
        if (!m_bFirstPaintAfterLayout)
        {
            rContext.Pop();
            return;
        }
        m_bFirstPaintAfterLayout = false;
    }
    else
@@ -459,110 +470,72 @@ void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext *pContext)

    if (mbVerticalMode)
    {
        sal_Int32 nTotalControlWidth = x + boxX + mxScroll->GetThumbPos();
        sal_Int32 nTotalControlWidth = x + boxX + mxScroll->hadjustment_get_value();
        if (nTotalControlWidth > GetOutputSizePixel().Width())
        {
            mxScroll->SetRangeMax(nTotalControlWidth);
            mxScroll->SetPosSizePixel(Point(0, nControlHeight), Size(nControlWidth, nScrollbarSize));
            mxScroll->SetVisibleSize(nControlWidth);
            mxScroll->SetPageSize(nControlWidth);
            mxScroll->Show();
            mxScroll->hadjustment_set_upper(nTotalControlWidth);
            mxScroll->hadjustment_set_page_size(nControlWidth);
            mxScroll->hadjustment_set_page_increment(nControlWidth);
            mxScroll->set_hpolicy(VclPolicyType::ALWAYS);
        }
        else
        {
            mxScroll->SetThumbPos(0);
            mxScroll->Hide();
            mxScroll->hadjustment_set_value(0);
            mxScroll->set_hpolicy(VclPolicyType::NEVER);
        }
    }
    else
    {
        sal_Int32 nTotalControlHeight = y + boxY + mxScroll->GetThumbPos();
        sal_Int32 nTotalControlHeight = y + boxY + mxScroll->vadjustment_get_value();
        if (nTotalControlHeight > GetOutputSizePixel().Height())
        {
            mxScroll->SetRangeMax(nTotalControlHeight);
            mxScroll->SetPosSizePixel(Point(nControlWidth, 0), Size(nScrollbarSize, nControlHeight));
            mxScroll->SetVisibleSize(nControlHeight);
            mxScroll->SetPageSize(nControlHeight);
            mxScroll->Show();
            mxScroll->vadjustment_set_upper(nTotalControlHeight);
            mxScroll->vadjustment_set_page_size(nControlHeight);
            mxScroll->vadjustment_set_page_increment(nControlHeight);
            mxScroll->set_vpolicy(VclPolicyType::ALWAYS);
        }
        else
        {
            mxScroll->SetThumbPos(0);
            mxScroll->Hide();
            mxScroll->vadjustment_set_value(0);
            mxScroll->set_vpolicy(VclPolicyType::NEVER);
        }
    }
    rContext.Pop();
}

void SmElementsControl::Resize()
{
    Window::Resize();
    LayoutOrPaintContents(nullptr);
}

void SmElementsControl::ApplySettings(vcl::RenderContext& rRenderContext)
{
    const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
    rRenderContext.SetBackground(rStyleSettings.GetFieldColor());
}

void SmElementsControl::DataChanged(const DataChangedEvent& rDCEvt)
{
    Window::DataChanged(rDCEvt);

    if (!((rDCEvt.GetType() == DataChangedEventType::FONTS) ||
          (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
          ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
           (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))))
        return;

    Invalidate();
    CustomWidgetController::Resize();
    LayoutOrPaintContents(GetDrawingArea()->get_ref_device(), false);
}

void SmElementsControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
{
    rRenderContext.Push();
    LayoutOrPaintContents(&rRenderContext);
    rRenderContext.Pop();
    LayoutOrPaintContents(rRenderContext, true);
}

void SmElementsControl::RequestHelp(const HelpEvent& rHEvt)
OUString SmElementsControl::RequestHelp(tools::Rectangle& rRect)
{
    if (rHEvt.GetMode() & (HelpEventMode::BALLOON | HelpEventMode::QUICK))
    {
        if (!rHEvt.KeyboardActivated() && !hasRollover())
            return;
    if (!hasRollover())
        return OUString();

        const SmElement* pHelpElement = current();
        if (!pHelpElement)
            return;
    const SmElement* pHelpElement = current();
    if (!pHelpElement)
        return OUString();

        tools::Rectangle aHelpRect(pHelpElement->mBoxLocation, pHelpElement->mBoxSize);
        Point aPt = OutputToScreenPixel( aHelpRect.TopLeft() );
        aHelpRect.SetLeft( aPt.X() );
        aHelpRect.SetTop( aPt.Y() );
        aPt = OutputToScreenPixel( aHelpRect.BottomRight() );
        aHelpRect.SetRight( aPt.X() );
        aHelpRect.SetBottom( aPt.Y() );
    rRect = tools::Rectangle(pHelpElement->mBoxLocation, pHelpElement->mBoxSize);

        // get text and display it
        OUString aStr = pHelpElement->getHelpText();
        if (rHEvt.GetMode() & HelpEventMode::BALLOON)
            Help::ShowBalloon(this, aHelpRect.Center(), aHelpRect, aStr);
        else
            Help::ShowQuickHelp(this, aHelpRect, aStr, QuickHelpFlags::CtrlText);
        return;
    }

    Control::RequestHelp(rHEvt);
    // get text and display it
    return pHelpElement->getHelpText();
}

void SmElementsControl::MouseMove( const MouseEvent& rMouseEvent )
bool SmElementsControl::MouseMove( const MouseEvent& rMouseEvent )
{
    if (rMouseEvent.IsLeaveWindow())
    {
        m_nCurrentRolloverElement = SAL_MAX_UINT16;
        Invalidate();
        return;
        return false;
    }

    if (tools::Rectangle(Point(0, 0), GetOutputSizePixel()).IsInside(rMouseEvent.GetPosPixel()))
@@ -572,7 +545,7 @@ void SmElementsControl::MouseMove( const MouseEvent& rMouseEvent )
        {
            const tools::Rectangle rect(pPrevElement->mBoxLocation, pPrevElement->mBoxSize);
            if (rect.IsInside(rMouseEvent.GetPosPixel()))
                return;
                return true;
        }

        const sal_uInt16 nElementCount = maElementList.size();
@@ -587,16 +560,16 @@ void SmElementsControl::MouseMove( const MouseEvent& rMouseEvent )
            {
                m_nCurrentRolloverElement = n;
                Invalidate();
                return;
                return true;
            }
        }
        if (pPrevElement && hasRollover())
            Invalidate();
        m_nCurrentRolloverElement = SAL_MAX_UINT16;
        return;
        return true;
    }

    Control::MouseMove(rMouseEvent);
    return false;
}

namespace {
@@ -613,7 +586,7 @@ void collectUIInformation(const OUString& aID)

}

void SmElementsControl::MouseButtonDown(const MouseEvent& rMouseEvent)
bool SmElementsControl::MouseButtonDown(const MouseEvent& rMouseEvent)
{
    GrabFocus();

@@ -628,7 +601,7 @@ void SmElementsControl::MouseButtonDown(const MouseEvent& rMouseEvent)
                setCurrentElement(m_nCurrentRolloverElement);
                maSelectHdlLink.Call(*const_cast<SmElement*>(pPrevElement));
                collectUIInformation(OUString::number(m_nCurrentRolloverElement));
                return;
                return true;
            }
        }

@@ -642,25 +615,24 @@ void SmElementsControl::MouseButtonDown(const MouseEvent& rMouseEvent)
                setCurrentElement(n);
                maSelectHdlLink.Call(*element);
                collectUIInformation(OUString::number(n));
                return;
                return true;
            }
        }

        return true;
    }
    else
    {
        Control::MouseButtonDown (rMouseEvent);
    }
    return false;
}

void SmElementsControl::GetFocus()
{
    Control::GetFocus();
    CustomWidgetController::GetFocus();
    Invalidate();
}

void SmElementsControl::LoseFocus()
{
    Control::LoseFocus();
    CustomWidgetController::LoseFocus();
    Invalidate();
}

@@ -694,20 +666,22 @@ sal_uInt16 SmElementsControl::nextElement(const bool bBackward, const sal_uInt16

void SmElementsControl::scrollToElement(const bool bBackward, const SmElement *pCur)
{
    long nScrollPos = mxScroll->GetThumbPos();
    if (mbVerticalMode)
    {
        auto nScrollPos = mxScroll->hadjustment_get_value();
        nScrollPos += pCur->mBoxLocation.X();
        if (!bBackward)
            nScrollPos += pCur->mBoxSize.Width() - GetOutputSizePixel().Width();
        mxScroll->hadjustment_set_value(nScrollPos);
    }
    else
    {
        auto nScrollPos = mxScroll->vadjustment_get_value();
        nScrollPos += pCur->mBoxLocation.Y();
        if (!bBackward)
            nScrollPos += pCur->mBoxSize.Height() - GetOutputSizePixel().Height();
        mxScroll->vadjustment_set_value(nScrollPos);
    }
    mxScroll->DoScroll(nScrollPos);
}

void SmElementsControl::stepFocus(const bool bBackward)
@@ -781,14 +755,13 @@ void SmElementsControl::pageFocus(const bool bBackward)
    }
}

void SmElementsControl::KeyInput(const KeyEvent& rKEvt)
bool SmElementsControl::KeyInput(const KeyEvent& rKEvt)
{
    vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();

    if (aKeyCode.GetModifier())
    {
        Control::KeyInput( rKEvt );
        return;
        return false;
    }

    switch(aKeyCode.GetCode())
@@ -818,14 +791,14 @@ void SmElementsControl::KeyInput(const KeyEvent& rKEvt)
            if (!maElementList.empty())
            {
                setCurrentElement(0);
                mxScroll->DoScroll(0);
                mxScroll->vadjustment_set_value(0);
            }
            break;
        case KEY_END:
            if (!maElementList.empty())
            {
                setCurrentElement(maElementList.size() - 1);
                mxScroll->DoScroll(mxScroll->GetRangeMax());
                mxScroll->vadjustment_set_value(mxScroll->vadjustment_get_upper());
            }
            break;

@@ -837,31 +810,14 @@ void SmElementsControl::KeyInput(const KeyEvent& rKEvt)
            break;

        default:
            Control::KeyInput( rKEvt );
            return false;
            break;
    }
    return true;
}

IMPL_LINK_NOARG( SmElementsControl, ScrollHdl, ScrollBar*, void )
IMPL_LINK_NOARG( SmElementsControl, ScrollHdl, weld::ScrolledWindow&, void )
{
    DoScroll(mxScroll->GetDelta());
}

void SmElementsControl::DoScroll(long nDelta)
{
    Point aNewPoint = mxScroll->GetPosPixel();
    tools::Rectangle aRect(Point(), GetOutputSize());
    if (mbVerticalMode)
    {
        aRect.AdjustBottom( -(mxScroll->GetSizePixel().Height()) );
        Scroll( -nDelta, 0, aRect );
    }
    else
    {
        aRect.AdjustRight( -(mxScroll->GetSizePixel().Width()) );
        Scroll( 0, -nDelta, aRect );
    }
    mxScroll->SetPosPixel(aNewPoint);
    Invalidate();
}

@@ -871,11 +827,13 @@ void SmElementsControl::addElement(SmParser &rParser, const OUString& aElementVi
    assert(maElementList.size() < SAL_MAX_UINT16 - 2);
    auto pNode = rParser.ParseExpression(aElementVisual);

    OutputDevice& rDevice = GetDrawingArea()->get_ref_device();

    pNode->Prepare(maFormat, *mpDocShell, 0);
    pNode->SetSize(Fraction(10,8));
    pNode->Arrange(*this, maFormat);
    pNode->Arrange(rDevice, maFormat);

    Size aSizePixel = LogicToPixel(Size(pNode->GetWidth(), pNode->GetHeight()), MapMode(MapUnit::Map100thMM));
    Size aSizePixel = rDevice.LogicToPixel(Size(pNode->GetWidth(), pNode->GetHeight()), MapMode(MapUnit::Map100thMM));
    if (aSizePixel.Width() > maMaxElementDimensions.Width()) {
        maMaxElementDimensions.setWidth( aSizePixel.Width() );
    }
@@ -1002,10 +960,14 @@ void SmElementsControl::build()
    //    This will check for new items after releasing them!
    // 3. Set the cursor element
    maElementList.clear();
    mxScroll->SetThumbPos(0);
    mxScroll->Hide();
    mxScroll->hadjustment_set_value(0);
    mxScroll->vadjustment_set_value(0);
    mxScroll->set_hpolicy(VclPolicyType::NEVER);
    mxScroll->set_vpolicy(VclPolicyType::NEVER);

    if (m_xAccessible.is())
        m_xAccessible->ReleaseAllItems();

    setCurrentElement(SAL_MAX_UINT16);

    // The first element is the scrollbar. We can't change its indexInParent
@@ -1023,16 +985,24 @@ void SmElementsControl::build()
    }

    m_nCurrentRolloverElement = SAL_MAX_UINT16;
    LayoutOrPaintContents();
    LayoutOrPaintContents(GetDrawingArea()->get_ref_device(), false);

    if (m_xAccessible.is())
        m_xAccessible->AddAllItems();

    setCurrentElement(0);
    Invalidate();
}

Size SmElementsControl::GetOptimalSize() const
void SmElementsControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
{
    return LogicToPixel(Size(100, 100), MapMode(MapUnit::MapAppFont));
    CustomWidgetController::SetDrawingArea(pDrawingArea);
    OutputDevice& rDevice = pDrawingArea->get_ref_device();
    maFormat.SetBaseSize(rDevice.PixelToLogic(Size(0, SmPtsTo100th_mm(12))));
    Size aSize(rDevice.LogicToPixel(Size(10, 100), MapMode(MapUnit::MapAppFont)));
    // give it an arbitrary small width request so it can shrink in the sidebar
    pDrawingArea->set_size_request(42, aSize.Height());
    SetOutputSizePixel(aSize);
}

FactoryFunction SmElementsControl::GetUITestFactory() const
@@ -1125,35 +1095,24 @@ sal_uInt16 SmElementsControl::itemAtPos(const Point& rPoint) const
    return SAL_MAX_UINT16;
}

css::uno::Reference<css::accessibility::XAccessible> SmElementsControl::scrollbarAccessible() const
SmElementsDockingWindow::SmElementsDockingWindow(SfxBindings* pInputBindings, SfxChildWindow* pChildWindow, vcl::Window* pParent)
    : SfxDockingWindow(pInputBindings, pChildWindow, pParent, "DockingElements",
        "modules/smath/ui/dockingelements.ui", true)
    , mxElementsControl(new SmElementsControl(m_xBuilder->weld_scrolled_window("scrolledwindow")))
    , mxElementsControlWin(new weld::CustomWeld(*m_xBuilder, "element_selector", *mxElementsControl))
    , mxElementListBox(m_xBuilder->weld_combo_box("listbox"))
{
    return mxScroll && mxScroll->IsVisible() ? mxScroll->GetAccessible() : css::uno::Reference<css::accessibility::XAccessible>();
}

SmElementsDockingWindow::SmElementsDockingWindow(SfxBindings* pInputBindings, SfxChildWindow* pChildWindow, vcl::Window* pParent) :
    SfxDockingWindow(pInputBindings, pChildWindow, pParent, "DockingElements",
        "modules/smath/ui/dockingelements.ui")
{
    mpElementsControl = VclPtr<SmElementsControl>::Create(get<vcl::Window>("box"));
    mpElementsControl->set_hexpand(true);
    mpElementsControl->set_vexpand(true);
    mpElementsControl->Show();
    get(mpElementListBox, "listbox");

    mpElementsControl->SetBorderStyle( WindowBorderStyle::MONO );

    mpElementListBox->SetDropDownLineCount(SmElementsControl::categoriesSize());
    // give it an arbitrary small width request so it can shrink in the sidebar
    mxElementListBox->set_size_request(42, -1);

    for (size_t i = 0; i < SmElementsControl::categoriesSize(); ++i)
        mpElementListBox->InsertEntry(SmResId(std::get<0>(SmElementsControl::categories()[i])));
        mxElementListBox->append_text(SmResId(std::get<0>(SmElementsControl::categories()[i])));

    mpElementListBox->SetSelectHdl(LINK(this, SmElementsDockingWindow, ElementSelectedHandle));
    mpElementListBox->SelectEntry(SmResId(RID_CATEGORY_UNARY_BINARY_OPERATORS));
    mxElementListBox->connect_changed(LINK(this, SmElementsDockingWindow, ElementSelectedHandle));
    mxElementListBox->set_active_text(SmResId(RID_CATEGORY_UNARY_BINARY_OPERATORS));

    mpElementsControl->SetBackground( COL_WHITE );
    mpElementsControl->SetTextColor( COL_BLACK );
    mpElementsControl->setElementSetId(RID_CATEGORY_UNARY_BINARY_OPERATORS);
    mpElementsControl->SetSelectHdl(LINK(this, SmElementsDockingWindow, SelectClickHandler));
    mxElementsControl->setElementSetId(RID_CATEGORY_UNARY_BINARY_OPERATORS);
    mxElementsControl->SetSelectHdl(LINK(this, SmElementsDockingWindow, SelectClickHandler));
}

SmElementsDockingWindow::~SmElementsDockingWindow ()
@@ -1163,8 +1122,9 @@ SmElementsDockingWindow::~SmElementsDockingWindow ()

void SmElementsDockingWindow::dispose()
{
    mpElementsControl.disposeAndClear();
    mpElementListBox.clear();
    mxElementsControlWin.reset();
    mxElementsControl.reset();
    mxElementListBox.reset();
    SfxDockingWindow::dispose();
}

@@ -1182,7 +1142,7 @@ void SmElementsDockingWindow::EndDocking( const tools::Rectangle& rReactangle, b
{
    SfxDockingWindow::EndDocking(rReactangle, bFloatMode);
    bool bVertical = ( GetAlignment() == SfxChildAlignment::TOP || GetAlignment() == SfxChildAlignment::BOTTOM );
    mpElementsControl->setVerticalMode(bVertical);
    mxElementsControl->setVerticalMode(bVertical);
}

IMPL_LINK(SmElementsDockingWindow, SelectClickHandler, SmElement&, rElement, void)
@@ -1198,15 +1158,15 @@ IMPL_LINK(SmElementsDockingWindow, SelectClickHandler, SmElement&, rElement, voi
    }
}

IMPL_LINK( SmElementsDockingWindow, ElementSelectedHandle, ListBox&, rList, void)
IMPL_LINK( SmElementsDockingWindow, ElementSelectedHandle, weld::ComboBox&, rList, void)
{
    for (size_t i = 0; i < SmElementsControl::categoriesSize(); ++i)
    {
        const char *pCurrentCategory = std::get<0>(SmElementsControl::categories()[i]);
        OUString aCurrentCategoryString = SmResId(pCurrentCategory);
        if (aCurrentCategoryString == rList.GetSelectedEntry())
        if (aCurrentCategoryString == rList.get_active_text())
        {
            mpElementsControl->setElementSetId(pCurrentCategory);
            mxElementsControl->setElementSetId(pCurrentCategory);
            return;
        }
    }
@@ -1221,7 +1181,7 @@ SmViewShell* SmElementsDockingWindow::GetView()
void SmElementsDockingWindow::Resize()
{
    bool bVertical = ( GetAlignment() == SfxChildAlignment::TOP || GetAlignment() == SfxChildAlignment::BOTTOM );
    mpElementsControl->setVerticalMode(bVertical);
    mxElementsControl->setVerticalMode(bVertical);

    SfxDockingWindow::Resize();
    Invalidate();
diff --git a/starmath/source/uiobject.cxx b/starmath/source/uiobject.cxx
index a4dad7f..a6f0c47 100644
--- a/starmath/source/uiobject.cxx
+++ b/starmath/source/uiobject.cxx
@@ -9,12 +9,12 @@

#include <memory>
#include "uiobject.hxx"

#include <vcl/layout.hxx>
#include <ElementsDockingWindow.hxx>

ElementUIObject::ElementUIObject(const VclPtr<SmElementsControl>& xElementSelector,
ElementUIObject::ElementUIObject(SmElementsControl* pElementSelector,
        const OUString& rID):
    mxElementsSelector(xElementSelector),
    mpElementsSelector(pElementSelector),
    maID(rID)
{
}
@@ -22,11 +22,11 @@ ElementUIObject::ElementUIObject(const VclPtr<SmElementsControl>& xElementSelect
SmElement* ElementUIObject::get_element()
{
    sal_uInt32 nID = maID.toUInt32();
    size_t n = mxElementsSelector->maElementList.size();
    size_t n = mpElementsSelector->maElementList.size();
    if (nID >= n)
        return nullptr;

    return mxElementsSelector->maElementList[nID].get();
    return mpElementsSelector->maElementList[nID].get();
}

StringMap ElementUIObject::get_state()
@@ -48,13 +48,13 @@ void ElementUIObject::execute(const OUString& rAction,
    {
        SmElement* pElement = get_element();
        if (pElement)
            mxElementsSelector->maSelectHdlLink.Call(*pElement);
            mpElementsSelector->maSelectHdlLink.Call(*pElement);
    }
}

ElementSelectorUIObject::ElementSelectorUIObject(const VclPtr<SmElementsControl>& xElementSelector):
    WindowUIObject(xElementSelector),
    mxElementsSelector(xElementSelector)
ElementSelectorUIObject::ElementSelectorUIObject(vcl::Window* pElementSelectorWindow, SmElementsControl* pElementSelector)
    : WindowUIObject(pElementSelectorWindow)
    , mpElementsSelector(pElementSelector)
{
}

@@ -62,11 +62,11 @@ StringMap ElementSelectorUIObject::get_state()
{
    StringMap aMap = WindowUIObject::get_state();

    SmElement* pElement = mxElementsSelector->current();
    SmElement* pElement = mpElementsSelector->current();
    if (pElement)
        aMap["CurrentEntry"] = pElement->getText();

    aMap["CurrentSelection"] = OUString::fromUtf8(mxElementsSelector->msCurrentSetId);
    aMap["CurrentSelection"] = OUString::fromUtf8(mpElementsSelector->msCurrentSetId);

    return aMap;
}
@@ -74,18 +74,18 @@ StringMap ElementSelectorUIObject::get_state()
std::unique_ptr<UIObject> ElementSelectorUIObject::get_child(const OUString& rID)
{
    size_t nID = rID.toInt32();
    size_t n = mxElementsSelector->maElementList.size();
    size_t n = mpElementsSelector->maElementList.size();
    if (nID >= n)
        throw css::uno::RuntimeException("invalid id");

    return std::unique_ptr<UIObject>(new ElementUIObject(mxElementsSelector, rID));
    return std::unique_ptr<UIObject>(new ElementUIObject(mpElementsSelector, rID));
}

std::set<OUString> ElementSelectorUIObject::get_children() const
{
    std::set<OUString> aChildren;

    size_t n = mxElementsSelector->maElementList.size();
    size_t n = mpElementsSelector->maElementList.size();
    for (size_t i = 0; i < n; ++i)
    {
        aChildren.insert(OUString::number(i));
@@ -96,10 +96,9 @@ std::set<OUString> ElementSelectorUIObject::get_children() const

std::unique_ptr<UIObject> ElementSelectorUIObject::create(vcl::Window* pWindow)
{
    SmElementsControl* pElementsControl = dynamic_cast<SmElementsControl*>(pWindow);
    assert(pElementsControl);

    return std::unique_ptr<UIObject>(new ElementSelectorUIObject(pElementsControl));
    VclDrawingArea* pSmElementsWin = dynamic_cast<VclDrawingArea*>(pWindow);
    assert(pSmElementsWin);
    return std::unique_ptr<UIObject>(new ElementSelectorUIObject(pSmElementsWin, static_cast<SmElementsControl*>(pSmElementsWin->GetUserData())));
}

OUString ElementSelectorUIObject::get_name() const
diff --git a/starmath/source/uiobject.hxx b/starmath/source/uiobject.hxx
index 1e8ea98..e862ca4 100644
--- a/starmath/source/uiobject.hxx
+++ b/starmath/source/uiobject.hxx
@@ -18,12 +18,12 @@
class ElementUIObject : public UIObject
{
private:
    VclPtr<SmElementsControl> mxElementsSelector;
    SmElementsControl* mpElementsSelector;
    OUString const maID;

public:

    ElementUIObject(const VclPtr<SmElementsControl>& xElementSelector,
    ElementUIObject(SmElementsControl* pElementSelector,
            const OUString& rID);

    virtual StringMap get_state() override;
@@ -38,11 +38,11 @@ private:
class ElementSelectorUIObject : public WindowUIObject
{
private:
    VclPtr<SmElementsControl> mxElementsSelector;
    SmElementsControl* mpElementsSelector;

public:

    explicit ElementSelectorUIObject(const VclPtr<SmElementsControl>& xElementSelector);
    explicit ElementSelectorUIObject(vcl::Window* pElementSelectorWindow, SmElementsControl* pElementSelector);

    virtual StringMap get_state() override;

diff --git a/starmath/uiconfig/smath/ui/dockingelements.ui b/starmath/uiconfig/smath/ui/dockingelements.ui
index 545279a..182117da 100644
--- a/starmath/uiconfig/smath/ui/dockingelements.ui
+++ b/starmath/uiconfig/smath/ui/dockingelements.ui
@@ -1,41 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sm">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkWindow" id="DockingElements">
  <object class="GtkBox" id="DockingElements">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="border_width">6</property>
    <property name="title" translatable="yes" context="dockingelements|DockingElements">Elements</property>
    <property name="type_hint">dock</property>
    <property name="orientation">vertical</property>
    <property name="spacing">12</property>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkBox" id="box">
      <object class="GtkComboBoxText" id="listbox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="tooltip_text" translatable="yes" context="dockingelements|ElementCategories|tooltip_text">Element categories</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkScrolledWindow" id="scrolledwindow">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
        <property name="vexpand">True</property>
        <property name="orientation">vertical</property>
        <property name="spacing">12</property>
        <property name="shadow_type">in</property>
        <child>
          <object class="GtkComboBoxText" id="listbox">
          <object class="GtkViewport">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="tooltip_text" translatable="yes" context="dockingelements|ElementCategories|tooltip_text">Element categories</property>
            <child>
              <object class="GtkDrawingArea" id="element_selector">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
</interface>