[Libreoffice-commits] core.git: include/vcl vcl/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Thu Oct 24 12:32:24 UTC 2019


 include/vcl/layout.hxx        |   33 +++++++++--
 vcl/source/window/builder.cxx |    6 +-
 vcl/source/window/layout.cxx  |  120 ++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 147 insertions(+), 12 deletions(-)

New commits:
commit a6922432ed5109b024e22a9c595b65c19e3b5c64
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Oct 24 11:50:08 2019 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Thu Oct 24 14:30:53 2019 +0200

    create a VclHPaned
    
    Change-Id: Iec1076cdca03fe75ad832c0b9f8133ee4276dd6f
    Reviewed-on: https://gerrit.libreoffice.org/81444
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx
index 494cb708f292..ec3fcc5041a9 100644
--- a/include/vcl/layout.hxx
+++ b/include/vcl/layout.hxx
@@ -370,21 +370,42 @@ public:
     virtual void setAllocation(const Size &rAllocation) override;
 };
 
-class VCL_DLLPUBLIC VclVPaned : public VclContainer
+class VCL_DLLPUBLIC VclPaned : public VclContainer
 {
-private:
+protected:
     VclPtr<Splitter> m_pSplitter;
     long m_nPosition;
+
+    VclPaned(vcl::Window *pParent, bool bVertical);
+public:
+    virtual ~VclPaned() override { disposeOnce(); }
+    virtual void dispose() override;
+    long get_position() const { return m_nPosition; }
+    void set_position(long nPosition) { m_nPosition = nPosition; }
+};
+
+class VCL_DLLPUBLIC VclVPaned : public VclPaned
+{
+private:
     DECL_LINK(SplitHdl, Splitter*, void);
     void arrange(const Size& rAllocation, long nFirstHeight, long nSecondHeight);
+
 public:
     VclVPaned(vcl::Window *pParent);
-    virtual ~VclVPaned() override { disposeOnce(); }
-    virtual void dispose() override;
     virtual Size calculateRequisition() const override;
     virtual void setAllocation(const Size &rAllocation) override;
-    long get_position() const { return m_nPosition; }
-    void set_position(long nPosition) { m_nPosition = nPosition; }
+};
+
+class VCL_DLLPUBLIC VclHPaned : public VclPaned
+{
+private:
+    DECL_LINK(SplitHdl, Splitter*, void);
+    void arrange(const Size& rAllocation, long nFirstHeight, long nSecondHeight);
+
+public:
+    VclHPaned(vcl::Window *pParent);
+    virtual Size calculateRequisition() const override;
+    virtual void setAllocation(const Size &rAllocation) override;
 };
 
 class VCL_DLLPUBLIC VclFrame : public VclBin
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 30e5a06ed31a..5913751b945f 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -1783,8 +1783,10 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
     else if (name == "GtkPaned")
     {
         bVertical = extractOrientation(rMap);
-        assert(bVertical && "hori not implemented, shouldn't be hard though");
-        xWindow = VclPtr<VclVPaned>::Create(pParent);
+        if (bVertical)
+            xWindow = VclPtr<VclVPaned>::Create(pParent);
+        else
+            xWindow = VclPtr<VclHPaned>::Create(pParent);
     }
     else if (name == "GtkHBox")
         xWindow = VclPtr<VclHBox>::Create(pParent);
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index c9dda1e98f9a..f510b38ce767 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -2353,22 +2353,27 @@ void MessageDialog::StateChanged(StateChangedType nType)
     }
 }
 
-VclVPaned::VclVPaned(vcl::Window *pParent)
+VclPaned::VclPaned(vcl::Window *pParent, bool bVertical)
     : VclContainer(pParent, WB_HIDE | WB_CLIPCHILDREN)
-    , m_pSplitter(VclPtr<Splitter>::Create(this, WB_VSCROLL))
+    , m_pSplitter(VclPtr<Splitter>::Create(this, bVertical ? WB_VSCROLL : WB_HSCROLL))
     , m_nPosition(-1)
 {
-    m_pSplitter->SetSplitHdl(LINK(this, VclVPaned, SplitHdl));
     m_pSplitter->SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetFaceColor()));
     m_pSplitter->Show();
 }
 
-void VclVPaned::dispose()
+void VclPaned::dispose()
 {
     m_pSplitter.disposeAndClear();
     VclContainer::dispose();
 }
 
