diff options
author | Caolán McNamara <caolanm@redhat.com> | 2011-11-09 22:58:42 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-09-28 08:47:53 +0100 |
commit | 7d4c786e5c8b2b664997df6e9193cb4352cf9615 (patch) | |
tree | 367b1eb26d045ad64166b7ac11c22c3419b9715e /vcl | |
parent | a73656244f75099415efe1b671783eea9dcbe5f9 (diff) |
add basic hbox, vbox and dialog support
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/Package_inc.mk | 1 | ||||
-rw-r--r-- | vcl/inc/vcl/dialog.hxx | 4 | ||||
-rw-r--r-- | vcl/inc/vcl/fixed.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/vcl/layout.hxx | 154 | ||||
-rw-r--r-- | vcl/inc/vcl/window.hxx | 13 | ||||
-rw-r--r-- | vcl/source/control/fixed.cxx | 9 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 23 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 171 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 18 |
10 files changed, 396 insertions, 0 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index f1eb6f12ad57..02f52320b04d 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -264,6 +264,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/window/introwin \ vcl/source/window/keycod \ vcl/source/window/keyevent \ + vcl/source/window/layout \ vcl/source/window/menu \ vcl/source/window/mnemonic \ vcl/source/window/mnemonicengine \ diff --git a/vcl/Package_inc.mk b/vcl/Package_inc.mk index e791793dbe62..cbdeb36234bc 100644 --- a/vcl/Package_inc.mk +++ b/vcl/Package_inc.mk @@ -89,6 +89,7 @@ $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/jobdata.hxx,vcl/jobdata.hxx)) $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/jobset.hxx,vcl/jobset.hxx)) $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/keycodes.hxx,vcl/keycodes.hxx)) $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/keycod.hxx,vcl/keycod.hxx)) +$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/layout.hxx,vcl/layout.hxx)) $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/lazydelete.hxx,vcl/lazydelete.hxx)) $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/lineinfo.hxx,vcl/lineinfo.hxx)) $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/longcurr.hxx,vcl/longcurr.hxx)) diff --git a/vcl/inc/vcl/dialog.hxx b/vcl/inc/vcl/dialog.hxx index 093ef1e0db69..c8bb05d2c9fb 100644 --- a/vcl/inc/vcl/dialog.hxx +++ b/vcl/inc/vcl/dialog.hxx @@ -83,6 +83,10 @@ public: virtual void StateChanged( StateChangedType nStateChange ); virtual void DataChanged( const DataChangedEvent& rDCEvt ); + virtual Size GetOptimalSize(WindowSizeType eType) const; + virtual void Resize(); + + virtual sal_Bool Close(); virtual short Execute(); diff --git a/vcl/inc/vcl/fixed.hxx b/vcl/inc/vcl/fixed.hxx index 63f094d0509d..4ce0d9d0c606 100644 --- a/vcl/inc/vcl/fixed.hxx +++ b/vcl/inc/vcl/fixed.hxx @@ -74,6 +74,8 @@ public: static Size CalcMinimumTextSize( Control const* pControl, long nMaxWidth = 0 ); Size CalcMinimumSize( long nMaxWidth = 0 ) const; virtual Size GetOptimalSize(WindowSizeType eType) const; + + virtual void SetText( const XubString& rStr ); }; // ------------- diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx new file mode 100644 index 000000000000..eaff5037a43a --- /dev/null +++ b/vcl/inc/vcl/layout.hxx @@ -0,0 +1,154 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Caolán McNamara <caolanm@redhat.com> (Red Hat, Inc.) + * Portions created by the Initial Developer are Copyright (C) 2011 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): Caolán McNamara <caolanm@redhat.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ +#ifndef _VCLLAYOUT_HXX +#define _VCLLAYOUT_HXX + +#include <vcl/dllapi.h> +#include <vcl/window.hxx> + +class VCL_DLLPUBLIC Box : public Window +{ +protected: + bool m_bHomogeneous; + int m_nSpacing; +public: + Box(Window *pParent, bool bHomogeneous = false, int nSpacing = 0) + : Window(pParent) + , m_bHomogeneous(bHomogeneous) + , m_nSpacing(nSpacing) + { + Show(); + } +public: + virtual Size GetOptimalSize(WindowSizeType eType) const; + using Window::SetPosSizePixel; + virtual void SetPosSizePixel(const Point& rNewPos, const Size& rNewSize); +protected: + Size calculateRequisition() const; + void setAllocation(const Size &rAllocation); + + virtual long getPrimaryDimension(const Size &rSize) const = 0; + virtual void setPrimaryDimension(Size &rSize, long) const = 0; + virtual long getPrimaryCoordinate(const Point &rPos) const = 0; + virtual void setPrimaryCoordinate(Point &rPos, long) const = 0; + virtual long getSecondaryDimension(const Size &rSize) const = 0; + virtual void setSecondaryDimension(Size &rSize, long) const = 0; + virtual long getSecondaryCoordinate(const Point &rPos) const = 0; + virtual void setSecondaryCoordinate(Point &rPos, long) const = 0; + + virtual long getPrimaryDimensionBorders(sal_Int32 nLeftBorder, sal_Int32 nTopBorder, + sal_Int32 nRightBorder, sal_Int32 nBottomBorder) = 0; +}; + +class VCL_DLLPUBLIC VBox : public Box +{ +protected: + virtual long getPrimaryDimension(const Size &rSize) const + { + return rSize.getHeight(); + } + virtual void setPrimaryDimension(Size &rSize, long nHeight) const + { + rSize.setHeight(nHeight); + } + virtual long getPrimaryCoordinate(const Point &rPos) const + { + return rPos.getY(); + } + virtual void setPrimaryCoordinate(Point &rPos, long nPos) const + { + rPos.setY(nPos); + } + virtual long getSecondaryDimension(const Size &rSize) const + { + return rSize.getWidth(); + } + virtual void setSecondaryDimension(Size &rSize, long nWidth) const + { + rSize.setWidth(nWidth); + } + virtual long getSecondaryCoordinate(const Point &rPos) const + { + return rPos.getX(); + } + virtual void setSecondaryCoordinate(Point &rPos, long nPos) const + { + rPos.setX(nPos); + } + virtual long getPrimaryDimensionBorders(sal_Int32, sal_Int32 nTopBorder, + sal_Int32, sal_Int32 nBottomBorder) + { + return nTopBorder + nBottomBorder; + } +}; + +class VCL_DLLPUBLIC HBox : public Box +{ +protected: + virtual long getPrimaryDimension(const Size &rSize) const + { + return rSize.getWidth(); + } + virtual void setPrimaryDimension(Size &rSize, long nWidth) const + { + rSize.setWidth(nWidth); + } + virtual long getPrimaryCoordinate(const Point &rPos) const + { + return rPos.getX(); + } + virtual void setPrimaryCoordinate(Point &rPos, long nPos) const + { + rPos.setX(nPos); + } + virtual long getSecondaryDimension(const Size &rSize) const + { + return rSize.getHeight(); + } + virtual void setSecondaryDimension(Size &rSize, long nHeight) const + { + rSize.setHeight(nHeight); + } + virtual long getSecondaryCoordinate(const Point &rPos) const + { + return rPos.getY(); + } + virtual void setSecondaryCoordinate(Point &rPos, long nPos) const + { + rPos.setY(nPos); + } + virtual long getPrimaryDimensionBorders(sal_Int32 nLeftBorder, sal_Int32, + sal_Int32 nRightBorder, sal_Int32) + { + return nLeftBorder + nRightBorder; + } +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index 67349eed3742..6fd7eca3cd13 100644 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -379,6 +379,11 @@ private: // WindowImpl* mpWindowImpl; + //^^^la la la, I can't hear you^^^ + bool m_bExpand; + bool m_bFill; + long m_nPadding; + SAL_DLLPRIVATE void ImplInitWindowData( WindowType nType ); #ifdef DBG_UTIL @@ -1057,6 +1062,14 @@ public: // Advisory Sizing - what is a good size for this widget ? virtual Size GetOptimalSize(WindowSizeType eType) const; + bool getExpand() const { return m_bExpand; } + bool getFill() const { return m_bFill; } + long getPadding() const { return m_nPadding; } + void setExpand(bool bExpand) { m_bExpand = bExpand; } + void setFill(bool bFill) { m_bFill = bFill; } + void setPadding(long nPadding) { m_nPadding = nPadding; } + void queueResize(); + //------------------------------------- // Native Widget Rendering functions diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx index 62fae387d47e..b1765b8bb427 100644 --- a/vcl/source/control/fixed.cxx +++ b/vcl/source/control/fixed.cxx @@ -429,6 +429,15 @@ void FixedText::FillLayoutData() const ImplDraw( const_cast<FixedText*>(this), 0, Point(), GetOutputSizePixel(), true ); } + +void FixedText::SetText( const XubString& rStr ) +{ + fprintf(stderr, "FixedText::SetText changed\n"); + Window::SetText(rStr); + //Text changed, tell possibly existing layout that size requisition has changed + queueResize(); +} + // ======================================================================= void FixedLine::ImplInit( Window* pParent, WinBits nStyle ) diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index 3d6ad01f1c67..4afdf7e7516a 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -944,6 +944,29 @@ void Dialog::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal pDev->Pop(); } +Size Dialog::GetOptimalSize(WindowSizeType eType) const +{ + if (eType == WINDOWSIZE_MAXIMUM) + return SystemWindow::GetOptimalSize(eType); + Size aSize; + if (GetChildCount() == 1) + aSize = GetChild(0)->GetOptimalSize(eType); + return Window::CalcWindowSize(aSize); +} + +void Dialog::Resize() +{ + fprintf(stderr, "Dialog::Resize\n"); + if (GetChildCount() == 1) + { + Size aSize = GetSizePixel(); + aSize.Width() -= mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder; + aSize.Height() -= mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder; + Point aPos(mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder); + GetChild(0)->SetPosSizePixel(aPos, aSize); + } +} + // ----------------------------------------------------------------------- ModelessDialog::ModelessDialog( Window* pParent, const ResId& rResId ) : diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx new file mode 100644 index 000000000000..b44c9fcaf12e --- /dev/null +++ b/vcl/source/window/layout.cxx @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Caolán McNamara <caolanm@redhat.com> (Red Hat, Inc.) + * Portions created by the Initial Developer are Copyright (C) 2011 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): Caolán McNamara <caolanm@redhat.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#include <vcl/layout.hxx> +#include <boost/bind.hpp> + +#define callDimension(object,ptrToMember) ((object).*(ptrToMember))() + +Size Box::calculateRequisition() const +{ + long nMaxChildDimension = 0; + + sal_uInt16 nVisibleChildren = 0; + + Size aSize; + sal_uInt16 nChildren = GetChildCount(); + for (sal_uInt16 i = 0; i < nChildren; ++i) + { + Window *pChild = GetChild(i); + if (!pChild->IsVisible()) + continue; + ++nVisibleChildren; + Size aChildSize = pChild->GetOptimalSize(WINDOWSIZE_PREFERRED); + fprintf(stderr, "child %p wants to be %ld %ld\n", pChild, aChildSize.Width(), aChildSize.Height()); + long nSecondaryDimension = getSecondaryDimension(aChildSize); + if (nSecondaryDimension > getSecondaryDimension(aSize)) + setSecondaryDimension(aSize, nSecondaryDimension); + if (m_bHomogeneous) + { + long nPrimaryDimension = getPrimaryDimension(aChildSize); + if (nPrimaryDimension > nMaxChildDimension) + nMaxChildDimension = nPrimaryDimension; + } + else + { + long nPrimaryDimension = getPrimaryDimension(aSize); + setPrimaryDimension(aSize, nPrimaryDimension + getPrimaryDimension(aChildSize)); + } + } + + if (nVisibleChildren) + { + long nPrimaryDimension = getPrimaryDimension(aSize); + if (m_bHomogeneous) + nPrimaryDimension += nMaxChildDimension * (nVisibleChildren-1); + setPrimaryDimension(aSize, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1)); + } + + return aSize; +} + +Size Box::GetOptimalSize(WindowSizeType eType) const +{ + if (eType == WINDOWSIZE_MAXIMUM) + return Window::GetOptimalSize(eType); + return calculateRequisition(); +} + +void Box::setAllocation(const Size &rAllocation) +{ + sal_uInt16 nChildren = GetChildCount(); + if (!nChildren) + return; + + sal_uInt16 nVisibleChildren = 0, nExpandChildren = 0;; + for (sal_uInt16 i = 0; i < nChildren; ++i) + { + Window *pChild = GetChild(i); + if (!pChild->IsVisible()) + continue; + ++nVisibleChildren; + if (pChild->getExpand()) + ++nExpandChildren; + } + + if (!nVisibleChildren) + return; + + sal_Int32 nLeftBorder, nTopBorder, nRightBorder, nBottomBorder; + GetBorder(nLeftBorder, nTopBorder, nRightBorder, nBottomBorder); + Point aPos(nLeftBorder, nTopBorder); + + Size aSize = rAllocation; + + long nHomogeneousDimension, nExtraSpace = 0; + if (m_bHomogeneous) + { + long nBorder = getPrimaryDimensionBorders(nLeftBorder, nTopBorder, nRightBorder, nBottomBorder); + nHomogeneousDimension = ( ( getPrimaryDimension(rAllocation) - nBorder - + ( nVisibleChildren - 1 ) * m_nSpacing )) / nVisibleChildren; + } + else if (nExpandChildren) + { + Size aRequisition = calculateRequisition(); + nExtraSpace = (getPrimaryDimension(rAllocation) - getPrimaryDimension(aRequisition)) / nExpandChildren; + } + + for (sal_uInt16 i = 0; i < nChildren; ++i) + { + Window *pChild = GetChild(i); + if (!pChild->IsVisible()) + continue; + + Size aBoxSize; + if (m_bHomogeneous) + setPrimaryDimension(aBoxSize, nHomogeneousDimension); + else + { + aBoxSize = pChild->GetOptimalSize(WINDOWSIZE_PREFERRED); + long nPrimaryDimension = getPrimaryDimension(aBoxSize); + nPrimaryDimension += pChild->getPadding(); + if (pChild->getExpand()) + setPrimaryDimension(aBoxSize, nPrimaryDimension + nExtraSpace); + } + setSecondaryDimension(aBoxSize, getSecondaryDimension(aSize)); + + Point aChildPos(aPos); + long nPrimaryCoordinate = getPrimaryCoordinate(aChildPos); + setPrimaryCoordinate(aChildPos, nPrimaryCoordinate + pChild->getPadding()); + + Size aChildSize(aBoxSize); + if (pChild->getFill()) + setPrimaryDimension(aChildSize, std::max(static_cast<long>(1), getPrimaryDimension(aBoxSize)-pChild->getPadding())); + else + { + setPrimaryDimension(aChildSize, getPrimaryDimension(pChild->GetOptimalSize(WINDOWSIZE_PREFERRED))); + setPrimaryCoordinate(aChildPos, getPrimaryCoordinate(aChildPos) + + (getPrimaryDimension(aBoxSize) - getPrimaryDimension(aChildSize)) / 2); + setSecondaryCoordinate(aChildPos, getSecondaryCoordinate(aChildPos) + + (getSecondaryDimension(aBoxSize) - getSecondaryDimension(aChildSize)) / 2); + } + + pChild->SetPosSizePixel(aChildPos, aChildSize); + fprintf(stderr, "child %p set to %ld %ld : %ld %ld\n", pChild, aPos.X(), aPos.Y(), aChildSize.Width(), aChildSize.Height()); + nPrimaryCoordinate = getPrimaryCoordinate(aPos); + setPrimaryCoordinate(aPos, nPrimaryCoordinate + getPrimaryDimension(aBoxSize) + m_nSpacing + pChild->getPadding()); + } +} + +void Box::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation) +{ + Window::SetPosSizePixel(rAllocPos, rAllocation); + setAllocation(rAllocation); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 73280fe1080f..a866a7d32974 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -574,6 +574,10 @@ CommandEvent ImplTranslateCommandEvent( const CommandEvent& rCEvt, Window* pSour void Window::ImplInitWindowData( WindowType nType ) { + m_bExpand = false; + m_bFill = false; + m_nPadding = 0; + mpWindowImpl = new WindowImpl; meOutDevType = OUTDEV_WINDOW; @@ -9571,4 +9575,18 @@ Selection Window::GetSurroundingTextSelection() const return Selection( 0, 0 ); } +//Poor man's equivalent, when widget want's to renegotiate +//size, get parent dialog and call resize on it +void Window::queueResize() +{ + fprintf(stderr, "Window::queueResize called\n"); + Window *pParent = GetParentDialog(); + fprintf(stderr, "parent dialog is %p\n", pParent); + if (pParent && pParent->GetChildCount() == 1) + { + fprintf(stderr, "suitable, so call resize\n"); + pParent->Resize(); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |