diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 30513d6dc19c..c32e814f8768 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -46,12 +46,12 @@ #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsSelectionManager.hxx" #include "controller/SlsSlotManager.hxx" +#include "controller/SlsTransferable.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" -#include "view/SlsViewOverlay.hxx" #include "view/SlsFontProvider.hxx" #include "view/SlsPageObjectLayouter.hxx" #include "view/SlsPageObjectPainter.hxx" @@ -209,6 +209,7 @@ SlideSorterController::~SlideSorterController (void) void SlideSorterController::Dispose (void) { mpInsertionIndicatorHandler->End(); + mpSelectionManager.reset(); mpAnimator->Dispose(); } @@ -439,11 +440,12 @@ bool SlideSorterController::Command ( // When there is no selection, then we show the insertion // indicator so that the user knows where a page insertion // would take place. - GetInsertionIndicatorHandler()->Start( + GetInsertionIndicatorHandler()->Start(false); + GetInsertionIndicatorHandler()->UpdatePosition( pWindow->PixelToLogic(rEvent.GetMousePosPixel()), - InsertionIndicatorHandler::MoveMode, - false); - GetInsertionIndicatorHandler()->UpdateIndicatorIcon(); + InsertionIndicatorHandler::MoveMode); + GetInsertionIndicatorHandler()->UpdateIndicatorIcon( + dynamic_cast(SD_MOD()->pTransferClip)); } pWindow->ReleaseMouse(); @@ -786,6 +788,9 @@ Rectangle SlideSorterController::Rearrange (bool bForce) { Rectangle aNewContentArea (maTotalWindowArea); + if (aNewContentArea.IsEmpty()) + return aNewContentArea; + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { @@ -812,6 +817,9 @@ Rectangle SlideSorterController::Rearrange (bool bForce) // Adapt the scroll bars to the new zoom factor of the browser // window and the arrangement of the page objects. GetScrollBarManager().UpdateScrollBars(false, !bForce); + + // When there is a selection then keep it in the visible area. + GetSelectionManager()->MakeSelectionVisible(); } return aNewContentArea; @@ -845,7 +853,7 @@ void SlideSorterController::SetZoom (long int nZoom) nZoom = 1; { - SlideSorterView::DrawLock aLock (mrView); + SlideSorterView::DrawLock aLock (mrSlideSorter); mrView.GetLayouter().SetZoom(nZoom/100.0); mrView.Layout(); GetScrollBarManager().UpdateScrollBars (false); diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index 052c154aa8b3..91c64a046cb5 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -212,6 +212,25 @@ void Animator::RemoveAnimation (const Animator::AnimationId nId) +void Animator::RemoveAllAnimations (void) +{ + ::std::for_each( + maAnimations.begin(), + maAnimations.end(), + ::boost::bind( + &Animation::Expire, + _1)); + maAnimations.clear(); + mnNextAnimationId = 0; + + // No more animations => we do not have to suppress painting + // anymore. + mpDrawLock.reset(); +} + + + + bool Animator::ProcessAnimations (const double nTime) { bool bExpired (false); diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 47bf42b826d0..453c1e69e81c 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -38,7 +38,6 @@ #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsViewOverlay.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsPageSelector.hxx" @@ -47,7 +46,8 @@ #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsFocusManager.hxx" #include "controller/SlsSelectionManager.hxx" -#include "SlsTransferable.hxx" +#include "controller/SlsTransferable.hxx" +#include "cache/SlsPageCache.hxx" #include "ViewShellBase.hxx" #include "DrawViewShell.hxx" @@ -363,21 +363,40 @@ void Clipboard::CreateSlideTransferable ( maPagesToRemove.push_back (pDescriptor->GetPage()); } + // Create a small set of representatives of the selection for which + // previews are included into the transferable so that an insertion + // indicator can be rendered. + aSelectedPages.Rewind(); + ::std::vector aRepresentatives; + aRepresentatives.reserve(3); + ::boost::shared_ptr pPreviewCache ( + mrSlideSorter.GetView().GetPreviewCache()); + while (aSelectedPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); + if ( ! pDescriptor || pDescriptor->GetPage()==NULL) + continue; + Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap()); + aRepresentatives.push_back(aPreview); + if (aRepresentatives.size() >= 3) + break; + } + if (aBookmarkList.Count() > 0) { mrSlideSorter.GetView().BrkAction(); SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument(); - ::boost::shared_ptr pSubstitutionHandler; + ::boost::shared_ptr pDragAndDropContext; ::rtl::Reference pSelectionFunction ( mrSlideSorter.GetController().GetCurrentSelectionFunction()); if (pSelectionFunction.is()) - pSubstitutionHandler = pSelectionFunction->GetSubstitutionHandler(); + pDragAndDropContext = pSelectionFunction->GetDragAndDropContext(); SdTransferable* pTransferable = new Transferable ( pDocument, NULL, FALSE, dynamic_cast(mrSlideSorter.GetViewShell()), - pSubstitutionHandler); + aRepresentatives); if (bDrag) SD_MOD()->pTransferDrag = pTransferable; @@ -540,11 +559,9 @@ sal_Int8 Clipboard::AcceptDrop ( // Show the insertion marker and the substitution for a drop. Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel); - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); mrController.GetInsertionIndicatorHandler()->UpdatePosition( aPosition, rEvent.maDragEvent.DropAction); - rOverlay.GetSubstitutionOverlay()->SetPosition(aPosition); // Scroll the window when the mouse reaches the window border. // mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel); @@ -629,7 +646,7 @@ sal_Int8 Clipboard::ExecuteDrop ( else { // Handle a general drop operation. - HandlePageDrop (*pDragTransferable); + HandlePageDrop(*pDragTransferable); nResult = rEvent.mnAction; } } diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx index ee79c5662219..72a380a02328 100644 --- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx @@ -51,8 +51,10 @@ using namespace ::com::sun::star::uno; using namespace ::sd::slidesorter::model; + namespace sd { namespace slidesorter { namespace controller { + CurrentSlideManager::CurrentSlideManager (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mnCurrentSlideIndex(-1), diff --git a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx similarity index 62% rename from sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx rename to sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx index bd2ec1434a29..8915addc5cba 100644 --- a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -6,9 +6,6 @@ * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: SlsSelectionFunction.cxx,v $ - * $Revision: 1.37 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -30,59 +27,98 @@ #include "precompiled_sd.hxx" -#include "SlsSubstitutionHandler.hxx" +#include "SlsDragAndDropContext.hxx" #include "SlideSorter.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsViewOverlay.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsProperties.hxx" #include "controller/SlsSelectionFunction.hxx" #include "controller/SlsSelectionManager.hxx" +#include "controller/SlsTransferable.hxx" +#include "DrawDocShell.hxx" +#include "DrawDoc.hxx" #include "app.hrc" #include #include namespace sd { namespace slidesorter { namespace controller { -SubstitutionHandler::SubstitutionHandler ( +DragAndDropContext::DragAndDropContext ( SlideSorter& rSlideSorter, - const model::SharedPageDescriptor& rpHitDescriptor, - const Point& rMouseModelPosition) + const Transferable* pTransferable) : mpTargetSlideSorter(&rSlideSorter), - mpHitDescriptor(rpHitDescriptor), mnInsertionIndex(-1) { + ::std::vector aPages; + // No Drag-and-Drop for master pages. if (rSlideSorter.GetModel().GetEditMode() != EM_PAGE) return; - view::ViewOverlay& rOverlay (rSlideSorter.GetView().GetOverlay()); + rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon( + dynamic_cast(SD_MOD()->pTransferDrag)); +} - if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible()) + + + +void DragAndDropContext::GetPagesFromBookmarks ( + ::std::vector& rPages, + sal_Int32& rnSelectionCount, + DrawDocShell* pDocShell, + const List& rBookmarks) const +{ + if (pDocShell == NULL) + return; + + const SdDrawDocument* pDocument = pDocShell->GetDoc(); + if (pDocument == NULL) + return; + + for (ULONG nIndex=0,nCount=rBookmarks.Count(); nIndexSetIsVisible(true); - rSlideSorter.GetController().GetInsertionIndicatorHandler()->Start( - rMouseModelPosition, - InsertionIndicatorHandler::MoveMode, - true); - rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon( - aSelectedPages); + const String sPageName (*static_cast(rBookmarks.GetObject(nIndex))); + BOOL bIsMasterPage (FALSE); + const USHORT nPageIndex (pDocument->GetPageByName(sPageName, bIsMasterPage)); + if (nPageIndex == SDRPAGE_NOTFOUND) + continue; + + const SdPage* pPage = dynamic_cast(pDocument->GetPage(nPageIndex)); + if (pPage != NULL) + rPages.push_back(pPage); + } + rnSelectionCount = rBookmarks.Count(); +} + + + + +void DragAndDropContext::GetPagesFromSelection ( + ::std::vector& rPages, + sal_Int32& rnSelectionCount, + model::PageEnumeration& rSelection) const +{ + // Show a new substitution for the selected page objects. + rnSelectionCount = 0; + + while (rSelection.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement()); + if (rPages.size() < 3) + rPages.push_back(pDescriptor->GetPage()); + ++rnSelectionCount; } } -SubstitutionHandler::~SubstitutionHandler (void) +DragAndDropContext::~DragAndDropContext (void) { if (mpTargetSlideSorter != NULL) mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll(); @@ -91,18 +127,14 @@ SubstitutionHandler::~SubstitutionHandler (void) if (mpTargetSlideSorter != NULL) { - view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - rOverlay.GetSubstitutionOverlay()->Clear(); mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); } - mpHitDescriptor.reset(); } -void SubstitutionHandler::Dispose (void) +void DragAndDropContext::Dispose (void) { mnInsertionIndex = -1; } @@ -110,7 +142,7 @@ void SubstitutionHandler::Dispose (void) -void SubstitutionHandler::UpdatePosition ( +void DragAndDropContext::UpdatePosition ( const Point& rMousePosition, const InsertionIndicatorHandler::Mode eMode, const bool bAllowAutoScroll) @@ -126,39 +158,28 @@ void SubstitutionHandler::UpdatePosition ( // constant while scrolling.) SharedSdWindow pWindow (mpTargetSlideSorter->GetContentWindow()); const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + ::boost::shared_ptr pInsertionIndicatorHandler ( + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()); if ( ! (bAllowAutoScroll && mpTargetSlideSorter->GetController().GetScrollBarManager().AutoScroll( - rMousePosition, - ::boost::bind( - &SubstitutionHandler::UpdatePosition, - this, - rMousePosition, - eMode, - false)))) + rMousePosition, + ::boost::bind( + &DragAndDropContext::UpdatePosition, this, rMousePosition, eMode, false)))) { - view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); - - // Move the existing substitution to the new position. - rOverlay.GetSubstitutionOverlay()->SetPosition(aMouseModelPosition); - - mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->UpdatePosition( - aMouseModelPosition, - eMode); + pInsertionIndicatorHandler->UpdatePosition(aMouseModelPosition, eMode); // Remember the new insertion index. - if (mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial(eMode)) + mnInsertionIndex = pInsertionIndicatorHandler->GetInsertionPageIndex(); + if (pInsertionIndicatorHandler->IsInsertionTrivial(mnInsertionIndex, eMode)) mnInsertionIndex = -1; - else - mnInsertionIndex = mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler() - ->GetInsertionPageIndex(); } } -void SubstitutionHandler::Process (void) +void DragAndDropContext::Process (void) { if (mpTargetSlideSorter == NULL) return; @@ -183,31 +204,21 @@ void SubstitutionHandler::Process (void) -void SubstitutionHandler::Show (void) +void DragAndDropContext::Show (void) { - if (mpTargetSlideSorter != NULL) - { - view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); - } } -void SubstitutionHandler::Hide (void) +void DragAndDropContext::Hide (void) { - if (mpTargetSlideSorter != NULL) - { - view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - } } -void SubstitutionHandler::SetTargetSlideSorter ( +void DragAndDropContext::SetTargetSlideSorter ( SlideSorter* pSlideSorter, const Point aMousePosition, const InsertionIndicatorHandler::Mode eMode, @@ -223,9 +234,11 @@ void SubstitutionHandler::SetTargetSlideSorter ( if (mpTargetSlideSorter != NULL) { mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start( - aMousePosition, - eMode, bIsOverSourceView); + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->UpdatePosition( + aMousePosition, + eMode); + } } diff --git a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx similarity index 76% rename from sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx rename to sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx index 56bcf08fd7db..a23071273202 100644 --- a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx @@ -6,9 +6,6 @@ * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: SlsSelectionFunction.cxx,v $ - * $Revision: 1.37 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -34,8 +31,9 @@ #include #include "model/SlsSharedPageDescriptor.hxx" -#include "view/SlsViewOverlay.hxx" #include "controller/SlsInsertionIndicatorHandler.hxx" +#include + namespace sd { namespace slidesorter { class SlideSorter; @@ -45,27 +43,27 @@ class SlideSorter; namespace sd { namespace slidesorter { namespace controller { +class Transferable; -/** A SubstitutionHandler object handles the display of a number of selected - slides at the mouse position and the insertion or (with or without - removing the pages at their original position) when the object is - destoyed. + +/** A DragAndDropContext object handles an active drag and drop operation. + When the mouse is moved from one slide sorter window to another the + target SlideSorter object is exchanged accordingly. */ -class SubstitutionHandler +class DragAndDropContext { public: - /** Create a substitution display of the currently selected pages and - use the given position as the anchor point. + /** Create a substitution display of the currently selected pages or, + when provided, the pages in the transferable. */ - SubstitutionHandler ( + DragAndDropContext ( SlideSorter& rSlideSorter, - const model::SharedPageDescriptor& rpHitDescriptor, - const Point& rMouseModelPosition); - ~SubstitutionHandler (void); + const Transferable* pTransferable); + ~DragAndDropContext (void); /** Call this method (for example as reaction to ESC key press) to avoid processing (ie moving or inserting) the substition when the called - SubstitutionHandler object is destroyed. + DragAndDropContext object is destroyed. */ void Dispose (void); @@ -91,6 +89,16 @@ private: model::SharedPageDescriptor mpHitDescriptor; sal_Int32 mnInsertionIndex; + void GetPagesFromBookmarks ( + ::std::vector& rPages, + sal_Int32& rnSelectionCount, + DrawDocShell* pDocShell, + const List& rBookmarks) const; + void GetPagesFromSelection ( + ::std::vector& rPages, + sal_Int32& rnSelectionCount, + model::PageEnumeration& rSelection) const; + /** Move the substitution display of the currently selected pages. */ void Process (void); diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 3421cb470e2f..65a3ee5b54b2 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -33,8 +33,8 @@ #include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsProperties.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsViewOverlay.hxx" #include "view/SlsLayouter.hxx" +#include "view/SlsInsertionIndicatorOverlay.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include @@ -49,10 +49,8 @@ namespace sd { namespace slidesorter { namespace controller { InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mpInsertAnimator(), - mpInsertionIndicatorOverlay( - mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()), - mnInsertionIndex(-1), - maVisualInsertionIndices(-1,-1), + mpInsertionIndicatorOverlay(new view::InsertionIndicatorOverlay(rSlideSorter)), + maInsertPosition(), meMode(MoveMode), mbIsActive(false), mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()), @@ -71,10 +69,7 @@ InsertionIndicatorHandler::~InsertionIndicatorHandler (void) -void InsertionIndicatorHandler::Start ( - const Point& rMouseModelPosition, - const Mode eMode, - const bool bIsOverSourceView) +void InsertionIndicatorHandler::Start (const bool bIsOverSourceView) { if (mbIsActive) { @@ -85,8 +80,6 @@ void InsertionIndicatorHandler::Start ( if (mbIsReadOnly) return; - SetPosition(rMouseModelPosition, eMode); - mbIsActive = true; mbIsOverSourceView = bIsOverSourceView; } @@ -94,19 +87,27 @@ void InsertionIndicatorHandler::Start ( -void InsertionIndicatorHandler::UpdateIndicatorIcon ( - model::PageEnumeration& rEnumeration) +void InsertionIndicatorHandler::End (void) { - mpInsertionIndicatorOverlay->Create(rEnumeration); - maIconSize = mpInsertionIndicatorOverlay->GetSize(); + if ( ! mbIsActive) + return; + + if (mbIsReadOnly) + return; + + GetInsertAnimator()->Reset(); + + mbIsActive = false; + mpInsertionIndicatorOverlay->Hide(); } -void InsertionIndicatorHandler::UpdateIndicatorIcon (void) +void InsertionIndicatorHandler::UpdateIndicatorIcon (const Transferable* pTransferable) { - mpInsertionIndicatorOverlay->Create(); + mpInsertionIndicatorOverlay->Create(pTransferable); + maIconSize = mpInsertionIndicatorOverlay->GetSize(); } @@ -152,24 +153,6 @@ void InsertionIndicatorHandler::UpdatePosition ( -void InsertionIndicatorHandler::End (void) -{ - if ( ! mbIsActive) - return; - - if (mbIsReadOnly) - return; - - GetInsertAnimator()->SetInsertPosition(-1, Pair(-1,-1), Size(0,0)); - - mbIsActive = false; - mpInsertionIndicatorOverlay->SetIsVisible(false); - GetInsertAnimator()->Reset(); -} - - - - bool InsertionIndicatorHandler::IsActive (void) const { return mbIsActive; @@ -183,7 +166,7 @@ sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const if (mbIsReadOnly) return -1; else - return mnInsertionIndex; + return maInsertPosition.GetIndex(); } @@ -197,54 +180,31 @@ void InsertionIndicatorHandler::SetPosition ( view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount()); - sal_Int32 nInsertionIndex (mnInsertionIndex); - Pair aVisualInsertionIndices (maVisualInsertionIndices); - if (rLayouter.GetColumnCount() == 1) - { - // Pages are placed in a single column. Insertion indicator is - // placed between rows. - nInsertionIndex = rLayouter.GetVerticalInsertionIndex(rPoint); - aVisualInsertionIndices = Pair(nInsertionIndex, -1); - } - else - { - // Pages are placed in a grid. Insertion indicator is placed - // between columns. - aVisualInsertionIndices = rLayouter.GetGridInsertionIndices(rPoint); - nInsertionIndex = aVisualInsertionIndices.A() * rLayouter.GetColumnCount() - + aVisualInsertionIndices.B(); - if (aVisualInsertionIndices.B() == rLayouter.GetColumnCount()) - --nInsertionIndex; - } + const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition( + rPoint, + maIconSize)); - if (mnInsertionIndex != nInsertionIndex - || maVisualInsertionIndices != aVisualInsertionIndices + if (maInsertPosition != aInsertPosition || meMode != eMode || ! mpInsertionIndicatorOverlay->IsVisible()) { - mnInsertionIndex = nInsertionIndex; - maVisualInsertionIndices = aVisualInsertionIndices; + maInsertPosition = aInsertPosition; meMode = eMode; - mbIsInsertionTrivial = IsInsertionTrivial(eMode); + mbIsInsertionTrivial = IsInsertionTrivial(maInsertPosition.GetIndex(), eMode); - const Point aIndicatorLocation ( - rLayouter.GetInsertionIndicatorLocation( - maVisualInsertionIndices, - maIconSize)); - mpInsertionIndicatorOverlay->SetLocation(aIndicatorLocation); - - if (mnInsertionIndex>=0 && ! mbIsInsertionTrivial) + if (maInsertPosition.GetIndex()>=0 && ! mbIsInsertionTrivial) { + mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation()); + GetInsertAnimator()->SetInsertPosition( - mnInsertionIndex, - maVisualInsertionIndices, + maInsertPosition, maIconSize); - mpInsertionIndicatorOverlay->SetIsVisible(true); + mpInsertionIndicatorOverlay->Show(); } else { GetInsertAnimator()->Reset(); - mpInsertionIndicatorOverlay->SetIsVisible(false); + mpInsertionIndicatorOverlay->Hide(); } } } @@ -262,7 +222,9 @@ void InsertionIndicatorHandler::SetPosition ( -bool InsertionIndicatorHandler::IsInsertionTrivial (const Mode eMode) const +bool InsertionIndicatorHandler::IsInsertionTrivial ( + const sal_Int32 nInsertionIndex, + const Mode eMode) const { if (eMode == CopyMode) return false; @@ -302,7 +264,7 @@ bool InsertionIndicatorHandler::IsInsertionTrivial (const Mode eMode) const // to check that the insertion position is not directly in front or // directly behind the selection and thus moving the selection there // would not change the model. - if (mnInsertionIndex(nLastIndex+1)) + if (nInsertionIndex(nLastIndex+1)) return false; return true; diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index d1f70d633d2a..d51693067f0e 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -38,7 +38,6 @@ #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" -#include "view/SlsViewOverlay.hxx" #include "view/SlsTheme.hxx" #include "Window.hxx" #include "sdpage.hxx" diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 9be9063c7d3b..209fd986af16 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -34,8 +34,8 @@ #include "SlideSorter.hxx" #include "SlideSorterViewShell.hxx" -#include "SlsSubstitutionHandler.hxx" -#include "SlsTransferable.hxx" +#include "SlsDragAndDropContext.hxx" +#include "controller/SlsTransferable.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsPageSelector.hxx" #include "controller/SlsFocusManager.hxx" @@ -50,7 +50,6 @@ #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsViewOverlay.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsPageObjectLayouter.hxx" #include "framework/FrameworkHelper.hxx" @@ -94,14 +93,13 @@ static const sal_uInt32 OVER_FADE_INDICATOR (0x00040000); static const sal_uInt32 OVER_BUTTON (0x00080000); static const sal_uInt32 SHIFT_MODIFIER (0x00100000); static const sal_uInt32 CONTROL_MODIFIER (0x00200000); -static const sal_uInt32 SUBSTITUTION_VISIBLE (0x01000000); -static const sal_uInt32 RECTANGLE_VISIBLE (0x02000000); +static const sal_uInt32 DRAG_ACTIVE (0x01000000); +static const sal_uInt32 MULTI_SELECTOR (0x02000000); static const sal_uInt32 KEY_EVENT (0x10000000); // Some absent events are defined so they can be expressed explicitly. static const sal_uInt32 NO_MODIFIER (0x00000000); -static const sal_uInt32 SUBSTITUTION_NOT_VISIBLE (0x00000000); static const sal_uInt32 NOT_OVER_PAGE (0x00000000); // Masks @@ -150,25 +148,6 @@ protected: namespace { - class RectangleSelector - : public SelectionFunction::MouseMultiSelector - { - public: - /** Start a rectangle selection at the given position. - */ - RectangleSelector ( - SlideSorter& rSlideSorter, - const Point& rMouseModelPosition); - virtual ~RectangleSelector (void); - - protected: - virtual void UpdateModelPosition (const Point& rMouseModelPosition); - - /** Select all pages that lie completly in the selection rectangle. - */ - virtual void UpdateSelection (void); - }; - class RangeSelector : public SelectionFunction::MouseMultiSelector { @@ -205,11 +184,12 @@ class SelectionFunction::EventDescriptor public: Point maMousePosition; Point maMouseModelPosition; - ::boost::weak_ptr mpHitDescriptor; + model::SharedPageDescriptor mpHitDescriptor; SdrPage* mpHitPage; sal_uInt32 mnEventCode; sal_Int32 mnButtonIndex; InsertionIndicatorHandler::Mode meDragMode; + bool mbMakeSelectionVisible; EventDescriptor ( sal_uInt32 nEventType, @@ -244,14 +224,13 @@ SelectionFunction::SelectionFunction ( mbDragSelection(false), maInsertionMarkerBox(), mbProcessingMouseButtonDown(false), - mpSubstitutionHandler(), + mpDragAndDropContext(), mpMouseMultiSelector(), mnButtonDownPageIndex(-1), mnButtonDownButtonIndex(-1), mbIsDeselectionPending(false), mnShiftKeySelectionAnchor(-1) { - aDragTimer.SetTimeoutHdl(LINK(this, SelectionFunction, DragSlideHdl)); } @@ -259,7 +238,6 @@ SelectionFunction::SelectionFunction ( SelectionFunction::~SelectionFunction (void) { - aDragTimer.Stop(); } @@ -297,15 +275,6 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) { Point aMousePosition (rEvent.GetPosPixel()); - // Allow one mouse move before the drag timer is disabled. - if (aDragTimer.IsActive()) - { - if (bFirstMouseMove) - bFirstMouseMove = FALSE; - else - aDragTimer.Stop(); - } - UpdatePageUnderMouse(aMousePosition, (rEvent.GetButtons() & MOUSE_LEFT)!=0); // Detect the mouse leaving the window. When not button is pressed then @@ -314,12 +283,10 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) if (rEvent.IsLeaveWindow() || ! Rectangle(Point(0,0),mpWindow->GetOutputSizePixel()).IsInside(aMousePosition)) { - if (mpSubstitutionHandler) + if (mpDragAndDropContext) { - // Mouse left the window with pressed left button. Make it a drag. - StartDrag(aMousePosition, InsertionIndicatorHandler::MoveMode); - mpSubstitutionHandler->Hide(); - mpSubstitutionHandler.reset(); + mpDragAndDropContext->Hide(); + mpDragAndDropContext.reset(); } mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); } @@ -347,9 +314,6 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent) // #95491# remember button state for creation of own MouseEvents SetMouseButtonCode (rEvent.GetButtons()); - if (aDragTimer.IsActive()) - aDragTimer.Stop(); - ProcessMouseEvent(BUTTON_UP, rEvent); mbProcessingMouseButtonDown = false; @@ -365,39 +329,26 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) { if (rEvent.mbLeaving) { - if (mpSubstitutionHandler) + if (mpDragAndDropContext) { // Disconnect the substitution handler from this selection function. - mpSubstitutionHandler->Hide(); - mpSubstitutionHandler->SetTargetSlideSorter(); - mpSubstitutionHandler.reset(); + mpDragAndDropContext->Hide(); + mpDragAndDropContext->SetTargetSlideSorter(); + mpDragAndDropContext.reset(); } } - else if ( ! mpSubstitutionHandler) + else if ( ! mpDragAndDropContext) { const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; - const Transferable* pSlideSorterTransferable - = dynamic_cast(pDragTransferable); - if (pSlideSorterTransferable != NULL) - { - // Connect the substitution handler to this selection function. - mpSubstitutionHandler = pSlideSorterTransferable->GetSubstitutionHandler(); - if (mpSubstitutionHandler) - { - mpSubstitutionHandler->SetTargetSlideSorter( - &mrSlideSorter, - rEvent.maPosPixel, - InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction), - pSlideSorterTransferable->GetView() == &mrSlideSorter.GetView()); - mpSubstitutionHandler->Show(); - } - } - else - mpSubstitutionHandler.reset( - new SubstitutionHandler( - mrSlideSorter, - mrSlideSorter.GetController().GetPageAt(rEvent.maPosPixel), - rEvent.maPosPixel)); + // Connect the substitution handler to this selection function. + mpDragAndDropContext.reset(new DragAndDropContext( + mrSlideSorter, + dynamic_cast(pDragTransferable))); + mrController.GetInsertionIndicatorHandler()->Start( + pDragTransferable->GetView()==&mrSlideSorter.GetView()); + mpDragAndDropContext->UpdatePosition( + rEvent.maPosPixel, + InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction)); } // 1. Compute some frequently used values relating to the event. @@ -405,23 +356,21 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) new EventDescriptor(rEvent, mrSlideSorter)); // 2. Detect whether we are dragging pages or dragging a selection rectangle. - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if (mpSubstitutionHandler) - pEventDescriptor->mnEventCode |= SUBSTITUTION_VISIBLE; + if (mpDragAndDropContext) + pEventDescriptor->mnEventCode |= DRAG_ACTIVE; if (mpMouseMultiSelector) - pEventDescriptor->mnEventCode |= RECTANGLE_VISIBLE; + pEventDescriptor->mnEventCode |= MULTI_SELECTOR; // 3. Set the drag mode. pEventDescriptor->SetDragMode( InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction)); // 4. Process the event. - EventPreprocessing(*pEventDescriptor); - if ( ! EventProcessing(*pEventDescriptor)) + if ( ! ProcessEvent(*pEventDescriptor)) { OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); } - EventPostprocessing(*pEventDescriptor); + PostProcessEvent(*pEventDescriptor); } @@ -429,10 +378,10 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) void SelectionFunction::NotifyDragFinished (void) { - if (mpSubstitutionHandler) + if (mpDragAndDropContext) { - mpSubstitutionHandler->Dispose(); - mpSubstitutionHandler.reset(); + mpDragAndDropContext->Dispose(); + mpDragAndDropContext.reset(); } mrController.GetInsertionIndicatorHandler()->End(); } @@ -440,9 +389,9 @@ void SelectionFunction::NotifyDragFinished (void) -::boost::shared_ptr SelectionFunction::GetSubstitutionHandler (void) const +::boost::shared_ptr SelectionFunction::GetDragAndDropContext (void) const { - return mpSubstitutionHandler; + return mpDragAndDropContext; } @@ -483,13 +432,13 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) // operation then stop that. Otherwise transfer the focus to // the tool box. - if ( ! (mpSubstitutionHandler || mpMouseMultiSelector)) + if ( ! (mpDragAndDropContext || mpMouseMultiSelector)) rFocusManager.SetFocusToToolBox(); - if (mpSubstitutionHandler) + if (mpDragAndDropContext) { - mpSubstitutionHandler->Dispose(); - mpSubstitutionHandler.reset(); + mpDragAndDropContext->Dispose(); + mpDragAndDropContext.reset(); } if (mpMouseMultiSelector) { @@ -734,53 +683,26 @@ void SelectionFunction::DoPaste (void) -void SelectionFunction::StartDragTimer (void) -{ - if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) - { - bFirstMouseMove = TRUE; - aDragTimer.Start(); - } -} - - - - -IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG ) -{ - StartDrag(aMDPos, InsertionIndicatorHandler::MoveMode); - return 0; -} - - - - void SelectionFunction::StartDrag ( const Point& rMousePosition, const InsertionIndicatorHandler::Mode eMode) { - if (mbPageHit - && ! mrSlideSorter.GetProperties()->IsUIReadOnly()) + if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { - if ( ! mpSubstitutionHandler) - mpSubstitutionHandler.reset( - new SubstitutionHandler( - mrSlideSorter, - mrSlideSorter.GetController().GetPageAt(rMousePosition), - rMousePosition)); - else - mpSubstitutionHandler->UpdatePosition( - rMousePosition, - eMode); - mbPageHit = false; - mpWindow->ReleaseMouse(); - if (mrSlideSorter.GetViewShell() != NULL) { SlideSorterViewShell* pSlideSorterViewShell = dynamic_cast(mrSlideSorter.GetViewShell()); pSlideSorterViewShell->StartDrag (rMousePosition, mpWindow); } + + if ( ! mpDragAndDropContext) + { + mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter, NULL)); + mrController.GetInsertionIndicatorHandler()->Start(true); + } + mpDragAndDropContext->UpdatePosition(rMousePosition, eMode); + mpWindow->ReleaseMouse(); } } @@ -802,7 +724,7 @@ void SelectionFunction::UpdatePageUnderMouse ( { // In some modes (dragging, moving) the mouse over indicator is only // annoying. Turn it off in these cases. - if (mpSubstitutionHandler || mpMouseMultiSelector) + if (mpDragAndDropContext || mpMouseMultiSelector) mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); else mrSlideSorter.GetView().UpdatePageUnderMouse(rMousePosition, bIsMouseButtonDown); @@ -888,19 +810,6 @@ void SelectionFunction::GotoNextPage (int nOffset) -void SelectionFunction::ClearOverlays (void) -{ - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - rOverlay.GetSubstitutionOverlay()->Clear(); - - mrController.GetInsertionIndicatorHandler()->End(); -} - - - - void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEvent& rEvent) { // #95491# remember button state for creation of own MouseEvents @@ -916,15 +825,11 @@ void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEve = EncodeMouseEvent(*pEventDescriptor, rEvent) | EncodeState(*pEventDescriptor); // 3. Process the event. - EventPreprocessing(*pEventDescriptor); - if ( ! EventProcessing(*pEventDescriptor)) + if ( ! ProcessEvent(*pEventDescriptor)) { OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); } - EventPostprocessing(*pEventDescriptor); - - if (nEventType == BUTTON_UP) - mbPageHit = false; + PostProcessEvent(*pEventDescriptor); } @@ -998,10 +903,9 @@ sal_uInt32 SelectionFunction::EncodeState ( sal_uInt32 nEventCode (0); // Detect whether the event has happened over a page object. - if (rDescriptor.mpHitPage != NULL && ! rDescriptor.mpHitDescriptor.expired()) + if (rDescriptor.mpHitPage != NULL && rDescriptor.mpHitDescriptor) { - model::SharedPageDescriptor pHitDescriptor (rDescriptor.mpHitDescriptor); - if (pHitDescriptor->HasState(model::PageDescriptor::ST_Selected)) + if (rDescriptor.mpHitDescriptor->HasState(model::PageDescriptor::ST_Selected)) nEventCode |= OVER_SELECTED_PAGE; else nEventCode |= OVER_UNSELECTED_PAGE; @@ -1013,10 +917,10 @@ sal_uInt32 SelectionFunction::EncodeState ( } // Detect whether we are dragging pages or dragging a selection rectangle. - if (mpSubstitutionHandler) - nEventCode |= SUBSTITUTION_VISIBLE; + if (mpDragAndDropContext) + nEventCode |= DRAG_ACTIVE; if (mpMouseMultiSelector) - nEventCode |= RECTANGLE_VISIBLE; + nEventCode |= MULTI_SELECTOR; return nEventCode; } @@ -1035,25 +939,9 @@ void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent) = EncodeKeyEvent(*pEventDescriptor, rEvent) | EncodeState(*pEventDescriptor); // 3. Process the event. - EventPreprocessing(*pEventDescriptor); - if ( ! EventProcessing(*pEventDescriptor)) + if ( ! ProcessEvent(*pEventDescriptor)) OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); - EventPostprocessing(*pEventDescriptor); -} - - - - -void SelectionFunction::EventPreprocessing (const EventDescriptor& rDescriptor) -{ - // Some general processing that is not specific to the exact event code. - if (rDescriptor.mnEventCode & BUTTON_DOWN) - mbPageHit = (rDescriptor.mpHitPage!=NULL); - - // Set the focus to the slide under the mouse. - // if (rDescriptor.mpHitPage != NULL) - // - // mrController.GetFocusManager().FocusPage((rDescriptor.mpHitPage->GetPageNum()-1)/2); + PostProcessEvent(*pEventDescriptor); } @@ -1069,221 +957,52 @@ bool Match ( -bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) +bool SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor) { // Define some macros to make the following switch statement more readable. #define ANY_MODIFIER(code) \ code|NO_MODIFIER: \ case code|SHIFT_MODIFIER: \ case code|CONTROL_MODIFIER -#define ANY_PAGE(code) \ - code|NOT_OVER_PAGE: \ - case code|OVER_UNSELECTED_PAGE: \ - case code|OVER_SELECTED_PAGE -#define ANY_PAGE_AND_MODIFIER(code) \ - ANY_PAGE(code|NO_MODIFIER): \ - case ANY_PAGE(code|SHIFT_MODIFIER): \ - case ANY_PAGE(code|CONTROL_MODIFIER) - bool bResult (true); - bool bMakeSelectionVisible (true); mrController.GetPageSelector().DisableBroadcasting(); PageSelector::UpdateLock aLock (mrSlideSorter); - // 2b. With the event code determine the type of operation with which to + // With the event code determine the type of operation with which to // react to the event. - // Acquire a shared_ptr to the hit page descriptor. - model::SharedPageDescriptor pHitDescriptor; - if ( ! rDescriptor.mpHitDescriptor.expired()) - pHitDescriptor = model::SharedPageDescriptor(rDescriptor.mpHitDescriptor); - - switch (rDescriptor.mnEventCode & (SUBSTITUTION_VISIBLE | RECTANGLE_VISIBLE)) + switch (rDescriptor.mnEventCode & (DRAG_ACTIVE | MULTI_SELECTOR)) { - case SUBSTITUTION_VISIBLE: - OSL_ASSERT(mpSubstitutionHandler); - // The substitution is visible. Handle events accordingly. - if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) - { - if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0) - StartDrag(rDescriptor.maMousePosition, InsertionIndicatorHandler::CopyMode); - mpSubstitutionHandler->UpdatePosition( - rDescriptor.maMousePosition, - rDescriptor.meDragMode); - } - else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG)) - { - mpSubstitutionHandler->UpdatePosition( - rDescriptor.maMousePosition, - rDescriptor.meDragMode); - } - else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON)) - { - // The following Process() call may lead to the desctruction - // of pHitDescriptor so release our reference to it. - pHitDescriptor.reset(); - mpSubstitutionHandler.reset(); - } + case DRAG_ACTIVE: + ProcessEventWhileDragActive(rDescriptor); break; - case RECTANGLE_VISIBLE: - OSL_ASSERT(mpMouseMultiSelector); - // The selection rectangle is visible. Handle events accordingly. - if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) - { - if (mpMouseMultiSelector) - { - mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); - mpMouseMultiSelector->UpdatePosition(rDescriptor.maMousePosition); - } - bMakeSelectionVisible = false; - } - else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK)) - { - mpMouseMultiSelector.reset(); - } - // Anything else stops the rectangle selection and the event is - // processed again. - else - { - mpMouseMultiSelector.reset(); - EventDescriptor aModifiedDescriptor (rDescriptor); - aModifiedDescriptor.mnEventCode &= ~RECTANGLE_VISIBLE; - EventProcessing(aModifiedDescriptor); - } + case MULTI_SELECTOR: + ProcessEventWhileMultiSelectorActive(rDescriptor); break; default: OSL_ASSERT(!mpMouseMultiSelector); + OSL_ASSERT(!mpDragAndDropContext); switch (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION)) { case BUTTON_DOWN: - switch (rDescriptor.mnEventCode) - { - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE: - SetCurrentPage(pHitDescriptor); - StartDragTimer(); - break; - - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: - StartDragTimer(); - break; - - case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_SELECTED_PAGE: - case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_UNSELECTED_PAGE: - // A double click allways shows the selected slide in the center - // pane in an edit view. - SetCurrentPage(pHitDescriptor); - SwitchView(pHitDescriptor); - break; - - // Range selection with the shift modifier. - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | SHIFT_MODIFIER: - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | SHIFT_MODIFIER: - RangeSelect(pHitDescriptor); - break; - - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON: - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON: - // Remember page and button index. When mouse button is - // released over same page and button then invoke action of that - // button. - mnButtonDownButtonIndex = rDescriptor.mnButtonIndex; - OSL_ASSERT(pHitDescriptor); - mnButtonDownPageIndex = pHitDescriptor->GetPageIndex(); - pHitDescriptor->GetVisualState().SetActiveButtonState( - mnButtonDownButtonIndex, - model::VisualState::BS_Pressed); - mrSlideSorter.GetView().RequestRepaint(pHitDescriptor); - break; - - // Right button for context menu. - case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE: - // Single right click and shift+F10 select as preparation to - // show the context menu. Change the selection only when the - // page under the mouse is not selected. In this case the - // selection is set to this single page. Otherwise the - // selection is not modified. - DeselectAllPages(); - SetCurrentPage(pHitDescriptor); - bMakeSelectionVisible = false; - break; - - case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: - // Do not change the selection. Just adjust the insertion indicator. - bMakeSelectionVisible = false; - break; - case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: - - // Rectangle selection. - case ANY_MODIFIER(BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): - mbIsDeselectionPending = true; - OSL_ASSERT(!mpMouseMultiSelector); - break; - } + ProcessButtonDownEvent(rDescriptor); break; case BUTTON_UP: - switch (rDescriptor.mnEventCode) - { - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: - SetCurrentPage(pHitDescriptor); - break; - - // Multi selection with the control modifier. - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER: - mrController.GetPageSelector().DeselectPage(pHitDescriptor); - break; - - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | CONTROL_MODIFIER: - mrController.GetPageSelector().SelectPage(pHitDescriptor); - // fallthrough - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON: - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON: - if (mnButtonDownButtonIndex == rDescriptor.mnButtonIndex - && mnButtonDownPageIndex == pHitDescriptor->GetPageIndex()) - { - ProcessButtonClick(pHitDescriptor, mnButtonDownButtonIndex); - } - break; - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: - if (mbIsDeselectionPending) - DeselectAllPages(); - break; - } + ProcessButtonUpEvent(rDescriptor); break; case MOUSE_MOTION: - switch (rDescriptor.mnEventCode) - { - // A mouse motion without visible substitution starts that. - case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE): - mpSubstitutionHandler.reset(new SubstitutionHandler( - mrSlideSorter, - pHitDescriptor, - rDescriptor.maMouseModelPosition)); - StartDrag( - rDescriptor.maMousePosition, - (rDescriptor.mnEventCode | CONTROL_MODIFIER) != 0 - ? InsertionIndicatorHandler::CopyMode - : InsertionIndicatorHandler::MoveMode); - break; - - // A mouse motion not over a page starts a rectangle selection. - case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): - OSL_ASSERT(!mpMouseMultiSelector); - mpMouseMultiSelector.reset( - new RangeSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); - mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); - break; - } + ProcessMouseMotionEvent(rDescriptor); break; } } - mrController.GetPageSelector().EnableBroadcasting(bMakeSelectionVisible); + mrController.GetPageSelector().EnableBroadcasting(rDescriptor.mbMakeSelectionVisible); return bResult; } @@ -1291,33 +1010,203 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) -void SelectionFunction::EventPostprocessing (const EventDescriptor& rDescriptor) +void SelectionFunction::ProcessEventWhileDragActive (EventDescriptor& rDescriptor) +{ + OSL_ASSERT(mpDragAndDropContext); + // The substitution is visible. Handle events accordingly. + if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) + { + if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0) + StartDrag(rDescriptor.maMousePosition, InsertionIndicatorHandler::CopyMode); + mpDragAndDropContext->UpdatePosition( + rDescriptor.maMousePosition, + rDescriptor.meDragMode); + } + else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG)) + { + mpDragAndDropContext->UpdatePosition( + rDescriptor.maMousePosition, + rDescriptor.meDragMode); + } + else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON)) + { + // The following Process() call may lead to the desctruction + // of rDescriptor.mpHitDescriptor so release our reference to it. + rDescriptor.mpHitDescriptor.reset(); + mpDragAndDropContext.reset(); + } +} + + + + +void SelectionFunction::ProcessEventWhileMultiSelectorActive (EventDescriptor& rDescriptor) +{ + OSL_ASSERT(mpMouseMultiSelector); + // The selection rectangle is visible. Handle events accordingly. + if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) + { + if (mpMouseMultiSelector) + { + mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); + mpMouseMultiSelector->UpdatePosition(rDescriptor.maMousePosition); + } + rDescriptor.mbMakeSelectionVisible = false; + } + else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK)) + { + mpMouseMultiSelector.reset(); + } + // Anything else stops the rectangle selection and the event is + // processed again. + else + { + mpMouseMultiSelector.reset(); + rDescriptor.mnEventCode &= ~MULTI_SELECTOR; + ProcessEvent(rDescriptor); + } +} + + + + +void SelectionFunction::ProcessButtonDownEvent (EventDescriptor& rDescriptor) +{ + switch (rDescriptor.mnEventCode) + { + case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE: + SetCurrentPage(rDescriptor.mpHitDescriptor); + break; + + case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: + break; + + case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_SELECTED_PAGE: + case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_UNSELECTED_PAGE: + // A double click allways shows the selected slide in the center + // pane in an edit view. + SetCurrentPage(rDescriptor.mpHitDescriptor); + SwitchView(rDescriptor.mpHitDescriptor); + break; + + case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | SHIFT_MODIFIER: + case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | SHIFT_MODIFIER: + // Range selection with the shift modifier. + RangeSelect(rDescriptor.mpHitDescriptor); + break; + + case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON: + case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON: + // Remember page and button index. When mouse button is + // released over same page and button then invoke action of that + // button. + mnButtonDownButtonIndex = rDescriptor.mnButtonIndex; + OSL_ASSERT(rDescriptor.mpHitDescriptor); + mnButtonDownPageIndex = rDescriptor.mpHitDescriptor->GetPageIndex(); + rDescriptor.mpHitDescriptor->GetVisualState().SetActiveButtonState( + mnButtonDownButtonIndex, + model::VisualState::BS_Pressed); + mrSlideSorter.GetView().RequestRepaint(rDescriptor.mpHitDescriptor); + break; + + // Right button for context menu. + case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE: + // Single right click and shift+F10 select as preparation to + // show the context menu. Change the selection only when the + // page under the mouse is not selected. In this case the + // selection is set to this single page. Otherwise the + // selection is not modified. + DeselectAllPages(); + SetCurrentPage(rDescriptor.mpHitDescriptor); + rDescriptor.mbMakeSelectionVisible = false; + break; + + case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: + // Do not change the selection. Just adjust the insertion indicator. + rDescriptor.mbMakeSelectionVisible = false; + break; + + case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: + // Fallthrough. + case ANY_MODIFIER(BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): + DeselectAllPages(); + break; + } +} + + + + +void SelectionFunction::ProcessButtonUpEvent (const EventDescriptor& rDescriptor) +{ + switch (rDescriptor.mnEventCode) + { + case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: + SetCurrentPage(rDescriptor.mpHitDescriptor); + break; + + // Multi selection with the control modifier. + case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER: + mrController.GetPageSelector().DeselectPage(rDescriptor.mpHitDescriptor); + break; + + case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | CONTROL_MODIFIER: + mrController.GetPageSelector().SelectPage(rDescriptor.mpHitDescriptor); + // fallthrough + case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON: + case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON: + if (mnButtonDownButtonIndex == rDescriptor.mnButtonIndex + && mnButtonDownPageIndex == rDescriptor.mpHitDescriptor->GetPageIndex()) + { + ProcessButtonClick(rDescriptor.mpHitDescriptor, mnButtonDownButtonIndex); + } + break; + + case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: + if (mbIsDeselectionPending) + DeselectAllPages(); + break; + } +} + + + + +void SelectionFunction::ProcessMouseMotionEvent (const EventDescriptor& rDescriptor) +{ + switch (rDescriptor.mnEventCode) + { + // A mouse motion without visible substitution starts that. + case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE): + StartDrag( + rDescriptor.maMousePosition, + (rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0 + ? InsertionIndicatorHandler::CopyMode + : InsertionIndicatorHandler::MoveMode); + break; + + // A mouse motion not over a page starts a rectangle selection. + case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): + OSL_ASSERT(!mpMouseMultiSelector); + mpMouseMultiSelector.reset( + new RangeSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); + mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); + break; + } +} + + + + +void SelectionFunction::PostProcessEvent (const EventDescriptor& rDescriptor) { if (rDescriptor.mnEventCode & BUTTON_UP) { - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - mpWindow->ReleaseMouse(); - // The overlays should not be visible anymore. Warn when one of - // them still is. An exception is th insertion indicator in the - // case that the context menu is visible. - DBG_ASSERT( - mrController.IsContextMenuOpen() - || !rOverlay.GetInsertionIndicatorOverlay()->IsVisible(), - "slidesorter::SelectionFunction: insertion indicator still visible"); - DBG_ASSERT( - !rOverlay.GetSubstitutionOverlay()->IsVisible(), - "slidesorter::SelectionFunction: substitution still visible"); - DBG_ASSERT( - !rOverlay.GetSelectionRectangleOverlay()->IsVisible(), - "slidesorter::SelectionFunction: selection rectangle still visible"); - // Now turn them off. if ( ! mrController.IsContextMenuOpen()) - rOverlay.GetInsertionIndicatorOverlay()->SetIsVisible(false); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - rOverlay.GetSelectionRectangleOverlay()->SetIsVisible(false); + mrController.GetInsertionIndicatorHandler()->End(); mnButtonDownPageIndex = -1; mnButtonDownButtonIndex = -1; @@ -1429,16 +1318,14 @@ SelectionFunction::EventDescriptor::EventDescriptor ( maMousePosition = rEvent.GetPosPixel(); maMouseModelPosition = pWindow->PixelToLogic(maMousePosition); - model::SharedPageDescriptor pHitDescriptor ( - rSlideSorter.GetController().GetPageAt(maMousePosition)); - if (pHitDescriptor.get() != NULL) + mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition); + if (mpHitDescriptor) { - mpHitDescriptor = pHitDescriptor; - mpHitPage = pHitDescriptor->GetPage(); + mpHitPage = mpHitDescriptor->GetPage(); - mnButtonIndex = rSlideSorter.GetView().GetLayouter() - .GetPageObjectLayouter()->GetButtonIndexAt( - pHitDescriptor, + mnButtonIndex + = rSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt( + mpHitDescriptor, maMouseModelPosition); } } @@ -1456,7 +1343,8 @@ SelectionFunction::EventDescriptor::EventDescriptor ( mpHitPage(), mnEventCode(0), mnButtonIndex(-1), - meDragMode(InsertionIndicatorHandler::MoveMode) + meDragMode(InsertionIndicatorHandler::MoveMode), + mbMakeSelectionVisible(true) { model::SharedPageDescriptor pHitDescriptor ( rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); @@ -1480,7 +1368,8 @@ SelectionFunction::EventDescriptor::EventDescriptor ( mpHitPage(), mnEventCode(MOUSE_DRAG), mnButtonIndex(-1), - meDragMode(InsertionIndicatorHandler::MoveMode) + meDragMode(InsertionIndicatorHandler::MoveMode), + mbMakeSelectionVisible(true) { SharedSdWindow pWindow (rSlideSorter.GetContentWindow()); @@ -1504,7 +1393,8 @@ SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDes mpHitPage(rDescriptor.mpHitPage), mnEventCode(rDescriptor.mnEventCode), mnButtonIndex(rDescriptor.mnButtonIndex), - meDragMode(InsertionIndicatorHandler::MoveMode) + meDragMode(InsertionIndicatorHandler::MoveMode), + mbMakeSelectionVisible(true) { } @@ -1603,15 +1493,15 @@ void SelectionFunction::MouseMultiSelector::SetSelectionModeFromModifier ( switch (nEventCode & MODIFIER_MASK) { case NO_MODIFIER: - SetSelectionMode(RectangleSelector::SM_Normal); + SetSelectionMode(SM_Normal); break; case SHIFT_MODIFIER: - SetSelectionMode(RectangleSelector::SM_Add); + SetSelectionMode(SM_Add); break; case CONTROL_MODIFIER: - SetSelectionMode(RectangleSelector::SM_Toggle); + SetSelectionMode(SM_Toggle); break; } } @@ -1669,92 +1559,6 @@ void SelectionFunction::MouseMultiSelector::UpdateSelectionState ( -//===== RectangleSelector ===================================================== - -namespace { - -RectangleSelector::RectangleSelector ( - SlideSorter& rSlideSorter, - const Point& rMouseModelPosition) - : MouseMultiSelector(rSlideSorter,rMouseModelPosition) -{ - if (mrSlideSorter.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay() - ->Start(rMouseModelPosition); - } -} - - - - -RectangleSelector::~RectangleSelector (void) -{ - if (mrSlideSorter.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay()->SetIsVisible(false); - } -} - - - - -void RectangleSelector::UpdateModelPosition (const Point& rMouseModelPosition) -{ - if (mrSlideSorter.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay() - ->Update(rMouseModelPosition); - UpdateSelection(); - } -} - - - - -void RectangleSelector::UpdateSelection (void) -{ - if ( ! mrSlideSorter.GetProperties()->IsShowSelection()) - return; - - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if (rOverlay.GetSelectionRectangleOverlay()->IsVisible()) - { - view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); - PageSelector::UpdateLock aPageSelectorUpdateLock (mrSlideSorter); - - // Select all pages whose page object lies completly or partially - // inside the selection rectangle. - const Rectangle& rSelectionRectangle ( - rOverlay.GetSelectionRectangleOverlay()->GetSelectionRectangle()); - model::PageEnumeration aPages ( - model::PageEnumerationProvider::CreateAllPagesEnumeration( - mrSlideSorter.GetModel())); - while (aPages.HasMoreElements()) - { - model::SharedPageDescriptor pDescriptor (aPages.GetNextElement()); - - // Determine whether the page object is inside the selection rectangle. - Rectangle aPageBox ( - mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox( - pDescriptor, - view::PageObjectLayouter::Preview, - view::PageObjectLayouter::WindowCoordinateSystem)); - const bool bIsPageInSelectionRectangle (rSelectionRectangle.IsOver(aPageBox)); - - UpdateSelectionState(pDescriptor, bIsPageInSelectionRectangle); - } - - // Rely on auto scrolling to make page objects visible. - mrSlideSorter.GetController().GetSelectionManager()->ResetMakeSelectionVisiblePending(); - } -} - -} // end of anonymous namespace - - - - //===== RangeSelector ========================================================= namespace { diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 43f1de2b1f02..c7b8da6016a3 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -81,8 +81,8 @@ namespace { private: SlideSorter& mrSlideSorter; double mnStart; - double mnEnd; - ::boost::function maAccelerationFunction; + const double mnEnd; + const ::boost::function maAccelerationFunction; }; class HorizontalVisibleAreaScroller { @@ -93,8 +93,8 @@ namespace { private: SlideSorter& mrSlideSorter; double mnStart; - double mnEnd; - ::boost::function maAccelerationFunction; + const double mnEnd; + const ::boost::function maAccelerationFunction; }; } @@ -116,6 +116,8 @@ SelectionManager::SelectionManager (SlideSorter& rSlideSorter) SelectionManager::~SelectionManager (void) { + if (mnAnimationId != Animator::NotAnAnimationId) + mrController.GetAnimator()->RemoveAnimation(mnAnimationId); } @@ -655,6 +657,8 @@ void SelectionManager::SetInsertionPosition (const sal_Int32 nInsertionPosition) namespace { +const static sal_Int32 gnMaxScrollDistance = 300; + VerticalVisibleAreaScroller::VerticalVisibleAreaScroller ( SlideSorter& rSlideSorter, const double nStart, @@ -666,6 +670,14 @@ VerticalVisibleAreaScroller::VerticalVisibleAreaScroller ( controller::AnimationParametricFunction( controller::AnimationBezierFunction (0.1,0.6))) { + // When the distance to scroll is larger than a threshold then first + // jump to within this distance of the final value and start the + // animation from there. + if (abs(nStart-nEnd) > gnMaxScrollDistance) + if (nStart < nEnd) + mnStart = nEnd-gnMaxScrollDistance; + else + mnStart = nEnd+gnMaxScrollDistance; } diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 7213fc5cb49d..13439f9a80db 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -49,7 +49,6 @@ #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" -#include "view/SlsViewOverlay.hxx" #include "framework/FrameworkHelper.hxx" #include "Window.hxx" #include "fupoor.hxx" @@ -1093,8 +1092,7 @@ void SlotManager::InsertSlide (SfxRequest& rRequest) } // No selection. Is there an insertion indicator? - else if (mrSlideSorter.GetView().GetOverlay() - .GetInsertionIndicatorOverlay()->IsVisible()) + else if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsActive()) { // Select the page before the insertion indicator. nInsertionIndex diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.cxx b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx index e9c6f58b1289..0f3a4818d95c 100644 --- a/sd/source/ui/slidesorter/controller/SlsTransferable.cxx +++ b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx @@ -31,7 +31,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" -#include "SlsTransferable.hxx" +#include "controller/SlsTransferable.hxx" #include "SlideSorterViewShell.hxx" #include "View.hxx" @@ -43,10 +43,10 @@ Transferable::Transferable ( ::sd::View* pWorkView, BOOL bInitOnGetData, SlideSorterViewShell* pViewShell, - const ::boost::shared_ptr& rpSubstitutionHandler) + const ::std::vector& rRepresentatives) : SdTransferable (pSrcDoc, pWorkView, bInitOnGetData), mpViewShell(pViewShell), - mpSubstitutionHandler(rpSubstitutionHandler) + maRepresentatives(rRepresentatives) { if (mpViewShell != NULL) StartListening(*mpViewShell); @@ -68,7 +68,6 @@ void Transferable::DragFinished (sal_Int8 nDropAction) { if (mpViewShell != NULL) mpViewShell->DragFinished(nDropAction); - mpSubstitutionHandler.reset(); } @@ -96,11 +95,10 @@ void Transferable::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) -::boost::shared_ptr Transferable::GetSubstitutionHandler (void) const +const ::std::vector& Transferable::GetRepresentatives (void) const { - return mpSubstitutionHandler; + return maRepresentatives; } - } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/makefile.mk b/sd/source/ui/slidesorter/controller/makefile.mk index 6f48104fdd9c..203219f509e8 100644 --- a/sd/source/ui/slidesorter/controller/makefile.mk +++ b/sd/source/ui/slidesorter/controller/makefile.mk @@ -52,6 +52,7 @@ SLOFILES = \ $(SLO)$/SlsAnimationFunction.obj \ $(SLO)$/SlsClipboard.obj \ $(SLO)$/SlsCurrentSlideManager.obj \ + $(SLO)$/SlsDragAndDropContext.obj \ $(SLO)$/SlsFocusManager.obj \ $(SLO)$/SlsInsertionIndicatorHandler.obj\ $(SLO)$/SlsListener.obj \ @@ -62,7 +63,6 @@ SLOFILES = \ $(SLO)$/SlsSelectionFunction.obj \ $(SLO)$/SlsSelectionManager.obj \ $(SLO)$/SlsSlotManager.obj \ - $(SLO)$/SlsSubstitutionHandler.obj \ $(SLO)$/SlsTransferable.obj # --- Tagets ------------------------------------------------------- diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx index 2972dab2d03a..68b6db5ef942 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx @@ -96,6 +96,12 @@ public: */ void RemoveAnimation (const AnimationId nAnimationId); + /** A typical use case for this method is the temporary shutdown of the + slidesorter when the slide sorter bar is put into a cache due to a + change of the edit mode. + */ + void RemoveAllAnimations (void); + private: SlideSorter& mrSlideSorter; Timer maTimer; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx index a87ff4e3066e..53c8bdfd3d42 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -33,6 +33,8 @@ #include "view/SlsInsertAnimator.hxx" +#include "view/SlsLayouter.hxx" + namespace sd { namespace slidesorter { class SlideSorter; } } namespace sd { namespace slidesorter { namespace model { class PageEnumeration; @@ -45,6 +47,8 @@ class InsertionIndicatorOverlay; namespace sd { namespace slidesorter { namespace controller { +class Transferable; + /** Manage the visibility and location of the insertion indicator. Its actual display is controlled by the InsertionIndicatorOverlay. @@ -60,13 +64,16 @@ public: /** Activate the insertion marker at the given coordinates. */ - void Start ( - const Point& rMouseModelPosition, - const Mode eMode, - const bool bIsOverSourceView); + void Start (const bool bIsOverSourceView); - void UpdateIndicatorIcon (model::PageEnumeration& rEnumeration); - void UpdateIndicatorIcon (void); + /** Deactivate the insertion marker. + */ + void End (void); + + /** Update the indicator icon from the current transferable (from the + clipboard or an active drag and drop operation.) + */ + void UpdateIndicatorIcon (const Transferable* pTransferable); /** Set the position of the insertion marker to the given coordinates. */ @@ -77,10 +84,6 @@ public: const Point& rMouseModelPosition, const sal_Int8 nDndAction); - /** Deactivate the insertion marker. - */ - void End (void); - /** Return whether the insertion marker is active. */ bool IsActive (void) const; @@ -96,14 +99,15 @@ public: would be the case when the selection is not consecutive or would be moved to a position outside and not adjacent to the selection. */ - bool IsInsertionTrivial (const Mode eMode) const; + bool IsInsertionTrivial ( + const sal_Int32 nInsertionIndex, + const Mode eMode) const; private: SlideSorter& mrSlideSorter; ::boost::shared_ptr mpInsertAnimator; ::boost::shared_ptr mpInsertionIndicatorOverlay; - sal_Int32 mnInsertionIndex; - Pair maVisualInsertionIndices; + view::InsertPosition maInsertPosition; Mode meMode; bool mbIsInsertionTrivial; bool mbIsActive; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index 33464fe10986..8a354697ceff 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -52,7 +52,7 @@ class SlideSorter; namespace sd { namespace slidesorter { namespace controller { class SlideSorterController; -class SubstitutionHandler; +class DragAndDropContext; class SelectionFunction @@ -109,7 +109,7 @@ public: const Point& rMousePosition, const bool bIsMouseButtonDown); - ::boost::shared_ptr GetSubstitutionHandler (void) const; + ::boost::shared_ptr GetDragAndDropContext (void) const; class MouseMultiSelector; @@ -126,9 +126,6 @@ protected: private: class EventDescriptor; - /// Set in MouseButtonDown this flag indicates that a page has been hit. - bool mbPageHit; - /// The rectangle of the mouse drag selection. Rectangle maDragSelectionRectangle; bool mbDragSelection; @@ -144,7 +141,7 @@ private: */ bool mbProcessingMouseButtonDown; - ::boost::shared_ptr mpSubstitutionHandler; + ::boost::shared_ptr mpDragAndDropContext; ::boost::scoped_ptr mpMouseMultiSelector; /** Remember where the left mouse button was pressed. @@ -159,7 +156,6 @@ private: */ sal_Int32 mnShiftKeySelectionAnchor; - DECL_LINK( DragSlideHdl, Timer* ); void StartDrag ( const Point& rMousePosition, const InsertionIndicatorHandler::Mode eMode); @@ -192,22 +188,11 @@ private: /// Deselect all pages. void DeselectAllPages (void); - /** For a possibly following mouse motion by starting the drag timer - that after a short time of pressed but un-moved mouse starts a drag - operation. - */ - void StartDragTimer (void); - /** Select all pages between and including the selection anchor and the specified page. */ void RangeSelect (const model::SharedPageDescriptor& rpDescriptor); - /** Hide and clear the insertion indiciator, substitution display and - selection rectangle. - */ - void ClearOverlays (void); - /** Compute a numerical code that describes a mouse event and that can be used for fast look up of the appropriate reaction. */ @@ -228,9 +213,13 @@ private: */ sal_uInt32 EncodeState (const EventDescriptor& rDescriptor) const; - void EventPreprocessing (const EventDescriptor& rEvent); - bool EventProcessing (const EventDescriptor& rEvent); - void EventPostprocessing (const EventDescriptor& rEvent); + bool ProcessEvent (EventDescriptor& rEvent); + void PostProcessEvent (const EventDescriptor& rEvent); + void ProcessEventWhileDragActive (EventDescriptor& rDescriptor); + void ProcessEventWhileMultiSelectorActive (EventDescriptor& rDescriptor); + void ProcessButtonDownEvent (EventDescriptor& rDescriptor); + void ProcessButtonUpEvent (const EventDescriptor& rDescriptor); + void ProcessMouseMotionEvent (const EventDescriptor& rDescriptor); void ProcessButtonClick ( const model::SharedPageDescriptor& rpDescriptor, @@ -245,4 +234,3 @@ private: } } } // end of namespace ::sd::slidesorter::controller #endif - diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx b/sd/source/ui/slidesorter/inc/controller/SlsTransferable.hxx similarity index 84% rename from sd/source/ui/slidesorter/controller/SlsTransferable.hxx rename to sd/source/ui/slidesorter/inc/controller/SlsTransferable.hxx index 3929e71176ff..51a804c92024 100644 --- a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsTransferable.hxx @@ -34,19 +34,12 @@ #include "sdxfer.hxx" class SdDrawDocument; -namespace sd -{ - class pWorkView; - namespace slidesorter - { - class SlideSorterViewShell; - } -} +namespace sd { namespace slidesorter { +class SlideSorterViewShell; +} } namespace sd { namespace slidesorter { namespace controller { -class SubstitutionHandler; - /** This class exists to have DragFinished call the correct object: the SlideSorterViewShell instead of the old SlideView. @@ -60,17 +53,17 @@ public: ::sd::View* pWorkView, BOOL bInitOnGetData, SlideSorterViewShell* pViewShell, - const ::boost::shared_ptr& rpSubstitutionHandler); + const ::std::vector& rRepresentatives); virtual ~Transferable (void); virtual void DragFinished (sal_Int8 nDropAction); - ::boost::shared_ptr GetSubstitutionHandler (void) const; + const ::std::vector& GetRepresentatives (void) const; private: SlideSorterViewShell* mpViewShell; - ::boost::shared_ptr mpSubstitutionHandler; + const ::std::vector maRepresentatives; virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); }; diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 0b270ff329b3..a6b1a389e5e4 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -31,6 +31,7 @@ #ifndef SD_SLIDESORTER_SLIDE_SORTER_VIEW_HXX #define SD_SLIDESORTER_SLIDE_SORTER_VIEW_HXX +#include "SlideSorter.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsSharedPageDescriptor.hxx" @@ -48,10 +49,6 @@ class Point; -namespace sd { namespace slidesorter { -class SlideSorter; -} } - namespace sd { namespace slidesorter { namespace controller { class SlideSorterController; class Properties; @@ -71,7 +68,6 @@ class LayeredDevice; class Layouter; class PageObjectPainter; class SelectionPainter; -class ViewOverlay; class SlideSorterView : public sd::View, @@ -162,8 +158,6 @@ public: ::boost::shared_ptr GetPreviewCache (void); - view::ViewOverlay& GetOverlay (void); - /** Set the bounding box of the insertion marker in model coordinates. It will be painted as a dark rectangle that fills the given box. @@ -209,15 +203,17 @@ public: const bool bStateValue); ::boost::shared_ptr GetPageObjectPainter (void); + ::boost::shared_ptr GetLayeredDevice (void) const; class DrawLock { public: - DrawLock (view::SlideSorterView& rView); + DrawLock (view::SlideSorterView& rView, const SharedSdWindow& rpWindow); DrawLock (SlideSorter& rSlideSorter); ~DrawLock (void); private: view::SlideSorterView& mrView; + SharedSdWindow mpWindow; }; protected: @@ -231,7 +227,6 @@ private: bool mbPageObjectVisibilitiesValid; ::boost::shared_ptr mpPreviewCache; ::boost::shared_ptr mpLayeredDevice; - ::boost::shared_ptr mpViewOverlay; Range maVisiblePageRange; bool mbModelChangedWhileModifyEnabled; Size maPreviewSize; @@ -242,6 +237,7 @@ private: sal_Int32 mnButtonUnderMouse; ::boost::shared_ptr mpPageObjectPainter; ::boost::shared_ptr mpSelectionPainter; + Region maRedrawRegion; /** Determine the visibility of all page objects. */ diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx index e7175a5d6a07..52c88b6e42cf 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx @@ -38,6 +38,9 @@ namespace sd { namespace slidesorter { namespace view { +class InsertPosition; + + /** Animate the positions of page objects to make room at the insert position while a move or copy operation takes place. */ @@ -51,8 +54,7 @@ public: icon. */ void SetInsertPosition ( - const sal_Int32 nPageIndex, - const Pair& rVisualInsertionIndices, + const InsertPosition& rInsertPosition, const Size& rIconSize); void Reset (void); diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx new file mode 100644 index 000000000000..691318419e11 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SD_SLIDESORTER_INSERTION_INDICATOR_OVERLAY_HXX +#define SD_SLIDESORTER_INSERTION_INDICATOR_OVERLAY_HXX + +#include "model/SlsSharedPageDescriptor.hxx" +#include "view/SlsILayerPainter.hxx" + +#include +#include +#include +#include +#include + +class OutputDevice; +class SdPage; + +namespace sd { namespace slidesorter { +class SlideSorter; +} } + +namespace sd { namespace slidesorter { namespace model { +class PageEnumeration; +} } } + +namespace sd { namespace slidesorter { namespace controller { +class Transferable; +} } } + +namespace sd { namespace slidesorter { namespace view { + +class FramePainter; +class LayeredDevice; + +/** The insertion indicator is painted as a vertical or horizonal bar + in the space between slides. +*/ +class InsertionIndicatorOverlay + : public ILayerPainter, + public ::boost::enable_shared_from_this +{ +public: + InsertionIndicatorOverlay (SlideSorter& rSlideSorter); + virtual ~InsertionIndicatorOverlay (void); + + virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator); + + void Create (const controller::Transferable* pTransferable); + + /** Given a position in model coordinates this method calculates the + insertion marker both as an index in the document and as a location + used for drawing the insertion indicator. + */ + void SetLocation (const Point& rPosition); + + Size GetSize (void) const; + + virtual void Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea); + + bool IsVisible (void) const; + void Hide (void); + void Show (void); + + Rectangle GetBoundingBox (void) const; + +private: + SlideSorter& mrSlideSorter; + bool mbIsVisible; + const sal_Int32 mnLayerIndex; + SharedILayerInvalidator mpLayerInvalidator; + // Center of the insertion indicator. + Point maLocation; + BitmapEx maIcon; + Point maIconOffset; + ::boost::scoped_ptr mpShadowPainter; + + void SetPositionAndSize (const Rectangle& rBoundingBox); + void SelectRepresentatives ( + model::PageEnumeration& rSelection, + ::std::vector& rDescriptors) const; + Point PaintRepresentatives ( + OutputDevice& rContent, + const Size aPreviewSize, + const sal_Int32 nOffset, + const ::std::vector& rPages) const; + void PaintPageCount ( + OutputDevice& rDevice, + const sal_Int32 nSelectionCount, + const Size aPreviewSize, + const Point aFirstPageOffset) const; + /** Setup the insertion indicator by creating the icon. It consists of + scaled down previews of some of the selected pages. + */ + void Create ( + const ::std::vector& rPages, + const sal_Int32 nSelectionCount); +}; + + + +} } } // end of namespace ::sd::slidesorter::view + +#endif diff --git a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx index 57f5b03b932c..228da649c3eb 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx @@ -45,6 +45,11 @@ class Size; namespace sd { namespace slidesorter { namespace view { +class InsertPosition; + + + + /** Calculate the size and position of page objects displayed by a slide sorter. The layouter takes into account various input values: 1.) Size of the window in which the slide sorter is displayed. @@ -192,20 +197,6 @@ public: */ Rectangle GetPageBox (const sal_Int32 nObjectCount = -1) const; - /** Return the location of the center of the insertion indicator that is - specified by the parameters. - @param aVisualIndicatorIndices - Row and column of where to paint the insertion indicator. Column - is -1 when the indicator is placed between rows of a single - column. - @param rIndicatorSize - The size of the insertion indicator. This size is used to adapt - the location when at the left or right of a row. - */ - Point GetInsertionIndicatorLocation ( - const Pair& rVisualIndicatorIndices, - const Size& rIndicatorSize) const; - /** Return the index of the first fully or partially visible page object. This takes into account only the vertical dimension. @return @@ -233,40 +224,22 @@ public: const Point& rModelPosition, const bool bIncludePageBorders = false) const; - /** Return the page index of where to do an insert operation when the - user would release the the mouse button at the given position after - a drag operation. This method assumes that pages are placed in a - single column. + /** Return an object that describes the logical and visual properties of + where to do an insert operation when the user would release the the + mouse button at the given position after a drag operation and of + where and how to display an insertion indicator. @param rPosition The position in the model coordinate system for which to determine the insertion page index. The position does not have to be over a page object to return a valid value. - @return - Returns the page index, as accepted by the slide sorter model, - of the page after which an insertion would take place. An index - of 0 means that insertion will take place before the first page, - An index equal to or greater than the page count means to insert - after the last page. - A value of -1 indicates that no valid insertion index exists for - the given point. + @param rIndicatorSize + The size of the insertion indicator. This size is used to adapt + the location when at the left or right of a row or at the top or + bottom of a column. */ - sal_Int32 GetVerticalInsertionIndex (const Point& rModelPosition) const; - - /** Return a pair of row and column indices of where to do an insert - operation when the user would release the the mouse button at the - given position after a drag operation. This method assumes that - pages are placed in a row-first grid. - @param rPosition - The position in the model coordinate system for which to - determine the insertion page index. The position does not have - to be over a page object to return a valid value. - @return - Returns a pair of (row,column) indices and defines the place of - where to paint the insertion indicator. The column index lies - in the range [0,column count]. A value of (-1,-1) indicates - that no valid insertion index exists for the given point. - */ - Pair GetGridInsertionIndices (const Point& rModelPosition) const; + InsertPosition GetInsertPosition ( + const Point& rModelPosition, + const Size& rIndicatorSize) const; /** Return whether the main orientation of the slides in the slide sorter is vertical, i.e. all slides are arranged in one column. @@ -293,6 +266,14 @@ private: 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; bool mbIsVertical; @@ -371,6 +352,42 @@ private: Rectangle GetPreviewBox (const sal_Int32 nIndex) const; }; + + + +/** Collect all values concerning the logical and visual properties of the + insertion position that is used for drag-and-drop and copy-and-past. +*/ +class InsertPosition +{ +public: + InsertPosition (void); + InsertPosition& operator= (const InsertPosition& rInsertPosition); + bool operator== (const InsertPosition& rInsertPosition) const; + bool operator!= (const InsertPosition& rInsertPosition) const; + + sal_Int32 GetRow (void) const { return mnRow; } + sal_Int32 GetColumn (void) const { return mnColumn; } + sal_Int32 GetIndex (void) const { return mnIndex; } + Point GetLocation (void) const { return maLocation; } + bool IsAtRunStart (void) const { return mbIsAtRunStart; } + bool IsAtRunEnd (void) const { return mbIsAtRunEnd; } + bool IsExtraSpaceNeeded (void) const { return mbIsExtraSpaceNeeded; } + +private: + sal_Int32 mnRow; + sal_Int32 mnColumn; + sal_Int32 mnIndex; + Point maLocation; + bool mbIsAtRunStart : 1; + bool mbIsAtRunEnd : 1; + bool mbIsExtraSpaceNeeded : 1; + + friend class Layouter; +}; + + + } } } // end of namespace ::sd::slidesorter::view #endif diff --git a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx b/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx deleted file mode 100644 index 3ecc1e5a6ee2..000000000000 --- a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx +++ /dev/null @@ -1,293 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: SlsViewOverlay.hxx,v $ - * $Revision: 1.10 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef SD_SLIDESORTER_VIEW_OVERLAY_HXX -#define SD_SLIDESORTER_VIEW_OVERLAY_HXX - -#include "model/SlsSharedPageDescriptor.hxx" -#include "view/SlsILayerPainter.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -class OutputDevice; -class Region; - - -namespace sd { namespace slidesorter { -class SlideSorter; -} } - -namespace sd { namespace slidesorter { namespace model { -class PageEnumeration; -} } } - -namespace sd { namespace slidesorter { namespace controller { -class SlideSorterController; -} } } - -namespace sd { namespace slidesorter { namespace view { - - -class LayeredDevice; -class InsertionIndicatorOverlay; -class SelectionRectangleOverlay; -class SubstitutionOverlay; -class ViewOverlay; -class FramePainter; - - -/** This base class of slide sorter overlays uses the drawing layer overlay - support for the display. -*/ -class OverlayBase : - public ILayerPainter, - public ::boost::enable_shared_from_this -{ -public: - OverlayBase (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); - virtual ~OverlayBase (void); - - bool IsVisible (void) const; - void SetIsVisible (const bool bIsVisible); - - virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator); - - sal_Int32 GetLayerIndex (void) const; - -protected: - ::osl::Mutex maMutex; - - ViewOverlay& mrViewOverlay; - SharedILayerInvalidator mpLayerInvalidator; - - class Invalidator; - friend class Invalidator; - - virtual Rectangle GetBoundingBox (void) const = 0; - -private: - bool mbIsVisible; - const sal_Int32 mnLayerIndex; - - void Invalidate (const Rectangle& rInvalidationBox); -}; - - - - -/** During internal drag and drop the outlines of the selected slides are - painted at the mouse position in dashed lines. -*/ -class SubstitutionOverlay - : public OverlayBase -{ -public: - SubstitutionOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); - virtual ~SubstitutionOverlay (void); - - void SetAnchor (const Point& rAnchor); - - /** Clear the substitution display. Until the next call of Create() no - substution is painted. - */ - void Clear (void); - - /** Move the substitution display by the given amount of pixels. - */ - void Move (const Point& rPositionOffset); - void SetPosition (const Point& rPosition); - Point GetPosition (void) const; - - virtual void Paint ( - OutputDevice& rDevice, - const Rectangle& rRepaintArea); - -protected: - virtual Rectangle GetBoundingBox (void) const; - -private: - /** The current position can be set by calling SetPosition() or Move(). - */ - Point maPosition; - - /** The substitution paints only the page object under the mouse and the - 8-neighborhood around it. It uses different levels of transparency - for the center and the four elements at its sides and the four - elements at its corners. All values between 0 (opaque) and 100 - (fully transparent.) - */ - static const sal_Int32 mnCenterTransparency; - static const sal_Int32 mnSideTransparency; - static const sal_Int32 mnCornerTransparency; -}; - - - - -/** Slides can be selected by drawing a selection rectangle in the slide - sorter. When the left mouse button is released all slides that are at - least partially in the rectangle are selected. -*/ -class SelectionRectangleOverlay - : public OverlayBase -{ -public: - SelectionRectangleOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); - - void Start (const Point& rAnchor); - void Update (const Point& rSecondCorner); - - Rectangle GetSelectionRectangle (void); - - virtual void Paint ( - OutputDevice& rDevice, - const Rectangle& rRepaintArea); - -protected: - virtual Rectangle GetBoundingBox (void) const; - -private: - Point maAnchor; - Point maSecondCorner; -}; - - - - -/** The insertion indicator is painted as a vertical or horizonal bar - in the space between slides. -*/ -class InsertionIndicatorOverlay - : public OverlayBase -{ -public: - InsertionIndicatorOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); - - /** Setup the insertion indicator by creating the icon. It consists of - scaled down previews of some of the selected pages. - */ - void Create (model::PageEnumeration& rSelection); - void Create (void); - - /** Given a position in model coordinates this method calculates the - insertion marker both as an index in the document and as a location - used for drawing the insertion indicator. - */ - void SetLocation (const Point& rPosition); - - Size GetSize (void) const; - - virtual void Paint ( - OutputDevice& rDevice, - const Rectangle& rRepaintArea); - -protected: - virtual Rectangle GetBoundingBox (void) const; - -private: - // Center of the insertion indicator. - Point maLocation; - /** Remember whether the insertion indicator is displayed before (left - of or above) or after (right of or below) the page at the insertion - index. - */ - bool mbIsBeforePage; - BitmapEx maIcon; - Point maIconOffset; - ::boost::scoped_ptr mpShadowPainter; - - void SetPositionAndSize (const Rectangle& rBoundingBox); - void SelectRepresentatives ( - model::PageEnumeration& rSelection, - ::std::vector& rDescriptors) const; - Point PaintRepresentatives ( - OutputDevice& rContent, - const Size aPreviewSize, - const sal_Int32 nOffset, - const ::std::vector& rDescriptors) const; - void PaintPageCount ( - OutputDevice& rDevice, - model::PageEnumeration& rSelection, - const Size aPreviewSize, - const Point aFirstPageOffset) const; -}; - - - - -/** The view overlay manages and paints some indicators that are painted on - top of the regular view content (the page objects). It is separated - from the view to allow the indicators to be altered in position and size - without repainting the whole view content (inside that the bounding box - of the indicator). This is achieved by using the drawing layer overlay - support. - - The view overlay itself simply gives access to the more specialized - classes that handle individual indicators. - -*/ -class ViewOverlay -{ -public: - ViewOverlay ( - SlideSorter& rSlideSorter, - const ::boost::shared_ptr& rpLayeredDevice); - virtual ~ViewOverlay (void); - - ::boost::shared_ptr GetSelectionRectangleOverlay (void); - ::boost::shared_ptr GetInsertionIndicatorOverlay (void); - ::boost::shared_ptr GetSubstitutionOverlay (void); - - SlideSorter& GetSlideSorter (void) const; - ::boost::shared_ptr GetLayeredDevice (void) const; - -private: - SlideSorter& mrSlideSorter; - const ::boost::shared_ptr mpLayeredDevice; - ::boost::shared_ptr mpSelectionRectangleOverlay; - ::boost::shared_ptr mpInsertionIndicatorOverlay; - ::boost::shared_ptr mpSubstitutionOverlay; -}; - - - -} } } // end of namespace ::sd::slidesorter::view - -#endif diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx index 8fe45e5e0cf7..089d9b70f5fc 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorter.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -37,6 +37,7 @@ #include "controller/SlideSorterController.hxx" #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsProperties.hxx" +#include "controller/SlsAnimator.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsTheme.hxx" #include "model/SlideSorterModel.hxx" @@ -497,18 +498,19 @@ void SlideSorter::ArrangeGUIElements ( { Point aOrigin (rOffset); - if (rSize.Width()!=0 && rSize.Height()!=0) + if (rSize.Width()>0 + && rSize.Height()>0 + && GetContentWindow() + && GetContentWindow()->IsVisible()) { // Prevent untimely redraws while the view is not yet correctly // resized. - view::SlideSorterView::DrawLock aLock (*mpSlideSorterView); - if (GetContentWindow()) - GetContentWindow()->EnablePaint (FALSE); + view::SlideSorterView::DrawLock aLock (*this); + GetContentWindow()->EnablePaint (FALSE); mpSlideSorterController->Resize (Rectangle(aOrigin, rSize)); - if (GetContentWindow()) - GetContentWindow()->EnablePaint (TRUE); + GetContentWindow()->EnablePaint (TRUE); mbLayoutPending = false; } @@ -537,6 +539,9 @@ SvBorder SlideSorter::GetBorder (void) bool SlideSorter::RelocateToWindow (::Window* pParentWindow) { + // Stop all animations for they have been started for the old window. + mpSlideSorterController->GetAnimator()->RemoveAllAnimations(); + ReleaseListeners(); if (mpViewShell != NULL) @@ -548,8 +553,8 @@ bool SlideSorter::RelocateToWindow (::Window* pParentWindow) // For accessibility we have to shortly hide the content window. This // triggers the construction of a new accessibility object for the new // view shell. (One is created earlier while the construtor of the base - // class is executed. At that time the correct accessibility object can - // not be constructed.) + // class is executed. But because at that time the correct + // accessibility object can not be constructed we do that now.) if (mpContentWindow.get() !=NULL) { mpContentWindow->Hide(); diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 9aa348bcb03a..ac8340a7b7aa 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -397,6 +397,11 @@ SdPage* SlideSorterViewShell::GetActualPage (void) pCurrentPage = pDescriptor->GetPage(); } + if (pCurrentPage == NULL) + { + + } + return pCurrentPage; } @@ -531,8 +536,8 @@ void SlideSorterViewShell::Paint ( ::sd::Window* pWindow) { SetActiveWindow (pWindow); - OSL_ASSERT(mpSlideSorter.get()!=NULL); - if (mpSlideSorter.get() != NULL) + OSL_ASSERT(mpSlideSorter); + if (mpSlideSorter) mpSlideSorter->GetController().Paint(rBBox,pWindow); } @@ -542,9 +547,7 @@ void SlideSorterViewShell::Paint ( void SlideSorterViewShell::ArrangeGUIElements (void) { OSL_ASSERT(mpSlideSorter.get()!=NULL); - mpSlideSorter->ArrangeGUIElements( - maViewPos, - maViewSize); + mpSlideSorter->ArrangeGUIElements(maViewPos, maViewSize); } @@ -611,6 +614,8 @@ void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView) } else rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow); + mpSlideSorter->GetController().GetCurrentSlideManager()->CurrentSlideHasChanged( + mpFrameView->GetSelectedPage()); mpSlideSorter->GetController().Rearrange(true); // DrawMode for 'main' window diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 22e3c05eff6c..d7b510464f19 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -41,7 +41,6 @@ #include "view/SlsLayouter.hxx" #include "view/SlsPageObjectLayouter.hxx" #include "view/SlsPageObjectPainter.hxx" -#include "view/SlsViewOverlay.hxx" #include "view/SlsILayerPainter.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsProperties.hxx" @@ -331,7 +330,6 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) mbPageObjectVisibilitiesValid (false), mpPreviewCache(), mpLayeredDevice(new LayeredDevice(rSlideSorter.GetContentWindow())), - mpViewOverlay (new ViewOverlay(rSlideSorter, mpLayeredDevice)), maVisiblePageRange(-1,-1), mbModelChangedWhileModifyEnabled(true), maPreviewSize(0,0), @@ -397,9 +395,6 @@ void SlideSorterView::Dispose (void) // Deletion of the objects and the page will be done in SdrModel // destructor (as long as objects and pages are added) - OSL_ASSERT(mpViewOverlay.unique()); - mpViewOverlay.reset(); - OSL_ASSERT(mpLayeredDevice.unique()); mpLayeredDevice.reset(); @@ -828,7 +823,7 @@ void SlideSorterView::CompleteRedraw ( } else { - View::CompleteRedraw(pDevice, rPaintArea, pRedirector); + maRedrawRegion.Union(rPaintArea); } #ifdef DEBUG_TIMING @@ -918,14 +913,6 @@ void SlideSorterView::ConfigurationChanged ( -ViewOverlay& SlideSorterView::GetOverlay (void) -{ - return *mpViewOverlay.get(); -} - - - - Pair SlideSorterView::GetVisiblePageRange (void) { if ( ! mbPageObjectVisibilitiesValid) @@ -1120,21 +1107,37 @@ bool SlideSorterView::SetState ( +::boost::shared_ptr SlideSorterView::GetLayeredDevice (void) const +{ + return mpLayeredDevice; +} + + + + //===== Animator::DrawLock ==================================================== -SlideSorterView::DrawLock::DrawLock (view::SlideSorterView& rView) - : mrView(rView) +SlideSorterView::DrawLock::DrawLock ( + view::SlideSorterView& rView, + const SharedSdWindow& rpWindow) + : mrView(rView), + mpWindow(rpWindow) { - mrView.LockRedraw(TRUE); + if (mrView.mnLockRedrawSmph == 0) + mrView.maRedrawRegion.SetEmpty(); + ++mrView.mnLockRedrawSmph; } SlideSorterView::DrawLock::DrawLock (SlideSorter& rSlideSorter) - : mrView(rSlideSorter.GetView()) + : mrView(rSlideSorter.GetView()), + mpWindow(rSlideSorter.GetContentWindow()) { - mrView.LockRedraw(TRUE); + if (mrView.mnLockRedrawSmph == 0) + mrView.maRedrawRegion.SetEmpty(); + ++mrView.mnLockRedrawSmph; } @@ -1142,7 +1145,19 @@ SlideSorterView::DrawLock::DrawLock (SlideSorter& rSlideSorter) SlideSorterView::DrawLock::~DrawLock (void) { - mrView.LockRedraw(FALSE); + OSL_ASSERT(mrView.mnLockRedrawSmph>0); + --mrView.mnLockRedrawSmph; + if (mrView.mnLockRedrawSmph == 0) + if (mpWindow) + { + mpWindow->Invalidate(mrView.maRedrawRegion); + mpWindow->Update(); + } + /* + mrView.CompleteRedraw( + mpWindow.get(), + mrView.maRedrawRegion); + */ } diff --git a/sd/source/ui/slidesorter/view/SlsFramePainter.cxx b/sd/source/ui/slidesorter/view/SlsFramePainter.cxx index a037f2c5f8c2..dfb2fd66e817 100644 --- a/sd/source/ui/slidesorter/view/SlsFramePainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsFramePainter.cxx @@ -50,6 +50,7 @@ FramePainter::FramePainter (const BitmapEx& rShadowBitmap) maShadowBottomLeft(rShadowBitmap,-1,+1), maShadowBottom(rShadowBitmap,0,+1), maShadowBottomRight(rShadowBitmap,+1,+1), + maShadowCenter(rShadowBitmap,0,0), mbIsValid(false) { if (rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height() @@ -100,6 +101,7 @@ void FramePainter::PaintFrame ( maShadowBottom.PaintSide(rDevice, aBox.BottomLeft(), aBox.BottomRight(), maShadowBottomLeft, maShadowBottomRight); + maShadowCenter.PaintCenter(rDevice,aBox); } @@ -137,13 +139,17 @@ FramePainter::OffsetBitmap::OffsetBitmap ( // Enlarge the side bitmaps so that painting the frame requires less // paint calls. const sal_Int32 nSideBitmapSize (64); - if (nHorizontalPosition == 0) + if (nHorizontalPosition == 0 && nVerticalPosition == 0) + { + maBitmap.Scale(Size(nSideBitmapSize,nSideBitmapSize), BMP_SCALE_FAST); + } + else if (nHorizontalPosition == 0) { maBitmap.Scale(Size(nSideBitmapSize,aSize.Height()), BMP_SCALE_FAST); } else if (nVerticalPosition == 0) { - maBitmap.Scale(Size(aSize.Width(), nSideBitmapSize), BMP_SCALE_FAST); + maBitmap.Scale(Size(maBitmap.GetSizePixel().Width(), nSideBitmapSize), BMP_SCALE_FAST); } } @@ -216,4 +222,23 @@ void FramePainter::OffsetBitmap::PaintSide ( } + + +void FramePainter::OffsetBitmap::PaintCenter ( + OutputDevice& rDevice, + const Rectangle& rBox) const +{ + const Size aBitmapSize (maBitmap.GetSizePixel()); + for (sal_Int32 nY=rBox.Top(); nY<=rBox.Bottom(); nY+=aBitmapSize.Height()) + for (sal_Int32 nX=rBox.Left(); nX<=rBox.Right(); nX+=aBitmapSize.Width()) + rDevice.DrawBitmapEx( + Point(nX,nY), + Size( + ::std::min(aBitmapSize.Width(), rBox.Right()-nX+1), + std::min(aBitmapSize.Height(), rBox.Bottom()-nY+1)), + maBitmap); +} + + + } } } // end of namespace sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsFramePainter.hxx b/sd/source/ui/slidesorter/view/SlsFramePainter.hxx index 7d0aa7a94e70..71f22ddf1649 100644 --- a/sd/source/ui/slidesorter/view/SlsFramePainter.hxx +++ b/sd/source/ui/slidesorter/view/SlsFramePainter.hxx @@ -46,6 +46,10 @@ class FramePainter public: FramePainter (const BitmapEx& rBitmap); ~FramePainter (void); + + /** Paint a border around the given box by using a set of bitmaps for + the corners and sides. + */ void PaintFrame (OutputDevice&rDevice, const Rectangle aBox) const; private: @@ -90,6 +94,12 @@ private: const OffsetBitmap& rCornerBitmap1, const OffsetBitmap& rCornerBitmap2) const; + /** Fill the given rectangle with the bitmap. + */ + void PaintCenter ( + OutputDevice& rDevice, + const Rectangle& rBox) const; + private: BitmapEx maBitmap; Point maOffset; @@ -102,6 +112,7 @@ private: OffsetBitmap maShadowBottomLeft; OffsetBitmap maShadowBottom; OffsetBitmap maShadowBottomRight; + OffsetBitmap maShadowCenter; bool mbIsValid; }; diff --git a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx index 6ae6e872df86..5731f7c49de6 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx @@ -75,15 +75,16 @@ public: void operator () (const double nTime); void UpdateOffsets( - const sal_Int32 nInsertIndex, + const InsertPosition& rInsertPosition, const Size& rRequiredSpace, const view::Layouter& GetLayouter); + void ResetOffsets (void); /// Index of the row or column that this run represents. sal_Int32 mnRunIndex; /// The index at which to make place for the insertion indicator (-1 for /// no indicator). - sal_Int32 mnInsertIndex; + sal_Int32 mnLocalInsertIndex; /// Index of the first page in the run. sal_Int32 mnStartIndex; /// Index of the last page in the run. @@ -132,8 +133,7 @@ public: virtual ~Implementation (void); void SetInsertPosition ( - const sal_Int32 nPageIndex, - const Pair& rVisualInsertionIndices, + const InsertPosition& rInsertPosition, const Size& rIconSize); void Reset (void); @@ -150,15 +150,12 @@ private: ::boost::shared_ptr mpAnimator; typedef ::std::set RunContainer; RunContainer maRuns; - /// The current insertion index. The special value -1 means that there - /// is no current insertion index. - sal_Int32 mnCurrentInsertPosition; - Pair maVisualInsertionIndices; + InsertPosition maInsertPosition; void StopAnimation (void); SharedPageObjectRun GetRun ( view::Layouter& rLayouter, - const sal_Int32 nRowIndex, + const InsertPosition& rInsertPosition, const bool bCreate = true); RunContainer::iterator FindRun (const sal_Int32 nRunIndex) const; }; @@ -178,11 +175,10 @@ InsertAnimator::InsertAnimator (SlideSorter& rSlideSorter) void InsertAnimator::SetInsertPosition ( - const sal_Int32 nPageIndex, - const Pair& rVisualInsertionIndices, + const InsertPosition& rInsertPosition, const Size& rIconSize) { - mpImplementation->SetInsertPosition(nPageIndex, rVisualInsertionIndices, rIconSize); + mpImplementation->SetInsertPosition(rInsertPosition, rIconSize); } @@ -203,8 +199,7 @@ InsertAnimator::Implementation::Implementation (SlideSorter& rSlideSorter) mrView(rSlideSorter.GetView()), mpAnimator(rSlideSorter.GetController().GetAnimator()), maRuns(), - mnCurrentInsertPosition(-1), - maVisualInsertionIndices() + maInsertPosition() { } @@ -220,17 +215,15 @@ InsertAnimator::Implementation::~Implementation (void) void InsertAnimator::Implementation::SetInsertPosition ( - const sal_Int32 nPageIndex, - const Pair& rVisualInsertionIndices, + const InsertPosition& rInsertPosition, const Size& rIconSize) { - if (nPageIndex==mnCurrentInsertPosition && rVisualInsertionIndices==maVisualInsertionIndices) + if (maInsertPosition == rInsertPosition) return; - SharedPageObjectRun pOldRun (GetRun(mrView.GetLayouter(), maVisualInsertionIndices.A())); - SharedPageObjectRun pCurrentRun (GetRun(mrView.GetLayouter(), rVisualInsertionIndices.A())); - mnCurrentInsertPosition = nPageIndex; - maVisualInsertionIndices = rVisualInsertionIndices; + SharedPageObjectRun pOldRun (GetRun(mrView.GetLayouter(), maInsertPosition)); + SharedPageObjectRun pCurrentRun (GetRun(mrView.GetLayouter(), rInsertPosition)); + maInsertPosition = rInsertPosition; // When the new insert position is in a different run then move the page // objects in the old run to their default positions. @@ -238,7 +231,7 @@ void InsertAnimator::Implementation::SetInsertPosition ( { if (pOldRun) { - pOldRun->UpdateOffsets(-1, Size(0,0), mrView.GetLayouter()); + pOldRun->ResetOffsets(); maRuns.insert(pOldRun); } } @@ -247,7 +240,7 @@ void InsertAnimator::Implementation::SetInsertPosition ( { const sal_Int32 nColumnCount (mrView.GetLayouter().GetColumnCount()); pCurrentRun->UpdateOffsets( - nColumnCount > 1 ? maVisualInsertionIndices.B() : maVisualInsertionIndices.A(), + rInsertPosition, nColumnCount > 1 ? Size(rIconSize.Width(),0) : Size(0, rIconSize.Height()), mrView.GetLayouter()); maRuns.insert(pCurrentRun); @@ -259,7 +252,7 @@ void InsertAnimator::Implementation::SetInsertPosition ( void InsertAnimator::Implementation::Reset (void) { - SetInsertPosition(-1, Pair(-1,-1), Size(0,0)); + SetInsertPosition(InsertPosition(), Size(0,0)); } @@ -267,10 +260,11 @@ void InsertAnimator::Implementation::Reset (void) SharedPageObjectRun InsertAnimator::Implementation::GetRun ( view::Layouter& rLayouter, - const sal_Int32 nRowIndex, + const InsertPosition& rInsertPosition, const bool bCreate) { - if (nRowIndex < 0) + const sal_Int32 nRow (rInsertPosition.GetRow()); + if (nRow < 0) return SharedPageObjectRun(); RunContainer::iterator iRun (maRuns.end()); @@ -287,17 +281,17 @@ SharedPageObjectRun InsertAnimator::Implementation::GetRun ( } else { - iRun = FindRun(nRowIndex); + iRun = FindRun(nRow); if (iRun == maRuns.end() && bCreate) { // Create a new run. - const sal_Int32 nStartIndex (rLayouter.GetIndex(nRowIndex,0)); - const sal_Int32 nEndIndex (rLayouter.GetIndex(nRowIndex,rLayouter.GetColumnCount()-1)); + const sal_Int32 nStartIndex (rLayouter.GetIndex(nRow, 0)); + const sal_Int32 nEndIndex (rLayouter.GetIndex(nRow, rLayouter.GetColumnCount()-1)); if (nStartIndex <= nEndIndex) { iRun = maRuns.insert(SharedPageObjectRun(new PageObjectRun( *this, - nRowIndex, + nRow, nStartIndex, nEndIndex))).first; OSL_ASSERT(iRun != maRuns.end()); @@ -334,7 +328,7 @@ void InsertAnimator::Implementation::RemoveRun (PageObjectRun* pRun) if (pRun != NULL) { // Do not remove runs that show the space for the insertion indicator. - if (pRun->mnInsertIndex == -1) + if (pRun->mnLocalInsertIndex == -1) maRuns.erase(FindRun(pRun->mnRunIndex)); } else @@ -355,7 +349,7 @@ PageObjectRun::PageObjectRun ( const sal_Int32 nStartIndex, const sal_Int32 nEndIndex) : mnRunIndex(nRunIndex), - mnInsertIndex(-1), + mnLocalInsertIndex(-1), mnStartIndex(nStartIndex), mnEndIndex(nEndIndex), maStartOffset(), @@ -382,21 +376,25 @@ PageObjectRun::~PageObjectRun (void) void PageObjectRun::UpdateOffsets( - const sal_Int32 nInsertIndex, + const InsertPosition& rInsertPosition, const Size& rRequiredSpace, const view::Layouter& rLayouter) { - if (nInsertIndex != mnInsertIndex) + const sal_Int32 nLocalInsertIndex(rLayouter.GetColumnCount()==1 + ? rInsertPosition.GetRow() + : rInsertPosition.GetColumn()); + if (nLocalInsertIndex != mnLocalInsertIndex) { - mnInsertIndex = nInsertIndex; + mnLocalInsertIndex = nLocalInsertIndex; model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel()); Point aLeadingOffset; Point aTrailingOffset; - const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1); const bool bUseX (rLayouter.GetColumnCount() > 1); - if (mnInsertIndex == 0) + const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1); + if (rInsertPosition.IsAtRunStart()) { + // Insertion position is at the left or top of the run. const Rectangle aInnerBox (rLayouter.GetPageObjectLayouter()->GetBoundingBox( Point(0,0), PageObjectLayouter::Preview, @@ -407,8 +405,9 @@ void PageObjectRun::UpdateOffsets( else aTrailingOffset.Y() = ::std::max(0L, rRequiredSpace.Height()-aAvailableSpace.Y()); } - else if (mnInsertIndex == nRunLength) + else if (rInsertPosition.IsAtRunEnd() && rInsertPosition.IsExtraSpaceNeeded()) { + // Insertion position is at the right or bottom of the run. const Rectangle aOuterBox (rLayouter.GetPageObjectBox(mnEndIndex)); const Rectangle aInnerBox (rLayouter.GetPageObjectLayouter()->GetBoundingBox( aOuterBox.TopLeft(), @@ -420,14 +419,15 @@ void PageObjectRun::UpdateOffsets( else aLeadingOffset.Y() = ::std::min(0L, aAvailableSpace.Y()-rRequiredSpace.Height()); } - else if (mnInsertIndex > 0) + else if ( ! rInsertPosition.IsAtRunEnd()) { + // Insertion position is somewhere in the middle of the run. const Rectangle aBox1 (rLayouter.GetPageObjectLayouter()->GetBoundingBox( - rModel.GetPageDescriptor(mnStartIndex + nInsertIndex - 1), + rModel.GetPageDescriptor(mnStartIndex + mnLocalInsertIndex - 1), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); const Rectangle aBox2 (rLayouter.GetPageObjectLayouter()->GetBoundingBox( - rModel.GetPageDescriptor(mnStartIndex + nInsertIndex), + rModel.GetPageDescriptor(mnStartIndex + mnLocalInsertIndex), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); const Size aDelta ( @@ -449,7 +449,7 @@ void PageObjectRun::UpdateOffsets( model::SharedPageDescriptor pDescriptor(rModel.GetPageDescriptor(nIndex+mnStartIndex)); if (pDescriptor) maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset(); - maEndOffset[nIndex] = nIndex < nInsertIndex + maEndOffset[nIndex] = nIndex < mnLocalInsertIndex ? aLeadingOffset : aTrailingOffset; } @@ -460,6 +460,24 @@ void PageObjectRun::UpdateOffsets( +void PageObjectRun::ResetOffsets (void) +{ + mnLocalInsertIndex = -1; + const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1); + model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel()); + for (sal_Int32 nIndex=0; nIndexGetVisualState().GetLocationOffset(); + maEndOffset[nIndex] = Point(0,0); + } + RestartAnimation(); +} + + + + void PageObjectRun::RestartAnimation (void) { // Stop the current animation. diff --git a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx new file mode 100644 index 000000000000..5a0b7a209799 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx @@ -0,0 +1,449 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "view/SlsInsertionIndicatorOverlay.hxx" + +#include "SlideSorter.hxx" +#include "model/SlsPageEnumeration.hxx" +#include "view/SlideSorterView.hxx" +#include "view/SlsLayouter.hxx" +#include "view/SlsPageObjectLayouter.hxx" +#include "view/SlsTheme.hxx" +#include "cache/SlsPageCache.hxx" +#include "controller/SlsTransferable.hxx" +#include "SlsFramePainter.hxx" +#include "SlsLayeredDevice.hxx" +#include "DrawDocShell.hxx" +#include "drawdoc.hxx" +#include "sdpage.hxx" +#include "sdmod.hxx" + +#include +#include +#include +#include +#include + + +namespace { + + +static const double gnPreviewOffsetScale = 1.0 / 8.0; + + + +Rectangle GrowRectangle (const Rectangle& rBox, const sal_Int32 nOffset) +{ + return Rectangle ( + rBox.Left() - nOffset, + rBox.Top() - nOffset, + rBox.Right() + nOffset, + rBox.Bottom() + nOffset); +} + +sal_Int32 RoundToInt (const double nValue) { return sal_Int32(::rtl::math::round(nValue)); } + +} // end of anonymous namespace + + +namespace sd { namespace slidesorter { namespace view { + + +//===== InsertionIndicatorOverlay =========================================== + +const static sal_Int32 gnShadowBorder = 3; +const static sal_Int32 gnSuperScaleFactor = 1; +const static sal_Int32 gnAngle = 0; // measured in 10th of degrees + +InsertionIndicatorOverlay::InsertionIndicatorOverlay (SlideSorter& rSlideSorter) + : mrSlideSorter(rSlideSorter), + mbIsVisible(false), + mnLayerIndex(2), + mpLayerInvalidator(), + maLocation(), + maIcon(), + maIconOffset(), + mpShadowPainter(new FramePainter(mrSlideSorter.GetTheme()->GetIcon(Theme::RawInsertShadow))) +{ +} + + + + +InsertionIndicatorOverlay::~InsertionIndicatorOverlay (void) +{ + Hide(); +} + + + + +void InsertionIndicatorOverlay::Create (const controller::Transferable* pTransferable) +{ + if (pTransferable == NULL) + return; + + sal_Int32 nSelectionCount (0); + if (pTransferable->HasPageBookmarks()) + nSelectionCount = pTransferable->GetPageBookmarks().Count(); + else + { + DrawDocShell* pDataDocShell = dynamic_cast(&pTransferable->GetDocShell()); + if (pDataDocShell != NULL) + { + SdDrawDocument* pDataDocument = pDataDocShell->GetDoc(); + if (pDataDocument != NULL) + nSelectionCount = pDataDocument->GetSdPageCount(PK_STANDARD); + } + } + Create(pTransferable->GetRepresentatives(), nSelectionCount); +} + + + + +void InsertionIndicatorOverlay::Create ( + const ::std::vector& rRepresentatives, + const sal_Int32 nSelectionCount) +{ + view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); + ::boost::shared_ptr pPageObjectLayouter ( + rLayouter.GetPageObjectLayouter()); + ::boost::shared_ptr pTheme (mrSlideSorter.GetTheme()); + const Size aOriginalPreviewSize (pPageObjectLayouter->GetPreviewSize()); + + const double nPreviewScale (0.5); + const Size aPreviewSize ( + RoundToInt(aOriginalPreviewSize.Width()*nPreviewScale), + RoundToInt(aOriginalPreviewSize.Height()*nPreviewScale)); + const sal_Int32 nOffset ( + RoundToInt(Min(aPreviewSize.Width(),aPreviewSize.Height()) * gnPreviewOffsetScale)); + + // Determine size and offset depending on the number of previews. + sal_Int32 nCount (rRepresentatives.size()); + if (nCount > 0) + --nCount; + Size aIconSize( + aPreviewSize.Width() + 2 * gnShadowBorder + nCount*nOffset, + aPreviewSize.Height() + 2 * gnShadowBorder + nCount*nOffset); + maIconOffset = Point(gnShadowBorder, gnShadowBorder); + + // Create virtual devices for bitmap and mask whose bitmaps later be + // combined to form the BitmapEx of the icon. + VirtualDevice aContent ( + *mrSlideSorter.GetContentWindow(), + 0, + 0); + if (gnAngle != 0) + { + aIconSize = Size( + RoundToInt( + cos(gnAngle/1800.0*M_PI) * aIconSize.Width() + + sin(gnAngle/1800.0*M_PI) * aIconSize.Height()), + RoundToInt( + sin(gnAngle/1800.0*M_PI) * aIconSize.Width() + + cos(gnAngle/1800.0*M_PI) * aIconSize.Height())); + } + aContent.SetOutputSizePixel(aIconSize); + + aContent.SetFillColor(); + aContent.SetLineColor(pTheme->GetColor(Theme::PreviewBorder)); + const Point aOffset = PaintRepresentatives(aContent, aPreviewSize, nOffset, rRepresentatives); + + PaintPageCount(aContent, nSelectionCount, aPreviewSize, aOffset); + + maIcon = aContent.GetBitmapEx(Point(0,0), aIconSize); + maIcon.Scale(aIconSize); +} + + + + +void InsertionIndicatorOverlay::SelectRepresentatives ( + model::PageEnumeration& rSelection, + ::std::vector& rDescriptors) const +{ + sal_Int32 nCount (0); + while (rSelection.HasMoreElements()) + { + if (nCount++ >= 3) + break; + rDescriptors.push_back(rSelection.GetNextElement()); + } +} + + + + +Point InsertionIndicatorOverlay::PaintRepresentatives ( + OutputDevice& rContent, + const Size aPreviewSize, + const sal_Int32 nOffset, + const ::std::vector& rRepresentatives) const +{ + const Point aOffset (0,rRepresentatives.size()==1 ? -nOffset : 0); + + // Paint the pages. + Point aPageOffset (0,0); + double nTransparency (0); + for (sal_Int32 nIndex=2; nIndex>=0; --nIndex) + { + if (rRepresentatives.size() <= nIndex) + continue; + switch(nIndex) + { + case 0 : + aPageOffset = Point(0, nOffset); + nTransparency = 0.85; + break; + case 1: + aPageOffset = Point(nOffset, 0); + nTransparency = 0.75; + break; + case 2: + aPageOffset = Point(2*nOffset, 2*nOffset); + nTransparency = 0.65; + break; + } + aPageOffset += aOffset; + aPageOffset.X() += gnShadowBorder; + aPageOffset.Y() += gnShadowBorder; + + ::boost::shared_ptr pPreviewCache ( + mrSlideSorter.GetView().GetPreviewCache()); + Bitmap aPreview (rRepresentatives[nIndex]); + const double nScale (double(aPreviewSize.Width())/double(aPreview.GetSizePixel().Width())); + const Size aSuperSampleSize( + aPreviewSize.Width()*gnSuperScaleFactor, + aPreviewSize.Height()*gnSuperScaleFactor); + if (gnAngle != 0) + { + aPreview.Scale(aSuperSampleSize, BMP_SCALE_INTERPOLATE); + aPreview.Rotate(gnAngle, Color(128,0,0,255)); + aPreview.Scale(1.0/gnSuperScaleFactor,1.0/gnSuperScaleFactor, BMP_SCALE_INTERPOLATE); + } + else + { + aPreview.Scale(aPreviewSize, BMP_SCALE_INTERPOLATE); + } + rContent.DrawBitmapEx(aPageOffset, aPreview); + + // Tone down the bitmap. The further back the darker it becomes. + Rectangle aBox ( + aPageOffset.X(), + aPageOffset.Y(), + aPageOffset.X()+aPreviewSize.Width()-1, + aPageOffset.Y()+aPreviewSize.Height()-1); + rContent.SetFillColor(COL_BLACK); + rContent.SetLineColor(); + rContent.DrawTransparent( + ::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right()+1, aBox.Bottom()+1), + 0, + 0)), + nTransparency); + + // Draw border around preview. + Rectangle aBorderBox (GrowRectangle(aBox, 1)); + rContent.SetLineColor(COL_GRAY); + rContent.SetFillColor(); + rContent.DrawRect(aBorderBox); + + // Draw shadow around preview. + mpShadowPainter->PaintFrame(rContent, aBorderBox); + } + + return aPageOffset; +} + + + + +void InsertionIndicatorOverlay::PaintPageCount ( + OutputDevice& rDevice, + const sal_Int32 nSelectionCount, + const Size aPreviewSize, + const Point aFirstPageOffset) const +{ + // Paint the number of slides. + ::boost::shared_ptr pTheme (mrSlideSorter.GetTheme()); + ::boost::shared_ptr pFont(Theme::GetFont(Theme::PageCountFont, rDevice)); + if (pFont) + { + ::rtl::OUString sNumber (::rtl::OUString::valueOf(nSelectionCount)); + + // Determine the size of the (painted) text and create a bounding + // box that centers the text on the first preview. + rDevice.SetFont(*pFont); + Rectangle aTextBox; + rDevice.GetTextBoundRect(aTextBox, sNumber); + Point aTextOffset (aTextBox.TopLeft()); + Size aTextSize (aTextBox.GetSize()); + // Place text inside the first page preview. + Point aTextLocation(aFirstPageOffset); + // Center the text. + aTextLocation += Point( + (aPreviewSize.Width()-aTextBox.GetWidth())/2, + (aPreviewSize.Height()-aTextBox.GetHeight())/2); + aTextBox = Rectangle(aTextLocation, aTextSize); + + // Paint background, border and text. + static const sal_Int32 nBorder = 5; + rDevice.SetFillColor(pTheme->GetColor(Theme::Selection)); + rDevice.SetLineColor(pTheme->GetColor(Theme::Selection)); + rDevice.DrawRect(GrowRectangle(aTextBox, nBorder)); + + rDevice.SetFillColor(); + rDevice.SetLineColor(COL_WHITE); + rDevice.DrawRect(GrowRectangle(aTextBox, nBorder-1)); + + rDevice.SetTextColor(COL_WHITE); + rDevice.DrawText(aTextBox.TopLeft()-aTextOffset, sNumber); + } +} + + + + +void InsertionIndicatorOverlay::SetLocation (const Point& rLocation) +{ + const Point aTopLeft ( + rLocation - Point( + maIcon.GetSizePixel().Width()/2, + maIcon.GetSizePixel().Height()/2)); + if (maLocation != aTopLeft) + { + const Rectangle aOldBoundingBox (GetBoundingBox()); + + maLocation = aTopLeft; + + if (mpLayerInvalidator && IsVisible()) + { + mpLayerInvalidator->Invalidate(aOldBoundingBox); + mpLayerInvalidator->Invalidate(GetBoundingBox()); + } + } +} + + + + +void InsertionIndicatorOverlay::Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea) +{ + (void)rRepaintArea; + + if ( ! IsVisible()) + return; + + rDevice.DrawImage(maLocation, maIcon); +} + + + + +void InsertionIndicatorOverlay::SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator) +{ + mpLayerInvalidator = rpInvalidator; + + if (mbIsVisible && mpLayerInvalidator) + mpLayerInvalidator->Invalidate(GetBoundingBox()); +} + + + + +bool InsertionIndicatorOverlay::IsVisible (void) const +{ + return mbIsVisible; +} + + + + +void InsertionIndicatorOverlay::Show (void) +{ + if ( ! mbIsVisible) + { + mbIsVisible = true; + + ::boost::shared_ptr pLayeredDevice ( + mrSlideSorter.GetView().GetLayeredDevice()); + if (pLayeredDevice) + { + pLayeredDevice->RegisterPainter(shared_from_this(), mnLayerIndex); + if (mpLayerInvalidator) + mpLayerInvalidator->Invalidate(GetBoundingBox()); + } + } +} + + + + +void InsertionIndicatorOverlay::Hide (void) +{ + if (mbIsVisible) + { + mbIsVisible = false; + + ::boost::shared_ptr pLayeredDevice ( + mrSlideSorter.GetView().GetLayeredDevice()); + if (pLayeredDevice) + { + if (mpLayerInvalidator) + mpLayerInvalidator->Invalidate(GetBoundingBox()); + pLayeredDevice->RemovePainter(shared_from_this(), mnLayerIndex); + } + } +} + + + + +Rectangle InsertionIndicatorOverlay::GetBoundingBox (void) const +{ + return Rectangle(maLocation, maIcon.GetSizePixel()); +} + + + + +Size InsertionIndicatorOverlay::GetSize (void) const +{ + return Size( + maIcon.GetSizePixel().Width() + 10, + maIcon.GetSizePixel().Height() + 10); +} + + + +} } } // end of namespace ::sd::slidesorter::view + diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx index 3441b30d6739..405da65cb8eb 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx @@ -91,6 +91,7 @@ private: }; + } } } // end of namespace ::sd::slidesorter::view #endif diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 5651e21a7696..1ed176d0fcae 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -54,10 +54,12 @@ Layouter::Layouter (const SharedSdWindow& rpWindow) mnPreferredWidth(200), mnMaximalWidth(300), mnMinimalColumnCount(1), - mnMaximalColumnCount(1), + mnMaximalColumnCount(4), mnPageCount(0), mnColumnCount(1), mnRowCount(0), + mnMaxColumnCount(0), + mnMaxRowCount(0), maPageObjectSize(1,1), mbIsVertical(true) { @@ -211,6 +213,10 @@ bool Layouter::RearrangeHorizontal ( nPageCount)); maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); + mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) + / (maPageObjectSize.Width() + mnHorizontalGap); + mnMaxRowCount = 1; + return true; } else @@ -289,6 +295,11 @@ bool Layouter::RearrangeVertical ( nPageCount)); maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); + mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) + / (maPageObjectSize.Width() + mnHorizontalGap); + mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) + / (maPageObjectSize.Height() + mnVerticalGap); + return true; } else @@ -462,15 +473,54 @@ Rectangle Layouter::GetPreviewBox (const sal_Int32 nIndex) const -Point Layouter::GetInsertionIndicatorLocation ( - const Pair& rVisualIndices, - const Size& rIndicatorSize) const +InsertPosition Layouter::GetInsertPosition ( + const Point& rModelPosition, + const Size& rIndicatorSize) const { - if (rVisualIndices.B() < 0) + InsertPosition aPosition; + + // Determine logical position. + if (mnColumnCount == 1) + { + const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; + const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); + aPosition.mnRow = ::std::min(mnPageCount, nY / nRowHeight); + aPosition.mnColumn = 0; + aPosition.mnIndex = aPosition.mnRow; + aPosition.mbIsAtRunStart = (aPosition.mnRow == 0); + aPosition.mbIsAtRunEnd = (aPosition.mnRow == mnRowCount); + aPosition.mbIsExtraSpaceNeeded = (aPosition.mnRow >= mnMaxRowCount); + } + else + { + aPosition.mnRow = ::std::min( + mnRowCount-1, + GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH)); + + const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; + const sal_Int32 nRowWidth (maPageObjectSize.Width() + mnHorizontalGap); + aPosition.mnColumn = ::std::min(mnColumnCount, nX / nRowWidth); + aPosition.mnIndex = aPosition.mnRow * mnColumnCount + aPosition.mnColumn; + + aPosition.mbIsAtRunStart = (aPosition.mnColumn == 0); + aPosition.mbIsAtRunEnd = (aPosition.mnColumn == mnColumnCount); + + if (aPosition.mnIndex >= mnPageCount) + { + aPosition.mnIndex = mnPageCount; + aPosition.mnRow = mnRowCount-1; + aPosition.mnColumn = mnPageCount%mnColumnCount; + aPosition.mbIsAtRunEnd = true; + } + aPosition.mbIsExtraSpaceNeeded = (aPosition.mnColumn >= mnMaxColumnCount); + } + + // Determine visual position. + if (mnColumnCount == 1) { // Place indicator between rows of a single column of pages. - if (rVisualIndices.A() == 0) + if (aPosition.mbIsAtRunStart) { // Place indicator at the top of the column. const Rectangle aOuterBox (GetPageObjectBox(0)); @@ -478,71 +528,95 @@ Point Layouter::GetInsertionIndicatorLocation ( aOuterBox.TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); - return Point(aPreviewBox.Center().X(), aOuterBox.Top()+rIndicatorSize.Height()/2); + aPosition.maLocation.X() = aPreviewBox.Center().X(); + aPosition.maLocation.Y() = aOuterBox.Top()+rIndicatorSize.Height()/2; } - else if (rVisualIndices.A() == mnRowCount) + else if (aPosition.mbIsAtRunEnd) { - // Place indicator at the bottom of the column. const Rectangle aOuterBox (GetPageObjectBox(mnRowCount-1)); const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( aOuterBox.TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); - return Point(aPreviewBox.Center().X(), aOuterBox.Bottom()-rIndicatorSize.Height()/2); + if (aPosition.mbIsExtraSpaceNeeded) + { + // Place indicator at the bottom of the column. + aPosition.maLocation.X() = aPreviewBox.Center().X(); + aPosition.maLocation.Y() = aOuterBox.Bottom()-rIndicatorSize.Height()/2; + } + else + { + // Place indicator at the bottom of the column in the space + // that is available below the last page. + aPosition.maLocation.X() = aPreviewBox.Center().X(); + aPosition.maLocation.Y() = aOuterBox.Bottom()+rIndicatorSize.Height()/2; + } } else { // Place indicator between two rows. const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(rVisualIndices.A()-1).TopLeft(), + GetPageObjectBox(aPosition.mnRow-1).TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(rVisualIndices.A()).TopLeft(), + GetPageObjectBox(aPosition.mnRow).TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); - return (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; + aPosition.maLocation = (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; } } else { // Place indicator between columns in one row. - const sal_Int32 nIndex (rVisualIndices.A() * mnColumnCount + rVisualIndices.B()); - - if (rVisualIndices.B() == 0) + if (aPosition.mbIsAtRunStart) { // Place indicator at the left of the row. - const Rectangle aOuterBox (GetPageObjectBox(nIndex)); + const Rectangle aOuterBox (GetPageObjectBox(aPosition.mnIndex)); const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( aOuterBox.TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); - return Point(aOuterBox.Left()+rIndicatorSize.Width()/2, aPreviewBox.Center().Y()); + aPosition.maLocation.X() = aOuterBox.Left()+rIndicatorSize.Width()/2; + aPosition.maLocation.Y() = aPreviewBox.Center().Y(); } - else if (rVisualIndices.B() == mnColumnCount) + else if (aPosition.mbIsAtRunEnd) { - // Place indicator at the end of the row. - const Rectangle aOuterBox (GetPageObjectBox(nIndex-1)); + const Rectangle aOuterBox (GetPageObjectBox(aPosition.mnIndex-1)); const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( aOuterBox.TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); - return Point(aOuterBox.Right()-rIndicatorSize.Width()/2, aPreviewBox.Center().Y()); + if (aPosition.mbIsExtraSpaceNeeded) + { + // Place indicator at the end of the row. + aPosition.maLocation.X() = aOuterBox.Right()-rIndicatorSize.Width()/2; + aPosition.maLocation.Y() = aPreviewBox.Center().Y(); + } + else + { + // Place indicator at the end of the row in the available + // space at its right end. + aPosition.maLocation.X() = aOuterBox.Right()+rIndicatorSize.Width()/2; + aPosition.maLocation.Y() = aPreviewBox.Center().Y(); + } } else { // Place indicator between two columns. const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(nIndex-1).TopLeft(), + GetPageObjectBox(aPosition.mnIndex-1).TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(nIndex).TopLeft(), + GetPageObjectBox(aPosition.mnIndex).TopLeft(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); - return (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; + aPosition.maLocation = (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; } } + + return aPosition; } @@ -581,31 +655,6 @@ sal_Int32 Layouter::GetIndexAtPoint ( -sal_Int32 Layouter::GetVerticalInsertionIndex (const Point& rPosition) const -{ - OSL_ASSERT(mnColumnCount == 1); - - const sal_Int32 nY = rPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; - const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); - return nY / nRowHeight; -} - - - - -Pair Layouter::GetGridInsertionIndices (const Point& rPosition) const -{ - const sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), true, GM_BOTH); - - const sal_Int32 nX = rPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; - const sal_Int32 nRowWidth (maPageObjectSize.Width() + mnHorizontalGap); - - return Pair(nRow, nX / nRowWidth); -} - - - - bool Layouter::IsVertical (void) const { return mbIsVertical; @@ -753,4 +802,59 @@ sal_Int32 Layouter::ResolvePositionInGap ( +//===== InsertPosition ======================================================== + +InsertPosition::InsertPosition (void) + : mnRow(-1), + mnColumn(-1), + mnIndex(-1), + maLocation(0,0), + mbIsAtRunStart(false), + mbIsAtRunEnd(false), + mbIsExtraSpaceNeeded(false) +{ +} + + + + +InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition) +{ + if (this != &rInsertPosition) + { + mnRow = rInsertPosition.mnRow; + mnColumn = rInsertPosition.mnColumn; + mnIndex = rInsertPosition.mnIndex; + maLocation = rInsertPosition.maLocation; + mbIsAtRunStart = rInsertPosition.mbIsAtRunStart; + mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd; + mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded; + } + return *this; +} + + + + +bool InsertPosition::operator== (const InsertPosition& rInsertPosition) const +{ + // Do not compare the geometrical information (maLocation). + return mnRow==rInsertPosition.mnRow + && mnColumn==rInsertPosition.mnColumn + && mnIndex==rInsertPosition.mnIndex + && mbIsAtRunStart==rInsertPosition.mbIsAtRunStart + && mbIsAtRunEnd==rInsertPosition.mbIsAtRunEnd + && mbIsExtraSpaceNeeded==rInsertPosition.mbIsExtraSpaceNeeded; +} + + + + +bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const +{ + return !operator==(rInsertPosition); +} + + + } } } // 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 e417dba20882..83ebcdaeb08c 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -287,14 +287,14 @@ void PageObjectPainter::PaintPreview ( if (rpDescriptor->GetVisualState().GetCurrentVisualState() == model::VisualState::VS_Excluded) { - rDevice.SetFillColor(COL_BLACK); + rDevice.SetFillColor(COL_GRAY); rDevice.SetLineColor(); rDevice.DrawTransparent( ::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect( ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right()+1, aBox.Bottom()+1), 0, 0)), - 0.5); + 0.3); } } @@ -506,11 +506,6 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( Rectangle aFrameBox (aBox.Left()-1,aBox.Top()-1,aBox.Right()+1,aBox.Bottom()+1); mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox); - // Clear the area where the preview will later be painted. - aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::PageBackground)); - aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::PageBackground)); - aBitmapDevice.DrawRect(aBox); - return aBitmapDevice.GetBitmap (Point(0,0),aSize); } diff --git a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx deleted file mode 100644 index c09c076cd807..000000000000 --- a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx +++ /dev/null @@ -1,718 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: SlsViewOverlay.cxx,v $ - * $Revision: 1.16 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "precompiled_sd.hxx" - -#include "view/SlsViewOverlay.hxx" - -#include "SlideSorter.hxx" -#include "SlideSorterViewShell.hxx" -#include "SlsLayeredDevice.hxx" -#include "SlsFramePainter.hxx" -#include "model/SlideSorterModel.hxx" -#include "model/SlsPageDescriptor.hxx" -#include "model/SlsPageEnumeration.hxx" -#include "view/SlideSorterView.hxx" -#include "view/SlsLayouter.hxx" -#include "view/SlsTheme.hxx" -#include "cache/SlsPageCache.hxx" -#include "ViewShell.hxx" -#include "ViewShellBase.hxx" -#include "UpdateLockManager.hxx" - -#include "Window.hxx" -#include "sdpage.hxx" -#include "sdresid.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace ::sdr::overlay; -using namespace ::basegfx; - -#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) - -namespace { - -#define Amber 0x007fff - -static const double gnPreviewOffsetScale = 1.0 / 8.0; - - - -Rectangle GrowRectangle (const Rectangle& rBox, const sal_Int32 nOffset) -{ - return Rectangle ( - rBox.Left() - nOffset, - rBox.Top() - nOffset, - rBox.Right() + nOffset, - rBox.Bottom() + nOffset); -} - -Rectangle ConvertRectangle (const B2DRectangle& rBox) -{ - const B2IRange rIntegerBox (unotools::b2ISurroundingRangeFromB2DRange(rBox)); - return Rectangle( - rIntegerBox.getMinX(), - rIntegerBox.getMinY(), - rIntegerBox.getMaxX(), - rIntegerBox.getMaxY()); -} - -sal_Int32 RoundToInt (const double nValue) { return sal_Int32(::rtl::math::round(nValue)); } - -} // end of anonymous namespace - - -namespace sd { namespace slidesorter { namespace view { - - -//===== ViewOverlay ========================================================= - -ViewOverlay::ViewOverlay ( - SlideSorter& rSlideSorter, - const ::boost::shared_ptr& rpLayeredDevice) - : mrSlideSorter(rSlideSorter), - mpLayeredDevice(rpLayeredDevice), - mpSelectionRectangleOverlay(new SelectionRectangleOverlay(*this, 3)), - mpInsertionIndicatorOverlay(new InsertionIndicatorOverlay(*this, 4)), - mpSubstitutionOverlay(new SubstitutionOverlay(*this, 3)) -{ -} - - - - -ViewOverlay::~ViewOverlay (void) -{ -} - - - - -::boost::shared_ptr ViewOverlay::GetSelectionRectangleOverlay (void) -{ - return mpSelectionRectangleOverlay; -} - - - - -::boost::shared_ptr ViewOverlay::GetInsertionIndicatorOverlay (void) -{ - return mpInsertionIndicatorOverlay; -} - - - - -::boost::shared_ptr ViewOverlay::GetSubstitutionOverlay (void) -{ - return mpSubstitutionOverlay; -} - - - - -SlideSorter& ViewOverlay::GetSlideSorter (void) const -{ - return mrSlideSorter; -} - - - - -::boost::shared_ptr ViewOverlay::GetLayeredDevice (void) const -{ - return mpLayeredDevice; -} - - - - -//===== OverlayBase::Invalidator ============================================== - -class OverlayBase::Invalidator -{ -public: - Invalidator (OverlayBase& rOverlayObject) - : mrOverlayObject(rOverlayObject), - maOldBoundingBox(rOverlayObject.IsVisible() - ? rOverlayObject.GetBoundingBox() - : Rectangle()) - { - } - - ~Invalidator (void) - { - if ( ! maOldBoundingBox.IsEmpty()) - mrOverlayObject.Invalidate(maOldBoundingBox); - if (mrOverlayObject.IsVisible()) - mrOverlayObject.Invalidate(mrOverlayObject.GetBoundingBox()); - } - -private: - OverlayBase& mrOverlayObject; - const Rectangle maOldBoundingBox; -}; - - - - -//===== OverlayBase ========================================================= - -OverlayBase::OverlayBase ( - ViewOverlay& rViewOverlay, - const sal_Int32 nLayerIndex) - : mrViewOverlay(rViewOverlay), - mbIsVisible(false), - mnLayerIndex(nLayerIndex) -{ -} - - - - -OverlayBase::~OverlayBase (void) -{ -} - - - - -bool OverlayBase::IsVisible (void) const -{ - return mbIsVisible; -} - - - - -void OverlayBase::SetIsVisible (const bool bIsVisible) -{ - if (mbIsVisible != bIsVisible) - { - Invalidator aInvalidator (*this); - mbIsVisible = bIsVisible; - - ::boost::shared_ptr pDevice (mrViewOverlay.GetLayeredDevice()); - if (pDevice) - if (mbIsVisible) - { - pDevice->RegisterPainter(shared_from_this(), GetLayerIndex()); - Invalidate(GetBoundingBox()); - } - else - { - Invalidate(GetBoundingBox()); - pDevice->RemovePainter(shared_from_this(), GetLayerIndex()); - } - } - } - - - - -void OverlayBase::SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator) -{ - if ( ! rpInvalidator) - Invalidate(GetBoundingBox()); - - mpLayerInvalidator = rpInvalidator; - - if (mbIsVisible) - Invalidate(GetBoundingBox()); -} - - - - -void OverlayBase::Invalidate (const Rectangle& rInvalidationBox) -{ - if (mpLayerInvalidator) - mpLayerInvalidator->Invalidate(rInvalidationBox); -} - - - - -sal_Int32 OverlayBase::GetLayerIndex (void) const -{ - return mnLayerIndex; -} - - - - -//===== SubstitutionOverlay ================================================= - -const sal_Int32 SubstitutionOverlay::mnCenterTransparency (60); -const sal_Int32 SubstitutionOverlay::mnSideTransparency (85); -const sal_Int32 SubstitutionOverlay::mnCornerTransparency (95); - -SubstitutionOverlay::SubstitutionOverlay ( - ViewOverlay& rViewOverlay, - const sal_Int32 nLayerIndex) - : OverlayBase(rViewOverlay, nLayerIndex), - maPosition(0,0) -{ -} - - - - -SubstitutionOverlay::~SubstitutionOverlay (void) -{ -} - - - - -void SubstitutionOverlay::Clear (void) -{ - SetIsVisible(false); -} - - - - -void SubstitutionOverlay::SetAnchor (const Point& rAnchor) -{ - (void)rAnchor; -} - - - - -void SubstitutionOverlay::Move (const Point& rOffset) -{ - (void)rOffset; -} - - - - -void SubstitutionOverlay::SetPosition (const Point& rPosition) -{ - (void)rPosition; -} - - - - -Point SubstitutionOverlay::GetPosition (void) const -{ - return Point(0,0); -} - - - - -void SubstitutionOverlay::Paint ( - OutputDevice& rDevice, - const Rectangle& rRepaintArea) -{ - (void)rDevice; - (void)rRepaintArea; -} - - - - -Rectangle SubstitutionOverlay::GetBoundingBox (void) const -{ - return Rectangle(); -} - - - - -//===== SelectionRectangleOverlay =========================================== - -SelectionRectangleOverlay::SelectionRectangleOverlay ( - ViewOverlay& rViewOverlay, - const sal_Int32 nLayerIndex) - : OverlayBase (rViewOverlay, nLayerIndex), - maAnchor(0,0), - maSecondCorner(0,0) -{ -} - - - -Rectangle SelectionRectangleOverlay::GetSelectionRectangle (void) -{ - return Rectangle(maAnchor, maSecondCorner); -} - - - - -void SelectionRectangleOverlay::Start (const Point& rAnchor) -{ - SetIsVisible(false); - maAnchor = rAnchor; - maSecondCorner = rAnchor; -} - - - - -void SelectionRectangleOverlay::Update (const Point& rSecondCorner) -{ - Invalidator aInvalidator (*this); - - maSecondCorner = rSecondCorner; - SetIsVisible(true); -} - - - - -void SelectionRectangleOverlay::Paint ( - OutputDevice& rDevice, - const Rectangle& rRepaintArea) -{ - if ( ! IsVisible()) - return; - - rDevice.SetFillColor(Color(Amber)); - rDevice.SetLineColor(Color(Amber)); - - const Rectangle aBox ( - ::std::min(maAnchor.X(), maSecondCorner.X()), - ::std::min(maAnchor.Y(), maSecondCorner.Y()), - ::std::max(maAnchor.X(), maSecondCorner.X()), - ::std::max(maAnchor.Y(), maSecondCorner.Y())); - if (rRepaintArea.IsOver(aBox)) - rDevice.DrawTransparent( - ::basegfx::B2DPolyPolygon( - ::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), - 5.0/aBox.GetWidth(), - 5.0/aBox.GetHeight())), - 0.5); -} - - - - -Rectangle SelectionRectangleOverlay::GetBoundingBox (void) const -{ - return GrowRectangle(Rectangle( - ::std::min(maAnchor.X(), maSecondCorner.X()), - ::std::min(maAnchor.Y(), maSecondCorner.Y()), - ::std::max(maAnchor.X(), maSecondCorner.X()), - ::std::max(maAnchor.Y(), maSecondCorner.Y())), - +1); -} - - - - -//===== InsertionIndicatorOverlay =========================================== - -const static sal_Int32 gnShadowBorder = 3; - -InsertionIndicatorOverlay::InsertionIndicatorOverlay ( - ViewOverlay& rViewOverlay, - const sal_Int32 nLayerIndex) - : OverlayBase (rViewOverlay, nLayerIndex), - maLocation(), - maIcon(), - mpShadowPainter(new FramePainter( - rViewOverlay.GetSlideSorter().GetTheme()->GetIcon(Theme::RawInsertShadow))) -{ -} - - - - -void InsertionIndicatorOverlay::Create (model::PageEnumeration& rSelection) -{ - view::Layouter& rLayouter (mrViewOverlay.GetSlideSorter().GetView().GetLayouter()); - ::boost::shared_ptr pPageObjectLayouter ( - rLayouter.GetPageObjectLayouter()); - ::boost::shared_ptr pTheme (mrViewOverlay.GetSlideSorter().GetTheme()); - const Size aOriginalPreviewSize (pPageObjectLayouter->GetPreviewSize()); - - const double nPreviewScale (0.5); - const Size aPreviewSize ( - RoundToInt(aOriginalPreviewSize.Width()*nPreviewScale), - RoundToInt(aOriginalPreviewSize.Height()*nPreviewScale)); - const sal_Int32 nOffset ( - RoundToInt(Min(aPreviewSize.Width(),aPreviewSize.Height()) * gnPreviewOffsetScale)); - - ::std::vector aDescriptors; - SelectRepresentatives(rSelection, aDescriptors); - - // Determine size and offset depending on the number of previews. - sal_Int32 nCount (aDescriptors.size()); - if (nCount > 0) - --nCount; - Size aIconSize( - aPreviewSize.Width() + 2 * gnShadowBorder + nCount*nOffset, - aPreviewSize.Height() + 2 * gnShadowBorder + nCount*nOffset); - maIconOffset = Point(gnShadowBorder, gnShadowBorder); - - // Create virtual devices for bitmap and mask whose bitmaps later be - // combined to form the BitmapEx of the icon. - VirtualDevice aContent ( - *mrViewOverlay.GetSlideSorter().GetContentWindow(), - 0, - 0); - aContent.SetOutputSizePixel(aIconSize); - - aContent.SetFillColor(); - aContent.SetLineColor(pTheme->GetColor(Theme::PreviewBorder)); - const Point aOffset = PaintRepresentatives(aContent, aPreviewSize, nOffset, aDescriptors); - - PaintPageCount(aContent, rSelection, aPreviewSize, aOffset); - - maIcon = aContent.GetBitmapEx(Point(0,0), aIconSize); -} - - - - -void InsertionIndicatorOverlay::SelectRepresentatives ( - model::PageEnumeration& rSelection, - ::std::vector& rDescriptors) const -{ - sal_Int32 nCount (0); - while (rSelection.HasMoreElements()) - { - if (nCount++ >= 3) - break; - rDescriptors.push_back(rSelection.GetNextElement()); - } -} - - - - -Point InsertionIndicatorOverlay::PaintRepresentatives ( - OutputDevice& rContent, - const Size aPreviewSize, - const sal_Int32 nOffset, - const ::std::vector& rDescriptors) const -{ - const Point aOffset (0,rDescriptors.size()==1 ? -nOffset : 0); - - // Paint the pages. - Point aPageOffset (0,0); - double nTransparency (0); - for (sal_Int32 nIndex=2; nIndex>=0; --nIndex) - { - if (rDescriptors.size() <= nIndex) - continue; - switch(nIndex) - { - case 0 : - aPageOffset = Point(0, nOffset); - nTransparency = 0.85; - break; - case 1: - aPageOffset = Point(nOffset, 0); - nTransparency = 0.75; - break; - case 2: - aPageOffset = Point(2*nOffset, 2*nOffset); - nTransparency = 0.65; - break; - } - aPageOffset += aOffset; - aPageOffset.X() += gnShadowBorder; - aPageOffset.Y() += gnShadowBorder; - - ::boost::shared_ptr pPreviewCache ( - mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache()); - BitmapEx aPreview (pPreviewCache->GetPreviewBitmap(rDescriptors[nIndex]->GetPage())); - aPreview.Scale(aPreviewSize, BMP_SCALE_INTERPOLATE); - rContent.DrawBitmapEx(aPageOffset, aPreview); - - // Tone down the bitmap. The further back the darker it becomes. - Rectangle aBox ( - aPageOffset.X(), - aPageOffset.Y(), - aPageOffset.X()+aPreviewSize.Width()-1, - aPageOffset.Y()+aPreviewSize.Height()-1); - rContent.SetFillColor(COL_BLACK); - rContent.SetLineColor(); - rContent.DrawTransparent( - ::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right()+1, aBox.Bottom()+1), - 0, - 0)), - nTransparency); - - // Draw border around preview. - Rectangle aBorderBox (GrowRectangle(aBox, 1)); - rContent.SetLineColor(COL_GRAY); - rContent.SetFillColor(); - rContent.DrawRect(aBorderBox); - - // Draw shadow around preview. - mpShadowPainter->PaintFrame(rContent, aBorderBox); - } - - return aPageOffset; -} - - - - -void InsertionIndicatorOverlay::PaintPageCount ( - OutputDevice& rDevice, - model::PageEnumeration& rSelection, - const Size aPreviewSize, - const Point aFirstPageOffset) const -{ - // Paint the number of slides. - ::boost::shared_ptr pTheme (mrViewOverlay.GetSlideSorter().GetTheme()); - ::boost::shared_ptr pFont(Theme::GetFont(Theme::PageCountFont, rDevice)); - if (pFont) - { - // Count the elements in the selection and create a string for the - // result. - sal_Int32 nSelectionCount (0); - rSelection.Rewind(); - while (rSelection.HasMoreElements()) - { - rSelection.GetNextElement(); - ++nSelectionCount; - } - ::rtl::OUString sNumber (::rtl::OUString::valueOf(nSelectionCount)); - - // Determine the size of the (painted) text and create a bounding - // box that centers the text on the first preview. - rDevice.SetFont(*pFont); - Rectangle aTextBox; - rDevice.GetTextBoundRect(aTextBox, sNumber); - Point aTextOffset (aTextBox.TopLeft()); - Size aTextSize (aTextBox.GetSize()); - // Place text inside the first page preview. - Point aTextLocation(aFirstPageOffset); - // Center the text. - aTextLocation += Point( - (aPreviewSize.Width()-aTextBox.GetWidth())/2, - (aPreviewSize.Height()-aTextBox.GetHeight())/2); - aTextBox = Rectangle(aTextLocation, aTextSize); - - // Paint background, border and text. - static const sal_Int32 nBorder = 5; - rDevice.SetFillColor(pTheme->GetColor(Theme::Selection)); - rDevice.SetLineColor(pTheme->GetColor(Theme::Selection)); - rDevice.DrawRect(GrowRectangle(aTextBox, nBorder)); - - rDevice.SetFillColor(); - rDevice.SetLineColor(COL_WHITE); - rDevice.DrawRect(GrowRectangle(aTextBox, nBorder-1)); - - rDevice.SetTextColor(COL_WHITE); - rDevice.DrawText(aTextBox.TopLeft()-aTextOffset, sNumber); - } -} - - - - -void InsertionIndicatorOverlay::Create (void) -{ -} - - - - -void InsertionIndicatorOverlay::SetLocation (const Point& rLocation) -{ - const Point aTopLeft ( - rLocation - Point( - maIcon.GetSizePixel().Width()/2, - maIcon.GetSizePixel().Height()/2)); - if (maLocation != aTopLeft) - { - Invalidator aInvalidator (*this); - maLocation = aTopLeft; - } -} - - - - -void InsertionIndicatorOverlay::Paint ( - OutputDevice& rDevice, - const Rectangle& rRepaintArea) -{ - (void)rRepaintArea; - - if ( ! IsVisible()) - return; - - rDevice.DrawImage(maLocation, maIcon); -} - - - - -Rectangle InsertionIndicatorOverlay::GetBoundingBox (void) const -{ - return Rectangle(maLocation, maIcon.GetSizePixel()); -} - - - - -Size InsertionIndicatorOverlay::GetSize (void) const -{ - return Size( - maIcon.GetSizePixel().Width() + 10, - maIcon.GetSizePixel().Height() + 10); -} - - - -} } } // end of namespace ::sd::slidesorter::view - diff --git a/sd/source/ui/slidesorter/view/makefile.mk b/sd/source/ui/slidesorter/view/makefile.mk index 6e0d0cc0761f..a31137273ae2 100644 --- a/sd/source/ui/slidesorter/view/makefile.mk +++ b/sd/source/ui/slidesorter/view/makefile.mk @@ -57,13 +57,13 @@ SLOFILES = \ $(SLO)$/SlsFontProvider.obj \ $(SLO)$/SlsFramePainter.obj \ $(SLO)$/SlsInsertAnimator.obj \ + $(SLO)$/SlsInsertionIndicatorOverlay.obj\ $(SLO)$/SlsLayeredDevice.obj \ $(SLO)$/SlsLayouter.obj \ $(SLO)$/SlsPageObjectLayouter.obj \ $(SLO)$/SlsPageObjectPainter.obj \ $(SLO)$/SlsTheme.obj \ - $(SLO)$/SlsViewCacheContext.obj \ - $(SLO)$/SlsViewOverlay.obj + $(SLO)$/SlsViewCacheContext.obj # --- Tagets ------------------------------------------------------- diff --git a/sd/source/ui/toolpanel/TaskPaneViewShell.cxx b/sd/source/ui/toolpanel/TaskPaneViewShell.cxx index 287298fdca9b..21178592c952 100644 --- a/sd/source/ui/toolpanel/TaskPaneViewShell.cxx +++ b/sd/source/ui/toolpanel/TaskPaneViewShell.cxx @@ -90,7 +90,7 @@ #include "TestPanel.hxx" #endif -#define SHOW_COLOR_MENU +//#define SHOW_COLOR_MENU #ifdef SHOW_COLOR_MENU #include "TestMenu.hxx" #endif