+VclVPaned::VclVPaned(vcl::Window *pParent)
+    : VclPaned(pParent, true)
+{
+    m_pSplitter->SetSplitHdl(LINK(this, VclVPaned, SplitHdl));
+}
+
 IMPL_LINK(VclVPaned, SplitHdl, Splitter*, pSplitter, void)
 {
     long nSize = pSplitter->GetSplitPosPixel();
@@ -2470,6 +2475,113 @@ Size VclVPaned::calculateRequisition() const
     return aRet;
 }
 
+VclHPaned::VclHPaned(vcl::Window *pParent)
+    : VclPaned(pParent, true)
+{
+    m_pSplitter->SetSplitHdl(LINK(this, VclHPaned, SplitHdl));
+}
+
+IMPL_LINK(VclHPaned, SplitHdl, Splitter*, pSplitter, void)
+{
+    long nSize = pSplitter->GetSplitPosPixel();
+    Size aSplitterSize(m_pSplitter->GetSizePixel());
+    Size aAllocation(GetSizePixel());
+    arrange(aAllocation, nSize, aAllocation.Width() - nSize - aSplitterSize.Width());
+}
+
+void VclHPaned::arrange(const Size& rAllocation, long nFirstWidth, long nSecondWidth)
+{
+    Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
+    Size aFirstChildSize(nFirstWidth, rAllocation.Height());
+    Size aSecondChildSize(nSecondWidth, rAllocation.Height());
+    int nElement = 0;
+    for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
+        pChild = pChild->GetWindow(GetWindowType::Next))
+    {
+        if (!pChild->IsVisible())
+            continue;
+        if (nElement == 0)
+        {
+            Point aSplitterPos(aFirstChildSize.Width(), 0);
+            setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
+            set_position(aSplitterPos.X() + aSplitterSize.Width() / 2);
+        }
+        else if (nElement == 1)
+        {
+            Point aChildPos(0, 0);
+            setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
+        }
+        else if (nElement == 2)
+        {
+            Point aChildPos(aFirstChildSize.Width() + aSplitterSize.Width(), 0);
+            setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
+        }
+        ++nElement;
+    }
+}
+
+void VclHPaned::setAllocation(const Size& rAllocation)
+{
+    //supporting "shrink" could be done by adjusting the allowed drag rectangle
+    m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
+    Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
+    const long nWidth = rAllocation.Width() - aSplitterSize.Width();
+
+    long nFirstWidth = 0;
+    long nSecondWidth = 0;
+    bool bFirstCanResize = true;
+    bool bSecondCanResize = true;
+    const bool bInitialAllocation = get_position() < 0;
+    int nElement = 0;
+    for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
+        pChild = pChild->GetWindow(GetWindowType::Next))
+    {
+        if (!pChild->IsVisible())
+            continue;
+        if (nElement == 1)
+        {
+            if (bInitialAllocation)
+                nFirstWidth = getLayoutRequisition(*pChild).Width();
+            else
+                nFirstWidth = pChild->GetSizePixel().Width();
+            bFirstCanResize = pChild->get_expand();
+        }
+        else if (nElement == 2)
+        {
+            if (bInitialAllocation)
+                nSecondWidth = getLayoutRequisition(*pChild).Width();
+            else
+                nSecondWidth = pChild->GetSizePixel().Width();
+            bSecondCanResize = pChild->get_expand();
+        }
+        ++nElement;
+    }
+    long nWidthRequest = nFirstWidth + nSecondWidth;
+    long nWidthDiff = nWidth - nWidthRequest;
+    if (bFirstCanResize == bSecondCanResize)
+        nFirstWidth += nWidthDiff/2;
+    else if (bFirstCanResize)
+        nFirstWidth += nWidthDiff;
+    arrange(rAllocation, nFirstWidth, nSecondWidth);
+}
+
+Size VclHPaned::calculateRequisition() const
+{
+    Size aRet(0, 0);
+
+    for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
+        pChild = pChild->GetWindow(GetWindowType::Next))
+    {
+        if (!pChild->IsVisible())
+            continue;
+        Size aChildSize = getLayoutRequisition(*pChild);
+        aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
+        aRet.AdjustWidth(aChildSize.Width() );
+    }
+
+    return aRet;
+}
+
 Size getLegacyBestSizeForChildren(const vcl::Window &rWindow)
 {
     tools::Rectangle aBounds;


More information about the Libreoffice-commits mailing list