diff options
-rw-r--r-- | vcl/inc/vcl/layout.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/vcl/tabctrl.hxx | 13 | ||||
-rw-r--r-- | vcl/source/control/tabctrl.cxx | 105 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 53 | ||||
-rw-r--r-- | vcl/source/window/window2.cxx | 38 |
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 |