summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2011-11-09 22:58:42 +0000
committerCaolán McNamara <caolanm@redhat.com>2012-09-28 08:47:53 +0100
commit7d4c786e5c8b2b664997df6e9193cb4352cf9615 (patch)
tree367b1eb26d045ad64166b7ac11c22c3419b9715e /vcl
parenta73656244f75099415efe1b671783eea9dcbe5f9 (diff)
add basic hbox, vbox and dialog support
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/Package_inc.mk1
-rw-r--r--vcl/inc/vcl/dialog.hxx4
-rw-r--r--vcl/inc/vcl/fixed.hxx2
-rw-r--r--vcl/inc/vcl/layout.hxx154
-rw-r--r--vcl/inc/vcl/window.hxx13
-rw-r--r--vcl/source/control/fixed.cxx9
-rw-r--r--vcl/source/window/dialog.cxx23
-rw-r--r--vcl/source/window/layout.cxx171
-rw-r--r--vcl/source/window/window.cxx18
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: */