summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/vcl/layout.hxx5
-rw-r--r--vcl/inc/vcl/tabctrl.hxx13
-rw-r--r--vcl/source/control/tabctrl.cxx105
-rw-r--r--vcl/source/window/layout.cxx53
-rw-r--r--vcl/source/window/window2.cxx38
5 files changed, 134 insertions, 80 deletions
diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx
index 42071ce4f4cd..c7af5b95bff4 100644
--- a/vcl/inc/vcl/layout.hxx
+++ b/vcl/inc/vcl/layout.hxx
@@ -52,11 +52,16 @@ public:
{
return m_nBorderWidth;
}
+ void markLayoutDirty()
+ {
+ m_bLayoutDirty = true;
+ }
protected:
virtual Size calculateRequisition() const = 0;
virtual void setAllocation(const Size &rAllocation) = 0;
private:
int m_nBorderWidth;
+ bool m_bLayoutDirty;
};
class VCL_DLLPUBLIC VclBox : public VclContainer
diff --git a/vcl/inc/vcl/tabctrl.hxx b/vcl/inc/vcl/tabctrl.hxx
index 1710ec84d0cc..cc3d78b1124e 100644
--- a/vcl/inc/vcl/tabctrl.hxx
+++ b/vcl/inc/vcl/tabctrl.hxx
@@ -66,6 +66,7 @@ private:
sal_Bool mbRestoreHelpId;
sal_Bool mbRestoreUnqId;
sal_Bool mbSmallInvalidate;
+ bool mbLayoutDirty;
Link maActivateHdl;
Link maDeactivateHdl;
@@ -195,6 +196,18 @@ public:
// rename nOldId to nNewId);
void ReassignPageId(sal_uInt16 nOldId, sal_uInt16 nNewId);
+
+ using Control::SetPosSizePixel;
+ virtual void SetPosSizePixel(const Point& rNewPos, const Size& rNewSize);
+ virtual void SetSizePixel(const Size& rNewSize);
+
+ Size calculateRequisition() const;
+ void setAllocation(const Size &rAllocation);
+
+ void markLayoutDirty()
+ {
+ mbLayoutDirty = true;
+ }
};
#endif // _SV_TABCTRL_HXX
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index ff680ba60a9a..46bfbbd1d4bb 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -101,6 +101,8 @@ struct ImplTabCtrlData
void TabControl::ImplInit( Window* pParent, WinBits nStyle )
{
+ mbLayoutDirty = true;
+
if ( !(nStyle & WB_NOTABSTOP) )
nStyle |= WB_TABSTOP;
if ( !(nStyle & WB_NOGROUP) )
@@ -1225,7 +1227,7 @@ void TabControl::ImplPaint( const Rectangle& rRect, bool bLayout )
// -----------------------------------------------------------------------
-void TabControl::Resize()
+void TabControl::setAllocation(const Size &rAllocation)
{
ImplFreeLayoutData();
@@ -1249,7 +1251,7 @@ void TabControl::Resize()
// Aktuelle TabPage resizen/positionieren
sal_Bool bTabPage = ImplPosCurTabPage();
// Feststellen, was invalidiert werden muss
- Size aNewSize = Control::GetOutputSizePixel();
+ Size aNewSize = rAllocation;
long nNewWidth = aNewSize.Width();
for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
it != mpTabCtrlData->maItemList.end(); ++it )
@@ -1282,6 +1284,29 @@ void TabControl::Resize()
else
Invalidate();
}
+
+ mbLayoutDirty = false;
+}
+
+void TabControl::SetPosSizePixel(const Point& rNewPos, const Size& rNewSize)
+{
+ Window::SetPosSizePixel(rNewPos, rNewSize);
+ //if size changed, TabControl::Resize got called already
+ if (mbLayoutDirty)
+ setAllocation(rNewSize);
+}
+
+void TabControl::SetSizePixel(const Size& rNewSize)
+{
+ Window::SetSizePixel(rNewSize);
+ //if size changed, TabControl::Resize got called already
+ if (mbLayoutDirty)
+ setAllocation(rNewSize);
+}
+
+void TabControl::Resize()
+{
+ setAllocation(Control::GetOutputSizePixel());
}
// -----------------------------------------------------------------------
@@ -2125,57 +2150,55 @@ Point TabControl::GetItemsOffset() const
// -----------------------------------------------------------------------
-Size TabControl::GetOptimalSize(WindowSizeType eType) const
+Size TabControl::calculateRequisition() const
{
- switch (eType) {
- case WINDOWSIZE_MINIMUM:
- return mpTabCtrlData ? mpTabCtrlData->maMinSize : Size();
+ Size aOptimalPageSize(0, 0);
+ long nTabLabelsBottom = 0;
+ long nTotalTabLabelWidths = 0;
- default:
+ for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin();
+ it != mpTabCtrlData->maItemList.end(); ++it )
{
- Size aOptimalPageSize(0, 0);
- long nTabLabelsBottom = 0;
- long nTotalTabLabelWidths = 0;
+ Size aPageSize;
+ const TabPage *pPage = it->mpTabPage;
+ //it's a real nuisance if the page is not inserted yet :-(
+ if (pPage)
+ aPageSize = pPage->GetOptimalSize(WINDOWSIZE_PREFERRED);
- for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin();
- it != mpTabCtrlData->maItemList.end(); ++it )
- {
- Size aPageSize;
- const TabPage *pPage = it->mpTabPage;
- if (pPage)
- aPageSize = pPage->GetOptimalSize(eType);
- else
- fprintf(stderr, "nuisance, page not inserted yet :-(\n");
+ if (aPageSize.Width() > aOptimalPageSize.Width())
+ aOptimalPageSize.Width() = aPageSize.Width();
+ if (aPageSize.Height() > aOptimalPageSize.Height())
+ aOptimalPageSize.Height() = aPageSize.Height();
- if (aPageSize.Width() > aOptimalPageSize.Width())
- aOptimalPageSize.Width() = aPageSize.Width();
- if (aPageSize.Height() > aOptimalPageSize.Height())
- aOptimalPageSize.Height() = aPageSize.Height();
+ TabControl* pThis = const_cast<TabControl*>(this);
- TabControl* pThis = const_cast<TabControl*>(this);
+ sal_uInt16 nPos = it - mpTabCtrlData->maItemList.begin();
+ Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aPageSize.Width(), aPageSize.Height());
+ if (aTabRect.Bottom() > nTabLabelsBottom)
+ nTabLabelsBottom = aTabRect.Bottom();
- sal_uInt16 nPos = it - mpTabCtrlData->maItemList.begin();
- Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aPageSize.Width(), aPageSize.Height());
- if (aTabRect.Bottom() > nTabLabelsBottom)
- nTabLabelsBottom = aTabRect.Bottom();
+ ImplTabItem* pItem = const_cast<ImplTabItem*>(&(*it));
+ Size aTabSize = pThis->ImplGetItemSize(pItem, LONG_MAX);
+ nTotalTabLabelWidths += aTabSize.Width();
+ }
- ImplTabItem* pItem = const_cast<ImplTabItem*>(&(*it));
- Size aTabSize = pThis->ImplGetItemSize(pItem, LONG_MAX);
- nTotalTabLabelWidths += aTabSize.Width();
- }
+ Size aOptimalSize(aOptimalPageSize);
+ aOptimalSize.Height() += nTabLabelsBottom;
- Size aOptimalSize(aOptimalPageSize);
- aOptimalSize.Height() += nTabLabelsBottom;
+ if (nTotalTabLabelWidths > aOptimalSize.Width())
+ aOptimalSize.Width() = nTotalTabLabelWidths;
- if (nTotalTabLabelWidths > aOptimalSize.Width())
- aOptimalSize.Width() = nTotalTabLabelWidths;
+ aOptimalSize.Width() += TAB_OFFSET * 2;
+ aOptimalSize.Height() += TAB_OFFSET * 2;
- aOptimalSize.Width() += TAB_OFFSET * 2;
- aOptimalSize.Height() += TAB_OFFSET * 2;
+ return aOptimalSize;
+}
- return aOptimalSize;
- }
- }
+Size TabControl::GetOptimalSize(WindowSizeType eType) const
+{
+ if (eType == WINDOWSIZE_MINIMUM)
+ return mpTabCtrlData ? mpTabCtrlData->maMinSize : Size();
+ return calculateRequisition();
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 67b4af8f5b1a..2290edd5a410 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -33,6 +33,7 @@
VclContainer::VclContainer(Window *pParent)
: Window(WINDOW_CONTAINER)
, m_nBorderWidth(0)
+ , m_bLayoutDirty(true)
{
ImplInit(pParent, 0, NULL);
}
@@ -67,8 +68,11 @@ void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocati
else if (bSizeChanged)
Window::SetSizePixel(aAllocation);
- if (bSizeChanged)
+ if (m_bLayoutDirty || bSizeChanged)
+ {
setAllocation(aAllocation);
+ m_bLayoutDirty = false;
+ }
}
void VclContainer::SetPosPixel(const Point& rAllocPos)
@@ -86,11 +90,13 @@ void VclContainer::SetSizePixel(const Size& rAllocation)
Size aAllocation = rAllocation;
aAllocation.Width() -= m_nBorderWidth*2;
aAllocation.Height() -= m_nBorderWidth*2;
-
- if (aAllocation != GetSizePixel())
- {
+ bool bSizeChanged = aAllocation != GetSizePixel();
+ if (bSizeChanged)
Window::SetSizePixel(aAllocation);
+ if (m_bLayoutDirty || bSizeChanged)
+ {
setAllocation(aAllocation);
+ m_bLayoutDirty = false;
}
}
@@ -143,22 +149,6 @@ Size VclBox::calculateRequisition() const
return aSize;
}
-namespace
-{
- //avoid redraws when size/pos is unchanged
- void setPosSizePixel(Window &rWindow, const Point& rAllocPos, const Size& rAllocation)
- {
- bool bPosChanged = rAllocPos != rWindow.GetPosPixel();
- bool bSizeChanged = rAllocation != rWindow.GetSizePixel();
- if (bPosChanged && bSizeChanged)
- rWindow.SetPosSizePixel(rAllocPos, rAllocation);
- else if (bPosChanged)
- rWindow.SetPosPixel(rAllocPos);
- else if (bSizeChanged)
- rWindow.SetSizePixel(rAllocation);
- }
-}
-
void VclBox::setAllocation(const Size &rAllocation)
{
//SetBackground( Color(0x00, 0xFF, 0x00) );
@@ -263,7 +253,7 @@ void VclBox::setAllocation(const Size &rAllocation)
getPrimaryDimension(aBoxSize));
}
- setPosSizePixel(*pChild, aChildPos, aChildSize);
+ pChild->SetPosSizePixel(aChildPos, aChildSize);
}
}
}
@@ -390,7 +380,7 @@ void VclButtonBox::setAllocation(const Size &rAllocation)
setSecondaryDimension(aChildSize, getSecondaryDimension(aSize));
setPrimaryDimension(aChildSize, nHomogeneousDimension);
- setPosSizePixel(*pChild, aPos, aChildSize);
+ pChild->SetPosSizePixel(aPos, aChildSize);
nPrimaryCoordinate = getPrimaryCoordinate(aPos);
setPrimaryCoordinate(aPos, nPrimaryCoordinate + nHomogeneousDimension + m_nSpacing);
@@ -723,7 +713,7 @@ void VclGrid::setAllocation(const Size& rAllocation)
break;
}
- setPosSizePixel(*pChild, aChildPos, aChildSize);
+ pChild->SetPosSizePixel(aChildPos, aChildSize);
}
aAllocPos.Y() += aHeights[y].m_nValue + get_row_spacing();
}
@@ -786,7 +776,7 @@ void VclBin::setAllocation(const Size &rAllocation)
{
Window *pChild = get_child();
if (pChild && pChild->IsVisible())
- setPosSizePixel(*pChild, Point(0, 0), rAllocation);
+ pChild->SetPosSizePixel(Point(0, 0), rAllocation);
}
//To-Do, hook a DecorationView into VclFrame ?
@@ -839,13 +829,13 @@ void VclFrame::setAllocation(const Size &rAllocation)
Size aLabelSize = pLabel->GetOptimalSize(WINDOWSIZE_PREFERRED);
aLabelSize.Height() = std::min(aLabelSize.Height(), aAllocation.Height());
aLabelSize.Width() = std::min(aLabelSize.Width(), aAllocation.Width());
- setPosSizePixel(*pLabel, aChildPos, aLabelSize);
+ pLabel->SetPosSizePixel(aChildPos, aLabelSize);
aAllocation.Height() -= aLabelSize.Height();
aChildPos.Y() += aLabelSize.Height();
}
if (pChild && pChild->IsVisible())
- setPosSizePixel(*pChild, aChildPos, aAllocation);
+ pChild->SetPosSizePixel(aChildPos, aAllocation);
}
Size VclAlignment::calculateRequisition() const
@@ -876,7 +866,7 @@ void VclAlignment::setAllocation(const Size &rAllocation)
aAllocation.Width() = rAllocation.Width() - (m_nLeftPadding + m_nRightPadding);
aAllocation.Height() = rAllocation.Height() - (m_nTopPadding + m_nBottomPadding);
- setPosSizePixel(*pChild, aChildPos, aAllocation);
+ pChild->SetPosSizePixel(aChildPos, aAllocation);
}
bool VclAlignment::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
@@ -980,7 +970,7 @@ void VclExpander::setAllocation(const Size &rAllocation)
long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
- setPosSizePixel(m_aDisclosureButton, aButtonPos, aButtonSize);
+ m_aDisclosureButton.SetPosSizePixel(aButtonPos, aButtonSize);
if (pLabel && pLabel->IsVisible())
{
@@ -990,7 +980,7 @@ void VclExpander::setAllocation(const Size &rAllocation)
long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
- setPosSizePixel(*pLabel, aLabelPos, aLabelSize);
+ pLabel->SetPosSizePixel(aLabelPos, aLabelSize);
}
aAllocation.Height() -= aExpanderSize.Height();
@@ -1000,7 +990,7 @@ void VclExpander::setAllocation(const Size &rAllocation)
{
if (!m_aDisclosureButton.IsChecked())
aAllocation = Size();
- setPosSizePixel(*pChild, aChildPos, aAllocation);
+ pChild->SetPosSizePixel(aChildPos, aAllocation);
}
}
@@ -1021,11 +1011,10 @@ IMPL_LINK( VclExpander, ClickHdl, DisclosureButton*, pBtn )
if (pChild)
{
pChild->Show(pBtn->IsChecked());
+ queue_resize();
Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : NULL;
if (pResizeDialog)
pResizeDialog->setInitialLayoutSize();
- else
- queue_resize();
}
return 0;
}
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index 9b51446260dd..5e27f5eed9e7 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -41,6 +41,7 @@
#include <vcl/window.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/dockwin.hxx>
+#include <vcl/tabctrl.hxx>
#include <window.h>
#include <outfont.hxx>
@@ -1749,16 +1750,39 @@ void Window::SetBackgroundBitmap( const BitmapEx& rBitmapEx )
}
}
-//When a widget wants to renegotiate size, get toplevel parent dialog and call
-//resize on it. Maybe better to just find direct parent and if its a container
-//chain it upwards one step at a time until a dialog is found.
+//When a widget wants to renegotiate layout, get toplevel parent dialog and call
+//resize on it. Mark all intermediate containers (or container-alike) widgets
+//as dirty for the size remains unchanged, but layout changed circumstances
void Window::queue_resize()
{
- Dialog *pParent = GetParentDialog();
- if (!pParent || pParent == this)
+ Dialog *pDialog = NULL;
+
+ Window *pWindow = this;
+
+ while( pWindow )
+ {
+ if (pWindow->GetType() == WINDOW_CONTAINER)
+ {
+ VclContainer *pContainer = static_cast<VclContainer*>(pWindow);
+ pContainer->markLayoutDirty();
+ }
+ else if (pWindow->GetType() == WINDOW_TABCONTROL)
+ {
+ TabControl *pTabControl = static_cast<TabControl*>(pWindow);
+ pTabControl->markLayoutDirty();
+ }
+ else if (pWindow->IsDialog())
+ {
+ pDialog = dynamic_cast<Dialog*>(pWindow);
+ break;
+ }
+ pWindow = pWindow->GetParent();
+ }
+
+ if (!pDialog || pDialog == this)
return;
- if (pParent->isLayoutEnabled())
- pParent->Resize();
+ if (pDialog->isLayoutEnabled())
+ pDialog->Resize();
}
//We deliberately do not overwrite our maHelpId here