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 <caol...@redhat.com> AuthorDate: Thu Oct 24 11:50:08 2019 +0100 Commit: Caolán McNamara <caol...@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 <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@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; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits