diff options
author | Andre Fischer <af@openoffice.org> | 2010-03-19 15:06:39 +0100 |
---|---|---|
committer | Andre Fischer <af@openoffice.org> | 2010-03-19 15:06:39 +0100 |
commit | b390fae1706b9c511158a03e4fd61f263be4e511 (patch) | |
tree | 644429f16c6834c397b10dee200a01aa7ed516ee /sd/source/ui/slidesorter/view | |
parent | 8c23aba539c0f5764ec543e4cfa6bac2fc20e7ae (diff) |
renaissance1: #i107215# Reorganized and improved layouting.
Diffstat (limited to 'sd/source/ui/slidesorter/view')
-rw-r--r-- | sd/source/ui/slidesorter/view/SlideSorterView.cxx | 290 | ||||
-rw-r--r-- | sd/source/ui/slidesorter/view/SlsLayouter.cxx | 1512 | ||||
-rw-r--r-- | sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx | 28 |
3 files changed, 1176 insertions, 654 deletions
diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 16da8620fb9b..fdfd9ec8f8f0 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -54,6 +54,7 @@ #include "cache/SlsCacheContext.hxx" #include "taskpane/SlideSorterCacheDisplay.hxx" #include "DrawDocShell.hxx" +#include "PaneDockingWindow.hxx" #include "drawdoc.hxx" #include "sdpage.hxx" @@ -122,97 +123,8 @@ private: SlideSorterView& mrView; }; -class AnimatedSphere -{ -public: - AnimatedSphere ( - const Size& rWindowSize, - const double nStartTime) - : mnCenterX(rand() * rWindowSize.Width() / RAND_MAX), - mnCenterY(rand() * rWindowSize.Height() / RAND_MAX), - mnStartRadius(10), - mnEndRadius(rand() * 150 / RAND_MAX), - maColor(GetColor()), - mnLocalTime(-nStartTime), - mnValue(0), - mnStartTime(nStartTime), - mbIsValid(rWindowSize.Width()>10 && rWindowSize.Height()>10), - mnSpeedUp(0.5 + rand() * 1.0 / RAND_MAX) - { - } - void SetTime (const double nTime) - { - mnLocalTime = (nTime - mnStartTime) * mnSpeedUp; - if (mnLocalTime >= 0 && mnLocalTime <= mnSpeedUp) - mnValue = controller::AnimationFunction::SlowInSlowOut_0to0_Sine(mnLocalTime/mnSpeedUp); - else - mnValue = 0; - } - bool IsExpired (void) - { - return mnLocalTime >= mnSpeedUp || ! mbIsValid; - } - - Rectangle GetBoundingBox (void) - { - if (mnLocalTime < 0) - return Rectangle(); - - const double nRadius (mnStartRadius*(1-mnValue) + mnEndRadius*mnValue); - const sal_Int32 nIntRadius (ceil(nRadius)+1); - return Rectangle( - mnCenterX-nIntRadius, - mnCenterY-nIntRadius, - mnCenterX+nIntRadius, - mnCenterY+nIntRadius); - } - - void Paint (OutputDevice& rDevice) - { - if (mnLocalTime < 0 || ! mbIsValid) - return; - - rDevice.SetFillColor(maColor); - rDevice.SetLineColor(); - - const Rectangle aBox (GetBoundingBox()); - const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); - rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); - rDevice.DrawPolygon( - ::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), - 1.0, - 1.0)); - rDevice.SetAntialiasing(nSavedAntialiasingMode); - } - -private: - const sal_Int32 mnCenterX; - const sal_Int32 mnCenterY; - const double mnStartRadius; - const double mnEndRadius; - const Color maColor; - double mnLocalTime; - double mnValue; - const double mnStartTime; - const bool mbIsValid; - const double mnSpeedUp; - - static Color GetColor (void) - { - Color aColor; - do - { - aColor.SetRed(rand() * 255 / RAND_MAX); - aColor.SetGreen(rand() * 255 / RAND_MAX); - aColor.SetBlue(rand() * 255 / RAND_MAX); - } - while (aColor.GetGreen()<=aColor.GetRed() || aColor.GetGreen()<=aColor.GetBlue()); - return aColor; - } -}; class BackgroundPainter : public ILayerPainter, @@ -220,31 +132,15 @@ class BackgroundPainter { public: BackgroundPainter ( - const ::boost::shared_ptr<controller::Animator>& rpAnimator, const SharedSdWindow& rpWindow, - const Color aBackgroundColor, - const bool bIsAnimated) - : mpAnimator(rpAnimator), - maBackgroundColor(aBackgroundColor), - maSpheres(), - mpInvalidator(), - mpWindow(rpWindow), - mnAnimationId(controller::Animator::NotAnAnimationId) + const Color aBackgroundColor) + : maBackgroundColor(aBackgroundColor), + mpWindow(rpWindow) { - if (bIsAnimated) - { - mnAnimationId = mpAnimator->AddInfiniteAnimation(::boost::ref(*this), 0.01); - - for (sal_Int32 nIndex=0; nIndex<10; ++nIndex) - maSpheres.push_back(::boost::shared_ptr<AnimatedSphere>( - new AnimatedSphere(rpWindow->GetSizePixel(), nIndex*0.3))); - } } ~BackgroundPainter (void) { - if (mnAnimationId >= 0) - mpAnimator->RemoveAnimation(mnAnimationId); } virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) @@ -252,66 +148,16 @@ public: rDevice.SetFillColor(maBackgroundColor); rDevice.SetLineColor(); rDevice.DrawRect(rRepaintArea); - - for (SphereVector::const_iterator - iSphere(maSpheres.begin()), - iEnd(maSpheres.end()); - iSphere!=iEnd; - ++iSphere) - { - if (rRepaintArea.IsOver((*iSphere)->GetBoundingBox())) - (*iSphere)->Paint(rDevice); - } } virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator) { - Invalidate(); - mpInvalidator = rpInvalidator; - Invalidate(); - } - - void operator () (const double nTime) - { - Invalidate(); - - for (SphereVector::iterator - iSphere(maSpheres.begin()), - iEnd(maSpheres.end()); - iSphere!=iEnd; - ++iSphere) - { - if ((*iSphere)->IsExpired()) - (*iSphere).reset( - new AnimatedSphere(mpWindow->GetSizePixel(), nTime)); - else - (*iSphere)->SetTime(nTime); - } - - Invalidate(); + (void)rpInvalidator; } private: - const ::boost::shared_ptr<controller::Animator> mpAnimator; const Color maBackgroundColor; - typedef ::std::vector< ::boost::shared_ptr<AnimatedSphere> > SphereVector; - SphereVector maSpheres; - SharedILayerInvalidator mpInvalidator; SharedSdWindow mpWindow; - controller::Animator::AnimationId mnAnimationId; - - void Invalidate (void) - { - if (mpInvalidator) - for (SphereVector::const_iterator - iSphere(maSpheres.begin()), - iEnd(maSpheres.end()); - iSphere!=iEnd; - ++iSphere) - { - mpInvalidator->Invalidate((*iSphere)->GetBoundingBox()); - } - } }; @@ -334,7 +180,7 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) mbModelChangedWhileModifyEnabled(true), maPreviewSize(0,0), mbPreciousFlagUpdatePending(true), - meOrientation(VERTICAL), + meOrientation(Layouter::GRID), mpProperties(rSlideSorter.GetProperties()), mpPageUnderMouse(), mbIsMouseOverIndicationAllowed(true), @@ -342,8 +188,6 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) mpPageObjectPainter(), mpSelectionPainter() { - OSL_TRACE("layered device at %x", mpLayeredDevice.get()); - // Hide the page that contains the page objects. SetPageVisible (FALSE); @@ -352,7 +196,6 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) // the SlideSorterView destructor the layered device is destroyed and // with it the only reference to the wrapper which therefore is also // destroyed. - OSL_TRACE("layered device at %x", mpLayeredDevice.get()); mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 2); } @@ -374,9 +217,6 @@ SlideSorterView::~SlideSorterView (void) void SlideSorterView::Init (void) { HandleModelChange(); - - // mpSelectionPainter.reset(new SelectionPainter(mrSlideSorter)); - // mpLayeredDevice->RegisterPainter(mpSelectionPainter, 1); } @@ -389,7 +229,7 @@ void SlideSorterView::Dispose (void) mpLayeredDevice->Dispose(); mpPreviewCache.reset(); - // hide the page to avoid problems in the view when deleting + // Hide the page to avoid problems in the view when deleting // visualized objects HideSdrPage(); @@ -448,11 +288,6 @@ void SlideSorterView::LocalModelHasChanged(void) // First call our base class. View::ModelHasChanged (); - - // Initialize everything that depends on a page view, now that we have - // one. - // SetApplicationDocumentColor( - // Application::GetSettings().GetStyleSettings().GetWindowColor()); } @@ -514,34 +349,25 @@ void SlideSorterView::HandleDrawModeChange (void) void SlideSorterView::Resize (void) { + UpdateOrientation(); + if ( ! mpLayeredDevice->HasPainter(0)) mpLayeredDevice->RegisterPainter( SharedILayerPainter(new BackgroundPainter( - mrSlideSorter.GetController().GetAnimator(), mrSlideSorter.GetContentWindow(), - mrSlideSorter.GetTheme()->GetColor(Theme::Background), - false)), + mrSlideSorter.GetTheme()->GetColor(Theme::Background))), 0); mpLayeredDevice->Resize(); SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (mrModel.GetPageCount()>0 && pWindow) { - bool bRearrangeSuccess (false); - if (meOrientation == HORIZONTAL) - { - bRearrangeSuccess = mpLayouter->RearrangeHorizontal ( - pWindow->GetSizePixel(), - mrModel.GetPageDescriptor(0)->GetPage()->GetSize(), - mrModel.GetPageCount()); - } - else - { - bRearrangeSuccess = mpLayouter->RearrangeVertical ( + const bool bRearrangeSuccess ( + mpLayouter->Rearrange ( + meOrientation, pWindow->GetSizePixel(), mrModel.GetPageDescriptor(0)->GetPage()->GetSize(), - mrModel.GetPageCount()); - } + mrModel.GetPageCount())); if (bRearrangeSuccess) { @@ -554,6 +380,75 @@ void SlideSorterView::Resize (void) +void SlideSorterView::UpdateOrientation (void) +{ + // The layout of slides depends on whether the slide sorter is + // displayed in the center or the side pane. + if (mrSlideSorter.GetViewShell()->IsMainViewShell()) + SetOrientation(Layouter::GRID); + else + { + // Get access to the docking window. + ::Window* pWindow = mrSlideSorter.GetContentWindow().get(); + PaneDockingWindow* pDockingWindow = NULL; + while (pWindow!=NULL && pDockingWindow==NULL) + { + pDockingWindow = dynamic_cast<PaneDockingWindow*>(pWindow); + pWindow = pWindow->GetParent(); + } + + if (pDockingWindow != NULL) + { + const long nScrollBarSize ( + Application::GetSettings().GetStyleSettings().GetScrollBarSize()); + switch (pDockingWindow->GetOrientation()) + { + case PaneDockingWindow::HorizontalOrientation: + if (SetOrientation(Layouter::HORIZONTAL)) + { + const Range aRange (mpLayouter->GetValidVerticalSizeRange()); + pDockingWindow->SetValidSizeRange(Range( + aRange.Min() + nScrollBarSize, + aRange.Max() + nScrollBarSize)); + } + break; + + case PaneDockingWindow::VerticalOrientation: + if (SetOrientation(Layouter::VERTICAL)) + { + const Range aRange (mpLayouter->GetValidHorizontalSizeRange()); + pDockingWindow->SetValidSizeRange(Range( + aRange.Min() + nScrollBarSize, + aRange.Max() + nScrollBarSize)); + } + break; + + case PaneDockingWindow::UnknownOrientation: + if (SetOrientation(Layouter::GRID)) + { + const sal_Int32 nAdditionalSize (10); + pDockingWindow->SetMinOutputSizePixel(Size( + mpLayouter->GetValidHorizontalSizeRange().Min() + + nScrollBarSize + + nAdditionalSize, + mpLayouter->GetValidVerticalSizeRange().Min() + + nScrollBarSize + + nAdditionalSize)); + } + return; + } + } + else + { + OSL_ASSERT(pDockingWindow!=NULL); + SetOrientation(Layouter::GRID); + } + } +} + + + + void SlideSorterView::Layout () { SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); @@ -561,7 +456,7 @@ void SlideSorterView::Layout () { // Set the model area, i.e. the smallest rectangle that includes all // page objects. - const Rectangle aViewBox (mpLayouter->GetPageBox(mrModel.GetPageCount())); + const Rectangle aViewBox (mpLayouter->GetTotalBoundingBox()); pWindow->SetViewOrigin (aViewBox.TopLeft()); pWindow->SetViewSize (aViewBox.GetSize()); @@ -679,16 +574,21 @@ void SlideSorterView::UpdatePreciousFlags (void) -void SlideSorterView::SetOrientation (const Orientation eOrientation) +bool SlideSorterView::SetOrientation (const Layouter::Orientation eOrientation) { - meOrientation = eOrientation; - RequestRepaint(); + if (meOrientation != eOrientation) + { + meOrientation = eOrientation; + return true; + } + else + return false; } -SlideSorterView::Orientation SlideSorterView::GetOrientation (void) const +Layouter::Orientation SlideSorterView::GetOrientation (void) const { return meOrientation; } @@ -747,7 +647,7 @@ void SlideSorterView::RequestRepaint (const Region& rRepaintRegion) Rectangle SlideSorterView::GetModelArea (void) { - return mpLayouter->GetPageBox(mrModel.GetPageCount()); + return mpLayouter->GetTotalBoundingBox(); } @@ -917,7 +817,7 @@ void SlideSorterView::SetIsMouseOverIndicationAllowed (const bool bIsAllowed) void SlideSorterView::UpdatePageUnderMouse (bool bAnimate) { SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - if (pWindow) + if (pWindow && ! pWindow->IsMouseCaptured()) { const Window::PointerState aPointerState (pWindow->GetPointerState()); UpdatePageUnderMouse ( diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 156ebaac8b7d..cc43787972a8 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -33,69 +33,301 @@ #include "view/SlsLayouter.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" - #include "Window.hxx" +#include <rtl/math.hxx> #include <basegfx/numeric/ftools.hxx> +namespace { + sal_Int32 RoundToInt (const double nValue) + { + return sal_Int32(::rtl::math::round(nValue)); + } +} + namespace sd { namespace slidesorter { namespace view { -Layouter::Layouter (const SharedSdWindow& rpWindow) - : mpWindow(rpWindow), - mnRequestedLeftBorder(5), - mnRequestedRightBorder(5), - mnRequestedTopBorder(5), - mnRequestedBottomBorder(5), - mnLeftBorder(5), - mnRightBorder(5), - mnTopBorder(5), - mnBottomBorder(5), - mnVerticalGap (10), - mnHorizontalGap(10), - mnMinimalWidth(100), - mnPreferredWidth(200), - mnMaximalWidth(300), - mnMinimalColumnCount(1), - mnMaximalColumnCount(4), - mnPageCount(0), - mnColumnCount(1), - mnRowCount(0), - mnMaxColumnCount(0), - mnMaxRowCount(0), - maPageObjectSize(1,1), - mbIsVertical(true) +class Layouter::Implementation { -} +public: + SharedSdWindow mpWindow; + sal_Int32 mnRequestedLeftBorder; + sal_Int32 mnRequestedRightBorder; + sal_Int32 mnRequestedTopBorder; + sal_Int32 mnRequestedBottomBorder; + sal_Int32 mnLeftBorder; + sal_Int32 mnRightBorder; + sal_Int32 mnTopBorder; + sal_Int32 mnBottomBorder; + sal_Int32 mnVerticalGap; + sal_Int32 mnHorizontalGap; + Size maMinimalSize; + Size maPreferredSize; + Size maMaximalSize; + sal_Int32 mnMinimalColumnCount; + sal_Int32 mnMaximalColumnCount; + sal_Int32 mnPageCount; + sal_Int32 mnColumnCount; + sal_Int32 mnRowCount; + /// The maximum number of columns. Can only be larger than the current + /// number of columns when there are not enough pages to fill all + /// available columns. + sal_Int32 mnMaxColumnCount; + /// The maximum number of rows. Can only be larger than the current + /// number of rows when there are not enough pages to fill all available + /// rows. + sal_Int32 mnMaxRowCount; + Size maPageObjectSize; + + ::boost::shared_ptr<PageObjectLayouter> mpPageObjectLayouter; + + enum GapMembership { + GM_NONE, + GM_PREVIOUS, + GM_BOTH, + GM_NEXT, + GM_PAGE_BORDER + }; + + static Implementation* Create ( + const Implementation& rImplementation, + const Layouter::Orientation eOrientation); + + virtual Layouter::Orientation GetOrientation (void) const = 0; + + bool Rearrange ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const sal_uInt32 nPageCount); + + /** Calculate the row that the point with the given vertical coordinate + is over. The horizontal component is ignored. + @param nYPosition + Vertical position in model coordinates. + @param bIncludeBordersAndGaps + When this flag is <TRUE/> then the area of borders and gaps are + interpreted as belonging to one of the rows. + @param eGapMembership + Specifies to what row the gap areas belong. Here GM_NONE + corresponds to bIncludeBordersAndGaps being <FALSE/>. When + GM_BOTH is given then the upper half is associated to the row + above and the lower half to the row below. Values of + GM_PREVIOUS and GM_NEXT associate the whole gap area with the + row above or below respectively. + */ + sal_Int32 GetRowAtPosition ( + sal_Int32 nYPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership = GM_NONE) const; + + /** Calculate the column that the point with the given horizontal + coordinate is over. The verical component is ignored. + @param nXPosition + Horizontal position in model coordinates. + @param bIncludeBordersAndGaps + When this flag is <TRUE/> then the area of borders and gaps are + interpreted as belonging to one of the columns. + @param eGapMembership + Specifies to what column the gap areas belong. Here GM_NONE + corresponds to bIncludeBordersAndGaps being <FALSE/>. When + GM_BOTH is given then the left half is associated with the + column at the left and the right half with the column to the + right. Values of GM_PREVIOUS and GM_NEXT associate the whole + gap area with the column to the left or right respectively. + */ + sal_Int32 GetColumnAtPosition ( + sal_Int32 nXPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership = GM_NONE) const; + + /** This method is typically called from GetRowAtPosition() and + GetColumnAtPosition() to handle a position that lies inside the gap + between two adjacent rows or columns. + @param nDistanceIntoGap + Vertical distance from the bottom of the upper row down into the + gap or or horizontal distance from the right edge right into the + gap. + @param eGapMemberhship + This value decides what areas in the gap belong to which (or no) + row or column. + @param nIndex + The row index of the upper row or the column index of the left + column. + @param nGap + Width or height of the gap in model coordiantes between the + page borders. + @return + Returns either the index of the upper row (as given as nRow), the + index of the lower row (nRow+1) or -1 to indicate that the + position belongs to no row. + */ + sal_Int32 ResolvePositionInGap ( + sal_Int32 nDistanceIntoGap, + GapMembership eGapMembership, + sal_Int32 nIndex, + sal_Int32 nGap) const; + + /** Calculate the logical part of the insert position, i.e. the page + after whicht to insert. + */ + virtual void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const = 0; + + /** Calculate the geometrical part of the insert position, i.e. the + location of where to display the insertion indicator and the + distances about which the leading and trailing pages have to be + moved to make room for the indicator. + */ + void CalculateGeometricPosition ( + InsertPosition& rPosition, + const Size& rIndicatorSize, + const bool bIsVertical, + model::SlideSorterModel& rModel) const; + + /** Return the bounding box of the preview or, when selected, of the page + object. Thus, it returns something like a visual bounding box. + */ + Rectangle GetInnerBoundingBox ( + model::SlideSorterModel& rModel, + const sal_Int32 nIndex) const; + + Range GetValidHorizontalSizeRange (void) const; + Range GetValidVerticalSizeRange (void) const; + + Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const bool bCalculateWidth, + const bool bCalculateHeight) const; + + Rectangle GetPageObjectBox ( + const sal_Int32 nIndex, + const bool bIncludeBorderAndGap = false) const; + + Rectangle GetPageObjectBox ( + const sal_Int32 nRow, + const sal_Int32 nColumn) const; + + Rectangle AddBorderAndGap ( + const Rectangle& rBoundingBox, + const sal_Int32 nRow, + const sal_Int32 nColumn) const; + + Rectangle GetTotalBoundingBox (void) const; + + virtual ~Implementation (void); +protected: + Implementation (const SharedSdWindow& rpWindow); + Implementation (const Implementation& rImplementation); + + virtual void CalculateRowAndColumnCount (const Size& rWindowSize) = 0; + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) = 0; + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const = 0; + void CalculateVerticalLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; +}; + + +/** The vertical layouter has one column and as many rows as there are + pages. +*/ +class VerticalImplementation : public Layouter::Implementation +{ +public: + VerticalImplementation (const SharedSdWindow& rpWindow); + VerticalImplementation (const Implementation& rImplementation); + virtual Layouter::Orientation GetOrientation (void) const; + void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; +protected: + virtual void CalculateRowAndColumnCount (const Size& rWindowSize); + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const; +}; -Layouter::~Layouter (void) + +/** The horizontal layouter has one row and as many columns as there are + pages. +*/ +class HorizontalImplementation : public Layouter::Implementation +{ +public: + HorizontalImplementation (const SharedSdWindow& rpWindow); + HorizontalImplementation (const Implementation& rImplementation); + + virtual Layouter::Orientation GetOrientation (void) const; + + void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; + +protected: + virtual void CalculateRowAndColumnCount (const Size& rWindowSize); + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const; +}; + + +/** The number of columns of the grid layouter is defined via a control in + the slide sorter tool bar. The number of rows is calculated from the + number of columns and the number of pages. +*/ +class GridImplementation : public Layouter::Implementation +{ +public: + GridImplementation (const SharedSdWindow& rpWindow); + GridImplementation (const Implementation& rImplementation); + + virtual Layouter::Orientation GetOrientation (void) const; + + void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; + +protected: + virtual void CalculateRowAndColumnCount (const Size& rWindowSize); + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const; +}; + + + + +//===== Layouter ============================================================== + +Layouter::Layouter (const SharedSdWindow& rpWindow) + : mpImplementation(new GridImplementation(rpWindow)), + mpWindow(rpWindow) { } -::boost::shared_ptr<PageObjectLayouter> Layouter::GetPageObjectLayouter (void) const +Layouter::~Layouter (void) { - return mpPageObjectLayouter; } -void Layouter::SetObjectWidth ( - sal_Int32 nMinimalWidth, - sal_Int32 nMaximalWidth, - sal_Int32 nPreferredWidth) +::boost::shared_ptr<PageObjectLayouter> Layouter::GetPageObjectLayouter (void) const { - if (nMinimalWidth <= nPreferredWidth && nPreferredWidth <= nMaximalWidth) - { - mnMinimalWidth = nMinimalWidth; - mnPreferredWidth = nMaximalWidth; - mnMaximalWidth = nPreferredWidth; - } + return mpImplementation->mpPageObjectLayouter; } @@ -108,13 +340,13 @@ void Layouter::SetBorders ( sal_Int32 nBottomBorder) { if (nLeftBorder >= 0) - mnRequestedLeftBorder = nLeftBorder; + mpImplementation->mnRequestedLeftBorder = nLeftBorder; if (nRightBorder >= 0) - mnRequestedRightBorder = nRightBorder; + mpImplementation->mnRequestedRightBorder = nRightBorder; if (nTopBorder >= 0) - mnRequestedTopBorder = nTopBorder; + mpImplementation->mnRequestedTopBorder = nTopBorder; if (nBottomBorder >= 0) - mnRequestedBottomBorder = nBottomBorder; + mpImplementation->mnRequestedBottomBorder = nBottomBorder; } @@ -125,9 +357,9 @@ void Layouter::SetGaps ( sal_Int32 nVerticalGap) { if (nHorizontalGap >= 0) - mnHorizontalGap = nHorizontalGap; + mpImplementation->mnHorizontalGap = nHorizontalGap; if (nVerticalGap >= 0) - mnVerticalGap = nVerticalGap; + mpImplementation->mnVerticalGap = nVerticalGap; } @@ -140,193 +372,46 @@ void Layouter::SetColumnCount ( { if (nMinimalColumnCount <= nMaximalColumnCount) { - mnMinimalColumnCount = nMinimalColumnCount; - mnMaximalColumnCount = nMaximalColumnCount; + mpImplementation->mnMinimalColumnCount = nMinimalColumnCount; + mpImplementation->mnMaximalColumnCount = nMaximalColumnCount; } } -bool Layouter::RearrangeHorizontal ( +bool Layouter::Rearrange ( + const Orientation eOrientation, const Size& rWindowSize, const Size& rPageSize, const sal_uInt32 nPageCount) { OSL_ASSERT(mpWindow); - mbIsVertical = false; - mnPageCount = nPageCount; - - if (rWindowSize.Width() > 0 - && rWindowSize.Height() > 0 - && rPageSize.Width() > 0 - && rPageSize.Height() > 0) - { - // Calculate the column count. - mnColumnCount = nPageCount; - mnRowCount = 1; - - // Update the border values. - mnLeftBorder = mnRequestedLeftBorder; - mnTopBorder = mnRequestedTopBorder; - mnRightBorder = mnRequestedRightBorder; - mnBottomBorder = mnRequestedBottomBorder; - if (mnColumnCount > 1) - { - int nMinimumBorderWidth = mnHorizontalGap/2; - if (mnLeftBorder < nMinimumBorderWidth) - mnLeftBorder = nMinimumBorderWidth; - if (mnRightBorder < nMinimumBorderWidth) - mnRightBorder = nMinimumBorderWidth; - } - else - { - int nMinimumBorderHeight = mnVerticalGap/2; - if (mnTopBorder < nMinimumBorderHeight) - mnTopBorder = nMinimumBorderHeight; - if (mnBottomBorder < nMinimumBorderHeight) - mnBottomBorder = nMinimumBorderHeight; - } - - // Calculate the width of each page object. - sal_uInt32 nTargetHeight = 0; - sal_uInt32 nRowCount = 1; - if (mnColumnCount > 0) - nTargetHeight = (rWindowSize.Height() - - mnTopBorder - - mnBottomBorder - - (nRowCount-1) * mnVerticalGap - ) - / nRowCount; - sal_uInt32 nMinimalHeight (mnMinimalWidth * rPageSize.Height() / rPageSize.Width()); - sal_uInt32 nMaximalHeight (mnMaximalWidth * rPageSize.Height() / rPageSize.Width()); - if (nTargetHeight < nMinimalHeight) - nTargetHeight = nMinimalHeight; - if (nTargetHeight > nMaximalHeight) - nTargetHeight = nMaximalHeight; - - // Setup the page object layouter and ask it for the page object size. - mpPageObjectLayouter.reset( - new PageObjectLayouter( - Size(0, nTargetHeight), - rPageSize, - mpWindow, - nPageCount)); - maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); - - mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) - / (maPageObjectSize.Width() + mnHorizontalGap); - mnMaxRowCount = 1; - - return true; - } - else - return false; -} - - - - -bool Layouter::RearrangeVertical ( - const Size& rWindowSize, - const Size& rPreviewModelSize, - const sal_uInt32 nPageCount) -{ - OSL_ASSERT(mpWindow); - - mbIsVertical = true; - mnPageCount = nPageCount; + if (eOrientation != mpImplementation->GetOrientation()) + mpImplementation.reset(Implementation::Create(*mpImplementation, eOrientation)); - if (rWindowSize.Width() > 0 - && rWindowSize.Height() > 0 - && rPreviewModelSize.Width() > 0 - && rPreviewModelSize.Height() > 0) - { - // Calculate the column count. - mnColumnCount = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder) - / (mnPreferredWidth + mnHorizontalGap); - if (mnColumnCount < mnMinimalColumnCount) - mnColumnCount = mnMinimalColumnCount; - if (mnColumnCount > mnMaximalColumnCount) - mnColumnCount = mnMaximalColumnCount; - mnRowCount = (nPageCount + mnColumnCount-1)/mnColumnCount; - - // Update the border values. - mnLeftBorder = mnRequestedLeftBorder; - mnTopBorder = mnRequestedTopBorder; - mnRightBorder = mnRequestedRightBorder; - mnBottomBorder = mnRequestedBottomBorder; - if (mnColumnCount > 1) - { - int nMinimumBorderWidth = mnHorizontalGap/2; - if (mnLeftBorder < nMinimumBorderWidth) - mnLeftBorder = nMinimumBorderWidth; - if (mnRightBorder < nMinimumBorderWidth) - mnRightBorder = nMinimumBorderWidth; - } - else - { - int nMinimumBorderHeight = mnVerticalGap/2; - if (mnTopBorder < nMinimumBorderHeight) - mnTopBorder = nMinimumBorderHeight; - if (mnBottomBorder < nMinimumBorderHeight) - mnBottomBorder = nMinimumBorderHeight; - } - - // Calculate the width of each page object. - sal_Int32 nTargetWidth = 0; - if (mnColumnCount > 0) - nTargetWidth = (rWindowSize.Width() - - mnLeftBorder - - mnRightBorder - - (mnColumnCount-1) * mnHorizontalGap - ) - / mnColumnCount; - if (nTargetWidth < mnMinimalWidth) - nTargetWidth = mnMinimalWidth; - if (nTargetWidth > mnMaximalWidth) - nTargetWidth = mnMaximalWidth; - - // Setup the page object layouter and ask it for the page object size. - mpPageObjectLayouter.reset( - new PageObjectLayouter( - Size(nTargetWidth, 0), - rPreviewModelSize, - mpWindow, - nPageCount)); - maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); - - mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) - / (maPageObjectSize.Width() + mnHorizontalGap); - mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) - / (maPageObjectSize.Height() + mnVerticalGap); - - return true; - } - else - return false; + return mpImplementation->Rearrange(rWindowSize, rPageSize, nPageCount); } -void Layouter::SetZoom (double nZoomFactor) +void Layouter::_SetZoom (double nZoomFactor) { - SetZoom(Fraction(nZoomFactor)); + _SetZoom(Fraction(nZoomFactor)); } -void Layouter::SetZoom (Fraction nZoomFactor) +void Layouter::_SetZoom (Fraction nZoomFactor) { OSL_ASSERT(mpWindow); MapMode aMapMode (mpWindow->GetMapMode()); aMapMode.SetScaleX (nZoomFactor); aMapMode.SetScaleY (nZoomFactor); - // maPageObjectPixelSize = mpWindow->LogicToPixel (maPageObjectModelSize); mpWindow->SetMapMode (aMapMode); } @@ -335,7 +420,7 @@ void Layouter::SetZoom (Fraction nZoomFactor) sal_Int32 Layouter::GetColumnCount (void) const { - return mnColumnCount; + return mpImplementation->mnColumnCount; } @@ -343,7 +428,7 @@ sal_Int32 Layouter::GetColumnCount (void) const sal_Int32 Layouter::GetRowCount (void) const { - return mnRowCount; + return mpImplementation->mnRowCount; } @@ -351,7 +436,7 @@ sal_Int32 Layouter::GetRowCount (void) const sal_Int32 Layouter::GetRow (const sal_Int32 nIndex) const { - return nIndex / mnColumnCount; + return nIndex / mpImplementation->mnColumnCount; } @@ -359,7 +444,7 @@ sal_Int32 Layouter::GetRow (const sal_Int32 nIndex) const sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const { - return nIndex % mnColumnCount; + return nIndex % mpImplementation->mnColumnCount; } @@ -367,9 +452,9 @@ sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const { - const sal_Int32 nIndex (nRow * mnColumnCount + nColumn); + const sal_Int32 nIndex (nRow * mpImplementation->mnColumnCount + nColumn); OSL_ASSERT(nIndex>=0); - return ::std::min(nIndex, mnPageCount-1); + return ::std::min(nIndex, mpImplementation->mnPageCount-1); } @@ -377,7 +462,7 @@ sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) con bool Layouter::IsColumnCountFixed (void) const { - return mnMinimalColumnCount == mnMaximalColumnCount; + return mpImplementation->mnMinimalColumnCount == mpImplementation->mnMaximalColumnCount; } @@ -385,7 +470,7 @@ bool Layouter::IsColumnCountFixed (void) const Size Layouter::GetPageObjectSize (void) const { - return maPageObjectSize; + return mpImplementation->maPageObjectSize; } @@ -395,70 +480,15 @@ Rectangle Layouter::GetPageObjectBox ( const sal_Int32 nIndex, const bool bIncludeBorderAndGap) const { - const sal_Int32 nRow (GetRow(nIndex)); - const sal_Int32 nColumn (GetColumn(nIndex)); - Rectangle aBoundingBox( - Point (mnLeftBorder - + nColumn * maPageObjectSize.Width() - + (nColumn>0 ? nColumn : 0) * mnHorizontalGap, - mnTopBorder - + nRow * maPageObjectSize.Height() - + (nRow>0 ? nRow : 0) * mnVerticalGap), - maPageObjectSize); - if (bIncludeBorderAndGap) - { - if (nColumn == 0) - aBoundingBox.Left() = 0; - else - aBoundingBox.Left() -= mnHorizontalGap/2; - if (nColumn == mnColumnCount-1) - aBoundingBox.Right() += mnRightBorder; - else - aBoundingBox.Right() += mnHorizontalGap/2; - if (nRow == 0) - aBoundingBox.Top() = 0; - else - aBoundingBox.Top() -= mnVerticalGap/2; - if (nRow == mnRowCount-1) - aBoundingBox.Bottom() += mnBottomBorder; - else - aBoundingBox.Bottom() += mnVerticalGap/2; - } - return aBoundingBox; + return mpImplementation->GetPageObjectBox(nIndex, bIncludeBorderAndGap); } -Rectangle Layouter::GetPageBox (const sal_Int32 nObjectCount) const +Rectangle Layouter::GetTotalBoundingBox (void) const { - sal_Int32 nCount (nObjectCount); - if (nCount < 0) - nCount = mnPageCount; - - sal_Int32 nHorizontalSize = 0; - sal_Int32 nVerticalSize = 0; - if (mnColumnCount > 0) - { - sal_Int32 nRowCount = (nCount+mnColumnCount-1) / mnColumnCount; - nHorizontalSize = - mnLeftBorder - + mnRightBorder - + mnColumnCount * maPageObjectSize.Width(); - if (mnColumnCount > 1) - nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap; - nVerticalSize = - mnTopBorder - + mnBottomBorder - + nRowCount * maPageObjectSize.Height(); - if (nRowCount > 1) - nVerticalSize += (nRowCount-1) * mnVerticalGap; - } - - return Rectangle ( - Point(0,0), - Size (nHorizontalSize, nVerticalSize) - ); + return mpImplementation->GetTotalBoundingBox(); } @@ -470,59 +500,353 @@ InsertPosition Layouter::GetInsertPosition ( model::SlideSorterModel& rModel) const { InsertPosition aPosition; - CalculateLogicalInsertPosition(rModelPosition, aPosition); - CalculateGeometricPosition(aPosition, rIndicatorSize, GetColumnCount()==1, rModel); + mpImplementation->CalculateLogicalInsertPosition( + rModelPosition, + aPosition); + mpImplementation->CalculateGeometricPosition( + aPosition, + rIndicatorSize, + GetColumnCount()==1, + rModel); return aPosition; } -void Layouter::CalculateLogicalInsertPosition ( - const Point& rModelPosition, - InsertPosition& rPosition) const +Range Layouter::GetValidHorizontalSizeRange (void) const { - // Determine logical position. - if (mnColumnCount == 1) + return mpImplementation->GetValidHorizontalSizeRange(); +} + + + + +Range Layouter::GetValidVerticalSizeRange (void) const +{ + return mpImplementation->GetValidVerticalSizeRange(); +} + + + + +Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const +{ + const sal_Int32 nRow0 (mpImplementation->GetRowAtPosition ( + aVisibleArea.Top(), + true, + Implementation::GM_BOTH)); + const sal_Int32 nRow1 (mpImplementation->GetRowAtPosition ( + aVisibleArea.Bottom(), + true, + Implementation::GM_BOTH)); + return Range( + ::std::min(nRow0*mpImplementation->mnColumnCount, mpImplementation->mnPageCount-1), + ::std::min((nRow1+1)*mpImplementation->mnColumnCount-1, mpImplementation->mnPageCount-1)); +} + + + + +sal_Int32 Layouter::GetIndexAtPoint ( + const Point& rPosition, + const bool bIncludePageBorders) const +{ + const sal_Int32 nRow ( + mpImplementation->GetRowAtPosition ( + rPosition.Y(), + bIncludePageBorders, + bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE)); + const sal_Int32 nColumn ( + mpImplementation->GetColumnAtPosition ( + rPosition.X(), + bIncludePageBorders, + bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE)); + + if (nRow >= 0 && nColumn >= 0) + return nRow * mpImplementation->mnColumnCount + nColumn; + else + return -1; +} + + + + +//===== Layouter::Implementation ============================================== + +Layouter::Implementation* Layouter::Implementation::Create ( + const Implementation& rImplementation, + const Layouter::Orientation eOrientation) +{ + switch (eOrientation) + { + case HORIZONTAL: return new HorizontalImplementation(rImplementation); + case VERTICAL: return new VerticalImplementation(rImplementation); + case GRID: + default: return new GridImplementation(rImplementation); + } +} + + + + +Layouter::Implementation::Implementation (const SharedSdWindow& rpWindow) + : mpWindow(rpWindow), + mnRequestedLeftBorder(5), + mnRequestedRightBorder(5), + mnRequestedTopBorder(5), + mnRequestedBottomBorder(5), + mnLeftBorder(5), + mnRightBorder(5), + mnTopBorder(5), + mnBottomBorder(5), + mnVerticalGap (10), + mnHorizontalGap(10), + maMinimalSize(100,75), + maPreferredSize(200,150), + maMaximalSize(300,200), + mnMinimalColumnCount(1), + mnMaximalColumnCount(15), + mnPageCount(0), + mnColumnCount(1), + mnRowCount(0), + mnMaxColumnCount(0), + mnMaxRowCount(0), + maPageObjectSize(1,1) +{ +} + + + + +Layouter::Implementation::Implementation (const Implementation& rImplementation) + : mpWindow(rImplementation.mpWindow), + mnRequestedLeftBorder(rImplementation.mnRequestedLeftBorder), + mnRequestedRightBorder(rImplementation.mnRequestedRightBorder), + mnRequestedTopBorder(rImplementation.mnRequestedTopBorder), + mnRequestedBottomBorder(rImplementation.mnRequestedBottomBorder), + mnLeftBorder(rImplementation.mnLeftBorder), + mnRightBorder(rImplementation.mnRightBorder), + mnTopBorder(rImplementation.mnTopBorder), + mnBottomBorder(rImplementation.mnBottomBorder), + mnVerticalGap(rImplementation.mnVerticalGap), + mnHorizontalGap(rImplementation.mnHorizontalGap), + maMinimalSize(rImplementation.maMinimalSize), + maPreferredSize(rImplementation.maPreferredSize), + maMaximalSize(rImplementation.maMaximalSize), + mnMinimalColumnCount(rImplementation.mnMinimalColumnCount), + mnMaximalColumnCount(rImplementation.mnMaximalColumnCount), + mnPageCount(rImplementation.mnPageCount), + mnColumnCount(rImplementation.mnColumnCount), + mnRowCount(rImplementation.mnRowCount), + mnMaxColumnCount(rImplementation.mnMaxColumnCount), + mnMaxRowCount(rImplementation.mnMaxRowCount), + maPageObjectSize(rImplementation.maPageObjectSize) +{ +} + + + + +Layouter::Implementation::~Implementation (void) +{ +} + + + + +bool Layouter::Implementation::Rearrange ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const sal_uInt32 nPageCount) +{ + mnPageCount = nPageCount; + + if (rWindowSize.Width()<=0 || rWindowSize.Height()<=0) + return false; + if (rPreviewModelSize.Width()<=0 || rPreviewModelSize.Height()<=0) + return false; + + CalculateRowAndColumnCount(rWindowSize); + + // Update the border values. + mnLeftBorder = mnRequestedLeftBorder; + mnTopBorder = mnRequestedTopBorder; + mnRightBorder = mnRequestedRightBorder; + mnBottomBorder = mnRequestedBottomBorder; + if (mnColumnCount > 1) { - const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; - const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); - rPosition.mnRow = ::std::min(mnPageCount, nY / nRowHeight); - rPosition.mnColumn = 0; - rPosition.mnIndex = rPosition.mnRow; - rPosition.mbIsAtRunStart = (rPosition.mnRow == 0); - rPosition.mbIsAtRunEnd = (rPosition.mnRow == mnRowCount); - rPosition.mbIsExtraSpaceNeeded = (rPosition.mnRow >= mnMaxRowCount); + int nMinimumBorderWidth = mnHorizontalGap/2; + if (mnLeftBorder < nMinimumBorderWidth) + mnLeftBorder = nMinimumBorderWidth; + if (mnRightBorder < nMinimumBorderWidth) + mnRightBorder = nMinimumBorderWidth; } else { - rPosition.mnRow = ::std::min( - mnRowCount-1, - GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH)); + int nMinimumBorderHeight = mnVerticalGap/2; + if (mnTopBorder < nMinimumBorderHeight) + mnTopBorder = nMinimumBorderHeight; + if (mnBottomBorder < nMinimumBorderHeight) + mnBottomBorder = nMinimumBorderHeight; + } - const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; - const sal_Int32 nRowWidth (maPageObjectSize.Width() + mnHorizontalGap); - rPosition.mnColumn = ::std::min(mnColumnCount, nX / nRowWidth); - rPosition.mnIndex = rPosition.mnRow * mnColumnCount + rPosition.mnColumn; + mpPageObjectLayouter.reset( + new PageObjectLayouter( + CalculateTargetSize(rWindowSize, rPreviewModelSize), + rPreviewModelSize, + mpWindow, + mnPageCount)); + maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); + + CalculateMaxRowAndColumnCount(rWindowSize); + + return true; +} - rPosition.mbIsAtRunStart = (rPosition.mnColumn == 0); - rPosition.mbIsAtRunEnd = (rPosition.mnColumn == mnColumnCount); - if (rPosition.mnIndex >= mnPageCount) + + +sal_Int32 Layouter::Implementation::GetRowAtPosition ( + sal_Int32 nYPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership) const +{ + sal_Int32 nRow = -1; + + const sal_Int32 nY = nYPosition - mnTopBorder; + if (nY >= 0) + { + // Vertical distance from one row to the next. + const sal_Int32 nRowOffset (maPageObjectSize.Height() + mnVerticalGap); + + // Calculate row consisting of page objects and gap below. + nRow = nY / nRowOffset; + + const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height()); + // When inside the gap below then nYPosition is not over a page + // object. + if (nDistanceIntoGap > 0) + nRow = ResolvePositionInGap ( + nDistanceIntoGap, + eGapMembership, + nRow, + mnVerticalGap); + } + else if (bIncludeBordersAndGaps) + { + // We are in the top border area. Set nRow to the first row when + // the top border shall be considered to belong to the first row. + nRow = 0; + } + + return nRow; +} + + + + +sal_Int32 Layouter::Implementation::GetColumnAtPosition ( + sal_Int32 nXPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership) const +{ + sal_Int32 nColumn = -1; + + sal_Int32 nX = nXPosition - mnLeftBorder; + if (nX >= 0) + { + // Horizontal distance from one column to the next. + const sal_Int32 nColumnOffset (maPageObjectSize.Width() + mnHorizontalGap); + + // Calculate row consisting of page objects and gap below. + nColumn = nX / nColumnOffset; + if (nColumn < 0) + nColumn = 0; + else if (nColumn >= mnColumnCount) + nColumn = mnColumnCount-1; + + const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width()); + // When inside the gap at the right then nXPosition is not over a + // page object. + if (nDistanceIntoGap > 0) + nColumn = ResolvePositionInGap ( + nDistanceIntoGap, + eGapMembership, + nColumn, + mnHorizontalGap); + } + else if (bIncludeBordersAndGaps) + { + // We are in the left border area. Set nColumn to the first column + // when the left border shall be considered to belong to the first + // column. + nColumn = 0; + } + return nColumn; +} + + + + +sal_Int32 Layouter::Implementation::ResolvePositionInGap ( + sal_Int32 nDistanceIntoGap, + GapMembership eGapMembership, + sal_Int32 nIndex, + sal_Int32 nGap) const +{ + switch (eGapMembership) + { + case GM_NONE: + // The gap is no man's land. + nIndex = -1; + break; + + case GM_BOTH: { - rPosition.mnIndex = mnPageCount; - rPosition.mnRow = mnRowCount-1; - rPosition.mnColumn = mnPageCount%mnColumnCount; - rPosition.mbIsAtRunEnd = true; + // The lower half of the gap belongs to the next row or column. + sal_Int32 nFirstHalfGapWidth = nGap / 2; + if (nDistanceIntoGap > nFirstHalfGapWidth) + nIndex ++; + break; } - rPosition.mbIsExtraSpaceNeeded = (rPosition.mnColumn >= mnMaxColumnCount); + + case GM_PREVIOUS: + // Row or column already at correct value. + break; + + case GM_NEXT: + // The complete gap belongs to the next row or column. + nIndex ++; + break; + + case GM_PAGE_BORDER: + if (nDistanceIntoGap > 0) + { + if (nDistanceIntoGap > nGap) + { + // Inside the border of the next row or column. + nIndex ++; + } + else + { + // Inside the gap between the page borders. + nIndex = -1; + } + } + break; + + default: + nIndex = -1; } + + return nIndex; } -void Layouter::CalculateGeometricPosition ( +void Layouter::Implementation::CalculateGeometricPosition ( InsertPosition& rPosition, const Size& rIndicatorSize, const bool bIsVertical, @@ -535,12 +859,13 @@ void Layouter::CalculateGeometricPosition ( bool bIsLeadingFixed (false); bool bIsTrailingFixed (false); sal_Int32 nSecondaryLocation (0); + const sal_Int32 nIndex (rPosition.GetIndex()); - if (rPosition.mbIsAtRunStart) + if (rPosition.IsAtRunStart()) { // Place indicator at the top of the column. - const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex)); - const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex)); + const Rectangle aOuterBox (GetPageObjectBox(nIndex)); + const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex)); if (bIsVertical) { nLeadingLocation = aOuterBox.Top(); @@ -555,12 +880,12 @@ void Layouter::CalculateGeometricPosition ( } bIsLeadingFixed = true; } - else if (rPosition.mbIsAtRunEnd) + else if (rPosition.IsAtRunEnd()) { // Place indicator at the bottom/right of the column/row. - const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex-1)); - const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex-1)); + const Rectangle aOuterBox (GetPageObjectBox(nIndex-1)); + const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex-1)); if (bIsVertical) { nLeadingLocation = aInnerBox.Bottom(); @@ -574,14 +899,14 @@ void Layouter::CalculateGeometricPosition ( nSecondaryLocation = aInnerBox.Center().Y(); } bIsTrailingFixed = true; - if ( ! rPosition.mbIsExtraSpaceNeeded) + if ( ! rPosition.IsExtraSpaceNeeded()) bIsLeadingFixed = true; } else { // Place indicator between two rows/columns. - const Rectangle aBox1 (GetInnerBoundingBox(rModel, rPosition.mnIndex-1)); - const Rectangle aBox2 (GetInnerBoundingBox(rModel, rPosition.mnIndex)); + const Rectangle aBox1 (GetInnerBoundingBox(rModel, nIndex-1)); + const Rectangle aBox2 (GetInnerBoundingBox(rModel, nIndex)); if (bIsVertical) { nLeadingLocation = aBox1.Bottom(); @@ -624,22 +949,24 @@ void Layouter::CalculateGeometricPosition ( if (bIsVertical) { - rPosition.maLocation = Point(nSecondaryLocation, nPrimaryLocation); - rPosition.maLeadingOffset = Point(0, nLeadingOffset); - rPosition.maTrailingOffset = Point(0, nTrailingOffset); + rPosition.SetGeometricalPosition( + Point(nSecondaryLocation, nPrimaryLocation), + Point(0, nLeadingOffset), + Point(0, nTrailingOffset)); } else { - rPosition.maLocation = Point(nPrimaryLocation, nSecondaryLocation); - rPosition.maLeadingOffset = Point(nLeadingOffset, 0); - rPosition.maTrailingOffset = Point(nTrailingOffset, 0); + rPosition.SetGeometricalPosition( + Point(nPrimaryLocation, nSecondaryLocation), + Point(nLeadingOffset, 0), + Point(nTrailingOffset, 0)); } } -Rectangle Layouter::GetInnerBoundingBox ( +Rectangle Layouter::Implementation::GetInnerBoundingBox ( model::SlideSorterModel& rModel, const sal_Int32 nIndex) const { @@ -649,12 +976,12 @@ Rectangle Layouter::GetInnerBoundingBox ( const Point aLocation (pDescriptor->GetLocation(true)); if (pDescriptor->HasState(model::PageDescriptor::ST_Selected)) - return GetPageObjectLayouter()->GetBoundingBox( + return mpPageObjectLayouter->GetBoundingBox( aLocation, PageObjectLayouter::PageObject, PageObjectLayouter::ModelCoordinateSystem); else - return GetPageObjectLayouter()->GetBoundingBox( + return mpPageObjectLayouter->GetBoundingBox( aLocation, PageObjectLayouter::Preview, PageObjectLayouter::ModelCoordinateSystem); @@ -663,181 +990,436 @@ Rectangle Layouter::GetInnerBoundingBox ( -Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const +Range Layouter::Implementation::GetValidHorizontalSizeRange (void) const { - sal_Int32 nRow0 = GetRowAtPosition (aVisibleArea.Top(), true, GM_BOTH); - sal_Int32 nRow1 = GetRowAtPosition (aVisibleArea.Bottom(), - true, GM_BOTH); return Range( - ::std::min(nRow0 * mnColumnCount, mnPageCount-1), - ::std::min((nRow1+1) * mnColumnCount - 1, mnPageCount-1)); + mnLeftBorder + maMinimalSize.Width() + mnRightBorder, + mnLeftBorder + maMaximalSize.Width() + mnRightBorder); } -sal_Int32 Layouter::GetIndexAtPoint ( - const Point& rPosition, - const bool bIncludePageBorders) const +Range Layouter::Implementation::GetValidVerticalSizeRange (void) const { - sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), - bIncludePageBorders, - bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE); - sal_Int32 nColumn = GetColumnAtPosition (rPosition.X(), - bIncludePageBorders, - bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE); + return Range( + mnTopBorder + maMinimalSize.Height() + mnBottomBorder, + mnTopBorder + maMaximalSize.Height() + mnBottomBorder); +} - if (nRow >= 0 && nColumn >= 0) - return nRow * mnColumnCount + nColumn; + + + +Size Layouter::Implementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const bool bCalculateWidth, + const bool bCalculateHeight) const +{ + if (mnColumnCount<=0 || mnRowCount<=0) + return maPreferredSize; + if ( ! (bCalculateWidth || bCalculateHeight)) + { + OSL_ASSERT(bCalculateWidth || bCalculateHeight); + return maPreferredSize; + } + + const double nPreviewAspectRatio ( + double(rPreviewModelSize.Width())/double(rPreviewModelSize.Height())); + + // Calculate the width of each page object. + Size aTargetSize (0,0); + if (bCalculateWidth) + aTargetSize.setWidth( + (rWindowSize.Width() - mnLeftBorder - mnRightBorder + - (mnColumnCount-1) * mnHorizontalGap) + / mnColumnCount); + else if (bCalculateHeight) + aTargetSize.setHeight( + (rWindowSize.Height() - mnTopBorder - mnBottomBorder + - (mnRowCount-1) * mnVerticalGap) + / mnRowCount); + + if (bCalculateWidth) + { + if (aTargetSize.Width() < maMinimalSize.Width()) + aTargetSize.setWidth(maMinimalSize.Width()); + else if (aTargetSize.Width() > maMaximalSize.Width()) + aTargetSize.setWidth(maMaximalSize.Width()); + } + else if (bCalculateHeight) + { + if (aTargetSize.Height() < maMinimalSize.Height()) + aTargetSize.setHeight(maMinimalSize.Height()); + else if (aTargetSize.Height() > maMaximalSize.Height()) + aTargetSize.setHeight(maMaximalSize.Height()); + } + + return aTargetSize; +} + + + + +Rectangle Layouter::Implementation::GetPageObjectBox ( + const sal_Int32 nIndex, + const bool bIncludeBorderAndGap) const +{ + const sal_Int32 nRow (nIndex / mnColumnCount); + const sal_Int32 nColumn (nIndex % mnColumnCount); + + const Rectangle aBoundingBox (GetPageObjectBox(nRow,nColumn)); + if (bIncludeBorderAndGap) + return AddBorderAndGap(aBoundingBox, nRow, nColumn); else - return -1; + return aBoundingBox; } -bool Layouter::IsVertical (void) const +Rectangle Layouter::Implementation::GetPageObjectBox ( + const sal_Int32 nRow, + const sal_Int32 nColumn) const { - return mbIsVertical; + return Rectangle( + Point (mnLeftBorder + + nColumn * maPageObjectSize.Width() + + (nColumn>0 ? nColumn : 0) * mnHorizontalGap, + mnTopBorder + + nRow * maPageObjectSize.Height() + + (nRow>0 ? nRow : 0) * mnVerticalGap), + maPageObjectSize); } -sal_Int32 Layouter::GetRowAtPosition ( - sal_Int32 nYPosition, - bool bIncludeBordersAndGaps, - GapMembership eGapMembership) const + +Rectangle Layouter::Implementation::AddBorderAndGap ( + const Rectangle& rBoundingBox, + const sal_Int32 nRow, + const sal_Int32 nColumn) const { - sal_Int32 nRow = -1; + Rectangle aBoundingBox (rBoundingBox); - const sal_Int32 nY = nYPosition - mnTopBorder; - if (nY >= 0) - { - // Vertical distance from one row to the next. - const sal_Int32 nRowOffset (maPageObjectSize.Height() + mnVerticalGap); + if (nColumn == 0) + aBoundingBox.Left() = 0; + else + aBoundingBox.Left() -= mnHorizontalGap/2; + if (nColumn == mnColumnCount-1) + aBoundingBox.Right() += mnRightBorder; + else + aBoundingBox.Right() += mnHorizontalGap/2; + if (nRow == 0) + aBoundingBox.Top() = 0; + else + aBoundingBox.Top() -= mnVerticalGap/2; + if (nRow == mnRowCount-1) + aBoundingBox.Bottom() += mnBottomBorder; + else + aBoundingBox.Bottom() += mnVerticalGap/2; + return aBoundingBox; +} - // Calculate row consisting of page objects and gap below. - nRow = nY / nRowOffset; - const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height()); - // When inside the gap below then nYPosition is not over a page - // object. - if (nDistanceIntoGap > 0) - nRow = ResolvePositionInGap ( - nDistanceIntoGap, - eGapMembership, - nRow, - mnVerticalGap); - } - else if (bIncludeBordersAndGaps) + + +Rectangle Layouter::Implementation::GetTotalBoundingBox (void) const +{ + sal_Int32 nHorizontalSize = 0; + sal_Int32 nVerticalSize = 0; + if (mnColumnCount > 0) { - // We are in the top border area. Set nRow to the first row when - // the top border shall be considered to belong to the first row. - nRow = 0; + sal_Int32 nRowCount = (mnPageCount+mnColumnCount-1) / mnColumnCount; + nHorizontalSize = + mnLeftBorder + + mnRightBorder + + mnColumnCount * maPageObjectSize.Width(); + if (mnColumnCount > 1) + nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap; + nVerticalSize = + mnTopBorder + + mnBottomBorder + + nRowCount * maPageObjectSize.Height(); + if (nRowCount > 1) + nVerticalSize += (nRowCount-1) * mnVerticalGap; } - return nRow; + return Rectangle ( + Point(0,0), + Size (nHorizontalSize, nVerticalSize) + ); } -sal_Int32 Layouter::GetColumnAtPosition ( - sal_Int32 nXPosition, - bool bIncludeBordersAndGaps, - GapMembership eGapMembership) const +void Layouter::Implementation::CalculateVerticalLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const { - sal_Int32 nColumn = -1; + const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; + const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); + const sal_Int32 nRow (::std::min(mnPageCount, nY / nRowHeight)); + rPosition.SetLogicalPosition ( + nRow, + 0, + nRow, + (nRow == 0), + (nRow == mnRowCount), + (nRow >= mnMaxRowCount)); +} - sal_Int32 nX = nXPosition - mnLeftBorder; - if (nX >= 0) - { - // Horizontal distance from one column to the next. - const sal_Int32 nColumnOffset (maPageObjectSize.Width() + mnHorizontalGap); - // Calculate row consisting of page objects and gap below. - nColumn = nX / nColumnOffset; - if (nColumn < 0) - nColumn = 0; - else if (nColumn >= mnColumnCount) - nColumn = mnColumnCount-1; - const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width()); - // When inside the gap at the right then nXPosition is not over a - // page object. - if (nDistanceIntoGap > 0) - nColumn = ResolvePositionInGap ( - nDistanceIntoGap, - eGapMembership, - nColumn, - mnHorizontalGap); - } - else if (bIncludeBordersAndGaps) - { - // We are in the left border area. Set nColumn to the first column - // when the left border shall be considered to belong to the first - // column. - nColumn = 0; - } - return nColumn; + +//===== HorizontalImplementation ================================================ + +HorizontalImplementation::HorizontalImplementation (const SharedSdWindow& rpWindow) + : Implementation(rpWindow) +{ } -sal_Int32 Layouter::ResolvePositionInGap ( - sal_Int32 nDistanceIntoGap, - GapMembership eGapMembership, - sal_Int32 nIndex, - sal_Int32 nGap) const +HorizontalImplementation::HorizontalImplementation (const Implementation& rImplementation) + : Implementation(rImplementation) { - switch (eGapMembership) - { - case GM_NONE: - // The gap is no man's land. - nIndex = -1; - break; +} - case GM_BOTH: - { - // The lower half of the gap belongs to the next row or column. - sal_Int32 nFirstHalfGapWidth = nGap / 2; - if (nDistanceIntoGap > nFirstHalfGapWidth) - nIndex ++; - break; - } - case GM_PREVIOUS: - // Row or column already at correct value. - break; - case GM_NEXT: - // The complete gap belongs to the next row or column. - nIndex ++; - break; - case GM_PAGE_BORDER: - if (nDistanceIntoGap > 0) - { - if (nDistanceIntoGap > nGap) - { - // Inside the border of the next row or column. - nIndex ++; - } - else - { - // Inside the gap between the page borders. - nIndex = -1; - } - } - break; +Layouter::Orientation HorizontalImplementation::GetOrientation (void) const +{ + return Layouter::HORIZONTAL; +} - default: - nIndex = -1; + + + +void HorizontalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) +{ + (void)rWindowSize; + + // Row and column count are fixed (for a given page count.) + mnColumnCount = mnPageCount; + mnRowCount = 1; +} + + + + +void HorizontalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) +{ + mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) + / (maPageObjectSize.Width() + mnHorizontalGap); + mnMaxRowCount = 1; +} + + + + +Size HorizontalImplementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const +{ + return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, false, true); +} + + + + +void HorizontalImplementation::CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const +{ + const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; + const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap); + const sal_Int32 nColumn (::std::min(mnPageCount, nX / nColumnWidth)); + rPosition.SetLogicalPosition ( + 0, + nColumn, + nColumn, + (nColumn == 0), + (nColumn == mnColumnCount), + (nColumn >= mnMaxColumnCount)); +} + + + + +//===== VerticalImplementation ================================================ + +VerticalImplementation::VerticalImplementation (const SharedSdWindow& rpWindow) + : Implementation(rpWindow) +{ +} + + + + +VerticalImplementation::VerticalImplementation (const Implementation& rImplementation) + : Implementation(rImplementation) +{ +} + + + + +Layouter::Orientation VerticalImplementation::GetOrientation (void) const +{ + return Layouter::VERTICAL; +} + + + + +void VerticalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) +{ + (void)rWindowSize; + + // Row and column count are fixed (for a given page count.) + mnRowCount = mnPageCount; + mnColumnCount = 1; + +} + + + + +void VerticalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) +{ + mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) + / (maPageObjectSize.Height() + mnVerticalGap); + mnMaxColumnCount = 1; +} + + + + +Size VerticalImplementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const +{ + return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, true, false); +} + + + + +void VerticalImplementation::CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const +{ + return CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition); +} + + + + +//===== GridImplementation ================================================ + +GridImplementation::GridImplementation (const SharedSdWindow& rpWindow) + : Implementation(rpWindow) +{ +} + + + + +GridImplementation::GridImplementation (const Implementation& rImplementation) + : Implementation(rImplementation) +{ +} + + + + +Layouter::Orientation GridImplementation::GetOrientation (void) const +{ + return Layouter::GRID; +} + + + + +void GridImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) +{ + // Calculate the column count. + mnColumnCount + = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder) + / (maPreferredSize.Width() + mnHorizontalGap); + if (mnColumnCount < mnMinimalColumnCount) + mnColumnCount = mnMinimalColumnCount; + if (mnColumnCount > mnMaximalColumnCount) + mnColumnCount = mnMaximalColumnCount; + mnRowCount = (mnPageCount + mnColumnCount-1)/mnColumnCount; +} + + + + +void GridImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) +{ + mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) + / (maPageObjectSize.Width() + mnHorizontalGap); + mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) + / (maPageObjectSize.Height() + mnVerticalGap); +} + + + + + +Size GridImplementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const +{ + return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, true, true); +} + + + + +void GridImplementation::CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const +{ + if (mnColumnCount == 1) + { + CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition); } + else + { + // Handle the general case of more than one column. + sal_Int32 nRow (::std::min( + mnRowCount-1, + GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH))); + const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; + const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap); + sal_Int32 nColumn (::std::min(mnColumnCount, nX / nColumnWidth)); + sal_Int32 nIndex (nRow * mnColumnCount + nColumn); + bool bIsAtRunEnd (nColumn == mnColumnCount); - return nIndex; + if (nIndex >= mnPageCount) + { + nIndex = mnPageCount; + nRow = mnRowCount-1; + nColumn = mnPageCount%mnColumnCount; + bIsAtRunEnd = true; + } + + rPosition.SetLogicalPosition ( + nRow, + nColumn, + nIndex, + (nColumn == 0), + bIsAtRunEnd, + (nColumn >= mnMaxColumnCount)); + } } @@ -849,12 +1431,12 @@ InsertPosition::InsertPosition (void) : mnRow(-1), mnColumn(-1), mnIndex(-1), - maLocation(0,0), - maLeadingOffset(0,0), - maTrailingOffset(0,0), mbIsAtRunStart(false), mbIsAtRunEnd(false), - mbIsExtraSpaceNeeded(false) + mbIsExtraSpaceNeeded(false), + maLocation(0,0), + maLeadingOffset(0,0), + maTrailingOffset(0,0) { } @@ -868,12 +1450,12 @@ InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition mnRow = rInsertPosition.mnRow; mnColumn = rInsertPosition.mnColumn; mnIndex = rInsertPosition.mnIndex; - maLocation = rInsertPosition.maLocation; - maLeadingOffset = rInsertPosition.maLeadingOffset; - maTrailingOffset = rInsertPosition.maTrailingOffset; mbIsAtRunStart = rInsertPosition.mbIsAtRunStart; mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd; mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded; + maLocation = rInsertPosition.maLocation; + maLeadingOffset = rInsertPosition.maLeadingOffset; + maTrailingOffset = rInsertPosition.maTrailingOffset; } return *this; } @@ -902,4 +1484,36 @@ bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const + +void InsertPosition::SetLogicalPosition ( + const sal_Int32 nRow, + const sal_Int32 nColumn, + const sal_Int32 nIndex, + const bool bIsAtRunStart, + const bool bIsAtRunEnd, + const bool bIsExtraSpaceNeeded) +{ + mnRow = nRow; + mnColumn = nColumn; + mnIndex = nIndex; + mbIsAtRunStart = bIsAtRunStart; + mbIsAtRunEnd = bIsAtRunEnd; + mbIsExtraSpaceNeeded = bIsExtraSpaceNeeded; +} + + + + +void InsertPosition::SetGeometricalPosition( + const Point aLocation, + const Point aLeadingOffset, + const Point aTrailingOffset) +{ + maLocation = aLocation; + maLeadingOffset = aLeadingOffset; + maTrailingOffset = aTrailingOffset; +} + + + } } } // end of namespace ::sd::slidesorter::namespace diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 19f7bc14b664..ec0b274397b7 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -59,7 +59,6 @@ #include <vcl/vclenum.hxx> #include <vcl/bmpacc.hxx> #include <vcl/virdev.hxx> -#include <canvas/elapsedtime.hxx> using namespace ::drawinglayer::primitive2d; using namespace ::basegfx; @@ -209,10 +208,14 @@ void PageObjectPainter::PaintPageObject ( void PageObjectPainter::NotifyResize (void) { - maNormalBackground.SetEmpty(); - maSelectionBackground.SetEmpty(); - maFocusedSelectionBackground.SetEmpty(); - maMouseOverBackground.SetEmpty(); + if ( ! mpPageObjectLayouter + || mpPageObjectLayouter->GetPageObjectSize() != maNewSlideIcon.GetSizePixel()) + { + maNormalBackground.SetEmpty(); + maSelectionBackground.SetEmpty(); + maFocusedSelectionBackground.SetEmpty(); + maMouseOverBackground.SetEmpty(); + } } @@ -270,7 +273,7 @@ void PageObjectPainter::PaintPreview ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const { - Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::Preview, PageObjectLayouter::ModelCoordinateSystem)); @@ -278,12 +281,17 @@ void PageObjectPainter::PaintPreview ( if (mpCache != NULL) { const SdrPage* pPage = rpDescriptor->GetPage(); - BitmapEx aBitmap (mpCache->GetPreviewBitmap(pPage)); - if (aBitmap.GetSizePixel() != aBox.GetSize()) - aBitmap.Scale(aBox.GetSize()); mpCache->SetPreciousFlag(pPage, true); - rDevice.DrawBitmapEx(aBox.TopLeft(), aBitmap); + const Bitmap aBitmap (mpCache->GetPreviewBitmap(pPage,false).GetBitmap()); + if (aBitmap.GetSizePixel() != aBox.GetSize()) + { + rDevice.DrawBitmap(aBox.TopLeft(), aBox.GetSize(), aBitmap); + } + else + { + rDevice.DrawBitmap(aBox.TopLeft(), aBitmap); + } } if (rpDescriptor->GetVisualState().GetCurrentVisualState() |