From 23a61a9969af9d099ce87d1169b7c2aeb5f6bb1e Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 27 Jan 2010 11:41:30 +0100 Subject: renaissance1: #i107215# First draft of the new slide sorter design. --- sd/inc/glob.hrc | 2 + .../accessibility/AccessibleSlideSorterObject.cxx | 11 +- .../configuration/ChangeRequestQueueProcessor.cxx | 3 +- .../configuration/ConfigurationUpdater.cxx | 2 +- sd/source/ui/inc/SlideSorter.hxx | 16 +- sd/source/ui/presenter/PresenterPreviewCache.cxx | 6 +- sd/source/ui/slideshow/slideshow.cxx | 2 +- sd/source/ui/slideshow/slideshowimpl.cxx | 2 + sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx | 8 +- .../ui/slidesorter/cache/SlsBitmapFactory.cxx | 24 +- .../ui/slidesorter/cache/SlsBitmapFactory.hxx | 3 +- .../ui/slidesorter/cache/SlsGenericPageCache.cxx | 44 +- .../ui/slidesorter/cache/SlsGenericPageCache.hxx | 33 +- sd/source/ui/slidesorter/cache/SlsPageCache.cxx | 25 +- .../ui/slidesorter/cache/SlsQueueProcessor.cxx | 9 +- .../ui/slidesorter/cache/SlsQueueProcessor.hxx | 8 +- .../controller/SlideSorterController.cxx | 130 +- .../controller/SlsAnimationFunction.cxx | 287 +++++ .../ui/slidesorter/controller/SlsAnimator.cxx | 165 ++- .../ui/slidesorter/controller/SlsClipboard.cxx | 46 +- .../controller/SlsCurrentSlideManager.cxx | 20 +- .../ui/slidesorter/controller/SlsFocusManager.cxx | 12 +- .../controller/SlsHideSlideFunction.cxx | 6 +- .../controller/SlsInsertionIndicatorHandler.cxx | 255 ++++ .../ui/slidesorter/controller/SlsListener.cxx | 32 +- .../ui/slidesorter/controller/SlsPageSelector.cxx | 16 +- .../ui/slidesorter/controller/SlsProperties.cxx | 2 +- .../slidesorter/controller/SlsScrollBarManager.cxx | 107 +- .../controller/SlsSelectionFunction.cxx | 1237 +++++++++++++------- .../slidesorter/controller/SlsSelectionManager.cxx | 86 +- .../ui/slidesorter/controller/SlsSlideFunction.cxx | 2 +- .../ui/slidesorter/controller/SlsSlotManager.cxx | 163 ++- sd/source/ui/slidesorter/controller/makefile.mk | 10 +- .../ui/slidesorter/inc/cache/SlsPageCache.hxx | 29 +- .../inc/controller/SlideSorterController.hxx | 16 +- .../inc/controller/SlsAnimationFunction.hxx | 178 +++ .../ui/slidesorter/inc/controller/SlsAnimator.hxx | 36 +- .../controller/SlsInsertionIndicatorHandler.hxx | 99 ++ .../inc/controller/SlsScrollBarManager.hxx | 16 +- .../inc/controller/SlsSelectionFunction.hxx | 77 +- .../inc/controller/SlsSelectionManager.hxx | 5 + .../ui/slidesorter/inc/model/SlideSorterModel.hxx | 27 +- .../ui/slidesorter/inc/model/SlsPageDescriptor.hxx | 101 +- .../ui/slidesorter/inc/model/SlsVisualState.hxx | 109 ++ .../ui/slidesorter/inc/view/SlideSorterView.hxx | 153 +-- .../ui/slidesorter/inc/view/SlsILayerPainter.hxx | 64 + .../ui/slidesorter/inc/view/SlsInsertAnimator.hxx | 64 + sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 146 +-- .../slidesorter/inc/view/SlsPageObjectLayouter.hxx | 178 +++ .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 90 ++ .../ui/slidesorter/inc/view/SlsViewOverlay.hxx | 176 +-- .../ui/slidesorter/model/SlideSorterModel.cxx | 102 +- .../ui/slidesorter/model/SlsPageDescriptor.cxx | 237 ++-- .../model/SlsPageEnumerationProvider.cxx | 4 +- sd/source/ui/slidesorter/model/SlsVisualState.cxx | 236 ++++ sd/source/ui/slidesorter/model/makefile.mk | 1 + sd/source/ui/slidesorter/shell/SlideSorter.cxx | 72 +- .../ui/slidesorter/shell/SlideSorterService.cxx | 49 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 9 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 840 +++++++------ sd/source/ui/slidesorter/view/SlsIcons.hrc | 45 + sd/source/ui/slidesorter/view/SlsIcons.hxx | 51 + sd/source/ui/slidesorter/view/SlsIcons.src | 65 + .../ui/slidesorter/view/SlsInsertAnimator.cxx | 465 ++++++++ sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 478 ++++++++ sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx | 118 ++ sd/source/ui/slidesorter/view/SlsLayouter.cxx | 533 ++++----- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 327 ++++++ .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 457 ++++++++ .../ui/slidesorter/view/SlsViewCacheContext.cxx | 24 +- .../ui/slidesorter/view/SlsViewCacheContext.hxx | 11 +- sd/source/ui/slidesorter/view/SlsViewOverlay.cxx | 601 +++++----- sd/source/ui/slidesorter/view/makefile.mk | 18 +- sd/source/ui/view/ViewShellManager.cxx | 2 +- sd/util/makefile.mk | 1 + 75 files changed, 6634 insertions(+), 2450 deletions(-) create mode 100644 sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx create mode 100644 sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx create mode 100644 sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx create mode 100644 sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx create mode 100644 sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx create mode 100644 sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx create mode 100644 sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx create mode 100644 sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx create mode 100644 sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx create mode 100644 sd/source/ui/slidesorter/model/SlsVisualState.cxx create mode 100644 sd/source/ui/slidesorter/view/SlsIcons.hrc create mode 100644 sd/source/ui/slidesorter/view/SlsIcons.hxx create mode 100644 sd/source/ui/slidesorter/view/SlsIcons.src create mode 100644 sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx create mode 100644 sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx create mode 100644 sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx create mode 100644 sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx create mode 100644 sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx diff --git a/sd/inc/glob.hrc b/sd/inc/glob.hrc index 7ef9ecad779c..2181f2dfeb30 100644 --- a/sd/inc/glob.hrc +++ b/sd/inc/glob.hrc @@ -154,5 +154,7 @@ #define STR_TABLEOBJECTBARSHELL RID_GLOB_START+225 #define RID_TABPAGE_PARA_NUMBERING RID_GLOB_START+226 +#define RID_SLIDESORTER_ICONS RID_GLOB_START+227 + diff --git a/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx b/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx index 2fd6cdb3cd39..41804bc8bdbc 100644 --- a/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx +++ b/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx @@ -40,6 +40,8 @@ #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" +#include "view/SlsLayouter.hxx" +#include "view/SlsPageObjectLayouter.hxx" #include #include #include @@ -392,10 +394,11 @@ awt::Rectangle SAL_CALL AccessibleSlideSorterObject::getBounds (void) const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - Rectangle aBBox (mrSlideSorter.GetView().GetPageBoundingBox ( - mnPageNumber, - ::sd::slidesorter::view::SlideSorterView::CS_SCREEN, - ::sd::slidesorter::view::SlideSorterView::BBT_INFO)); + Rectangle aBBox ( + mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox( + mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber), + ::sd::slidesorter::view::PageObjectLayouter::PageObject, + ::sd::slidesorter::view::PageObjectLayouter::ScreenCoordinateSystem)); if (mxParent.is()) { diff --git a/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx index 918aaacd0bd7..4739bda92151 100644 --- a/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx +++ b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx @@ -200,9 +200,10 @@ void ChangeRequestQueueProcessor::ProcessOneEvent (void) // its state. if (mpConfigurationUpdater.get() != NULL) { +#ifdef VERBOSE ConfigurationTracer::TraceConfiguration ( mxConfiguration, "updating to configuration"); - +#endif mpConfigurationUpdater->RequestUpdate(mxConfiguration); } } diff --git a/sd/source/ui/framework/configuration/ConfigurationUpdater.cxx b/sd/source/ui/framework/configuration/ConfigurationUpdater.cxx index e2aab7316937..5721f483595f 100644 --- a/sd/source/ui/framework/configuration/ConfigurationUpdater.cxx +++ b/sd/source/ui/framework/configuration/ConfigurationUpdater.cxx @@ -49,7 +49,7 @@ using ::rtl::OUString; using ::std::vector; #undef VERBOSE -#define VERBOSE 2 +//#define VERBOSE 2 namespace { static const sal_Int32 snShortTimeout (100); diff --git a/sd/source/ui/inc/SlideSorter.hxx b/sd/source/ui/inc/SlideSorter.hxx index 06bea31f8ff6..3e2c69232fe3 100644 --- a/sd/source/ui/inc/SlideSorter.hxx +++ b/sd/source/ui/inc/SlideSorter.hxx @@ -63,12 +63,12 @@ namespace sd { namespace slidesorter { namespace controller { class Listener; class SlideSorterController; class SlotManager; +class Properties; } } } namespace sd { namespace slidesorter { - /** Show previews for all the slides in a document and allow the user to insert or delete slides and modify the order of the slides. @@ -146,11 +146,6 @@ public: */ ::boost::shared_ptr GetContentWindow (void) const; - /** Return the active window as it is returned by a view shell. - Typically the content window. - */ - ::sd::Window* GetActiveWindow (void) const; - model::SlideSorterModel& GetModel (void) const; view::SlideSorterView& GetView (void) const; @@ -193,6 +188,11 @@ public: */ void SetCurrentFunction (const FunctionReference& rpFunction); + /** Return a collection of properties that are used througout the slide + sorter. + */ + ::boost::shared_ptr GetProperties (void) const; + protected: /** This virtual method makes it possible to create a specialization of the slide sorter view shell that works with its own implementation @@ -238,6 +238,10 @@ private: */ bool mbLayoutPending; + /** Some slide sorter wide properties that are used in different + classes. + */ + ::boost::shared_ptr mpProperties; SlideSorter ( ViewShell& rViewShell, diff --git a/sd/source/ui/presenter/PresenterPreviewCache.cxx b/sd/source/ui/presenter/PresenterPreviewCache.cxx index 798e2e3f211f..523097f53247 100644 --- a/sd/source/ui/presenter/PresenterPreviewCache.cxx +++ b/sd/source/ui/presenter/PresenterPreviewCache.cxx @@ -126,7 +126,7 @@ PresenterPreviewCache::PresenterPreviewCache (const Reference : PresenterPreviewCacheInterfaceBase(m_aMutex), maPreviewSize(Size(200,200)), mpCacheContext(new PresenterCacheContext()), - mpCache(new PageCache(maPreviewSize, mpCacheContext)) + mpCache(new PageCache(maPreviewSize, false, mpCacheContext)) { (void)rxContext; } @@ -191,7 +191,7 @@ void SAL_CALL PresenterPreviewCache::setPreviewSize ( OSL_ASSERT(mpCache.get()!=NULL); maPreviewSize = Size(rSize.Width, rSize.Height); - mpCache->ChangeSize(maPreviewSize); + mpCache->ChangeSize(maPreviewSize, false); } @@ -213,7 +213,7 @@ Reference SAL_CALL PresenterPreviewCache::getSlidePreview ( if (pPage == NULL) throw RuntimeException(); - const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage, maPreviewSize)); + const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage)); if (aPreview.IsEmpty()) return NULL; else diff --git a/sd/source/ui/slideshow/slideshow.cxx b/sd/source/ui/slideshow/slideshow.cxx index f1cb2cf4afb9..50db60c57e17 100644 --- a/sd/source/ui/slideshow/slideshow.cxx +++ b/sd/source/ui/slideshow/slideshow.cxx @@ -1181,9 +1181,9 @@ void SlideShow::StartFullscreenPresentation( ) // fullscreen. const sal_Int32 nDisplay (GetDisplay()); WorkWindow* pWorkWindow = new FullScreenWorkWindow(this, mpCurrentViewShellBase); + pWorkWindow->SetBackground(Wallpaper(COL_BLACK)); pWorkWindow->StartPresentationMode( TRUE, mpDoc->getPresentationSettings().mbAlwaysOnTop ? PRESENTATION_HIDEALLAPPS : 0, nDisplay); // pWorkWindow->ShowFullScreenMode(FALSE, nDisplay); - pWorkWindow->SetBackground(Wallpaper(COL_BLACK)); if (pWorkWindow->IsVisible()) { diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index e59f45b71e12..972e75a7f486 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -1221,9 +1221,11 @@ void SlideshowImpl::onFirstPaint() { if( mpShowWindow ) { + /* mpShowWindow->SetBackground( Wallpaper( Color( COL_BLACK ) ) ); mpShowWindow->Erase(); mpShowWindow->SetBackground(); + */ } ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx b/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx index 283c0e08cf62..fbdd09032a29 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx @@ -47,10 +47,10 @@ class BitmapCompressor; /** This low level cache is the actual bitmap container. It supports a precious flag for every preview bitmap and keeps track of total sizes - for all previews with as well as those without the flag. The precious - flag is used by compaction algorithms to determine which previews may be - compressed or even discarded and which have to remain in their original - form. The precious flag is usually set for the visible previews. + for all previews with/without this flag. The precious flag is used by + compaction algorithms to determine which previews may be compressed or + even discarded and which have to remain in their original form. The + precious flag is usually set for the visible previews. */ class BitmapCache { diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index 915daccecd50..82575d0bce11 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -37,7 +37,6 @@ #include "PreviewRenderer.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" #include "sdpage.hxx" #include "Window.hxx" #include @@ -52,7 +51,7 @@ class PageObjectViewObjectContact; namespace sd { namespace slidesorter { namespace cache { BitmapFactory::BitmapFactory (void) - : maRenderer(NULL,false) + : maRenderer(NULL, false) { } @@ -68,14 +67,23 @@ BitmapFactory::~BitmapFactory (void) ::boost::shared_ptr BitmapFactory::CreateBitmap ( const SdPage& rPage, - const Size& rPixelSize) + const Size& rPixelSize, + const bool bDoSuperSampling) { - Image aPreview (maRenderer.RenderPage ( - &rPage, - rPixelSize, - String())); + Size aSize (rPixelSize); + if (bDoSuperSampling) + { + aSize.Width() *= 2; + aSize.Height() *= 2; + } - return ::boost::shared_ptr(new BitmapEx(aPreview.GetBitmapEx())); + const Image aPreview (maRenderer.RenderPage (&rPage, aSize, String())); + + ::boost::shared_ptr pPreview (new BitmapEx(aPreview.GetBitmapEx())); + if (bDoSuperSampling) + pPreview->Scale(rPixelSize, BMP_SCALE_INTERPOLATE); + + return pPreview; } diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx index 5eca09bbaa8c..51d7d1c60f1b 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx @@ -56,7 +56,8 @@ public: ::boost::shared_ptr CreateBitmap ( const SdPage& rPage, - const Size& rPixelSize); + const Size& rPixelSize, + const bool bDoSuperSampling); private: PreviewRenderer maRenderer; diff --git a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx index 702517029fb6..ba1eb21e9ca6 100644 --- a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx +++ b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx @@ -41,20 +41,26 @@ #include "cache/SlsPageCacheManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" #include "controller/SlideSorterController.hxx" namespace sd { namespace slidesorter { namespace cache { GenericPageCache::GenericPageCache ( const Size& rPreviewSize, + const bool bDoSuperSampling, const SharedCacheContext& rpCacheContext) : mpBitmapCache(), maRequestQueue(rpCacheContext), mpQueueProcessor(), mpCacheContext(rpCacheContext), - maPreviewSize(rPreviewSize) + maPreviewSize(rPreviewSize), + mbDoSuperSampling(bDoSuperSampling) { + // A large size may indicate an error of the caller. After all we + // are creating previews. + DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000, + "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. " + "This may indicate an error."); } @@ -91,36 +97,44 @@ void GenericPageCache::ProvideCacheAndProcessor (void) maRequestQueue, mpBitmapCache, maPreviewSize, + mbDoSuperSampling, mpCacheContext)); } -void GenericPageCache::ChangePreviewSize (const Size& rPreviewSize) +void GenericPageCache::ChangePreviewSize ( + const Size& rPreviewSize, + const bool bDoSuperSampling) { - if (rPreviewSize != maPreviewSize) + if (rPreviewSize!=maPreviewSize || bDoSuperSampling!=mbDoSuperSampling) { + // A large size may indicate an error of the caller. After all we + // are creating previews. + DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000, + "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. " + "This may indicate an error."); + if (mpBitmapCache.get() != NULL) { mpBitmapCache = PageCacheManager::Instance()->ChangeSize( mpBitmapCache, maPreviewSize, rPreviewSize); if (mpQueueProcessor.get() != NULL) { - mpQueueProcessor->SetPreviewSize(rPreviewSize); + mpQueueProcessor->SetPreviewSize(rPreviewSize, bDoSuperSampling); mpQueueProcessor->SetBitmapCache(mpBitmapCache); } } maPreviewSize = rPreviewSize; + mbDoSuperSampling = bDoSuperSampling; } } -BitmapEx GenericPageCache::GetPreviewBitmap ( - CacheKey aKey, - const Size& rSize) +BitmapEx GenericPageCache::GetPreviewBitmap (CacheKey aKey) { OSL_ASSERT(aKey != NULL); @@ -134,17 +148,12 @@ BitmapEx GenericPageCache::GetPreviewBitmap ( OSL_ASSERT(pPreview.get() != NULL); aPreview = *pPreview; Size aBitmapSize (aPreview.GetSizePixel()); - if (aBitmapSize != rSize) + if (aBitmapSize != maPreviewSize) { - // The bitmap has the wrong size. - DBG_ASSERT (rSize.Width() < 1000, - "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. " - "This may indicate an error."); - // Scale the bitmap to the desired size when that is possible, // i.e. the bitmap is not empty. if (aBitmapSize.Width()>0 && aBitmapSize.Height()>0) - aPreview.Scale (rSize, BMP_SCALE_FAST); + aPreview.Scale (maPreviewSize, BMP_SCALE_FAST); } bMayBeUpToDate = true; } @@ -154,7 +163,7 @@ BitmapEx GenericPageCache::GetPreviewBitmap ( // Request the creation of a correctly sized preview bitmap. We do this // even when the size of the bitmap in the cache is correct because its // content may be not up-to-date anymore. - RequestPreviewBitmap(aKey, rSize, bMayBeUpToDate); + RequestPreviewBitmap(aKey, bMayBeUpToDate); return aPreview; } @@ -164,7 +173,6 @@ BitmapEx GenericPageCache::GetPreviewBitmap ( void GenericPageCache::RequestPreviewBitmap ( CacheKey aKey, - const Size& rSize, bool bMayBeUpToDate) { OSL_ASSERT(aKey != NULL); @@ -180,7 +188,7 @@ void GenericPageCache::RequestPreviewBitmap ( if (bIsUpToDate) { ::boost::shared_ptr pPreview (mpBitmapCache->GetBitmap(pPage)); - if (pPreview.get()==NULL || pPreview->GetSizePixel()!=rSize) + if (pPreview.get()==NULL || pPreview->GetSizePixel()!=maPreviewSize) bIsUpToDate = false; } diff --git a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx index d11c74c50839..7afa01a9b860 100644 --- a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx +++ b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx @@ -47,12 +47,18 @@ class QueueProcessor; class GenericPageCache { public: - /** The page chache is created with references both to the SlideSorter. - This allows access to both view and model and the cache can so fill - itself with requests for all or just the visible pages. + /** The page chache is created with a reference to the SlideSorter and + thus has access to both view and model. This allows the cache to + fill itself with requests for all pages or just the visible ones. + @param rPreviewSize + The size of the previews is expected in pixel values. + @param bDoSuperSampling + When the previews are rendered larger and then scaled + down to the requested size to improve image quality. */ GenericPageCache ( const Size& rPreviewSize, + const bool bDoSuperSampling, const SharedCacheContext& rpCacheContext); ~GenericPageCache (void); @@ -61,10 +67,12 @@ public: resize of the slide sorter window or a change of the number of columns. */ - void ChangePreviewSize (const Size& rPreviewSize); + void ChangePreviewSize ( + const Size& rPreviewSize, + const bool bDoSuperSampling); /** Request a preview bitmap for the specified page object in the - specified size. The returned bitmap may be preview of the preview, + specified size. The returned bitmap may be a preview of the preview, i.e. either a scaled (up or down) version of a previous preview (of the wrong size) or an empty bitmap. In this case a request for the generation of a new preview is created and inserted into the request @@ -73,33 +81,26 @@ public: receives the correctly sized preview bitmap. @param rRequestData This data is used to determine the preview. - @param rSize - The size of the requested preview bitmap. @return Returns a bitmap that is either empty, contains a scaled (up or down) version or is the requested bitmap. */ - BitmapEx GetPreviewBitmap ( - CacheKey aKey, - const Size& rSize); + BitmapEx GetPreviewBitmap (CacheKey aKey); /** When the requested preview bitmap does not yet exist or is not up-to-date then the rendering of one is scheduled. Otherwise this method does nothing. @param rRequestData This data is used to determine the preview. - @param rSize - The size of the requested preview bitmap in pixel coordinates. @param bMayBeUpToDate This flag helps the method to determine whether an existing preview that matches the request is up to date. If the caller - know that it is not then by passing he tells us that we + knows that it is not then by passing he tells us that we do not have to check the up-to-date flag a second time. If - unsure pass . + unsure use . */ void RequestPreviewBitmap ( CacheKey aKey, - const Size& rSize, bool bMayBeUpToDate = true); /** Tell the cache to replace the bitmap associated with the given @@ -147,6 +148,8 @@ private: */ Size maPreviewSize; + bool mbDoSuperSampling; + /** Both bitmap cache and queue processor are created on demand by this method. */ diff --git a/sd/source/ui/slidesorter/cache/SlsPageCache.cxx b/sd/source/ui/slidesorter/cache/SlsPageCache.cxx index 1f9c7b1ccbd6..0e0b7e2f01c4 100644 --- a/sd/source/ui/slidesorter/cache/SlsPageCache.cxx +++ b/sd/source/ui/slidesorter/cache/SlsPageCache.cxx @@ -48,10 +48,12 @@ namespace sd { namespace slidesorter { namespace cache { PageCache::PageCache ( const Size& rPreviewSize, + const bool bDoSuperSampling, const SharedCacheContext& rpCacheContext) : mpImplementation( new GenericPageCache( rPreviewSize, + bDoSuperSampling, rpCacheContext)) { } @@ -66,38 +68,39 @@ PageCache::~PageCache (void) -void PageCache::ChangeSize(const Size& rPreviewSize) +void PageCache::ChangeSize ( + const Size& rPreviewSize, + const bool bDoSuperSampling) { - mpImplementation->ChangePreviewSize(rPreviewSize); + mpImplementation->ChangePreviewSize(rPreviewSize, bDoSuperSampling); } -BitmapEx PageCache::GetPreviewBitmap ( - CacheKey aKey, - const Size& rSize) +BitmapEx PageCache::GetPreviewBitmap (CacheKey aKey) { - return mpImplementation->GetPreviewBitmap(aKey, rSize); + return mpImplementation->GetPreviewBitmap(aKey); } -void PageCache::RequestPreviewBitmap ( - CacheKey aKey, - const Size& rSize) +void PageCache::RequestPreviewBitmap (CacheKey aKey) { - return mpImplementation->RequestPreviewBitmap(aKey, rSize); + return mpImplementation->RequestPreviewBitmap(aKey); } void PageCache::InvalidatePreviewBitmap ( - CacheKey aKey) + const CacheKey aKey, + const bool bRequestPreview) { mpImplementation->InvalidatePreviewBitmap(aKey); + if (bRequestPreview) + RequestPreviewBitmap(aKey); } diff --git a/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx b/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx index 09c633424c6d..16c49c48f23f 100644 --- a/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx +++ b/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx @@ -44,6 +44,7 @@ QueueProcessor::QueueProcessor ( RequestQueue& rQueue, const ::boost::shared_ptr& rpCache, const Size& rPreviewSize, + const bool bDoSuperSampling, const SharedCacheContext& rpCacheContext) : maMutex(), maTimer(), @@ -51,6 +52,7 @@ QueueProcessor::QueueProcessor ( mnTimeBetweenLowPriorityRequests (100/*ms*/), mnTimeBetweenRequestsWhenNotIdle (1000/*ms*/), maPreviewSize(rPreviewSize), + mbDoSuperSampling(bDoSuperSampling), mpCacheContext(rpCacheContext), mrQueue(rQueue), mpCache(rpCache), @@ -140,9 +142,12 @@ void QueueProcessor::Terminate (void) -void QueueProcessor::SetPreviewSize (const Size& rPreviewSize) +void QueueProcessor::SetPreviewSize ( + const Size& rPreviewSize, + const bool bDoSuperSampling) { maPreviewSize = rPreviewSize; + mbDoSuperSampling = bDoSuperSampling; } @@ -212,7 +217,7 @@ void QueueProcessor::ProcessOneRequest ( if (pSdPage != NULL) { const ::boost::shared_ptr pPreview ( - maBitmapFactory.CreateBitmap(*pSdPage, maPreviewSize)); + maBitmapFactory.CreateBitmap(*pSdPage, maPreviewSize, mbDoSuperSampling)); mpCache->SetBitmap ( pSdPage, pPreview, diff --git a/sd/source/ui/slidesorter/cache/SlsQueueProcessor.hxx b/sd/source/ui/slidesorter/cache/SlsQueueProcessor.hxx index f7f8a36190cd..53e9eb71f34b 100644 --- a/sd/source/ui/slidesorter/cache/SlsQueueProcessor.hxx +++ b/sd/source/ui/slidesorter/cache/SlsQueueProcessor.hxx @@ -34,9 +34,7 @@ #include "cache/SlsPageCache.hxx" #include "SlsRequestPriorityClass.hxx" #include "SlsBitmapFactory.hxx" -#include "view/SlsPageObject.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" #include "tools/IdleDetection.hxx" #include "SlsBitmapCache.hxx" #include "sdpage.hxx" @@ -74,6 +72,7 @@ public: RequestQueue& rQueue, const ::boost::shared_ptr& rpCache, const Size& rPreviewSize, + const bool bDoSuperSampling, const SharedCacheContext& rpCacheContext); virtual ~QueueProcessor(); @@ -93,7 +92,9 @@ public: void Terminate (void); - void SetPreviewSize (const Size& rSize); + void SetPreviewSize ( + const Size& rSize, + const bool bDoSuperSampling); /** As we can not really terminate the rendering of a preview bitmap for a request in midair this method acts more like a semaphor. It @@ -121,6 +122,7 @@ private: sal_uInt32 mnTimeBetweenLowPriorityRequests; sal_uInt32 mnTimeBetweenRequestsWhenNotIdle; Size maPreviewSize; + bool mbDoSuperSampling; SharedCacheContext mpCacheContext; RequestQueue& mrQueue; ::boost::shared_ptr mpCache; diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 5303b9dc6426..98d6ca4afee9 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -42,8 +42,8 @@ #include "SlsSelectionCommand.hxx" #include "controller/SlsAnimator.hxx" #include "controller/SlsClipboard.hxx" +#include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsScrollBarManager.hxx" -#include "controller/SlsPageObjectFactory.hxx" #include "controller/SlsSelectionManager.hxx" #include "controller/SlsSlotManager.hxx" #include "model/SlideSorterModel.hxx" @@ -53,6 +53,7 @@ #include "view/SlsLayouter.hxx" #include "view/SlsViewOverlay.hxx" #include "view/SlsFontProvider.hxx" +#include "view/SlsPageObjectLayouter.hxx" #include "cache/SlsPageCache.hxx" #include "cache/SlsPageCacheManager.hxx" @@ -101,6 +102,7 @@ using namespace ::com::sun::star::uno; using namespace ::sd::slidesorter::model; using namespace ::sd::slidesorter::view; using namespace ::sd::slidesorter::controller; +using namespace ::basegfx; namespace sd { namespace slidesorter { namespace controller { @@ -116,6 +118,7 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) mpScrollBarManager(), mpCurrentSlideManager(), mpSelectionManager(), + mpInsertionIndicatorHandler(new InsertionIndicatorHandler(rSlideSorter)), mpAnimator(new Animator(rSlideSorter)), mpListener(), mnModelChangeLockCount(0), @@ -126,12 +129,11 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) mpEditModeChangeMasterPage(NULL), maTotalWindowArea(), mnPaintEntranceCount(0), - mbIsContextMenuOpen(false), - mpProperties(new Properties()) + mbIsContextMenuOpen(false) { - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - OSL_ASSERT(pWindow!=NULL); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + OSL_ASSERT(pWindow); + if (pWindow) { // The whole background is painted by the view and controls. ::Window* pParentWindow = pWindow->GetParent(); @@ -140,22 +142,12 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) // Connect the view with the window that has been created by our base // class. - pWindow->SetBackground (Wallpaper()); - mrView.AddWindowToPaintView(pWindow); - mrView.SetActualWin(pWindow); - pWindow->SetCenterAllowed (false); - pWindow->SetViewSize (mrView.GetModelArea().GetSize()); - pWindow->EnableRTL(FALSE); - - // Reinitialize colors in Properties with window specific values. - mpProperties->SetBackgroundColor( - pWindow->GetSettings().GetStyleSettings().GetWindowColor()); - mpProperties->SetTextColor( - pWindow->GetSettings().GetStyleSettings().GetWindowTextColor()); - mpProperties->SetSelectionColor( - pWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor()); - mpProperties->SetHighlightColor( - pWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor()); + // mrView.AddWindowToPaintView(pWindow.get()); + // mrView.SetActualWin(pWindow.get()); + pWindow->SetBackground(Wallpaper()); + pWindow->SetCenterAllowed(false); + pWindow->SetMapMode(MapMode(MAP_PIXEL)); + pWindow->SetViewSize(mrView.GetModelArea().GetSize()); } } @@ -214,6 +206,14 @@ SlideSorterController::~SlideSorterController (void) +void SlideSorterController::Dispose (void) +{ + mpAnimator->Dispose(); +} + + + + SlideSorter& SlideSorterController::GetSlideSorter (void) const { return mrSlideSorter; @@ -313,10 +313,20 @@ ScrollBarManager& SlideSorterController::GetScrollBarManager (void) +::boost::shared_ptr + SlideSorterController::GetInsertionIndicatorHandler (void) const +{ + OSL_ASSERT(mpInsertionIndicatorHandler.get()!=NULL); + return mpInsertionIndicatorHandler; +} + + + + void SlideSorterController::PrePaint() { // forward VCLs PrePaint window event to DrawingLayer - mrView.PrePaint(); + //AF mrView.PrePaint(); } @@ -326,7 +336,7 @@ void SlideSorterController::Paint ( const Rectangle& rBBox, ::Window* pWindow) { - // if (mnPaintEntranceCount == 0) + if (mnPaintEntranceCount == 0) { ++mnPaintEntranceCount; @@ -335,7 +345,6 @@ void SlideSorterController::Paint ( if (GetSelectionManager()->IsMakeSelectionVisiblePending()) GetSelectionManager()->MakeSelectionVisible(); - mrView.SetApplicationDocumentColor(GetProperties()->GetBackgroundColor()); mrView.CompleteRedraw(pWindow, Region(rBBox), 0); } catch (const Exception&) @@ -429,9 +438,8 @@ 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. - mrView.GetOverlay().GetInsertionIndicatorOverlay().SetPosition( + GetInsertionIndicatorHandler()->Start( pWindow->PixelToLogic(rEvent.GetMousePosPixel())); - mrView.GetOverlay().GetInsertionIndicatorOverlay().setVisible(true); } pWindow->ReleaseMouse(); @@ -455,17 +463,18 @@ bool SlideSorterController::Command ( GetFocusManager().GetFocusedPageDescriptor()); if (pDescriptor.get() != NULL) { - Rectangle aBBox (mrView.GetPageBoundingBox ( - pDescriptor, - view::SlideSorterView::CS_SCREEN, - view::SlideSorterView::BBT_SHAPE)); - Point aPosition (aBBox.Center()); + Rectangle aBBox ( + mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox ( + pDescriptor, + PageObjectLayouter::PageObject, + PageObjectLayouter::WindowCoordinateSystem)); + Point aCenter (aBBox.Center()); mbIsContextMenuOpen = true; if (pViewShell != NULL) pViewShell->GetViewFrame()->GetDispatcher()->ExecutePopup( SdResId(nPopupId), pWindow, - &aPosition); + &aCenter); } } } @@ -476,8 +485,8 @@ bool SlideSorterController::Command ( // it is hidden, so that a pending slide insertion slot call // finds the right place to insert a new slide. GetSelectionManager()->SetInsertionPosition( - mrView.GetOverlay().GetInsertionIndicatorOverlay().GetInsertionPageIndex()); - mrView.GetOverlay().GetInsertionIndicatorOverlay().setVisible(false); + GetInsertionIndicatorHandler()->GetInsertionPageIndex()); + GetInsertionIndicatorHandler()->End(); } bEventHasBeenHandled = true; } @@ -531,8 +540,7 @@ void SlideSorterController::PreModelChange (void) mpPageSelector->PrepareModelChange(); GetCurrentSlideManager()->PrepareModelChange(); - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - if (pWindow != NULL) + if (mrSlideSorter.GetContentWindow()) mrView.PreModelChange(); mbPostModelChangePending = true; @@ -546,8 +554,8 @@ void SlideSorterController::PostModelChange (void) mbPostModelChangePending = false; mrModel.Resync(); - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) { GetCurrentSlideManager()->HandleModelChange(); @@ -593,22 +601,22 @@ IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent) if (pEvent != NULL) { ::Window* pWindow = pEvent->GetWindow(); - ::sd::Window* pActiveWindow = mrSlideSorter.GetActiveWindow(); + ::boost::shared_ptr pActiveWindow (mrSlideSorter.GetContentWindow()); switch (pEvent->GetId()) { case VCLEVENT_WINDOW_ACTIVATE: case VCLEVENT_WINDOW_SHOW: - if (pActiveWindow != NULL && pWindow == pActiveWindow->GetParent()) + if (pActiveWindow && pWindow == pActiveWindow->GetParent()) mrView.RequestRepaint(); break; case VCLEVENT_WINDOW_GETFOCUS: - if (pActiveWindow != NULL && pWindow == pActiveWindow) + if (pActiveWindow && pWindow == pActiveWindow.get()) GetFocusManager().ShowFocus(false); break; case VCLEVENT_WINDOW_LOSEFOCUS: - if (pActiveWindow != NULL && pWindow == pActiveWindow) + if (pActiveWindow && pWindow == pActiveWindow.get()) GetFocusManager().HideFocus(); break; @@ -668,10 +676,9 @@ void SlideSorterController::GetCtrlState (SfxItemSet& rSet) ||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SFX_ITEM_AVAILABLE ||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SFX_ITEM_AVAILABLE) { - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - if (pWindow != NULL) + if (mrSlideSorter.GetContentWindow()) { - ULONG nMode = pWindow->GetDrawMode(); + ULONG nMode = mrSlideSorter.GetContentWindow()->GetDrawMode(); UINT16 nQuality = 0; switch (nMode) @@ -744,7 +751,7 @@ void SlideSorterController::ExecStatusBar (SfxRequest& ) void SlideSorterController::UpdateAllPages (void) { // Do a redraw. - mrView.InvalidateAllWin(); + mrSlideSorter.GetContentWindow()->Invalidate(); } @@ -770,8 +777,8 @@ Rectangle SlideSorterController::Rearrange (bool bForce) { Rectangle aNewContentArea (maTotalWindowArea); - ::boost::shared_ptr pWindow = mrSlideSorter.GetContentWindow(); - if (pWindow.get() != NULL) + const ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) { // Place the scroll bars. aNewContentArea = GetScrollBarManager().PlaceScrollBars(maTotalWindowArea); @@ -806,16 +813,13 @@ Rectangle SlideSorterController::Rearrange (bool bForce) void SlideSorterController::SetZoom (long int nZoom) { - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); long int nCurrentZoom ((long int)( pWindow->GetMapMode().GetScaleX().operator double() * 100)); if (nZoom > nCurrentZoom) { - Size aPageSize (mrView.GetPageBoundingBox( - 0, - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_SHAPE).GetSize()); + Size aPageSize (mrView.GetLayouter().GetPageObjectSize()); Size aWindowSize (pWindow->PixelToLogic( pWindow->GetOutputSizePixel())); @@ -831,13 +835,13 @@ void SlideSorterController::SetZoom (long int nZoom) if (nZoom < 1) nZoom = 1; - mrView.LockRedraw (TRUE); - mrView.GetLayouter().SetZoom(nZoom/100.0, pWindow); + mrView.LockRedraw(true); + mrView.GetLayouter().SetZoom(nZoom/100.0); mrView.Layout(); GetScrollBarManager().UpdateScrollBars (false); mrView.GetPreviewCache()->InvalidateCache(); mrView.RequestRepaint(); - mrView.LockRedraw (FALSE); + mrView.LockRedraw(false); /* ViewShell::SetZoom (nZoom); @@ -960,8 +964,8 @@ void SlideSorterController::PageNameHasChanged (int nPageIndex, const String& rs // that of the name change. do { - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); - if (pWindow == NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if ( ! pWindow) break; ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > @@ -1010,14 +1014,6 @@ bool SlideSorterController::IsContextMenuOpen (void) const -::boost::shared_ptr SlideSorterController::GetProperties (void) const -{ - return mpProperties; -} - - - - void SlideSorterController::SetDocumentSlides (const Reference& rxSlides) { if (mrModel.GetDocumentSlides() != rxSlides) diff --git a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx new file mode 100644 index 000000000000..905b28ee5f6b --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx @@ -0,0 +1,287 @@ +/************************************************************************* + * + * 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: SlsAnimator.cxx,v $ + * + * $Revision: 1.3 $ + * + * 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 "controller/SlsAnimationFunction.hxx" +#include "model/SlsPageDescriptor.hxx" +#include "view/SlideSorterView.hxx" + + +#include +#include + +namespace sd { namespace slidesorter { namespace controller { + + +double AnimationFunction::FastInSlowOut_Sine (const double nTime) +{ + OSL_ASSERT(nTime>=0.0 && nTime<=1.0); + + const double nResult (sin(nTime * M_PI/2)); + + OSL_ASSERT(nResult>=0.0 && nResult<=1.0); + return nResult; +} + + + + +double AnimationFunction::FastInSlowOut_Root (const double nTime) +{ + OSL_ASSERT(nTime>=0.0 && nTime<=1.0); + + const double nResult (sqrt(nTime)); + + OSL_ASSERT(nResult>=0.0 && nResult<=1.0); + return nResult; +} + + + + +double AnimationFunction::SlowInSlowOut_0to0_Sine (const double nTime) +{ + OSL_ASSERT(nTime>=0.0 && nTime<=1.0); + + const double nResult (sin(nTime * M_PI)); + + OSL_ASSERT(nResult>=0.0 && nResult<=1.0); + return nResult; +} + + + + +double AnimationFunction::Vibrate_Sine (const double nTime) +{ + return sin(nTime*M_PI*8); +} + + + + +Point AnimationFunction::ScalePoint (const Point& rPoint, const double nTime) +{ + return Point( + sal_Int32(::rtl::math::round(rPoint.X() * nTime)), + sal_Int32(::rtl::math::round(rPoint.Y() * nTime))); +} + + + + +double AnimationFunction::Blend ( + const double nStartValue, + const double nEndValue, + const double nTime) +{ + return nStartValue*(1-nTime) + nEndValue*nTime; +} + + + + +void AnimationFunction::ApplyVisualStateChange ( + const model::SharedPageDescriptor& rpDescriptor, + view::SlideSorterView& rView, + const double nTime) +{ + if (rpDescriptor) + { + rpDescriptor->GetVisualState().SetVisualStateBlend(nTime); + rView.RequestRepaint(rpDescriptor); + } +} + + + + +void AnimationFunction::ApplyLocationOffsetChange ( + const model::SharedPageDescriptor& rpDescriptor, + view::SlideSorterView& rView, + const Point aLocationOffset) +{ + if (rpDescriptor) + { + const Rectangle aOldBoundingBox(rpDescriptor->GetBoundingBox()); + rpDescriptor->GetVisualState().SetLocationOffset(aLocationOffset); + rView.RequestRepaint(aOldBoundingBox); + rView.RequestRepaint(rpDescriptor); + } +} + + + + +void AnimationFunction::ApplyButtonAlphaChange( + const model::SharedPageDescriptor& rpDescriptor, + view::SlideSorterView& rView, + const double nAlpha) +{ + if (rpDescriptor) + { + rpDescriptor->GetVisualState().SetButtonAlpha(nAlpha); + rView.RequestRepaint(rpDescriptor); + } +} + + + + +//===== AnimationBezierFunction =============================================== + +AnimationBezierFunction::AnimationBezierFunction ( + const double nX1, + const double nY1, + const double nX2, + const double nY2) + : mnX1(nX1), + mnY1(nY1), + mnX2(nX2), + mnY2(nY2) +{ +} + + + + +AnimationBezierFunction::AnimationBezierFunction ( + const double nX1, + const double nY1) + : mnX1(nX1), + mnY1(nY1), + mnX2(1-nY1), + mnY2(1-nX1) +{ +} + + + + +::basegfx::B2DPoint AnimationBezierFunction::operator() (const double nT) +{ + return ::basegfx::B2DPoint( + EvaluateComponent(nT, mnX1, mnX2), + EvaluateComponent(nT, mnY1, mnY2)); +} + + + + +double AnimationBezierFunction::EvaluateComponent ( + const double nT, + const double nV1, + const double nV2) +{ + const double nS (1-nT); + + // While the control point values 1 and 2 are explicitly given the start + // and end values are implicitly given. + const double nV0 (0); + const double nV3 (1); + + const double nV01 (nS*nV0 + nT*nV1); + const double nV12 (nS*nV1 + nT*nV2); + const double nV23 (nS*nV2 + nT*nV3); + + const double nV012 (nS*nV01 + nT*nV12); + const double nV123 (nS*nV12 + nT*nV23); + + const double nV0123 (nS*nV012 + nT*nV123); + + return nV0123; +} + + + + +//===== AnimationParametricFunction =========================================== + +AnimationParametricFunction::AnimationParametricFunction (const ParametricFunction& rFunction) + : maY() +{ + const sal_Int32 nSampleCount (64); + + // Sample the given parametric function. + ::std::vector aPoints; + aPoints.reserve(nSampleCount); + for (sal_Int32 nIndex=0; nIndex nX1 && nIndex=maY.size() || nIndex1>=maY.size()) + return maY[maY.size()-1]; + + const double nU ((nX-nX1) / (nX0 - nX1)); + return maY[nIndex0]*nU + maY[nIndex1]*(1-nU); +} + + +} } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index 9878d7b36a47..d7679d88328e 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -33,6 +33,7 @@ #include "controller/SlsAnimator.hxx" #include "view/SlideSorterView.hxx" #include "View.hxx" +#include namespace sd { namespace slidesorter { namespace controller { @@ -46,14 +47,23 @@ class Animator::Animation { public: Animation ( - const Animator::AnimationFunction& rAnimation, - const double nDelta); + const Animator::AnimationFunctor& rAnimation, + const double nDelta, + const double nEnd, + const Animator::AnimationId nAnimationId, + const Animator::FinishFunctor& rFinishFunctor); ~Animation (void); bool Run (void); + void Expire (void); bool IsExpired (void); - Animator::AnimationFunction maAnimation; + + Animator::AnimationFunctor maAnimation; + Animator::FinishFunctor maFinishFunctor; + const Animator::AnimationId mnAnimationId; double mnValue; - double mnDelta; + const double mnEnd; + const double mnDelta; + bool mbIsExpired; }; @@ -62,11 +72,11 @@ public: class Animator::DrawLock { public: - DrawLock (View& rView); + DrawLock (view::SlideSorterView& rView); ~DrawLock (void); private: - View& mrView; + view::SlideSorterView& mrView; }; @@ -75,8 +85,10 @@ private: Animator::Animator (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), maTimer(), + mbIsDisposed(false), maAnimations(), - mpDrawLock() + mpDrawLock(), + mnNextAnimationId(0) { maTimer.SetTimeout(gnResolution); maTimer.SetTimeoutHdl(LINK(this,Animator,TimeoutHandler)); @@ -87,6 +99,19 @@ Animator::Animator (SlideSorter& rSlideSorter) Animator::~Animator (void) { + if ( ! mbIsDisposed) + { + OSL_ASSERT(mbIsDisposed); + Dispose(); + } +} + + + + +void Animator::Dispose (void) +{ + mbIsDisposed = true; maTimer.Stop(); mpDrawLock.reset(); } @@ -94,25 +119,82 @@ Animator::~Animator (void) -void Animator::AddAnimation ( - const AnimationFunction& rAnimation, - const sal_Int32 nDuration) +Animator::AnimationId Animator::AddAnimation ( + const AnimationFunctor& rAnimation, + const sal_Int32 nDuration, + const FinishFunctor& rFinishFunctor) { + OSL_ASSERT( ! mbIsDisposed); + const double nDelta = double(gnResolution) / double(nDuration); - maAnimations.push_back(boost::shared_ptr(new Animation(rAnimation, nDelta))); + boost::shared_ptr pAnimation ( + new Animation(rAnimation, nDelta, 1.0, ++mnNextAnimationId, rFinishFunctor)); + maAnimations.push_back(pAnimation); // Prevent redraws except for the ones in TimeoutHandler. // While the Animator is active it will schedule repaints regularly. // Repaints in between would only lead to visual artifacts. mpDrawLock.reset(new DrawLock(mrSlideSorter.GetView())); maTimer.Start(); + + return pAnimation->mnAnimationId; } -bool Animator::ServeAnimations (void) +Animator::AnimationId Animator::AddInfiniteAnimation ( + const AnimationFunctor& rAnimation, + const double nDelta) { + OSL_ASSERT( ! mbIsDisposed); + + boost::shared_ptr pAnimation ( + new Animation(rAnimation, nDelta, -1.0, mnNextAnimationId++, FinishFunctor())); + maAnimations.push_back(pAnimation); + + // Prevent redraws except for the ones in TimeoutHandler. + // While the Animator is active it will schedule repaints regularly. + // Repaints in between would only lead to visual artifacts. + mpDrawLock.reset(new DrawLock(mrSlideSorter.GetView())); + maTimer.Start(); + + return pAnimation->mnAnimationId; +} + + + + +void Animator::RemoveAnimation (const Animator::AnimationId nId) +{ + OSL_ASSERT( ! mbIsDisposed); + + const AnimationList::iterator iAnimation (::std::find_if( + maAnimations.begin(), + maAnimations.end(), + ::boost::bind( + ::std::equal_to(), + nId, + ::boost::bind(&Animation::mnAnimationId, _1)))); + if (iAnimation != maAnimations.end()) + { + OSL_ASSERT((*iAnimation)->mnAnimationId == nId); + (*iAnimation)->Expire(); + maAnimations.erase(iAnimation); + } + + // Reset the animation id when we can. + if (maAnimations.empty()) + mnNextAnimationId = 0; +} + + + + +bool Animator::ProcessAnimations (void) +{ + OSL_ASSERT( ! mbIsDisposed); + bool bExpired (false); AnimationList aCopy (maAnimations); @@ -130,6 +212,8 @@ bool Animator::ServeAnimations (void) void Animator::CleanUpAnimationList (void) { + OSL_ASSERT( ! mbIsDisposed); + AnimationList aActiveAnimations; AnimationList::const_iterator iAnimation; @@ -147,7 +231,10 @@ void Animator::CleanUpAnimationList (void) IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) { - if (ServeAnimations()) + if (mbIsDisposed) + return 0; + + if (ProcessAnimations()) CleanUpAnimationList(); // Unlock the draw lock. This should lead to a repaint. @@ -168,11 +255,18 @@ IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) //===== Animator::Animation =================================================== Animator::Animation::Animation ( - const Animator::AnimationFunction& rAnimation, - const double nDelta) + const Animator::AnimationFunctor& rAnimation, + const double nDelta, + const double nEnd, + const Animator::AnimationId nId, + const Animator::FinishFunctor& rFinishFunctor) : maAnimation(rAnimation), + maFinishFunctor(rFinishFunctor), mnValue(0), - mnDelta(nDelta) + mnEnd(nEnd), + mnDelta(nDelta), + mnAnimationId(nId), + mbIsExpired(false) { maAnimation(mnValue); @@ -192,16 +286,35 @@ Animator::Animation::~Animation (void) bool Animator::Animation::Run (void) { - if (mnValue < 1.0) + if ( ! mbIsExpired) { - maAnimation(mnValue); - mnValue += mnDelta; - return false; + if (mnEnd>=0 && mnValue>=mnEnd) + { + maAnimation(mnEnd); + Expire(); + return true; + } + else + { + maAnimation(mnValue); + mnValue += mnDelta; + return false; + } } else - { - maAnimation(1.0); return true; +} + + + + +void Animator::Animation::Expire (void) +{ + if ( ! mbIsExpired) + { + mbIsExpired = true; + if (maFinishFunctor) + maFinishFunctor(); } } @@ -210,7 +323,7 @@ bool Animator::Animation::Run (void) bool Animator::Animation::IsExpired (void) { - return mnValue >= 1.0; + return mbIsExpired; } @@ -218,10 +331,10 @@ bool Animator::Animation::IsExpired (void) //===== Animator::DrawLock ==================================================== -Animator::DrawLock::DrawLock (View& rView) +Animator::DrawLock::DrawLock (view::SlideSorterView& rView) : mrView(rView) { - mrView.LockRedraw(TRUE); + mrView.LockRedraw(true); } @@ -229,7 +342,7 @@ Animator::DrawLock::DrawLock (View& rView) Animator::DrawLock::~DrawLock (void) { - mrView.LockRedraw(FALSE); + mrView.LockRedraw(false); } diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 805628396a35..0e5b839a1de9 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -39,8 +39,8 @@ #include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsViewOverlay.hxx" -#include "view/SlsPageObject.hxx" #include "controller/SlideSorterController.hxx" +#include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsPageSelector.hxx" #include "controller/SlsSelectionFunction.hxx" #include "controller/SlsCurrentSlideManager.hxx" @@ -212,7 +212,7 @@ void Clipboard::DoPaste (::Window* pWindow) sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition); // Select the pasted pages and make the first of them the // current page. - mrSlideSorter.GetView().GetWindow()->GrabFocus(); + mrSlideSorter.GetContentWindow()->GrabFocus(); SelectPageRange(nInsertPosition, nInsertPageCount); } } @@ -233,11 +233,11 @@ sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow) // selection. // d) After the last page when there is no selection and no focus. - view::InsertionIndicatorOverlay& rInsertionIndicatorOverlay ( - mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()); - if (rInsertionIndicatorOverlay.isVisible()) + ::boost::shared_ptr pInsertionIndicatorHandler ( + mrController.GetInsertionIndicatorHandler()); + if (pInsertionIndicatorHandler->IsActive()) { - nInsertPosition = rInsertionIndicatorOverlay.GetInsertionPageIndex(); + nInsertPosition = pInsertionIndicatorHandler->GetInsertionPageIndex(); } else if (mrController.GetFocusManager().IsFocusShowing()) { @@ -426,13 +426,15 @@ void Clipboard::CreateSlideTransferable ( void Clipboard::StartDrag ( - const Point&, + const Point& rPosition, ::Window* pWindow) { maPagesToRemove.clear(); maPagesToSelect.clear(); mbUpdateSelectionPending = false; - CreateSlideTransferable (pWindow, TRUE); + CreateSlideTransferable(pWindow, TRUE); + + mrController.GetInsertionIndicatorHandler()->UpdatePosition(rPosition); } @@ -441,8 +443,8 @@ void Clipboard::StartDrag ( void Clipboard::DragFinished (sal_Int8 nDropAction) { // Hide the substitution display and insertion indicator. - mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay().setVisible(false); - mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay().setVisible(false); + mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay()->SetIsVisible(false); + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(); SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; @@ -497,6 +499,11 @@ sal_Int8 Clipboard::AcceptDrop ( { sal_Int8 nResult = DND_ACTION_NONE; + FunctionReference rFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction()); + SelectionFunction* pSelectionFunction = dynamic_cast(rFunction.get()); + if (pSelectionFunction != NULL) + pSelectionFunction->MouseDragged(rEvent); + switch (IsDropAccepted()) { case DT_PAGE: @@ -521,12 +528,11 @@ 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()); - rOverlay.GetInsertionIndicatorOverlay().SetPosition (aPosition); - rOverlay.GetInsertionIndicatorOverlay().setVisible(true); - rOverlay.GetSubstitutionOverlay().SetPosition (aPosition); + mrController.GetInsertionIndicatorHandler()->UpdatePosition(aPosition); + rOverlay.GetSubstitutionOverlay()->SetPosition(aPosition); // Scroll the window when the mouse reaches the window border. - mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel); + // mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel); } break; @@ -576,12 +582,11 @@ sal_Int8 Clipboard::ExecuteDrop ( // Get insertion position and then turn off the insertion indicator. view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetInsertionIndicatorOverlay().SetPosition( - aEventModelPosition); - USHORT nIndex = DetermineInsertPosition (*pDragTransferable); + mrController.GetInsertionIndicatorHandler()->UpdatePosition(aEventModelPosition); + USHORT nIndex = DetermineInsertPosition(*pDragTransferable); OSL_TRACE ("Clipboard::AcceptDrop() called for index %d", nIndex); - rOverlay.GetInsertionIndicatorOverlay().setVisible(false); + mrController.GetInsertionIndicatorHandler()->End(); if (bContinue) { @@ -644,9 +649,8 @@ USHORT Clipboard::DetermineInsertPosition (const SdTransferable& ) // Tell the model to move the dragged pages behind the one with the // index nInsertionIndex which first has to be transformed into an index // understandable by the document. - view::InsertionIndicatorOverlay& rOverlay ( - mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()); - sal_Int32 nInsertionIndex (rOverlay.GetInsertionPageIndex()); + sal_Int32 nInsertionIndex ( + mrController.GetInsertionIndicatorHandler()->GetInsertionPageIndex()); // The index returned by the overlay starts with 1 for the first slide. // This is now converted that to an SdModel index that also starts with 1. diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx index 9220532239ab..2f97124d8576 100644 --- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx @@ -38,7 +38,6 @@ #include "controller/SlideSorterController.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" #include "ViewShellBase.hxx" #include "ViewShell.hxx" #include "DrawViewShell.hxx" @@ -90,10 +89,7 @@ void CurrentSlideManager::CurrentSlideHasChanged (const sal_Int32 nSlideIndex) void CurrentSlideManager::ReleaseCurrentSlide (void) { if (mpCurrentSlide.get() != NULL) - { - mpCurrentSlide->SetIsCurrentPage(false); - mrSlideSorter.GetView().RequestRepaint(mpCurrentSlide); - } + mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, false); mpCurrentSlide.reset(); mnCurrentSlideIndex = -1; @@ -121,10 +117,7 @@ void CurrentSlideManager::AcquireCurrentSlide (const sal_Int32 nSlideIndex) // document. mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(mnCurrentSlideIndex); if (mpCurrentSlide.get() != NULL) - { - mpCurrentSlide->SetIsCurrentPage(true); - mrSlideSorter.GetView().RequestRepaint(mpCurrentSlide); - } + mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, true); } } @@ -143,8 +136,8 @@ void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDesc { if (rpDescriptor.get() != NULL) { - mpCurrentSlide = rpDescriptor; - mnCurrentSlideIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2; + ReleaseCurrentSlide(); + AcquireCurrentSlide((rpDescriptor->GetPage()->GetPageNum()-1)/2); ViewShell* pViewShell = mrSlideSorter.GetViewShell(); if (pViewShell != NULL && pViewShell->IsMainViewShell()) @@ -250,10 +243,9 @@ void CurrentSlideManager::HandleModelChange (void) { if (mnCurrentSlideIndex >= 0) { - mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor( - mnCurrentSlideIndex); + mpCurrentSlide = mrSlideSorter.GetModel().GetPageDescriptor(mnCurrentSlideIndex); if (mpCurrentSlide.get() != NULL) - mpCurrentSlide->SetIsCurrentPage(true); + mrSlideSorter.GetView().SetState(mpCurrentSlide, PageDescriptor::ST_Current, true); } } diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index 1077184b7db7..8128752417fe 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -175,7 +175,7 @@ bool FocusManager::ToggleFocus (void) bool FocusManager::HasFocus (void) const { - return mrSlideSorter.GetView().GetWindow()->HasFocus(); + return mrSlideSorter.GetContentWindow()->HasFocus(); } @@ -246,8 +246,7 @@ void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor& rpDesc { if (rpDescriptor.get() != NULL) { - rpDescriptor->RemoveFocus(); - mrSlideSorter.GetView().RequestRepaint(rpDescriptor); + mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, false); } } @@ -260,7 +259,7 @@ void FocusManager::ShowFocusIndicator ( { if (rpDescriptor.get() != NULL) { - rpDescriptor->SetFocus (); + mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true); if (bScrollToFocus) { @@ -268,10 +267,7 @@ void FocusManager::ShowFocusIndicator ( // it, so that the focus indicator becomes visible. view::SlideSorterView& rView (mrSlideSorter.GetView()); mrSlideSorter.GetController().GetSelectionManager()->MakeRectangleVisible ( - rView.GetPageBoundingBox ( - GetFocusedPageDescriptor(), - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_INFO)); + GetFocusedPageDescriptor()->GetBoundingBox()); } mrSlideSorter.GetView().RequestRepaint (rpDescriptor); diff --git a/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx index 035f6ecd2dd1..d8d42d6bbbe9 100644 --- a/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsHideSlideFunction.cxx @@ -112,8 +112,10 @@ void HideSlideFunction::DoExecute (SfxRequest& rRequest) while (aSelectedPages.HasMoreElements()) { model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); - pDescriptor->GetPage()->SetExcluded (eState==EXCLUDED); - static_cast(mpView)->RequestRepaint(pDescriptor); + static_cast(mpView)->SetState( + pDescriptor, + model::PageDescriptor::ST_Excluded, + eState==EXCLUDED); } } diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx new file mode 100644 index 000000000000..8b9cc659fd54 --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -0,0 +1,255 @@ +/************************************************************************* + * + * 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: 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 + * 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 "controller/SlsInsertionIndicatorHandler.hxx" +#include "controller/SlsProperties.hxx" +#include "view/SlideSorterView.hxx" +#include "view/SlsViewOverlay.hxx" +#include "view/SlsLayouter.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageEnumerationProvider.hxx" + +#include "SlideSorter.hxx" + + +namespace sd { namespace slidesorter { namespace controller { + + +InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter) + : mrSlideSorter(rSlideSorter), + mpInsertAnimator(), + mpInsertionIndicatorOverlay( + mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()), + mnInsertionIndex(-1), + mbIsBeforePage(false), + mbIsActive(false) +{ +} + + + + +InsertionIndicatorHandler::~InsertionIndicatorHandler (void) +{ +} + + + + +void InsertionIndicatorHandler::Start (const Point& rMouseModelPosition) +{ + if (mbIsActive) + { + OSL_ASSERT(!mbIsActive); + } + + if (mrSlideSorter.GetProperties()->IsUIReadOnly()) + return; + + SetPosition(rMouseModelPosition); + + mbIsActive = true; +} + + + + +void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition) +{ + OSL_ASSERT(mbIsActive); + + if (mrSlideSorter.GetProperties()->IsUIReadOnly()) + return; + + SetPosition(rMouseModelPosition); +} + + + + +void InsertionIndicatorHandler::End (void) +{ + OSL_ASSERT(mbIsActive); + GetInsertAnimator()->SetInsertPosition(-1, false); + + mbIsActive = false; + mpInsertionIndicatorOverlay->SetIsVisible(false); + GetInsertAnimator()->Reset(); +} + + + + +bool InsertionIndicatorHandler::IsActive (void) const +{ + return mbIsActive; +} + + + + +sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const +{ + return mnInsertionIndex; +} + + + + +void InsertionIndicatorHandler::SetPosition (const Point& rPoint) +{ + static const bool bAllowHorizontalInsertMarker = true; + view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); + USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount()); + + sal_Int32 nInsertionIndex = rLayouter.GetInsertionIndex (rPoint, + bAllowHorizontalInsertMarker); + if (nInsertionIndex >= nPageCount) + nInsertionIndex = nPageCount-1; + sal_Int32 nDrawIndex = nInsertionIndex; + + bool bVertical = false; + bool bIsBeforePage = false; + if (nInsertionIndex >= 0) + { + // Now that we know where to insert, we still have to determine + // where to draw the marker. There are two decisions to make: + // 1. Draw a vertical or a horizontal insert marker. + // The horizontal one may only be chosen when there is only one + // column. + // 2. The vertical (standard) insert marker may be painted left to + // the insert page or right of the previous one. When both pages + // are in the same row this makes no difference. Otherwise the + // posiotions are at the left and right ends of two rows. + + Point aPageCenter (rLayouter.GetPageObjectBox ( + nInsertionIndex).Center()); + + if (bAllowHorizontalInsertMarker + && rLayouter.GetColumnCount() == 1) + { + bVertical = false; + bIsBeforePage = (rPoint.Y() <= aPageCenter.Y()); + } + else + { + bVertical = true; + bIsBeforePage = (rPoint.X() <= aPageCenter.X()); + } + + // Add one when the mark was painted below or to the right of the + // page object. + if ( ! bIsBeforePage) + nInsertionIndex += 1; + } + + if (mnInsertionIndex!=nInsertionIndex || mbIsBeforePage!=bIsBeforePage) + { + mnInsertionIndex = nInsertionIndex; + mbIsBeforePage = bIsBeforePage; + mbIsInsertionTrivial = IsInsertionTrivial(); + + mpInsertionIndicatorOverlay->SetLocation( + rLayouter.GetInsertionMarkerLocation ( + nDrawIndex, + bVertical, + mbIsBeforePage)); + } + + if (mnInsertionIndex>=0 && ! mbIsInsertionTrivial) + { + GetInsertAnimator()->SetInsertPosition( + mnInsertionIndex, + mbIsBeforePage); + mpInsertionIndicatorOverlay->SetIsVisible(true); + } + else + { + GetInsertAnimator()->Reset(); + mpInsertionIndicatorOverlay->SetIsVisible(false); + } +} + + + + +::boost::shared_ptr InsertionIndicatorHandler::GetInsertAnimator (void) +{ + if ( ! mpInsertAnimator) + mpInsertAnimator.reset(new view::InsertAnimator(mrSlideSorter)); + return mpInsertAnimator; +} + + + + +bool InsertionIndicatorHandler::IsInsertionTrivial (void) const +{ + // Iterate over all selected pages and check whether there are + // holes. While we do this we remember the indices of the first and + // last selected page as preparation for the next step. + sal_Int32 nCurrentIndex = -1; + sal_Int32 nFirstIndex = -1; + sal_Int32 nLastIndex = -1; + model::PageEnumeration aSelectedPages ( + model::PageEnumerationProvider::CreateSelectedPagesEnumeration( + mrSlideSorter.GetModel())); + while (aSelectedPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); + + // Get the page number and compare it to the last one. + const sal_Int32 nPageNumber (pDescriptor->GetPageIndex()); + if (nCurrentIndex>=0 && nPageNumber>(nCurrentIndex+1)) + return false; + else + nCurrentIndex = nPageNumber; + + // Remember indices of the first and last page of the selection. + if (nFirstIndex == -1) + nFirstIndex = nPageNumber; + nLastIndex = nPageNumber; + } + + // When we come here then the selection has no holes. We still have + // 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)) + return false; + + return true; +} + + + +} } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 9c51643b2b49..b78abb2e5298 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -28,8 +28,8 @@ * ************************************************************************/ -// MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" + #include "SlsListener.hxx" #include "SlideSorter.hxx" @@ -40,6 +40,7 @@ #include "controller/SlsCurrentSlideManager.hxx" #include "model/SlideSorterModel.hxx" #include "view/SlideSorterView.hxx" +#include "cache/SlsPageCache.hxx" #include "drawdoc.hxx" #include "glob.hrc" @@ -129,7 +130,7 @@ Listener::Listener ( if (pMainViewShell != NULL && pMainViewShell!=pViewShell) { - StartListening (*pMainViewShell); + StartListening(*pMainViewShell); } Link aLink (LINK(this, Listener, EventMultiplexerCallback)); @@ -309,18 +310,27 @@ void Listener::Notify ( if (rHint.ISA(SdrHint)) { SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint)); - if(rSdrHint.GetKind() == HINT_PAGEORDERCHG ) + switch (rSdrHint.GetKind()) { - if (rBroadcaster.ISA(SdDrawDocument)) - { - SdDrawDocument& rDocument ( - static_cast(rBroadcaster)); - if (rDocument.GetMasterSdPageCount(PK_STANDARD) - == rDocument.GetMasterSdPageCount(PK_NOTES)) + case HINT_PAGEORDERCHG: + if (rBroadcaster.ISA(SdDrawDocument)) { - mrController.HandleModelChange(); + SdDrawDocument& rDocument (static_cast(rBroadcaster)); + if (rDocument.GetMasterSdPageCount(PK_STANDARD) + == rDocument.GetMasterSdPageCount(PK_NOTES)) + { + mrController.HandleModelChange(); + } } - } + break; + + case HINT_OBJINSERTED: + case HINT_OBJREMOVED: + case HINT_OBJCHG: + mrSlideSorter.GetView().GetPreviewCache()->InvalidatePreviewBitmap( + rSdrHint.GetPage(), + true); + break; } } else if (rHint.ISA(ViewShellHint)) diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index 0c69a2b27c11..d715acfec252 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -36,6 +36,7 @@ #include "SlideSorterViewShell.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsSelectionManager.hxx" +#include "controller/SlsAnimator.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlideSorterModel.hxx" @@ -47,6 +48,8 @@ #include "ViewShellBase.hxx" #include #include +#include + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -55,7 +58,6 @@ using namespace ::sd::slidesorter::view; namespace sd { namespace slidesorter { namespace controller { - PageSelector::PageSelector (SlideSorter& rSlideSorter) : mrModel(rSlideSorter.GetModel()), mrSlideSorter(rSlideSorter), @@ -112,7 +114,7 @@ void PageSelector::UpdateAllPages (void) bSelectionHasChanged = true; } - if (pDescriptor->IsSelected()) + if (pDescriptor->HasState(PageDescriptor::ST_Selected)) mnSelectedPageCount++; } @@ -151,7 +153,8 @@ void PageSelector::SelectPage (const SdPage* pPage) void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor) { - if (rpDescriptor.get()!=NULL && rpDescriptor->Select()) + if (rpDescriptor.get()!=NULL + && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true)) { mnSelectedPageCount ++; mrSlideSorter.GetView().RequestRepaint(rpDescriptor); @@ -193,7 +196,8 @@ void PageSelector::DeselectPage (const SdPage* pPage) void PageSelector::DeselectPage (const SharedPageDescriptor& rpDescriptor) { - if (rpDescriptor.get()!=NULL && rpDescriptor->Deselect()) + if (rpDescriptor.get()!=NULL + && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false)) { mnSelectedPageCount --; mrSlideSorter.GetView().RequestRepaint(rpDescriptor); @@ -213,7 +217,7 @@ bool PageSelector::IsPageSelected (int nPageIndex) { SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); if (pDescriptor.get() != NULL) - return pDescriptor->IsSelected(); + return pDescriptor->HasState(PageDescriptor::ST_Selected); else return false; } @@ -315,7 +319,7 @@ void PageSelector::DisableBroadcasting (void) for (int nIndex=0; nIndexIsSelected()) + if (pDescriptor.get()!=NULL && pDescriptor->HasState(PageDescriptor::ST_Selected)) pSelection->push_back(pDescriptor->GetPage()); } diff --git a/sd/source/ui/slidesorter/controller/SlsProperties.cxx b/sd/source/ui/slidesorter/controller/SlsProperties.cxx index 6015c36e9510..829cc1b05368 100644 --- a/sd/source/ui/slidesorter/controller/SlsProperties.cxx +++ b/sd/source/ui/slidesorter/controller/SlsProperties.cxx @@ -41,7 +41,7 @@ Properties::Properties (void) mbIsShowSelection(true), mbIsShowFocus(true), mbIsCenterSelection(false), - mbIsSmoothSelectionScrolling(false), + mbIsSmoothSelectionScrolling(true),//false), mbIsSuspendPreviewUpdatesDuringFullScreenPresentation(true), maBackgroundColor(Application::GetSettings().GetStyleSettings().GetWindowColor()), maTextColor(Application::GetSettings().GetStyleSettings().GetActiveTextColor()), diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index ed363dc6743e..e874f67ce48e 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -54,11 +54,13 @@ ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter) mpVerticalScrollBar(mrSlideSorter.GetVerticalScrollBar()), mnHorizontalPosition (0), mnVerticalPosition (0), - maScrollBorder (10,10), + maScrollBorder (20,20), mnHorizontalScrollFactor (0.1), mnVerticalScrollFactor (0.1), mpScrollBarFiller(mrSlideSorter.GetScrollBarFiller()), - mpContentWindow(mrSlideSorter.GetContentWindow()) + mpContentWindow(mrSlideSorter.GetContentWindow()), + mbIsAutoScrollActive(false), + maAutoScrollFunctor() { // Hide the scroll bars by default to prevent display errors while // switching between view shells: In the short time between initiating @@ -69,7 +71,7 @@ ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter) mpVerticalScrollBar->Hide(); mpScrollBarFiller->Hide(); - maAutoScrollTimer.SetTimeout(50); + maAutoScrollTimer.SetTimeout(25); maAutoScrollTimer.SetTimeoutHdl ( LINK(this, ScrollBarManager, AutoScrollTimeoutHandler)); } @@ -176,9 +178,7 @@ void ScrollBarManager::PlaceVerticalScrollBar (const Rectangle& aArea) if (mpVerticalScrollBar != NULL && mpVerticalScrollBar->IsVisible()) { - view::Layouter::DoublePoint aLayouterPosition - = mrSlideSorter.GetView().GetLayouter().ConvertModelToLayouterCoordinates ( - Point (0, mpVerticalScrollBar->GetThumbPos())); + const double nThumbPosition (mpVerticalScrollBar->GetThumbPos()); // Place the scroll bar. Size aScrollBarSize (mpVerticalScrollBar->GetSizePixel()); @@ -187,11 +187,8 @@ void ScrollBarManager::PlaceVerticalScrollBar (const Rectangle& aArea) mpVerticalScrollBar->SetPosSizePixel(aPosition, aSize); // Restore the position. - mpVerticalScrollBar->SetThumbPos( - mrSlideSorter.GetView().GetLayouter().ConvertLayouterToModelCoordinates( - aLayouterPosition).Y()); - mnVerticalPosition = double(mpVerticalScrollBar->GetThumbPos()) - / double(mpVerticalScrollBar->GetRange().Len()); + mpVerticalScrollBar->SetThumbPos(nThumbPosition); + mnVerticalPosition = nThumbPosition / double(mpVerticalScrollBar->GetRange().Len()); } } @@ -245,7 +242,7 @@ void ScrollBarManager::AdaptWindowSize (const Rectangle& rArea) void ScrollBarManager::UpdateScrollBars (bool bResetThumbPosition, bool bUseScrolling) { Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); - ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); Size aWindowModelSize (pWindow->PixelToLogic(pWindow->GetSizePixel())); // The horizontal scroll bar is only shown when the window is @@ -329,12 +326,12 @@ IMPL_LINK(ScrollBarManager, VerticalScrollBarHandler, ScrollBar*, pScrollBar) if (pScrollBar!=NULL && pScrollBar==mpVerticalScrollBar.get() && pScrollBar->IsVisible() - && mrSlideSorter.GetView().GetWindow()!=NULL) + && mrSlideSorter.GetContentWindow()!=NULL) { double nRelativePosition = double(pScrollBar->GetThumbPos()) / double(pScrollBar->GetRange().Len()); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetView().GetWindow()->SetVisibleXY ( + mrSlideSorter.GetContentWindow()->SetVisibleXY ( -1, nRelativePosition); } @@ -349,12 +346,12 @@ IMPL_LINK(ScrollBarManager, HorizontalScrollBarHandler, ScrollBar*, pScrollBar) if (pScrollBar!=NULL && pScrollBar==mpHorizontalScrollBar.get() && pScrollBar->IsVisible() - && mrSlideSorter.GetView().GetWindow()!=NULL) + && mrSlideSorter.GetContentWindow()!=NULL) { double nRelativePosition = double(pScrollBar->GetThumbPos()) / double(pScrollBar->GetRange().Len()); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetView().GetWindow()->SetVisibleXY (nRelativePosition, -1); + mrSlideSorter.GetContentWindow()->SetVisibleXY (nRelativePosition, -1); } return TRUE; } @@ -369,7 +366,7 @@ void ScrollBarManager::SetWindowOrigin ( mnHorizontalPosition = nHorizontalPosition; mnVerticalPosition = nVerticalPosition; - ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); Size aViewSize (pWindow->GetViewSize()); Point aOrigin ( (long int) (mnHorizontalPosition * aViewSize.Width()), @@ -440,6 +437,8 @@ bool ScrollBarManager::TestScrollBarVisibilities ( { bool bAreVisibilitiesOK = true; + model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); + // Adapt the available size by subtracting the sizes of the scroll bars // visible in this combination. Size aBrowserSize (rAvailableArea.GetSize()); @@ -455,22 +454,21 @@ bool ScrollBarManager::TestScrollBarVisibilities ( { bRearrangeSuccess = mrSlideSorter.GetView().GetLayouter().RearrangeHorizontal ( aBrowserSize, - mrSlideSorter.GetModel().GetPageDescriptor(0)->GetPage()->GetSize(), - mpContentWindow.get(), - mrSlideSorter.GetModel().GetPageCount()); + rModel.GetPageDescriptor(0)->GetPage()->GetSize(), + rModel.GetPageCount()); } else { bRearrangeSuccess = mrSlideSorter.GetView().GetLayouter().RearrangeVertical ( aBrowserSize, - mrSlideSorter.GetModel().GetPageDescriptor(0)->GetPage()->GetSize(), - mpContentWindow.get()); + rModel.GetPageDescriptor(0)->GetPage()->GetSize(), + rModel.GetPageCount()); } if (bRearrangeSuccess) { Size aPageSize = mrSlideSorter.GetView().GetLayouter().GetPageBox ( - mrSlideSorter.GetModel().GetPageCount()).GetSize(); + rModel.GetPageCount()).GetSize(); Size aWindowModelSize = mpContentWindow->PixelToLogic(aBrowserSize); bool bHorizontallyClipped = (aPageSize.Width() > aWindowModelSize.Width()); @@ -493,11 +491,11 @@ void ScrollBarManager::SetTop (const sal_Int32 nNewTop) && mpVerticalScrollBar->GetThumbPos() != nNewTop) { // Flush pending repaints before scrolling to avoid temporary artifacts. - mrSlideSorter.GetView().GetWindow()->Update(); + mrSlideSorter.GetContentWindow()->Update(); mpVerticalScrollBar->SetThumbPos(nNewTop); mnVerticalPosition = double(nNewTop) / double(mpVerticalScrollBar->GetRange().Len()); - mrSlideSorter.GetView().GetWindow()->SetVisibleXY ( + mrSlideSorter.GetContentWindow()->SetVisibleXY ( mnHorizontalPosition, mnVerticalPosition); } } @@ -505,17 +503,28 @@ void ScrollBarManager::SetTop (const sal_Int32 nNewTop) +sal_Int32 ScrollBarManager::GetTop (void) const +{ + if (mpVerticalScrollBar != NULL) + return mpVerticalScrollBar->GetThumbPos(); + else + return 0; +} + + + + void ScrollBarManager::SetLeft (const sal_Int32 nNewLeft) { if (mpHorizontalScrollBar != NULL && mpHorizontalScrollBar->GetThumbPos() != nNewLeft) { // Flush pending repaints before scrolling to avoid temporary artifacts. - mrSlideSorter.GetView().GetWindow()->Update(); + mrSlideSorter.GetContentWindow()->Update(); mpHorizontalScrollBar->SetThumbPos(nNewLeft); mnHorizontalPosition = double(nNewLeft) / double(mpHorizontalScrollBar->GetRange().Len()); - mrSlideSorter.GetView().GetWindow()->SetVisibleXY ( + mrSlideSorter.GetContentWindow()->SetVisibleXY ( mnHorizontalPosition, mnVerticalPosition); } } @@ -523,6 +532,17 @@ void ScrollBarManager::SetLeft (const sal_Int32 nNewLeft) +sal_Int32 ScrollBarManager::GetLeft (void) const +{ + if (mpHorizontalScrollBar != NULL) + return mpHorizontalScrollBar->GetThumbPos(); + else + return 0; +} + + + + int ScrollBarManager::GetVerticalScrollBarWidth (void) const { if (mpVerticalScrollBar != NULL && mpVerticalScrollBar->IsVisible()) @@ -547,7 +567,7 @@ int ScrollBarManager::GetHorizontalScrollBarHeight (void) const void ScrollBarManager::CalcAutoScrollOffset (const Point& rMouseWindowPosition) { - ::sd::Window* pWindow = mrSlideSorter.GetView().GetWindow(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); int nDx = 0; int nDy = 0; @@ -602,14 +622,16 @@ void ScrollBarManager::CalcAutoScrollOffset (const Point& rMouseWindowPosition) -bool ScrollBarManager::AutoScroll (const Point& rMouseWindowPosition) +bool ScrollBarManager::AutoScroll ( + const Point& rMouseWindowPosition, + const ::boost::function& rAutoScrollFunctor) { - CalcAutoScrollOffset (rMouseWindowPosition); - bool bResult = RepeatAutoScroll(); - if (bResult) - { - maAutoScrollTimer.Start(); - } + maAutoScrollFunctor = rAutoScrollFunctor; + CalcAutoScrollOffset(rMouseWindowPosition); + bool bResult (true); + if ( ! mbIsAutoScrollActive) + bResult = RepeatAutoScroll(); + return bResult; } @@ -619,6 +641,7 @@ bool ScrollBarManager::AutoScroll (const Point& rMouseWindowPosition) void ScrollBarManager::StopAutoScroll (void) { maAutoScrollTimer.Stop(); + mbIsAutoScrollActive = false; } @@ -630,13 +653,23 @@ bool ScrollBarManager::RepeatAutoScroll (void) { if (mrSlideSorter.GetViewShell() != NULL) { - mrSlideSorter.GetViewShell()->ScrollLines( + mrSlideSorter.GetViewShell()->Scroll( maAutoScrollOffset.Width(), - maAutoScrollOffset.Height()); + maAutoScrollOffset.Height()); + mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); + + if (maAutoScrollFunctor) + maAutoScrollFunctor(); + + mbIsAutoScrollActive = true; + maAutoScrollTimer.Start(); + return true; } } + maAutoScrollFunctor = ::boost::function(); + mbIsAutoScrollActive = false; return false; } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 9ed68156f701..8cb815fd5787 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -40,6 +40,7 @@ #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsClipboard.hxx" #include "controller/SlsCurrentSlideManager.hxx" +#include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsSelectionManager.hxx" #include "controller/SlsProperties.hxx" #include "model/SlideSorterModel.hxx" @@ -48,16 +49,11 @@ #include "view/SlideSorterView.hxx" #include "view/SlsViewOverlay.hxx" #include "view/SlsLayouter.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" +#include "view/SlsPageObjectLayouter.hxx" #include "framework/FrameworkHelper.hxx" #include "showview.hxx" #include "ViewShellBase.hxx" #include "DrawController.hxx" -#include -#include -#include -#include -#include #include "Window.hxx" #include "sdpage.hxx" #include "drawdoc.hxx" @@ -67,6 +63,13 @@ #include "app.hrc" #include "sdresid.hxx" #include "strings.hrc" +#include +#include +#include +#include +#include +#include +#include namespace { static const sal_uInt32 SINGLE_CLICK (0x00000001); @@ -77,11 +80,13 @@ static const sal_uInt32 MIDDLE_BUTTON (0x00000040); static const sal_uInt32 BUTTON_DOWN (0x00000100); static const sal_uInt32 BUTTON_UP (0x00000200); static const sal_uInt32 MOUSE_MOTION (0x00000400); +static const sal_uInt32 MOUSE_DRAG (0x00000800); // The rest leaves the lower 16 bit untouched so that it can be used with // key codes. static const sal_uInt32 OVER_SELECTED_PAGE (0x00010000); static const sal_uInt32 OVER_UNSELECTED_PAGE (0x00020000); 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); @@ -94,6 +99,9 @@ static const sal_uInt32 NO_MODIFIER (0x00000000); static const sal_uInt32 SUBSTITUTION_NOT_VISIBLE (0x00000000); static const sal_uInt32 NOT_OVER_PAGE (0x00000000); +// Masks +static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIFIER); + } // end of anonymous namespace @@ -106,6 +114,8 @@ public: SubstitutionHandler (SlideSorter& rSlideSorter); ~SubstitutionHandler (void); + void SetHitDescriptor (const model::SharedPageDescriptor& rpHitDescriptor); + /** Create a substitution display of the currently selected pages and use the given position as the anchor point. */ @@ -115,7 +125,9 @@ public: travelled since the last call to this method or to CreateSubstitution(). The given point becomes the new anchor. */ - void UpdatePosition (const Point& rMouseModelPosition); + void UpdatePosition ( + const Point& rMousePosition, + const bool bAllowAutoScroll = true); /** Move the substitution display of the currently selected pages. */ @@ -123,42 +135,50 @@ public: void End (void); - bool HasBeenMoved (void) const; + bool IsActive (void) const; private: SlideSorter& mrSlideSorter; - - bool mbHasBeenMoved; - - /** Determine whether there is a) a substitution and b) its insertion at - the current position of the insertion marker would alter the - document. This would be the case when the substitution has been - moved or is not consecutive. - */ - bool IsSubstitutionInsertionNonTrivial (void) const; + model::SharedPageDescriptor mpHitDescriptor; + bool mbIsActive; + sal_Int32 mnInsertionIndex; }; -class SelectionFunction::InsertionIndicatorHandler +class SelectionFunction::RectangleSelector { public: - InsertionIndicatorHandler (SlideSorter& rSlideSorter); - ~InsertionIndicatorHandler (void); - - /** Show the insertion marker at the given coordinates. + /** Start a rectangle selection at the given position. */ - void Start (const Point& rMouseModelPosition); + RectangleSelector ( + SlideSorter& rSlideSorter, + const Point& rMouseModelPosition); + ~RectangleSelector (void); - void UpdatePosition (const Point& rMouseModelPosition); + void RestoreInitialSelection (void); - /** Hide the insertion marker. + /** Update the rectangle selection so that the given position becomes + the new second point of the selection rectangle. */ - void End (void); + void UpdatePosition ( + const Point& rMousePosition, + const bool bAllowAutoScroll = true); + + enum SelectionMode { SM_Normal, SM_Add, SM_Toggle }; + void SetSelectionMode (const SelectionMode eSelectionMode); + void SetSelectionModeFromModifier (const sal_uInt32 nEventCode); private: SlideSorter& mrSlideSorter; + SelectionMode meSelectionMode; + ::std::set maInitialSelection; + + /** Select all pages that lie completly in the selection rectangle. + */ + void ProcessRectangleSelection (void); }; + class SelectionFunction::EventDescriptor { public: @@ -168,6 +188,7 @@ public: ::boost::weak_ptr mpHitDescriptor; SdrPage* mpHitPage; sal_uInt32 mnEventCode; + sal_Int32 mnButtonIndex; EventDescriptor ( sal_uInt32 nEventType, @@ -176,6 +197,10 @@ public: EventDescriptor ( const KeyEvent& rEvent, SlideSorter& rSlideSorter); + EventDescriptor ( + const AcceptDropEvent& rEvent, + SlideSorter& rSlideSorter); + EventDescriptor (const EventDescriptor& rDescriptor); }; @@ -185,14 +210,23 @@ TYPEINIT1(SelectionFunction, FuPoor); SelectionFunction::SelectionFunction ( SlideSorter& rSlideSorter, SfxRequest& rRequest) - : SlideFunction (rSlideSorter, rRequest), + : FuPoor ( + rSlideSorter.GetViewShell(), + rSlideSorter.GetContentWindow().get(), + &rSlideSorter.GetView(), + rSlideSorter.GetModel().GetDocument(), + rRequest), mrSlideSorter(rSlideSorter), mrController(mrSlideSorter.GetController()), mbDragSelection(false), maInsertionMarkerBox(), mbProcessingMouseButtonDown(false), mpSubstitutionHandler(new SubstitutionHandler(mrSlideSorter)), - mpInsertionIndicatorHandler(new InsertionIndicatorHandler(mrSlideSorter)) + mpRectangleSelector(), + mnButtonDownPageIndex(-1), + mnButtonDownButtonIndex(-1), + mbIsDeselectionPending(false), + mnShiftKeySelectionAnchor(-1) { //af aDelayToScrollTimer.SetTimeout(50); aDragTimer.SetTimeoutHdl( LINK( this, SelectionFunction, DragSlideHdl ) ); @@ -221,6 +255,7 @@ BOOL SelectionFunction::MouseButtonDown (const MouseEvent& rEvent) { // #95491# remember button state for creation of own MouseEvents SetMouseButtonCode (rEvent.GetButtons()); + aMDPos = rEvent.GetPosPixel(); mbProcessingMouseButtonDown = true; mpWindow->CaptureMouse(); @@ -237,16 +272,6 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) { Point aMousePosition (rEvent.GetPosPixel()); - // Determine page under mouse and show the mouse over effect. - model::SharedPageDescriptor pHitDescriptor (mrController.GetPageAt(aMousePosition)); - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetMouseOverIndicatorOverlay().SetSlideUnderMouse( - rEvent.IsLeaveWindow() ? model::SharedPageDescriptor() : pHitDescriptor); - if (pHitDescriptor.get() != NULL) - rOverlay.GetMouseOverIndicatorOverlay().setVisible(true); - else - rOverlay.GetMouseOverIndicatorOverlay().setVisible(false); - // Allow one mouse move before the drag timer is disabled. if (aDragTimer.IsActive()) { @@ -256,12 +281,26 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) aDragTimer.Stop(); } + + // In some modes (dragging, moving) the mouse over indicator is only + // annoying. Turn it off in these cases. + if (mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay()->IsVisible() + || mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay()->IsVisible()) + { + mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); + } + else + { + UpdatePageUnderMouse(aMousePosition, (rEvent.GetButtons() & MOUSE_LEFT)!=0); + } + + view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel()); if ( ! aRectangle.IsInside(aMousePosition) - && rOverlay.GetSubstitutionOverlay().isVisible()) + && rOverlay.GetSubstitutionOverlay()->IsVisible()) { // Mouse left the window with pressed left button. Make it a drag. - StartDrag(); + StartDrag(aMousePosition); } else { @@ -301,6 +340,31 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent) +void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) +{ + // 1. Compute some frequently used values relating to the event. + ::std::auto_ptr pEventDescriptor ( + new EventDescriptor(rEvent, mrSlideSorter)); + + // 2. Detect whether we are dragging pages or dragging a selection rectangle. + view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); + if (rOverlay.GetSubstitutionOverlay()->IsVisible()) + pEventDescriptor->mnEventCode |= SUBSTITUTION_VISIBLE; + if (mpRectangleSelector) + pEventDescriptor->mnEventCode |= RECTANGLE_VISIBLE; + + // 3. Process the event. + EventPreprocessing(*pEventDescriptor); + if ( ! EventProcessing(*pEventDescriptor)) + { + OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); + } + EventPostprocessing(*pEventDescriptor); +} + + + + BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) { FocusManager& rFocusManager (mrController.GetFocusManager()); @@ -334,6 +398,13 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) case KEY_ESCAPE: rFocusManager.SetFocusToToolBox(); + if (mpSubstitutionHandler->IsActive()) + mpSubstitutionHandler->End(); + if (mpRectangleSelector) + { + mpRectangleSelector->RestoreInitialSelection(); + mpRectangleSelector.reset(); + } bResult = TRUE; break; @@ -345,7 +416,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) { // Doing a multi selection by default. Can we ask the event // for the state of the shift key? - if (pDescriptor->IsSelected()) + if (pDescriptor->HasState(model::PageDescriptor::ST_Selected)) mrController.GetPageSelector().DeselectPage(pDescriptor); else mrController.GetPageSelector().SelectPage(pDescriptor); @@ -357,25 +428,25 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) // Move the focus indicator left. case KEY_LEFT: - rFocusManager.MoveFocus (FocusManager::FMD_LEFT); + MoveFocus(FocusManager::FMD_LEFT, rEvent.GetKeyCode().IsShift()); bResult = TRUE; break; // Move the focus indicator right. case KEY_RIGHT: - rFocusManager.MoveFocus (FocusManager::FMD_RIGHT); + MoveFocus(FocusManager::FMD_RIGHT, rEvent.GetKeyCode().IsShift()); bResult = TRUE; break; // Move the focus indicator up. case KEY_UP: - rFocusManager.MoveFocus (FocusManager::FMD_UP); + MoveFocus(FocusManager::FMD_UP, rEvent.GetKeyCode().IsShift()); bResult = TRUE; break; // Move the focus indicator down. case KEY_DOWN: - rFocusManager.MoveFocus (FocusManager::FMD_DOWN); + MoveFocus(FocusManager::FMD_DOWN, rEvent.GetKeyCode().IsShift()); bResult = TRUE; break; @@ -394,7 +465,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) case KEY_DELETE: case KEY_BACKSPACE: { - if (mrController.GetProperties()->IsUIReadOnly()) + if (mrSlideSorter.GetProperties()->IsUIReadOnly()) break; int nSelectedPagesCount = 0; @@ -414,13 +485,18 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) if (nSelectedPagesCount > 0) mrController.GetSelectionManager()->DeleteSelectedPages(); + mnShiftKeySelectionAnchor = -1; bResult = TRUE; } break; case KEY_F10: if (rEvent.GetKeyCode().IsShift()) - ProcessKeyEvent(rEvent); + { + DeselectAllPages(); + mrController.GetPageSelector().SelectPage( + mrSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); + } break; default: @@ -428,7 +504,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) } if ( ! bResult) - bResult = SlideFunction::KeyInput (rEvent); + bResult = FuPoor::KeyInput(rEvent); return bResult; } @@ -436,6 +512,62 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) +void SelectionFunction::MoveFocus ( + const FocusManager::FocusMoveDirection eDirection, + const bool bIsShiftDown) +{ + // Remember the anchor of shift key multi selection. + if (bIsShiftDown) + { + if (mnShiftKeySelectionAnchor<0) + { + model::SharedPageDescriptor pFocusedDescriptor ( + mrController.GetFocusManager().GetFocusedPageDescriptor()); + mnShiftKeySelectionAnchor = pFocusedDescriptor->GetPageIndex(); + } + } + else + mnShiftKeySelectionAnchor = -1; + + mrController.GetFocusManager().MoveFocus(eDirection); + + // When shift is pressed then select all pages in the range between the + // currently and the previously focused pages, including them. + if (bIsShiftDown) + { + model::SharedPageDescriptor pFocusedDescriptor ( + mrController.GetFocusManager().GetFocusedPageDescriptor()); + if (pFocusedDescriptor) + { + PageSelector& rSelector (mrController.GetPageSelector()); + sal_Int32 nPageRangeEnd (pFocusedDescriptor->GetPageIndex()); + model::PageEnumeration aPages ( + model::PageEnumerationProvider::CreateAllPagesEnumeration( + mrSlideSorter.GetModel())); + while (aPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aPages.GetNextElement()); + if (pDescriptor) + { + const sal_Int32 nPageIndex(pDescriptor->GetPageIndex()); + if ((nPageIndex>=mnShiftKeySelectionAnchor && nPageIndex<=nPageRangeEnd) + || (nPageIndex<=mnShiftKeySelectionAnchor && nPageIndex>=nPageRangeEnd)) + { + rSelector.SelectPage(pDescriptor); + } + else + { + rSelector.DeselectPage(pDescriptor); + } + } + } + } + } +} + + + + void SelectionFunction::Activate() { FuPoor::Activate(); @@ -467,7 +599,7 @@ void SelectionFunction::ScrollEnd (void) void SelectionFunction::DoCut (void) { - if ( ! mrController.GetProperties()->IsUIReadOnly()) + if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { mrController.GetClipboard().DoCut(); } @@ -486,7 +618,7 @@ void SelectionFunction::DoCopy (void) void SelectionFunction::DoPaste (void) { - if ( ! mrController.GetProperties()->IsUIReadOnly()) + if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { mrController.GetClipboard().DoPaste(); } @@ -495,8 +627,13 @@ void SelectionFunction::DoPaste (void) -void SelectionFunction::Paint (const Rectangle&, ::sd::Window* ) +void SelectionFunction::StartDragTimer (void) { + if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) + { + bFirstMouseMove = TRUE; + aDragTimer.Start(); + } } @@ -504,20 +641,20 @@ void SelectionFunction::Paint (const Rectangle&, ::sd::Window* ) IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG ) { - StartDrag(); + StartDrag(aMDPos); return 0; } -void SelectionFunction::StartDrag (void) +void SelectionFunction::StartDrag (const Point& rMousePosition) { if (mbPageHit - && ! mrController.GetProperties()->IsUIReadOnly()) + && ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - mpSubstitutionHandler->Start(rOverlay.GetSubstitutionOverlay().GetPosition()); + mpSubstitutionHandler->Start(rMousePosition); mbPageHit = false; mpWindow->ReleaseMouse(); @@ -525,9 +662,7 @@ void SelectionFunction::StartDrag (void) { SlideSorterViewShell* pSlideSorterViewShell = dynamic_cast(mrSlideSorter.GetViewShell()); - pSlideSorterViewShell->StartDrag ( - rOverlay.GetSubstitutionOverlay().GetPosition(), - mpWindow); + pSlideSorterViewShell->StartDrag (rMousePosition, mpWindow); } } } @@ -544,105 +679,11 @@ bool SelectionFunction::cancel (void) -void SelectionFunction::SelectHitPage (const model::SharedPageDescriptor& rpDescriptor) -{ - mrController.GetPageSelector().SelectPage(rpDescriptor); -} - - - - -void SelectionFunction::DeselectHitPage (const model::SharedPageDescriptor& rpDescriptor) -{ - mrController.GetPageSelector().DeselectPage(rpDescriptor); -} - - - - void SelectionFunction::DeselectAllPages (void) { + mbIsDeselectionPending = false; mrController.GetPageSelector().DeselectAllPages(); -} - - - - -void SelectionFunction::StartRectangleSelection (const Point& rMouseModelPosition) -{ - if (mrController.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay().Start( - rMouseModelPosition); - } -} - - - - -void SelectionFunction::UpdateRectangleSelection (const Point& rMouseModelPosition) -{ - if (mrController.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay().Update( - rMouseModelPosition); - } -} - - - - -void SelectionFunction::ProcessRectangleSelection (bool bToggleSelection) -{ - if ( ! mrController.GetProperties()->IsShowSelection()) - return; - - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if (rOverlay.GetSelectionRectangleOverlay().isVisible()) - { - PageSelector& rSelector (mrController.GetPageSelector()); - - rOverlay.GetSelectionRectangleOverlay().setVisible(false); - - // Select all pages whose page object lies completly inside the drag - // rectangle. - const Rectangle& rSelectionRectangle ( - rOverlay.GetSelectionRectangleOverlay().GetSelectionRectangle()); - model::PageEnumeration aPages ( - model::PageEnumerationProvider::CreateAllPagesEnumeration( - mrSlideSorter.GetModel())); - while (aPages.HasMoreElements()) - { - model::SharedPageDescriptor pDescriptor (aPages.GetNextElement()); - Rectangle aPageBox (mrSlideSorter.GetView().GetPageBoundingBox( - pDescriptor, - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_SHAPE)); - if (rSelectionRectangle.IsOver(aPageBox)) - { - // When we are extending the selection (shift key is - // pressed) then toggle the selection state of the page. - // Otherwise select it: this results in the previously - // selected pages becoming deslected. - if (bToggleSelection && pDescriptor->IsSelected()) - rSelector.DeselectPage(pDescriptor); - else - rSelector.SelectPage(pDescriptor); - } - } - } -} - - - - -void SelectionFunction::PrepareMouseMotion (const Point& ) -{ - if ( ! mrController.GetProperties()->IsUIReadOnly()) - { - bFirstMouseMove = TRUE; - aDragTimer.Start(); - } + mnShiftKeySelectionAnchor = -1; } @@ -708,6 +749,7 @@ void SelectionFunction::GotoNextPage (int nOffset) OSL_ASSERT(pNextPageDescriptor.get() != NULL); } } + mnShiftKeySelectionAnchor = -1; } @@ -717,11 +759,10 @@ void SelectionFunction::ClearOverlays (void) { view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay().setVisible(false); - rOverlay.GetSubstitutionOverlay().Clear(); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); + rOverlay.GetSubstitutionOverlay()->Clear(); - mpInsertionIndicatorHandler->End(); - rOverlay.GetMouseOverIndicatorOverlay().SetSlideUnderMouse(model::SharedPageDescriptor()); + mrController.GetInsertionIndicatorHandler()->End(); } @@ -738,7 +779,8 @@ void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEve // 2. Compute a numerical code that describes the event and that is used // for fast look-up of the associated reaction. - pEventDescriptor->mnEventCode = EncodeMouseEvent(*pEventDescriptor, rEvent); + pEventDescriptor->mnEventCode + = EncodeMouseEvent(*pEventDescriptor, rEvent) | EncodeState(*pEventDescriptor); // 3. Process the event. EventPreprocessing(*pEventDescriptor); @@ -777,54 +819,22 @@ sal_uInt32 SelectionFunction::EncodeMouseEvent ( case 2: nEventCode |= DOUBLE_CLICK; break; } - // Detect whether the event has happened over a page object. - if (rDescriptor.mpHitPage != NULL && ! rDescriptor.mpHitDescriptor.expired()) - { - model::SharedPageDescriptor pHitDescriptor (rDescriptor.mpHitDescriptor); - if (pHitDescriptor->IsSelected()) - nEventCode |= OVER_SELECTED_PAGE; - else - nEventCode |= OVER_UNSELECTED_PAGE; - } - // Detect pressed modifier keys. if (rEvent.IsShift()) nEventCode |= SHIFT_MODIFIER; if (rEvent.IsMod1()) nEventCode |= CONTROL_MODIFIER; - // Detect whether we are dragging pages or dragging a selection rectangle. - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if (rOverlay.GetSubstitutionOverlay().isVisible()) - nEventCode |= SUBSTITUTION_VISIBLE; - if (rOverlay.GetSelectionRectangleOverlay().isVisible()) - nEventCode |= RECTANGLE_VISIBLE; + // Detect whether the mouse is over one of the active elements inside a + // page object. + if (rDescriptor.mnButtonIndex >= 0) + nEventCode |= OVER_BUTTON; return nEventCode; } - -void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent) -{ - // 1. Compute some frequently used values relating to the event. - ::std::auto_ptr pEventDescriptor ( - new EventDescriptor(rEvent, mrSlideSorter)); - - // 2. Encode the event. - pEventDescriptor->mnEventCode = EncodeKeyEvent(*pEventDescriptor, rEvent); - - // 3. Process the event. - EventPreprocessing(*pEventDescriptor); - if ( ! EventProcessing(*pEventDescriptor)) - OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); - EventPostprocessing(*pEventDescriptor); -} - - - - sal_uInt32 SelectionFunction::EncodeKeyEvent ( const EventDescriptor& rDescriptor, const KeyEvent& rEvent) const @@ -841,21 +851,37 @@ sal_uInt32 SelectionFunction::EncodeKeyEvent ( if (rEvent.GetKeyCode().IsMod1()) nEventCode |= CONTROL_MODIFIER; + return nEventCode; +} + + + + +sal_uInt32 SelectionFunction::EncodeState ( + const EventDescriptor& rDescriptor) const +{ + sal_uInt32 nEventCode (0); + // Detect whether the event has happened over a page object. if (rDescriptor.mpHitPage != NULL && ! rDescriptor.mpHitDescriptor.expired()) { model::SharedPageDescriptor pHitDescriptor (rDescriptor.mpHitDescriptor); - if (pHitDescriptor->IsSelected()) + if (pHitDescriptor->HasState(model::PageDescriptor::ST_Selected)) nEventCode |= OVER_SELECTED_PAGE; else nEventCode |= OVER_UNSELECTED_PAGE; + + // Detect whether the mouse is over one of the active elements + // inside a page object. + if (rDescriptor.mnButtonIndex >= 0) + nEventCode |= OVER_BUTTON; } // Detect whether we are dragging pages or dragging a selection rectangle. view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if (rOverlay.GetSubstitutionOverlay().isVisible()) + if (rOverlay.GetSubstitutionOverlay()->IsVisible()) nEventCode |= SUBSTITUTION_VISIBLE; - if (rOverlay.GetSelectionRectangleOverlay().isVisible()) + if (mpRectangleSelector) nEventCode |= RECTANGLE_VISIBLE; return nEventCode; @@ -863,6 +889,27 @@ sal_uInt32 SelectionFunction::EncodeKeyEvent ( + +void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent) +{ + // 1. Compute some frequently used values relating to the event. + ::std::auto_ptr pEventDescriptor ( + new EventDescriptor(rEvent, mrSlideSorter)); + + // 2. Encode the event. + pEventDescriptor->mnEventCode + = EncodeKeyEvent(*pEventDescriptor, rEvent) | EncodeState(*pEventDescriptor); + + // 3. Process the event. + EventPreprocessing(*pEventDescriptor); + if ( ! EventProcessing(*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. @@ -870,8 +917,21 @@ void SelectionFunction::EventPreprocessing (const EventDescriptor& rDescriptor) 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); + // if (rDescriptor.mpHitPage != NULL) + // + // mrController.GetFocusManager().FocusPage((rDescriptor.mpHitPage->GetPageNum()-1)/2); +} + + + + +bool Match ( + const sal_uInt32 nEventCode, + const sal_uInt32 nPositivePattern, + const sal_uInt32 nNegativePattern = 0) +{ + return (nEventCode & nPositivePattern)==nPositivePattern + && (nEventCode & nNegativePattern)==0; } @@ -880,13 +940,13 @@ void SelectionFunction::EventPreprocessing (const EventDescriptor& rDescriptor) bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) { // Define some macros to make the following switch statement more readable. -#define ANY_MODIFIER(code) \ - code|NO_MODIFIER: \ - case code|SHIFT_MODIFIER: \ +#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: \ +#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): \ @@ -907,148 +967,180 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) if ( ! rDescriptor.mpHitDescriptor.expired()) pHitDescriptor = model::SharedPageDescriptor(rDescriptor.mpHitDescriptor); - switch (rDescriptor.mnEventCode) + switch (rDescriptor.mnEventCode & (SUBSTITUTION_VISIBLE | RECTANGLE_VISIBLE)) { - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE: - SetCurrentPage(pHitDescriptor); - PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition)); - mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition); - break; - - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: - SetCurrentPage(pHitDescriptor); - mpSubstitutionHandler->End(); - break; - - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: - PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition)); - mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition); - 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; - - // Multi selection with the control modifier. - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER: - DeselectHitPage(pHitDescriptor); - PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition)); - break; - - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | CONTROL_MODIFIER: - SelectHitPage(pHitDescriptor); - PrepareMouseMotion(mpWindow->PixelToLogic(rDescriptor.maMousePosition)); - - 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; - - // Was: Preview of the page transition effect. - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_FADE_INDICATOR: - // No action. - break; - - // Right button for context menu. - case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE: - case KEY_EVENT | KEY_F10 | SHIFT_MODIFIER | 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(); - SelectHitPage(pHitDescriptor); - SetCurrentPage(pHitDescriptor); - bMakeSelectionVisible = false; - break; - - case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: - case KEY_EVENT | KEY_F10 | OVER_SELECTED_PAGE | SHIFT_MODIFIER: - // Do not change the selection. Just adjust the insertion indicator. - bMakeSelectionVisible = false; - break; - - case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: - // The Shift+F10 key event is here just for completeness. It should - // not be possible to really receive this (not being over a page.) - case KEY_EVENT | KEY_F10 | SHIFT_MODIFIER | NOT_OVER_PAGE: - DeselectAllPages(); - bMakeSelectionVisible = false; - break; - - // A mouse motion without visible substitution starts that. - case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE): - mrController.GetScrollBarManager().AutoScroll(rDescriptor.maMousePosition); - mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition); - break; - - // Move substitution. - case ANY_PAGE_AND_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | SUBSTITUTION_VISIBLE): - if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0) - StartDrag(); - mrController.GetScrollBarManager().AutoScroll(rDescriptor.maMousePosition); - mpSubstitutionHandler->UpdatePosition(rDescriptor.maMouseModelPosition); - break; - - // Place substitution. - case ANY_PAGE_AND_MODIFIER(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | SUBSTITUTION_VISIBLE): - // When the substitution has not been moved the button up event - // is taken to be part of a single click. The selected pages - // are therefore not moved (which technically would be necessary - // for unconsecutive multi selections). Instead the page under - // the mouse becomes the only selected page. - if (mpSubstitutionHandler->HasBeenMoved()) + case SUBSTITUTION_VISIBLE: + // The substitution is visible. Handle events accordingly. + if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) + { + // Move substitution. + mpSubstitutionHandler->SetHitDescriptor(pHitDescriptor); + if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0) + StartDrag(rDescriptor.maMousePosition); + mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition); + } + else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG)) + { + mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition); + } + 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->End(); mpSubstitutionHandler->Process(); } - else - if (pHitDescriptor != NULL) - SetCurrentPage(pHitDescriptor); - mpSubstitutionHandler->End(); - break; - - // Rectangle selection. - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE | NO_MODIFIER: - DeselectAllPages(); - StartRectangleSelection(rDescriptor.maMouseModelPosition); - break; - - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE | SHIFT_MODIFIER: - case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE | CONTROL_MODIFIER: - StartRectangleSelection(rDescriptor.maMouseModelPosition); - break; - - case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): - case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE): - case ANY_PAGE_AND_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE): - mrController.GetScrollBarManager().AutoScroll(rDescriptor.maMousePosition); - UpdateRectangleSelection(rDescriptor.maMouseModelPosition); break; - case ANY_PAGE(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE | NO_MODIFIER): - ProcessRectangleSelection(false); - break; - - case ANY_PAGE(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE | SHIFT_MODIFIER): - case ANY_PAGE(BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | RECTANGLE_VISIBLE | CONTROL_MODIFIER): - ProcessRectangleSelection(true); + case RECTANGLE_VISIBLE: + OSL_ASSERT(mpRectangleSelector); + // The selection rectangle is visible. Handle events accordingly. + if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) + { + if (mpRectangleSelector) + { + mpRectangleSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); + mpRectangleSelector->UpdatePosition(rDescriptor.maMousePosition); + } + bMakeSelectionVisible = false; + } + else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK)) + { + mpRectangleSelector.reset(); + } + // Anything else stops the rectangle selection and the event is + // processed again. + else + { + mpRectangleSelector.reset(); + EventDescriptor aModifiedDescriptor (rDescriptor); + aModifiedDescriptor.mnEventCode &= ~RECTANGLE_VISIBLE; + EventProcessing(aModifiedDescriptor); + } break; default: - bResult = false; - break; + OSL_ASSERT(!mpRectangleSelector); + 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(!mpRectangleSelector); + break; + } + 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; + } + 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->SetHitDescriptor(pHitDescriptor); + mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition); + 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(!mpRectangleSelector); + mpRectangleSelector.reset( + new RectangleSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); + mpRectangleSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); + break; + } + break; + } } + mrController.GetPageSelector().EnableBroadcasting(bMakeSelectionVisible); return bResult; @@ -1070,20 +1162,23 @@ void SelectionFunction::EventPostprocessing (const EventDescriptor& rDescriptor) // case that the context menu is visible. DBG_ASSERT( mrController.IsContextMenuOpen() - || !rOverlay.GetInsertionIndicatorOverlay().isVisible(), + || !rOverlay.GetInsertionIndicatorOverlay()->IsVisible(), "slidesorter::SelectionFunction: insertion indicator still visible"); DBG_ASSERT( - !rOverlay.GetSubstitutionOverlay().isVisible(), + !rOverlay.GetSubstitutionOverlay()->IsVisible(), "slidesorter::SelectionFunction: substitution still visible"); DBG_ASSERT( - !rOverlay.GetSelectionRectangleOverlay().isVisible(), + !rOverlay.GetSelectionRectangleOverlay()->IsVisible(), "slidesorter::SelectionFunction: selection rectangle still visible"); // Now turn them off. if ( ! mrController.IsContextMenuOpen()) - rOverlay.GetInsertionIndicatorOverlay().setVisible(false); - rOverlay.GetSubstitutionOverlay().setVisible(false); - rOverlay.GetSelectionRectangleOverlay().setVisible(false); + rOverlay.GetInsertionIndicatorOverlay()->SetIsVisible(false); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); + rOverlay.GetSelectionRectangleOverlay()->SetIsVisible(false); + + mnButtonDownPageIndex = -1; + mnButtonDownButtonIndex = -1; } } @@ -1097,6 +1192,9 @@ void SelectionFunction::SetCurrentPage (const model::SharedPageDescriptor& rpDes rSelector.SelectPage(rpDescriptor); mrController.GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor); + mrController.GetFocusManager().SetFocusedPage(rpDescriptor); + + mnShiftKeySelectionAnchor = -1; } @@ -1125,6 +1223,83 @@ void SelectionFunction::SwitchView (const model::SharedPageDescriptor& rpDescrip +void SelectionFunction::UpdatePageUnderMouse ( + const Point& rMousePosition, + const bool bIsMouseButtonDown) +{ + // Determine page under mouse and show the mouse over effect. + model::SharedPageDescriptor pHitDescriptor ( + mrController.GetPageAt(rMousePosition)); + mrSlideSorter.GetView().SetPageUnderMouse(pHitDescriptor); + + // Handle the mouse being over any buttons. + if (pHitDescriptor) + { + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + const sal_Int32 nButtonIndex ( + mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt ( + pHitDescriptor, + aMouseModelPosition)); + mrSlideSorter.GetView().SetButtonUnderMouse(nButtonIndex); + if (bIsMouseButtonDown) + { + pHitDescriptor->GetVisualState().SetActiveButtonState( + nButtonIndex, + model::VisualState::BS_Pressed); + } + } +} + + + + +void SelectionFunction::ProcessButtonClick ( + const model::SharedPageDescriptor& rpDescriptor, + const sal_Int32 nButtonIndex) +{ + OSL_ASSERT(rpDescriptor); + + PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); + switch (nButtonIndex) + { + case 2: + // Start slide show at current slide. + mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide( + rpDescriptor); + if (mrSlideSorter.GetViewShell() != NULL) + mrSlideSorter.GetViewShell()->GetDispatcher()->Execute( + SID_PRESENTATION, + SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); + break; + + case 1: + // Toggle exclusion state. + rSelector.DeselectAllPages(); + rSelector.SelectPage(rpDescriptor); + if (mrSlideSorter.GetViewShell() != NULL) + mrSlideSorter.GetViewShell()->GetDispatcher()->Execute( + rpDescriptor->HasState(model::PageDescriptor::ST_Excluded) + ? SID_SHOW_SLIDE + : SID_HIDE_SLIDE, + SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); + break; + + case 0: + // Insert page after current page. + rSelector.DeselectAllPages(); + rSelector.SelectPage(rpDescriptor); + if (mrSlideSorter.GetViewShell() != NULL) + mrSlideSorter.GetViewShell()->GetDispatcher()->Execute( + SID_INSERTPAGE, + SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); + break; + } +} + + + + //===== EventDescriptor ======================================================= SelectionFunction::EventDescriptor::EventDescriptor ( @@ -1135,9 +1310,10 @@ SelectionFunction::EventDescriptor::EventDescriptor ( maMouseModelPosition(), mpHitDescriptor(), mpHitPage(), - mnEventCode(nEventType) + mnEventCode(nEventType), + mnButtonIndex(-1) { - ::Window* pWindow = rSlideSorter.GetActiveWindow(); + ::boost::shared_ptr pWindow (rSlideSorter.GetContentWindow()); maMousePosition = rEvent.GetPosPixel(); maMouseModelPosition = pWindow->PixelToLogic(maMousePosition); @@ -1147,6 +1323,11 @@ SelectionFunction::EventDescriptor::EventDescriptor ( { mpHitDescriptor = pHitDescriptor; mpHitPage = pHitDescriptor->GetPage(); + + mnButtonIndex = rSlideSorter.GetView().GetLayouter() + .GetPageObjectLayouter()->GetButtonIndexAt( + pHitDescriptor, + maMouseModelPosition); } } @@ -1161,9 +1342,9 @@ SelectionFunction::EventDescriptor::EventDescriptor ( maMouseModelPosition(), mpHitDescriptor(), mpHitPage(), - mnEventCode(0) + mnEventCode(0), + mnButtonIndex(-1) { - mpHitDescriptor = rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor(); model::SharedPageDescriptor pHitDescriptor ( rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); if (pHitDescriptor.get() != NULL) @@ -1177,11 +1358,51 @@ SelectionFunction::EventDescriptor::EventDescriptor ( +SelectionFunction::EventDescriptor::EventDescriptor ( + const AcceptDropEvent& rEvent, + SlideSorter& rSlideSorter) + : maMousePosition(rEvent.maPosPixel), + maMouseModelPosition(), + mpHitDescriptor(), + mpHitPage(), + mnEventCode(MOUSE_DRAG), + mnButtonIndex(-1) +{ + ::boost::shared_ptr pWindow (rSlideSorter.GetContentWindow()); + + maMouseModelPosition = pWindow->PixelToLogic(maMousePosition); + model::SharedPageDescriptor pHitDescriptor ( + rSlideSorter.GetController().GetPageAt(maMousePosition)); + if (pHitDescriptor.get() != NULL) + { + mpHitDescriptor = pHitDescriptor; + mpHitPage = pHitDescriptor->GetPage(); + } +} + + + + +SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDescriptor) + : maMousePosition(rDescriptor.maMousePosition), + maMouseModelPosition(rDescriptor.maMouseModelPosition), + mpHitDescriptor(rDescriptor.mpHitDescriptor), + mpHitPage(rDescriptor.mpHitPage), + mnEventCode(rDescriptor.mnEventCode), + mnButtonIndex(rDescriptor.mnButtonIndex) +{ +} + + + + //===== SubstitutionHandler =================================================== SelectionFunction::SubstitutionHandler::SubstitutionHandler (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), - mbHasBeenMoved(false) + mpHitDescriptor(), + mbIsActive(false), + mnInsertionIndex(-1) { } @@ -1190,59 +1411,98 @@ SelectionFunction::SubstitutionHandler::SubstitutionHandler (SlideSorter& rSlide SelectionFunction::SubstitutionHandler::~SubstitutionHandler (void) { + OSL_ASSERT(!mbIsActive); if (mrSlideSorter.IsValid()) { view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay().setVisible(false); - rOverlay.GetSubstitutionOverlay().Clear(); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); + rOverlay.GetSubstitutionOverlay()->Clear(); } } +void SelectionFunction::SubstitutionHandler::SetHitDescriptor ( + const model::SharedPageDescriptor& rpHitDescriptor) +{ + mpHitDescriptor = rpHitDescriptor; +} + + + + void SelectionFunction::SubstitutionHandler::Start (const Point& rMouseModelPosition) { + OSL_ASSERT(!mbIsActive); + mbIsActive = true; + mnInsertionIndex = -1; + // No Drag-and-Drop for master pages. if (mrSlideSorter.GetModel().GetEditMode() != EM_PAGE) return; - if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly()) + if (mrSlideSorter.GetProperties()->IsUIReadOnly()) return; view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if ( ! rOverlay.GetSubstitutionOverlay().isVisible()) + if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible()) { // Show a new substitution for the selected page objects. model::PageEnumeration aSelectedPages( model::PageEnumerationProvider::CreateSelectedPagesEnumeration( mrSlideSorter.GetModel())); - rOverlay.GetSubstitutionOverlay().Create(aSelectedPages, rMouseModelPosition); - rOverlay.GetSubstitutionOverlay().setVisible(true); - mbHasBeenMoved = false; + rOverlay.GetSubstitutionOverlay()->Create( + aSelectedPages, + rMouseModelPosition, + mpHitDescriptor); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(rMouseModelPosition); } - else - UpdatePosition(rMouseModelPosition); } -void SelectionFunction::SubstitutionHandler::UpdatePosition (const Point& rMouseModelPosition) +void SelectionFunction::SubstitutionHandler::UpdatePosition ( + const Point& rMousePosition, + const bool bAllowAutoScroll) { - if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly()) + OSL_ASSERT(mbIsActive); + + if (mrSlideSorter.GetProperties()->IsUIReadOnly()) return; - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); + // Convert window coordinates into model coordinates (we need the + // window coordinates for auto-scrolling because that remains + // constant while scrolling.) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + + if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll( + rMousePosition, + ::boost::bind( + &SelectionFunction::SubstitutionHandler::UpdatePosition, + this, + rMousePosition, + false)))) + { + view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - // Move the existing substitution to the new position. - rOverlay.GetSubstitutionOverlay().SetPosition(rMouseModelPosition); + // Move the existing substitution to the new position. + rOverlay.GetSubstitutionOverlay()->SetPosition(aMouseModelPosition); - rOverlay.GetInsertionIndicatorOverlay().SetPosition(rMouseModelPosition); - rOverlay.GetInsertionIndicatorOverlay().setVisible(true); + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdatePosition( + aMouseModelPosition); - mbHasBeenMoved = true; + // Remember the new insertion index. + if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial()) + mnInsertionIndex = -1; + else + mnInsertionIndex = mrSlideSorter.GetController().GetInsertionIndicatorHandler() + ->GetInsertionPageIndex(); + } } @@ -1250,22 +1510,16 @@ void SelectionFunction::SubstitutionHandler::UpdatePosition (const Point& rMouse void SelectionFunction::SubstitutionHandler::Process (void) { - if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly()) + if (mrSlideSorter.GetProperties()->IsUIReadOnly()) return; - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - - if (IsSubstitutionInsertionNonTrivial()) + if (mnInsertionIndex >= 0) { // Tell the model to move the selected pages behind the one with the // index mnInsertionIndex which first has to transformed into an index // understandable by the document. - sal_Int32 nInsertionIndex = rOverlay.GetInsertionIndicatorOverlay().GetInsertionPageIndex(); - if (nInsertionIndex >= 0) - { - USHORT nDocumentIndex = (USHORT)nInsertionIndex-1; - mrSlideSorter.GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex); - } + USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1; + mrSlideSorter.GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex); ViewShell* pViewShell = mrSlideSorter.GetViewShell(); if (pViewShell != NULL) @@ -1278,130 +1532,223 @@ void SelectionFunction::SubstitutionHandler::Process (void) void SelectionFunction::SubstitutionHandler::End (void) { + OSL_ASSERT(mbIsActive); + mbIsActive = false; + view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay().setVisible(false); - rOverlay.GetSubstitutionOverlay().Clear(); - rOverlay.GetInsertionIndicatorOverlay().setVisible(false); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); + rOverlay.GetSubstitutionOverlay()->Clear(); + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(); + mpHitDescriptor.reset(); } -bool SelectionFunction::SubstitutionHandler::HasBeenMoved (void) const +bool SelectionFunction::SubstitutionHandler::IsActive (void) const { - return mbHasBeenMoved; + return mbIsActive; } -bool SelectionFunction::SubstitutionHandler::IsSubstitutionInsertionNonTrivial (void) const +//===== SelectionFunction::RectangleSelector ================================== + +SelectionFunction::RectangleSelector::RectangleSelector ( + SlideSorter& rSlideSorter, + const Point& rMouseModelPosition) + : mrSlideSorter(rSlideSorter), + meSelectionMode(SM_Normal), + maInitialSelection() { - bool bIsNonTrivial = false; + if (mrSlideSorter.GetProperties()->IsShowSelection()) + { + mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay() + ->Start(rMouseModelPosition); + } - do + // Remember the current selection. + model::PageEnumeration aPages ( + model::PageEnumerationProvider::CreateAllPagesEnumeration( + mrSlideSorter.GetModel())); + while (aPages.HasMoreElements()) { - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); + model::SharedPageDescriptor pDescriptor (aPages.GetNextElement()); + pDescriptor->SetState( + model::PageDescriptor::ST_WasSelected, + pDescriptor->HasState(model::PageDescriptor::ST_Selected)); + } +} - // Make sure that the substitution and the insertion indicator are visible. - if ( ! rOverlay.GetSubstitutionOverlay().isVisible()) - break; - if ( ! rOverlay.GetInsertionIndicatorOverlay().isVisible()) - break; - // Iterate over all selected pages and check whether there are - // holes. While we do this we remember the indices of the first and - // last selected page as preparation for the next step. - sal_Int32 nCurrentIndex = -1; - sal_Int32 nFirstIndex = -1; - sal_Int32 nLastIndex = -1; - model::PageEnumeration aSelectedPages ( - model::PageEnumerationProvider::CreateSelectedPagesEnumeration( - mrSlideSorter.GetModel())); - while (aSelectedPages.HasMoreElements() && ! bIsNonTrivial) - { - model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); - SdPage* pPage = pDescriptor->GetPage(); - if (pPage != NULL) - { - // Get the page number and compare it to the last one. - sal_Int32 nPageNumber = (pPage->GetPageNum()-1)/2; - if (nCurrentIndex>=0 && nPageNumber>(nCurrentIndex+1)) - bIsNonTrivial = true; - else - nCurrentIndex = nPageNumber; - // Remember indices of the first and last page of the selection. - if (nFirstIndex == -1) - nFirstIndex = nPageNumber; - nLastIndex = nPageNumber; - } - } - if (bIsNonTrivial) - break; - // When we come here then the selection is consecutive. We still - // have 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. - sal_Int32 nInsertionIndex = rOverlay.GetInsertionIndicatorOverlay().GetInsertionPageIndex(); - if (nInsertionIndex(nLastIndex+1)) - bIsNonTrivial = true; +SelectionFunction::RectangleSelector::~RectangleSelector (void) +{ + if (mrSlideSorter.GetProperties()->IsShowSelection()) + { + mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay()->SetIsVisible(false); } - while (false); - - return bIsNonTrivial; } -//===== InsertionIndicatorHandler ============================================= - -SelectionFunction::InsertionIndicatorHandler::InsertionIndicatorHandler ( - SlideSorter& rSlideSorter) - : mrSlideSorter(rSlideSorter) +void SelectionFunction::RectangleSelector::RestoreInitialSelection (void) { + // Remember the current selection. + model::PageEnumeration aPages ( + model::PageEnumerationProvider::CreateAllPagesEnumeration( + mrSlideSorter.GetModel())); + view::SlideSorterView& rView (mrSlideSorter.GetView()); + while (aPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aPages.GetNextElement()); + pDescriptor->SetState( + model::PageDescriptor::ST_Selected, + pDescriptor->HasState(model::PageDescriptor::ST_WasSelected)); + rView.RequestRepaint(pDescriptor); + } } -SelectionFunction::InsertionIndicatorHandler::~InsertionIndicatorHandler (void) +void SelectionFunction::RectangleSelector::UpdatePosition ( + const Point& rMousePosition, + const bool bAllowAutoScroll) { + // Convert window coordinates into model coordinates (we need the + // window coordinates for auto-scrolling because that remains + // constant while scrolling.) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + + if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll( + rMousePosition, + ::boost::bind( + &SelectionFunction::RectangleSelector::UpdatePosition, + this, + rMousePosition, + false)))) + { + if (mrSlideSorter.GetProperties()->IsShowSelection()) + { + mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay() + ->Update(aMouseModelPosition); + ProcessRectangleSelection(); + } + } } -void SelectionFunction::InsertionIndicatorHandler::Start (const Point& rMouseModelPosition) +void SelectionFunction::RectangleSelector::SetSelectionModeFromModifier ( + const sal_uInt32 nEventCode) { - if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly()) - return; + switch (nEventCode & MODIFIER_MASK) + { + case NO_MODIFIER: + SetSelectionMode(RectangleSelector::SM_Normal); + break; - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetInsertionIndicatorOverlay().SetPosition(rMouseModelPosition); - rOverlay.GetInsertionIndicatorOverlay().setVisible(true); + case SHIFT_MODIFIER: + SetSelectionMode(RectangleSelector::SM_Add); + break; + + case CONTROL_MODIFIER: + SetSelectionMode(RectangleSelector::SM_Toggle); + break; + } } -void SelectionFunction::InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition) +void SelectionFunction::RectangleSelector::SetSelectionMode (const SelectionMode eSelectionMode) { - if (mrSlideSorter.GetController().GetProperties()->IsUIReadOnly()) + if (meSelectionMode != eSelectionMode) + { + meSelectionMode = eSelectionMode; + ProcessRectangleSelection(); + } +} + + + + +void SelectionFunction::RectangleSelector::ProcessRectangleSelection (void) +{ + if ( ! mrSlideSorter.GetProperties()->IsShowSelection()) return; view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetInsertionIndicatorOverlay().SetPosition(rMouseModelPosition); -} + if (rOverlay.GetSelectionRectangleOverlay()->IsVisible()) + { + mrSlideSorter.GetView().LockRedraw(true); + PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); + // 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)); + + // Determine whether the page was selected before the rectangle + // selection was started. + const bool bWasSelected (pDescriptor->HasState(model::PageDescriptor::ST_WasSelected)); + + // Combine the two selection states depending on the selection mode. + bool bSelect (false); + switch(meSelectionMode) + { + case SM_Normal: + bSelect = bIsPageInSelectionRectangle; + break; + + case SM_Add: + bSelect = bIsPageInSelectionRectangle || bWasSelected; + break; + + case SM_Toggle: + if (bIsPageInSelectionRectangle) + bSelect = !bWasSelected; + else + bSelect = bWasSelected; + break; + } -void SelectionFunction::InsertionIndicatorHandler::End (void) -{ - mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay().setVisible(false); + // Set the new selection state. + if (bSelect) + rSelector.SelectPage(pDescriptor); + else + rSelector.DeselectPage(pDescriptor); + } + + // Rely on auto scrolling to make page objects visible. + mrSlideSorter.GetController().GetSelectionManager()->ResetMakeSelectionVisiblePending(); + + mrSlideSorter.GetView().LockRedraw(false); + } } + + + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 2eac8b757780..83ce65981bce 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -37,6 +37,7 @@ #include "SlsSelectionCommand.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsAnimator.hxx" +#include "controller/SlsAnimationFunction.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "controller/SlsFocusManager.hxx" #include "controller/SlsProperties.hxx" @@ -46,6 +47,7 @@ #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" +#include "view/SlsLayouter.hxx" #include "drawdoc.hxx" #include "Window.hxx" #include @@ -80,6 +82,7 @@ namespace { SlideSorter& mrSlideSorter; double mnStart; double mnEnd; + ::boost::function maAccelerationFunction; }; class HorizontalVisibleAreaScroller { @@ -91,6 +94,7 @@ namespace { SlideSorter& mrSlideSorter; double mnStart; double mnEnd; + ::boost::function maAccelerationFunction; }; } @@ -329,6 +333,14 @@ bool SelectionManager::IsMakeSelectionVisiblePending (void) const +void SelectionManager::ResetMakeSelectionVisiblePending (void) +{ + mbIsMakeSelectionVisiblePending = false; +} + + + + /** We have to distinguish three cases: 1) the selection is empty, 2) the selection fits completely into the visible area, 3) it does not. 1) The visible area is not modified. @@ -346,7 +358,7 @@ bool SelectionManager::IsMakeSelectionVisiblePending (void) const */ Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) { - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); if (pWindow == NULL) return Size(0,0); @@ -357,6 +369,7 @@ Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) model::SharedPageDescriptor pFirst; model::SharedPageDescriptor pLast; Rectangle aSelectionBox; + const view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); model::PageEnumeration aSelectedPages ( PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); while (aSelectedPages.HasMoreElements()) @@ -367,10 +380,7 @@ Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) pFirst = pDescriptor; pLast = pDescriptor; - aSelectionBox.Union (mrSlideSorter.GetView().GetPageBoundingBox ( - pDescriptor, - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_INFO)); + aSelectionBox.Union(rLayouter.GetPageObjectBox(pDescriptor->GetPageIndex(), true)); } if (pFirst != NULL) @@ -395,7 +405,7 @@ Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) { - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); if (pWindow == NULL) return Size(0,0); @@ -408,7 +418,7 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) { // Scroll the visible area to make aSelectionBox visible. sal_Int32 nNewTop (aVisibleArea.Top()); - if (mrSlideSorter.GetController().GetProperties()->IsCenterSelection()) + if (mrSlideSorter.GetProperties()->IsCenterSelection()) { nNewTop = rBox.Top() - (aVisibleArea.GetHeight() - rBox.GetHeight()) / 2; } @@ -431,11 +441,12 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) // Scroll. if (nNewTop != aVisibleArea.Top()) { - mrController.GetAnimator()->AddAnimation( - VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop), - mrSlideSorter.GetController().GetProperties()->IsSmoothSelectionScrolling() ? - 1000 : 0 - ); + if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) + mrController.GetAnimator()->AddAnimation( + VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop), + 300); + else + VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop)(1.0); } return Size(0,aVisibleArea.Top() - nNewTop); @@ -444,7 +455,7 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) { // Scroll the visible area to make aSelectionBox visible. sal_Int32 nNewLeft (aVisibleArea.Left()); - if (mrSlideSorter.GetController().GetProperties()->IsCenterSelection()) + if (mrSlideSorter.GetProperties()->IsCenterSelection()) { nNewLeft = rBox.Left() - (aVisibleArea.GetWidth() - rBox.GetWidth()) / 2; } @@ -467,11 +478,12 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) // Scroll. if (nNewLeft != aVisibleArea.Left()) { - mrController.GetAnimator()->AddAnimation( - HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft), - mrSlideSorter.GetController().GetProperties()->IsSmoothSelectionScrolling() ? - 1000 : 0 - ); + if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) + mrController.GetAnimator()->AddAnimation( + HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft), + 300); + else + HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft)(1.0); } return Size(aVisibleArea.Left() - nNewLeft, 0); @@ -509,7 +521,7 @@ void SelectionManager::RemoveSelectionChangeListener(const Link&rListener) bool SelectionManager::DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const { - ::sd::Window* pWindow = mrSlideSorter.GetActiveWindow(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); if (pWindow == NULL) return true; @@ -562,10 +574,7 @@ Rectangle SelectionManager::ResolveLargeSelection ( } OSL_ASSERT(pRepresentative.get() != NULL); - return mrSlideSorter.GetView().GetPageBoundingBox ( - pRepresentative, - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_INFO); + return pRepresentative->GetBoundingBox(); } @@ -624,40 +633,55 @@ VerticalVisibleAreaScroller::VerticalVisibleAreaScroller ( const double nEnd) : mrSlideSorter(rSlideSorter), mnStart(nStart), - mnEnd(nEnd) + mnEnd(nEnd), + maAccelerationFunction( + controller::AnimationParametricFunction( + controller::AnimationBezierFunction (0.1,0.6))) { } -void VerticalVisibleAreaScroller::operator() (const double nValue) +void VerticalVisibleAreaScroller::operator() (const double nTime) { + const double nLocalTime (maAccelerationFunction(nTime)); + const sal_Int32 nNewTop (mnStart * (1.0 - nLocalTime) + mnEnd * nLocalTime); + mrSlideSorter.GetViewShell()->Scroll( + 0, + nNewTop - mrSlideSorter.GetController().GetScrollBarManager().GetTop()); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetController().GetScrollBarManager().SetTop( - int(mnStart * (1.0 - nValue) + mnEnd * nValue)); } +//===== HorizontalVisibleAreaScroller ========================================= + HorizontalVisibleAreaScroller::HorizontalVisibleAreaScroller ( SlideSorter& rSlideSorter, const double nStart, const double nEnd) : mrSlideSorter(rSlideSorter), mnStart(nStart), - mnEnd(nEnd) + mnEnd(nEnd), + maAccelerationFunction( + controller::AnimationParametricFunction( + controller::AnimationBezierFunction (0.1,0.6))) + { } -void HorizontalVisibleAreaScroller::operator() (const double nValue) +void HorizontalVisibleAreaScroller::operator() (const double nTime) { + const double nLocalTime (maAccelerationFunction(nTime)); + const sal_Int32 nNewLeft (mnStart * (1.0 - nLocalTime) + mnEnd * nLocalTime); + mrSlideSorter.GetViewShell()->Scroll( + nNewLeft - mrSlideSorter.GetController().GetScrollBarManager().GetLeft(), + 0); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetController().GetScrollBarManager().SetLeft( - int(mnStart * (1.0 - nValue) + mnEnd * nValue)); } } // end of anonymous namespace diff --git a/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx index d12b485b8d87..e58966079e0c 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlideFunction.cxx @@ -49,7 +49,7 @@ SlideFunction::SlideFunction ( SfxRequest& rRequest) : FuPoor ( rSlideSorter.GetViewShell(), - rSlideSorter.GetView().GetWindow(), + rSlideSorter.GetContentWindow().get(), &rSlideSorter.GetView(), rSlideSorter.GetModel().GetDocument(), rRequest) diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 4aa35f91292f..2dde82c121e1 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -36,13 +36,13 @@ #include "SlideSorter.hxx" #include "SlideSorterViewShell.hxx" #include "controller/SlideSorterController.hxx" -#include "controller/SlsPageSelector.hxx" #include "controller/SlsClipboard.hxx" -#include "controller/SlsSelectionFunction.hxx" -#include "controller/SlsFocusManager.hxx" #include "controller/SlsCurrentSlideManager.hxx" +#include "controller/SlsFocusManager.hxx" +#include "controller/SlsInsertionIndicatorHandler.hxx" +#include "controller/SlsPageSelector.hxx" +#include "controller/SlsSelectionFunction.hxx" #include "controller/SlsSelectionManager.hxx" -#include "SlsHideSlideFunction.hxx" #include "SlsCommand.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" @@ -103,6 +103,24 @@ using namespace ::com::sun::star::presentation; namespace sd { namespace slidesorter { namespace controller { +namespace { + +/** The state of a set of slides with respect to being excluded from the + slide show. +*/ +enum SlideExclusionState {UNDEFINED, EXCLUDED, INCLUDED, MIXED}; + +void ChangeSlideExclusionState (SlideSorter& rSlideSorter, SfxRequest& rRequest); + +/** Return for the given set of slides whether they included are + excluded from the slide show. +*/ +SlideExclusionState GetSlideExclusionState (model::PageEnumeration& rPageSet); + +} // end of anonymous namespace + + + SlotManager::SlotManager (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), maCommandQueue() @@ -139,7 +157,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_HIDE_SLIDE: case SID_SHOW_SLIDE: - HideSlideFunction::Create(mrSlideSorter, rRequest); + ChangeSlideExclusionState(mrSlideSorter, rRequest); break; case SID_PAGES_PER_ROW: @@ -167,6 +185,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_SELECTALL: mrSlideSorter.GetController().GetPageSelector().SelectAllPages(); + mrSlideSorter.GetController().GetSelectionManager()->ResetMakeSelectionVisiblePending(); rRequest.Done(); break; @@ -184,7 +203,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_PRESENTATION_DLG: FuSlideShowDlg::Create ( pShell, - mrSlideSorter.GetView().GetWindow(), + mrSlideSorter.GetContentWindow().get(), &mrSlideSorter.GetView(), pDocument, rRequest); @@ -193,7 +212,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_CUSTOMSHOW_DLG: FuCustomShowDlg::Create ( pShell, - mrSlideSorter.GetView().GetWindow(), + mrSlideSorter.GetContentWindow().get(), &mrSlideSorter.GetView(), pDocument, rRequest); @@ -202,7 +221,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_EXPAND_PAGE: FuExpandPage::Create ( pShell, - mrSlideSorter.GetView().GetWindow(), + mrSlideSorter.GetContentWindow().get(), &mrSlideSorter.GetView(), pDocument, rRequest); @@ -211,7 +230,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_SUMMARY_PAGE: FuSummaryPage::Create ( pShell, - mrSlideSorter.GetView().GetWindow(), + mrSlideSorter.GetContentWindow().get(), &mrSlideSorter.GetView(), pDocument, rRequest); @@ -518,7 +537,7 @@ void SlotManager::GetCtrlState (SfxItemSet& rSet) ||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SFX_ITEM_AVAILABLE ||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SFX_ITEM_AVAILABLE) { - ULONG nMode = mrSlideSorter.GetView().GetWindow()->GetDrawMode(); + ULONG nMode = mrSlideSorter.GetContentWindow()->GetDrawMode(); UINT16 nQuality = 0; switch (nMode) @@ -671,23 +690,22 @@ void SlotManager::GetMenuState ( SfxItemSet& rSet) model::PageEnumeration aSelectedPages ( model::PageEnumerationProvider::CreateSelectedPagesEnumeration( mrSlideSorter.GetModel())); - HideSlideFunction::ExclusionState eState ( - HideSlideFunction::GetExclusionState(aSelectedPages)); + const SlideExclusionState eState (GetSlideExclusionState(aSelectedPages)); switch (eState) { - case HideSlideFunction::MIXED: + case MIXED: // Show both entries. break; - case HideSlideFunction::EXCLUDED: + case EXCLUDED: rSet.DisableItem(SID_HIDE_SLIDE); break; - case HideSlideFunction::INCLUDED: + case INCLUDED: rSet.DisableItem(SID_SHOW_SLIDE); break; - case HideSlideFunction::UNDEFINED: + case UNDEFINED: rSet.DisableItem(SID_HIDE_SLIDE); rSet.DisableItem(SID_SHOW_SLIDE); break; @@ -904,7 +922,7 @@ void SlotManager::RenameSlide (void) SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); DBG_ASSERT(pFact, "Dialogdiet fail!"); AbstractSvxNameDialog* aNameDlg = pFact->CreateSvxNameDialog( - mrSlideSorter.GetActiveWindow(), + mrSlideSorter.GetContentWindow().get(), aPageName, aDescr); DBG_ASSERT(aNameDlg, "Dialogdiet fail!"); aNameDlg->SetText( aTitle ); @@ -1076,11 +1094,11 @@ void SlotManager::InsertSlide (SfxRequest& rRequest) // No selection. Is there an insertion indicator? else if (mrSlideSorter.GetView().GetOverlay() - .GetInsertionIndicatorOverlay().isVisible()) + .GetInsertionIndicatorOverlay()->IsVisible()) { // Select the page before the insertion indicator. - nInsertionIndex = mrSlideSorter.GetView().GetOverlay() - .GetInsertionIndicatorOverlay().GetInsertionPageIndex(); + nInsertionIndex + = mrSlideSorter.GetController().GetInsertionIndicatorHandler()->GetInsertionPageIndex(); nInsertionIndex --; rSelector.SelectPage (nInsertionIndex); } @@ -1157,15 +1175,18 @@ void SlotManager::InsertSlide (SfxRequest& rRequest) } } - // When a new page has been inserted then select it and make it the - // current page. + // When a new page has been inserted then select it, make it the + // current page, and focus it. mrSlideSorter.GetView().LockRedraw(TRUE); if (mrSlideSorter.GetModel().GetPageCount() > nPageCount) { nInsertionIndex++; model::SharedPageDescriptor pDescriptor = mrSlideSorter.GetModel().GetPageDescriptor(nInsertionIndex); if (pDescriptor.get() != NULL) + { mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); + mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(pDescriptor); + } } rSelector.EnableBroadcasting(); mrSlideSorter.GetView().LockRedraw(FALSE); @@ -1230,5 +1251,103 @@ IMPL_LINK(SlotManager, UserEventCallback, void*, EMPTYARG) return 1; } + + + +//----------------------------------------------------------------------------- + +namespace { + +void ChangeSlideExclusionState ( + SlideSorter& rSlideSorter, + SfxRequest& rRequest) +{ + model::PageEnumeration aSelectedPages ( + model::PageEnumerationProvider::CreateSelectedPagesEnumeration(rSlideSorter.GetModel())); + + SlideExclusionState eState (UNDEFINED); + + switch (rRequest.GetSlot()) + { + case SID_HIDE_SLIDE: + eState = EXCLUDED; + break; + + case SID_SHOW_SLIDE: + eState = INCLUDED; + break; + + default: + eState = UNDEFINED; + break; + } + + if (eState != UNDEFINED) + { + // Set status at the selected pages. + aSelectedPages.Rewind (); + while (aSelectedPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); + rSlideSorter.GetView().SetState( + pDescriptor, + model::PageDescriptor::ST_Excluded, + eState==EXCLUDED); + } + } + + SfxBindings& rBindings = rSlideSorter.GetViewShell()->GetViewFrame()->GetBindings(); + rBindings.Invalidate(SID_PRESENTATION); + rBindings.Invalidate(SID_REHEARSE_TIMINGS); + rBindings.Invalidate(SID_HIDE_SLIDE); + rBindings.Invalidate(SID_SHOW_SLIDE); + rSlideSorter.GetModel().GetDocument()->SetChanged(); +} + + + + +SlideExclusionState GetSlideExclusionState (model::PageEnumeration& rPageSet) +{ + SlideExclusionState eState (UNDEFINED); + BOOL bState; + + // Get toggle state of the selected pages. + while (rPageSet.HasMoreElements() && eState!=MIXED) + { + bState = rPageSet.GetNextElement()->GetPage()->IsExcluded(); + switch (eState) + { + case UNDEFINED: + // Use the first selected page to set the inital value. + eState = bState ? EXCLUDED : INCLUDED; + break; + + case EXCLUDED: + // The pages before where all not part of the show, + // this one is. + if ( ! bState) + eState = MIXED; + break; + + case INCLUDED: + // The pages before where all part of the show, + // this one is not. + if (bState) + eState = MIXED; + break; + + case MIXED: + default: + // No need to change anything. + break; + } + } + + return eState; +} + +} // end of anonymous namespace + } } } // 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 0eda7ccba22d..be1e56464d59 100644 --- a/sd/source/ui/slidesorter/controller/makefile.mk +++ b/sd/source/ui/slidesorter/controller/makefile.mk @@ -49,22 +49,20 @@ PRJINC=..$/.. SLOFILES = \ $(SLO)$/SlideSorterController.obj \ $(SLO)$/SlsAnimator.obj \ + $(SLO)$/SlsAnimationFunction.obj \ $(SLO)$/SlsClipboard.obj \ $(SLO)$/SlsCurrentSlideManager.obj \ $(SLO)$/SlsFocusManager.obj \ + $(SLO)$/SlsInsertionIndicatorHandler.obj\ $(SLO)$/SlsListener.obj \ - $(SLO)$/SlsPageObjectFactory.obj \ $(SLO)$/SlsPageSelector.obj \ $(SLO)$/SlsProperties.obj \ $(SLO)$/SlsScrollBarManager.obj \ $(SLO)$/SlsSelectionCommand.obj \ + $(SLO)$/SlsSelectionFunction.obj \ $(SLO)$/SlsSelectionManager.obj \ $(SLO)$/SlsSlotManager.obj \ - $(SLO)$/SlsTransferable.obj \ - \ - $(SLO)$/SlsHideSlideFunction.obj \ - $(SLO)$/SlsSelectionFunction.obj \ - $(SLO)$/SlsSlideFunction.obj + $(SLO)$/SlsTransferable.obj EXCEPTIONSFILES= \ $(SLO)$/SlideSorterController.obj diff --git a/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx index 8191a18df54e..b4e91acd0dca 100644 --- a/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx +++ b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx @@ -97,11 +97,14 @@ public: */ PageCache ( const Size& rPreviewSize, + const bool bDoSuperSampling, const SharedCacheContext& rpCacheContext); ~PageCache (void); - void ChangeSize(const Size& rPreviewSize); + void ChangeSize( + const Size& rPreviewSize, + const bool bDoSuperSampling); /** Request a preview bitmap for the specified page object in the specified size. The returned bitmap may be a preview of the @@ -113,33 +116,27 @@ public: method again if receives the correctly sized preview bitmap. @param rRequestData This data is used to determine the preview. - @param rSize - The size of the requested preview bitmap. @return Returns a bitmap that is either empty, contains a scaled (up or down) version or is the requested bitmap. */ - BitmapEx GetPreviewBitmap ( - CacheKey aKey, - const Size& rSize); + BitmapEx GetPreviewBitmap (CacheKey aKey); /** When the requested preview bitmap does not yet exist or is not up-to-date then the rendering of one is scheduled. Otherwise this method does nothing. */ - void RequestPreviewBitmap ( - CacheKey aKey, - const Size& rSize); + void RequestPreviewBitmap (CacheKey aKey); /** Tell the cache that the bitmap associated with the given request - data is not up-to-date anymore. Unlike the RequestPreviewBitmap() - method this does not trigger the rendering itself. It just - remembers to render it when the preview is requested the next time. - @param rRequestData - It is safe to pass a (barly) living object. It will called only - once to obtain its page object. + data is not up-to-date anymore. + @param bRequestPreview + When then a new preview is requested and will lead + eventually to a repaint of the associated page object. */ - void InvalidatePreviewBitmap (CacheKey aKey); + void InvalidatePreviewBitmap ( + const CacheKey aKey, + const bool bRequestPreview); /** Call this method when a view-object-contact object is being deleted and does not need (a) its current bitmap in the cache and (b) a diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index 06dc252f7b96..d1266efae992 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -64,9 +64,9 @@ class Animator; class Clipboard; class CurrentSlideManager; class FocusManager; +class InsertionIndicatorHandler; class Listener; class PageSelector; -class Properties; class ScrollBarManager; class SelectionManager; class SlotManager; @@ -88,6 +88,8 @@ public: virtual ~SlideSorterController (void); + void Dispose (void); + /** Place and size the scroll bars and the browser window so that the given rectangle is filled. @return @@ -138,6 +140,7 @@ public: ::boost::shared_ptr GetCurrentSlideManager (void) const; ::boost::shared_ptr GetSlotManager (void) const; ::boost::shared_ptr GetSelectionManager (void) const; + ::boost::shared_ptr GetInsertionIndicatorHandler (void) const; // forward VCLs PrePaint window event to DrawingLayer void PrePaint(); @@ -240,11 +243,6 @@ public: */ bool IsContextMenuOpen (void) const; - /** Return a collection of properties that are used througout the slide - sorter. - */ - ::boost::shared_ptr GetProperties (void) const; - /** Provide the set of pages to be displayed in the slide sorter. The GetDocumentSlides() method can be found only in the SlideSorterModel. */ @@ -265,6 +263,7 @@ private: ::std::auto_ptr mpScrollBarManager; mutable ::boost::shared_ptr mpCurrentSlideManager; ::boost::shared_ptr mpSelectionManager; + ::boost::shared_ptr mpInsertionIndicatorHandler; ::boost::shared_ptr mpAnimator; // The listener listens to UNO events and thus is a UNO object. @@ -307,11 +306,6 @@ private: */ bool mbIsContextMenuOpen; - /** Some slide sorter wide properties that are used in different - classes. - */ - ::boost::shared_ptr mpProperties; - /** Delete the given list of normal pages. This method is a helper function for DeleteSelectedPages(). @param rSelectedNormalPages diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx new file mode 100644 index 000000000000..7cd27573e72c --- /dev/null +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx @@ -0,0 +1,178 @@ +/************************************************************************* + * + * 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: SlsAnimator.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_CONTROLLER_ANIMATION_FUNCTION_HXX +#define SD_SLIDESORTER_CONTROLLER_ANIMATION_FUNCTION_HXX + +#include "model/SlsSharedPageDescriptor.hxx" +#include +#include +#include +#include +#include + +namespace sd { namespace slidesorter { namespace view { +class SlideSorterView; +} } } + + + +namespace sd { namespace slidesorter { namespace controller { + +/** A collection of functions that are usefull when creating animations. + They are collected here until a better place is found. +*/ +class AnimationFunction + : private ::boost::noncopyable +{ +public: + /** Acceleration function that maps [0,1] to [0,1]. Speed starts fast + and ends slow following the sine function. + */ + static double FastInSlowOut_Sine (const double nTime); + + /** Acceleration function that maps [0,1] to [0,1]. Speed starts fast + and ends slow following the square root function. + */ + static double FastInSlowOut_Root (const double nTime); + + /** Acceleration function that maps [0,1] to [0,0]. Speed starts slow, + rises, drops and ends slow following the sine function. + */ + static double SlowInSlowOut_0to0_Sine (const double nTime); + + /** Acceleration function that maps [0,1] to [0,0]. Speed starts slow, + rises and drops several times and ends slow following multiple + cycles of the the sine function. + */ + static double Vibrate_Sine (const double nTime); + + /** Scale point linearly. + */ + static Point ScalePoint (const Point& rPoint, const double nTime); + + /** Blend two points together according to the given weight. + */ + static double Blend (const double nStartValue, const double nEndValue, const double nWeight); + + /** Apply a gradual visual state change. The kind of change, i.e. the + previous and the new states are expected to be already set. This + method only adjusts the blending of the visual representation from + one state to the other. + */ + static void ApplyVisualStateChange ( + const model::SharedPageDescriptor& rpDescriptor, + view::SlideSorterView& rView, + const double nTime); + + /** Apply a gradual change of a previously set offset to the location of + a page object. + */ + static void ApplyLocationOffsetChange ( + const model::SharedPageDescriptor& rpDescriptor, + view::SlideSorterView& rView, + const Point aLocationOffset); + + /** Apply a gradual change the alpha value from the old value to a + new value (set prior to this call.) + */ + static void ApplyButtonAlphaChange( + const model::SharedPageDescriptor& rpDescriptor, + view::SlideSorterView& rView, + const double nAlpha); +}; + + + + +class AnimationBezierFunction +{ +public: + /** Create a cubic bezier curve whose start and end points are given + implicitly as P0=(0,0) and P3=(1,1). + */ + AnimationBezierFunction ( + const double nX1, + const double nY1, + const double nX2, + const double nY2); + + /** Create a cubic bezier curve whose start and end points are given + implicitly as P0=(0,0) and P3=(1,1). The second control point is + implicitly given as P2=(1-nY1,1-nX1). + */ + AnimationBezierFunction ( + const double nX1, + const double nY1); + + ::basegfx::B2DPoint operator() (const double nT); + +private: + const double mnX1; + const double mnY1; + const double mnX2; + const double mnY2; + + double EvaluateComponent ( + const double nT, + const double nV1, + const double nV2); +}; + + + + +/** Turn a parametric function into one whose y-Values depend on its + x-Values. Note a lot of interpolation takes place. The resulting + accuracy should be good enough for the purpose of acceleration + function for animations. +*/ +class AnimationParametricFunction +{ +public: + typedef ::boost::function ParametricFunction; + AnimationParametricFunction (const ParametricFunction& rFunction); + + double operator() (const double nX); + +private: + /** y-Values of the parametric function given to the constructor + evaluated (and interpolated) for evenly spaced x-Values. + */ + ::std::vector maY; +}; + + + + +} } } // end of namespace ::sd::slidesorter::controller + +#endif diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx index d96d200d2476..ffcfabcb925f 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx @@ -53,10 +53,19 @@ public: Animator (SlideSorter& rSlideSorter); ~Animator (void); + /** When disposed the animator will stop its work immediately and not + process any timer events anymore. + */ + void Dispose (void); + /** An animation object is called with values between 0 and 1 as single argument to its operator() method. */ - typedef ::boost::function1 AnimationFunction; + typedef ::boost::function1 AnimationFunctor; + typedef ::boost::function0 FinishFunctor; + + typedef sal_Int32 AnimationId; + static const AnimationId NotAnAnimationId = -1; /** Schedule a new animation for execution. The () operator of that animation will be called with increasing values between 0 and 1 for @@ -66,14 +75,26 @@ public: @param nDuration The duration in milli seconds. */ - void AddAnimation ( - const AnimationFunction& rAnimation, - const sal_Int32 nDuration); + AnimationId AddAnimation ( + const AnimationFunctor& rAnimation, + const sal_Int32 nDuration, + const FinishFunctor& rFinishFunctor = FinishFunctor()); + + AnimationId AddInfiniteAnimation ( + const AnimationFunctor& rAnimation, + const double nDelta); + + /** Abort and remove an animation. In order to reduce the bookkeeping + on the caller side, it is OK to call this method with an animation + function that is not currently being animated. Such a call is + silently ignored. + */ + void RemoveAnimation (const AnimationId nAnimationId); private: SlideSorter& mrSlideSorter; Timer maTimer; - + bool mbIsDisposed; class Animation; typedef ::std::vector > AnimationList; AnimationList maAnimations; @@ -81,6 +102,8 @@ private: class DrawLock; ::boost::scoped_ptr mpDrawLock; + AnimationId mnNextAnimationId; + DECL_LINK(TimeoutHandler, Timer*); /** Execute one step of every active animation. @@ -88,13 +111,14 @@ private: When one or more animation has finished then is returned. Call CleanUpAnimationList() in this case. */ - bool ServeAnimations (void); + bool ProcessAnimations (void); /** Remove animations that have expired. */ void CleanUpAnimationList (void); }; + } } } // end of namespace ::sd::slidesorter::controller #endif diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx new file mode 100644 index 000000000000..514b0ca056a5 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * 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: 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 + * 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_HANDLER_HXX +#define SD_SLIDESORTER_INSERTION_INDICATOR_HANDLER_HXX + +#include "view/SlsInsertAnimator.hxx" + +namespace sd { namespace slidesorter { class SlideSorter; } } +namespace sd { namespace slidesorter { namespace view { +class InsertAnimator; +class InsertionIndicatorOverlay; +} } } + + +namespace sd { namespace slidesorter { namespace controller { + + +/** Manage the visibility and location of the insertion indicator. Its + actual display is controlled by the InsertionIndicatorOverlay. +*/ +class InsertionIndicatorHandler +{ +public: + InsertionIndicatorHandler (SlideSorter& rSlideSorter); + ~InsertionIndicatorHandler (void); + + /** Activate the insertion marker at the given coordinates. + */ + void Start (const Point& rMouseModelPosition); + + /** Set the position of the insertion marker to the given coordinates. + */ + void UpdatePosition (const Point& rMouseModelPosition); + + /** Deactivate the insertion marker. + */ + void End (void); + + /** Return whether the insertion marker is active. + */ + bool IsActive (void) const; + + /** Return the insertion index that corresponds with the current + graphical location of the insertion indicator. + */ + sal_Int32 GetInsertionPageIndex (void) const; + + /** Determine whether moving the current selection to the current + position of the insertion marker would alter the document. This + 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 (void) const; + +private: + SlideSorter& mrSlideSorter; + ::boost::shared_ptr mpInsertAnimator; + ::boost::shared_ptr mpInsertionIndicatorOverlay; + sal_Int32 mnInsertionIndex; + bool mbIsBeforePage; + bool mbIsInsertionTrivial; + bool mbIsActive; + + void SetPosition (const Point& rPoint); + ::boost::shared_ptr GetInsertAnimator (void); +}; + + +} } } // end of namespace ::sd::slidesorter::controller + +#endif diff --git a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx index e3ae4ef60175..0e1edb0576d7 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx @@ -35,6 +35,7 @@ #include #include #include +#include class Point; class Rectangle; @@ -133,11 +134,15 @@ public: */ void SetTop (const sal_Int32 nTop); + sal_Int32 GetTop (void) const; + /** Update the horizontal scroll bar so that the visible area has the given left value. */ void SetLeft (const sal_Int32 nLeft); + sal_Int32 GetLeft (void) const; + /** Return the width of the vertical scroll bar, which--when shown--should be fixed in contrast to its height. @return @@ -157,11 +162,17 @@ public: /** Call this method to scroll a window while the mouse is in dragging a selection. If the mouse is near the window border or is outside the window then scroll the window accordingly. + @param rMouseWindowPosition + The mouse position for which the scroll amount is calculated. + @param rAutoScrollFunctor + Every time when the window is scrolled then this functor is executed. @return When the window is scrolled then this method returns . When the window is not changed then is returned. */ - bool AutoScroll (const Point& rMouseWindowPosition); + bool AutoScroll ( + const Point& rMouseWindowPosition, + const ::boost::function& rAutoScrollFunctor); void StopAutoScroll (void); @@ -200,12 +211,15 @@ private: */ Timer maAutoScrollTimer; Size maAutoScrollOffset; + bool mbIsAutoScrollActive; /** The content window is the one whose view port is controlled by the scroll bars. */ ::boost::shared_ptr mpContentWindow; + ::boost::function maAutoScrollFunctor; + void SetWindowOrigin ( double nHorizontalPosition, double nVerticalPosition); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index 4646726ed9ff..bc5f49b12c8b 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -31,10 +31,13 @@ #ifndef SD_SLIDESORTER_SELECTION_FUNCTION_HXX #define SD_SLIDESORTER_SELECTION_FUNCTION_HXX -#include "controller/SlsSlideFunction.hxx" #include "model/SlsSharedPageDescriptor.hxx" -#include -#include +#include "controller/SlsFocusManager.hxx" +#include "fupoor.hxx" +#include +//#include +#include +#include class SdSlideViewShell; class SdWindow; @@ -51,7 +54,8 @@ namespace sd { namespace slidesorter { namespace controller { class SlideSorterController; class SelectionFunction - : public SlideFunction + : public FuPoor, + private ::boost::noncopyable { public: TYPEINFO(); @@ -63,10 +67,9 @@ public: virtual BOOL MouseMove(const MouseEvent& rMEvt); virtual BOOL MouseButtonUp(const MouseEvent& rMEvt); virtual BOOL MouseButtonDown(const MouseEvent& rMEvt); - virtual void Paint(const Rectangle&, ::sd::Window* ); - virtual void Activate(); // Function aktivieren - virtual void Deactivate(); // Function deaktivieren + virtual void Activate(); + virtual void Deactivate(); virtual void ScrollStart(); virtual void ScrollEnd(); @@ -89,6 +92,8 @@ public: */ virtual bool cancel(); + void MouseDragged (const AcceptDropEvent& rEvent); + protected: SlideSorter& mrSlideSorter; SlideSorterController& mrController; @@ -101,8 +106,8 @@ protected: private: class SubstitutionHandler; + class RectangleSelector; class EventDescriptor; - class InsertionIndicatorHandler; /// Set in MouseButtonDown this flag indicates that a page has been hit. bool mbPageHit; @@ -122,12 +127,23 @@ private: */ bool mbProcessingMouseButtonDown; - ::std::auto_ptr mpSubstitutionHandler; + ::boost::scoped_ptr mpSubstitutionHandler; + ::boost::scoped_ptr mpRectangleSelector; + + /** Remember where the left mouse button was pressed. + */ + sal_Int32 mnButtonDownPageIndex; + sal_Int32 mnButtonDownButtonIndex; + + bool mbIsDeselectionPending; - ::std::auto_ptr mpInsertionIndicatorHandler; + /** Remember the slide where the shift key was pressed and started a + multiselection via keyboard. + */ + sal_Int32 mnShiftKeySelectionAnchor; DECL_LINK( DragSlideHdl, Timer* ); - void StartDrag (void); + void StartDrag (const Point& rMousePosition); /** Set the selection to exactly the specified page and also set it as the current page. @@ -154,37 +170,20 @@ private: // What follows are a couple of helper methods that are used by // ProcessMouseEvent(). - /// Select the specified page and set the selection anchor. - void SelectHitPage (const model::SharedPageDescriptor& rpDescriptor); - /// Deselect the specified page. - void DeselectHitPage (const model::SharedPageDescriptor& rpDescriptor); /// Deselect all pages. void DeselectAllPages (void); - /** for a possibly following mouse motion by starting the drag timer + /** 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 PrepareMouseMotion (const Point& aMouseModelPosition); + void StartDragTimer (void); /** Select all pages between and including the selection anchor and the specified page. */ void RangeSelect (const model::SharedPageDescriptor& rpDescriptor); - /** Start a rectangle selection at the given position. - */ - void StartRectangleSelection (const Point& aMouseModelPosition); - - /** Update the rectangle selection so that the given position becomes - the new second point of the selection rectangle. - */ - void UpdateRectangleSelection (const Point& aMouseModelPosition); - - /** Select all pages that lie completly in the selection rectangle. - */ - void ProcessRectangleSelection (bool bToggleSelection); - /** Hide and clear the insertion indiciator, substitution display and selection rectangle. */ @@ -204,9 +203,27 @@ private: const EventDescriptor& rDescriptor, const KeyEvent& rEvent) const; + /** Compute a numerical code that describes the current state like + whether the selection rectangle is visible or whether the page under + the mouse or the one that has the focus is selected. + */ + sal_uInt32 EncodeState (const EventDescriptor& rDescriptor) const; + void EventPreprocessing (const EventDescriptor& rEvent); bool EventProcessing (const EventDescriptor& rEvent); void EventPostprocessing (const EventDescriptor& rEvent); + + void UpdatePageUnderMouse ( + const Point& rMousePosition, + const bool bIsMouseButtonDown); + + void ProcessButtonClick ( + const model::SharedPageDescriptor& rpDescriptor, + const sal_Int32 nButtonIndex); + + void MoveFocus ( + const FocusManager::FocusMoveDirection eDirection, + const bool bIsShiftDown); }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx index 10b3167af563..665d01a89987 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx @@ -35,6 +35,7 @@ #include "model/SlsSharedPageDescriptor.hxx" #include #include +#include #include class Link; @@ -84,6 +85,10 @@ public: */ bool IsMakeSelectionVisiblePending (void) const; + /** Reset any request to make the set of selected pages visible. + */ + void ResetMakeSelectionVisiblePending (void); + enum SelectionHint { SH_FIRST, SH_LAST, SH_RECENT }; /** Try to make all currently selected page objects visible, i.e. set diff --git a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx index 9922787c42bc..e9c76e68fd35 100644 --- a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx @@ -46,6 +46,8 @@ class SdDrawDocument; namespace css = ::com::sun::star; +class SdrPage; + namespace sd { namespace slidesorter { class SlideSorter; } } @@ -69,6 +71,7 @@ public: SlideSorterModel (SlideSorter& rSlideSorter); virtual ~SlideSorterModel (void); + void Dispose (void); /** This method is present to let the view create a ShowView for displaying slides. @@ -132,6 +135,18 @@ public: sal_Int32 GetIndex ( const ::com::sun::star::uno::Reference& rxSlide) const; + /** Return a page descriptor for the given SdrPage. Page descriptors + are created on demand. The page descriptor is found (or not found) + in (at most) linear time. Note that all page descriptors in front of + the one associated with the given XDrawPage are created when not yet + present. When the SdrPage is not found then all descriptors are + created. + @return + Returns the index to the requested page descriptor or -1 when + there is no such page descriptor. + */ + sal_Int32 GetIndex (const SdrPage* pPage) const; + /** Call this method after the document has changed its structure. This will get the model in sync with the SdDrawDocument. This method tries not to throw away to much information already gathered. This @@ -154,17 +169,6 @@ public: */ void SynchronizeModelSelection (void); - /** Replace the factory for the creation of the page objects and - contacts with the given object. The old factory is destroyed. - */ - void SetPageObjectFactory( - ::std::auto_ptr pPageObjectFactory); - - /** Return the page object factory. It none has been set so far or it - has been reset, then a new one is created. - */ - const controller::PageObjectFactory& GetPageObjectFactory (void) const; - /** Return the mutex so that the caller can lock it and then safely access the model. */ @@ -197,7 +201,6 @@ private: EditMode meEditMode; typedef ::std::vector DescriptorContainer; mutable DescriptorContainer maPageDescriptors; - mutable ::std::auto_ptr mpPageObjectFactory; /** Resize the descriptor container according to current values of page kind and edit mode. diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx index e04e5c6e6afb..34c092e4b3f8 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx @@ -31,6 +31,7 @@ #ifndef SD_SLIDESORTER_PAGE_DESCRIPTOR_HXX #define SD_SLIDESORTER_PAGE_DESCRIPTOR_HXX +#include "model/SlsVisualState.hxx" #include #include #include @@ -90,8 +91,7 @@ public: PageDescriptor ( const css::uno::Reference& rxPage, SdPage* pPage, - const sal_Int32 nIndex, - const controller::PageObjectFactory& rPageObjectFactory); + const sal_Int32 nIndex); ~PageDescriptor (void); @@ -110,33 +110,12 @@ public: */ sal_Int32 GetPageIndex (void) const; - /** Return the page shape that is used for visualizing the page. - */ - view::PageObject* GetPageObject (void); - void ReleasePageObject (void); - - /** Return when the page object is fully or parially visible. */ - bool IsVisible (void) const; - - /** Set the visible state that is returned by the IsVisible() method. - This method is typically called by the view who renders the object - onto the screen. - */ - void SetVisible (bool bVisible); + enum State { ST_Visible, ST_Selected, ST_WasSelected, + ST_Focused, ST_MouseOver, ST_Current, ST_Excluded }; - /** Make sure that the page is selected and return whether the - selection state changed. - */ - bool Select (void); - /** Make sure that the page is not selected and return whether the - selection state changed. - */ - bool Deselect (void); + bool HasState (const State eState) const; - /** Return whether the page is selected (and thus bypasses the internal - mbIsSelected flag. - */ - bool IsSelected (void) const; + bool SetState (const State eState, const bool bStateValue); /** Set the internal mbIsSelected flag to the selection state of the page. Use this method to synchronize a page descriptor with the @@ -149,72 +128,30 @@ public: */ bool UpdateSelection (void); - bool IsFocused (void) const; - void SetFocus (void); - void RemoveFocus (void); - - view::PageObjectViewObjectContact* GetViewObjectContact (void) const; - - void SetViewObjectContact ( - view::PageObjectViewObjectContact* pViewObjectContact); + VisualState& GetVisualState (void); - /** Return the currently used page object factory. - */ - const controller::PageObjectFactory& GetPageObjectFactory (void) const; - - /** Replace the current page object factory by the given one. - */ - void SetPageObjectFactory (const controller::PageObjectFactory& rFactory); - - void SetModelBorder (const SvBorder& rBorder); - SvBorder GetModelBorder (void) const; - - /** The size of the area in which the page number is displayed is - calculated by the SlideSorterView and then stored in the page - descriptors so that the contact objects can access them. The - contact objects can not calculate them on demand because the total - number of slides is needed to do that and this number is not known - to the contact objects. - */ - void SetPageNumberAreaModelSize (const Size& rSize); - Size GetPageNumberAreaModelSize (void) const; - - /** Returns when the slide is the current slide. - */ - bool IsCurrentPage (void) const; - - /** Set or revoke the state of this slide being the current slide. - */ - void SetIsCurrentPage (const bool bIsCurrent); + Rectangle GetBoundingBox (void) const; + Point GetLocation (void) const; + void SetBoundingBox (const Rectangle& rBoundingBox); private: SdPage* mpPage; css::uno::Reference mxPage; /** This index is displayed as page number in the view. It may or may - not be actual page index. + not be the actual page index. */ const sal_Int32 mnIndex; - /// The factory that is used to create PageObject objects. - const controller::PageObjectFactory* mpPageObjectFactory; - - /** The page object will be destroyed by the page into which it has - been inserted. - */ - view::PageObject* mpPageObject; - - bool mbIsSelected; - bool mbIsVisible; - bool mbIsFocused; - bool mbIsCurrent; - - view::PageObjectViewObjectContact* mpViewObjectContact; + bool mbIsSelected : 1; + bool mbWasSelected : 1; + bool mbIsVisible : 1; + bool mbIsFocused : 1; + bool mbIsCurrent : 1; + bool mbIsMouseOver : 1; - /// The borders in model coordinates arround the page object. - SvBorder maModelBorder; + Rectangle maBoundingBox; - /// The size of the page number area in model coordinates. - Size maPageNumberAreaModelSize; + VisualState maVisualState; // Do not use the copy constructor operator. It is not implemented. PageDescriptor (const PageDescriptor& rDescriptor); diff --git a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx new file mode 100644 index 000000000000..b8df8a6688f8 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * 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: SlsPageDescriptor.hxx,v $ + * $Revision: 1.8 $ + * + * 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_VISUAL_STATE_HXX +#define SD_SLIDESORTER_VISUAL_STATE_HXX + +#include +#include +#include + +namespace sd { namespace slidesorter { namespace model { + +class PageDescriptor; + +/** This class gives access to values related to the visualization of page + objects. This includes animation state when blending from one state to + another. +*/ +class VisualState +{ +public: + enum State { + VS_Selected, + VS_Focused, + VS_Current, + VS_Excluded, + VS_None }; + + VisualState (const sal_Int32 nPageId); + ~VisualState (void); + + State GetCurrentVisualState (void) const; + State GetOldVisualState (void) const; + void SetVisualState (const State eState); + double GetVisualStateBlend (void) const; + void SetVisualStateBlend (const double nBlend); + + void UpdateVisualState (const PageDescriptor& rDescriptor); + + void SetMouseOverState (const bool bIsMouseOver); + + sal_Int32 GetStateAnimationId (void) const; + void SetStateAnimationId (const sal_Int32 nAnimationId); + + Point GetLocationOffset (void) const; + bool SetLocationOffset (const Point& rPoint); + sal_Int32 GetLocationAnimationId (void) const; + void SetLocationAnimationId (const sal_Int32 nAnimationId); + + double GetButtonAlpha (void) const; + void SetButtonAlpha (const double nAlpha); + sal_Int32 GetButtonAlphaAnimationId (void) const; + void SetButtonAlphaAnimationId (const sal_Int32 nAnimationId); + + enum ButtonState { BS_Normal, BS_MouseOver, BS_Pressed }; + + void SetActiveButtonState (const sal_Int32 nIndex, const ButtonState eState); + ButtonState GetButtonState (const sal_Int32 nIndex); + + const sal_Int32 mnPageId; // For debugging + +private: + State meCurrentVisualState; + State meOldVisualState; + double mnVisualStateBlend; + sal_Int32 mnStateAnimationId; + bool mbOldMouseOverState; + bool mbCurrentMouseOverState; + + Point maLocationOffset; + sal_Int32 mnLocationAnimationId; + + double mnButtonAlpha; + sal_Int32 mnButtonAlphaAnimationId; + + sal_Int32 mnActiveButtonIndex; + ButtonState meActiveButtonState; +}; + +} } } // end of namespace ::sd::slidesorter::model + +#endif diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 360ecaba703c..8b927d0c630e 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -31,28 +31,30 @@ #ifndef SD_SLIDESORTER_SLIDE_SORTER_VIEW_HXX #define SD_SLIDESORTER_SLIDE_SORTER_VIEW_HXX -#include "View.hxx" - +#include "model/SlsPageDescriptor.hxx" #include "model/SlsSharedPageDescriptor.hxx" +#include "View.hxx" #include #include "pres.hxx" #include +#include +#include +#include +#include #include #include +#include class Point; -namespace sdr { namespace contact { -class ObjectContact; -} } - namespace sd { namespace slidesorter { class SlideSorter; } } namespace sd { namespace slidesorter { namespace controller { class SlideSorterController; +class Properties; } } } namespace sd { namespace slidesorter { namespace cache { @@ -65,15 +67,18 @@ class SlideSorterModel; namespace sd { namespace slidesorter { namespace view { +class LayeredDevice; class Layouter; +class PageObjectPainter; class ViewOverlay; class SlideSorterView - : public View + : public sd::View, + public ::boost::noncopyable { public: - TYPEINFO(); + TYPEINFO (); /** Create a new view for the slide sorter. @param rViewShell @@ -84,6 +89,7 @@ public: SlideSorterView (SlideSorter& rSlideSorter); virtual ~SlideSorterView (void); + void Dispose (void); enum Orientation { HORIZONTAL, VERTICAL }; void SetOrientation (const Orientation eOrientation); @@ -91,44 +97,10 @@ public: void RequestRepaint (void); void RequestRepaint (const model::SharedPageDescriptor& rDescriptor); + void RequestRepaint (const Rectangle& rRepaintBox); Rectangle GetModelArea (void); - enum CoordinateSystem { CS_SCREEN, CS_MODEL }; - enum BoundingBoxType { BBT_SHAPE, BBT_INFO }; - - /** Return the rectangle that bounds the page object represented by the - given page descriptor. - @param rDescriptor - The descriptor of the page for which to return the bounding box. - @param eCoordinateSystem - Specifies whether to return the screen or model coordinates. - @param eBoundingBoxType - Specifies whether to return the bounding box of only the page - object or the one that additionally includes other displayed - information like page name and fader symbol. - */ - Rectangle GetPageBoundingBox ( - const model::SharedPageDescriptor& rpDescriptor, - CoordinateSystem eCoordinateSystem, - BoundingBoxType eBoundingBoxType) const; - - /** Return the rectangle that bounds the page object represented by the - given page index . - @param nIndex - The index of the page for which to return the bounding box. - @param eCoordinateSystem - Specifies whether to return the screen or model coordinates. - @param eBoundingBoxType - Specifies whether to return the bounding box of only the page - object or the one that additionally includes other displayed - information like page name and fader symbol. - */ - Rectangle GetPageBoundingBox ( - sal_Int32 nIndex, - CoordinateSystem eCoordinateSystem, - BoundingBoxType eBoundingBoxType) const; - /** Return the index of the page that is rendered at the given position. @param rPosition The position is expected to be in pixel coordinates. @@ -167,12 +139,11 @@ public: void HandleDrawModeChange (void); virtual void Resize (void); - virtual void CompleteRedraw (OutputDevice* pDevice, const Region& rPaintArea, sdr::contact::ViewObjectContactRedirector* pRedirector = 0L); - virtual void InvalidateOneWin ( - ::Window& rWindow); - virtual void InvalidateOneWin ( - ::Window& rWindow, - const Rectangle& rPaintArea ); + virtual void CompleteRedraw ( + OutputDevice* pDevice, + const Region& rPaintArea, + sdr::contact::ViewObjectContactRedirector* pRedirector = NULL); + void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea); void Layout (void); /** This tells the view that it has to re-determine the visibility of @@ -182,8 +153,7 @@ public: /** Return the window to which this view renders its output. */ - ::sd::Window* GetWindow (void) const; - + // ::boost::shared_ptr GetWindow (void) const; ::boost::shared_ptr GetPreviewCache (void); @@ -209,8 +179,6 @@ public: */ void SetSelectionRectangleVisibility (bool bVisible); - ::sdr::contact::ObjectContact& GetObjectContact (void) const; - typedef ::std::pair PageRange; /** Return the range of currently visible page objects including the first and last one in that range. @@ -220,84 +188,59 @@ public: */ PageRange GetVisiblePageRange (void); - /** Return the size of the area where the page numbers are displayed. - @return - The returned size is given in model coordinates. - */ - Size GetPageNumberAreaModelSize (void) const; - - /** Return the size of the border around the original SdrPageObj. - */ - SvBorder GetModelBorder (void) const; - /** Add a shape to the page. Typically used from inside PostModelChange(). */ void AddSdrObject (SdrObject& rObject); + /** Lock or unlock painting into the content window. + @param bLock + When then painting is locked. When then + painting is unlocked. + */ + void LockRedraw (const bool bLock); + + void SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor); + void SetButtonUnderMouse (const sal_Int32 nButtonIndex); + + void AddVisualStateAnimation (const model::SharedPageDescriptor& rpDescriptor); + bool SetState ( + const model::SharedPageDescriptor& rpDescriptor, + const model::PageDescriptor::State eState, + const bool bStateValue); + + ::boost::shared_ptr GetPageObjectPainter (void); + protected: virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); private: SlideSorter& mrSlideSorter; model::SlideSorterModel& mrModel; - /// This model is used for the maPage object and for the page visualizers - /// (SdrPageObj) - SdrModel maPageModel; - /** This page acts as container for the page objects that represent the - pages of the document that is represented by the SlideSorterModel. - */ - SdrPage* mpPage; ::std::auto_ptr mpLayouter; bool mbPageObjectVisibilitiesValid; ::boost::shared_ptr mpPreviewCache; - ::std::auto_ptr mpViewOverlay; - + ::boost::shared_ptr mpLayeredDevice; + ::boost::shared_ptr mpViewOverlay; int mnFirstVisiblePageIndex; int mnLastVisiblePageIndex; - - SvBorder maPagePixelBorder; - bool mbModelChangedWhileModifyEnabled; - Size maPreviewSize; - bool mbPreciousFlagUpdatePending; - - Size maPageNumberAreaModelSize; - SvBorder maModelBorder; - Orientation meOrientation; - - /** Adapt the coordinates of the given bounding box according to the - other parameters. - @param rModelPageObjectBoundingBox - Bounding box given in model coordinates that bounds only the - page object. - @param eCoordinateSystem - When CS_SCREEN is given then the bounding box is converted into - screen coordinates. - @param eBoundingBoxType - When BBT_INFO is given then the bounding box is made larger so - that it encloses all relevant displayed information. - */ - void AdaptBoundingBox ( - Rectangle& rModelPageObjectBoundingBox, - CoordinateSystem eCoordinateSystem, - BoundingBoxType eBoundingBoxType) const; + ::boost::shared_ptr mpProperties; + model::SharedPageDescriptor mpPageUnderMouse; + sal_Int32 mnButtonUnderMouse; + ::boost::shared_ptr mpPageObjectPainter; /** Determine the visibility of all page objects. */ void DeterminePageObjectVisibilities (void); - /** Update the page borders used by the layouter by using those returned - by the first page. Call this function when the model changes, - especially when the number of pages changes, or when the window is - resized as the borders may be device dependent. - */ - void UpdatePageBorders (void); - void UpdatePreciousFlags (void); + + ::drawinglayer::primitive2d::Primitive2DSequence GetPrimitive2DHierarchy ( + const Region& rPaintArea) const; }; diff --git a/sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx new file mode 100644 index 000000000000..2489068ad470 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx @@ -0,0 +1,64 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_LAYER_PAINTER_HXX +#define SD_SLIDESORTER_VIEW_LAYER_PAINTER_HXX + +#include +#include + +class OutputDevice; +class Rectangle; + +namespace sd { namespace slidesorter { namespace view { + +class ILayerInvalidator +{ +public: + virtual void Invalidate (const Rectangle& rInvalidationBox) = 0; +}; +typedef ::boost::shared_ptr SharedILayerInvalidator; + +class ILayerPainter +{ +public: + virtual void SetLayerInvalidator ( + const SharedILayerInvalidator& rpInvalidator) = 0; + virtual void Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea) = 0; +}; +typedef ::boost::shared_ptr SharedILayerPainter; + + +} } } // end of namespace ::sd::slidesorter::view + +#endif diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx new file mode 100644 index 000000000000..7d5a8e5f21f5 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx @@ -0,0 +1,64 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_INSERT_ANIMATOR_HXX +#define SD_SLIDESORTER_VIEW_INSERT_ANIMATOR_HXX + +#include "controller/SlsAnimator.hxx" +#include +#include + +namespace sd { namespace slidesorter { namespace view { + +/** Animate the positions of page objects to make room at the insert + position while a move or copy operation takes place. +*/ +class InsertAnimator + : private ::boost::noncopyable +{ +public: + InsertAnimator (SlideSorter& rSlideSorter); + + void SetInsertPosition ( + const sal_Int32 nPageIndex, + const bool bInsertBefore); + + void Reset (void); + +private: + class Implementation; + ::boost::shared_ptr mpImplementation; +}; + + +} } } // 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 194f83680f06..b697b157017d 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx @@ -31,6 +31,8 @@ #ifndef SD_SLIDESORTER_VIEW_LAYOUTER_HXX #define SD_SLIDESORTER_VIEW_LAYOUTER_HXX +#include "SlideSorter.hxx" +#include "SlsPageObjectLayouter.hxx" #include #include #include @@ -69,15 +71,19 @@ namespace sd { namespace slidesorter { namespace view { class Layouter { public: - Layouter (void); + Layouter (const ::boost::shared_ptr< ::Window>& rpWindow); ~Layouter (void); + ::boost::shared_ptr GetPageObjectLayouter (void) const; + /** Set the minimal, the maximal, and the desired width of the page objects. The three parameters have to fullfill the constraint nMinimalWidth <= nPreferredWidth <= nMaximalWidth or the call is ignored. */ - void SetObjectWidth (sal_Int32 nMinimalWidth, sal_Int32 nMaximalWidth, + void SetObjectWidth ( + sal_Int32 nMinimalWidth, + sal_Int32 nMaximalWidth, sal_Int32 nPreferredWidth); /** Set the horizontal and vertical borders in pixel coordinates between @@ -100,23 +106,6 @@ public: void SetBorders (sal_Int32 nLeftBorder, sal_Int32 nRightBorder, sal_Int32 nTopBorder, sal_Int32 nBottomBorder); - /** Set the borders arround every page object. - @param nLeftBorder - A negative value indicates that the left border shall not be - modified. A value of 0 is the default. - @param nRightBorder - A negative value indicates that the left border shall not be - modified. A value of 0 is the default. - @param nTopBorder - A negative value indicates that the left border shall not be - modified. A value of 0 is the default. - @param nBottomBorder - A negative value indicates that the left border shall not be - modified. A value of 0 is the default. - */ - void SetPageBorders (sal_Int32 nLeftBorder, sal_Int32 nRightBorder, - sal_Int32 nTopBorder, sal_Int32 nBottomBorder); - /** Set the horizontal and vertical gaps between adjacent page objects. These gaps are only relevant when there is more than one column or more than one row. Negative values indicate that the respective gap @@ -140,36 +129,44 @@ public: dimension or the call is ignored. @param rWindowSize The size of the window in pixels that the slide sorter is - displayed in. - @param rPageObjectSize + displayed in. This can differ from the size of mpWindow during + detection of whether or not the scroll bars should be visible. + @param rPreviewModelSize Size of each page in model coordinates. - @param pDevice - The map mode of this output device is adapted to the new layout - of the page objects. + @param rpWindow + The map mode of this window is adapted to the new layout of the + page objects. @return The return value indicates whether the Get... methods can be used to obtain valid values (). */ bool RearrangeHorizontal ( const Size& rWindowSize, - const Size& rPageObjectSize, - OutputDevice* pDevice, + const Size& rPreviewModelSize, const sal_uInt32 nPageCount); bool RearrangeVertical ( const Size& rWindowSize, - const Size& rPageObjectSize, - OutputDevice* pDevice); + const Size& rPreviewModelSize, + const sal_uInt32 nPageCount); /** Change the zoom factor. This does not change the general layout (number of columns). */ - void SetZoom (double nZoomFactor, OutputDevice* pDevice); - void SetZoom (Fraction nZoomFactor, OutputDevice* pDevice); + void SetZoom (double nZoomFactor); + void SetZoom (Fraction nZoomFactor); /** Return the number of columns. */ sal_Int32 GetColumnCount (void) const; + sal_Int32 GetRowCount (void) const; + + sal_Int32 GetRow (const sal_Int32 nIndex) const; + + sal_Int32 GetColumn (const sal_Int32 nIndex) const; + + sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const; + /** Returns whether the column count is fixed () or variable (). It is fixed if SetColumnCount() was called with the same value for minimal and maximal column count. @@ -183,17 +180,19 @@ public: Size GetPageObjectSize (void) const; - /** Return the bounding box in model coordinates of the nIndex-th page + /** Return the bounding box in window coordinates of the nIndex-th page object. */ - Rectangle GetPageObjectBox (sal_Int32 nIndex) const; + Rectangle GetPageObjectBox ( + const sal_Int32 nIndex, + const bool bIncludeBorderAndGap = false) const; /** Return the bounding box in model coordinates of the page that contains the given amount of page objects. */ - Rectangle GetPageBox (sal_Int32 nObjectCount) const; + Rectangle GetPageBox (const sal_Int32 nObjectCount = -1) const; - /** Return the rectangle that bounds the insertion marker that is + /** Return the location of the center of the insertion marker that is specified by the parameters. @param nIndex Index of the page object from which the position of the marker @@ -210,16 +209,15 @@ public: is given then the marker will be positioned below or to the right of the page object. */ - Rectangle GetInsertionMarkerBox ( - sal_Int32 nIndex, - bool bVertical, - bool bLeftOrTop) const; + Point GetInsertionMarkerLocation ( + const sal_Int32 nIndex, + const bool bVertical, + const bool bLeftOrTop) const; /** Return the index of the first fully or partially visible page object. This takes into account only the vertical dimension. */ - sal_Int32 GetIndexOfFirstVisiblePageObject ( - const Rectangle& rVisibleArea) const; + sal_Int32 GetIndexOfFirstVisiblePageObject (const Rectangle& rVisibleArea) const; /** Return the index of the last fully or partially visible page object. This takes into account only the vertical dimension. @@ -227,8 +225,7 @@ public: The returned index may be larger than the number of existing page objects. */ - sal_Int32 GetIndexOfLastVisiblePageObject ( - const Rectangle& rVisibleArea) const; + sal_Int32 GetIndexOfLastVisiblePageObject (const Rectangle& rVisibleArea) const; /** Return the index of the page object that is rendered at the given point. @@ -247,7 +244,7 @@ public: */ sal_Int32 GetIndexAtPoint ( const Point& rModelPosition, - bool bIncludePageBorders = false) const; + 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 @@ -275,58 +272,29 @@ public: const Point& rModelPosition, bool bAllowVerticalPosition) const; - typedef ::std::pair DoublePoint; - /** Transform a point given in model coordinates in to layouter - coordinates. Layouter coordinates are floating point numbers where - the integer part denotes a row or a column and the part after the - decimal point is a relative position in that row or column. - */ - DoublePoint ConvertModelToLayouterCoordinates ( - const Point& rModelPoint) const; - - /** Transform a point given in layouter coordinates to model - coordinates. See ConvertModelToLayouterCoordinates for a - description of layouter coordinates. - */ - Point ConvertLayouterToModelCoordinates ( - const DoublePoint&rLayouterPoint) const; - - typedef ::std::vector BackgroundRectangleList; - const BackgroundRectangleList& GetBackgroundRectangleList (void) const; - private: - class ScreenAndModelValue {public: - sal_Int32 mnScreen,mnModel; - explicit ScreenAndModelValue (sal_Int32 nScreen, sal_Int32 nModel = 0) - : mnScreen(nScreen),mnModel(nModel) {} - }; - ScreenAndModelValue mnRequestedLeftBorder; - ScreenAndModelValue mnRequestedRightBorder; - ScreenAndModelValue mnRequestedTopBorder; - ScreenAndModelValue mnRequestedBottomBorder; - ScreenAndModelValue mnLeftBorder; - ScreenAndModelValue mnRightBorder; - ScreenAndModelValue mnTopBorder; - ScreenAndModelValue mnBottomBorder; - ScreenAndModelValue mnLeftPageBorder; - ScreenAndModelValue mnRightPageBorder; - ScreenAndModelValue mnTopPageBorder; - ScreenAndModelValue mnBottomPageBorder; - ScreenAndModelValue mnVerticalGap; - ScreenAndModelValue mnHorizontalGap; - ScreenAndModelValue mnInsertionMarkerThickness; - ScreenAndModelValue mnTotalVerticalGap; - ScreenAndModelValue mnTotalHorizontalGap; + ::boost::shared_ptr< ::Window> mpWindow; + sal_Int32 mnRequestedLeftBorder; + sal_Int32 mnRequestedRightBorder; + sal_Int32 mnRequestedTopBorder; + sal_Int32 mnRequestedBottomBorder; + sal_Int32 mnLeftBorder; + sal_Int32 mnRightBorder; + sal_Int32 mnTopBorder; + sal_Int32 mnBottomBorder; + sal_Int32 mnVerticalGap; + sal_Int32 mnHorizontalGap; sal_Int32 mnMinimalWidth; sal_Int32 mnPreferredWidth; sal_Int32 mnMaximalWidth; sal_Int32 mnMinimalColumnCount; sal_Int32 mnMaximalColumnCount; + sal_Int32 mnPageCount; sal_Int32 mnColumnCount; - Size maPageObjectModelSize; - Size maPageObjectPixelSize; + sal_Int32 mnRowCount; + Size maPageObjectSize; - BackgroundRectangleList maBackgroundRectangleList; + ::boost::shared_ptr mpPageObjectLayouter; enum GapMembership { GM_NONE, GM_PREVIOUS, GM_BOTH, GM_NEXT, GM_PAGE_BORDER}; @@ -384,9 +352,6 @@ private: @param nIndex The row index of the upper row or the column index of the left column. - @param nLeftOrTopPageBorder - Width in model coordinates of the border the the right of or - below a page. @param nGap Width or height of the gap in model coordiantes between the page borders. @@ -399,7 +364,6 @@ private: sal_Int32 nDistanceIntoGap, GapMembership eGapMembership, sal_Int32 nIndex, - sal_Int32 nLeftOrTopPageBorder, sal_Int32 nGap) const; }; diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx new file mode 100644 index 000000000000..fcd398377b01 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx @@ -0,0 +1,178 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_PAGE_OBJECT_LAYOUTER_HXX +#define SD_SLIDESORTER_PAGE_OBJECT_LAYOUTER_HXX + +#include "SlideSorter.hxx" +#include "model/SlsSharedPageDescriptor.hxx" +#include "tools/gen.hxx" +#include + +namespace sd { namespace slidesorter { namespace view { + + +/** In contrast to the Layouter that places page objects in the view, the + PageObjectLayouter places the parts of individual page objects like page + number area, borders, preview. +*/ +class PageObjectLayouter +{ +public: + /** Create a new PageObjectLayouter object. + @param rPageObjectSize + In general either the width or the height will be 0 in order to + signal that this size component has to be calculated from the other. + This calculation will make the preview as large as possible. + @param nPageCount + The page count is used to determine how wide the page number + area has to be, how many digits to except for the largest page number. + */ + PageObjectLayouter ( + const Size& rPageObjectWindowSize, + const Size& rPreviewModelSize, + const ::boost::shared_ptr< ::Window>& rpWindow, + const int nPageCount); + + enum Part { + // This is the outer bounding box that includes the preview, page + // number, title. + PageObject, + // Bounding box of the actual preview. + Preview, + // Bounding box of the mouse indicator indicator frame. + MouseOverIndicator, + // Bounding box of the focus indicator frame. + FocusIndicator, + // Bounding box of the selection indicator frame. + SelectionIndicator, + // Bounding box of the page number. + PageNumber, + // Bounding box of the pane name. + Name, + // Indicator whether or not there is a slide transition associated + // with this slide. + TransitionEffectIndicator, + ButtonArea, + Button + }; + /** Two coordinate systems are supported. They differ only in + translation not in scale. Both relate to pixel values in the window. + A position in the window coordinate system does not change when the window content is + scrolled up or down. In the screen coordinate system (relative + to the top left point of the window)scrolling leads to different values. + Example: Scroll up the point (0,0) in the the window coordinate + system by 20 pixels. It lies not inside the visible area of the + window anymore. Its screen coordinates are now (-20,0). + + WindowCoordinateSystem corresponds to the logic coordinate system of + class Window, while ScreenCoordinateSystem corresponds to its pixel + coordinate system. + */ + enum CoordinateSystem { + WindowCoordinateSystem, + ScreenCoordinateSystem}; + + /** Return the bounding box of the page object or one of its graphical + parts. + @param rWindow + This device is used to translate between model and window + coordinates. + @param rpPageDescriptor + The page for which to calculate the bounding box. + @param ePart + The part of the page object for which to return the bounding + box. + @param eCoodinateSystem + The bounding box can be returned in model and in pixel + (window) coordinates. + @param nIndex + Used only for some parts (Button) to distinguish between + different parts of the same type. + */ + Rectangle GetBoundingBox ( + const model::SharedPageDescriptor& rpPageDescriptor, + const Part ePart, + const CoordinateSystem eCoordinateSystem, + const sal_Int32 nIndex = 0); + + /** Return the size in pixel of the whole page object. + */ + Size GetPageObjectSize (void) const; + + /** Return the size in pixel of the preview. + */ + Size GetPreviewSize (void) const; + + Image GetTransitionEffectIcon (void) const; + + // void Update (void); + + sal_Int32 GetButtonIndexAt ( + const model::SharedPageDescriptor& rpPageDescriptor, + const Point& rWindowLocation); + +private: + /// Gap between border of page object and inside of selection rectangle. + static const sal_Int32 mnSelectionIndicatorOffset; + /// Thickness of the selection rectangle. + static const sal_Int32 mnSelectionIndicatorThickness; + /// Gap between border of page object and inside of focus rectangle. + static const sal_Int32 mnFocusIndicatorOffset; + /// Minimal border around the page number area. + static const sal_Int32 mnPageNumberOffset; + static const sal_Int32 mnOuterBorderWidth; + static const Size maButtonSize; + static const sal_Int32 mnButtonGap; + + const ::boost::shared_ptr< ::Window> mpWindow; + Size maPageObjectSize; + double mnModelToWindowScale; + Rectangle maPageObjectBoundingBox; + Rectangle maPageNumberAreaBoundingBox; + Rectangle maPreviewBoundingBox; + Rectangle maFocusIndicatorBoundingBox; + Rectangle maSelectionIndicatorBoundingBox; + Rectangle maTransitionEffectBoundingBox; + Rectangle maButtonAreaBoundingBox; + const Image maTransitionEffectIcon; + + Size GetPageNumberAreaSize (const int nPageCount); + Rectangle CalculatePreviewBoundingBox ( + Size& rPageObjectSize, + const Size& rPreviewModelSize, + const Size& rPageNumberAreaSize); +}; + + +} } } // end of namespace ::sd::slidesorter::view + +#endif diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx new file mode 100644 index 000000000000..b67e6cb3969f --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: baseprimitive2d.hxx,v $ + * + * $Revision: 1.8 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef SD_SLIDESORTER_PAGE_OBJECT_PAINTER_HEADER +#define SD_SLIDESORTER_PAGE_OBJECT_PAINTER_HEADER + +#include "SlideSorter.hxx" +#include "model/SlsPageDescriptor.hxx" +#include "view/SlsLayouter.hxx" + +namespace sd { namespace slidesorter { namespace cache { class PageCache; } } } + +namespace sd { namespace slidesorter { namespace view { + +class Layouter; +class PageObjectLayouter; + +class PageObjectPainter +{ +public: + PageObjectPainter (const SlideSorter& rSlideSorter); + + void PaintPageObject ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor); + +private: + const Layouter& mrLayouter; + ::boost::shared_ptr mpPageObjectLayouter; + ::boost::shared_ptr mpCache; + ::boost::shared_ptr mpProperties; + ::boost::scoped_ptr mpFont; + BitmapEx maStartPresentationIcon; + BitmapEx maShowSlideIcon; + BitmapEx maNewSlideIcon; + + void PaintBackground ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; + void PaintPreview ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; + void PaintPageNumber ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; + void PaintTransitionEffect ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; + void PaintButtons ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; + + ColorData GetColorForVisualState (const model::SharedPageDescriptor& rpDescriptor) const; +}; + +} } } // 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 index 93798e095871..2e141ad6b9be 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx @@ -32,14 +32,19 @@ #define SD_SLIDESORTER_VIEW_OVERLAY_HXX #include "model/SlsSharedPageDescriptor.hxx" +#include "view/SlsILayerPainter.hxx" #include #include -#include #include +#include +#include +#include +#include #include #include -#include +#include + class OutputDevice; class Region; @@ -57,15 +62,11 @@ namespace sd { namespace slidesorter { namespace controller { class SlideSorterController; } } } -namespace sdr { namespace overlay { -class OverlayManager; -} } - namespace sd { namespace slidesorter { namespace view { +class LayeredDevice; class InsertionIndicatorOverlay; -class PageObjectViewObjectContact; class SelectionRectangleOverlay; class SubstitutionOverlay; class ViewOverlay; @@ -73,23 +74,37 @@ class ViewOverlay; /** This base class of slide sorter overlays uses the drawing layer overlay support for the display. */ -class OverlayBase - : public sdr::overlay::OverlayObject +class OverlayBase : + public ILayerPainter, + public ::boost::enable_shared_from_this { public: - OverlayBase (ViewOverlay& rViewOverlay); + 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; - /** Make sure that the overlay object is registered at the - OverlayManager. This registration is done on demand. - */ - void EnsureRegistration (void); - void RemoveRegistration(); + class Invalidator; + friend class Invalidator; + + virtual Rectangle GetBoundingBox (void) const = 0; + +private: + bool mbIsVisible; + const sal_Int32 mnLayerIndex; + + void Invalidate (const Rectangle& rInvalidationBox); }; @@ -102,7 +117,7 @@ class SubstitutionOverlay : public OverlayBase { public: - SubstitutionOverlay (ViewOverlay& rViewOverlay); + SubstitutionOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); virtual ~SubstitutionOverlay (void); /** Setup the substitution display of the given set of selected pages. @@ -111,7 +126,8 @@ public: */ void Create ( model::PageEnumeration& rSelection, - const Point& rPosition); + const Point& rPosition, + const model::SharedPageDescriptor& rpHitDescriptor); /** Clear the substitution display. Until the next call of Create() no substution is painted. @@ -124,16 +140,36 @@ public: void SetPosition (const Point& rPosition); Point GetPosition (void) const; - // react on stripe definition change - virtual void stripeDefinitionHasChanged(); + virtual void Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea); protected: - // geometry creation for OverlayObject - virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence(); + virtual Rectangle GetBoundingBox (void) const; private: Point maPosition; - basegfx::B2DPolyPolygon maShapes; + Point maTranslation; + /** 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; + + class ItemDescriptor + { + public: + BitmapEx maImage; + Point maLocation; + double mnTransparency; + basegfx::B2DPolygon maShape; + }; + ::std::vector maItems; + Rectangle maBoundingBox; }; @@ -147,20 +183,19 @@ class SelectionRectangleOverlay : public OverlayBase { public: - SelectionRectangleOverlay (ViewOverlay& rViewOverlay); - virtual ~SelectionRectangleOverlay(); + SelectionRectangleOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); void Start (const Point& rAnchor); void Update (const Point& rSecondCorner); Rectangle GetSelectionRectangle (void); - // react on stripe definition change - virtual void stripeDefinitionHasChanged(); + virtual void Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea); protected: - // geometry creation for OverlayObject - virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence(); + virtual Rectangle GetBoundingBox (void) const; private: Point maAnchor; @@ -177,59 +212,34 @@ class InsertionIndicatorOverlay : public OverlayBase { public: - InsertionIndicatorOverlay (ViewOverlay& rViewOverlay); - virtual ~InsertionIndicatorOverlay(); + InsertionIndicatorOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); /** Given a position in model coordinates this method calculates the - insertion marker both as an index in the document and as a rectangle + insertion marker both as an index in the document and as a location used for drawing the insertion indicator. */ - void SetPosition (const Point& rPosition); + void SetLocation (const Point& rPosition); - sal_Int32 GetInsertionPageIndex (void) const; + virtual void Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea); protected: - // geometry creation for OverlayObject - virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence(); + virtual Rectangle GetBoundingBox (void) const; private: - sal_Int32 mnInsertionIndex; - Rectangle maBoundingBox; - - void SetPositionAndSize (const Rectangle& rBoundingBox); -}; - - - - -/** Paint a frame around the slide preview under the mouse. The actual - painting is done by the PageObjectViewObjectContact of the slidesorter. -*/ -class MouseOverIndicatorOverlay - : public OverlayBase -{ -public: - MouseOverIndicatorOverlay (ViewOverlay& rViewOverlay); - virtual ~MouseOverIndicatorOverlay (void); - - /** Set the page object for which to paint a mouse over indicator. - @param pContact - A value of indicates to not paint the mouse over indicator. + // 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. */ - void SetSlideUnderMouse (const model::SharedPageDescriptor& rpDescriptor); - -protected: - // geometry creation for OverlayObject - virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence(); - -private: - /** The page under the mouse is stored as weak shared pointer so that - model changes can be handled without having the SlideSorterModel - inform this class explicitly. - */ - ::boost::weak_ptr mpPageUnderMouse; - - view::PageObjectViewObjectContact* GetViewObjectContact (void) const; + bool mbIsBeforePage; + ImageList maIcons; + Image maIconWithBorder; + Image maIcon; + Image maMask; + void SetPositionAndSize (const Rectangle& rBoundingBox); }; @@ -249,24 +259,24 @@ private: class ViewOverlay { public: - ViewOverlay (SlideSorter& rSlideSorter); - ~ViewOverlay (void); + ViewOverlay ( + SlideSorter& rSlideSorter, + const ::boost::shared_ptr& rpLayeredDevice); + virtual ~ViewOverlay (void); - SelectionRectangleOverlay& GetSelectionRectangleOverlay (void); - MouseOverIndicatorOverlay& GetMouseOverIndicatorOverlay (void); - InsertionIndicatorOverlay& GetInsertionIndicatorOverlay (void); - SubstitutionOverlay& GetSubstitutionOverlay (void); + ::boost::shared_ptr GetSelectionRectangleOverlay (void); + ::boost::shared_ptr GetInsertionIndicatorOverlay (void); + ::boost::shared_ptr GetSubstitutionOverlay (void); SlideSorter& GetSlideSorter (void) const; - - sdr::overlay::OverlayManager* GetOverlayManager (void) const; + ::boost::shared_ptr GetLayeredDevice (void) const; private: SlideSorter& mrSlideSorter; - SelectionRectangleOverlay maSelectionRectangleOverlay; - MouseOverIndicatorOverlay maMouseOverIndicatorOverlay; - InsertionIndicatorOverlay maInsertionIndicatorOverlay; - SubstitutionOverlay maSubstitutionOverlay; + const ::boost::shared_ptr mpLayeredDevice; + ::boost::shared_ptr mpSelectionRectangleOverlay; + ::boost::shared_ptr mpInsertionIndicatorOverlay; + ::boost::shared_ptr mpSubstitutionOverlay; }; diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx index 4f21e48cce93..4d449b5c330f 100644 --- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx +++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx @@ -36,7 +36,6 @@ #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "controller/SlideSorterController.hxx" -#include "controller/SlsPageObjectFactory.hxx" #include "controller/SlsProperties.hxx" #include "controller/SlsPageSelector.hxx" #include "controller/SlsCurrentSlideManager.hxx" @@ -79,8 +78,7 @@ SlideSorterModel::SlideSorterModel (SlideSorter& rSlideSorter) mxSlides(), mePageKind(PK_STANDARD), meEditMode(EM_PAGE), - maPageDescriptors(0), - mpPageObjectFactory(NULL) + maPageDescriptors(0) { } @@ -95,6 +93,14 @@ SlideSorterModel::~SlideSorterModel (void) +void SlideSorterModel::Dispose (void) +{ + ClearDescriptorList (); +} + + + + SdDrawDocument* SlideSorterModel::GetDocument (void) { if (mrSlideSorter.GetViewShellBase() != NULL) @@ -195,8 +201,7 @@ SharedPageDescriptor SlideSorterModel::GetPageDescriptor ( pDescriptor.reset(new PageDescriptor ( Reference(mxSlides->getByIndex(nPageIndex),UNO_QUERY), pPage, - nPageIndex, - GetPageObjectFactory())); + nPageIndex)); maPageDescriptors[nPageIndex] = pDescriptor; } } @@ -263,6 +268,47 @@ sal_Int32 SlideSorterModel::GetIndex (const Reference& rxSli +sal_Int32 SlideSorterModel::GetIndex (const SdrPage* pPage) const +{ + if (pPage == NULL) + return -1; + + ::osl::MutexGuard aGuard (maMutex); + + // First try to guess the right index. + sal_Int16 nNumber ((pPage->GetPageNum()-1)/2); + SharedPageDescriptor pDescriptor (GetPageDescriptor(nNumber, false)); + if (pDescriptor.get() != NULL + && pDescriptor->GetPage() == pPage) + { + return nNumber; + } + + // Guess was wrong, iterate over all slides and search for the right + // one. + const sal_Int32 nCount (maPageDescriptors.size()); + for (sal_Int32 nIndex=0; nIndexGetPage() == pPage) + return nIndex; + } + + return -1; +} + + + + /** For now this method uses a trivial algorithm: throw away all descriptors and create them anew (on demand). The main problem that we are facing when designing a better algorithm is that we can not compare pointers to @@ -312,7 +358,7 @@ void SlideSorterModel::SynchronizeDocumentSelection (void) while (aAllPages.HasMoreElements()) { SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); - pDescriptor->GetPage()->SetSelected (pDescriptor->IsSelected()); + pDescriptor->GetPage()->SetSelected(pDescriptor->HasState(PageDescriptor::ST_Selected)); } } @@ -327,50 +373,8 @@ void SlideSorterModel::SynchronizeModelSelection (void) while (aAllPages.HasMoreElements()) { SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); - if (pDescriptor->GetPage()->IsSelected()) - pDescriptor->Select (); - else - pDescriptor->Deselect (); - } -} - - - - -void SlideSorterModel::SetPageObjectFactory( - ::std::auto_ptr pPageObjectFactory) -{ - ::osl::MutexGuard aGuard (maMutex); - - mpPageObjectFactory = pPageObjectFactory; - // When a NULL pointer was given then create a default factory. - const controller::PageObjectFactory& rFactory (GetPageObjectFactory()); - PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this)); - while (aAllPages.HasMoreElements()) - { - SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); - pDescriptor->SetPageObjectFactory(rFactory); - } -} - - - - -const controller::PageObjectFactory& - SlideSorterModel::GetPageObjectFactory (void) const -{ - ::osl::MutexGuard aGuard (maMutex); - - if (mpPageObjectFactory.get() == NULL) - { - // We have to create a new factory. The pointer is mutable so we - // are alowed to do so. - mpPageObjectFactory = ::std::auto_ptr ( - new controller::PageObjectFactory( - mrSlideSorter.GetView().GetPreviewCache(), - mrSlideSorter.GetController().GetProperties())); + pDescriptor->SetState(PageDescriptor::ST_Selected, pDescriptor->GetPage()->IsSelected()); } - return *mpPageObjectFactory.get(); } diff --git a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx index 5061d44a88a4..2e5e9b08f905 100644 --- a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx @@ -32,9 +32,6 @@ #include "precompiled_sd.hxx" #include "model/SlsPageDescriptor.hxx" -#include "view/SlsPageObject.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" -#include "controller/SlsPageObjectFactory.hxx" #include "sdpage.hxx" #include "drawdoc.hxx" @@ -51,20 +48,18 @@ namespace sd { namespace slidesorter { namespace model { PageDescriptor::PageDescriptor ( const Reference& rxPage, SdPage* pPage, - const sal_Int32 nIndex, - const controller::PageObjectFactory& rPageObjectFactory) + const sal_Int32 nIndex) : mpPage(pPage), mxPage(rxPage), mnIndex(nIndex), - mpPageObjectFactory(&rPageObjectFactory), - mpPageObject(NULL), mbIsSelected(false), + mbWasSelected(false), mbIsVisible(false), mbIsFocused(false), mbIsCurrent(false), - mpViewObjectContact(NULL), - maModelBorder(0,0,0,0), - maPageNumberAreaModelSize(0,0) + mbIsMouseOver(false), + maBoundingBox(), + maVisualState(nIndex) { OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage)); } @@ -103,74 +98,104 @@ sal_Int32 PageDescriptor::GetPageIndex (void) const -view::PageObject* PageDescriptor::GetPageObject (void) +bool PageDescriptor::HasState (const State eState) const { - if (mpPageObject==NULL && mpPageObjectFactory!=NULL && mpPage != NULL) + switch (eState) { - mpPageObject = mpPageObjectFactory->CreatePageObject(mpPage, shared_from_this()); - } - - return mpPageObject; -} - - - - -void PageDescriptor::ReleasePageObject (void) -{ - mpPageObject = NULL; -} - - + case ST_Visible: + return mbIsVisible; + case ST_Selected: + return mbIsSelected; -bool PageDescriptor::IsVisible (void) const -{ - return mbIsVisible; -} - + case ST_WasSelected: + return mbWasSelected; + case ST_Focused: + return mbIsFocused; + case ST_MouseOver: + return mbIsMouseOver; -void PageDescriptor::SetVisible (bool bIsVisible) -{ - mbIsVisible = bIsVisible; -} - + case ST_Current: + return mbIsCurrent; + case ST_Excluded: + return mpPage!=NULL && mpPage->IsExcluded(); - -bool PageDescriptor::Select (void) -{ - if ( ! IsSelected()) - { - mbIsSelected = true; - return true; + default: + OSL_ASSERT(false); + return false; } - else - return false; } -bool PageDescriptor::Deselect (void) +bool PageDescriptor::SetState (const State eState, const bool bNewStateValue) { - if (IsSelected()) + bool bModified (false); + switch (eState) { - mbIsSelected = false; - return true; + case ST_Visible: + bModified = (bNewStateValue!=mbIsVisible); + if (bModified) + mbIsVisible = bNewStateValue; + break; + + case ST_Selected: + bModified = (bNewStateValue!=mbIsSelected); + if (bModified) + mbIsSelected = bNewStateValue; + break; + + case ST_WasSelected: + bModified = (bNewStateValue!=mbWasSelected); + if (bModified) + mbWasSelected = bNewStateValue; + break; + + case ST_Focused: + bModified = (bNewStateValue!=mbIsFocused); + if (bModified) + mbIsFocused = bNewStateValue; + break; + + case ST_MouseOver: + bModified = (bNewStateValue!=mbIsMouseOver); + if (bModified) + mbIsMouseOver = bNewStateValue; + break; + + case ST_Current: + bModified = (bNewStateValue!=mbIsCurrent); + if (bModified) + mbIsCurrent = bNewStateValue; + break; + + case ST_Excluded: + // This is a state of the page and has to be handled differently + // from the view-only states. + if (mpPage != NULL) + if (bNewStateValue != (mpPage->IsExcluded()==TRUE)) + { + mpPage->SetExcluded(bNewStateValue); + bModified = true; + } + break; } - else - return false; + + if (bModified) + maVisualState.UpdateVisualState(*this); + return bModified; } -bool PageDescriptor::IsSelected (void) const +VisualState& PageDescriptor::GetVisualState (void) { - return mbIsSelected; + return maVisualState; } @@ -179,10 +204,7 @@ bool PageDescriptor::IsSelected (void) const bool PageDescriptor::UpdateSelection (void) { if (mpPage!=NULL && (mpPage->IsSelected()==TRUE) != mbIsSelected) - { - mbIsSelected = ! mbIsSelected; - return true; - } + return SetState(ST_Selected, !mbIsSelected); else return false; } @@ -190,109 +212,28 @@ bool PageDescriptor::UpdateSelection (void) -bool PageDescriptor::IsFocused (void) const -{ - return mbIsFocused; -} - - - - -void PageDescriptor::SetFocus (void) -{ - mbIsFocused = true; -} - - - - -void PageDescriptor::RemoveFocus (void) -{ - mbIsFocused = false; -} - - - - -view::PageObjectViewObjectContact* - PageDescriptor::GetViewObjectContact (void) const -{ - return mpViewObjectContact; -} - - - - -void PageDescriptor::SetViewObjectContact ( - view::PageObjectViewObjectContact* pViewObjectContact) -{ - mpViewObjectContact = pViewObjectContact; -} - - - - -const controller::PageObjectFactory& - PageDescriptor::GetPageObjectFactory (void) const -{ - return *mpPageObjectFactory; -} - - - - -void PageDescriptor::SetPageObjectFactory ( - const controller::PageObjectFactory& rFactory) -{ - mpPageObjectFactory = &rFactory; -} - - - - -void PageDescriptor::SetModelBorder (const SvBorder& rBorder) -{ - maModelBorder = rBorder; -} - - - - -SvBorder PageDescriptor::GetModelBorder (void) const -{ - return maModelBorder; -} - - - - -void PageDescriptor::SetPageNumberAreaModelSize (const Size& rSize) -{ - maPageNumberAreaModelSize = rSize; -} - - - - -Size PageDescriptor::GetPageNumberAreaModelSize (void) const +Rectangle PageDescriptor::GetBoundingBox (void) const { - return maPageNumberAreaModelSize; + Rectangle aBox (maBoundingBox); + const Point aOffset (maVisualState.GetLocationOffset()); + aBox.Move(aOffset.X(), aOffset.Y()); + return aBox; } -bool PageDescriptor::IsCurrentPage (void) const +Point PageDescriptor::GetLocation (void) const { - return mbIsCurrent; + return maBoundingBox.TopLeft() + maVisualState.GetLocationOffset(); } -void PageDescriptor::SetIsCurrentPage (const bool bIsCurrent) +void PageDescriptor::SetBoundingBox (const Rectangle& rBoundingBox) { - mbIsCurrent = bIsCurrent; + maBoundingBox = rBoundingBox; } diff --git a/sd/source/ui/slidesorter/model/SlsPageEnumerationProvider.cxx b/sd/source/ui/slidesorter/model/SlsPageEnumerationProvider.cxx index e6e3b89b12d5..e860beeb6c23 100644 --- a/sd/source/ui/slidesorter/model/SlsPageEnumerationProvider.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageEnumerationProvider.cxx @@ -60,7 +60,7 @@ class SelectedPagesPredicate public: bool operator() (const SharedPageDescriptor& rpDescriptor) { - return rpDescriptor->IsSelected(); + return rpDescriptor->HasState(PageDescriptor::ST_Selected); } }; @@ -72,7 +72,7 @@ class VisiblePagesPredicate public: bool operator() (const SharedPageDescriptor& rpDescriptor) { - return rpDescriptor->IsVisible(); + return rpDescriptor->HasState(PageDescriptor::ST_Visible); } }; diff --git a/sd/source/ui/slidesorter/model/SlsVisualState.cxx b/sd/source/ui/slidesorter/model/SlsVisualState.cxx new file mode 100644 index 000000000000..d6b3deecea5b --- /dev/null +++ b/sd/source/ui/slidesorter/model/SlsVisualState.cxx @@ -0,0 +1,236 @@ +/************************************************************************* + * + * 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: SlsPageDescriptor.hxx,v $ + * $Revision: 1.8 $ + * + * 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 "model/SlsVisualState.hxx" +#include "model/SlsPageDescriptor.hxx" +#include "controller/SlsAnimator.hxx" + +namespace sd { namespace slidesorter { namespace model { + +VisualState::VisualState (const sal_Int32 nPageId) + : mnPageId(nPageId), + meCurrentVisualState(VS_None), + meOldVisualState(VS_None), + mnVisualStateBlend(1.0), + mnStateAnimationId(controller::Animator::NotAnAnimationId), + maLocationOffset(0,0), + mnLocationAnimationId(controller::Animator::NotAnAnimationId), + mnButtonAlpha(1.0), + mnButtonAlphaAnimationId(controller::Animator::NotAnAnimationId) +{ +} + + + + +VisualState::~VisualState (void) +{ + OSL_ASSERT(mnStateAnimationId == controller::Animator::NotAnAnimationId); + OSL_ASSERT(mnLocationAnimationId == controller::Animator::NotAnAnimationId); +} + + + + +VisualState::State VisualState::GetCurrentVisualState (void) const +{ + return meCurrentVisualState; +} + + + + +VisualState::State VisualState::GetOldVisualState (void) const +{ + return meOldVisualState; +} + + + + +void VisualState::SetVisualState (const State eState) +{ + meOldVisualState = meCurrentVisualState; + meCurrentVisualState = eState; + mnVisualStateBlend = 1.0; +} + + + + +double VisualState::GetVisualStateBlend (void) const +{ + return mnVisualStateBlend; +} + + + + +void VisualState::SetVisualStateBlend (const double nBlend) +{ + mnVisualStateBlend = nBlend; +} + + + + +void VisualState::UpdateVisualState (const PageDescriptor& rDescriptor) +{ + if (rDescriptor.HasState(PageDescriptor::ST_Excluded)) + SetVisualState(VS_Excluded); + else if (rDescriptor.HasState(PageDescriptor::ST_Current)) + SetVisualState(VS_Current); + else if (rDescriptor.HasState(PageDescriptor::ST_Focused)) + SetVisualState(VS_Focused); + else if (rDescriptor.HasState(PageDescriptor::ST_Selected)) + SetVisualState(VS_Selected); + else + SetVisualState(VS_None); + + SetMouseOverState(rDescriptor.HasState(PageDescriptor::ST_MouseOver)); +} + + + + +void VisualState::SetMouseOverState (const bool bIsMouseOver) +{ + mbOldMouseOverState = mbCurrentMouseOverState; + mbCurrentMouseOverState = bIsMouseOver; +} + + + + +sal_Int32 VisualState::GetStateAnimationId (void) const +{ + return mnStateAnimationId; +} + + + + +void VisualState::SetStateAnimationId (const sal_Int32 nAnimationId) +{ + mnStateAnimationId = nAnimationId; +} + + + + +Point VisualState::GetLocationOffset (void) const +{ + return maLocationOffset; +} + + + + +bool VisualState::SetLocationOffset (const Point& rOffset) +{ + if (maLocationOffset != rOffset) + { + maLocationOffset = rOffset; + return true; + } + else + return false; +} + + + + +sal_Int32 VisualState::GetLocationAnimationId (void) const +{ + return mnLocationAnimationId; +} + + + + +void VisualState::SetLocationAnimationId (const sal_Int32 nAnimationId) +{ + mnLocationAnimationId = nAnimationId; +} + + + + +double VisualState::GetButtonAlpha (void) const +{ + return mnButtonAlpha; +} + + + + +void VisualState::SetButtonAlpha (const double nAlpha) +{ + mnButtonAlpha = nAlpha; +} + + + + +sal_Int32 VisualState::GetButtonAlphaAnimationId (void) const +{ + return mnButtonAlphaAnimationId; +} + + + + +void VisualState::SetButtonAlphaAnimationId (const sal_Int32 nAnimationId) +{ + mnButtonAlphaAnimationId = nAnimationId; +} + + + + +void VisualState::SetActiveButtonState (const sal_Int32 nIndex, const ButtonState eState) +{ + mnActiveButtonIndex = nIndex; + meActiveButtonState = eState; +} + + + + +VisualState::ButtonState VisualState::GetButtonState (const sal_Int32 nIndex) +{ + if (nIndex == mnActiveButtonIndex) + return meActiveButtonState; + else + return BS_Normal; +} + + +} } } // end of namespace ::sd::slidesorter::model diff --git a/sd/source/ui/slidesorter/model/makefile.mk b/sd/source/ui/slidesorter/model/makefile.mk index 653e437be91b..bff5d8aeaddf 100644 --- a/sd/source/ui/slidesorter/model/makefile.mk +++ b/sd/source/ui/slidesorter/model/makefile.mk @@ -50,6 +50,7 @@ SLOFILES = \ $(SLO)$/SlsPageDescriptor.obj \ $(SLO)$/SlsPageEnumeration.obj \ $(SLO)$/SlsPageEnumerationProvider.obj \ + $(SLO)$/SlsVisualState.obj \ $(SLO)$/SlideSorterModel.obj EXCEPTIONSFILES= diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx index 9d0dbae862fa..4d8943ddd7e3 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorter.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -36,6 +36,7 @@ #include "SlideSorterViewShell.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsScrollBarManager.hxx" +#include "controller/SlsProperties.hxx" #include "view/SlideSorterView.hxx" #include "model/SlideSorterModel.hxx" @@ -138,7 +139,8 @@ SlideSorter::SlideSorter ( mpHorizontalScrollBar(rpHorizontalScrollBar), mpVerticalScrollBar(rpVerticalScrollBar), mpScrollBarBox(rpScrollBarBox), - mbLayoutPending(true) + mbLayoutPending(true), + mpProperties(new controller::Properties()) { } @@ -160,7 +162,8 @@ SlideSorter::SlideSorter ( mpHorizontalScrollBar(new ScrollBar(&rParentWindow,WinBits(WB_HSCROLL | WB_DRAG))), mpVerticalScrollBar(new ScrollBar(&rParentWindow,WinBits(WB_VSCROLL | WB_DRAG))), mpScrollBarBox(new ScrollBarBox(&rParentWindow)), - mbLayoutPending(true) + mbLayoutPending(true), + mpProperties(new controller::Properties()) { } @@ -172,12 +175,26 @@ void SlideSorter::Init (void) if (mpViewShellBase != NULL) mxControllerWeak = mpViewShellBase->GetController(); + + // Reinitialize colors in Properties with window specific values. + if (mpContentWindow) + { + mpProperties->SetBackgroundColor( + mpContentWindow->GetSettings().GetStyleSettings().GetWindowColor()); + mpProperties->SetTextColor( + mpContentWindow->GetSettings().GetStyleSettings().GetWindowTextColor()); + mpProperties->SetSelectionColor( + mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor()); + mpProperties->SetHighlightColor( + mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor()); + } + CreateModelViewController (); SetupListeners (); // Initialize the window. - ::sd::Window* pWindow = GetActiveWindow(); + ::boost::shared_ptr pWindow (GetContentWindow()); if (pWindow != NULL) { ::Window* pParentWindow = pWindow->GetParent(); @@ -207,6 +224,12 @@ SlideSorter::~SlideSorter (void) ReleaseListeners(); + // Dispose model, view and controller to avoid calls between them when + // they are being destructed and one or two of them are already gone. + mpSlideSorterController->Dispose(); + mpSlideSorterView->Dispose(); + mpSlideSorterModel->Dispose(); + // Reset the auto pointers explicitly to control the order of destruction. mpSlideSorterController.reset(); mpSlideSorterView.reset(); @@ -215,6 +238,9 @@ SlideSorter::~SlideSorter (void) mpHorizontalScrollBar.reset(); mpVerticalScrollBar.reset(); mpScrollBarBox.reset(); + const int nCount (mpContentWindow.use_count()); + OSL_ASSERT(mpContentWindow.unique()); + OSL_ASSERT(mpContentWindow.use_count()==1); mpContentWindow.reset(); } @@ -308,17 +334,6 @@ void SlideSorter::Paint (const Rectangle& rRepaintArea) -::sd::Window* SlideSorter::GetActiveWindow (void) const -{ - if (mpViewShell != NULL) - return mpViewShell->GetActiveWindow(); - else - return mpContentWindow.get(); -} - - - - ViewShellBase* SlideSorter::GetViewShellBase (void) const { return mpViewShellBase; @@ -346,8 +361,8 @@ void SlideSorter::SetupControls (::Window* ) void SlideSorter::SetupListeners (void) { - ::sd::Window* pWindow = GetActiveWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (GetContentWindow()); + if (pWindow) { ::Window* pParentWindow = pWindow->GetParent(); if (pParentWindow != NULL) @@ -378,8 +393,8 @@ void SlideSorter::ReleaseListeners (void) { mpSlideSorterController->GetScrollBarManager().Disconnect(); - ::sd::Window* pWindow = GetActiveWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (GetContentWindow()); + if (pWindow) { pWindow->RemoveEventListener( @@ -468,22 +483,17 @@ void SlideSorter::ArrangeGUIElements ( // Prevent untimely redraws while the view is not yet correctly // resized. mpSlideSorterView->LockRedraw (TRUE); - if (GetActiveWindow() != NULL) - GetActiveWindow()->EnablePaint (FALSE); + if (GetContentWindow()) + GetContentWindow()->EnablePaint (FALSE); - // maAllWindowRectangle = mpSlideSorterController->Resize (Rectangle(aOrigin, rSize)); - if (GetActiveWindow() != NULL) - GetActiveWindow()->EnablePaint (TRUE); + if (GetContentWindow()) + GetContentWindow()->EnablePaint (TRUE); mbLayoutPending = false; mpSlideSorterView->LockRedraw (FALSE); } - else - { - // maAllWindowRectangle = Rectangle(); - } } @@ -553,6 +563,14 @@ void SlideSorter::SetCurrentFunction (const FunctionReference& rpFunction) +::boost::shared_ptr SlideSorter::GetProperties (void) const +{ + return mpProperties; +} + + + + //===== ContentWindow ========================================================= namespace { diff --git a/sd/source/ui/slidesorter/shell/SlideSorterService.cxx b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx index 75b7d23db43f..272a85b3f391 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterService.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx @@ -321,7 +321,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsHighlightCurrentSlide (void) if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return false; else - return mpSlideSorter->GetController().GetProperties()->IsHighlightCurrentSlide(); + return mpSlideSorter->GetProperties()->IsHighlightCurrentSlide(); } @@ -333,7 +333,7 @@ void SAL_CALL SlideSorterService::setIsHighlightCurrentSlide (sal_Bool bValue) ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) { - mpSlideSorter->GetController().GetProperties()->SetHighlightCurrentSlide(bValue); + mpSlideSorter->GetProperties()->SetHighlightCurrentSlide(bValue); controller::SlideSorterController::ModelChangeLock aLock (mpSlideSorter->GetController()); mpSlideSorter->GetController().HandleModelChange(); } @@ -349,7 +349,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsShowSelection (void) if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return false; else - return mpSlideSorter->GetController().GetProperties()->IsShowSelection(); + return mpSlideSorter->GetProperties()->IsShowSelection(); } @@ -360,7 +360,7 @@ void SAL_CALL SlideSorterService::setIsShowSelection (sal_Bool bValue) { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetShowSelection(bValue); + mpSlideSorter->GetProperties()->SetShowSelection(bValue); } @@ -373,7 +373,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsShowFocus (void) if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return false; else - return mpSlideSorter->GetController().GetProperties()->IsShowFocus(); + return mpSlideSorter->GetProperties()->IsShowFocus(); } @@ -384,7 +384,7 @@ void SAL_CALL SlideSorterService::setIsShowFocus (sal_Bool bValue) { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetShowFocus(bValue); + mpSlideSorter->GetProperties()->SetShowFocus(bValue); } @@ -397,7 +397,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsCenterSelection (void) if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return false; else - return mpSlideSorter->GetController().GetProperties()->IsCenterSelection(); + return mpSlideSorter->GetProperties()->IsCenterSelection(); } @@ -408,7 +408,7 @@ void SAL_CALL SlideSorterService::setIsCenterSelection (sal_Bool bValue) { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetCenterSelection(bValue); + mpSlideSorter->GetProperties()->SetCenterSelection(bValue); } @@ -421,7 +421,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsSuspendPreviewUpdatesDuringFullScreen if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return true; else - return mpSlideSorter->GetController().GetProperties() + return mpSlideSorter->GetProperties() ->IsSuspendPreviewUpdatesDuringFullScreenPresentation(); } @@ -434,7 +434,7 @@ void SAL_CALL SlideSorterService::setIsSuspendPreviewUpdatesDuringFullScreenPres { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties() + mpSlideSorter->GetProperties() ->SetSuspendPreviewUpdatesDuringFullScreenPresentation(bValue); } @@ -474,7 +474,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsSmoothScrolling (void) if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return false; else - return mpSlideSorter->GetController().GetProperties()->IsSmoothSelectionScrolling(); + return mpSlideSorter->GetProperties()->IsSmoothSelectionScrolling(); } @@ -485,7 +485,7 @@ void SAL_CALL SlideSorterService::setIsSmoothScrolling (sal_Bool bValue) { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetSmoothSelectionScrolling(bValue); + mpSlideSorter->GetProperties()->SetSmoothSelectionScrolling(bValue); } @@ -499,7 +499,7 @@ util::Color SAL_CALL SlideSorterService::getBackgroundColor (void) return util::Color(); else return util::Color( - mpSlideSorter->GetController().GetProperties()->GetBackgroundColor().GetColor()); + mpSlideSorter->GetProperties()->GetBackgroundColor().GetColor()); } @@ -510,8 +510,7 @@ void SAL_CALL SlideSorterService::setBackgroundColor (util::Color aBackgroundCol { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetBackgroundColor( - Color(aBackgroundColor)); + mpSlideSorter->GetProperties()->SetBackgroundColor(Color(aBackgroundColor)); } @@ -525,7 +524,7 @@ util::Color SAL_CALL SlideSorterService::getTextColor (void) return util::Color(); else return util::Color( - mpSlideSorter->GetController().GetProperties()->GetTextColor().GetColor()); + mpSlideSorter->GetProperties()->GetTextColor().GetColor()); } @@ -536,8 +535,7 @@ void SAL_CALL SlideSorterService::setTextColor (util::Color aTextColor) { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetTextColor( - Color(aTextColor)); + mpSlideSorter->GetProperties()->SetTextColor(Color(aTextColor)); } @@ -551,7 +549,7 @@ util::Color SAL_CALL SlideSorterService::getSelectionColor (void) return util::Color(); else return util::Color( - mpSlideSorter->GetController().GetProperties()->GetSelectionColor().GetColor()); + mpSlideSorter->GetProperties()->GetSelectionColor().GetColor()); } @@ -562,8 +560,7 @@ void SAL_CALL SlideSorterService::setSelectionColor (util::Color aSelectionColor { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetSelectionColor( - Color(aSelectionColor)); + mpSlideSorter->GetProperties()->SetSelectionColor(Color(aSelectionColor)); } @@ -577,7 +574,7 @@ util::Color SAL_CALL SlideSorterService::getHighlightColor (void) return util::Color(); else return util::Color( - mpSlideSorter->GetController().GetProperties()->GetHighlightColor().GetColor()); + mpSlideSorter->GetProperties()->GetHighlightColor().GetColor()); } @@ -588,8 +585,7 @@ void SAL_CALL SlideSorterService::setHighlightColor (util::Color aHighlightColor { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetHighlightColor( - Color(aHighlightColor)); + mpSlideSorter->GetProperties()->SetHighlightColor(Color(aHighlightColor)); } @@ -601,7 +597,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsUIReadOnly (void) if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return true; else - return mpSlideSorter->GetController().GetProperties()->IsUIReadOnly(); + return mpSlideSorter->GetProperties()->IsUIReadOnly(); } @@ -612,8 +608,7 @@ void SAL_CALL SlideSorterService::setIsUIReadOnly (sal_Bool bIsUIReadOnly) { ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) - mpSlideSorter->GetController().GetProperties()->SetUIReadOnly( - bIsUIReadOnly); + mpSlideSorter->GetProperties()->SetUIReadOnly(bIsUIReadOnly); } diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 0a04a236511c..194cf0f0ab83 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -191,8 +191,8 @@ void SlideSorterViewShell::Initialize (void) // 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.) - ::Window* pWindow = mpSlideSorter->GetActiveWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (mpSlideSorter->GetContentWindow()); + if (pWindow) { pWindow->Hide(); pWindow->Show(); @@ -641,10 +641,7 @@ void SlideSorterViewShell::SetZoom (long int ) void SlideSorterViewShell::SetZoomRect (const Rectangle& rZoomRect) { OSL_ASSERT(mpSlideSorter.get()!=NULL); - Size aPageSize (mpSlideSorter->GetView().GetPageBoundingBox( - 0, - view::SlideSorterView::CS_MODEL, - view::SlideSorterView::BBT_SHAPE).GetSize()); + Size aPageSize (mpSlideSorter->GetView().GetLayouter().GetPageObjectSize()); Rectangle aRect(rZoomRect); diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index e877b41d3738..f21063a1057c 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -37,20 +37,22 @@ #include "SlideSorterViewShell.hxx" #include "ViewShell.hxx" #include "SlsViewCacheContext.hxx" +#include "SlsLayeredDevice.hxx" #include "view/SlsLayouter.hxx" +#include "view/SlsPageObjectLayouter.hxx" +#include "view/SlsPageObjectPainter.hxx" #include "view/SlsViewOverlay.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" +#include "view/SlsILayerPainter.hxx" #include "controller/SlideSorterController.hxx" -#include "controller/SlsPageObjectFactory.hxx" #include "controller/SlsProperties.hxx" +#include "controller/SlsAnimator.hxx" +#include "controller/SlsAnimationFunction.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageDescriptor.hxx" #include "cache/SlsPageCache.hxx" #include "cache/SlsPageCacheManager.hxx" #include "cache/SlsCacheContext.hxx" -#include "view/SlsPageObject.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" #include "taskpane/SlideSorterCacheDisplay.hxx" #include "DrawDocShell.hxx" @@ -70,21 +72,243 @@ #include #include #include -#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include -#ifndef _SFXITEMPOOL_HXX -#include -#endif using namespace std; using namespace ::sd::slidesorter::model; +using namespace ::drawinglayer::primitive2d; + +using ::sd::slidesorter::controller::Animator; +using ::sd::slidesorter::controller::AnimationFunction; + +//#define VERBOSE namespace sd { namespace slidesorter { namespace view { -TYPEINIT1(SlideSorterView, ::sd::View); +/** Wrapper around the SlideSorterView that supports the IPainter interface + and that allows the LayeredDevice to hold the SlideSorterView (held as + scoped_ptr by the SlideSorter) as shared_ptr. +*/ +class Painter : public ILayerPainter +{ +public: + Painter (SlideSorterView& rView) : mrView(rView) {} + virtual ~Painter (void) {} + + virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) + { + mrView.Paint(rDevice,rRepaintArea); + } + virtual void SetLayerInvalidator (const SharedILayerInvalidator&) + { + } + +private: + SlideSorterView& mrView; +}; + +class AnimatedSphere +{ +public: + AnimatedSphere ( + const Size& rWindowSize, + const double nStartTime) + : mnCenterX(rand() * rWindowSize.Width() / RAND_MAX), + mnCenterY(rand() * rWindowSize.Height() / RAND_MAX), + mnStartRadius(10), + mnEndRadius(rand() * 150 / RAND_MAX), + maColor(GetColor()), + mnLocalTime(-nStartTime), + mnValue(0), + mnStartTime(nStartTime) + { + } + + void SetTime (const double nTime) + { + mnLocalTime = nTime - mnStartTime; + if (mnLocalTime >= 0 && mnLocalTime <= 1) + mnValue = controller::AnimationFunction::SlowInSlowOut_0to0_Sine(mnLocalTime); + else + mnValue = 0; + } + + bool IsExpired (void) + { + return mnLocalTime >= 1.0; + } + + Rectangle GetBoundingBox (void) + { + if (mnLocalTime < 0) + return Rectangle(); + + const double nRadius (mnStartRadius*(1-mnValue) + mnEndRadius*mnValue); + const sal_Int32 nIntRadius (ceil(nRadius)+1); + return Rectangle( + mnCenterX-nIntRadius, + mnCenterY-nIntRadius, + mnCenterX+nIntRadius, + mnCenterY+nIntRadius); + } + + void Paint (OutputDevice& rDevice) + { + if (mnLocalTime < 0) + return; + + rDevice.SetFillColor(maColor); + rDevice.SetLineColor(); + + const Rectangle aBox (GetBoundingBox()); + const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); + rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); + rDevice.DrawPolygon( + ::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), + 1.0, + 1.0)); + rDevice.SetAntialiasing(nSavedAntialiasingMode); + } + +private: + const sal_Int32 mnCenterX; + const sal_Int32 mnCenterY; + const double mnStartRadius; + const double mnEndRadius; + const Color maColor; + double mnLocalTime; + double mnValue; + const double mnStartTime; + + static Color GetColor (void) + { + Color aColor; + do + { + aColor.SetRed(rand() * 255 / RAND_MAX); + aColor.SetGreen(rand() * 255 / RAND_MAX); + aColor.SetBlue(rand() * 255 / RAND_MAX); + } + while (aColor.GetGreen()<=aColor.GetRed() || aColor.GetGreen()<=aColor.GetBlue()); + return aColor; + } +}; + +class BackgroundPainter + : public ILayerPainter, + public ::boost::noncopyable +{ +public: + BackgroundPainter ( + const ::boost::shared_ptr& rpAnimator, + const ::boost::shared_ptr< ::Window>& rpWindow, + const Color aBackgroundColor, + const bool bIsAnimated) + : mpAnimator(rpAnimator), + mnAnimationId(controller::Animator::NotAnAnimationId), + maBackgroundColor(aBackgroundColor), + maSpheres(), + mpInvalidator(), + mpWindow(rpWindow) + { + if (bIsAnimated) + { + mnAnimationId = mpAnimator->AddInfiniteAnimation(::boost::ref(*this), 0.01); + + for (sal_Int32 nIndex=0; nIndex<10; ++nIndex) + maSpheres.push_back(::boost::shared_ptr( + new AnimatedSphere(rpWindow->GetSizePixel(), nIndex*0.3))); + } + } + + ~BackgroundPainter (void) + { + mpAnimator->RemoveAnimation(mnAnimationId); + } + + virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) + { + rDevice.SetFillColor(maBackgroundColor); + rDevice.SetLineColor(); + rDevice.DrawRect(rRepaintArea); + + for (SphereVector::const_iterator + iSphere(maSpheres.begin()), + iEnd(maSpheres.end()); + iSphere!=iEnd; + ++iSphere) + { + if (rRepaintArea.IsOver((*iSphere)->GetBoundingBox())) + (*iSphere)->Paint(rDevice); + } + } + + virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator) + { + Invalidate(); + mpInvalidator = rpInvalidator; + Invalidate(); + } + + void operator () (const double nTime) + { + Invalidate(); + + for (SphereVector::iterator + iSphere(maSpheres.begin()), + iEnd(maSpheres.end()); + iSphere!=iEnd; + ++iSphere) + { + if ((*iSphere)->IsExpired()) + (*iSphere).reset( + new AnimatedSphere(mpWindow->GetSizePixel(), nTime)); + else + (*iSphere)->SetTime(nTime); + } + + Invalidate(); + } + +private: + const ::boost::shared_ptr mpAnimator; + const Color maBackgroundColor; + typedef ::std::vector< ::boost::shared_ptr > SphereVector; + SphereVector maSpheres; + SharedILayerInvalidator mpInvalidator; + ::boost::shared_ptr< ::Window> mpWindow; + controller::Animator::AnimationId mnAnimationId; + + void Invalidate (void) + { + if (mpInvalidator) + for (SphereVector::const_iterator + iSphere(maSpheres.begin()), + iEnd(maSpheres.end()); + iSphere!=iEnd; + ++iSphere) + { + mpInvalidator->Invalidate((*iSphere)->GetBoundingBox()); + } + } +}; + + + +TYPEINIT1(SlideSorterView, ::sd::View); SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) : ::sd::View ( @@ -93,33 +317,31 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) rSlideSorter.GetViewShell()), mrSlideSorter(rSlideSorter), mrModel(rSlideSorter.GetModel()), - maPageModel(), - mpPage(new SdrPage(maPageModel)), - mpLayouter (new Layouter ()), + mpLayouter (new Layouter (rSlideSorter.GetContentWindow())), mbPageObjectVisibilitiesValid (false), mpPreviewCache(), - mpViewOverlay (new ViewOverlay(rSlideSorter)), + mpLayeredDevice(new LayeredDevice(rSlideSorter.GetContentWindow())), + mpViewOverlay (new ViewOverlay(rSlideSorter, mpLayeredDevice)), mnFirstVisiblePageIndex(0), mnLastVisiblePageIndex(-1), mbModelChangedWhileModifyEnabled(true), maPreviewSize(0,0), mbPreciousFlagUpdatePending(true), - maPageNumberAreaModelSize(0,0), - maModelBorder(), - meOrientation(VERTICAL) + meOrientation(VERTICAL), + mpProperties(rSlideSorter.GetProperties()), + mpPageUnderMouse(), + mnButtonUnderMouse(-1), + mpPageObjectPainter() { // Hide the page that contains the page objects. SetPageVisible (FALSE); - // call FreezeIdRanges() at the pool from the newly constructed SdrModel, - // else creating SfxItemSets on it will complain - maPageModel.GetItemPool().FreezeIdRanges(); - - // add the page to the model (no, this is NOT done by the constructor :-( ) - maPageModel.InsertPage(mpPage); - - // show page - LocalModelHasChanged(); + // Wrap a shared_ptr held wrapper around this view and register it as + // painter at the layered device. There is no explicit destruction: in + // the SlideSorterView destructor the layered device is destroyed and + // with it the only reference to the wrapper which therefore is also + // destroyed. + mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 1); } @@ -127,20 +349,8 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) SlideSorterView::~SlideSorterView (void) { - // Inform the contact objects to disconnect from the preview cache. - // Otherwise each dying contact object invalidates its preview. When - // the previews are kept for a later re-use than this invalidation is - // not wanted. - ::boost::shared_ptr pEmptyCache; - model::PageEnumeration aPageEnumeration ( - model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); - while (aPageEnumeration.HasMoreElements()) - { - view::PageObjectViewObjectContact* pContact - = aPageEnumeration.GetNextElement()->GetViewObjectContact(); - if (pContact != NULL) - pContact->SetCache(pEmptyCache); - } + mpLayeredDevice->Dispose(); + mpPreviewCache.reset(); // hide the page to avoid problems in the view when deleting @@ -149,6 +359,19 @@ SlideSorterView::~SlideSorterView (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(); +} + + + + +void SlideSorterView::Dispose (void) +{ } @@ -158,8 +381,8 @@ sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rPosition) const { sal_Int32 nIndex (-1); - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) { nIndex = mpLayouter->GetIndexAtPoint (pWindow->PixelToLogic (rPosition)); @@ -179,8 +402,8 @@ sal_Int32 SlideSorterView::GetFadePageIndexAtPoint ( { sal_Int32 nIndex (-1); - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) { Point aModelPosition (pWindow->PixelToLogic (rPosition)); nIndex = mpLayouter->GetIndexAtPoint( @@ -196,20 +419,13 @@ sal_Int32 SlideSorterView::GetFadePageIndexAtPoint ( { // Now test whether the given position is inside the area of the // fade effect indicator. - view::PageObjectViewObjectContact* pContact - = mrModel.GetPageDescriptor(nIndex)->GetViewObjectContact(); - if (pContact != NULL) - { - if ( ! pContact->GetBoundingBox( - *pWindow, - PageObjectViewObjectContact::FadeEffectIndicatorBoundingBox, - PageObjectViewObjectContact::ModelCoordinateSystem).IsInside ( - aModelPosition)) - { - nIndex = -1; - } - } - else + const Rectangle aBox ( + mpLayouter->GetPageObjectLayouter()->GetBoundingBox( + mrModel.GetPageDescriptor(nIndex), + PageObjectLayouter::TransitionEffectIndicator, + PageObjectLayouter::WindowCoordinateSystem)); + const Point aPoint (aModelPosition.getX(), aModelPosition.getY()); + if ( ! aBox.IsInside(aPoint)) nIndex = -1; } } @@ -230,12 +446,16 @@ Layouter& SlideSorterView::GetLayouter (void) void SlideSorterView::ModelHasChanged (void) { + // Ignore this call. Rely on hints sent by the model to get informed of + // model changes. + /* if (mbModelChangedWhileModifyEnabled) { controller::SlideSorterController::ModelChangeLock alock( mrSlideSorter.GetController() ); mrSlideSorter.GetController().HandleModelChange(); LocalModelHasChanged(); } + */ } @@ -248,15 +468,10 @@ void SlideSorterView::LocalModelHasChanged(void) // First call our base class. View::ModelHasChanged (); - // Then re-set the page as current page that contains the page objects. - ShowSdrPage(mpPage); - // Initialize everything that depends on a page view, now that we have // one. // SetApplicationDocumentColor( // Application::GetSettings().GetStyleSettings().GetWindowColor()); - - UpdatePageBorders(); } @@ -266,17 +481,7 @@ void SlideSorterView::PreModelChange (void) { // Reset the slide under the mouse. It will be set to the correct slide // on the next mouse motion. - GetOverlay().GetMouseOverIndicatorOverlay().SetSlideUnderMouse(SharedPageDescriptor()); - - // Tell the page descriptors of the model that the page objects do not - // exist anymore. - model::PageEnumeration aPageEnumeration ( - model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); - while (aPageEnumeration.HasMoreElements()) - aPageEnumeration.GetNextElement()->ReleasePageObject(); - - // Remove all page objects from the page. - mpPage->Clear(); + SetPageUnderMouse(SharedPageDescriptor()); } @@ -290,13 +495,6 @@ void SlideSorterView::PostModelChange (void) model::PageEnumeration aPageEnumeration ( model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); - UpdatePageBorders(); - while (aPageEnumeration.HasMoreElements()) - { - SdrPageObj* pPageObject = aPageEnumeration.GetNextElement()->GetPageObject(); - if (pPageObject != NULL) - AddSdrObject(*pPageObject); - } // The new page objects have to be scaled and positioned. Layout (); @@ -321,18 +519,11 @@ void SlideSorterView::HandleModelChange (void) void SlideSorterView::HandleDrawModeChange (void) { - UpdatePageBorders(); - // Replace the preview cache with a new and empty one. The // PreviewRenderer that is used by the cache is replaced by this as // well. mpPreviewCache.reset(); GetPreviewCache()->InvalidateCache(true); - mrModel.SetPageObjectFactory( - ::std::auto_ptr( - new controller::PageObjectFactory( - GetPreviewCache(), - mrSlideSorter.GetController().GetProperties()))); RequestRepaint(); } @@ -342,17 +533,25 @@ void SlideSorterView::HandleDrawModeChange (void) void SlideSorterView::Resize (void) { - ::sd::Window* pWindow = GetWindow(); - if (mrModel.GetPageCount()>0 && pWindow != NULL) + if ( ! mpLayeredDevice->HasPainter(0)) + mpLayeredDevice->RegisterPainter( + SharedILayerPainter(new BackgroundPainter( + mrSlideSorter.GetController().GetAnimator(), + mrSlideSorter.GetContentWindow(), + Color(0xf9fafa),//mpProperties->GetBackgroundColor(), + false)), + 0); + + mpLayeredDevice->Resize(); + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (mrModel.GetPageCount()>0 && pWindow) { - UpdatePageBorders(); bool bRearrangeSuccess (false); if (meOrientation == HORIZONTAL) { bRearrangeSuccess = mpLayouter->RearrangeHorizontal ( pWindow->GetSizePixel(), mrModel.GetPageDescriptor(0)->GetPage()->GetSize(), - pWindow, mrModel.GetPageCount()); } else @@ -360,13 +559,12 @@ void SlideSorterView::Resize (void) bRearrangeSuccess = mpLayouter->RearrangeVertical ( pWindow->GetSizePixel(), mrModel.GetPageDescriptor(0)->GetPage()->GetSize(), - pWindow); + mrModel.GetPageCount()); } if (bRearrangeSuccess) { Layout(); - pWindow->Invalidate(); } } } @@ -376,38 +574,36 @@ void SlideSorterView::Resize (void) void SlideSorterView::Layout () { - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL) + const ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) { // Set the model area, i.e. the smallest rectangle that includes all // page objects. - Rectangle aViewBox (mpLayouter->GetPageBox(mrModel.GetPageCount())); + const Rectangle aViewBox (mpLayouter->GetPageBox(mrModel.GetPageCount())); pWindow->SetViewOrigin (aViewBox.TopLeft()); pWindow->SetViewSize (aViewBox.GetSize()); - Size aPageObjectPixelSize (pWindow->LogicToPixel(mpLayouter->GetPageObjectSize())); - if (maPreviewSize != aPageObjectPixelSize && mpPreviewCache.get()!=NULL) + ::boost::shared_ptr pPageObjectLayouter( + mpLayouter->GetPageObjectLayouter()); + if (pPageObjectLayouter) { - mpPreviewCache->ChangeSize(aPageObjectPixelSize); - maPreviewSize = aPageObjectPixelSize; + const Size aNewPreviewSize (mpLayouter->GetPageObjectLayouter()->GetPreviewSize()); + if (maPreviewSize != aNewPreviewSize && GetPreviewCache()) + { + mpPreviewCache->ChangeSize(aNewPreviewSize, false); + maPreviewSize = aNewPreviewSize; + } } // Iterate over all page objects and place them relative to the // containing page. model::PageEnumeration aPageEnumeration ( model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); - int nIndex = 0; while (aPageEnumeration.HasMoreElements()) { model::SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); - SdrPageObj* pPageObject = pDescriptor->GetPageObject(); - Rectangle aPageObjectBox (mpLayouter->GetPageObjectBox (nIndex)); - pPageObject->SetSnapRect(aPageObjectBox); - - nIndex += 1; + pDescriptor->SetBoundingBox(mpLayouter->GetPageObjectBox(pDescriptor->GetPageIndex())); } - // Set the page so that it encloses all page objects. - mpPage->SetSize (aViewBox.GetSize()); } InvalidatePageObjectVisibilities (); @@ -426,52 +622,33 @@ void SlideSorterView::InvalidatePageObjectVisibilities (void) void SlideSorterView::DeterminePageObjectVisibilities (void) { - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) { // Set this flag to true here so that an invalidate during the // visibility calculation can correctly invalidate it again. mbPageObjectVisibilitiesValid = true; - Rectangle aViewArea ( - Point(0,0), - pWindow->GetSizePixel()); - aViewArea = pWindow->PixelToLogic (aViewArea); - int nFirstIndex = - mpLayouter->GetIndexOfFirstVisiblePageObject (aViewArea); - int nLastIndex = - mpLayouter->GetIndexOfLastVisiblePageObject (aViewArea); + Rectangle aViewArea (pWindow->PixelToLogic(Rectangle(Point(0,0),pWindow->GetSizePixel()))); + const int nFirstIndex (mpLayouter->GetIndexOfFirstVisiblePageObject(aViewArea)); + const int nLastIndex (mpLayouter->GetIndexOfLastVisiblePageObject(aViewArea)); + const int nMinIndex (::std::min (mnFirstVisiblePageIndex, nFirstIndex)); + const int nMaxIndex (::std::max (mnLastVisiblePageIndex, nLastIndex)); // For page objects that just dropped off the visible area we // decrease the priority of pending requests for preview bitmaps. - - int nMinIndex = ::std::min (mnFirstVisiblePageIndex, nFirstIndex); - int nMaxIndex = ::std::max (mnLastVisiblePageIndex, nLastIndex); if (mnFirstVisiblePageIndex!=nFirstIndex || mnLastVisiblePageIndex!=nLastIndex) mbPreciousFlagUpdatePending |= true; + model::SharedPageDescriptor pDescriptor; - view::PageObjectViewObjectContact* pContact; for (int nIndex=nMinIndex; nIndex<=nMaxIndex; nIndex++) { - // Determine the visibility before and after the change so that - // we can handle the page objects for which the visibility has - // changed. - bool bWasVisible = nIndex>=mnFirstVisiblePageIndex - && nIndex<=mnLastVisiblePageIndex; - bool bIsVisible = nIndex>=nFirstIndex && nIndex<=nLastIndex; - - // Get the view-object-contact. - if (bWasVisible != bIsVisible) - { - pContact = NULL; - pDescriptor = mrModel.GetPageDescriptor(nIndex); - if (pDescriptor.get() != NULL) - pContact = pDescriptor->GetViewObjectContact(); - - if (pDescriptor.get() != NULL) - pDescriptor->SetVisible (bIsVisible); - } - + pDescriptor = mrModel.GetPageDescriptor(nIndex); + if (pDescriptor.get() != NULL) + SetState( + pDescriptor, + PageDescriptor::ST_Visible, + nIndex>=nFirstIndex && nIndex<=nLastIndex); } mnFirstVisiblePageIndex = nFirstIndex; mnLastVisiblePageIndex = nLastIndex; @@ -535,9 +712,15 @@ SlideSorterView::Orientation SlideSorterView::GetOrientation (void) const void SlideSorterView::RequestRepaint (void) { - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { pWindow->Invalidate(); + mpLayeredDevice->InvalidateAllLayers( + Rectangle( + pWindow->PixelToLogic(Point(0,0)), + pWindow->PixelToLogic(pWindow->GetSizePixel()))); + } } @@ -545,157 +728,106 @@ void SlideSorterView::RequestRepaint (void) void SlideSorterView::RequestRepaint (const model::SharedPageDescriptor& rpDescriptor) { - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL) - pWindow->Invalidate( - GetPageBoundingBox ( - rpDescriptor, - CS_MODEL, - BBT_INFO)); -} - - - - -Rectangle SlideSorterView::GetModelArea (void) -{ - return Rectangle ( - Point (0,0), - Size (mpPage->GetSize().Width(),mpPage->GetSize().Height())); + RequestRepaint(rpDescriptor->GetBoundingBox()); } -Rectangle SlideSorterView::GetPageBoundingBox ( - const model::SharedPageDescriptor& rpDescriptor, - CoordinateSystem eCoordinateSystem, - BoundingBoxType eBoundingBoxType) const +void SlideSorterView::RequestRepaint (const Rectangle& rRepaintBox) { - Rectangle aBBox; - SdrObject* pPageObject = rpDescriptor->GetPageObject(); - if (pPageObject != NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) { - aBBox = pPageObject->GetCurrentBoundRect(); - AdaptBoundingBox (aBBox, eCoordinateSystem, eBoundingBoxType); + pWindow->Invalidate(rRepaintBox); + mpLayeredDevice->InvalidateAllLayers(rRepaintBox); } - - return aBBox; } -Rectangle SlideSorterView::GetPageBoundingBox ( - sal_Int32 nIndex, - CoordinateSystem eCoordinateSystem, - BoundingBoxType eBoundingBoxType) const +Rectangle SlideSorterView::GetModelArea (void) { - Rectangle aBBox; - if (nIndex >= 0 && nIndexGetPageObjectBox(nIndex); - AdaptBoundingBox (aBBox, eCoordinateSystem, eBoundingBoxType); - } - - return aBBox; + return mpLayouter->GetPageBox(mrModel.GetPageCount()); } +static sal_Int32 nPaintIndex = 0; - -void SlideSorterView::CompleteRedraw(OutputDevice* pDevice, const Region& rPaintArea, sdr::contact::ViewObjectContactRedirector* pRedirector) +void SlideSorterView::CompleteRedraw ( + OutputDevice* pDevice, + const Region& rPaintArea, + sdr::contact::ViewObjectContactRedirector* pRedirector) { + if (pDevice == NULL || pDevice!=mrSlideSorter.GetContentWindow().get()) + return; + + // The parent implementation of CompleteRedraw is called only when + // painting is locked. We do all the painting ourself. When painting + // is locked the parent implementation keeps track of the repaint + // requests and later, when painting is unlocked, calls CompleteRedraw + // for all missed repaints. + if (mnLockRedrawSmph == 0) { - // Update the page visibilities when they have been invalidated. - if ( ! mbPageObjectVisibilitiesValid) - DeterminePageObjectVisibilities(); +#ifdef VERBOSE + OSL_TRACE("%5d CompleteRedraw %d %d %d %d", + nPaintIndex++, + rPaintArea.GetBoundRect().Left(), + rPaintArea.GetBoundRect().Top(), + rPaintArea.GetBoundRect().GetWidth(), + rPaintArea.GetBoundRect().GetHeight()); +#endif - if (mbPreciousFlagUpdatePending) - UpdatePreciousFlags(); + mrSlideSorter.GetContentWindow()->IncrementLockCount(); + mpLayeredDevice->Repaint(rPaintArea); + mrSlideSorter.GetContentWindow()->DecrementLockCount(); - // Call the base class InitRedraw even when re-drawing is locked to - // let it remember the request for a redraw. - View::CompleteRedraw (pDevice, rPaintArea, pRedirector); +#ifdef VERBOSE + OSL_TRACE("CompleteRedraw done"); +#endif } else { - // In sd::View::CompleteRedraw() this call is recorded and given - // region is painted when the view is unlocked. - View::CompleteRedraw (pDevice, rPaintArea, pRedirector); +#ifdef VERBOSE + OSL_TRACE("%5d CompleteRedraw while locked", nPaintIndex++); +#endif + View::CompleteRedraw(pDevice, rPaintArea, pRedirector); } } -void SlideSorterView::InvalidateOneWin (::Window& rWindow) +void SlideSorterView::Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea) { - // if ( IsInvalidateAllowed() ) - View::InvalidateOneWin (rWindow); -} - - - - -void SlideSorterView::InvalidateOneWin ( - ::Window& rWindow, - const Rectangle& rPaintArea) -{ - // if( IsInvalidateAllowed() ) - View::InvalidateOneWin (rWindow, rPaintArea); -} - - - - -::sd::Window* SlideSorterView::GetWindow (void) const -{ - return static_cast< ::sd::Window*>(GetFirstOutputDevice()); -} - - + if ( ! mpPageObjectPainter) + if ( ! GetPageObjectPainter()) + return; + // Update the page visibilities when they have been invalidated. + if ( ! mbPageObjectVisibilitiesValid) + DeterminePageObjectVisibilities(); -void SlideSorterView::AdaptBoundingBox ( - Rectangle& rModelPageObjectBoundingBox, - CoordinateSystem eCoordinateSystem, - BoundingBoxType eBoundingBoxType) const -{ - CoordinateSystem aCurrentCoordinateSystem = CS_MODEL; - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL) + if (mbPreciousFlagUpdatePending) + UpdatePreciousFlags(); + + // Paint all page objects that are fully or partially inside the + // repaint region. + sal_Int32 nFirst (mpLayouter->GetIndexOfFirstVisiblePageObject(rRepaintArea)); + sal_Int32 nLast (std::min( + mpLayouter->GetIndexOfLastVisiblePageObject(rRepaintArea), + mrModel.GetPageCount())); + for (sal_Int32 nIndex=nFirst; nIndex<=nLast; ++nIndex) { - if (eBoundingBoxType == BBT_INFO) - { - // Make the box larger so that it encloses all relevant - // displayed information. - if (aCurrentCoordinateSystem == CS_MODEL) - { - // The relevant offsets are given in pixel values. Therefore - // transform the box first into screen coordinates. - rModelPageObjectBoundingBox - = pWindow->LogicToPixel (rModelPageObjectBoundingBox); - aCurrentCoordinateSystem = CS_SCREEN; - } - rModelPageObjectBoundingBox.Left() -= maPagePixelBorder.Left(); - rModelPageObjectBoundingBox.Right() += maPagePixelBorder.Right(); - rModelPageObjectBoundingBox.Top() -= maPagePixelBorder.Top(); - rModelPageObjectBoundingBox.Bottom() += maPagePixelBorder.Bottom(); - } + model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex)); + if (!pDescriptor || ! pDescriptor->HasState(PageDescriptor::ST_Visible)) + continue; - // Make sure that the bounding box is given in the correct coordinate - // system. - if (eCoordinateSystem != aCurrentCoordinateSystem) - { - if (eCoordinateSystem == CS_MODEL) - rModelPageObjectBoundingBox - = pWindow->PixelToLogic (rModelPageObjectBoundingBox); - else - rModelPageObjectBoundingBox - = pWindow->LogicToPixel (rModelPageObjectBoundingBox); - } + mpPageObjectPainter->PaintPageObject(rDevice, pDescriptor); } } @@ -704,14 +836,14 @@ void SlideSorterView::AdaptBoundingBox ( ::boost::shared_ptr SlideSorterView::GetPreviewCache (void) { - ::sd::Window* pWindow = GetWindow(); - if (pWindow != NULL && mpPreviewCache.get() == NULL) + ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow && mpPreviewCache.get() == NULL) { - maPreviewSize = pWindow->LogicToPixel(mpLayouter->GetPageObjectSize()); mpPreviewCache.reset( new cache::PageCache( - maPreviewSize, - cache::SharedCacheContext(new ViewCacheContext(mrSlideSorter.GetModel(), *this)))); + mpLayouter->GetPageObjectSize(), + false, + cache::SharedCacheContext(new ViewCacheContext(mrSlideSorter)))); } return mpPreviewCache; @@ -728,14 +860,6 @@ ViewOverlay& SlideSorterView::GetOverlay (void) -::sdr::contact::ObjectContact& SlideSorterView::GetObjectContact (void) const -{ - return GetSdrPageView()->GetPageWindow(0)->GetObjectContact(); -} - - - - SlideSorterView::PageRange SlideSorterView::GetVisiblePageRange (void) { const int nMaxPageIndex (mrModel.GetPageCount() - 1); @@ -761,89 +885,151 @@ void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint -void SlideSorterView::UpdatePageBorders (void) +void SlideSorterView::LockRedraw (const bool bLock) { - maPagePixelBorder = SvBorder(); - ::sd::Window* pWindow = GetWindow(); - if (mrModel.GetPageCount()>0 && pWindow!=NULL) - { - // Calculate the border in model coordinates. - maPageNumberAreaModelSize = PageObjectViewObjectContact::CalculatePageNumberAreaModelSize ( - pWindow, - mrModel.GetPageCount()); - maModelBorder = PageObjectViewObjectContact::CalculatePageModelBorder ( - pWindow, - mrModel.GetPageCount()); + ::sd::View::LockRedraw(bLock ? TRUE : FALSE); +} - // Depending on values in the global properties the border has to be - // extended a little bit. - ::boost::shared_ptr pProperties( - mrSlideSorter.GetController().GetProperties()); - if (pProperties.get()!=NULL && pProperties->IsHighlightCurrentSlide()) - { - Size aBorderSize (pWindow->PixelToLogic (Size(3,3))); - maModelBorder.Left() += aBorderSize.Width(); - maModelBorder.Right() += aBorderSize.Width(); - maModelBorder.Top() += aBorderSize.Height(); - maModelBorder.Bottom() += aBorderSize.Height(); - } - // Set the border at all page descriptors so that the contact - // objects have access to them. - model::PageEnumeration aPageEnumeration ( - model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); - while (aPageEnumeration.HasMoreElements()) + + +void SlideSorterView::SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor) +{ + if (mpPageUnderMouse != rpDescriptor) + { + if (mpPageUnderMouse) { - model::SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); - pDescriptor->SetModelBorder(maModelBorder); - pDescriptor->SetPageNumberAreaModelSize(maPageNumberAreaModelSize); + mpPageUnderMouse->GetVisualState().SetActiveButtonState( + -1, + model::VisualState::BS_Normal); + SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false); } - // Convert the borders to pixel coordinates and store them for later - // use. - Size aTopLeftBorders(pWindow->LogicToPixel( - Size (maModelBorder.Left(), maModelBorder.Top()))); - Size aBottomRightBorders(pWindow->LogicToPixel( - Size (maModelBorder.Right(), maModelBorder.Bottom()))); - maPagePixelBorder = SvBorder ( - aTopLeftBorders.Width(), - aTopLeftBorders.Height(), - aBottomRightBorders.Width(), - aBottomRightBorders.Height()); + mpPageUnderMouse = rpDescriptor; + SetButtonUnderMouse(-1); + + if (mpPageUnderMouse) + SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true); } +} + + + - // Finally tell the layouter about the borders. - mpLayouter->SetBorders (2,5,4,5); - mpLayouter->SetPageBorders ( - maPagePixelBorder.Left(), - maPagePixelBorder.Right(), - maPagePixelBorder.Top(), - maPagePixelBorder.Bottom()); +void SlideSorterView::SetButtonUnderMouse (const sal_Int32 nButtonIndex) +{ + if (mnButtonUnderMouse != nButtonIndex) + { + if (mpPageUnderMouse) + { + mnButtonUnderMouse = nButtonIndex; + mpPageUnderMouse->GetVisualState().SetActiveButtonState( + mnButtonUnderMouse, + model::VisualState::BS_MouseOver); + RequestRepaint(mpPageUnderMouse); + } + } } -Size SlideSorterView::GetPageNumberAreaModelSize (void) const +void SlideSorterView::AddVisualStateAnimation (const model::SharedPageDescriptor& rpDescriptor) { - return maPageNumberAreaModelSize; + // Stop a state animation for the given descriptor that is still running. + const Animator::AnimationId nId (rpDescriptor->GetVisualState().GetStateAnimationId()); + if (nId != Animator::NotAnAnimationId) + { + mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(nId); + } + + rpDescriptor->GetVisualState().SetStateAnimationId( + mrSlideSorter.GetController().GetAnimator()->AddAnimation( + ::boost::bind( + controller::AnimationFunction::ApplyVisualStateChange, + rpDescriptor, + ::boost::ref(*this), + ::boost::bind(AnimationFunction::FastInSlowOut_Sine, _1)), + 350, + ::boost::bind( + &VisualState::SetStateAnimationId, + ::boost::ref(rpDescriptor->GetVisualState()), + controller::Animator::NotAnAnimationId))); } -SvBorder SlideSorterView::GetModelBorder (void) const +bool SlideSorterView::SetState ( + const model::SharedPageDescriptor& rpDescriptor, + const PageDescriptor::State eState, + const bool bStateValue) { - return maModelBorder; + const bool bModified (rpDescriptor->SetState(eState, bStateValue)); + if ( ! bModified) + return false; + + switch(eState) + { + case PageDescriptor::ST_Visible: + RequestRepaint(rpDescriptor); + break; + + case PageDescriptor::ST_Selected: + case PageDescriptor::ST_Focused: + case PageDescriptor::ST_MouseOver: + case PageDescriptor::ST_Current: + case PageDescriptor::ST_Excluded: + AddVisualStateAnimation(rpDescriptor); + break; + } + + // Fade in or out the buttons. + if (eState == PageDescriptor::ST_MouseOver) + { + // Stop a running animation. + const Animator::AnimationId nId ( + rpDescriptor->GetVisualState().GetButtonAlphaAnimationId()); + if (nId != Animator::NotAnAnimationId) + { + mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(nId); + } + + const double nStartAlpha (rpDescriptor->GetVisualState().GetButtonAlpha()); + const double nEndAlpha (bStateValue ? 0.2 : 1.0); + const ::boost::function aBlendFunctor ( + ::boost::bind( + AnimationFunction::Blend, + nStartAlpha, + nEndAlpha, + ::boost::bind(AnimationFunction::FastInSlowOut_Root, _1))); + rpDescriptor->GetVisualState().SetButtonAlphaAnimationId( + mrSlideSorter.GetController().GetAnimator()->AddAnimation( + ::boost::bind( + AnimationFunction::ApplyButtonAlphaChange, + rpDescriptor, + ::boost::ref(*this), + ::boost::bind(aBlendFunctor, _1)), + 400, + ::boost::bind( + &VisualState::SetButtonAlphaAnimationId, + ::boost::ref(rpDescriptor->GetVisualState()), + controller::Animator::NotAnAnimationId) + )); + } + + return bModified; } -void SlideSorterView::AddSdrObject (SdrObject& rObject) +::boost::shared_ptr SlideSorterView::GetPageObjectPainter (void) { - mpPage->InsertObject(&rObject); - rObject.SetModel(&maPageModel); + if ( ! mpPageObjectPainter) + mpPageObjectPainter.reset(new PageObjectPainter(mrSlideSorter)); + return mpPageObjectPainter; } + } } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hrc b/sd/source/ui/slidesorter/view/SlsIcons.hrc new file mode 100644 index 000000000000..c174252aa7ce --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsIcons.hrc @@ -0,0 +1,45 @@ +/************************************************************************* + * + * 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: CondFormat.hrc,v $ + * $Revision: 1.4 $ + * + * 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_ICONS_HRC +#define SD_SLIDESORTER_ICONS_HRC + +#include "glob.hrc" + +#define IMG_ICONS RID_SLIDESORTER_ICONS + +#define IMAGE_INSERTION_INDICATOR_NORMAL 1 +#define IMAGE_INSERTION_INDICATOR_MASK 2 +#define IMAGE_INSERTION_INDICATOR_SELECT 3 +#define IMAGE_PRESENTATION 4 +#define IMAGE_SHOW_SLIDE 5 +#define IMAGE_NEW_SLIDE 6 + +#endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hxx b/sd/source/ui/slidesorter/view/SlsIcons.hxx new file mode 100644 index 000000000000..63c4de22584a --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsIcons.hxx @@ -0,0 +1,51 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_ICONS_HXX +#define SD_SLIDESORTER_ICONS_HXX + +#include "SlsIcons.hrc" +#include "sdresid.hxx" +#include + +namespace sd { namespace slidesorter { namespace view { + +class LocalResource : public Resource +{ +public: + LocalResource (const sal_uInt16 nResourceId) : Resource(SdResId(nResourceId)){} + ~LocalResource (void) { FreeResource(); } +}; + + +} } } // end of namespace ::sd::slidesorter::view + +#endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.src b/sd/source/ui/slidesorter/view/SlsIcons.src new file mode 100644 index 000000000000..c3f68cde7436 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsIcons.src @@ -0,0 +1,65 @@ +/************************************************************************* + * + * 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: CondFormat.src,v $ + * $Revision: 1.6 $ + * + * 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 "SlsIcons.hrc" + +Resource IMG_ICONS +{ + Image IMAGE_INSERTION_INDICATOR_NORMAL + { + ImageBitmap = Bitmap { File = "moving_50.png" ; }; + }; + + Image IMAGE_INSERTION_INDICATOR_MASK + { + ImageBitmap = Bitmap { File = "moving_50_mask.png" ; }; + }; + + Image IMAGE_INSERTION_INDICATOR_SELECT + { + ImageBitmap = Bitmap { File = "moving_50_select.png" ; }; + }; + + Image IMAGE_PRESENTATION + { + ImageBitmap = Bitmap { File = "commandimagelist/lc_presentation.png" ; }; + }; + + Image IMAGE_SHOW_SLIDE + { + ImageBitmap = Bitmap { File = "commandimagelist/lc_showslide.png" ; }; + }; + + Image IMAGE_NEW_SLIDE + { + ImageBitmap = Bitmap { File = "commandimagelist/lc_insertpage.png" ; }; + }; + +}; diff --git a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx new file mode 100644 index 000000000000..3376fc9e0c6c --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx @@ -0,0 +1,465 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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/SlsInsertAnimator.hxx" +#include "controller/SlideSorterController.hxx" +#include "controller/SlsAnimationFunction.hxx" +#include "view/SlideSorterView.hxx" +#include "view/SlsLayouter.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageEnumerationProvider.hxx" + +#include +#include + + +namespace sd { namespace slidesorter { namespace view { + +namespace { + +class PageObjectRun; + +class AnimatorAccess +{ +public: + virtual void RemoveRun (PageObjectRun* pRun) = 0; + virtual model::SlideSorterModel& GetModel (void) const = 0; + virtual view::SlideSorterView& GetView (void) const = 0; + virtual ::boost::shared_ptr GetAnimator (void) = 0; +}; + + +/** Controller of the position offsets of all page objects in one row or one + column. +*/ +class PageObjectRun +{ +public: + PageObjectRun ( + AnimatorAccess& rAnimatorAccess, + const sal_Int32 nRunIndex, + const sal_Int32 nStartIndex, + const sal_Int32 nEndIndex); + ~PageObjectRun (void); + + void operator () (const double nTime); + + void UpdateOffsets( + const sal_Int32 nInsertIndex, + const Point& rLeadingOffset, + const Point& rTrailingOffset); + + /// 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; + /// Index of the first page in the run. + sal_Int32 mnStartIndex; + /// Index of the last page in the run. + sal_Int32 mnEndIndex; + /// Offset of each item in the run at the start of the current animation. + ::std::vector maStartOffset; + /// Target offset of each item in the run at the end of the current animation. + ::std::vector maEndOffset; + /// Time at which the current animation started. + double mnStartTime; + + class Comparator + { + public: bool operator() ( + const ::boost::shared_ptr& rpRunA, + const ::boost::shared_ptr& rpRunB) const + { + return rpRunA->mnRunIndex < rpRunB->mnRunIndex; + } + }; +private: + controller::Animator::AnimationId mnAnimationId; + AnimatorAccess& mrAnimatorAccess; + ::boost::function maAccelerationFunction; + + void RestartAnimation (void); +}; +typedef ::boost::shared_ptr SharedPageObjectRun; + + +Point Blend (const Point& rPointA, const Point& rPointB, const double nT) +{ + return Point( + sal_Int32(rPointA.X() * (1-nT) + rPointB.X() * nT), + sal_Int32(rPointA.Y() * (1-nT) + rPointB.Y() * nT)); +} + +} // end of anonymous namespace + + + +class InsertAnimator::Implementation : public AnimatorAccess +{ +public: + Implementation (SlideSorter& rSlideSorter); + virtual ~Implementation (void); + + void SetInsertPosition ( + const sal_Int32 nPageIndex, + const bool bInsertBefore); + + void Reset (void); + + virtual void RemoveRun (PageObjectRun* pRun); + + virtual model::SlideSorterModel& GetModel (void) const { return mrModel; } + virtual view::SlideSorterView& GetView (void) const { return mrView; } + virtual ::boost::shared_ptr GetAnimator (void) { return mpAnimator; } + +private: + model::SlideSorterModel& mrModel; + view::SlideSorterView& mrView; + ::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; + bool mbCurrentInsertBefore; + + void StopAnimation (void); + SharedPageObjectRun GetRun ( + view::Layouter& rLayouter, + const sal_Int32 nPageIndex, + const bool bInsertBefore, + const bool bCreate = true); + RunContainer::iterator FindRun (const sal_Int32 nRunIndex) const; +}; + + + + + +//===== InsertAnimator ======================================================== + +InsertAnimator::InsertAnimator (SlideSorter& rSlideSorter) + : mpImplementation(new Implementation(rSlideSorter)) +{ +} + + + + +void InsertAnimator::SetInsertPosition ( + const sal_Int32 nPageIndex, + const bool bInsertBefore) +{ + mpImplementation->SetInsertPosition(nPageIndex, bInsertBefore); +} + + + + +void InsertAnimator::Reset (void) +{ + mpImplementation->Reset(); +} + + + + +//===== InsertAnimator::Implementation ======================================== + +InsertAnimator::Implementation::Implementation (SlideSorter& rSlideSorter) + : mrModel(rSlideSorter.GetModel()), + mrView(rSlideSorter.GetView()), + mpAnimator(rSlideSorter.GetController().GetAnimator()), + maRuns(), + mnCurrentInsertPosition(-1), + mbCurrentInsertBefore(false) +{ +} + + + + +InsertAnimator::Implementation::~Implementation (void) +{ + Reset(); +} + + + + +void InsertAnimator::Implementation::SetInsertPosition ( + const sal_Int32 nPageIndex, + const bool bInsertBefore) +{ + if (nPageIndex==mnCurrentInsertPosition && bInsertBefore==mbCurrentInsertBefore) + return; + + SharedPageObjectRun pOldRun ( + GetRun(mrView.GetLayouter(), mnCurrentInsertPosition, mbCurrentInsertBefore)); + SharedPageObjectRun pCurrentRun ( + GetRun(mrView.GetLayouter(), nPageIndex, bInsertBefore)); + mnCurrentInsertPosition = nPageIndex; + mbCurrentInsertBefore = bInsertBefore; + + // When the new insert position is in a different run then move the page + // objects in the old run to their default positions. + if (pOldRun != pCurrentRun) + { + if (pOldRun) + { + pOldRun->UpdateOffsets(-1, Point(0,0), Point(0,0)); + maRuns.insert(pOldRun); + } + } + + if (pCurrentRun) + { + const sal_Int32 nColumnCount (mrView.GetLayouter().GetColumnCount()); + pCurrentRun->UpdateOffsets( + mnCurrentInsertPosition, + nColumnCount > 1 ? Point(-20,0) : Point(0,-20), + nColumnCount > 1 ? Point(+20,0) : Point(0,+20)); + maRuns.insert(pCurrentRun); + } +} + + + + +void InsertAnimator::Implementation::Reset (void) +{ + SetInsertPosition(-1, false); +} + + + + +SharedPageObjectRun InsertAnimator::Implementation::GetRun ( + view::Layouter& rLayouter, + const sal_Int32 nPageIndex, + const bool bInsertBefore, + const bool bCreate) +{ + if (nPageIndex < 0) + return SharedPageObjectRun(); + + RunContainer::iterator iRun (maRuns.end()); + if (rLayouter.GetColumnCount() == 1) + { + // There is only one run that contains all slides. + if (maRuns.empty() && bCreate) + maRuns.insert(SharedPageObjectRun(new PageObjectRun( + *this, + 0, + 0, + mrModel.GetPageCount()-1))); + iRun = maRuns.begin(); + } + else + { + // Look up the row that contains the insert position (take into + // acount the flag that states whether the indicator is to place + // before or after the page object at that position.) + int nIndex (nPageIndex); + if ( ! bInsertBefore && nPageIndex > 0) + --nIndex; + const sal_Int32 nRow (rLayouter.GetRow(nIndex)); + iRun = FindRun(nRow); + if (iRun == maRuns.end() && bCreate) + { + // Create a new run. + 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, + nRow, + nStartIndex, + nEndIndex))).first; + OSL_ASSERT(iRun != maRuns.end()); + } + } + } + + if (iRun != maRuns.end()) + return *iRun; + else + return SharedPageObjectRun(); +} + + + + +InsertAnimator::Implementation::RunContainer::iterator + InsertAnimator::Implementation::FindRun (const sal_Int32 nRunIndex) const +{ + return std::find_if( + maRuns.begin(), + maRuns.end(), + ::boost::bind( + ::std::equal_to(), + ::boost::bind(&PageObjectRun::mnRunIndex, _1), + nRunIndex)); +} + + + + +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) + maRuns.erase(FindRun(pRun->mnRunIndex)); + } + else + { + OSL_ASSERT(pRun!=NULL); + } +} + + + + + +//===== PageObjectRun ========================================================= + +PageObjectRun::PageObjectRun ( + AnimatorAccess& rAnimatorAccess, + const sal_Int32 nRunIndex, + const sal_Int32 nStartIndex, + const sal_Int32 nEndIndex) + : mnRunIndex(nRunIndex), + mnInsertIndex(-1), + mnStartIndex(nStartIndex), + mnEndIndex(nEndIndex), + maStartOffset(), + maEndOffset(), + mnStartTime(-1), + mnAnimationId(controller::Animator::NotAnAnimationId), + mrAnimatorAccess(rAnimatorAccess), + maAccelerationFunction( + controller::AnimationParametricFunction( + controller::AnimationBezierFunction (0.1,0.6))) +{ + maStartOffset.resize(nEndIndex - nStartIndex + 1); + maEndOffset.resize(nEndIndex - nStartIndex + 1); +} + + + + +PageObjectRun::~PageObjectRun (void) +{ +} + + + + +void PageObjectRun::UpdateOffsets( + const sal_Int32 nInsertIndex, + const Point& rLeadingOffset, + const Point& rTrailingOffset) +{ + if (nInsertIndex != mnInsertIndex) + { + mnInsertIndex = nInsertIndex; + + model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel()); + for (sal_Int32 nIndex=mnStartIndex; nIndex<=mnEndIndex; ++nIndex) + { + model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); + if (pDescriptor) + maStartOffset[nIndex-mnStartIndex] = pDescriptor->GetVisualState().GetLocationOffset(); + maEndOffset[nIndex-mnStartIndex] = nIndex < nInsertIndex + ? rLeadingOffset + : rTrailingOffset; + } + RestartAnimation(); + } +} + + + + +void PageObjectRun::RestartAnimation (void) +{ + // Stop the current animation. + if (mnAnimationId != controller::Animator::NotAnAnimationId) + { + mrAnimatorAccess.GetAnimator()->RemoveAnimation(mnAnimationId); + } + + // Restart the animation. + mnAnimationId = mrAnimatorAccess.GetAnimator()->AddAnimation( + ::boost::ref(*this), + 300, + ::boost::bind(&AnimatorAccess::RemoveRun, ::boost::ref(mrAnimatorAccess), this)); +} + + + + +void PageObjectRun::operator () (const double nGlobalTime) +{ + if (mnStartTime < 0) + mnStartTime = nGlobalTime; + + double nLocalTime (nGlobalTime - mnStartTime); + if (nLocalTime > 1.0) + nLocalTime = 1.0; + nLocalTime = maAccelerationFunction(nLocalTime); + + model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel()); + view::SlideSorterView& rView (mrAnimatorAccess.GetView()); + for (sal_Int32 nIndex=mnStartIndex; nIndex<=mnEndIndex; ++nIndex) + { + model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); + const Rectangle aOldBoundingBox (pDescriptor->GetBoundingBox()); + pDescriptor->GetVisualState().SetLocationOffset( + Blend( + maStartOffset[nIndex-mnStartIndex], + maEndOffset[nIndex-mnStartIndex], + nLocalTime)); + rView.RequestRepaint(aOldBoundingBox); + rView.RequestRepaint(pDescriptor); + } +} + + + + +} } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx new file mode 100644 index 000000000000..6b6231fcad69 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx @@ -0,0 +1,478 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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 "SlsLayeredDevice.hxx" + +#include +#include + +#include +#include + + +namespace sd { namespace slidesorter { namespace view { + +namespace { +static const sal_Int32 gnMaximumLayerCount = 8; + +class LayerInvalidator : public ILayerInvalidator +{ +public: + LayerInvalidator ( + const ::boost::shared_ptr& rpLayeredDevice, + const ::boost::shared_ptr< ::Window>& rpTargetWindow, + const int nLayer) + : mpLayeredDevice(rpLayeredDevice), + mpTargetWindow(rpTargetWindow), + mnLayer(nLayer) + { + } + + virtual void Invalidate (const Rectangle& rInvalidationBox) + { + mpLayeredDevice->Invalidate(rInvalidationBox, mnLayer); + mpTargetWindow->Invalidate(rInvalidationBox); + } + +private: + const ::boost::shared_ptr mpLayeredDevice; + const ::boost::shared_ptr< ::Window> mpTargetWindow; + const int mnLayer; +}; + +void DeviceCopy ( + OutputDevice& rTargetDevice, + OutputDevice& rSourceDevice, + const Rectangle& rBox) +{ + rTargetDevice.DrawOutDev( + rBox.TopLeft(), + rBox.GetSize(), + rBox.TopLeft(), + rBox.GetSize(), + rSourceDevice); +} + + +void ForAllRectangles (const Region& rRegion, ::boost::function aFunction) +{ + OSL_ASSERT(aFunction); + + if (rRegion.GetRectCount() <= 1) + { + aFunction(rRegion.GetBoundRect()); + } + else + { + Region aMutableRegionCopy (rRegion); + RegionHandle aHandle(aMutableRegionCopy.BeginEnumRects()); + Rectangle aBox; + while (aMutableRegionCopy.GetNextEnumRect(aHandle, aBox)) + aFunction(aBox); + aMutableRegionCopy.EndEnumRects(aHandle); + } +} + + +} // end of anonymous namespace + + + + +LayeredDevice::LayeredDevice (const ::boost::shared_ptr< ::Window>& rpTargetWindow) + : mpTargetWindow(rpTargetWindow), + maLayers(1), + mpBackBuffer(new VirtualDevice(*mpTargetWindow)), + maSavedMapMode(rpTargetWindow->GetMapMode()) +{ + mpBackBuffer->SetOutputSizePixel(mpTargetWindow->GetSizePixel()); +} + + + + +LayeredDevice::~LayeredDevice (void) +{ +} + + + + +void LayeredDevice::Invalidate ( + const Rectangle& rInvalidationArea, + const sal_Int32 nLayer) +{ + if (nLayer<0 || nLayer>=maLayers.size()) + { + OSL_ASSERT(nLayer>=0 && nLayer=gnMaximumLayerCount) + { + OSL_ASSERT(nLayer>=0 && nLayer= maLayers.size()) + maLayers.resize(nLayer+1); + maLayers[nLayer].AddPainter(rpPainter); + if (nLayer == 0) + maLayers[nLayer].Initialize(mpTargetWindow); + + rpPainter->SetLayerInvalidator( + SharedILayerInvalidator(new LayerInvalidator(shared_from_this(),mpTargetWindow,nLayer))); +} + + + + +void LayeredDevice::RemovePainter ( + const SharedILayerPainter& rpPainter, + const sal_Int32 nLayer) +{ + if ( ! rpPainter) + { + OSL_ASSERT(rpPainter); + return; + } + if (nLayer<0 || nLayer>=maLayers.size()) + { + OSL_ASSERT(nLayer>=0 && nLayerSetLayerInvalidator(SharedILayerInvalidator()); + + maLayers[nLayer].RemovePainter(rpPainter); + + // Remove top most layers that do not contain any painters. + while ( ! maLayers.empty() && ! maLayers.back().HasPainter()) + maLayers.erase(maLayers.end()-1); +} + + + + +bool LayeredDevice::HasPainter (const sal_Int32 nLayer) +{ + return maLayers.size()>nLayer && maLayers[nLayer].HasPainter(); +} + + + + +void LayeredDevice::Repaint (const Region& rRepaintRegion) +{ + HandleMapModeChange(); + + // Validate the contents of all layers (that have their own devices.) + ::std::for_each( + maLayers.begin(), + maLayers.end(), + ::boost::bind(&Layer::Validate, _1, mpTargetWindow->GetMapMode())); + + ForAllRectangles(rRepaintRegion, ::boost::bind(&LayeredDevice::RepaintRectangle, this, _1)); +} + + + + +void LayeredDevice::RepaintRectangle (const Rectangle& rRepaintRectangle) +{ + if (maLayers.size() <= 1) + { + // Just copy the main layer into the target device. + maLayers[0].Repaint(*mpTargetWindow, rRepaintRectangle); + } + else + { + // Paint all layers first into the back buffer (to avoid flickering + // due to synchronous paints) and then copy that into the target + // device. + mpBackBuffer->SetMapMode(mpTargetWindow->GetMapMode()); + ::std::for_each( + maLayers.begin(), + maLayers.end(), + ::boost::bind(&Layer::Repaint, _1, ::boost::ref(*mpBackBuffer), rRepaintRectangle)); + + DeviceCopy(*mpTargetWindow, *mpBackBuffer, rRepaintRectangle); + } +} + + + + +void LayeredDevice::Resize (void) +{ + const Size aSize (mpTargetWindow->GetSizePixel()); + mpBackBuffer->SetOutputSizePixel(aSize); + ::std::for_each(maLayers.begin(), maLayers.end(), ::boost::bind(&Layer::Resize, _1, aSize)); +} + + + + +void LayeredDevice::Dispose (void) +{ + ::std::for_each(maLayers.begin(), maLayers.end(), ::boost::bind(&Layer::Dispose, _1)); + maLayers.clear(); +} + + + + +void LayeredDevice::HandleMapModeChange (void) +{ + const MapMode& rMapMode (mpTargetWindow->GetMapMode()); + if (maSavedMapMode == rMapMode) + return; + + const Rectangle aLogicWindowBox ( + mpTargetWindow->PixelToLogic(Rectangle(Point(0,0), mpTargetWindow->GetSizePixel()))); + if (maSavedMapMode.GetScaleX() != rMapMode.GetScaleX() + || maSavedMapMode.GetScaleY() != rMapMode.GetScaleY() + || maSavedMapMode.GetMapUnit() != rMapMode.GetMapUnit()) + { + // When the scale has changed then we have to paint everything. + ::std::for_each( + maLayers.begin(), + maLayers.end(), + ::boost::bind(&Layer::Invalidate, _1, ::boost::cref(aLogicWindowBox))); + } + else if (maSavedMapMode.GetOrigin() != rMapMode.GetOrigin()) + { + // Window has been scrolled. Adapt contents of backbuffers and + // layer devices. + const Point aDelta (rMapMode.GetOrigin() - maSavedMapMode.GetOrigin()); + mpBackBuffer->CopyArea( + aLogicWindowBox.TopLeft(), + mpTargetWindow->PixelToLogic(Point(0,0), maSavedMapMode), + aLogicWindowBox.GetSize()); + InvalidateAllLayers(aLogicWindowBox); + + /* + const Rectangle aWindowBox (Point(0,0), mpTargetWindow->GetSizePixel()); + if (aDelta.X < 0) + Invalidate( + mpTargetWindow->PixelToLogic( + aWindowBox.TopRight(), + Point(mpTargetWindow->GetSizePixel().Right()X+aDelta.X,0)), + mpTargetWindow->PixelToLogic( + Point(mpTargetWindow->GetSizePixel().X+aDelta.X,0)), + */ + } + else + { + // Can this happen? Lets trigger a warning when it does. + OSL_ASSERT(false); + } + + maSavedMapMode = rMapMode; +} + + + + +//===== LayeredDevice::Layer ================================================== + +LayeredDevice::Layer::Layer (void) + : mpLayerDevice(), + maPainters(), + maInvalidationRegion() +{ +} + + + + +void LayeredDevice::Layer::Initialize (const ::boost::shared_ptr< ::Window>& rpTargetWindow) +{ + if ( ! mpLayerDevice) + { + mpLayerDevice.reset(new VirtualDevice(*rpTargetWindow)); + mpLayerDevice->SetOutputSizePixel(rpTargetWindow->GetSizePixel()); + } +} + + + + +void LayeredDevice::Layer::Invalidate (const Rectangle& rInvalidationBox) +{ + maInvalidationRegion.Union(rInvalidationBox); +} + + + + +void LayeredDevice::Layer::Validate (const MapMode& rMapMode) +{ + if (mpLayerDevice && ! maInvalidationRegion.IsEmpty()) + { + mpLayerDevice->SetMapMode(rMapMode); + + ForAllRectangles( + maInvalidationRegion, + ::boost::bind(&LayeredDevice::Layer::ValidateRectangle, this, _1)); + } + // else nothing to do now. The painting is done in Repaint() directly + // into the back buffer. + + maInvalidationRegion.SetEmpty(); +} + + + + +void LayeredDevice::Layer::ValidateRectangle (const Rectangle& rBox) +{ + const Region aSavedClipRegion (mpLayerDevice->GetClipRegion()); + mpLayerDevice->SetClipRegion(Region(rBox)); + + for (::std::vector::const_iterator + iPainter(maPainters.begin()), + iEnd(maPainters.end()); + iPainter!=iEnd; + ++iPainter) + { + (*iPainter)->Paint(*mpLayerDevice, rBox); + } + + mpLayerDevice->SetClipRegion(aSavedClipRegion); +} + + + + +void LayeredDevice::Layer::Repaint ( + OutputDevice& rTargetDevice, + const Rectangle& rRepaintRectangle) +{ + if (mpLayerDevice) + { + DeviceCopy(rTargetDevice, *mpLayerDevice, rRepaintRectangle); + } + else + { + ::std::for_each( + maPainters.begin(), + maPainters.end(), + ::boost::bind(&ILayerPainter::Paint, + _1, + ::boost::ref(rTargetDevice), + rRepaintRectangle)); + } +} + + + + +void LayeredDevice::Layer::Resize (const Size& rSize) +{ + if (mpLayerDevice) + { + mpLayerDevice->SetOutputSizePixel(rSize); + maInvalidationRegion.Union(Rectangle(Point(0,0), rSize)); + } +} + + + + +void LayeredDevice::Layer::AddPainter (const SharedILayerPainter& rpPainter) +{ + OSL_ASSERT(::std::find(maPainters.begin(), maPainters.end(), rpPainter) == maPainters.end()); + + maPainters.push_back(rpPainter); +} + + + + +void LayeredDevice::Layer::RemovePainter (const SharedILayerPainter& rpPainter) +{ + const ::std::vector::iterator iPainter ( + ::std::find(maPainters.begin(), maPainters.end(), rpPainter)); + if (iPainter != maPainters.end()) + { + maPainters.erase(iPainter); + } + else + { + DBG_ASSERT(false,"LayeredDevice::RemovePainter called for painter that is not registered"); + } +} + + + + +bool LayeredDevice::Layer::HasPainter (void) const +{ + return !maPainters.empty(); +} + + + + +void LayeredDevice::Layer::Dispose (void) +{ + maPainters.clear(); +} + + +} } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx new file mode 100644 index 000000000000..522355ca303e --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_LAYERED_DEVICE_HXX +#define SD_SLIDESORTER_VIEW_LAYERED_DEVICE_HXX + +#include "view/SlsILayerPainter.hxx" + +#include +#include +#include + +#include +#include +#include +#include +#include + +class Window; + +namespace sd { namespace slidesorter { namespace view { + +class LayeredDevice + : public ::boost::enable_shared_from_this + +{ +public: + LayeredDevice (const ::boost::shared_ptr< ::Window>& rpTargetWindow); + ~LayeredDevice (void); + + void Invalidate ( + const Rectangle& rInvalidationBox, + const sal_Int32 nLayer); + void InvalidateAllLayers ( + const Rectangle& rInvalidationBox); + + void RegisterPainter ( + const SharedILayerPainter& rPainter, + const sal_Int32 nLayer); + + void RemovePainter ( + const SharedILayerPainter& rPainter, + const sal_Int32 nLayer); + + bool HasPainter (const sal_Int32 nLayer); + + void Repaint (const Region& rRepaintRegion); + + void Resize (void); + + void Dispose (void); + + class Layer + { + public: + Layer (void); + + void Initialize (const ::boost::shared_ptr< ::Window>& rpTargetWindow); + void Invalidate (const Rectangle& rInvalidationBox); + void Validate (const MapMode& rMapMode); + void Repaint ( + OutputDevice& rTargetDevice, + const Rectangle& rRepaintRectangle); + void Resize (const Size& rSize); + void AddPainter (const SharedILayerPainter& rpPainter); + void RemovePainter (const SharedILayerPainter& rpPainter); + bool HasPainter (void) const; + void Dispose (void); + + private: + ::boost::shared_ptr mpLayerDevice; + ::std::vector maPainters; + Region maInvalidationRegion; + void ValidateRectangle (const Rectangle& rBox); + }; + +private: + const ::boost::shared_ptr< ::Window> mpTargetWindow; + ::std::vector maLayers; + ::boost::scoped_ptr mpBackBuffer; + MapMode maSavedMapMode; + + void RepaintRectangle (const Rectangle& rRepaintRectangle); + void HandleMapModeChange (void); +}; + + +} } } // 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 f3d91fff96dd..c2a54b63e8bf 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -32,37 +32,33 @@ #include "view/SlsLayouter.hxx" -#include -#include +#include "Window.hxx" +#include + namespace sd { namespace slidesorter { namespace view { -Layouter::Layouter (void) - : mnRequestedLeftBorder(10), - mnRequestedRightBorder(10), +Layouter::Layouter (const ::boost::shared_ptr< ::Window>& rpWindow) + : mpWindow(rpWindow), + mnRequestedLeftBorder(35), + mnRequestedRightBorder(35), mnRequestedTopBorder(10), mnRequestedBottomBorder(10), - mnLeftBorder(10), - mnRightBorder(10), + mnLeftBorder(30), + mnRightBorder(30), mnTopBorder(10), mnBottomBorder(10), - mnLeftPageBorder(0), - mnRightPageBorder(0), - mnTopPageBorder(0), - mnBottomPageBorder(0), mnVerticalGap (20), mnHorizontalGap (20), - mnInsertionMarkerThickness (4), - mnTotalVerticalGap(0), - mnTotalHorizontalGap(0), mnMinimalWidth (100), mnPreferredWidth (200), mnMaximalWidth (300), mnMinimalColumnCount (1), mnMaximalColumnCount (5), - mnColumnCount (1), - maPageObjectModelSize (1,1), - maPageObjectPixelSize (1,1) + mnPageCount(0), + mnColumnCount(1), + mnRowCount(0), + maPageObjectSize(1,1) { } @@ -74,6 +70,16 @@ Layouter::~Layouter (void) } + + +::boost::shared_ptr Layouter::GetPageObjectLayouter (void) const +{ + return mpPageObjectLayouter; +} + + + + void Layouter::SetObjectWidth ( sal_Int32 nMinimalWidth, sal_Int32 nMaximalWidth, @@ -97,32 +103,13 @@ void Layouter::SetBorders ( sal_Int32 nBottomBorder) { if (nLeftBorder >= 0) - mnRequestedLeftBorder.mnScreen = nLeftBorder; + mnRequestedLeftBorder = nLeftBorder; if (nRightBorder >= 0) - mnRequestedRightBorder.mnScreen = nRightBorder; + mnRequestedRightBorder = nRightBorder; if (nTopBorder >= 0) - mnRequestedTopBorder.mnScreen = nTopBorder; + mnRequestedTopBorder = nTopBorder; if (nBottomBorder >= 0) - mnRequestedBottomBorder.mnScreen = nBottomBorder; -} - - - - -void Layouter::SetPageBorders ( - sal_Int32 nLeftBorder, - sal_Int32 nRightBorder, - sal_Int32 nTopBorder, - sal_Int32 nBottomBorder) -{ - if (nLeftBorder >= 0) - mnLeftPageBorder.mnScreen = nLeftBorder; - if (nRightBorder >= 0) - mnRightPageBorder.mnScreen = nRightBorder; - if (nTopBorder >= 0) - mnTopPageBorder.mnScreen = nTopBorder; - if (nBottomBorder >= 0) - mnBottomPageBorder.mnScreen = nBottomBorder; + mnRequestedBottomBorder = nBottomBorder; } @@ -133,9 +120,9 @@ void Layouter::SetGaps ( sal_Int32 nVerticalGap) { if (nHorizontalGap >= 0) - mnHorizontalGap.mnScreen = nHorizontalGap; + mnHorizontalGap = nHorizontalGap; if (nVerticalGap >= 0) - mnVerticalGap.mnScreen = nVerticalGap; + mnVerticalGap = nVerticalGap; } @@ -158,45 +145,42 @@ void Layouter::SetColumnCount ( bool Layouter::RearrangeHorizontal ( const Size& rWindowSize, - const Size& rPageObjectSize, - OutputDevice* pDevice, + const Size& rPageSize, const sal_uInt32 nPageCount) { + OSL_ASSERT(mpWindow); + + mnPageCount = nPageCount; + if (rWindowSize.Width() > 0 && rWindowSize.Height() > 0 - && rPageObjectSize.Width() > 0 - && rPageObjectSize.Height() > 0) + && rPageSize.Width() > 0 + && rPageSize.Height() > 0) { - mnTotalHorizontalGap.mnScreen = mnHorizontalGap.mnScreen - + mnRightPageBorder.mnScreen + mnLeftPageBorder.mnScreen; - mnTotalVerticalGap.mnScreen = mnVerticalGap.mnScreen - + mnTopPageBorder.mnScreen + mnBottomPageBorder.mnScreen; - // Calculate the column count. mnColumnCount = nPageCount; + mnRowCount = 1; - // Update the border values. The insertion marker has to have space. - mnLeftBorder.mnScreen = mnRequestedLeftBorder.mnScreen; - mnTopBorder.mnScreen = mnRequestedTopBorder.mnScreen; - mnRightBorder.mnScreen = mnRequestedRightBorder.mnScreen; - mnBottomBorder.mnScreen = mnRequestedBottomBorder.mnScreen; + // Update the border values. + mnLeftBorder = mnRequestedLeftBorder; + mnTopBorder = mnRequestedTopBorder; + mnRightBorder = mnRequestedRightBorder; + mnBottomBorder = mnRequestedBottomBorder; if (mnColumnCount > 1) { - int nMinimumBorderWidth = mnInsertionMarkerThickness.mnScreen - + mnHorizontalGap.mnScreen/2; - if (mnLeftBorder.mnScreen < nMinimumBorderWidth) - mnLeftBorder.mnScreen = nMinimumBorderWidth; - if (mnRightBorder.mnScreen < nMinimumBorderWidth) - mnRightBorder.mnScreen = nMinimumBorderWidth; + int nMinimumBorderWidth = mnHorizontalGap/2; + if (mnLeftBorder < nMinimumBorderWidth) + mnLeftBorder = nMinimumBorderWidth; + if (mnRightBorder < nMinimumBorderWidth) + mnRightBorder = nMinimumBorderWidth; } else { - int nMinimumBorderHeight = mnInsertionMarkerThickness.mnScreen - + mnVerticalGap.mnScreen/2; - if (mnTopBorder.mnScreen < nMinimumBorderHeight) - mnTopBorder.mnScreen = nMinimumBorderHeight; - if (mnBottomBorder.mnScreen < nMinimumBorderHeight) - mnBottomBorder.mnScreen = nMinimumBorderHeight; + int nMinimumBorderHeight = mnVerticalGap/2; + if (mnTopBorder < nMinimumBorderHeight) + mnTopBorder = nMinimumBorderHeight; + if (mnBottomBorder < nMinimumBorderHeight) + mnBottomBorder = nMinimumBorderHeight; } // Calculate the width of each page object. @@ -204,40 +188,26 @@ bool Layouter::RearrangeHorizontal ( sal_uInt32 nRowCount = 1; if (mnColumnCount > 0) nTargetHeight = (rWindowSize.Height() - - mnTopBorder.mnScreen - - mnBottomBorder.mnScreen - - nRowCount * (mnTopPageBorder.mnScreen - + mnBottomPageBorder.mnScreen) - - (nRowCount-1) * mnTotalVerticalGap.mnScreen + - mnTopBorder + - mnBottomBorder + - (nRowCount-1) * mnVerticalGap ) / nRowCount; - sal_uInt32 nMinimalHeight ( - mnMinimalWidth * rPageObjectSize.Height() / rPageObjectSize.Width()); - sal_uInt32 nMaximalHeight ( - mnMaximalWidth * rPageObjectSize.Height() / rPageObjectSize.Width()); + sal_uInt32 nMinimalHeight (mnMinimalWidth * rPageSize.Height() / rPageSize.Width()); + sal_uInt32 nMaximalHeight (mnMaximalWidth * rPageSize.Height() / rPageSize.Width()); if (nTargetHeight < nMinimalHeight) nTargetHeight = nMinimalHeight; if (nTargetHeight > nMaximalHeight) nTargetHeight = nMaximalHeight; - // Initialize the device with some arbitrary zoom factor just in - // case that the current zoom factor is numerically instable when - // used in a multiplication. - MapMode aMapMode (pDevice->GetMapMode()); - aMapMode.SetScaleX (Fraction(1,1)); - aMapMode.SetScaleY (Fraction(1,1)); - pDevice->SetMapMode (aMapMode); - - // Calculate the resulting scale factor and the page object size in - // pixels. - maPageObjectModelSize = rPageObjectSize; - int nPagePixelHeight (pDevice->LogicToPixel(maPageObjectModelSize).Height()); - - // Adapt the layout of the given output device to the new layout of - // page objects. The zoom factor is set so that the page objects in - // one column fill the screen. - Fraction aScaleFactor (nTargetHeight, nPagePixelHeight); - SetZoom (aMapMode.GetScaleX() * aScaleFactor, pDevice); + // Setup the page object layouter and ask it for the page object size. + mpPageObjectLayouter.reset( + new PageObjectLayouter( + Size(0, nTargetHeight), + rPageSize, + mpWindow, + nPageCount)); + maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); return true; } @@ -250,86 +220,71 @@ bool Layouter::RearrangeHorizontal ( bool Layouter::RearrangeVertical ( const Size& rWindowSize, - const Size& rPageObjectSize, - OutputDevice* pDevice) + const Size& rPreviewModelSize, + const sal_uInt32 nPageCount) { + OSL_ASSERT(mpWindow); + + mnPageCount = nPageCount; + if (rWindowSize.Width() > 0 && rWindowSize.Height() > 0 - && rPageObjectSize.Width() > 0 - && rPageObjectSize.Height() > 0) + && rPreviewModelSize.Width() > 0 + && rPreviewModelSize.Height() > 0) { - mnTotalHorizontalGap.mnScreen = mnHorizontalGap.mnScreen - + mnRightPageBorder.mnScreen + mnLeftPageBorder.mnScreen; - mnTotalVerticalGap.mnScreen = mnVerticalGap.mnScreen - + mnTopPageBorder.mnScreen + mnBottomPageBorder.mnScreen; - // Calculate the column count. - mnColumnCount = (rWindowSize.Width() - - mnRequestedLeftBorder.mnScreen - mnRequestedRightBorder.mnScreen) - / (mnPreferredWidth + mnTotalHorizontalGap.mnScreen); + mnColumnCount = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder) + / (mnPreferredWidth + mnHorizontalGap); if (mnColumnCount < mnMinimalColumnCount) mnColumnCount = mnMinimalColumnCount; if (mnColumnCount > mnMaximalColumnCount) mnColumnCount = mnMaximalColumnCount; + mnRowCount = (nPageCount + mnColumnCount-1)/mnColumnCount; - // Update the border values. The insertion marker has to have space. - mnLeftBorder.mnScreen = mnRequestedLeftBorder.mnScreen; - mnTopBorder.mnScreen = mnRequestedTopBorder.mnScreen; - mnRightBorder.mnScreen = mnRequestedRightBorder.mnScreen; - mnBottomBorder.mnScreen = mnRequestedBottomBorder.mnScreen; + // Update the border values. + mnLeftBorder = mnRequestedLeftBorder; + mnTopBorder = mnRequestedTopBorder; + mnRightBorder = mnRequestedRightBorder; + mnBottomBorder = mnRequestedBottomBorder; if (mnColumnCount > 1) { - int nMinimumBorderWidth = mnInsertionMarkerThickness.mnScreen - + mnHorizontalGap.mnScreen/2; - if (mnLeftBorder.mnScreen < nMinimumBorderWidth) - mnLeftBorder.mnScreen = nMinimumBorderWidth; - if (mnRightBorder.mnScreen < nMinimumBorderWidth) - mnRightBorder.mnScreen = nMinimumBorderWidth; + int nMinimumBorderWidth = mnHorizontalGap/2; + if (mnLeftBorder < nMinimumBorderWidth) + mnLeftBorder = nMinimumBorderWidth; + if (mnRightBorder < nMinimumBorderWidth) + mnRightBorder = nMinimumBorderWidth; } else { - int nMinimumBorderHeight = mnInsertionMarkerThickness.mnScreen - + mnVerticalGap.mnScreen/2; - if (mnTopBorder.mnScreen < nMinimumBorderHeight) - mnTopBorder.mnScreen = nMinimumBorderHeight; - if (mnBottomBorder.mnScreen < nMinimumBorderHeight) - mnBottomBorder.mnScreen = nMinimumBorderHeight; + int nMinimumBorderHeight = mnVerticalGap/2; + if (mnTopBorder < nMinimumBorderHeight) + mnTopBorder = nMinimumBorderHeight; + if (mnBottomBorder < nMinimumBorderHeight) + mnBottomBorder = nMinimumBorderHeight; } // Calculate the width of each page object. sal_Int32 nTargetWidth = 0; if (mnColumnCount > 0) nTargetWidth = (rWindowSize.Width() - - mnLeftBorder.mnScreen - - mnRightBorder.mnScreen - - mnColumnCount * (mnRightPageBorder.mnScreen - + mnLeftPageBorder.mnScreen) - - (mnColumnCount-1) * mnTotalHorizontalGap.mnScreen + - mnLeftBorder + - mnRightBorder + - (mnColumnCount-1) * mnHorizontalGap ) - / mnColumnCount; + / mnColumnCount; if (nTargetWidth < mnMinimalWidth) nTargetWidth = mnMinimalWidth; if (nTargetWidth > mnMaximalWidth) nTargetWidth = mnMaximalWidth; - // Initialize the device with some arbitrary zoom factor just in - // case that the current zoom factor is numerically instable when - // used in a multiplication. - MapMode aMapMode (pDevice->GetMapMode()); - aMapMode.SetScaleX (Fraction(1,1)); - aMapMode.SetScaleY (Fraction(1,1)); - pDevice->SetMapMode (aMapMode); - - // Calculate the resulting scale factor and the page object size in - // pixels. - maPageObjectModelSize = rPageObjectSize; - int nPagePixelWidth (pDevice->LogicToPixel (maPageObjectModelSize).Width()); - - // Adapt the layout of the given output device to the new layout of - // page objects. The zoom factor is set so that the page objects in - // one row fill the screen. - Fraction aScaleFactor (nTargetWidth, nPagePixelWidth); - SetZoom (aMapMode.GetScaleX() * aScaleFactor, pDevice); + // Setup the page object layouter and ask it for the page object size. + mpPageObjectLayouter.reset( + new PageObjectLayouter( + Size(nTargetWidth, 0), + rPreviewModelSize, + mpWindow, + nPageCount)); + maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); return true; } @@ -340,62 +295,23 @@ bool Layouter::RearrangeVertical ( -void Layouter::SetZoom (double nZoomFactor, OutputDevice* pDevice) +void Layouter::SetZoom (double nZoomFactor) { - SetZoom(Fraction(nZoomFactor), pDevice); + SetZoom(Fraction(nZoomFactor)); } -void Layouter::SetZoom (Fraction nZoomFactor, OutputDevice* pDevice) +void Layouter::SetZoom (Fraction nZoomFactor) { - MapMode aMapMode (pDevice->GetMapMode()); + OSL_ASSERT(mpWindow); + + MapMode aMapMode (mpWindow->GetMapMode()); aMapMode.SetScaleX (nZoomFactor); aMapMode.SetScaleY (nZoomFactor); - maPageObjectPixelSize = pDevice->LogicToPixel (maPageObjectModelSize); - pDevice->SetMapMode (aMapMode); - - // Transform frequently used values from pixel to model coordinates. - - Size aTotalGap (pDevice->PixelToLogic (Size ( - mnTotalHorizontalGap.mnScreen, - mnTotalVerticalGap.mnScreen))); - mnTotalHorizontalGap.mnModel = aTotalGap.Width(); - mnTotalVerticalGap.mnModel = aTotalGap.Height(); - - Size aGap (pDevice->PixelToLogic (Size ( - mnHorizontalGap.mnScreen, - mnVerticalGap.mnScreen))); - mnHorizontalGap.mnModel = aGap.Width(); - mnVerticalGap.mnModel = aGap.Height(); - - Size aTopLeftBorder (pDevice->PixelToLogic (Size ( - mnLeftBorder.mnScreen, - mnTopBorder.mnScreen))); - mnLeftBorder.mnModel = aTopLeftBorder.Width(); - mnTopBorder.mnModel = aTopLeftBorder.Height(); - - Size aBottomRightBorder (pDevice->PixelToLogic (Size ( - mnLeftBorder.mnScreen, - mnTopBorder.mnScreen))); - mnRightBorder.mnModel = aBottomRightBorder.Width(); - mnBottomBorder.mnModel = aBottomRightBorder.Height(); - - Size aTopLeftPageBorder (pDevice->PixelToLogic (Size ( - mnLeftPageBorder.mnScreen, - mnTopPageBorder.mnScreen))); - mnLeftPageBorder.mnModel = aTopLeftPageBorder.Width(); - mnTopPageBorder.mnModel = aTopLeftPageBorder.Height(); - - Size aBottomRightPageBorder (pDevice->PixelToLogic (Size ( - mnRightPageBorder.mnScreen, - mnBottomPageBorder.mnScreen))); - mnRightPageBorder.mnModel = aBottomRightPageBorder.Width(); - mnBottomPageBorder.mnModel = aBottomRightPageBorder.Height(); - - mnInsertionMarkerThickness.mnModel = pDevice->PixelToLogic ( - Size(mnInsertionMarkerThickness.mnScreen,0)).Width(); + // maPageObjectPixelSize = mpWindow->LogicToPixel (maPageObjectModelSize); + mpWindow->SetMapMode (aMapMode); } @@ -409,6 +325,40 @@ sal_Int32 Layouter::GetColumnCount (void) const +sal_Int32 Layouter::GetRowCount (void) const +{ + return mnRowCount; +} + + + + +sal_Int32 Layouter::GetRow (const sal_Int32 nIndex) const +{ + return nIndex / mnColumnCount; +} + + + + +sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const +{ + return nIndex % mnColumnCount; +} + + + + +sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const +{ + const sal_Int32 nIndex (nRow * mnColumnCount + nColumn); + OSL_ASSERT(nIndex>=0); + return ::std::min(nIndex, mnPageCount-1); +} + + + + bool Layouter::IsColumnCountFixed (void) const { return mnMinimalColumnCount == mnMaximalColumnCount; @@ -419,53 +369,76 @@ bool Layouter::IsColumnCountFixed (void) const Size Layouter::GetPageObjectSize (void) const { - return maPageObjectModelSize; + return maPageObjectSize; } -Rectangle Layouter::GetPageObjectBox (sal_Int32 nIndex) const +Rectangle Layouter::GetPageObjectBox ( + const sal_Int32 nIndex, + const bool bIncludeBorderAndGap) const { int nColumn = nIndex % mnColumnCount; int nRow = nIndex / mnColumnCount; - return Rectangle ( - Point (mnLeftBorder.mnModel - + nColumn * maPageObjectModelSize.Width() - + mnLeftPageBorder.mnModel - + (nColumn>0 ? nColumn : 0) * mnTotalHorizontalGap.mnModel, - mnTopBorder.mnModel - + nRow * maPageObjectModelSize.Height() - + mnTopPageBorder.mnModel - + (nRow>0 ? nRow : 0) * mnTotalVerticalGap.mnModel), - maPageObjectModelSize); + Rectangle aBoundingBox( + Point (mnLeftBorder + + nColumn * maPageObjectSize.Width() + + (nColumn>0 ? nColumn : 0) * mnHorizontalGap, + mnTopBorder + + nRow * maPageObjectSize.Height() + + (nRow>0 ? nRow : 0) * mnVerticalGap), + maPageObjectSize); + if (bIncludeBorderAndGap) + { + const sal_Int32 nRow (GetRow(nIndex)); + const sal_Int32 nColumn (GetColumn(nIndex)); + if (nColumn == 0) + aBoundingBox.Left() = 0; + else + aBoundingBox.Left() -= mnHorizontalGap/2; + if (nColumn == mnColumnCount-1) + aBoundingBox.Right() += mnRightBorder; + else + aBoundingBox.Right() += mnHorizontalGap/2; + if (nRow == 0) + aBoundingBox.Top() = 0; + else + aBoundingBox.Top() -= mnVerticalGap/2; + if (nRow == mnRowCount-1) + aBoundingBox.Bottom() += mnBottomBorder; + else + aBoundingBox.Bottom() += mnVerticalGap/2; + } + return aBoundingBox; } -Rectangle Layouter::GetPageBox (sal_Int32 nObjectCount) const +Rectangle Layouter::GetPageBox (const sal_Int32 nObjectCount) const { + sal_Int32 nCount (nObjectCount); + if (nCount < 0) + nCount = mnPageCount; + sal_Int32 nHorizontalSize = 0; sal_Int32 nVerticalSize = 0; if (mnColumnCount > 0) { - sal_Int32 nRowCount = (nObjectCount+mnColumnCount-1) / mnColumnCount; + sal_Int32 nRowCount = (nCount+mnColumnCount-1) / mnColumnCount; nHorizontalSize = - mnLeftBorder.mnModel - + mnRightBorder.mnModel - + mnColumnCount * maPageObjectModelSize.Width() - + mnLeftPageBorder.mnModel + mnRightPageBorder.mnModel; + mnLeftBorder + + mnRightBorder + + mnColumnCount * maPageObjectSize.Width(); if (mnColumnCount > 1) - nHorizontalSize - += (mnColumnCount-1) * mnTotalHorizontalGap.mnModel; + nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap; nVerticalSize = - mnTopBorder.mnModel - + mnBottomBorder.mnModel - + nRowCount * maPageObjectModelSize.Height() - + mnTopPageBorder.mnModel + mnBottomPageBorder.mnModel; + mnTopBorder + + mnBottomBorder + + nRowCount * maPageObjectSize.Height(); if (nRowCount > 1) - nVerticalSize += (nRowCount-1) * mnTotalVerticalGap.mnModel; + nVerticalSize += (nRowCount-1) * mnVerticalGap; } return Rectangle ( @@ -477,55 +450,42 @@ Rectangle Layouter::GetPageBox (sal_Int32 nObjectCount) const -Rectangle Layouter::GetInsertionMarkerBox ( +Point Layouter::GetInsertionMarkerLocation ( sal_Int32 nIndex, bool bVertical, bool bLeftOrTop) const { Rectangle aBox (GetPageObjectBox (nIndex)); + Point aLocation = aBox.Center(); if (bVertical) { - sal_Int32 nHorizontalInsertionMarkerOffset - = (mnHorizontalGap.mnModel-mnInsertionMarkerThickness.mnModel) / 2; if (bLeftOrTop) { // Left. - aBox.Left() -= mnLeftPageBorder.mnModel - + mnHorizontalGap.mnModel - - nHorizontalInsertionMarkerOffset; + aLocation.setX(aBox.Left() - (mnHorizontalGap+1)/2 - 1); } else { // Right. - aBox.Left() = aBox.Right() - + mnRightPageBorder.mnModel - + nHorizontalInsertionMarkerOffset; + aLocation.setX(aBox.Right() + mnHorizontalGap/2); } - aBox.Right() = aBox.Left() + mnInsertionMarkerThickness.mnModel; } else { - sal_Int32 nVerticalInsertionMarkerOffset - = (mnVerticalGap.mnModel - mnInsertionMarkerThickness.mnModel) / 2; if (bLeftOrTop) { // Above. - aBox.Top() -= mnTopPageBorder.mnModel - + mnVerticalGap.mnModel - - nVerticalInsertionMarkerOffset; + aLocation.setY(aBox.Top() - mnVerticalGap/2); } else { // Below. - aBox.Top() = aBox.Bottom() - + mnBottomPageBorder.mnModel - + nVerticalInsertionMarkerOffset; + aLocation.setY(aBox.Bottom() + mnVerticalGap/2); } - aBox.Bottom() = aBox.Top() + mnInsertionMarkerThickness.mnModel; } - return aBox; + return aLocation; } @@ -603,59 +563,6 @@ sal_Int32 Layouter::GetInsertionIndex ( -Layouter::DoublePoint - Layouter::ConvertModelToLayouterCoordinates ( - const Point& rModelPoint) const -{ - sal_Int32 nColumn = GetColumnAtPosition (rModelPoint.X(), true, GM_BOTH); - sal_Int32 nColumnWidth - = maPageObjectModelSize.Width() + mnTotalHorizontalGap.mnModel; - sal_Int32 nDistanceIntoColumn = - rModelPoint.X() - mnLeftBorder.mnModel - mnLeftPageBorder.mnModel - - nColumn * nColumnWidth; - - sal_Int32 nRow = GetRowAtPosition (rModelPoint.Y(), true, GM_BOTH); - sal_Int32 nRowHeight - = maPageObjectModelSize.Height() + mnTotalVerticalGap.mnModel; - sal_Int32 nDistanceIntoRow = - rModelPoint.Y() - mnTopBorder.mnModel - mnTopPageBorder.mnModel - - nRow * nRowHeight; - - return DoublePoint ( - nColumn + double(nDistanceIntoColumn) / double(nColumnWidth), - nRow + double(nDistanceIntoRow) / double(nRowHeight)); -} - - - - -Point Layouter::ConvertLayouterToModelCoordinates ( - const DoublePoint & rLayouterPoint) const -{ - sal_Int32 nColumn = (sal_Int32) ::rtl::math::round(rLayouterPoint.first, - 0,rtl_math_RoundingMode_Floor); - sal_Int32 nColumnWidth - = maPageObjectModelSize.Width() + mnTotalHorizontalGap.mnModel; - sal_Int32 nDistanceIntoColumn - = (sal_Int32)((rLayouterPoint.first - nColumn) * nColumnWidth); - - sal_Int32 nRow = (sal_Int32) ::rtl::math::round(rLayouterPoint.second, - 0,rtl_math_RoundingMode_Floor); - sal_Int32 nRowHeight - = maPageObjectModelSize.Height() + mnTotalVerticalGap.mnModel; - sal_Int32 nDistanceIntoRow - = (sal_Int32)((rLayouterPoint.second - nRow) * nRowHeight); - - return Point ( - mnLeftBorder.mnModel + mnLeftPageBorder.mnModel - + nColumn * nColumnWidth + nDistanceIntoColumn, - mnTopBorder.mnModel + mnTopPageBorder.mnModel - + nRow * nRowHeight + nDistanceIntoRow); -} - - - - sal_Int32 Layouter::GetRowAtPosition ( sal_Int32 nYPosition, bool bIncludeBordersAndGaps, @@ -663,19 +570,16 @@ sal_Int32 Layouter::GetRowAtPosition ( { sal_Int32 nRow = -1; - const sal_Int32 nY = nYPosition - - mnTopBorder.mnModel - mnTopPageBorder.mnModel; + const sal_Int32 nY = nYPosition - mnTopBorder; if (nY >= 0) { // Vertical distance from one row to the next. - const sal_Int32 nRowOffset ( - maPageObjectModelSize.Height() + mnTotalVerticalGap.mnModel); + const sal_Int32 nRowOffset (maPageObjectSize.Height() + mnVerticalGap); // Calculate row consisting of page objects and gap below. nRow = nY / nRowOffset; - const sal_Int32 nDistanceIntoGap ( - (nY - nRow*nRowOffset) - maPageObjectModelSize.Height()); + const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height()); // When inside the gap below then nYPosition is not over a page // object. if (nDistanceIntoGap > 0) @@ -683,8 +587,7 @@ sal_Int32 Layouter::GetRowAtPosition ( nDistanceIntoGap, eGapMembership, nRow, - mnBottomPageBorder.mnModel, - mnVerticalGap.mnModel); + mnVerticalGap); } else if (bIncludeBordersAndGaps) { @@ -706,13 +609,11 @@ sal_Int32 Layouter::GetColumnAtPosition ( { sal_Int32 nColumn = -1; - sal_Int32 nX = nXPosition - - mnLeftBorder.mnModel - mnLeftPageBorder.mnModel; + sal_Int32 nX = nXPosition - mnLeftBorder; if (nX >= 0) { // Horizontal distance from one column to the next. - const sal_Int32 nColumnOffset ( - maPageObjectModelSize.Width() + mnTotalHorizontalGap.mnModel); + const sal_Int32 nColumnOffset (maPageObjectSize.Width() + mnHorizontalGap); // Calculate row consisting of page objects and gap below. nColumn = nX / nColumnOffset; @@ -721,8 +622,7 @@ sal_Int32 Layouter::GetColumnAtPosition ( else if (nColumn >= mnColumnCount) nColumn = mnColumnCount-1; - const sal_Int32 nDistanceIntoGap ( - (nX - nColumn*nColumnOffset) - maPageObjectModelSize.Width()); + const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width()); // When inside the gap at the right then nXPosition is not over a // page object. if (nDistanceIntoGap > 0) @@ -730,8 +630,7 @@ sal_Int32 Layouter::GetColumnAtPosition ( nDistanceIntoGap, eGapMembership, nColumn, - mnRightPageBorder.mnModel, - mnHorizontalGap.mnModel); + mnHorizontalGap); } else if (bIncludeBordersAndGaps) { @@ -750,7 +649,6 @@ sal_Int32 Layouter::ResolvePositionInGap ( sal_Int32 nDistanceIntoGap, GapMembership eGapMembership, sal_Int32 nIndex, - sal_Int32 nLeftOrTopPageBorder, sal_Int32 nGap) const { switch (eGapMembership) @@ -763,7 +661,7 @@ sal_Int32 Layouter::ResolvePositionInGap ( case GM_BOTH: { // The lower half of the gap belongs to the next row or column. - sal_Int32 nFirstHalfGapWidth = nLeftOrTopPageBorder + nGap / 2; + sal_Int32 nFirstHalfGapWidth = nGap / 2; if (nDistanceIntoGap > nFirstHalfGapWidth) nIndex ++; break; @@ -779,9 +677,9 @@ sal_Int32 Layouter::ResolvePositionInGap ( break; case GM_PAGE_BORDER: - if (nDistanceIntoGap > nLeftOrTopPageBorder) + if (nDistanceIntoGap > 0) { - if (nDistanceIntoGap > nLeftOrTopPageBorder + nGap) + if (nDistanceIntoGap > nGap) { // Inside the border of the next row or column. nIndex ++; @@ -804,13 +702,4 @@ sal_Int32 Layouter::ResolvePositionInGap ( -const Layouter::BackgroundRectangleList& - Layouter::GetBackgroundRectangleList (void) const -{ - return maBackgroundRectangleList; -} - - - - } } } // end of namespace ::sd::slidesorter::namespace diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx new file mode 100644 index 000000000000..a517584cea40 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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 "view/SlsPageObjectLayouter.hxx" + +#include "model/SlsPageDescriptor.hxx" +#include "view/SlsFontProvider.hxx" +#include "tools/IconCache.hxx" +#include "Window.hxx" +#include "res_bmp.hrc" + +namespace sd { namespace slidesorter { namespace view { + +const sal_Int32 PageObjectLayouter::mnSelectionIndicatorOffset = 0; +const sal_Int32 PageObjectLayouter::mnSelectionIndicatorThickness = 3; +const sal_Int32 PageObjectLayouter::mnFocusIndicatorOffset = 3; +const sal_Int32 PageObjectLayouter::mnPageNumberOffset = 9; +const sal_Int32 PageObjectLayouter::mnOuterBorderWidth = 5; +const Size PageObjectLayouter::maButtonSize (32,32); +const sal_Int32 PageObjectLayouter::mnButtonGap (5); + + +PageObjectLayouter::PageObjectLayouter ( + const Size& rPageObjectWindowSize, + const Size& rPageSize, + const ::boost::shared_ptr< ::Window>& rpWindow, + const int nPageCount) + : mpWindow(rpWindow), + maPageObjectSize(rPageObjectWindowSize.Width(), rPageObjectWindowSize.Height()), + mnModelToWindowScale(1), + maPageObjectBoundingBox(), + maPageNumberAreaBoundingBox(), + maPreviewBoundingBox(), + maFocusIndicatorBoundingBox(), + maSelectionIndicatorBoundingBox(), + maTransitionEffectBoundingBox(), + maButtonAreaBoundingBox(), + maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)) +{ + const Size aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount)); + + const int nMaximumBorderWidth (mnSelectionIndicatorOffset + mnOuterBorderWidth); + + maPageNumberAreaBoundingBox = Rectangle( + mnPageNumberOffset, + nMaximumBorderWidth, + mnPageNumberOffset + aPageNumberAreaSize.Width(), + nMaximumBorderWidth + aPageNumberAreaSize.Height()); + + maPreviewBoundingBox = CalculatePreviewBoundingBox( + maPageObjectSize, + Size(rPageSize.Width(), rPageSize.Height()), + aPageNumberAreaSize); + maPageObjectBoundingBox = Rectangle(Point(0,0), maPageObjectSize); + + maFocusIndicatorBoundingBox = maPreviewBoundingBox; + maFocusIndicatorBoundingBox.Left() -= mnFocusIndicatorOffset; + maFocusIndicatorBoundingBox.Top() -= mnFocusIndicatorOffset; + maFocusIndicatorBoundingBox.Right() += mnFocusIndicatorOffset; + maFocusIndicatorBoundingBox.Bottom() += mnFocusIndicatorOffset; + + maSelectionIndicatorBoundingBox = maPreviewBoundingBox; + maSelectionIndicatorBoundingBox.Left() -= mnSelectionIndicatorOffset; + maSelectionIndicatorBoundingBox.Top() -= mnSelectionIndicatorOffset; + maSelectionIndicatorBoundingBox.Right() += mnSelectionIndicatorOffset; + maSelectionIndicatorBoundingBox.Bottom() += mnSelectionIndicatorOffset; + + const Size aIconSize (maTransitionEffectIcon.GetSizePixel()); + const int nLeft (maPreviewBoundingBox.Left() + - mnPageNumberOffset - aIconSize.Width() - nMaximumBorderWidth); + const int nTop (maPreviewBoundingBox.Bottom() - aIconSize.Height()); + maTransitionEffectBoundingBox = Rectangle( + nLeft, + nTop, + nLeft + aIconSize.Width(), + nTop + aIconSize.Height()); + + maButtonAreaBoundingBox = Rectangle( + 0, + maPageObjectBoundingBox.Bottom() - maButtonSize.Height() - mnButtonGap, + maPageObjectBoundingBox.Right() - mnButtonGap, + maPageObjectBoundingBox.Bottom() - mnButtonGap); +} + + + + +Rectangle PageObjectLayouter::CalculatePreviewBoundingBox ( + Size& rPageObjectSize, + const Size& rPageSize, + const Size& rPageNumberAreaSize) +{ + const int nMaximumBorderWidth (mnSelectionIndicatorOffset + mnOuterBorderWidth); + const int nLeftAreaWidth ( + 2*mnPageNumberOffset + + ::std::max( + rPageNumberAreaSize.Width(), + maTransitionEffectIcon.GetSizePixel().Width())); + int nPreviewWidth; + int nPreviewHeight; + const double nPageAspectRatio (double(rPageSize.Width()) / double(rPageSize.Height())); + if (rPageObjectSize.Height() == 0) + { + // Calculate height so that the preview fills the available + // horizontal space completely while observing the aspect ratio of + // the preview. + nPreviewWidth = rPageObjectSize.Width() - nLeftAreaWidth - 2*nMaximumBorderWidth - 1; + nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio); + rPageObjectSize.setHeight(nPreviewHeight + 2*nMaximumBorderWidth + 1); + } + else if (rPageObjectSize.Width() == 0) + { + // Calculate the width of the page object so that the preview fills + // the available vertical space completely while observing the + // aspect ratio of the preview. + nPreviewHeight = rPageObjectSize.Height() - 2*nMaximumBorderWidth - 1; + nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio); + rPageObjectSize.setWidth(nPreviewWidth + nLeftAreaWidth + 2*nMaximumBorderWidth + 1); + + } + else + { + // The size of the page object is given. Calculate the size of the + // preview. + nPreviewWidth = rPageObjectSize.Width() - nLeftAreaWidth - 2*nMaximumBorderWidth - 1; + nPreviewHeight = rPageObjectSize.Height() - 2*nMaximumBorderWidth - 1; + if (double(nPreviewWidth)/double(nPreviewHeight) > nPageAspectRatio) + nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio); + else + nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio); + } + // When the preview does not fill the available space completely then + // place it flush right and vertically centered. + const int nLeft (rPageObjectSize.Width() - nMaximumBorderWidth - nPreviewWidth - 1); + const int nTop (nMaximumBorderWidth + + (rPageObjectSize.Height() - 2*nMaximumBorderWidth - nPreviewHeight)/2); + return Rectangle( + nLeft, + nTop, + nLeft + nPreviewWidth, + nTop + nPreviewHeight); +} + + + + +Rectangle PageObjectLayouter::GetBoundingBox ( + const model::SharedPageDescriptor& rpPageDescriptor, + const Part ePart, + const CoordinateSystem eCoordinateSystem, + const sal_Int32 nIndex) +{ + if ( ! rpPageDescriptor) + { + OSL_ASSERT(rpPageDescriptor); + return Rectangle(); + } + + Rectangle aBoundingBox; + switch (ePart) + { + case PageObject: + case MouseOverIndicator: + aBoundingBox = maPageObjectBoundingBox; + break; + + case Preview: + aBoundingBox = maPreviewBoundingBox; + break; + + case FocusIndicator: + aBoundingBox = maFocusIndicatorBoundingBox; + break; + + case SelectionIndicator: + aBoundingBox = maSelectionIndicatorBoundingBox; + break; + + case PageNumber: + aBoundingBox = maPageNumberAreaBoundingBox; + break; + + case Name: + aBoundingBox = maPageNumberAreaBoundingBox; + break; + + case TransitionEffectIndicator: + aBoundingBox = maTransitionEffectBoundingBox; + break; + + case ButtonArea: + aBoundingBox = maButtonAreaBoundingBox; + break; + + case Button: + aBoundingBox = Rectangle( + maPageObjectBoundingBox.BottomRight() + - Point( + (nIndex+1)*(maButtonSize.Width() + mnButtonGap), + maButtonSize.Height() + mnButtonGap), + maButtonSize); + break; + } + + Point aLocation (rpPageDescriptor->GetLocation()); + if (eCoordinateSystem == ScreenCoordinateSystem) + aLocation += mpWindow->GetMapMode().GetOrigin(); + + return Rectangle( + aBoundingBox.TopLeft() + aLocation, + aBoundingBox.BottomRight() + aLocation); + + return aBoundingBox; +} + + + + +Size PageObjectLayouter::GetPageObjectSize (void) const +{ + return maPageObjectSize; +} + + + + +Size PageObjectLayouter::GetPreviewSize (void) const +{ + return maPreviewBoundingBox.GetSize(); +} + + + + +Size PageObjectLayouter::GetPageNumberAreaSize (const int nPageCount) +{ + OSL_ASSERT(mpWindow); + + // Set the correct font. + Font aOriginalFont (mpWindow->GetFont()); + mpWindow->SetFont(*FontProvider::Instance().GetFont(*mpWindow)); + + String sPageNumberTemplate; + if (nPageCount < 10) + sPageNumberTemplate = String::CreateFromAscii("9"); + else if (nPageCount < 100) + sPageNumberTemplate = String::CreateFromAscii("99"); + else if (nPageCount < 200) + // Just for the case that 1 is narrower than 9. + sPageNumberTemplate = String::CreateFromAscii("199"); + else if (nPageCount < 1000) + sPageNumberTemplate = String::CreateFromAscii("999"); + else + sPageNumberTemplate = String::CreateFromAscii("9999"); + // More then 9999 pages are not handled. + + const Size aSize ( + mpWindow->GetTextWidth(sPageNumberTemplate), + mpWindow->GetTextHeight()); + + mpWindow->SetFont(aOriginalFont); + + return aSize; +} + + + + +Image PageObjectLayouter::GetTransitionEffectIcon (void) const +{ + return maTransitionEffectIcon; +} + + + + +sal_Int32 PageObjectLayouter::GetButtonIndexAt ( + const model::SharedPageDescriptor& rpPageDescriptor, + const Point& rWindowLocation) +{ + if ( ! GetBoundingBox(rpPageDescriptor, ButtonArea, WindowCoordinateSystem) + .IsInside(rWindowLocation)) + { + return -1; + } + for (sal_Int32 nIndex=0; nIndex<3; ++nIndex) + { + if (GetBoundingBox(rpPageDescriptor, Button, WindowCoordinateSystem, nIndex) + .IsInside(rWindowLocation)) + { + return nIndex; + } + } + return -1; +} + + + +} } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx new file mode 100644 index 000000000000..eae033b817e8 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -0,0 +1,457 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: baseprimitive2d.hxx,v $ + * + * $Revision: 1.8 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "view/SlsPageObjectPainter.hxx" + +#include "model/SlsPageDescriptor.hxx" +#include "view/SlideSorterView.hxx" +#include "view/SlsPageObjectLayouter.hxx" +#include "view/SlsLayouter.hxx" +#include "SlsIcons.hxx" +#include "cache/SlsPageCache.hxx" +#include "controller/SlsProperties.hxx" +#include "Window.hxx" +#include "sdpage.hxx" +#include "sdresid.hxx" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::drawinglayer::primitive2d; +using namespace ::basegfx; + +namespace sd { namespace slidesorter { namespace view { + +namespace { + +// Reds +#define Amber 0xff7e00 + +// Greens +#define AndroidGreen 0xa4c639 +#define AppleGreen 0x8db600 +#define Asparagus 0x87a96b + +// Blues +#define Azure 0x000fff +#define DarkCerulean 0x08457e +#define StellaBlue 0x009ee1 +#define AirForceBlue 0x5d8aa8 + +// Off white +#define OldLace 0xfdf5e6 + +// Off grays +#define Arsenic 0x3b444b + +#define MouseOverColor (0x59000000 | StellaBlue) + +#define CornerRadius 4.0 + +UINT8 Blend ( + const UINT8 nValue1, + const UINT8 nValue2, + const double nWeight) +{ + const double nValue (nValue1*(1-nWeight) + nValue2 * nWeight); + if (nValue < 0) + return 0; + else if (nValue > 255) + return 255; + else + return (UINT8)nValue; +} + +sal_uInt8 ClampColorChannel (const double nValue) +{ + if (nValue <= 0) + return 0; + else if (nValue >= 255) + return 255; + else + return sal_uInt8(nValue); +} + +sal_uInt8 CalculateColorChannel( + const double nColor1, + const double nColor2, + const double nAlpha1, + const double nAlpha2, + const double nAlpha0) +{ + if (nAlpha0 == 0) + return 0; + + const double nColor0 ((nAlpha1*nColor1 + nAlpha1*nAlpha2*nColor1 + nAlpha2*nColor2) / nAlpha0); + return ClampColorChannel(255 * nColor0); +} + + + +void AdaptTransparency (AlphaMask& rMask, const double nAlpha) +{ + BitmapWriteAccess* pBitmap = rMask.AcquireWriteAccess(); + + if (pBitmap != NULL) + { + const sal_Int32 nWidth (pBitmap->Width()); + const sal_Int32 nHeight (pBitmap->Height()); + + const BitmapColor aWhite (255,255,255); + for (sal_Int32 nY = 0; nYGetPixel(nY, nX).GetBlueOrIndex()); + const BYTE nNewValue (nValue * (1-nAlpha)); + pBitmap->SetPixel( + nY, + nX, + 255-nNewValue); + } + } +} + + +} // end of anonymous namespace + + + +PageObjectPainter::PageObjectPainter ( + const SlideSorter& rSlideSorter) + : mrLayouter(rSlideSorter.GetView().GetLayouter()), + mpPageObjectLayouter(), + mpCache(rSlideSorter.GetView().GetPreviewCache()), + mpProperties(rSlideSorter.GetProperties()), + mpFont(), + maStartPresentationIcon(), + maShowSlideIcon(), + maNewSlideIcon() +{ + LocalResource aResource (IMG_ICONS); + maStartPresentationIcon = Image(SdResId(IMAGE_PRESENTATION)).GetBitmapEx(); + maShowSlideIcon = Image(SdResId(IMAGE_SHOW_SLIDE)).GetBitmapEx(); + maNewSlideIcon = Image(SdResId(IMAGE_NEW_SLIDE)).GetBitmapEx(); +} + + + + +void PageObjectPainter::PaintPageObject ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) +{ + // The page object layouter is quite volatile. It may have been replaced + // since the last call. Update it now. + mpPageObjectLayouter = mrLayouter.GetPageObjectLayouter(); + if ( ! mpPageObjectLayouter) + { + OSL_ASSERT(mpPageObjectLayouter); + return; + } + + if ( ! mpFont) + { + mpFont.reset(new Font(rDevice.GetFont())); + mpFont->SetWeight(WEIGHT_BOLD); + } + if (mpFont) + rDevice.SetFont(*mpFont); + + PaintBackground(rDevice, rpDescriptor); + PaintPreview(rDevice, rpDescriptor); + PaintPageNumber(rDevice, rpDescriptor); + PaintTransitionEffect(rDevice, rpDescriptor); + PaintButtons(rDevice, rpDescriptor); + // PaintBorder(rDevice, rpDescriptor); +} + + + + +void PageObjectPainter::PaintBackground ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const +{ + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::PageObject, + PageObjectLayouter::WindowCoordinateSystem)); + + rDevice.SetLineColor(); + const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); + rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); + + const ColorData nColor (GetColorForVisualState(rpDescriptor)); + rDevice.SetFillColor(Color(nColor & 0x00ffffff)); + const double nTransparency (COLORDATA_TRANSPARENCY(nColor)/255.0); + rDevice.DrawTransparent( + ::basegfx::B2DPolyPolygon( + ::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), + CornerRadius/aBox.GetWidth(), + CornerRadius/aBox.GetHeight())), + nTransparency); + + if (rpDescriptor->HasState(model::PageDescriptor::ST_MouseOver)) + { + rDevice.SetFillColor(Color(MouseOverColor & 0x00ffffff)); + double nTransparency (COLORDATA_TRANSPARENCY(MouseOverColor)/255.0); + nTransparency *= 1-rpDescriptor->GetVisualState().GetVisualStateBlend(); + rDevice.DrawTransparent( + ::basegfx::B2DPolyPolygon( + ::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), + CornerRadius/aBox.GetWidth(), + CornerRadius/aBox.GetHeight())), + nTransparency); + } + + rDevice.SetAntialiasing(nSavedAntialiasingMode); +} + + + + +void PageObjectPainter::PaintPreview ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const +{ + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + + if (mpCache != NULL) + { + const SdrPage* pPage = rpDescriptor->GetPage(); + BitmapEx aBitmap (mpCache->GetPreviewBitmap(pPage)); + mpCache->SetPreciousFlag(pPage, true); + + if (rpDescriptor->GetVisualState().GetCurrentVisualState() + == model::VisualState::VS_Excluded) + { + AlphaMask aMask (aBitmap.GetSizePixel()); + aMask.Erase(128); + aBitmap = BitmapEx(aBitmap.GetBitmap(), aMask); + } + + rDevice.DrawBitmapEx(aBox.TopLeft(), aBitmap); + } + + rDevice.SetLineColor(Color(0,0,0)); + rDevice.SetFillColor(); + rDevice.DrawRect(aBox); +} + + + + +void PageObjectPainter::PaintPageNumber ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const +{ + Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::PageNumber, + PageObjectLayouter::WindowCoordinateSystem)); + + // Paint the page number. + OSL_ASSERT(rpDescriptor->GetPage()!=NULL); + const sal_Int32 nPageNumber ((rpDescriptor->GetPage()->GetPageNum() - 1) / 2 + 1); + const String sPageNumber (String::CreateFromInt32(nPageNumber)); + rDevice.SetTextColor(Color(0x0848a8f)); + rDevice.DrawText(aBox.TopLeft(), sPageNumber); + + if (rpDescriptor->GetVisualState().GetCurrentVisualState() + == model::VisualState::VS_Excluded) + { + // Paint border around the number. + aBox.Left()-= 2; + aBox.Top() -= 1; + aBox.Right() += 2; + aBox.Bottom() += 1; + rDevice.SetLineColor(Color(Azure)); + rDevice.SetFillColor(); + rDevice.DrawRect(aBox); + + rDevice.DrawLine(aBox.TopLeft(), aBox.BottomRight()); + } +} + + + + +void PageObjectPainter::PaintTransitionEffect ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const +{ + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::TransitionEffectIndicator, + PageObjectLayouter::WindowCoordinateSystem)); + + rDevice.DrawBitmapEx( + aBox.TopLeft(), + mpPageObjectLayouter->GetTransitionEffectIcon().GetBitmapEx()); +} + + + + +void PageObjectPainter::PaintButtons ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const +{ + if (rpDescriptor->GetVisualState().GetButtonAlpha() >= 1) + return; + + const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + + const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); + rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); + + rDevice.SetLineColor(Color(Arsenic)); + + const double nCornerRadius(3); + for (int nButtonIndex=0; nButtonIndex<3; ++nButtonIndex) + { + Color aButtonFillColor (AirForceBlue); + const Rectangle aBox ( + mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::Button, + PageObjectLayouter::WindowCoordinateSystem, + nButtonIndex)); + + switch (rpDescriptor->GetVisualState().GetButtonState(nButtonIndex)) + { + case model::VisualState::BS_Normal: + break; + + case model::VisualState::BS_MouseOver: + aButtonFillColor.IncreaseLuminance(50); + break; + + case model::VisualState::BS_Pressed: + aButtonFillColor.DecreaseLuminance(50); + break; + } + rDevice.SetFillColor(aButtonFillColor); + rDevice.DrawTransparent( + ::basegfx::B2DPolyPolygon( + ::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), + nCornerRadius/aBox.GetWidth(), + nCornerRadius/aBox.GetHeight())), + rpDescriptor->GetVisualState().GetButtonAlpha()); + + // Choose icon. + const BitmapEx* pImage = NULL; + switch (nButtonIndex) + { + case 0: + pImage = &maNewSlideIcon; + break; + case 1: + pImage = &maShowSlideIcon; + break; + case 2: + pImage = &maStartPresentationIcon; + break; + } + // Paint icon over the button background. + if (pImage != NULL) + { + AlphaMask aMask (pImage->GetMask()); + AdaptTransparency( + aMask, + rpDescriptor->GetVisualState().GetButtonAlpha()); + rDevice.DrawImage( + Point( + aBox.Left()+(aBox.GetWidth()-pImage->GetSizePixel().Width())/2, + aBox.Top()+(aBox.GetHeight()-pImage->GetSizePixel().Height())/2), + BitmapEx(pImage->GetBitmap(), aMask)); + } + } + + rDevice.SetAntialiasing(nSavedAntialiasingMode); +} + + + + +ColorData PageObjectPainter::GetColorForVisualState ( + const model::SharedPageDescriptor& rpDescriptor) const +{ + ColorData nColor; + switch (rpDescriptor->GetVisualState().GetCurrentVisualState()) + { + case model::VisualState::VS_Selected: + nColor = 0x80000000 | StellaBlue; + break; + + case model::VisualState::VS_Focused: + nColor = AndroidGreen; + break; + + case model::VisualState::VS_Current: + nColor = 0x80000000 | StellaBlue; + // aColor = mpProperties->GetSelectionColor(); + break; + + case model::VisualState::VS_Excluded: + nColor = 0xcc929ca2; + break; + + case model::VisualState::VS_None: + default: + nColor = OldLace;//0x80000000 | OldLace; + break; + } + + return nColor; +} + + +} } } // end of namespace sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx index b2f4f5874a56..7389887efe1e 100644 --- a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx @@ -35,11 +35,11 @@ #include "SlsViewCacheContext.hxx" +#include "SlideSorter.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" #include "sdpage.hxx" #include "Window.hxx" #include "drawdoc.hxx" @@ -52,11 +52,9 @@ namespace sd { namespace slidesorter { namespace view { -ViewCacheContext::ViewCacheContext ( - model::SlideSorterModel& rModel, - SlideSorterView& rView) - : mrModel(rModel), - mrView(rView) +ViewCacheContext::ViewCacheContext (SlideSorter& rSlideSorter) + : mrModel(rSlideSorter.GetModel()), + mrSlideSorter(rSlideSorter) { } @@ -78,16 +76,12 @@ void ViewCacheContext::NotifyPreviewCreation ( const model::SharedPageDescriptor pDescriptor (GetDescriptor(aKey)); if (pDescriptor.get() != NULL) { - // Use direct view-invalidate here and no ActionChanged() at the VC - // since the VC is a PageObjectViewObjectContact and in its ActionChanged() - // implementation invalidates the cache entry again. - view::PageObjectViewObjectContact* pContact = pDescriptor->GetViewObjectContact(); - if (pContact != NULL) - pContact->GetObjectContact().InvalidatePartOfView(pContact->getObjectRange()); + // Force a repaint that will trigger their re-creation. + mrSlideSorter.GetView().RequestRepaint(pDescriptor); } else { - OSL_ASSERT(pDescriptor.get() != NULL); + OSL_ASSERT(pDescriptor); } } @@ -96,7 +90,7 @@ void ViewCacheContext::NotifyPreviewCreation ( bool ViewCacheContext::IsIdle (void) { - sal_Int32 nIdleState (tools::IdleDetection::GetIdleState(mrView.GetWindow())); + sal_Int32 nIdleState (tools::IdleDetection::GetIdleState(mrSlideSorter.GetContentWindow().get())); if (nIdleState == tools::IdleDetection::IDET_IDLE) return true; else @@ -108,7 +102,7 @@ bool ViewCacheContext::IsIdle (void) bool ViewCacheContext::IsVisible (cache::CacheKey aKey) { - return GetDescriptor(aKey)->IsVisible(); + return GetDescriptor(aKey)->HasState(model::PageDescriptor::ST_Visible); } diff --git a/sd/source/ui/slidesorter/view/SlsViewCacheContext.hxx b/sd/source/ui/slidesorter/view/SlsViewCacheContext.hxx index f6dab2ec8d29..cea0dfadd706 100644 --- a/sd/source/ui/slidesorter/view/SlsViewCacheContext.hxx +++ b/sd/source/ui/slidesorter/view/SlsViewCacheContext.hxx @@ -39,9 +39,12 @@ namespace sd { namespace slidesorter { namespace model { class SlideSorterModel; } } } +namespace sd { namespace slidesorter { +class SlideSorter; +} } + namespace sd { namespace slidesorter { namespace view { -class SlideSorterView; /** The cache context for the SlideSorter as used by Draw and Impress. See the base class for documentation of the individual methods. @@ -49,9 +52,7 @@ class SlideSorterView; class ViewCacheContext : public cache::CacheContext { public: - ViewCacheContext ( - model::SlideSorterModel& rModel, - SlideSorterView& rView); + ViewCacheContext (SlideSorter& rSlideSorter); virtual ~ViewCacheContext (void); virtual void NotifyPreviewCreation (cache::CacheKey aKey, const ::boost::shared_ptr& rPreview); virtual bool IsIdle (void); @@ -63,7 +64,7 @@ public: private: model::SlideSorterModel& mrModel; - SlideSorterView& mrView; + SlideSorter& mrSlideSorter; model::SharedPageDescriptor GetDescriptor (cache::CacheKey aKey); }; diff --git a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx index 0cad1985ce35..8a82c58111c5 100644 --- a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx @@ -33,29 +33,31 @@ #include "view/SlsViewOverlay.hxx" #include "SlideSorter.hxx" +#include "SlideSorterViewShell.hxx" +#include "SlsLayeredDevice.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumeration.hxx" #include "view/SlideSorterView.hxx" -#include "SlideSorterViewShell.hxx" #include "view/SlsLayouter.hxx" -#include "view/SlsPageObject.hxx" -#include "view/SlsPageObjectViewObjectContact.hxx" +#include "SlsIcons.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 @@ -66,21 +68,53 @@ #include using namespace ::sdr::overlay; +using namespace ::basegfx; + +#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) namespace { - const static sal_Int32 gnSubstitutionStripeLength (3); + +#define AirForceBlue 0x5d8aa8 +#define Arsenic 0x3b444b +#define Amber 0x007fff +#define Charcoal 0x36454f + + +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()); } + +} // end of anonymous namespace + + namespace sd { namespace slidesorter { namespace view { //===== ViewOverlay ========================================================= -ViewOverlay::ViewOverlay (SlideSorter& rSlideSorter) +ViewOverlay::ViewOverlay ( + SlideSorter& rSlideSorter, + const ::boost::shared_ptr& rpLayeredDevice) : mrSlideSorter(rSlideSorter), - maSelectionRectangleOverlay(*this), - maMouseOverIndicatorOverlay(*this), - maInsertionIndicatorOverlay(*this), - maSubstitutionOverlay(*this) + mpLayeredDevice(rpLayeredDevice), + mpSelectionRectangleOverlay(new SelectionRectangleOverlay(*this, 2)), + mpInsertionIndicatorOverlay(new InsertionIndicatorOverlay(*this, 3)), + mpSubstitutionOverlay(new SubstitutionOverlay(*this, 2)) { } @@ -94,72 +128,84 @@ ViewOverlay::~ViewOverlay (void) -SelectionRectangleOverlay& ViewOverlay::GetSelectionRectangleOverlay (void) +::boost::shared_ptr ViewOverlay::GetSelectionRectangleOverlay (void) { - return maSelectionRectangleOverlay; + return mpSelectionRectangleOverlay; } -MouseOverIndicatorOverlay& ViewOverlay::GetMouseOverIndicatorOverlay (void) +::boost::shared_ptr ViewOverlay::GetInsertionIndicatorOverlay (void) { - return maMouseOverIndicatorOverlay; + return mpInsertionIndicatorOverlay; } -InsertionIndicatorOverlay& ViewOverlay::GetInsertionIndicatorOverlay (void) +::boost::shared_ptr ViewOverlay::GetSubstitutionOverlay (void) { - return maInsertionIndicatorOverlay; + return mpSubstitutionOverlay; } -SubstitutionOverlay& ViewOverlay::GetSubstitutionOverlay (void) +SlideSorter& ViewOverlay::GetSlideSorter (void) const { - return maSubstitutionOverlay; + return mrSlideSorter; } -SlideSorter& ViewOverlay::GetSlideSorter (void) const +::boost::shared_ptr ViewOverlay::GetLayeredDevice (void) const { - return mrSlideSorter; + return mpLayeredDevice; } -OverlayManager* ViewOverlay::GetOverlayManager (void) const +//===== OverlayBase::Invalidator ============================================== + +class OverlayBase::Invalidator { - OverlayManager* pOverlayManager = NULL; +public: + Invalidator (OverlayBase& rOverlayObject) + : mrOverlayObject(rOverlayObject), + maOldBoundingBox(rOverlayObject.IsVisible() + ? rOverlayObject.GetBoundingBox() + : Rectangle()) + { + } - SlideSorterView& rView (mrSlideSorter.GetView()); - SdrPageView* pPageView = rView.GetSdrPageView(); - if (pPageView != NULL && pPageView->PageWindowCount()>0) + ~Invalidator (void) { - SdrPageWindow* pPageWindow = pPageView->GetPageWindow(0); - if (pPageWindow != NULL) - pOverlayManager = pPageWindow->GetOverlayManager(); + if ( ! maOldBoundingBox.IsEmpty()) + mrOverlayObject.Invalidate(maOldBoundingBox); + if (mrOverlayObject.IsVisible()) + mrOverlayObject.Invalidate(mrOverlayObject.GetBoundingBox()); } - return pOverlayManager; -} +private: + OverlayBase& mrOverlayObject; + const Rectangle maOldBoundingBox; +}; //===== OverlayBase ========================================================= -OverlayBase::OverlayBase (ViewOverlay& rViewOverlay) - : OverlayObject(Color(0,0,0)), - mrViewOverlay(rViewOverlay) +OverlayBase::OverlayBase ( + ViewOverlay& rViewOverlay, + const sal_Int32 nLayerIndex) + : mrViewOverlay(rViewOverlay), + mbIsVisible(false), + mnLayerIndex(nLayerIndex) { - setVisible(false); } @@ -167,30 +213,70 @@ OverlayBase::OverlayBase (ViewOverlay& rViewOverlay) OverlayBase::~OverlayBase (void) { - OSL_ENSURE(!getOverlayManager(), "Please call RemoveRegistration() in the derived class; it's too late to call it in the base class since virtual methods will be missing when called in the destructor."); } -void OverlayBase::EnsureRegistration (void) +bool OverlayBase::IsVisible (void) const { - if (getOverlayManager() == NULL) + return mbIsVisible; +} + + + + +void OverlayBase::SetIsVisible (const bool bIsVisible) +{ + if (mbIsVisible != bIsVisible) { - OverlayManager* pOverlayManager = mrViewOverlay.GetOverlayManager(); - if (pOverlayManager != NULL) - pOverlayManager->add(*this); + 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); } -void OverlayBase::RemoveRegistration() +sal_Int32 OverlayBase::GetLayerIndex (void) const { - OverlayManager* pOverlayManager = getOverlayManager(); - if (pOverlayManager != NULL) - pOverlayManager->remove(*this); + return mnLayerIndex; } @@ -198,10 +284,18 @@ void OverlayBase::RemoveRegistration() //===== SubstitutionOverlay ================================================= -SubstitutionOverlay::SubstitutionOverlay (ViewOverlay& rViewOverlay) - : OverlayBase(rViewOverlay), +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), - maShapes() + maTranslation(0,0), + maItems(), + maBoundingBox() { } @@ -210,7 +304,6 @@ SubstitutionOverlay::SubstitutionOverlay (ViewOverlay& rViewOverlay) SubstitutionOverlay::~SubstitutionOverlay (void) { - RemoveRegistration(); } @@ -218,28 +311,75 @@ SubstitutionOverlay::~SubstitutionOverlay (void) void SubstitutionOverlay::Create ( model::PageEnumeration& rSelection, - const Point& rPosition) + const Point& rPosition, + const model::SharedPageDescriptor& rpHitDescriptor) { - EnsureRegistration(); - maPosition = rPosition; - - maShapes.clear(); + maTranslation = Point(0,0); + + ::boost::shared_ptr pPreviewCache ( + mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache()); + view::Layouter& rLayouter (mrViewOverlay.GetSlideSorter().GetView().GetLayouter()); + ::boost::shared_ptr pPageObjectLayouter ( + rLayouter.GetPageObjectLayouter()); + + const sal_Int32 nRow0 (rpHitDescriptor + ? rLayouter.GetRow(rpHitDescriptor->GetPageIndex()) + : -1); + const sal_Int32 nColumn0 (rpHitDescriptor + ? rLayouter.GetColumn(rpHitDescriptor->GetPageIndex()) + : -1); + + maItems.clear(); while (rSelection.HasMoreElements()) { - const Rectangle aBox (rSelection.GetNextElement()->GetPageObject()->GetCurrentBoundRect()); + model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement()); + + sal_uInt8 nTransparency (128); + + // Calculate distance between current page object and the one under + // the mouse. + if (nRow0>=0 || nColumn0>=0) + { + const sal_Int32 nRow (rLayouter.GetRow(pDescriptor->GetPageIndex())); + const sal_Int32 nColumn (rLayouter.GetColumn(pDescriptor->GetPageIndex())); + + const sal_Int32 nRowDistance (abs(nRow - nRow0)); + const sal_Int32 nColumnDistance (abs(nColumn - nColumn0)); + if (nRowDistance>1 || nColumnDistance>1) + continue; + if (nRowDistance!=0 && nColumnDistance!=0) + nTransparency = 255 * mnCornerTransparency / 100; + else if (nRowDistance!=0 || nColumnDistance!=0) + nTransparency = 255 * mnSideTransparency / 100; + else + nTransparency = 255 * mnCenterTransparency / 100; + } + + const Rectangle aBox (pDescriptor->GetBoundingBox()); + maBoundingBox.Union(aBox); basegfx::B2DRectangle aB2DBox( aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()); - maShapes.append(basegfx::tools::createPolygonFromRect(aB2DBox), 4); + + const Bitmap aBitmap (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap()); + AlphaMask aMask (aBitmap.GetSizePixel()); + aMask.Erase(nTransparency); + maItems.push_back(ItemDescriptor()); + maItems.back().maImage = BitmapEx( + aBitmap, + aMask); + maItems.back().maLocation = pPageObjectLayouter->GetBoundingBox( + pDescriptor, + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem).TopLeft(); + maItems.back().mnTransparency = nTransparency/255.0; + maItems.back().maShape = basegfx::tools::createPolygonFromRect(aB2DBox); } - setVisible(maShapes.count() > 0); - // The selection indicator may have been visible already so call - // objectChange() to enforce an update. - objectChange(); + SetIsVisible(maItems.size() > 0); } @@ -247,8 +387,8 @@ void SubstitutionOverlay::Create ( void SubstitutionOverlay::Clear (void) { - maShapes.clear(); - setVisible(false); + SetIsVisible(false); + maItems.clear(); } @@ -256,12 +396,11 @@ void SubstitutionOverlay::Clear (void) void SubstitutionOverlay::Move (const Point& rOffset) { - const basegfx::B2DHomMatrix aTranslation(basegfx::tools::createTranslateB2DHomMatrix(rOffset.X(), rOffset.Y())); + Invalidator aInvalidator (*this); - maShapes.transform(aTranslation); maPosition += rOffset; - - objectChange(); + maTranslation += rOffset; + maBoundingBox.Move(rOffset.X(), rOffset.Y()); } @@ -283,57 +422,58 @@ Point SubstitutionOverlay::GetPosition (void) const -drawinglayer::primitive2d::Primitive2DSequence SubstitutionOverlay::createOverlayObjectPrimitive2DSequence() +void SubstitutionOverlay::Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea) { - drawinglayer::primitive2d::Primitive2DSequence aRetval; - const sal_uInt32 nCount(maShapes.count()); + (void)rRepaintArea; - if(nCount && getOverlayManager()) - { - aRetval.realloc(nCount); - const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); - const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + if ( ! IsVisible()) + return; - for(sal_uInt32 a(0); a < nCount; a++) - { - aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( - new drawinglayer::primitive2d::PolygonMarkerPrimitive2D( - maShapes.getB2DPolygon(a), - aRGBColorA, - aRGBColorB, - gnSubstitutionStripeLength)); - } - } + basegfx::B2DHomMatrix aTranslation; + aTranslation.translate(maTranslation.X(), maTranslation.Y()); - return aRetval; -} + rDevice.SetFillColor(Color(AirForceBlue)); + rDevice.SetLineColor(); -void SubstitutionOverlay::stripeDefinitionHasChanged() -{ - // react on OverlayManager's stripe definition change - objectChange(); + for (::std::vector::const_iterator + iItem(maItems.begin()), + iEnd(maItems.end()); + iItem!=iEnd; + ++iItem) + { + ::basegfx::B2DPolyPolygon aPolygon (iItem->maShape); + aPolygon.transform(aTranslation); + rDevice.DrawTransparent(aPolygon, iItem->mnTransparency); + rDevice.DrawBitmapEx(iItem->maLocation+maTranslation, iItem->maImage); + } } -//===== SelectionRectangleOverlay =========================================== -SelectionRectangleOverlay::SelectionRectangleOverlay (ViewOverlay& rViewOverlay) - : OverlayBase (rViewOverlay), - maAnchor(0,0), - maSecondCorner(0,0) + +Rectangle SubstitutionOverlay::GetBoundingBox (void) const { + return maBoundingBox; } -SelectionRectangleOverlay::~SelectionRectangleOverlay() + +//===== SelectionRectangleOverlay =========================================== + +SelectionRectangleOverlay::SelectionRectangleOverlay ( + ViewOverlay& rViewOverlay, + const sal_Int32 nLayerIndex) + : OverlayBase (rViewOverlay, nLayerIndex), + maAnchor(0,0), + maSecondCorner(0,0) { - RemoveRegistration(); } - Rectangle SelectionRectangleOverlay::GetSelectionRectangle (void) { return Rectangle(maAnchor, maSecondCorner); @@ -344,9 +484,9 @@ Rectangle SelectionRectangleOverlay::GetSelectionRectangle (void) void SelectionRectangleOverlay::Start (const Point& rAnchor) { - EnsureRegistration(); - setVisible(false); + SetIsVisible(false); maAnchor = rAnchor; + maSecondCorner = rAnchor; } @@ -354,252 +494,111 @@ void SelectionRectangleOverlay::Start (const Point& rAnchor) void SelectionRectangleOverlay::Update (const Point& rSecondCorner) { - maSecondCorner = rSecondCorner; - setVisible(true); - // The selection rectangle may have been visible already so call - // objectChange() to enforce an update. - objectChange(); -} - - - - -drawinglayer::primitive2d::Primitive2DSequence SelectionRectangleOverlay::createOverlayObjectPrimitive2DSequence() -{ - drawinglayer::primitive2d::Primitive2DSequence aRetval; - const basegfx::B2DRange aRange(maAnchor.X(), maAnchor.Y(), maSecondCorner.X(), maSecondCorner.Y()); - const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aRange)); - - if(aPolygon.count()) - { - const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); - const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); - const drawinglayer::primitive2d::Primitive2DReference xReference( - new drawinglayer::primitive2d::PolygonMarkerPrimitive2D( - aPolygon, - aRGBColorA, - aRGBColorB, - gnSubstitutionStripeLength)); - - aRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); - } + Invalidator aInvalidator (*this); - return aRetval; -} - -void SelectionRectangleOverlay::stripeDefinitionHasChanged() -{ - // react on OverlayManager's stripe definition change - objectChange(); -} - - - - -//===== InsertionIndicatorOverlay =========================================== - -InsertionIndicatorOverlay::InsertionIndicatorOverlay (ViewOverlay& rViewOverlay) - : OverlayBase (rViewOverlay), - mnInsertionIndex(-1), - maBoundingBox() -{ -} - - - - -InsertionIndicatorOverlay::~InsertionIndicatorOverlay() -{ - RemoveRegistration(); -} - - - - -void InsertionIndicatorOverlay::SetPositionAndSize (const Rectangle& aNewBoundingBox) -{ - EnsureRegistration(); - maBoundingBox = aNewBoundingBox; - setVisible( ! maBoundingBox.IsEmpty()); - // The insertion indicator may have been visible already so call - // objectChange() to enforce an update. - objectChange(); + maSecondCorner = rSecondCorner; + SetIsVisible(true); } -void InsertionIndicatorOverlay::SetPosition (const Point& rPoint) +void SelectionRectangleOverlay::Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea) { - static const bool bAllowHorizontalInsertMarker = true; - Layouter& rLayouter (mrViewOverlay.GetSlideSorter().GetView().GetLayouter()); - USHORT nPageCount - = (USHORT)mrViewOverlay.GetSlideSorter().GetModel().GetPageCount(); - - sal_Int32 nInsertionIndex = rLayouter.GetInsertionIndex (rPoint, - bAllowHorizontalInsertMarker); - if (nInsertionIndex >= nPageCount) - nInsertionIndex = nPageCount-1; - sal_Int32 nDrawIndex = nInsertionIndex; - - bool bVertical = false; - bool bLeftOrTop = false; - if (nInsertionIndex >= 0) - { - // Now that we know where to insert, we still have to determine - // where to draw the marker. There are two decisions to make: - // 1. Draw a vertical or a horizontal insert marker. - // The horizontal one may only be chosen when there is only one - // column. - // 2. The vertical (standard) insert marker may be painted left to - // the insert page or right of the previous one. When both pages - // are in the same row this makes no difference. Otherwise the - // posiotions are at the left and right ends of two rows. - - Point aPageCenter (rLayouter.GetPageObjectBox ( - nInsertionIndex).Center()); - - if (bAllowHorizontalInsertMarker - && rLayouter.GetColumnCount() == 1) - { - bVertical = false; - bLeftOrTop = (rPoint.Y() <= aPageCenter.Y()); - } - else - { - bVertical = true; - bLeftOrTop = (rPoint.X() <= aPageCenter.X()); - } + if ( ! IsVisible()) + return; - // Add one when the mark was painted below or to the right of the - // page object. - if ( ! bLeftOrTop) - nInsertionIndex += 1; - } - - mnInsertionIndex = nInsertionIndex; + rDevice.SetFillColor(Color(Amber)); + rDevice.SetLineColor(Color(Amber)); - Rectangle aBox; - if (mnInsertionIndex >= 0) - aBox = rLayouter.GetInsertionMarkerBox ( - nDrawIndex, - bVertical, - bLeftOrTop); - SetPositionAndSize (aBox); + 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())); + 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); } -sal_Int32 InsertionIndicatorOverlay::GetInsertionPageIndex (void) const +Rectangle SelectionRectangleOverlay::GetBoundingBox (void) const { - return mnInsertionIndex; + 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); } -drawinglayer::primitive2d::Primitive2DSequence InsertionIndicatorOverlay::createOverlayObjectPrimitive2DSequence() -{ - drawinglayer::primitive2d::Primitive2DSequence aRetval(2); - const basegfx::B2DRange aRange(maBoundingBox.Left(), maBoundingBox.Top(), maBoundingBox.Right(), maBoundingBox.Bottom()); - const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aRange)); - const basegfx::BColor aRGBColor(Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetFontColor().getBColor()); - - aRetval[0] = drawinglayer::primitive2d::Primitive2DReference( - new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( - basegfx::B2DPolyPolygon(aPolygon), - aRGBColor)); - aRetval[1] = drawinglayer::primitive2d::Primitive2DReference( - new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( - aPolygon, - aRGBColor)); - - return aRetval; -} - - - - -//===== MouseOverIndicatorOverlay =========================================== - -MouseOverIndicatorOverlay::MouseOverIndicatorOverlay (ViewOverlay& rViewOverlay) - : OverlayBase (rViewOverlay), - mpPageUnderMouse() -{ -} - - - +//===== InsertionIndicatorOverlay =========================================== -MouseOverIndicatorOverlay::~MouseOverIndicatorOverlay (void) +InsertionIndicatorOverlay::InsertionIndicatorOverlay ( + ViewOverlay& rViewOverlay, + const sal_Int32 nLayerIndex) + : OverlayBase (rViewOverlay, nLayerIndex), + maLocation(), + maIconWithBorder(), + maIcon(), + maMask() { - RemoveRegistration(); + LocalResource aResource (IMG_ICONS); + maIconWithBorder = Image(SdResId(IMAGE_INSERTION_INDICATOR_SELECT)); + maIcon = Image(SdResId(IMAGE_INSERTION_INDICATOR_NORMAL)); + maMask = Image(SdResId(IMAGE_INSERTION_INDICATOR_MASK)); } -void MouseOverIndicatorOverlay::SetSlideUnderMouse ( - const model::SharedPageDescriptor& rpDescriptor) +void InsertionIndicatorOverlay::SetLocation (const Point& rLocation) { - ViewShellBase* pBase = mrViewOverlay.GetSlideSorter().GetViewShellBase(); - if (pBase==NULL || ! pBase->GetUpdateLockManager()->IsLocked()) + const Point aTopLeft ( + rLocation - Point( + maIconWithBorder.GetSizePixel().Width()/2, + maIconWithBorder.GetSizePixel().Height()/2)); + if (maLocation != aTopLeft) { - model::SharedPageDescriptor pDescriptor; - if ( ! mpPageUnderMouse.expired()) - { - try - { - pDescriptor = model::SharedPageDescriptor(mpPageUnderMouse); - } - catch (::boost::bad_weak_ptr) - { - } - } - - if (pDescriptor != rpDescriptor) - { - // Switch to the new (possibly empty) descriptor. - mpPageUnderMouse = rpDescriptor; - - EnsureRegistration(); - - // Show the indicator when a valid page descriptor is given. - setVisible( ! mpPageUnderMouse.expired()); - // The mouse over indicator may have been visible already so call - // objectChange() to enforce an update. - objectChange(); - } + Invalidator aInvalidator (*this); + maLocation = aTopLeft; } } -drawinglayer::primitive2d::Primitive2DSequence MouseOverIndicatorOverlay::createOverlayObjectPrimitive2DSequence() +void InsertionIndicatorOverlay::Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea) { - view::PageObjectViewObjectContact* pContact = GetViewObjectContact(); + (void)rRepaintArea; - if(pContact) - { - return pContact->createMouseOverEffectPrimitive2DSequence(); - } + if ( ! IsVisible()) + return; - return drawinglayer::primitive2d::Primitive2DSequence(); + rDevice.DrawImage( + maLocation, + maIconWithBorder); } -view::PageObjectViewObjectContact* MouseOverIndicatorOverlay::GetViewObjectContact (void) const +Rectangle InsertionIndicatorOverlay::GetBoundingBox (void) const { - if ( ! mpPageUnderMouse.expired()) - { - model::SharedPageDescriptor pDescriptor (mpPageUnderMouse); - return pDescriptor->GetViewObjectContact(); - } - return NULL; + return Rectangle(maLocation, maIconWithBorder.GetSizePixel()); } diff --git a/sd/source/ui/slidesorter/view/makefile.mk b/sd/source/ui/slidesorter/view/makefile.mk index ebde1e7fe02d..0741b9e9551f 100644 --- a/sd/source/ui/slidesorter/view/makefile.mk +++ b/sd/source/ui/slidesorter/view/makefile.mk @@ -39,6 +39,8 @@ ENABLE_EXCEPTIONS=TRUE AUTOSEG=true PRJINC=..$/.. +IMGLST_SRS=$(SRS)$/$(TARGET).srs + # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk @@ -46,19 +48,21 @@ PRJINC=..$/.. # --- Files -------------------------------------------------------- +SRS1NAME=$(TARGET) +SRC1FILES = \ + SlsIcons.src + SLOFILES = \ + $(SLO)$/SlideSorterView.obj \ $(SLO)$/SlsFontProvider.obj \ - $(SLO)$/SlsPageObject.obj \ - $(SLO)$/SlsPageObjectViewContact.obj \ - $(SLO)$/SlsPageObjectViewObjectContact.obj \ + $(SLO)$/SlsInsertAnimator.obj \ + $(SLO)$/SlsLayeredDevice.obj \ $(SLO)$/SlsLayouter.obj \ - $(SLO)$/SlideSorterView.obj \ + $(SLO)$/SlsPageObjectLayouter.obj \ + $(SLO)$/SlsPageObjectPainter.obj \ $(SLO)$/SlsViewCacheContext.obj \ $(SLO)$/SlsViewOverlay.obj -EXCEPTIONSFILES= \ - $(SLO)$/SlsPageObjectViewObjectContact.obj - # --- Tagets ------------------------------------------------------- .INCLUDE : target.mk diff --git a/sd/source/ui/view/ViewShellManager.cxx b/sd/source/ui/view/ViewShellManager.cxx index e8337c97dfb3..528969bcbf4d 100755 --- a/sd/source/ui/view/ViewShellManager.cxx +++ b/sd/source/ui/view/ViewShellManager.cxx @@ -45,7 +45,7 @@ #include #undef VERBOSE -#define VERBOSE 2 +//#define VERBOSE 2 namespace sd { diff --git a/sd/util/makefile.mk b/sd/util/makefile.mk index d74700307291..5c0c16e4a71e 100644 --- a/sd/util/makefile.mk +++ b/sd/util/makefile.mk @@ -54,6 +54,7 @@ RESLIB1SRSFILES=\ $(SRS)$/notes.srs \ $(SRS)$/animui.srs \ $(SRS)$/slideshow.srs \ + $(SRS)$/slsview.srs \ $(SRS)$/uitable.srs \ $(SRS)$/view.srs \ $(SRS)$/uiannotations.srs \ -- cgit v1.2.3 From df407bc1d622181187849b6b4c7c377242902757 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 27 Jan 2010 15:11:16 +0100 Subject: renaissance1: #i107215# Added SlideShowView::DrawLock class. --- .../controller/SlideSorterController.cxx | 20 +++++------- .../ui/slidesorter/controller/SlsAnimator.cxx | 36 ++------------------- .../ui/slidesorter/controller/SlsClipboard.cxx | 3 +- .../controller/SlsSelectionFunction.cxx | 4 +-- .../slidesorter/controller/SlsSelectionManager.cxx | 4 +-- .../ui/slidesorter/controller/SlsSlotManager.cxx | 3 +- .../ui/slidesorter/inc/controller/SlsAnimator.hxx | 4 +-- .../ui/slidesorter/inc/view/SlideSorterView.hxx | 17 ++++++---- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 3 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 37 +++++++++++++++++----- 10 files changed, 57 insertions(+), 74 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 98d6ca4afee9..e47e934a47b9 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -835,18 +835,14 @@ void SlideSorterController::SetZoom (long int nZoom) if (nZoom < 1) nZoom = 1; - mrView.LockRedraw(true); - mrView.GetLayouter().SetZoom(nZoom/100.0); - mrView.Layout(); - GetScrollBarManager().UpdateScrollBars (false); - mrView.GetPreviewCache()->InvalidateCache(); - mrView.RequestRepaint(); - mrView.LockRedraw(false); - - /* - ViewShell::SetZoom (nZoom); - GetViewFrame()->GetBindings().Invalidate (SID_ATTR_ZOOM); - */ + { + SlideSorterView::DrawLock aLock (mrView); + mrView.GetLayouter().SetZoom(nZoom/100.0); + mrView.Layout(); + GetScrollBarManager().UpdateScrollBars (false); + mrView.GetPreviewCache()->InvalidateCache(); + mrView.RequestRepaint(); + } } diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index d7679d88328e..0bc3b0aeb7cd 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -69,19 +69,6 @@ public: -class Animator::DrawLock -{ -public: - DrawLock (view::SlideSorterView& rView); - ~DrawLock (void); - -private: - view::SlideSorterView& mrView; -}; - - - - Animator::Animator (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), maTimer(), @@ -134,7 +121,7 @@ Animator::AnimationId Animator::AddAnimation ( // Prevent redraws except for the ones in TimeoutHandler. // While the Animator is active it will schedule repaints regularly. // Repaints in between would only lead to visual artifacts. - mpDrawLock.reset(new DrawLock(mrSlideSorter.GetView())); + mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter)); maTimer.Start(); return pAnimation->mnAnimationId; @@ -156,7 +143,7 @@ Animator::AnimationId Animator::AddInfiniteAnimation ( // Prevent redraws except for the ones in TimeoutHandler. // While the Animator is active it will schedule repaints regularly. // Repaints in between would only lead to visual artifacts. - mpDrawLock.reset(new DrawLock(mrSlideSorter.GetView())); + mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter)); maTimer.Start(); return pAnimation->mnAnimationId; @@ -242,7 +229,7 @@ IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) if (maAnimations.size() > 0) { - mpDrawLock.reset(new DrawLock(mrSlideSorter.GetView())); + mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter)); maTimer.Start(); } @@ -329,21 +316,4 @@ bool Animator::Animation::IsExpired (void) -//===== Animator::DrawLock ==================================================== - -Animator::DrawLock::DrawLock (view::SlideSorterView& rView) - : mrView(rView) -{ - mrView.LockRedraw(true); -} - - - - -Animator::DrawLock::~DrawLock (void) -{ - mrView.LockRedraw(false); -} - - } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 0e5b839a1de9..16b845489ffc 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -146,13 +146,12 @@ void Clipboard::HandleSlotCall (SfxRequest& rRequest) // a crash. if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE) { - mrSlideSorter.GetView().LockRedraw (TRUE); + view::SlideSorterView::DrawLock aLock (mrSlideSorter); if(xFunc.is()) xFunc->DoPaste(); else DoPaste(); mrController.GetSelectionManager()->MakeSelectionVisible(); - mrSlideSorter.GetView().LockRedraw(FALSE); } rRequest.Done(); break; diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 8cb815fd5787..51bd01d7ae6f 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -1687,7 +1687,7 @@ void SelectionFunction::RectangleSelector::ProcessRectangleSelection (void) view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); if (rOverlay.GetSelectionRectangleOverlay()->IsVisible()) { - mrSlideSorter.GetView().LockRedraw(true); + view::SlideSorterView::DrawLock aLock (mrSlideSorter); PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); @@ -1743,8 +1743,6 @@ void SelectionFunction::RectangleSelector::ProcessRectangleSelection (void) // Rely on auto scrolling to make page objects visible. mrSlideSorter.GetController().GetSelectionManager()->ResetMakeSelectionVisiblePending(); - - mrSlideSorter.GetView().LockRedraw(false); } } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 83ce65981bce..2ce5b11e302a 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -235,7 +235,7 @@ bool SelectionManager::MoveSelectedPages (const sal_Int32 nTargetPageIndex) bool bMoved (false); PageSelector& rSelector (mrController.GetPageSelector()); - mrSlideSorter.GetView().LockRedraw (TRUE); + view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); SlideSorterController::ModelChangeLock aLock (mrController); // Transfer selection of the slide sorter to the document. @@ -276,8 +276,6 @@ bool SelectionManager::MoveSelectedPages (const sal_Int32 nTargetPageIndex) mrController.GetSlotManager()->ExecuteCommandAsynchronously( ::std::auto_ptr(pCommand)); - mrSlideSorter.GetView().LockRedraw (FALSE); - return bMoved; } diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 2dde82c121e1..7213fc5cb49d 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -1177,7 +1177,7 @@ void SlotManager::InsertSlide (SfxRequest& rRequest) // When a new page has been inserted then select it, make it the // current page, and focus it. - mrSlideSorter.GetView().LockRedraw(TRUE); + view::SlideSorterView::DrawLock aLock (mrSlideSorter); if (mrSlideSorter.GetModel().GetPageCount() > nPageCount) { nInsertionIndex++; @@ -1189,7 +1189,6 @@ void SlotManager::InsertSlide (SfxRequest& rRequest) } } rSelector.EnableBroadcasting(); - mrSlideSorter.GetView().LockRedraw(FALSE); } diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx index ffcfabcb925f..e9683e0dc075 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx @@ -33,6 +33,7 @@ #define SD_SLIDESORTER_CONTROLLER_ANIMATOR_HXX #include "SlideSorter.hxx" +#include "view/SlideSorterView.hxx" #include #include #include @@ -99,8 +100,7 @@ private: typedef ::std::vector > AnimationList; AnimationList maAnimations; - class DrawLock; - ::boost::scoped_ptr mpDrawLock; + ::boost::scoped_ptr mpDrawLock; AnimationId mnNextAnimationId; diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 8b927d0c630e..6c7c5f735045 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -193,13 +193,6 @@ public: */ void AddSdrObject (SdrObject& rObject); - /** Lock or unlock painting into the content window. - @param bLock - When then painting is locked. When then - painting is unlocked. - */ - void LockRedraw (const bool bLock); - void SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor); void SetButtonUnderMouse (const sal_Int32 nButtonIndex); @@ -211,6 +204,16 @@ public: ::boost::shared_ptr GetPageObjectPainter (void); + class DrawLock + { + public: + DrawLock (view::SlideSorterView& rView); + DrawLock (SlideSorter& rSlideSorter); + ~DrawLock (void); + private: + view::SlideSorterView& mrView; + }; + protected: virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx index 4d8943ddd7e3..1012197fa8c5 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorter.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -482,7 +482,7 @@ void SlideSorter::ArrangeGUIElements ( { // Prevent untimely redraws while the view is not yet correctly // resized. - mpSlideSorterView->LockRedraw (TRUE); + view::SlideSorterView::DrawLock aLock (*mpSlideSorterView); if (GetContentWindow()) GetContentWindow()->EnablePaint (FALSE); @@ -492,7 +492,6 @@ void SlideSorter::ArrangeGUIElements ( GetContentWindow()->EnablePaint (TRUE); mbLayoutPending = false; - mpSlideSorterView->LockRedraw (FALSE); } } diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index f21063a1057c..e402a5565feb 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -885,14 +885,6 @@ void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint -void SlideSorterView::LockRedraw (const bool bLock) -{ - ::sd::View::LockRedraw(bLock ? TRUE : FALSE); -} - - - - void SlideSorterView::SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor) { if (mpPageUnderMouse != rpDescriptor) @@ -1032,4 +1024,33 @@ bool SlideSorterView::SetState ( } + + +//===== Animator::DrawLock ==================================================== + +SlideSorterView::DrawLock::DrawLock (view::SlideSorterView& rView) + : mrView(rView) +{ + mrView.LockRedraw(TRUE); +} + + + + +SlideSorterView::DrawLock::DrawLock (SlideSorter& rSlideSorter) + : mrView(rSlideSorter.GetView()) +{ + mrView.LockRedraw(TRUE); +} + + + + +SlideSorterView::DrawLock::~DrawLock (void) +{ + mrView.LockRedraw(FALSE); +} + + + } } } // end of namespace ::sd::slidesorter::view -- cgit v1.2.3 From 2336af0eb45bee98f98b0ac9a6988bfd0e6193e5 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Thu, 28 Jan 2010 13:00:30 +0100 Subject: renaissance1: #i107215# Fixed some minor compilation problems. --- .../controller/SlsAnimationFunction.cxx | 4 ++-- .../ui/slidesorter/controller/SlsAnimator.cxx | 4 +--- .../ui/slidesorter/controller/SlsClipboard.cxx | 1 - .../ui/slidesorter/controller/SlsFocusManager.cxx | 1 - .../ui/slidesorter/controller/SlsListener.cxx | 3 +++ .../slidesorter/controller/SlsScrollBarManager.cxx | 4 +++- .../controller/SlsSelectionFunction.cxx | 3 ++- .../ui/slidesorter/model/SlideSorterModel.cxx | 2 +- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 1 - sd/source/ui/slidesorter/view/SlideSorterView.cxx | 27 ++++++---------------- sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 12 ++++++---- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 6 ++--- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 2 -- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 4 ++-- sd/source/ui/slidesorter/view/SlsViewOverlay.cxx | 11 +++++---- 15 files changed, 36 insertions(+), 49 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx index 905b28ee5f6b..d86b0811348e 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx @@ -271,12 +271,12 @@ double AnimationParametricFunction::operator() (const double nX) { const sal_Int32 nIndex0 (nX * maY.size()); const double nX0 (nIndex0 / double(maY.size()-1)); - const sal_Int32 nIndex1 (nIndex0 + 1); + const sal_uInt32 nIndex1 (nIndex0 + 1); const double nX1 (nIndex1 / double(maY.size()-1)); if (nIndex0<=0) return maY[0]; - else if (nIndex0>=maY.size() || nIndex1>=maY.size()) + else if (sal_uInt32(nIndex0)>=maY.size() || nIndex1>=maY.size()) return maY[maY.size()-1]; const double nU ((nX-nX1) / (nX0 - nX1)); diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index 0bc3b0aeb7cd..dff12bda7f3e 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -249,16 +249,14 @@ Animator::Animation::Animation ( const Animator::FinishFunctor& rFinishFunctor) : maAnimation(rAnimation), maFinishFunctor(rFinishFunctor), + mnAnimationId(nId), mnValue(0), mnEnd(nEnd), mnDelta(nDelta), - mnAnimationId(nId), mbIsExpired(false) { - maAnimation(mnValue); mnValue = mnDelta; - } diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 16b845489ffc..2c44ffc6d754 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -580,7 +580,6 @@ sal_Int8 Clipboard::ExecuteDrop ( || ( nXOffset >= 2 && nYOffset >= 2 ); // Get insertion position and then turn off the insertion indicator. - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); mrController.GetInsertionIndicatorHandler()->UpdatePosition(aEventModelPosition); USHORT nIndex = DetermineInsertPosition(*pDragTransferable); OSL_TRACE ("Clipboard::AcceptDrop() called for index %d", diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index 8128752417fe..ca272b405b8b 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -265,7 +265,6 @@ void FocusManager::ShowFocusIndicator ( { // Scroll the focused page object into the visible area and repaint // it, so that the focus indicator becomes visible. - view::SlideSorterView& rView (mrSlideSorter.GetView()); mrSlideSorter.GetController().GetSelectionManager()->MakeRectangleVisible ( GetFocusedPageDescriptor()->GetBoundingBox()); } diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index b78abb2e5298..8d6868c65728 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -331,6 +331,9 @@ void Listener::Notify ( rSdrHint.GetPage(), true); break; + + default: + break; } } else if (rHint.ISA(ViewShellHint)) diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index e874f67ce48e..0a8bebc1bdbf 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -58,8 +58,10 @@ ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter) mnHorizontalScrollFactor (0.1), mnVerticalScrollFactor (0.1), mpScrollBarFiller(mrSlideSorter.GetScrollBarFiller()), - mpContentWindow(mrSlideSorter.GetContentWindow()), + maAutoScrollTimer(), + maAutoScrollOffset(0,0), mbIsAutoScrollActive(false), + mpContentWindow(mrSlideSorter.GetContentWindow()), maAutoScrollFunctor() { // Hide the scroll bars by default to prevent display errors while diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 51bd01d7ae6f..e0566bb3818b 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -653,7 +653,6 @@ void SelectionFunction::StartDrag (const Point& rMousePosition) if (mbPageHit && ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); mpSubstitutionHandler->Start(rMousePosition); mbPageHit = false; mpWindow->ReleaseMouse(); @@ -839,6 +838,8 @@ sal_uInt32 SelectionFunction::EncodeKeyEvent ( const EventDescriptor& rDescriptor, const KeyEvent& rEvent) const { + (void)rDescriptor; + // Initialize as key event. sal_uInt32 nEventCode (KEY_EVENT); diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx index 4d449b5c330f..553737d1493d 100644 --- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx +++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx @@ -289,7 +289,7 @@ sal_Int32 SlideSorterModel::GetIndex (const SdrPage* pPage) const const sal_Int32 nCount (maPageDescriptors.size()); for (sal_Int32 nIndex=0; nIndexIncrementLockCount(); mpLayeredDevice->Repaint(rPaintArea); mrSlideSorter.GetContentWindow()->DecrementLockCount(); - -#ifdef VERBOSE - OSL_TRACE("CompleteRedraw done"); -#endif } else { -#ifdef VERBOSE - OSL_TRACE("%5d CompleteRedraw while locked", nPaintIndex++); -#endif View::CompleteRedraw(pDevice, rPaintArea, pRedirector); } } @@ -974,6 +957,10 @@ bool SlideSorterView::SetState ( case PageDescriptor::ST_Excluded: AddVisualStateAnimation(rpDescriptor); break; + + case PageDescriptor::ST_WasSelected: + // Ignore. + break; } // Fade in or out the buttons. diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx index 6b6231fcad69..e76728e95c1c 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx @@ -132,7 +132,7 @@ void LayeredDevice::Invalidate ( const Rectangle& rInvalidationArea, const sal_Int32 nLayer) { - if (nLayer<0 || nLayer>=maLayers.size()) + if (nLayer<0 || sal_uInt32(nLayer)>=maLayers.size()) { OSL_ASSERT(nLayer>=0 && nLayer= maLayers.size()) + if (sal_uInt32(nLayer) >= maLayers.size()) maLayers.resize(nLayer+1); maLayers[nLayer].AddPainter(rpPainter); if (nLayer == 0) @@ -190,7 +190,7 @@ void LayeredDevice::RemovePainter ( OSL_ASSERT(rpPainter); return; } - if (nLayer<0 || nLayer>=maLayers.size()) + if (nLayer<0 || sal_uInt32(nLayer)>=maLayers.size()) { OSL_ASSERT(nLayer>=0 && nLayernLayer && maLayers[nLayer].HasPainter(); + return nLayer>=0 + && sal_uInt32(nLayer)HasState(model::PageDescriptor::ST_MouseOver)) { rDevice.SetFillColor(Color(MouseOverColor & 0x00ffffff)); - double nTransparency (COLORDATA_TRANSPARENCY(MouseOverColor)/255.0); + nTransparency = COLORDATA_TRANSPARENCY(MouseOverColor)/255.0; nTransparency *= 1-rpDescriptor->GetVisualState().GetVisualStateBlend(); rDevice.DrawTransparent( ::basegfx::B2DPolyPolygon( diff --git a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx index 8a82c58111c5..3d997689dc45 100644 --- a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx @@ -518,12 +518,13 @@ void SelectionRectangleOverlay::Paint ( ::std::min(maAnchor.Y(), maSecondCorner.Y()), ::std::max(maAnchor.X(), maSecondCorner.X()), ::std::max(maAnchor.Y(), maSecondCorner.Y())); - rDevice.DrawTransparent( + 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())), + ::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), + 5.0/aBox.GetWidth(), + 5.0/aBox.GetHeight())), 0.5); } -- cgit v1.2.3 From ab518ae9111d251a4e6267ae9f40836b8a7a3913 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 12 Feb 2010 13:58:24 +0100 Subject: renaissance1: #i107215# Adaption to latest changes of the spec. --- .../ui/accessibility/AccessibleSlideSorterView.cxx | 9 +- sd/source/ui/inc/SlideSorter.hxx | 15 +- sd/source/ui/inc/SlideSorterViewShell.hxx | 2 + sd/source/ui/inc/ViewShell.hxx | 2 +- .../ui/slidesorter/cache/SlsBitmapFactory.cxx | 55 +- .../ui/slidesorter/cache/SlsBitmapFactory.hxx | 1 + .../controller/SlideSorterController.cxx | 15 +- .../ui/slidesorter/controller/SlsAnimator.cxx | 32 +- .../ui/slidesorter/controller/SlsFocusManager.cxx | 101 ++-- .../controller/SlsInsertionIndicatorHandler.cxx | 23 +- .../slidesorter/controller/SlsScrollBarManager.cxx | 11 +- .../controller/SlsSelectionFunction.cxx | 557 +++++++++++++-------- .../slidesorter/controller/SlsSelectionManager.cxx | 6 +- .../slidesorter/inc/controller/SlsFocusManager.hxx | 6 + .../controller/SlsInsertionIndicatorHandler.hxx | 1 + .../inc/controller/SlsScrollBarManager.hxx | 4 +- .../inc/controller/SlsSelectionFunction.hxx | 6 +- .../ui/slidesorter/inc/model/SlideSorterModel.hxx | 3 + .../ui/slidesorter/inc/view/SlideSorterView.hxx | 14 +- sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 38 +- .../slidesorter/inc/view/SlsPageObjectLayouter.hxx | 28 +- .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 21 +- sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 102 ++++ .../ui/slidesorter/inc/view/SlsViewOverlay.hxx | 5 +- .../ui/slidesorter/model/SlideSorterModel.cxx | 22 + sd/source/ui/slidesorter/model/SlsVisualState.cxx | 8 +- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 54 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 19 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 168 +++++-- sd/source/ui/slidesorter/view/SlsIcons.hrc | 2 + sd/source/ui/slidesorter/view/SlsIcons.src | 4 + sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 144 ++++-- sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx | 32 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 80 ++- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 59 +-- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 518 +++++++++++++++---- sd/source/ui/slidesorter/view/SlsTheme.cxx | 242 +++++++++ sd/source/ui/slidesorter/view/SlsViewOverlay.cxx | 26 +- sd/source/ui/slidesorter/view/makefile.mk | 20 +- sd/source/ui/view/viewshel.cxx | 8 +- sd/util/makefile.mk | 2 +- 41 files changed, 1825 insertions(+), 640 deletions(-) create mode 100644 sd/source/ui/slidesorter/inc/view/SlsTheme.hxx create mode 100644 sd/source/ui/slidesorter/view/SlsTheme.cxx diff --git a/sd/source/ui/accessibility/AccessibleSlideSorterView.cxx b/sd/source/ui/accessibility/AccessibleSlideSorterView.cxx index 1169795139db..5b00b7da303b 100644 --- a/sd/source/ui/accessibility/AccessibleSlideSorterView.cxx +++ b/sd/source/ui/accessibility/AccessibleSlideSorterView.cxx @@ -809,10 +809,9 @@ AccessibleSlideSorterView::Implementation::~Implementation (void) void AccessibleSlideSorterView::Implementation::UpdateVisibility (void) { - ::sd::slidesorter::view::SlideSorterView::PageRange aRange ( - mrSlideSorter.GetView().GetVisiblePageRange()); - mnFirstVisibleChild = aRange.first; - mnLastVisibleChild = aRange.second; + Pair aRange (mrSlideSorter.GetView().GetVisiblePageRange()); + mnFirstVisibleChild = aRange.A(); + mnLastVisibleChild = aRange.B(); } @@ -850,7 +849,7 @@ void AccessibleSlideSorterView::Implementation::Clear (void) sal_Int32 AccessibleSlideSorterView::Implementation::GetVisibleChildCount (void) const { - if (mnFirstVisibleChild <= mnLastVisibleChild) + if (mnFirstVisibleChild <= mnLastVisibleChild && mnFirstVisibleChild>=0) return mnLastVisibleChild - mnFirstVisibleChild + 1; else return 0; diff --git a/sd/source/ui/inc/SlideSorter.hxx b/sd/source/ui/inc/SlideSorter.hxx index 3e2c69232fe3..49869d807848 100644 --- a/sd/source/ui/inc/SlideSorter.hxx +++ b/sd/source/ui/inc/SlideSorter.hxx @@ -33,12 +33,15 @@ #define SD_SLIDESORTER_SLIDE_SORTER_HXX #include "fupoor.hxx" +#include "Window.hxx" #include #include #include #include #include #include +#include + class ScrollBar; class ScrollBarBox; @@ -57,6 +60,7 @@ class SlideSorterModel; namespace sd { namespace slidesorter { namespace view { class SlideSorterView; +class Theme; } } } namespace sd { namespace slidesorter { namespace controller { @@ -67,6 +71,9 @@ class Properties; } } } +typedef ::boost::shared_ptr SharedSdWindow; + + namespace sd { namespace slidesorter { /** Show previews for all the slides in a document and allow the user to @@ -144,7 +151,7 @@ public: /** Return the content window. This is a sibling and is geometrically enclosed by the scroll bars. */ - ::boost::shared_ptr GetContentWindow (void) const; + SharedSdWindow GetContentWindow (void) const; model::SlideSorterModel& GetModel (void) const; @@ -193,6 +200,8 @@ public: */ ::boost::shared_ptr GetProperties (void) const; + ::boost::shared_ptr GetTheme (void) const; + protected: /** This virtual method makes it possible to create a specialization of the slide sorter view shell that works with its own implementation @@ -229,7 +238,8 @@ private: ::com::sun::star::uno::WeakReference mxControllerWeak; ViewShell* mpViewShell; ViewShellBase* mpViewShellBase; - ::boost::shared_ptr mpContentWindow; + SharedSdWindow mpContentWindow; + bool mbOwnesContentWindow; ::boost::shared_ptr mpHorizontalScrollBar; ::boost::shared_ptr mpVerticalScrollBar; ::boost::shared_ptr mpScrollBarBox; @@ -242,6 +252,7 @@ private: classes. */ ::boost::shared_ptr mpProperties; + ::boost::shared_ptr mpTheme; SlideSorter ( ViewShell& rViewShell, diff --git a/sd/source/ui/inc/SlideSorterViewShell.hxx b/sd/source/ui/inc/SlideSorterViewShell.hxx index 42eacb552e9e..c861af9dfa21 100644 --- a/sd/source/ui/inc/SlideSorterViewShell.hxx +++ b/sd/source/ui/inc/SlideSorterViewShell.hxx @@ -129,6 +129,8 @@ public: */ virtual void ArrangeGUIElements (void); + virtual bool HandleScrollCommand (const CommandEvent& rEvent, ::sd::Window* pWindow); + //===== Drag and Drop ===================================================== virtual void StartDrag ( diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 395566f0cded..84587e6464a3 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -216,7 +216,7 @@ public: virtual BOOL RequestHelp( const HelpEvent& rEvt, ::sd::Window* pWin ); virtual long Notify( NotifyEvent& rNEvt, ::sd::Window* pWin ); - BOOL HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWin); + virtual bool HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWin); virtual void Draw(OutputDevice &rDev, const Region &rReg); diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index 82575d0bce11..519acebe1526 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -42,6 +42,10 @@ #include #include #include +#include + + +const static sal_Int32 gnSuperSampleFactor (2); namespace sd { namespace slidesorter { namespace view { class SlideSorterView; @@ -51,7 +55,8 @@ class PageObjectViewObjectContact; namespace sd { namespace slidesorter { namespace cache { BitmapFactory::BitmapFactory (void) - : maRenderer(NULL, false) + : maRenderer(NULL, false), + mbRemoveBorder(true) { } @@ -71,17 +76,57 @@ BitmapFactory::~BitmapFactory (void) const bool bDoSuperSampling) { Size aSize (rPixelSize); - if (bDoSuperSampling) + bool bDo (true); + if (bDo) + { + aSize.Width() *= gnSuperSampleFactor; + aSize.Height() *= gnSuperSampleFactor; + } + if (mbRemoveBorder) { - aSize.Width() *= 2; - aSize.Height() *= 2; + aSize.Width() += 2; + aSize.Height() += 2; } const Image aPreview (maRenderer.RenderPage (&rPage, aSize, String())); ::boost::shared_ptr pPreview (new BitmapEx(aPreview.GetBitmapEx())); - if (bDoSuperSampling) + if (mbRemoveBorder) + pPreview->Crop(Rectangle(1,1,aSize.Width()-2,aSize.Height()-2)); + if (bDo) + { +#if 1 + const sal_Int32 nSuperSampleCount (gnSuperSampleFactor * gnSuperSampleFactor); + BitmapReadAccess* pRA = pPreview->GetBitmap().AcquireReadAccess(); + Bitmap aBitmap (rPixelSize, pPreview->GetBitCount()); + BitmapWriteAccess* pWA = aBitmap.AcquireWriteAccess(); + const sal_Int32 nWidth (pRA->Width()); + const sal_Int32 nHeight (pRA->Height()); + for (sal_Int32 nY=0; nYGetColor(nY+nV, nX+nU)); + nRed += aColor.GetRed(); + nGreen += aColor.GetGreen(); + nBlue += aColor.GetBlue(); + } + pWA->SetPixel(nY/gnSuperSampleFactor, nX/gnSuperSampleFactor, + BitmapColor( + nRed/nSuperSampleCount, + nGreen/nSuperSampleCount, + nBlue/nSuperSampleCount)); + } + pPreview.reset(new BitmapEx(aBitmap)); +#else pPreview->Scale(rPixelSize, BMP_SCALE_INTERPOLATE); +#endif + } return pPreview; } diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx index 51d7d1c60f1b..6da0aabfe3d2 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx @@ -61,6 +61,7 @@ public: private: PreviewRenderer maRenderer; + const bool mbRemoveBorder; }; diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index e47e934a47b9..8ee0f748fcd3 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -131,7 +131,7 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) mnPaintEntranceCount(0), mbIsContextMenuOpen(false) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); OSL_ASSERT(pWindow); if (pWindow) { @@ -156,8 +156,6 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) void SlideSorterController::Init (void) { - mrView.HandleModelChange(); - mpCurrentSlideManager.reset(new CurrentSlideManager(mrSlideSorter)); mpPageSelector.reset(new PageSelector(mrSlideSorter)); mpFocusManager.reset(new FocusManager(mrSlideSorter)); @@ -208,6 +206,7 @@ SlideSorterController::~SlideSorterController (void) void SlideSorterController::Dispose (void) { + mpInsertionIndicatorHandler->End(); mpAnimator->Dispose(); } @@ -554,7 +553,7 @@ void SlideSorterController::PostModelChange (void) mbPostModelChangePending = false; mrModel.Resync(); - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { GetCurrentSlideManager()->HandleModelChange(); @@ -601,7 +600,7 @@ IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent) if (pEvent != NULL) { ::Window* pWindow = pEvent->GetWindow(); - ::boost::shared_ptr pActiveWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pActiveWindow (mrSlideSorter.GetContentWindow()); switch (pEvent->GetId()) { case VCLEVENT_WINDOW_ACTIVATE: @@ -777,7 +776,7 @@ Rectangle SlideSorterController::Rearrange (bool bForce) { Rectangle aNewContentArea (maTotalWindowArea); - const ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { // Place the scroll bars. @@ -813,7 +812,7 @@ Rectangle SlideSorterController::Rearrange (bool bForce) void SlideSorterController::SetZoom (long int nZoom) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); long int nCurrentZoom ((long int)( pWindow->GetMapMode().GetScaleX().operator double() * 100)); @@ -960,7 +959,7 @@ void SlideSorterController::PageNameHasChanged (int nPageIndex, const String& rs // that of the name change. do { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if ( ! pWindow) break; diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index dff12bda7f3e..69be776179d3 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -53,7 +53,14 @@ public: const Animator::AnimationId nAnimationId, const Animator::FinishFunctor& rFinishFunctor); ~Animation (void); + /** Run next animation step. If animation has reached its end it is + expired. + */ bool Run (void); + /** Typically called when an animation has finished, but also from + Animator::Disposed(). The finish functor is called and the + animation is marked as expired to prevent another run. + */ void Expire (void); bool IsExpired (void); @@ -99,6 +106,12 @@ Animator::~Animator (void) void Animator::Dispose (void) { mbIsDisposed = true; + + AnimationList aCopy (maAnimations); + AnimationList::const_iterator iAnimation; + for (iAnimation=aCopy.begin(); iAnimation!=aCopy.end(); ++iAnimation) + (*iAnimation)->Expire(); + maTimer.Stop(); mpDrawLock.reset(); } @@ -111,7 +124,11 @@ Animator::AnimationId Animator::AddAnimation ( const sal_Int32 nDuration, const FinishFunctor& rFinishFunctor) { + // When the animator is already disposed then ignore this call + // silently (well, we show an assertion, but do not throw an exception.) OSL_ASSERT( ! mbIsDisposed); + if (mbIsDisposed) + return -1; const double nDelta = double(gnResolution) / double(nDuration); boost::shared_ptr pAnimation ( @@ -134,7 +151,11 @@ Animator::AnimationId Animator::AddInfiniteAnimation ( const AnimationFunctor& rAnimation, const double nDelta) { + // When the animator is already disposed then ignore this call + // silently (well, we show an assertion, but do not throw an exception.) OSL_ASSERT( ! mbIsDisposed); + if (mbIsDisposed) + return -1; boost::shared_ptr pAnimation ( new Animation(rAnimation, nDelta, -1.0, mnNextAnimationId++, FinishFunctor())); @@ -180,9 +201,12 @@ void Animator::RemoveAnimation (const Animator::AnimationId nId) bool Animator::ProcessAnimations (void) { + bool bExpired (false); + OSL_ASSERT( ! mbIsDisposed); + if (mbIsDisposed) + return bExpired; - bool bExpired (false); AnimationList aCopy (maAnimations); AnimationList::const_iterator iAnimation; @@ -200,6 +224,8 @@ bool Animator::ProcessAnimations (void) void Animator::CleanUpAnimationList (void) { OSL_ASSERT( ! mbIsDisposed); + if (mbIsDisposed) + return; AnimationList aActiveAnimations; @@ -221,6 +247,8 @@ IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) if (mbIsDisposed) return 0; + OSL_TRACE("Animator timeout start"); + if (ProcessAnimations()) CleanUpAnimationList(); @@ -233,6 +261,8 @@ IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) maTimer.Start(); } + OSL_TRACE("Animator timeout end"); + return 0; } diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index ca272b405b8b..0c0213e9e702 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -49,7 +49,8 @@ namespace sd { namespace slidesorter { namespace controller { FocusManager::FocusManager (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mnPageIndex(0), - mbPageIsFocused(false) + mbPageIsFocused(false), + mbIsVerticalWrapActive(false) { if (mrSlideSorter.GetModel().GetPageCount() > 0) mnPageIndex = 0; @@ -71,67 +72,97 @@ void FocusManager::MoveFocus (FocusMoveDirection eDirection) { HideFocusIndicator (GetFocusedPageDescriptor()); - int nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount()); + const sal_Int32 nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount()); + const sal_Int32 nPageCount (mrSlideSorter.GetModel().GetPageCount()); switch (eDirection) { case FMD_NONE: - if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount()) - mnPageIndex = mrSlideSorter.GetModel().GetPageCount() - 1; + // Nothing to be done. break; case FMD_LEFT: - mnPageIndex -= 1; - if (mnPageIndex < 0) - { - mnPageIndex = mrSlideSorter.GetModel().GetPageCount() - 1; - SetFocusToToolBox(); - } + if (mnPageIndex > 0) + mnPageIndex -= 1; + else if (mbIsVerticalWrapActive) + mnPageIndex = nPageCount-1; break; case FMD_RIGHT: - mnPageIndex += 1; - if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount()) - { + if (mnPageIndex < nPageCount-1) + mnPageIndex += 1; + else if (mbIsVerticalWrapActive) mnPageIndex = 0; - SetFocusToToolBox(); - } break; case FMD_UP: { - int nColumn = mnPageIndex % nColumnCount; - mnPageIndex -= nColumnCount; - if (mnPageIndex < 0) + const sal_Int32 nCandidate (mnPageIndex - nColumnCount); + if (nCandidate < 0) { - // Wrap arround to the bottom row or the one above and - // go to the correct column. - int nCandidate = mrSlideSorter.GetModel().GetPageCount()-1; - int nCandidateColumn = nCandidate % nColumnCount; - if (nCandidateColumn > nColumn) - mnPageIndex = nCandidate - (nCandidateColumn-nColumn); - else if (nCandidateColumn < nColumn) - mnPageIndex = nCandidate - - nColumnCount - + (nColumn - nCandidateColumn); - else - mnPageIndex = nCandidate; + if (mbIsVerticalWrapActive) + { + // Wrap arround to the bottom row or the one above + // and go to the correct column. + const sal_Int32 nLastIndex (nPageCount-1); + const sal_Int32 nLastColumn (nLastIndex % nColumnCount); + const sal_Int32 nCurrentColumn (mnPageIndex%nColumnCount); + if (nLastColumn >= nCurrentColumn) + { + // The last row contains the current column. + mnPageIndex = nLastIndex - (nLastColumn-nCurrentColumn); + } + else + { + // Only the second to last row contains the current column. + mnPageIndex = nLastIndex - nLastColumn + - nColumnCount + + nCurrentColumn; + } + } + } + else + { + // Move the focus the previous row. + mnPageIndex = nCandidate; } } break; case FMD_DOWN: { - int nColumn = mnPageIndex % nColumnCount; - mnPageIndex += nColumnCount; - if (mnPageIndex >= mrSlideSorter.GetModel().GetPageCount()) + const sal_Int32 nCandidate (mnPageIndex + nColumnCount); + if (nCandidate >= nPageCount) { - // Wrap arround to the correct column. - mnPageIndex = nColumn; + if (mbIsVerticalWrapActive) + { + // Wrap arround to the correct column. + mnPageIndex = mnPageIndex % nColumnCount; + } + else + { + // Do not move the focus. + } + } + else + { + // Move the focus to the next row. + mnPageIndex = nCandidate; } } break; } + if (mnPageIndex < 0) + { + OSL_ASSERT(mnPageIndex>=0); + mnPageIndex = 0; + } + else if (mnPageIndex >= nPageCount) + { + OSL_ASSERT(mnPageIndexIsUIReadOnly()) + mbIsReadOnly = mrSlideSorter.GetModel().IsReadOnly(); + if (mbIsReadOnly) return; SetPosition(rMouseModelPosition); @@ -85,9 +87,10 @@ void InsertionIndicatorHandler::Start (const Point& rMouseModelPosition) void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition) { - OSL_ASSERT(mbIsActive); + if ( ! mbIsActive) + return; - if (mrSlideSorter.GetProperties()->IsUIReadOnly()) + if (mbIsReadOnly) return; SetPosition(rMouseModelPosition); @@ -98,7 +101,12 @@ void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition void InsertionIndicatorHandler::End (void) { - OSL_ASSERT(mbIsActive); + if ( ! mbIsActive) + return; + + if (mbIsReadOnly) + return; + GetInsertAnimator()->SetInsertPosition(-1, false); mbIsActive = false; @@ -119,7 +127,10 @@ bool InsertionIndicatorHandler::IsActive (void) const sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const { - return mnInsertionIndex; + if (mbIsReadOnly) + return -1; + else + return mnInsertionIndex; } diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index 0a8bebc1bdbf..5f4e2b3c1fb5 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -244,7 +244,7 @@ void ScrollBarManager::AdaptWindowSize (const Rectangle& rArea) void ScrollBarManager::UpdateScrollBars (bool bResetThumbPosition, bool bUseScrolling) { Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); Size aWindowModelSize (pWindow->PixelToLogic(pWindow->GetSizePixel())); // The horizontal scroll bar is only shown when the window is @@ -336,6 +336,11 @@ IMPL_LINK(ScrollBarManager, VerticalScrollBarHandler, ScrollBar*, pScrollBar) mrSlideSorter.GetContentWindow()->SetVisibleXY ( -1, nRelativePosition); + /* + mrSlideSorter.GetView().UpdatePageUnderMouse( + aMousePosition, + (rEvent.GetButtons() & MOUSE_LEFT)!=0); + */ } return TRUE; } @@ -368,7 +373,7 @@ void ScrollBarManager::SetWindowOrigin ( mnHorizontalPosition = nHorizontalPosition; mnVerticalPosition = nVerticalPosition; - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); Size aViewSize (pWindow->GetViewSize()); Point aOrigin ( (long int) (mnHorizontalPosition * aViewSize.Width()), @@ -569,7 +574,7 @@ int ScrollBarManager::GetHorizontalScrollBarHeight (void) const void ScrollBarManager::CalcAutoScrollOffset (const Point& rMouseWindowPosition) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); int nDx = 0; int nDy = 0; diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index e0566bb3818b..d12fbe3bbfc0 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -108,18 +108,28 @@ static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIF namespace sd { namespace slidesorter { namespace controller { +/** 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. +*/ class SelectionFunction::SubstitutionHandler { public: - SubstitutionHandler (SlideSorter& rSlideSorter); - ~SubstitutionHandler (void); - - void SetHitDescriptor (const model::SharedPageDescriptor& rpHitDescriptor); - /** Create a substitution display of the currently selected pages and use the given position as the anchor point. */ - void Start (const Point& rMouseModelPosition); + SubstitutionHandler ( + SlideSorter& rSlideSorter, + const model::SharedPageDescriptor& rpHitDescriptor, + const Point& rMouseModelPosition); + ~SubstitutionHandler (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. + */ + void Dispose (void); /** Move the substitution display by the distance the mouse has travelled since the last call to this method or to @@ -129,31 +139,26 @@ public: const Point& rMousePosition, const bool bAllowAutoScroll = true); - /** Move the substitution display of the currently selected pages. - */ - void Process (void); - - void End (void); - - bool IsActive (void) const; - private: SlideSorter& mrSlideSorter; model::SharedPageDescriptor mpHitDescriptor; - bool mbIsActive; sal_Int32 mnInsertionIndex; + + /** Move the substitution display of the currently selected pages. + */ + void Process (void); }; -class SelectionFunction::RectangleSelector + + +class SelectionFunction::MouseMultiSelector { public: - /** Start a rectangle selection at the given position. - */ - RectangleSelector ( + MouseMultiSelector ( SlideSorter& rSlideSorter, const Point& rMouseModelPosition); - ~RectangleSelector (void); + virtual ~MouseMultiSelector (void); void RestoreInitialSelection (void); @@ -163,21 +168,75 @@ public: void UpdatePosition ( const Point& rMousePosition, const bool bAllowAutoScroll = true); - enum SelectionMode { SM_Normal, SM_Add, SM_Toggle }; + void SetSelectionMode (const SelectionMode eSelectionMode); void SetSelectionModeFromModifier (const sal_uInt32 nEventCode); -private: +protected: SlideSorter& mrSlideSorter; SelectionMode meSelectionMode; ::std::set maInitialSelection; - /** Select all pages that lie completly in the selection rectangle. - */ - void ProcessRectangleSelection (void); + virtual void UpdateModelPosition (const Point& rMouseModelPosition) = 0; + virtual void UpdateSelection (void) = 0; + + void UpdateSelectionState ( + const model::SharedPageDescriptor& rpDescriptor, + const bool bIsInSelection) const; }; +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 + { + public: + /** Start a rectangle selection at the given position. + */ + RangeSelector ( + SlideSorter& rSlideSorter, + const Point& rMouseModelPosition); + virtual ~RangeSelector (void); + + protected: + virtual void UpdateModelPosition (const Point& rMouseModelPosition); + + /** Select all pages that lie completly in the selection rectangle. + */ + virtual void UpdateSelection (void); + + private: + Point maAnchor; + Point maSecondCorner; + Pointer maSavedPointer; + sal_Int32 mnAnchorIndex; + sal_Int32 mnSecondIndex; + + Rectangle GetBoundingBox (void) const; + }; + +} // end of anonymous namespace + class SelectionFunction::EventDescriptor { @@ -221,15 +280,14 @@ SelectionFunction::SelectionFunction ( mbDragSelection(false), maInsertionMarkerBox(), mbProcessingMouseButtonDown(false), - mpSubstitutionHandler(new SubstitutionHandler(mrSlideSorter)), - mpRectangleSelector(), + mpSubstitutionHandler(), + mpMouseMultiSelector(), mnButtonDownPageIndex(-1), mnButtonDownButtonIndex(-1), mbIsDeselectionPending(false), mnShiftKeySelectionAnchor(-1) { - //af aDelayToScrollTimer.SetTimeout(50); - aDragTimer.SetTimeoutHdl( LINK( this, SelectionFunction, DragSlideHdl ) ); + aDragTimer.SetTimeoutHdl(LINK(this, SelectionFunction, DragSlideHdl)); } SelectionFunction::~SelectionFunction (void) @@ -284,23 +342,28 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) // In some modes (dragging, moving) the mouse over indicator is only // annoying. Turn it off in these cases. - if (mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay()->IsVisible() - || mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay()->IsVisible()) + if (mpSubstitutionHandler || mpMouseMultiSelector) { mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); } else { - UpdatePageUnderMouse(aMousePosition, (rEvent.GetButtons() & MOUSE_LEFT)!=0); + mrSlideSorter.GetView().UpdatePageUnderMouse( + aMousePosition, + (rEvent.GetButtons() & MOUSE_LEFT)!=0); } view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel()); if ( ! aRectangle.IsInside(aMousePosition) - && rOverlay.GetSubstitutionOverlay()->IsVisible()) + && mpSubstitutionHandler) { // Mouse left the window with pressed left button. Make it a drag. StartDrag(aMousePosition); + // Mouse motion events are not sent to us while the mouse is outside + // the window and drag&drop is active. Therefore hide the + // substitution. + // mpSubstitutionHandler->Hide(); } else { @@ -350,7 +413,7 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); if (rOverlay.GetSubstitutionOverlay()->IsVisible()) pEventDescriptor->mnEventCode |= SUBSTITUTION_VISIBLE; - if (mpRectangleSelector) + if (mpMouseMultiSelector) pEventDescriptor->mnEventCode |= RECTANGLE_VISIBLE; // 3. Process the event. @@ -398,12 +461,15 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) case KEY_ESCAPE: rFocusManager.SetFocusToToolBox(); - if (mpSubstitutionHandler->IsActive()) - mpSubstitutionHandler->End(); - if (mpRectangleSelector) + if (mpSubstitutionHandler) + { + mpSubstitutionHandler->Dispose(); + mpSubstitutionHandler.reset(); + } + if (mpMouseMultiSelector) { - mpRectangleSelector->RestoreInitialSelection(); - mpRectangleSelector.reset(); + mpMouseMultiSelector->RestoreInitialSelection(); + mpMouseMultiSelector.reset(); } bResult = TRUE; break; @@ -653,7 +719,14 @@ void SelectionFunction::StartDrag (const Point& rMousePosition) if (mbPageHit && ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { - mpSubstitutionHandler->Start(rMousePosition); + if ( ! mpSubstitutionHandler) + mpSubstitutionHandler.reset( + new SubstitutionHandler( + mrSlideSorter, + mrSlideSorter.GetController().GetPageAt(rMousePosition), + rMousePosition)); + else + mpSubstitutionHandler->UpdatePosition(rMousePosition); mbPageHit = false; mpWindow->ReleaseMouse(); @@ -880,9 +953,9 @@ sal_uInt32 SelectionFunction::EncodeState ( // Detect whether we are dragging pages or dragging a selection rectangle. view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if (rOverlay.GetSubstitutionOverlay()->IsVisible()) + if (mpSubstitutionHandler) nEventCode |= SUBSTITUTION_VISIBLE; - if (mpRectangleSelector) + if (mpMouseMultiSelector) nEventCode |= RECTANGLE_VISIBLE; return nEventCode; @@ -928,11 +1001,9 @@ void SelectionFunction::EventPreprocessing (const EventDescriptor& rDescriptor) bool Match ( const sal_uInt32 nEventCode, - const sal_uInt32 nPositivePattern, - const sal_uInt32 nNegativePattern = 0) + const sal_uInt32 nPositivePattern) { - return (nEventCode & nPositivePattern)==nPositivePattern - && (nEventCode & nNegativePattern)==0; + return (nEventCode & nPositivePattern)==nPositivePattern; } @@ -974,8 +1045,6 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) // The substitution is visible. Handle events accordingly. if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) { - // Move substitution. - mpSubstitutionHandler->SetHitDescriptor(pHitDescriptor); if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0) StartDrag(rDescriptor.maMousePosition); mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition); @@ -989,32 +1058,31 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) // The following Process() call may lead to the desctruction // of pHitDescriptor so release our reference to it. pHitDescriptor.reset(); - mpSubstitutionHandler->End(); - mpSubstitutionHandler->Process(); + mpSubstitutionHandler.reset(); } break; case RECTANGLE_VISIBLE: - OSL_ASSERT(mpRectangleSelector); + OSL_ASSERT(mpMouseMultiSelector); // The selection rectangle is visible. Handle events accordingly. if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) { - if (mpRectangleSelector) + if (mpMouseMultiSelector) { - mpRectangleSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); - mpRectangleSelector->UpdatePosition(rDescriptor.maMousePosition); + mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); + mpMouseMultiSelector->UpdatePosition(rDescriptor.maMousePosition); } bMakeSelectionVisible = false; } else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK)) { - mpRectangleSelector.reset(); + mpMouseMultiSelector.reset(); } // Anything else stops the rectangle selection and the event is // processed again. else { - mpRectangleSelector.reset(); + mpMouseMultiSelector.reset(); EventDescriptor aModifiedDescriptor (rDescriptor); aModifiedDescriptor.mnEventCode &= ~RECTANGLE_VISIBLE; EventProcessing(aModifiedDescriptor); @@ -1022,7 +1090,7 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) break; default: - OSL_ASSERT(!mpRectangleSelector); + OSL_ASSERT(!mpMouseMultiSelector); switch (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION)) { case BUTTON_DOWN: @@ -1086,7 +1154,7 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) // Rectangle selection. case ANY_MODIFIER(BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): mbIsDeselectionPending = true; - OSL_ASSERT(!mpRectangleSelector); + OSL_ASSERT(!mpMouseMultiSelector); break; } break; @@ -1126,16 +1194,18 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) { // A mouse motion without visible substitution starts that. case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE): - mpSubstitutionHandler->SetHitDescriptor(pHitDescriptor); - mpSubstitutionHandler->Start(rDescriptor.maMouseModelPosition); + mpSubstitutionHandler.reset(new SubstitutionHandler( + mrSlideSorter, + pHitDescriptor, + rDescriptor.maMouseModelPosition)); 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(!mpRectangleSelector); - mpRectangleSelector.reset( - new RectangleSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); - mpRectangleSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); + OSL_ASSERT(!mpMouseMultiSelector); + mpMouseMultiSelector.reset( + new RangeSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); + mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); break; } break; @@ -1224,37 +1294,6 @@ void SelectionFunction::SwitchView (const model::SharedPageDescriptor& rpDescrip -void SelectionFunction::UpdatePageUnderMouse ( - const Point& rMousePosition, - const bool bIsMouseButtonDown) -{ - // Determine page under mouse and show the mouse over effect. - model::SharedPageDescriptor pHitDescriptor ( - mrController.GetPageAt(rMousePosition)); - mrSlideSorter.GetView().SetPageUnderMouse(pHitDescriptor); - - // Handle the mouse being over any buttons. - if (pHitDescriptor) - { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); - const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); - const sal_Int32 nButtonIndex ( - mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt ( - pHitDescriptor, - aMouseModelPosition)); - mrSlideSorter.GetView().SetButtonUnderMouse(nButtonIndex); - if (bIsMouseButtonDown) - { - pHitDescriptor->GetVisualState().SetActiveButtonState( - nButtonIndex, - model::VisualState::BS_Pressed); - } - } -} - - - - void SelectionFunction::ProcessButtonClick ( const model::SharedPageDescriptor& rpDescriptor, const sal_Int32 nButtonIndex) @@ -1314,7 +1353,7 @@ SelectionFunction::EventDescriptor::EventDescriptor ( mnEventCode(nEventType), mnButtonIndex(-1) { - ::boost::shared_ptr pWindow (rSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (rSlideSorter.GetContentWindow()); maMousePosition = rEvent.GetPosPixel(); maMouseModelPosition = pWindow->PixelToLogic(maMousePosition); @@ -1369,7 +1408,7 @@ SelectionFunction::EventDescriptor::EventDescriptor ( mnEventCode(MOUSE_DRAG), mnButtonIndex(-1) { - ::boost::shared_ptr pWindow (rSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (rSlideSorter.GetContentWindow()); maMouseModelPosition = pWindow->PixelToLogic(maMousePosition); model::SharedPageDescriptor pHitDescriptor ( @@ -1399,44 +1438,14 @@ SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDes //===== SubstitutionHandler =================================================== -SelectionFunction::SubstitutionHandler::SubstitutionHandler (SlideSorter& rSlideSorter) +SelectionFunction::SubstitutionHandler::SubstitutionHandler ( + SlideSorter& rSlideSorter, + const model::SharedPageDescriptor& rpHitDescriptor, + const Point& rMouseModelPosition) : mrSlideSorter(rSlideSorter), - mpHitDescriptor(), - mbIsActive(false), + mpHitDescriptor(rpHitDescriptor), mnInsertionIndex(-1) { -} - - - - -SelectionFunction::SubstitutionHandler::~SubstitutionHandler (void) -{ - OSL_ASSERT(!mbIsActive); - if (mrSlideSorter.IsValid()) - { - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - rOverlay.GetSubstitutionOverlay()->Clear(); - } -} - - - - -void SelectionFunction::SubstitutionHandler::SetHitDescriptor ( - const model::SharedPageDescriptor& rpHitDescriptor) -{ - mpHitDescriptor = rpHitDescriptor; -} - - - - -void SelectionFunction::SubstitutionHandler::Start (const Point& rMouseModelPosition) -{ - OSL_ASSERT(!mbIsActive); - mbIsActive = true; mnInsertionIndex = -1; // No Drag-and-Drop for master pages. @@ -1466,19 +1475,39 @@ void SelectionFunction::SubstitutionHandler::Start (const Point& rMouseModelPosi +SelectionFunction::SubstitutionHandler::~SubstitutionHandler (void) +{ + Process(); + + view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); + rOverlay.GetSubstitutionOverlay()->Clear(); + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(); + mpHitDescriptor.reset(); +} + + + + +void SelectionFunction::SubstitutionHandler::Dispose (void) +{ + mnInsertionIndex = -1; +} + + + + void SelectionFunction::SubstitutionHandler::UpdatePosition ( const Point& rMousePosition, const bool bAllowAutoScroll) { - OSL_ASSERT(mbIsActive); - if (mrSlideSorter.GetProperties()->IsUIReadOnly()) return; // Convert window coordinates into model coordinates (we need the // window coordinates for auto-scrolling because that remains // constant while scrolling.) - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll( @@ -1531,44 +1560,15 @@ void SelectionFunction::SubstitutionHandler::Process (void) -void SelectionFunction::SubstitutionHandler::End (void) -{ - OSL_ASSERT(mbIsActive); - mbIsActive = false; - - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - rOverlay.GetSubstitutionOverlay()->Clear(); - mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(); - mpHitDescriptor.reset(); -} - - - - -bool SelectionFunction::SubstitutionHandler::IsActive (void) const -{ - return mbIsActive; -} - - - +//===== SelectionFunction::MouseMultiSelector ====================================== -//===== SelectionFunction::RectangleSelector ================================== - -SelectionFunction::RectangleSelector::RectangleSelector ( +SelectionFunction::MouseMultiSelector::MouseMultiSelector ( SlideSorter& rSlideSorter, const Point& rMouseModelPosition) : mrSlideSorter(rSlideSorter), meSelectionMode(SM_Normal), maInitialSelection() { - if (mrSlideSorter.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay() - ->Start(rMouseModelPosition); - } - // Remember the current selection. model::PageEnumeration aPages ( model::PageEnumerationProvider::CreateAllPagesEnumeration( @@ -1585,18 +1585,14 @@ SelectionFunction::RectangleSelector::RectangleSelector ( -SelectionFunction::RectangleSelector::~RectangleSelector (void) +SelectionFunction::MouseMultiSelector::~MouseMultiSelector (void) { - if (mrSlideSorter.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay()->SetIsVisible(false); - } } -void SelectionFunction::RectangleSelector::RestoreInitialSelection (void) +void SelectionFunction::MouseMultiSelector::RestoreInitialSelection (void) { // Remember the current selection. model::PageEnumeration aPages ( @@ -1616,37 +1612,32 @@ void SelectionFunction::RectangleSelector::RestoreInitialSelection (void) -void SelectionFunction::RectangleSelector::UpdatePosition ( +void SelectionFunction::MouseMultiSelector::UpdatePosition ( const Point& rMousePosition, const bool bAllowAutoScroll) { // Convert window coordinates into model coordinates (we need the // window coordinates for auto-scrolling because that remains // constant while scrolling.) - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll( rMousePosition, ::boost::bind( - &SelectionFunction::RectangleSelector::UpdatePosition, + &SelectionFunction::MouseMultiSelector::UpdatePosition, this, rMousePosition, false)))) { - if (mrSlideSorter.GetProperties()->IsShowSelection()) - { - mrSlideSorter.GetView().GetOverlay().GetSelectionRectangleOverlay() - ->Update(aMouseModelPosition); - ProcessRectangleSelection(); - } + UpdateModelPosition(aMouseModelPosition); } } -void SelectionFunction::RectangleSelector::SetSelectionModeFromModifier ( +void SelectionFunction::MouseMultiSelector::SetSelectionModeFromModifier ( const sal_uInt32 nEventCode) { switch (nEventCode & MODIFIER_MASK) @@ -1668,19 +1659,100 @@ void SelectionFunction::RectangleSelector::SetSelectionModeFromModifier ( -void SelectionFunction::RectangleSelector::SetSelectionMode (const SelectionMode eSelectionMode) +void SelectionFunction::MouseMultiSelector::SetSelectionMode (const SelectionMode eSelectionMode) { if (meSelectionMode != eSelectionMode) { meSelectionMode = eSelectionMode; - ProcessRectangleSelection(); + UpdateSelection(); } } -void SelectionFunction::RectangleSelector::ProcessRectangleSelection (void) +void SelectionFunction::MouseMultiSelector::UpdateSelectionState ( + const model::SharedPageDescriptor& rpDescriptor, + const bool bIsInSelection) const +{ + // Determine whether the page was selected before the rectangle + // selection was started. + const bool bWasSelected (rpDescriptor->HasState(model::PageDescriptor::ST_WasSelected)); + + // Combine the two selection states depending on the selection mode. + bool bSelect (false); + switch(meSelectionMode) + { + case SM_Normal: + bSelect = bIsInSelection; + break; + + case SM_Add: + bSelect = bIsInSelection || bWasSelected; + break; + + case SM_Toggle: + if (bIsInSelection) + bSelect = !bWasSelected; + else + bSelect = bWasSelected; + break; + } + + // Set the new selection state. + if (bSelect) + mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor); + else + mrSlideSorter.GetController().GetPageSelector().DeselectPage(rpDescriptor); +} + + + + +//===== 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; @@ -1690,8 +1762,6 @@ void SelectionFunction::RectangleSelector::ProcessRectangleSelection (void) { view::SlideSorterView::DrawLock aLock (mrSlideSorter); - PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); - // Select all pages whose page object lies completly or partially // inside the selection rectangle. const Rectangle& rSelectionRectangle ( @@ -1711,35 +1781,85 @@ void SelectionFunction::RectangleSelector::ProcessRectangleSelection (void) view::PageObjectLayouter::WindowCoordinateSystem)); const bool bIsPageInSelectionRectangle (rSelectionRectangle.IsOver(aPageBox)); - // Determine whether the page was selected before the rectangle - // selection was started. - const bool bWasSelected (pDescriptor->HasState(model::PageDescriptor::ST_WasSelected)); + UpdateSelectionState(pDescriptor, bIsPageInSelectionRectangle); + } - // Combine the two selection states depending on the selection mode. - bool bSelect (false); - switch(meSelectionMode) - { - case SM_Normal: - bSelect = bIsPageInSelectionRectangle; - break; + // Rely on auto scrolling to make page objects visible. + mrSlideSorter.GetController().GetSelectionManager()->ResetMakeSelectionVisiblePending(); + } +} - case SM_Add: - bSelect = bIsPageInSelectionRectangle || bWasSelected; - break; +} // end of anonymous namespace - case SM_Toggle: - if (bIsPageInSelectionRectangle) - bSelect = !bWasSelected; - else - bSelect = bWasSelected; - break; - } - // Set the new selection state. - if (bSelect) - rSelector.SelectPage(pDescriptor); - else - rSelector.DeselectPage(pDescriptor); + + +//===== RangeSelector ========================================================= + +namespace { + +RangeSelector::RangeSelector ( + SlideSorter& rSlideSorter, + const Point& rMouseModelPosition) + : MouseMultiSelector(rSlideSorter,rMouseModelPosition), + maAnchor(rMouseModelPosition), + maSecondCorner(rMouseModelPosition), + maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()), + mnAnchorIndex(-1) +{ + const Pointer aSelectionPointer (POINTER_TEXT); + mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer); +} + + + + +RangeSelector::~RangeSelector (void) +{ + mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer); +} + + + + +void RangeSelector::UpdateModelPosition (const Point& rMouseModelPosition) +{ + maSecondCorner = rMouseModelPosition; + UpdateSelection(); +} + + + + +void RangeSelector::UpdateSelection (void) +{ + view::SlideSorterView::DrawLock aLock (mrSlideSorter); + + PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); + + const sal_Int32 nIndexUnderMouse ( + mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint ( + maSecondCorner, + false)); + if (nIndexUnderMouse >= 0) + { + if (mnAnchorIndex < 0) + mnAnchorIndex = nIndexUnderMouse; + mnSecondIndex = nIndexUnderMouse; + + Range aRange (mnAnchorIndex, mnSecondIndex); + aRange.Justify(); + + model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); + for (sal_Int32 nIndex=0,nCount(rModel.GetPageCount()); nIndexHasState(model::PageDescriptor::ST_WasSelected)); + + UpdateSelectionState(pDescriptor, aRange.IsInside(nIndex)); } // Rely on auto scrolling to make page objects visible. @@ -1750,4 +1870,17 @@ void SelectionFunction::RectangleSelector::ProcessRectangleSelection (void) +Rectangle RangeSelector::GetBoundingBox (void) const +{ + return 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())); +} + + +} // end of anonymous namespace + + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 2ce5b11e302a..ff511b60625e 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -356,7 +356,7 @@ void SelectionManager::ResetMakeSelectionVisiblePending (void) */ Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow == NULL) return Size(0,0); @@ -403,7 +403,7 @@ Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow == NULL) return Size(0,0); @@ -519,7 +519,7 @@ void SelectionManager::RemoveSelectionChangeListener(const Link&rListener) bool SelectionManager::DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow == NULL) return true; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx index 4384e1a66d9d..2529915b2fea 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx @@ -206,6 +206,12 @@ private: ::std::vector maFocusChangeListeners; + /** When vertical wrap is active then pressing UP in the top row moves + the focus to the bottom row, DOWN in the bottom row moves the focus + to the top row. + */ + bool mbIsVerticalWrapActive; + /** Reset the focus state of the given descriptor and request a repaint so that the focus indicator is hidden. @param pDescriptor diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx index 514b0ca056a5..006cf0083ed9 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -88,6 +88,7 @@ private: bool mbIsBeforePage; bool mbIsInsertionTrivial; bool mbIsActive; + bool mbIsReadOnly; void SetPosition (const Point& rPoint); ::boost::shared_ptr GetInsertAnimator (void); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx index 0e1edb0576d7..7c1f76bf1407 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx @@ -31,6 +31,8 @@ #ifndef SD_SLIDESORTER_SLIDE_SORTER_SCROLL_BAR_MANAGER_HXX #define SD_SLIDESORTER_SLIDE_SORTER_SCROLL_BAR_MANAGER_HXX +#include "SlideSorter.hxx" + #include #include #include @@ -216,7 +218,7 @@ private: /** The content window is the one whose view port is controlled by the scroll bars. */ - ::boost::shared_ptr mpContentWindow; + SharedSdWindow mpContentWindow; ::boost::function maAutoScrollFunctor; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index bc5f49b12c8b..d1b8fedd1143 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -35,7 +35,6 @@ #include "controller/SlsFocusManager.hxx" #include "fupoor.hxx" #include -//#include #include #include @@ -94,6 +93,8 @@ public: void MouseDragged (const AcceptDropEvent& rEvent); + class MouseMultiSelector; + protected: SlideSorter& mrSlideSorter; SlideSorterController& mrController; @@ -106,7 +107,6 @@ protected: private: class SubstitutionHandler; - class RectangleSelector; class EventDescriptor; /// Set in MouseButtonDown this flag indicates that a page has been hit. @@ -128,7 +128,7 @@ private: bool mbProcessingMouseButtonDown; ::boost::scoped_ptr mpSubstitutionHandler; - ::boost::scoped_ptr mpRectangleSelector; + ::boost::scoped_ptr mpMouseMultiSelector; /** Remember where the left mouse button was pressed. */ diff --git a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx index e9c76e68fd35..e8fed3b423ce 100644 --- a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx @@ -69,6 +69,7 @@ class SlideSorterModel { public: SlideSorterModel (SlideSorter& rSlideSorter); + void Init (void); virtual ~SlideSorterModel (void); void Dispose (void); @@ -193,6 +194,8 @@ public: */ void UpdatePageList (void); + bool IsReadOnly (void) const; + private: mutable ::osl::Mutex maMutex; SlideSorter& mrSlideSorter; diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 6c7c5f735045..4abdfdc328b1 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -70,9 +70,9 @@ namespace sd { namespace slidesorter { namespace view { class LayeredDevice; class Layouter; class PageObjectPainter; +class SelectionPainter; class ViewOverlay; - class SlideSorterView : public sd::View, public ::boost::noncopyable @@ -87,6 +87,7 @@ public: */ SlideSorterView (SlideSorter& rSlideSorter); + void Init (void); virtual ~SlideSorterView (void); void Dispose (void); @@ -179,20 +180,22 @@ public: */ void SetSelectionRectangleVisibility (bool bVisible); - typedef ::std::pair PageRange; /** Return the range of currently visible page objects including the first and last one in that range. @return The returned pair of page object indices is empty when the second index is lower than the first. */ - PageRange GetVisiblePageRange (void); + Pair GetVisiblePageRange (void); /** Add a shape to the page. Typically used from inside PostModelChange(). */ void AddSdrObject (SdrObject& rObject); + void UpdatePageUnderMouse ( + const Point& rMousePosition, + const bool bIsMouseButtonDown); void SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor); void SetButtonUnderMouse (const sal_Int32 nButtonIndex); @@ -220,13 +223,13 @@ protected: private: SlideSorter& mrSlideSorter; model::SlideSorterModel& mrModel; + bool mbIsDisposed; ::std::auto_ptr mpLayouter; bool mbPageObjectVisibilitiesValid; ::boost::shared_ptr mpPreviewCache; ::boost::shared_ptr mpLayeredDevice; ::boost::shared_ptr mpViewOverlay; - int mnFirstVisiblePageIndex; - int mnLastVisiblePageIndex; + Range maVisiblePageRange; bool mbModelChangedWhileModifyEnabled; Size maPreviewSize; bool mbPreciousFlagUpdatePending; @@ -235,6 +238,7 @@ private: model::SharedPageDescriptor mpPageUnderMouse; sal_Int32 mnButtonUnderMouse; ::boost::shared_ptr mpPageObjectPainter; + ::boost::shared_ptr mpSelectionPainter; /** Determine the visibility of all page objects. */ diff --git a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx index b697b157017d..e90fb968ff7e 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx @@ -71,7 +71,7 @@ namespace sd { namespace slidesorter { namespace view { class Layouter { public: - Layouter (const ::boost::shared_ptr< ::Window>& rpWindow); + Layouter (const SharedSdWindow& rpWindow); ~Layouter (void); ::boost::shared_ptr GetPageObjectLayouter (void) const; @@ -216,16 +216,30 @@ public: /** Return the index of the first fully or partially visible page object. This takes into account only the vertical dimension. - */ - sal_Int32 GetIndexOfFirstVisiblePageObject (const Rectangle& rVisibleArea) const; - - /** Return the index of the last fully or partially visible page - object. This takes into account only the vertical dimension. @return - The returned index may be larger than the number of existing + The second index may be larger than the number of existing page objects. */ - sal_Int32 GetIndexOfLastVisiblePageObject (const Rectangle& rVisibleArea) const; + Range GetRangeOfVisiblePageObjects (const Rectangle& rVisibleArea) const; + + /** Return a pair of indices that point to the first and last slide in + the selection delimited by the two given points. The second point + may be located above and/or left of the anchor. + @param rAnchor + Location where the mouse button was pressed and the range + selection started. + @param rOther + Current location of the mouse. + @param rCurrentSelectionRange + Current range of the selection. + @return + The indices are sorted. When the first index is -1 then the + range is empty. + */ + Range GetSelectionRange ( + const Point& rAnchor, + const Point& rOther, + const Range& rCurrentSelectionRange) const; /** Return the index of the page object that is rendered at the given point. @@ -272,8 +286,13 @@ public: const Point& rModelPosition, bool bAllowVerticalPosition) const; + /** Return whether the main orientation of the slides in the slide + sorter is vertical, i.e. all slides are arranged in one column. + */ + bool IsVertical (void) const; + private: - ::boost::shared_ptr< ::Window> mpWindow; + SharedSdWindow mpWindow; sal_Int32 mnRequestedLeftBorder; sal_Int32 mnRequestedRightBorder; sal_Int32 mnRequestedTopBorder; @@ -293,6 +312,7 @@ private: sal_Int32 mnColumnCount; sal_Int32 mnRowCount; Size maPageObjectSize; + bool mbIsVertical; ::boost::shared_ptr mpPageObjectLayouter; diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx index fcd398377b01..65f67efaeb22 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx @@ -56,11 +56,12 @@ public: The page count is used to determine how wide the page number area has to be, how many digits to except for the largest page number. */ - PageObjectLayouter ( + PageObjectLayouter( const Size& rPageObjectWindowSize, const Size& rPreviewModelSize, - const ::boost::shared_ptr< ::Window>& rpWindow, - const int nPageCount); + const SharedSdWindow& rpWindow, + const sal_Int32 nPageCount); + ~PageObjectLayouter(void); enum Part { // This is the outer bounding box that includes the preview, page @@ -70,10 +71,6 @@ public: Preview, // Bounding box of the mouse indicator indicator frame. MouseOverIndicator, - // Bounding box of the focus indicator frame. - FocusIndicator, - // Bounding box of the selection indicator frame. - SelectionIndicator, // Bounding box of the page number. PageNumber, // Bounding box of the pane name. @@ -107,7 +104,9 @@ public: This device is used to translate between model and window coordinates. @param rpPageDescriptor - The page for which to calculate the bounding box. + The page for which to calculate the bounding box. This may be + NULL. When it is NULL then a generic bounding box is calculated + for the location (0,0). @param ePart The part of the page object for which to return the bounding box. @@ -141,26 +140,19 @@ public: const Point& rWindowLocation); private: - /// Gap between border of page object and inside of selection rectangle. - static const sal_Int32 mnSelectionIndicatorOffset; - /// Thickness of the selection rectangle. - static const sal_Int32 mnSelectionIndicatorThickness; - /// Gap between border of page object and inside of focus rectangle. - static const sal_Int32 mnFocusIndicatorOffset; /// Minimal border around the page number area. static const sal_Int32 mnPageNumberOffset; static const sal_Int32 mnOuterBorderWidth; + static const sal_Int32 mnInfoAreaMinWidth; static const Size maButtonSize; static const sal_Int32 mnButtonGap; - const ::boost::shared_ptr< ::Window> mpWindow; + SharedSdWindow mpWindow; Size maPageObjectSize; double mnModelToWindowScale; Rectangle maPageObjectBoundingBox; Rectangle maPageNumberAreaBoundingBox; Rectangle maPreviewBoundingBox; - Rectangle maFocusIndicatorBoundingBox; - Rectangle maSelectionIndicatorBoundingBox; Rectangle maTransitionEffectBoundingBox; Rectangle maButtonAreaBoundingBox; const Image maTransitionEffectIcon; @@ -169,7 +161,7 @@ private: Rectangle CalculatePreviewBoundingBox ( Size& rPageObjectSize, const Size& rPreviewModelSize, - const Size& rPageNumberAreaSize); + const sal_Int32 nInfoAreaWidth); }; diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index b67e6cb3969f..36a7dde48eae 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -39,6 +39,8 @@ #include "SlideSorter.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlsLayouter.hxx" +#include "view/SlsTheme.hxx" +#include namespace sd { namespace slidesorter { namespace cache { class PageCache; } } } @@ -47,24 +49,35 @@ namespace sd { namespace slidesorter { namespace view { class Layouter; class PageObjectLayouter; +namespace { class FramePainter; } + + class PageObjectPainter { public: PageObjectPainter (const SlideSorter& rSlideSorter); + ~PageObjectPainter (void); void PaintPageObject ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor); + void NotifyResize (void); + private: const Layouter& mrLayouter; ::boost::shared_ptr mpPageObjectLayouter; ::boost::shared_ptr mpCache; ::boost::shared_ptr mpProperties; - ::boost::scoped_ptr mpFont; + ::boost::shared_ptr mpTheme; + ::boost::shared_ptr mpPageNumberFont; BitmapEx maStartPresentationIcon; BitmapEx maShowSlideIcon; BitmapEx maNewSlideIcon; + ::boost::scoped_ptr mpShadowPainter; + Bitmap maNormalBackground; + Bitmap maSelectionBackground; + Bitmap maMouseOverBackground; void PaintBackground ( OutputDevice& rDevice, @@ -81,8 +94,10 @@ private: void PaintButtons ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const; - - ColorData GetColorForVisualState (const model::SharedPageDescriptor& rpDescriptor) const; + void PrepareBackgrounds (OutputDevice& rDevice); + Bitmap CreateBackgroundBitmap( + const OutputDevice& rReferenceDevice, + const Theme::ColorType eType) const; }; } } } // end of namespace sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx new file mode 100644 index 000000000000..6eed762a0c44 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_THEME_HXX +#define SD_SLIDESORTER_VIEW_THEME_HXX + +#include "model/SlsVisualState.hxx" + +#include +#include +#include +#include + +#include + + +namespace sd { namespace slidesorter { namespace controller { +class Properties; +} } } + +namespace sd { namespace slidesorter { namespace view { + + +/** Collection of colors and styles that are used to paint the slide sorter + view. +*/ +class Theme +{ +public: + Theme (const ::boost::shared_ptr& rpProperties); + + /** Call this method to update some colors as response to a change of + a system color change. + */ + void Update (const ::boost::shared_ptr& rpProperties); + + BitmapEx GetInsertIndicatorIcon (void) const; + + enum FontType { PageNumberFont }; + ::boost::shared_ptr CreateFont ( + const FontType eType, + OutputDevice& rDevice) const; + + ColorData GetColorForVisualState (const model::VisualState::State eState) const; + + enum ColorType { + Background, + ButtonBackground, + MouseOverColor, + PageNumberBorder, + Selection, + NormalPage, + SelectedPage, + MouseOverPage + }; + enum ColorClass { Border1, Border2, Fill1, Fill2, Other }; + ColorData GetColor (const ColorType eType, const ColorClass eClass = Other); + + enum IconType { + InsertionIndicator, + RawShadow + }; + BitmapEx GetIcon (const IconType eType); + +private: + ColorData maBackgroundColor; + BitmapEx maRawShadow; + BitmapEx maInsertionIndicator; +}; + + +} } } // 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 index 2e141ad6b9be..911160501935 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx @@ -235,10 +235,7 @@ private: index. */ bool mbIsBeforePage; - ImageList maIcons; - Image maIconWithBorder; - Image maIcon; - Image maMask; + BitmapEx maIcon; void SetPositionAndSize (const Rectangle& rBoundingBox); }; diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx index 553737d1493d..f60b8494edfd 100644 --- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx +++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx @@ -48,6 +48,7 @@ #include "ViewShellBase.hxx" #include "DrawViewShell.hxx" +#include "DrawDocShell.hxx" #include "drawdoc.hxx" #include "sdpage.hxx" #include "FrameView.hxx" @@ -93,6 +94,13 @@ SlideSorterModel::~SlideSorterModel (void) +void SlideSorterModel::Init (void) +{ +} + + + + void SlideSorterModel::Dispose (void) { ClearDescriptorList (); @@ -493,4 +501,18 @@ void SlideSorterModel::AdaptSize (void) maPageDescriptors.resize(0); } + + + +bool SlideSorterModel::IsReadOnly (void) const +{ + if (mrSlideSorter.GetViewShellBase() != NULL + && mrSlideSorter.GetViewShellBase()->GetDocShell()) + return mrSlideSorter.GetViewShellBase()->GetDocShell()->IsReadOnly(); + else + return true; +} + + + } } } // end of namespace ::sd::slidesorter::model diff --git a/sd/source/ui/slidesorter/model/SlsVisualState.cxx b/sd/source/ui/slidesorter/model/SlsVisualState.cxx index d6b3deecea5b..c900403eed84 100644 --- a/sd/source/ui/slidesorter/model/SlsVisualState.cxx +++ b/sd/source/ui/slidesorter/model/SlsVisualState.cxx @@ -52,8 +52,12 @@ VisualState::VisualState (const sal_Int32 nPageId) VisualState::~VisualState (void) { - OSL_ASSERT(mnStateAnimationId == controller::Animator::NotAnAnimationId); - OSL_ASSERT(mnLocationAnimationId == controller::Animator::NotAnAnimationId); + if (mnStateAnimationId != controller::Animator::NotAnAnimationId + || mnLocationAnimationId != controller::Animator::NotAnAnimationId) + { + OSL_ASSERT(mnStateAnimationId == controller::Animator::NotAnAnimationId); + OSL_ASSERT(mnLocationAnimationId == controller::Animator::NotAnAnimationId); + } } diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx index 2e42f5672d6a..8fe45e5e0cf7 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorter.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -38,6 +38,7 @@ #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsProperties.hxx" #include "view/SlideSorterView.hxx" +#include "view/SlsTheme.hxx" #include "model/SlideSorterModel.hxx" #include "glob.hrc" @@ -136,11 +137,13 @@ SlideSorter::SlideSorter ( mpViewShell(&rViewShell), mpViewShellBase(&rViewShell.GetViewShellBase()), mpContentWindow(rpContentWindow), + mbOwnesContentWindow(false), mpHorizontalScrollBar(rpHorizontalScrollBar), mpVerticalScrollBar(rpVerticalScrollBar), mpScrollBarBox(rpScrollBarBox), mbLayoutPending(true), - mpProperties(new controller::Properties()) + mpProperties(new controller::Properties()), + mpTheme(new view::Theme(mpProperties)) { } @@ -159,11 +162,13 @@ SlideSorter::SlideSorter ( mpViewShell(pViewShell), mpViewShellBase(&rBase), mpContentWindow(new ContentWindow(rParentWindow,*this )), + mbOwnesContentWindow(true), mpHorizontalScrollBar(new ScrollBar(&rParentWindow,WinBits(WB_HSCROLL | WB_DRAG))), mpVerticalScrollBar(new ScrollBar(&rParentWindow,WinBits(WB_VSCROLL | WB_DRAG))), mpScrollBarBox(new ScrollBarBox(&rParentWindow)), mbLayoutPending(true), - mpProperties(new controller::Properties()) + mpProperties(new controller::Properties()), + mpTheme(new view::Theme(mpProperties)) { } @@ -194,7 +199,7 @@ void SlideSorter::Init (void) SetupListeners (); // Initialize the window. - ::boost::shared_ptr pWindow (GetContentWindow()); + SharedSdWindow pWindow (GetContentWindow()); if (pWindow != NULL) { ::Window* pParentWindow = pWindow->GetParent(); @@ -213,6 +218,7 @@ void SlideSorter::Init (void) mbIsValid = true; } + } @@ -238,8 +244,17 @@ SlideSorter::~SlideSorter (void) mpHorizontalScrollBar.reset(); mpVerticalScrollBar.reset(); mpScrollBarBox.reset(); - OSL_ASSERT(mpContentWindow.unique()); - OSL_ASSERT(mpContentWindow.use_count()==1); + + if (mbOwnesContentWindow) + { + OSL_ASSERT(mpContentWindow.unique()); + } + else + { + // Assume that outside this class only the owner holds a reference + // to the content window. + OSL_ASSERT(mpContentWindow.use_count()==2); + } mpContentWindow.reset(); } @@ -325,7 +340,7 @@ void SlideSorter::Paint (const Rectangle& rRepaintArea) -::boost::shared_ptr SlideSorter::GetContentWindow (void) const +::SharedSdWindow SlideSorter::GetContentWindow (void) const { return mpContentWindow; } @@ -360,7 +375,7 @@ void SlideSorter::SetupControls (::Window* ) void SlideSorter::SetupListeners (void) { - ::boost::shared_ptr pWindow (GetContentWindow()); + SharedSdWindow pWindow (GetContentWindow()); if (pWindow) { ::Window* pParentWindow = pWindow->GetParent(); @@ -392,7 +407,7 @@ void SlideSorter::ReleaseListeners (void) { mpSlideSorterController->GetScrollBarManager().Disconnect(); - ::boost::shared_ptr pWindow (GetContentWindow()); + SharedSdWindow pWindow (GetContentWindow()); if (pWindow) { @@ -430,7 +445,12 @@ void SlideSorter::CreateModelViewController (void) mpSlideSorterController.reset(CreateController()); DBG_ASSERT (mpSlideSorterController.get()!=NULL, "Can not create controller for slide browser"); + + // Now that model, view, and controller are constructed, do the + // initialization that relies on all three being in place. + mpSlideSorterModel->Init(); mpSlideSorterController->Init(); + mpSlideSorterView->Init(); } @@ -551,9 +571,8 @@ void SlideSorter::SetCurrentFunction (const FunctionReference& rpFunction) } else { - ::boost::shared_ptr pWindow - = ::boost::dynamic_pointer_cast(GetContentWindow()); - if (pWindow.get() != NULL) + ContentWindow* pWindow = dynamic_cast(GetContentWindow().get()); + if (pWindow != NULL) pWindow->SetCurrentFunction(rpFunction); } } @@ -563,12 +582,22 @@ void SlideSorter::SetCurrentFunction (const FunctionReference& rpFunction) ::boost::shared_ptr SlideSorter::GetProperties (void) const { + OSL_ASSERT(mpProperties); return mpProperties; } +::boost::shared_ptr SlideSorter::GetTheme (void) const +{ + OSL_ASSERT(mpTheme); + return mpTheme; +} + + + + //===== ContentWindow ========================================================= namespace { @@ -667,4 +696,7 @@ long ContentWindow::Notify (NotifyEvent& rEvent) } // end of anonymous namespace + + + } } // end of namespace ::sd::slidesorter diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 194cf0f0ab83..97d2b563906d 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -191,7 +191,7 @@ void SlideSorterViewShell::Initialize (void) // 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.) - ::boost::shared_ptr pWindow (mpSlideSorter->GetContentWindow()); + SharedSdWindow pWindow (mpSlideSorter->GetContentWindow()); if (pWindow) { pWindow->Hide(); @@ -549,6 +549,23 @@ void SlideSorterViewShell::ArrangeGUIElements (void) +bool SlideSorterViewShell::HandleScrollCommand (const CommandEvent& rEvent, ::sd::Window* pWindow) +{ + bool bDone = ViewShell::HandleScrollCommand(rEvent, pWindow); + + if (bDone) + { + OSL_ASSERT(mpSlideSorter.get()!=NULL); + if (rEvent.GetCommand() == COMMAND_WHEEL) + mpSlideSorter->GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false); + } + + return bDone; +} + + + + SvBorder SlideSorterViewShell::GetBorder (bool ) { OSL_ASSERT(mpSlideSorter.get()!=NULL); diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 410971abf664..ec3a83202e56 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -38,6 +38,7 @@ #include "ViewShell.hxx" #include "SlsViewCacheContext.hxx" #include "SlsLayeredDevice.hxx" +#include "SlsSelectionPainter.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsPageObjectLayouter.hxx" #include "view/SlsPageObjectPainter.hxx" @@ -82,6 +83,7 @@ #include #include #include +#include #include @@ -131,22 +133,24 @@ public: maColor(GetColor()), mnLocalTime(-nStartTime), mnValue(0), - mnStartTime(nStartTime) + mnStartTime(nStartTime), + mbIsValid(rWindowSize.Width()>10 && rWindowSize.Height()>10), + mnSpeedUp(0.5 + rand() * 1.0 / RAND_MAX) { } void SetTime (const double nTime) { - mnLocalTime = nTime - mnStartTime; - if (mnLocalTime >= 0 && mnLocalTime <= 1) - mnValue = controller::AnimationFunction::SlowInSlowOut_0to0_Sine(mnLocalTime); + mnLocalTime = (nTime - mnStartTime) * mnSpeedUp; + if (mnLocalTime >= 0 && mnLocalTime <= mnSpeedUp) + mnValue = controller::AnimationFunction::SlowInSlowOut_0to0_Sine(mnLocalTime/mnSpeedUp); else mnValue = 0; } bool IsExpired (void) { - return mnLocalTime >= 1.0; + return mnLocalTime >= mnSpeedUp || ! mbIsValid; } Rectangle GetBoundingBox (void) @@ -165,7 +169,7 @@ public: void Paint (OutputDevice& rDevice) { - if (mnLocalTime < 0) + if (mnLocalTime < 0 || ! mbIsValid) return; rDevice.SetFillColor(maColor); @@ -191,6 +195,8 @@ private: double mnLocalTime; double mnValue; const double mnStartTime; + const bool mbIsValid; + const double mnSpeedUp; static Color GetColor (void) { @@ -213,7 +219,7 @@ class BackgroundPainter public: BackgroundPainter ( const ::boost::shared_ptr& rpAnimator, - const ::boost::shared_ptr< ::Window>& rpWindow, + const SharedSdWindow& rpWindow, const Color aBackgroundColor, const bool bIsAnimated) : mpAnimator(rpAnimator), @@ -235,7 +241,8 @@ public: ~BackgroundPainter (void) { - mpAnimator->RemoveAnimation(mnAnimationId); + if (mnAnimationId >= 0) + mpAnimator->RemoveAnimation(mnAnimationId); } virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) @@ -288,7 +295,7 @@ private: typedef ::std::vector< ::boost::shared_ptr > SphereVector; SphereVector maSpheres; SharedILayerInvalidator mpInvalidator; - ::boost::shared_ptr< ::Window> mpWindow; + SharedSdWindow mpWindow; controller::Animator::AnimationId mnAnimationId; void Invalidate (void) @@ -316,13 +323,13 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) rSlideSorter.GetViewShell()), mrSlideSorter(rSlideSorter), mrModel(rSlideSorter.GetModel()), + mbIsDisposed(false), mpLayouter (new Layouter (rSlideSorter.GetContentWindow())), mbPageObjectVisibilitiesValid (false), mpPreviewCache(), mpLayeredDevice(new LayeredDevice(rSlideSorter.GetContentWindow())), mpViewOverlay (new ViewOverlay(rSlideSorter, mpLayeredDevice)), - mnFirstVisiblePageIndex(0), - mnLastVisiblePageIndex(-1), + maVisiblePageRange(-1,-1), mbModelChangedWhileModifyEnabled(true), maPreviewSize(0,0), mbPreciousFlagUpdatePending(true), @@ -330,8 +337,11 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) mpProperties(rSlideSorter.GetProperties()), mpPageUnderMouse(), mnButtonUnderMouse(-1), - mpPageObjectPainter() + mpPageObjectPainter(), + mpSelectionPainter() { + OSL_TRACE("layered device at %x", mpLayeredDevice.get()); + // Hide the page that contains the page objects. SetPageVisible (FALSE); @@ -340,7 +350,8 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) // the SlideSorterView destructor the layered device is destroyed and // with it the only reference to the wrapper which therefore is also // destroyed. - mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 1); + OSL_TRACE("layered device at %x", mpLayeredDevice.get()); + mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 2); } @@ -348,8 +359,32 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) SlideSorterView::~SlideSorterView (void) { - mpLayeredDevice->Dispose(); + if ( ! mbIsDisposed) + { + OSL_ASSERT(mbIsDisposed); + Dispose(); + } +} + + + + +void SlideSorterView::Init (void) +{ + HandleModelChange(); + + // mpSelectionPainter.reset(new SelectionPainter(mrSlideSorter)); + // mpLayeredDevice->RegisterPainter(mpSelectionPainter, 1); +} + + + +void SlideSorterView::Dispose (void) +{ + mpSelectionPainter.reset(); + + mpLayeredDevice->Dispose(); mpPreviewCache.reset(); // hide the page to avoid problems in the view when deleting @@ -364,13 +399,8 @@ SlideSorterView::~SlideSorterView (void) OSL_ASSERT(mpLayeredDevice.unique()); mpLayeredDevice.reset(); -} - - - -void SlideSorterView::Dispose (void) -{ + mbIsDisposed = true; } @@ -380,7 +410,7 @@ sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rPosition) const { sal_Int32 nIndex (-1); - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { nIndex = mpLayouter->GetIndexAtPoint (pWindow->PixelToLogic (rPosition)); @@ -401,7 +431,7 @@ sal_Int32 SlideSorterView::GetFadePageIndexAtPoint ( { sal_Int32 nIndex (-1); - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { Point aModelPosition (pWindow->PixelToLogic (rPosition)); @@ -537,12 +567,12 @@ void SlideSorterView::Resize (void) SharedILayerPainter(new BackgroundPainter( mrSlideSorter.GetController().GetAnimator(), mrSlideSorter.GetContentWindow(), - Color(0xf9fafa),//mpProperties->GetBackgroundColor(), + mrSlideSorter.GetTheme()->GetColor(Theme::Background), false)), 0); mpLayeredDevice->Resize(); - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (mrModel.GetPageCount()>0 && pWindow) { bool bRearrangeSuccess (false); @@ -564,6 +594,7 @@ void SlideSorterView::Resize (void) if (bRearrangeSuccess) { Layout(); + RequestRepaint(); } } } @@ -573,7 +604,7 @@ void SlideSorterView::Resize (void) void SlideSorterView::Layout () { - const ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { // Set the model area, i.e. the smallest rectangle that includes all @@ -589,7 +620,7 @@ void SlideSorterView::Layout () const Size aNewPreviewSize (mpLayouter->GetPageObjectLayouter()->GetPreviewSize()); if (maPreviewSize != aNewPreviewSize && GetPreviewCache()) { - mpPreviewCache->ChangeSize(aNewPreviewSize, false); + mpPreviewCache->ChangeSize(aNewPreviewSize, true); maPreviewSize = aNewPreviewSize; } } @@ -603,6 +634,8 @@ void SlideSorterView::Layout () model::SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); pDescriptor->SetBoundingBox(mpLayouter->GetPageObjectBox(pDescriptor->GetPageIndex())); } + + GetPageObjectPainter()->NotifyResize(); } InvalidatePageObjectVisibilities (); @@ -621,7 +654,7 @@ void SlideSorterView::InvalidatePageObjectVisibilities (void) void SlideSorterView::DeterminePageObjectVisibilities (void) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { // Set this flag to true here so that an invalidate during the @@ -629,28 +662,27 @@ void SlideSorterView::DeterminePageObjectVisibilities (void) mbPageObjectVisibilitiesValid = true; Rectangle aViewArea (pWindow->PixelToLogic(Rectangle(Point(0,0),pWindow->GetSizePixel()))); - const int nFirstIndex (mpLayouter->GetIndexOfFirstVisiblePageObject(aViewArea)); - const int nLastIndex (mpLayouter->GetIndexOfLastVisiblePageObject(aViewArea)); - const int nMinIndex (::std::min (mnFirstVisiblePageIndex, nFirstIndex)); - const int nMaxIndex (::std::max (mnLastVisiblePageIndex, nLastIndex)); + const Range aRange (mpLayouter->GetRangeOfVisiblePageObjects(aViewArea)); + const Range aUnion( + ::std::min(maVisiblePageRange.Min(), aRange.Min()), + ::std::max(maVisiblePageRange.Max(), aRange.Max())); // For page objects that just dropped off the visible area we // decrease the priority of pending requests for preview bitmaps. - if (mnFirstVisiblePageIndex!=nFirstIndex || mnLastVisiblePageIndex!=nLastIndex) + if (maVisiblePageRange != aRange) mbPreciousFlagUpdatePending |= true; model::SharedPageDescriptor pDescriptor; - for (int nIndex=nMinIndex; nIndex<=nMaxIndex; nIndex++) + for (int nIndex=aUnion.Min(); nIndex<=aUnion.Max(); nIndex++) { pDescriptor = mrModel.GetPageDescriptor(nIndex); if (pDescriptor.get() != NULL) SetState( pDescriptor, PageDescriptor::ST_Visible, - nIndex>=nFirstIndex && nIndex<=nLastIndex); + aRange.IsInside(nIndex)); } - mnFirstVisiblePageIndex = nFirstIndex; - mnLastVisiblePageIndex = nLastIndex; + maVisiblePageRange = aRange; } } @@ -674,9 +706,9 @@ void SlideSorterView::UpdatePreciousFlags (void) { pCache->SetPreciousFlag( pDescriptor->GetPage(), - (nIndex>=mnFirstVisiblePageIndex && nIndex<=mnLastVisiblePageIndex)); + maVisiblePageRange.IsInside(nIndex)); SSCD_SET_VISIBILITY(mrModel.GetDocument(), nIndex, - (nIndex>=mnFirstVisiblePageIndex && nIndex<=mnLastVisiblePageIndex)); + maVisiblePageRange.IsInside(nIndex)); } else { @@ -711,7 +743,7 @@ SlideSorterView::Orientation SlideSorterView::GetOrientation (void) const void SlideSorterView::RequestRepaint (void) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { pWindow->Invalidate(); @@ -735,7 +767,7 @@ void SlideSorterView::RequestRepaint (const model::SharedPageDescriptor& rpDescr void SlideSorterView::RequestRepaint (const Rectangle& rRepaintBox) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { pWindow->Invalidate(rRepaintBox); @@ -752,6 +784,7 @@ Rectangle SlideSorterView::GetModelArea (void) } +static ::canvas::tools::ElapsedTime gaTimer; void SlideSorterView::CompleteRedraw ( @@ -759,6 +792,11 @@ void SlideSorterView::CompleteRedraw ( const Region& rPaintArea, sdr::contact::ViewObjectContactRedirector* pRedirector) { + const double nStartTime (gaTimer.getElapsedTime()); + OSL_TRACE("SlideSorterView::CompleteRedraw start at %f, %d", + nStartTime, + mnLockRedrawSmph); + if (pDevice == NULL || pDevice!=mrSlideSorter.GetContentWindow().get()) return; @@ -778,6 +816,9 @@ void SlideSorterView::CompleteRedraw ( { View::CompleteRedraw(pDevice, rPaintArea, pRedirector); } + + const double nEndTime (gaTimer.getElapsedTime()); + OSL_TRACE("SlideSorterView::CompleteRedraw end at %f after %fms", nEndTime, (nEndTime-nStartTime)*1000); } @@ -800,11 +841,8 @@ void SlideSorterView::Paint ( // Paint all page objects that are fully or partially inside the // repaint region. - sal_Int32 nFirst (mpLayouter->GetIndexOfFirstVisiblePageObject(rRepaintArea)); - sal_Int32 nLast (std::min( - mpLayouter->GetIndexOfLastVisiblePageObject(rRepaintArea), - mrModel.GetPageCount())); - for (sal_Int32 nIndex=nFirst; nIndex<=nLast; ++nIndex) + const Range aRange (mpLayouter->GetRangeOfVisiblePageObjects(rRepaintArea)); + for (sal_Int32 nIndex=aRange.Min(); nIndex<=aRange.Max(); ++nIndex) { model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex)); if (!pDescriptor || ! pDescriptor->HasState(PageDescriptor::ST_Visible)) @@ -819,7 +857,7 @@ void SlideSorterView::Paint ( ::boost::shared_ptr SlideSorterView::GetPreviewCache (void) { - ::boost::shared_ptr pWindow (mrSlideSorter.GetContentWindow()); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow && mpPreviewCache.get() == NULL) { mpPreviewCache.reset( @@ -843,14 +881,11 @@ ViewOverlay& SlideSorterView::GetOverlay (void) -SlideSorterView::PageRange SlideSorterView::GetVisiblePageRange (void) +Pair SlideSorterView::GetVisiblePageRange (void) { - const int nMaxPageIndex (mrModel.GetPageCount() - 1); if ( ! mbPageObjectVisibilitiesValid) DeterminePageObjectVisibilities(); - return PageRange( - ::std::min(mnFirstVisiblePageIndex,nMaxPageIndex), - ::std::min(mnLastVisiblePageIndex, nMaxPageIndex)); + return maVisiblePageRange; } @@ -868,6 +903,37 @@ void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint +void SlideSorterView::UpdatePageUnderMouse ( + const Point& rMousePosition, + const bool bIsMouseButtonDown) +{ + // Determine page under mouse and show the mouse over effect. + model::SharedPageDescriptor pHitDescriptor ( + mrSlideSorter.GetController().GetPageAt(rMousePosition)); + SetPageUnderMouse(pHitDescriptor); + + // Handle the mouse being over any buttons. + if (pHitDescriptor) + { + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + const sal_Int32 nButtonIndex ( + GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt ( + pHitDescriptor, + aMouseModelPosition)); + SetButtonUnderMouse(nButtonIndex); + if (bIsMouseButtonDown) + { + pHitDescriptor->GetVisualState().SetActiveButtonState( + nButtonIndex, + model::VisualState::BS_Pressed); + } + } +} + + + + void SlideSorterView::SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor) { if (mpPageUnderMouse != rpDescriptor) diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hrc b/sd/source/ui/slidesorter/view/SlsIcons.hrc index c174252aa7ce..cb0fe634f501 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.hrc +++ b/sd/source/ui/slidesorter/view/SlsIcons.hrc @@ -42,4 +42,6 @@ #define IMAGE_SHOW_SLIDE 5 #define IMAGE_NEW_SLIDE 6 +#define IMAGE_SHADOW 10 + #endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.src b/sd/source/ui/slidesorter/view/SlsIcons.src index c3f68cde7436..facd4138b574 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.src +++ b/sd/source/ui/slidesorter/view/SlsIcons.src @@ -62,4 +62,8 @@ Resource IMG_ICONS ImageBitmap = Bitmap { File = "commandimagelist/lc_insertpage.png" ; }; }; + Image IMAGE_SHADOW + { + ImageBitmap = Bitmap { File = "slide_sorter_shadow.png" ; }; + }; }; diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx index e76728e95c1c..aba967ebdeda 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx @@ -50,7 +50,7 @@ class LayerInvalidator : public ILayerInvalidator public: LayerInvalidator ( const ::boost::shared_ptr& rpLayeredDevice, - const ::boost::shared_ptr< ::Window>& rpTargetWindow, + const SharedSdWindow& rpTargetWindow, const int nLayer) : mpLayeredDevice(rpLayeredDevice), mpTargetWindow(rpTargetWindow), @@ -66,7 +66,7 @@ public: private: const ::boost::shared_ptr mpLayeredDevice; - const ::boost::shared_ptr< ::Window> mpTargetWindow; + SharedSdWindow mpTargetWindow; const int mnLayer; }; @@ -103,18 +103,56 @@ void ForAllRectangles (const Region& rRegion, ::boost::function mpLayerDevice; + ::std::vector maPainters; + Region maInvalidationRegion; + + void ValidateRectangle (const Rectangle& rBox); +}; +typedef ::boost::shared_ptr SharedLayer; + } // end of anonymous namespace +class LayeredDevice::LayerContainer : public ::std::vector +{ +public: + LayerContainer (void) { OSL_TRACE("created layer container at %x", this); } + ~LayerContainer (void) { OSL_TRACE("destroyed layer container at %x", this); } +}; + + -LayeredDevice::LayeredDevice (const ::boost::shared_ptr< ::Window>& rpTargetWindow) +//===== LayeredDevice ========================================================= + +LayeredDevice::LayeredDevice (const SharedSdWindow& rpTargetWindow) : mpTargetWindow(rpTargetWindow), - maLayers(1), + mpLayers(new LayerContainer()), mpBackBuffer(new VirtualDevice(*mpTargetWindow)), maSavedMapMode(rpTargetWindow->GetMapMode()) { + OSL_TRACE("layered device created at %x", this); mpBackBuffer->SetOutputSizePixel(mpTargetWindow->GetSizePixel()); } @@ -123,6 +161,7 @@ LayeredDevice::LayeredDevice (const ::boost::shared_ptr< ::Window>& rpTargetWind LayeredDevice::~LayeredDevice (void) { + OSL_TRACE("layered device destroyed at %x", this); } @@ -132,13 +171,13 @@ void LayeredDevice::Invalidate ( const Rectangle& rInvalidationArea, const sal_Int32 nLayer) { - if (nLayer<0 || sal_uInt32(nLayer)>=maLayers.size()) + if (nLayer<0 || sal_uInt32(nLayer)>=mpLayers->size()) { - OSL_ASSERT(nLayer>=0 && nLayer=0 && nLayersize()); return; } - maLayers[nLayer].Invalidate(rInvalidationArea); + (*mpLayers)[nLayer]->Invalidate(rInvalidationArea); } @@ -146,8 +185,8 @@ void LayeredDevice::Invalidate ( void LayeredDevice::InvalidateAllLayers (const Rectangle& rInvalidationArea) { - for (sal_uInt32 nLayer=0; nLayersize(); ++nLayer) + (*mpLayers)[nLayer]->Invalidate(rInvalidationArea); } @@ -157,6 +196,8 @@ void LayeredDevice::RegisterPainter ( const SharedILayerPainter& rpPainter, const sal_Int32 nLayer) { + OSL_TRACE("layered device registering painter at %x", this); + OSL_ASSERT(mpLayers); if ( ! rpPainter) { OSL_ASSERT(rpPainter); @@ -168,11 +209,19 @@ void LayeredDevice::RegisterPainter ( return; } - if (sal_uInt32(nLayer) >= maLayers.size()) - maLayers.resize(nLayer+1); - maLayers[nLayer].AddPainter(rpPainter); + // Provide the layers. + if (sal_uInt32(nLayer) >= mpLayers->size()) + { + const sal_Int32 nOldLayerCount (mpLayers->size()); + mpLayers->resize(nLayer+1); + + for (sal_Int32 nIndex=nOldLayerCount; nIndexsize(); ++nIndex) + (*mpLayers)[nIndex].reset(new Layer()); + } + + (*mpLayers)[nLayer]->AddPainter(rpPainter); if (nLayer == 0) - maLayers[nLayer].Initialize(mpTargetWindow); + (*mpLayers)[nLayer]->Initialize(mpTargetWindow); rpPainter->SetLayerInvalidator( SharedILayerInvalidator(new LayerInvalidator(shared_from_this(),mpTargetWindow,nLayer))); @@ -190,19 +239,19 @@ void LayeredDevice::RemovePainter ( OSL_ASSERT(rpPainter); return; } - if (nLayer<0 || sal_uInt32(nLayer)>=maLayers.size()) + if (nLayer<0 || sal_uInt32(nLayer)>=mpLayers->size()) { - OSL_ASSERT(nLayer>=0 && nLayer=0 && nLayersize()); return; } rpPainter->SetLayerInvalidator(SharedILayerInvalidator()); - maLayers[nLayer].RemovePainter(rpPainter); + (*mpLayers)[nLayer]->RemovePainter(rpPainter); // Remove top most layers that do not contain any painters. - while ( ! maLayers.empty() && ! maLayers.back().HasPainter()) - maLayers.erase(maLayers.end()-1); + while ( ! mpLayers->empty() && ! mpLayers->back()->HasPainter()) + mpLayers->erase(mpLayers->end()-1); } @@ -211,8 +260,8 @@ void LayeredDevice::RemovePainter ( bool LayeredDevice::HasPainter (const sal_Int32 nLayer) { return nLayer>=0 - && sal_uInt32(nLayer)size() + && (*mpLayers)[nLayer]->HasPainter(); } @@ -224,8 +273,8 @@ void LayeredDevice::Repaint (const Region& rRepaintRegion) // Validate the contents of all layers (that have their own devices.) ::std::for_each( - maLayers.begin(), - maLayers.end(), + mpLayers->begin(), + mpLayers->end(), ::boost::bind(&Layer::Validate, _1, mpTargetWindow->GetMapMode())); ForAllRectangles(rRepaintRegion, ::boost::bind(&LayeredDevice::RepaintRectangle, this, _1)); @@ -236,10 +285,10 @@ void LayeredDevice::Repaint (const Region& rRepaintRegion) void LayeredDevice::RepaintRectangle (const Rectangle& rRepaintRectangle) { - if (maLayers.size() <= 1) + if (mpLayers->size() <= 1) { // Just copy the main layer into the target device. - maLayers[0].Repaint(*mpTargetWindow, rRepaintRectangle); + (*mpLayers)[0]->Repaint(*mpTargetWindow, rRepaintRectangle); } else { @@ -248,8 +297,8 @@ void LayeredDevice::RepaintRectangle (const Rectangle& rRepaintRectangle) // device. mpBackBuffer->SetMapMode(mpTargetWindow->GetMapMode()); ::std::for_each( - maLayers.begin(), - maLayers.end(), + mpLayers->begin(), + mpLayers->end(), ::boost::bind(&Layer::Repaint, _1, ::boost::ref(*mpBackBuffer), rRepaintRectangle)); DeviceCopy(*mpTargetWindow, *mpBackBuffer, rRepaintRectangle); @@ -263,7 +312,7 @@ void LayeredDevice::Resize (void) { const Size aSize (mpTargetWindow->GetSizePixel()); mpBackBuffer->SetOutputSizePixel(aSize); - ::std::for_each(maLayers.begin(), maLayers.end(), ::boost::bind(&Layer::Resize, _1, aSize)); + ::std::for_each(mpLayers->begin(), mpLayers->end(), ::boost::bind(&Layer::Resize, _1, aSize)); } @@ -271,8 +320,8 @@ void LayeredDevice::Resize (void) void LayeredDevice::Dispose (void) { - ::std::for_each(maLayers.begin(), maLayers.end(), ::boost::bind(&Layer::Dispose, _1)); - maLayers.clear(); + ::std::for_each(mpLayers->begin(), mpLayers->end(), ::boost::bind(&Layer::Dispose, _1)); + mpLayers->clear(); } @@ -292,8 +341,8 @@ void LayeredDevice::HandleMapModeChange (void) { // When the scale has changed then we have to paint everything. ::std::for_each( - maLayers.begin(), - maLayers.end(), + mpLayers->begin(), + mpLayers->end(), ::boost::bind(&Layer::Invalidate, _1, ::boost::cref(aLogicWindowBox))); } else if (maSavedMapMode.GetOrigin() != rMapMode.GetOrigin()) @@ -330,9 +379,9 @@ void LayeredDevice::HandleMapModeChange (void) -//===== LayeredDevice::Layer ================================================== +//===== Layer ================================================================= -LayeredDevice::Layer::Layer (void) +Layer::Layer (void) : mpLayerDevice(), maPainters(), maInvalidationRegion() @@ -342,7 +391,14 @@ LayeredDevice::Layer::Layer (void) -void LayeredDevice::Layer::Initialize (const ::boost::shared_ptr< ::Window>& rpTargetWindow) +Layer::~Layer (void) +{ +} + + + + +void Layer::Initialize (const SharedSdWindow& rpTargetWindow) { if ( ! mpLayerDevice) { @@ -354,7 +410,7 @@ void LayeredDevice::Layer::Initialize (const ::boost::shared_ptr< ::Window>& rpT -void LayeredDevice::Layer::Invalidate (const Rectangle& rInvalidationBox) +void Layer::Invalidate (const Rectangle& rInvalidationBox) { maInvalidationRegion.Union(rInvalidationBox); } @@ -362,7 +418,7 @@ void LayeredDevice::Layer::Invalidate (const Rectangle& rInvalidationBox) -void LayeredDevice::Layer::Validate (const MapMode& rMapMode) +void Layer::Validate (const MapMode& rMapMode) { if (mpLayerDevice && ! maInvalidationRegion.IsEmpty()) { @@ -370,7 +426,7 @@ void LayeredDevice::Layer::Validate (const MapMode& rMapMode) ForAllRectangles( maInvalidationRegion, - ::boost::bind(&LayeredDevice::Layer::ValidateRectangle, this, _1)); + ::boost::bind(&Layer::ValidateRectangle, this, _1)); } // else nothing to do now. The painting is done in Repaint() directly // into the back buffer. @@ -381,7 +437,7 @@ void LayeredDevice::Layer::Validate (const MapMode& rMapMode) -void LayeredDevice::Layer::ValidateRectangle (const Rectangle& rBox) +void Layer::ValidateRectangle (const Rectangle& rBox) { const Region aSavedClipRegion (mpLayerDevice->GetClipRegion()); mpLayerDevice->SetClipRegion(Region(rBox)); @@ -401,7 +457,7 @@ void LayeredDevice::Layer::ValidateRectangle (const Rectangle& rBox) -void LayeredDevice::Layer::Repaint ( +void Layer::Repaint ( OutputDevice& rTargetDevice, const Rectangle& rRepaintRectangle) { @@ -424,7 +480,7 @@ void LayeredDevice::Layer::Repaint ( -void LayeredDevice::Layer::Resize (const Size& rSize) +void Layer::Resize (const Size& rSize) { if (mpLayerDevice) { @@ -436,7 +492,7 @@ void LayeredDevice::Layer::Resize (const Size& rSize) -void LayeredDevice::Layer::AddPainter (const SharedILayerPainter& rpPainter) +void Layer::AddPainter (const SharedILayerPainter& rpPainter) { OSL_ASSERT(::std::find(maPainters.begin(), maPainters.end(), rpPainter) == maPainters.end()); @@ -446,7 +502,7 @@ void LayeredDevice::Layer::AddPainter (const SharedILayerPainter& rpPainter) -void LayeredDevice::Layer::RemovePainter (const SharedILayerPainter& rpPainter) +void Layer::RemovePainter (const SharedILayerPainter& rpPainter) { const ::std::vector::iterator iPainter ( ::std::find(maPainters.begin(), maPainters.end(), rpPainter)); @@ -463,7 +519,7 @@ void LayeredDevice::Layer::RemovePainter (const SharedILayerPainter& rpPainter) -bool LayeredDevice::Layer::HasPainter (void) const +bool Layer::HasPainter (void) const { return !maPainters.empty(); } @@ -471,7 +527,7 @@ bool LayeredDevice::Layer::HasPainter (void) const -void LayeredDevice::Layer::Dispose (void) +void Layer::Dispose (void) { maPainters.clear(); } diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx index 522355ca303e..3441b30d6739 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx @@ -33,6 +33,7 @@ #define SD_SLIDESORTER_VIEW_LAYERED_DEVICE_HXX #include "view/SlsILayerPainter.hxx" +#include "SlideSorter.hxx" #include #include @@ -53,7 +54,7 @@ class LayeredDevice { public: - LayeredDevice (const ::boost::shared_ptr< ::Window>& rpTargetWindow); + LayeredDevice (const SharedSdWindow& rpTargetWindow); ~LayeredDevice (void); void Invalidate ( @@ -78,33 +79,10 @@ public: void Dispose (void); - class Layer - { - public: - Layer (void); - - void Initialize (const ::boost::shared_ptr< ::Window>& rpTargetWindow); - void Invalidate (const Rectangle& rInvalidationBox); - void Validate (const MapMode& rMapMode); - void Repaint ( - OutputDevice& rTargetDevice, - const Rectangle& rRepaintRectangle); - void Resize (const Size& rSize); - void AddPainter (const SharedILayerPainter& rpPainter); - void RemovePainter (const SharedILayerPainter& rpPainter); - bool HasPainter (void) const; - void Dispose (void); - - private: - ::boost::shared_ptr mpLayerDevice; - ::std::vector maPainters; - Region maInvalidationRegion; - void ValidateRectangle (const Rectangle& rBox); - }; - private: - const ::boost::shared_ptr< ::Window> mpTargetWindow; - ::std::vector maLayers; + SharedSdWindow mpTargetWindow; + class LayerContainer; + ::boost::scoped_ptr mpLayers; ::boost::scoped_ptr mpBackBuffer; MapMode maSavedMapMode; diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 0c93c865dec8..9eee19b796c2 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -38,7 +38,7 @@ namespace sd { namespace slidesorter { namespace view { -Layouter::Layouter (const ::boost::shared_ptr< ::Window>& rpWindow) +Layouter::Layouter (const SharedSdWindow& rpWindow) : mpWindow(rpWindow), mnRequestedLeftBorder(35), mnRequestedRightBorder(35), @@ -58,7 +58,8 @@ Layouter::Layouter (const ::boost::shared_ptr< ::Window>& rpWindow) mnPageCount(0), mnColumnCount(1), mnRowCount(0), - maPageObjectSize(1,1) + maPageObjectSize(1,1), + mbIsVertical(true) { } @@ -150,6 +151,7 @@ bool Layouter::RearrangeHorizontal ( { OSL_ASSERT(mpWindow); + mbIsVertical = false; mnPageCount = nPageCount; if (rWindowSize.Width() > 0 @@ -225,6 +227,7 @@ bool Layouter::RearrangeVertical ( { OSL_ASSERT(mpWindow); + mbIsVertical = true; mnPageCount = nPageCount; if (rWindowSize.Width() > 0 @@ -489,22 +492,69 @@ Point Layouter::GetInsertionMarkerLocation ( -sal_Int32 Layouter::GetIndexOfFirstVisiblePageObject ( - const Rectangle& aVisibleArea) const +Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const { - sal_Int32 nRow = GetRowAtPosition (aVisibleArea.Top(), true, GM_BOTH); - return nRow * mnColumnCount; + sal_Int32 nRow0 = GetRowAtPosition (aVisibleArea.Top(), true, GM_BOTH); + sal_Int32 nRow1 = GetRowAtPosition (aVisibleArea.Bottom(), + true, GM_BOTH); + return Range( + ::std::min(nRow0 * mnColumnCount, mnPageCount-1), + ::std::min((nRow1+1) * mnColumnCount - 1, mnPageCount-1)); } -sal_Int32 Layouter::GetIndexOfLastVisiblePageObject ( - const Rectangle& aVisibleArea) const +Range Layouter::GetSelectionRange ( + const Point& rAnchor, + const Point& rOther, + const Range& rCurrentSelectionRange) const { - sal_Int32 nRow = GetRowAtPosition (aVisibleArea.Bottom(), - true, GM_BOTH); - return (nRow+1) * mnColumnCount - 1; + sal_Int32 nIndexA (GetInsertionIndex(rAnchor, true)); + sal_Int32 nIndexB (GetInsertionIndex(rOther, true)); + + // When either of the locations does not lie over a page then we may + // have to adapt the start or end index. + Rectangle aBoxA (GetPageObjectBox(nIndexA)); + Rectangle aBoxB (GetPageObjectBox(nIndexB)); + if (nIndexA > nIndexB) + { + ::std::swap(nIndexA,nIndexB); + ::std::swap(aBoxA, aBoxB); + } + + if (mnColumnCount == 1) + { + // Vertical arrangement of pages. + if (nIndexA <= nIndexB) + { + if (rOther.Y() < aBoxB.Top()) + --nIndexB; + } + else + { + if (rOther.Y() > aBoxB.Bottom()) + --nIndexA; + } + } + else + { + // Horizontal arrangement of pages. + if (nIndexA <= nIndexB) + { + if (rOther.X() < aBoxB.Left()) + --nIndexB; + } + else + { + if (rOther.X() > aBoxB.Right()) + --nIndexA; + } + } + + return Range( + ::std::min(nIndexA, nIndexB), + ::std::min(mnPageCount-1, ::std::max(nIndexA, nIndexB))); } @@ -561,6 +611,14 @@ sal_Int32 Layouter::GetInsertionIndex ( +bool Layouter::IsVertical (void) const +{ + return mbIsVertical; +} + + + + sal_Int32 Layouter::GetRowAtPosition ( sal_Int32 nYPosition, bool bIncludeBordersAndGaps, diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx index 24cd3e0cdc86..be5c5066863a 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -39,11 +39,9 @@ namespace sd { namespace slidesorter { namespace view { -const sal_Int32 PageObjectLayouter::mnSelectionIndicatorOffset = 0; -const sal_Int32 PageObjectLayouter::mnSelectionIndicatorThickness = 3; -const sal_Int32 PageObjectLayouter::mnFocusIndicatorOffset = 3; const sal_Int32 PageObjectLayouter::mnPageNumberOffset = 9; -const sal_Int32 PageObjectLayouter::mnOuterBorderWidth = 5; +const sal_Int32 PageObjectLayouter::mnOuterBorderWidth = 6; +const sal_Int32 PageObjectLayouter::mnInfoAreaMinWidth = 26; const Size PageObjectLayouter::maButtonSize (32,32); const sal_Int32 PageObjectLayouter::mnButtonGap (5); @@ -51,23 +49,23 @@ const sal_Int32 PageObjectLayouter::mnButtonGap (5); PageObjectLayouter::PageObjectLayouter ( const Size& rPageObjectWindowSize, const Size& rPageSize, - const ::boost::shared_ptr< ::Window>& rpWindow, - const int nPageCount) + const SharedSdWindow& rpWindow, + const sal_Int32 nPageCount) : mpWindow(rpWindow), maPageObjectSize(rPageObjectWindowSize.Width(), rPageObjectWindowSize.Height()), mnModelToWindowScale(1), maPageObjectBoundingBox(), maPageNumberAreaBoundingBox(), maPreviewBoundingBox(), - maFocusIndicatorBoundingBox(), - maSelectionIndicatorBoundingBox(), maTransitionEffectBoundingBox(), maButtonAreaBoundingBox(), maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)) { const Size aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount)); - const int nMaximumBorderWidth (mnSelectionIndicatorOffset + mnOuterBorderWidth); + const int nMaximumBorderWidth (mnOuterBorderWidth); + + // Set up some bounding boxes relative to the page object origin. maPageNumberAreaBoundingBox = Rectangle( mnPageNumberOffset, @@ -78,21 +76,9 @@ PageObjectLayouter::PageObjectLayouter ( maPreviewBoundingBox = CalculatePreviewBoundingBox( maPageObjectSize, Size(rPageSize.Width(), rPageSize.Height()), - aPageNumberAreaSize); + ::std::min(aPageNumberAreaSize.Width(), mnInfoAreaMinWidth)); maPageObjectBoundingBox = Rectangle(Point(0,0), maPageObjectSize); - maFocusIndicatorBoundingBox = maPreviewBoundingBox; - maFocusIndicatorBoundingBox.Left() -= mnFocusIndicatorOffset; - maFocusIndicatorBoundingBox.Top() -= mnFocusIndicatorOffset; - maFocusIndicatorBoundingBox.Right() += mnFocusIndicatorOffset; - maFocusIndicatorBoundingBox.Bottom() += mnFocusIndicatorOffset; - - maSelectionIndicatorBoundingBox = maPreviewBoundingBox; - maSelectionIndicatorBoundingBox.Left() -= mnSelectionIndicatorOffset; - maSelectionIndicatorBoundingBox.Top() -= mnSelectionIndicatorOffset; - maSelectionIndicatorBoundingBox.Right() += mnSelectionIndicatorOffset; - maSelectionIndicatorBoundingBox.Bottom() += mnSelectionIndicatorOffset; - const Size aIconSize (maTransitionEffectIcon.GetSizePixel()); const int nLeft (maPreviewBoundingBox.Left() - mnPageNumberOffset - aIconSize.Width() - nMaximumBorderWidth); @@ -113,16 +99,23 @@ PageObjectLayouter::PageObjectLayouter ( +PageObjectLayouter::~PageObjectLayouter(void) +{ +} + + + + Rectangle PageObjectLayouter::CalculatePreviewBoundingBox ( Size& rPageObjectSize, const Size& rPageSize, - const Size& rPageNumberAreaSize) + const sal_Int32 nInfoAreaWidth) { - const int nMaximumBorderWidth (mnSelectionIndicatorOffset + mnOuterBorderWidth); + const int nMaximumBorderWidth (mnOuterBorderWidth); const int nLeftAreaWidth ( 2*mnPageNumberOffset + ::std::max( - rPageNumberAreaSize.Width(), + nInfoAreaWidth, maTransitionEffectIcon.GetSizePixel().Width())); int nPreviewWidth; int nPreviewHeight; @@ -178,12 +171,6 @@ Rectangle PageObjectLayouter::GetBoundingBox ( const CoordinateSystem eCoordinateSystem, const sal_Int32 nIndex) { - if ( ! rpPageDescriptor) - { - OSL_ASSERT(rpPageDescriptor); - return Rectangle(); - } - Rectangle aBoundingBox; switch (ePart) { @@ -196,14 +183,6 @@ Rectangle PageObjectLayouter::GetBoundingBox ( aBoundingBox = maPreviewBoundingBox; break; - case FocusIndicator: - aBoundingBox = maFocusIndicatorBoundingBox; - break; - - case SelectionIndicator: - aBoundingBox = maSelectionIndicatorBoundingBox; - break; - case PageNumber: aBoundingBox = maPageNumberAreaBoundingBox; break; @@ -230,7 +209,7 @@ Rectangle PageObjectLayouter::GetBoundingBox ( break; } - Point aLocation (rpPageDescriptor->GetLocation()); + Point aLocation (rpPageDescriptor ? rpPageDescriptor->GetLocation() : Point(0,0)); if (eCoordinateSystem == ScreenCoordinateSystem) aLocation += mpWindow->GetMapMode().GetOrigin(); diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 99674577e99c..41a9400c374c 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -39,6 +39,7 @@ #include "view/SlideSorterView.hxx" #include "view/SlsPageObjectLayouter.hxx" #include "view/SlsLayouter.hxx" +#include "view/SlsTheme.hxx" #include "SlsIcons.hxx" #include "cache/SlsPageCache.hxx" #include "controller/SlsProperties.hxx" @@ -54,6 +55,8 @@ #include #include #include +#include +#include using namespace ::drawinglayer::primitive2d; using namespace ::basegfx; @@ -62,29 +65,6 @@ namespace sd { namespace slidesorter { namespace view { namespace { -// Reds -#define Amber 0xff7e00 - -// Greens -#define AndroidGreen 0xa4c639 -#define AppleGreen 0x8db600 -#define Asparagus 0x87a96b - -// Blues -#define Azure 0x000fff -#define DarkCerulean 0x08457e -#define StellaBlue 0x009ee1 -#define AirForceBlue 0x5d8aa8 - -// Off white -#define OldLace 0xfdf5e6 - -// Off grays -#define Arsenic 0x3b444b - -#define MouseOverColor (0x59000000 | StellaBlue) - -#define CornerRadius 4.0 UINT8 Blend ( const UINT8 nValue1, @@ -150,25 +130,126 @@ void AdaptTransparency (AlphaMask& rMask, const double nAlpha) } +/** Bitmap with offset that is used when the bitmap is painted. The bitmap +*/ +class OffsetBitmap +{ +public: + /** Create one of the eight shadow bitmaps from one that combines them + all. This larger bitmap is expected to have dimension NxN with + N=1+2*M. Of this larger bitmap there are created four corner + bitmaps of size 2*M x 2*M and four side bitmaps of sizes 1xM (top + and bottom) and Mx1 (left and right). The corner bitmaps have each + one quadrant of size MxM that is painted under the interior of the + frame. + @param rBitmap + The larger bitmap of which the eight shadow bitmaps are cut out + from. + @param nHorizontalPosition + Valid values are -1 (left), 0 (center), and +1 (right). + @param nVerticalPosition + Valid values are -1 (top), 0 (center), and +1 (bottom). + */ + OffsetBitmap ( + const BitmapEx& rBitmap, + const sal_Int32 nHorizontalPosition, + const sal_Int32 nVerticalPosition); + + /** Create bitmap and offset from the given values. Corner bitmaps are + constructed with the given width and height. Side bitmaps are + stretched along one axis to reduce the paint calls when the sides of + a frame are painted. + @param rBitmap + The larger bitmap that contains the four corner bitmaps and the + four side bitmaps. + */ + void SetBitmap ( + const BitmapEx& rBitmap, + const sal_Int32 nOriginX, + const sal_Int32 nOriginY, + const sal_Int32 nWidth, + const sal_Int32 nHeight, + const sal_Int32 nOffsetX, + const sal_Int32 nOffsetY); + + /** Use the given device to paint the bitmap at the location that is the + sum of the given anchor and the internal offset. + */ + void PaintCorner (OutputDevice& rDevice, const Point& rAnchor) const; + + /** Use the given device to paint the bitmap stretched between the two + given locations. Offsets of the adjacent corner bitmaps and the + offset of the side bitmap are used to determine the area that is to + be filled with the side bitmap. + */ + void PaintSide ( + OutputDevice& rDevice, + const Point& rAnchor1, + const Point& rAnchor2, + const OffsetBitmap& rCornerBitmap1, + const OffsetBitmap& rCornerBitmap2) const; + +private: + BitmapEx maBitmap; + Point maOffset; +}; + +class FramePainter +{ +public: + FramePainter (const BitmapEx& rBitmap); + ~FramePainter (void); + void PaintFrame (OutputDevice&rDevice, const Rectangle aBox) const; + +private: + OffsetBitmap maShadowTopLeft; + OffsetBitmap maShadowTop; + OffsetBitmap maShadowTopRight; + OffsetBitmap maShadowLeft; + OffsetBitmap maShadowRight; + OffsetBitmap maShadowBottomLeft; + OffsetBitmap maShadowBottom; + OffsetBitmap maShadowBottomRight; + bool mbIsValid; +}; + + } // end of anonymous namespace +//===== PageObjectPainter ===================================================== + PageObjectPainter::PageObjectPainter ( const SlideSorter& rSlideSorter) : mrLayouter(rSlideSorter.GetView().GetLayouter()), mpPageObjectLayouter(), mpCache(rSlideSorter.GetView().GetPreviewCache()), mpProperties(rSlideSorter.GetProperties()), - mpFont(), + mpTheme(rSlideSorter.GetTheme()), + mpPageNumberFont(), maStartPresentationIcon(), maShowSlideIcon(), - maNewSlideIcon() + maNewSlideIcon(), + mpShadowPainter(), + maNormalBackground(), + maSelectionBackground(), + maMouseOverBackground() { LocalResource aResource (IMG_ICONS); + maStartPresentationIcon = Image(SdResId(IMAGE_PRESENTATION)).GetBitmapEx(); maShowSlideIcon = Image(SdResId(IMAGE_SHOW_SLIDE)).GetBitmapEx(); maNewSlideIcon = Image(SdResId(IMAGE_NEW_SLIDE)).GetBitmapEx(); + + mpShadowPainter.reset(new FramePainter(mpTheme->GetIcon(Theme::RawShadow))); +} + + + + +PageObjectPainter::~PageObjectPainter (void) +{ } @@ -187,20 +268,32 @@ void PageObjectPainter::PaintPageObject ( return; } - if ( ! mpFont) - { - mpFont.reset(new Font(rDevice.GetFont())); - mpFont->SetWeight(WEIGHT_BOLD); - } - if (mpFont) - rDevice.SetFont(*mpFont); + if ( ! mpPageNumberFont) + mpPageNumberFont = mpTheme->CreateFont(Theme::PageNumberFont, rDevice); + PrepareBackgrounds(rDevice); + + // Turn off antialiasing to avoid the bitmaps from being shifted by + // fractions of a pixel and thus show blurry edges. + const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); + rDevice.SetAntialiasing(nSavedAntialiasingMode & ~ANTIALIASING_ENABLE_B2DDRAW); PaintBackground(rDevice, rpDescriptor); PaintPreview(rDevice, rpDescriptor); PaintPageNumber(rDevice, rpDescriptor); PaintTransitionEffect(rDevice, rpDescriptor); PaintButtons(rDevice, rpDescriptor); - // PaintBorder(rDevice, rpDescriptor); + + rDevice.SetAntialiasing(nSavedAntialiasingMode); +} + + + + +void PageObjectPainter::NotifyResize (void) +{ + maNormalBackground.SetEmpty(); + maSelectionBackground.SetEmpty(); + maMouseOverBackground.SetEmpty(); } @@ -215,36 +308,24 @@ void PageObjectPainter::PaintBackground ( PageObjectLayouter::PageObject, PageObjectLayouter::WindowCoordinateSystem)); - rDevice.SetLineColor(); - const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); - rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); - - const ColorData nColor (GetColorForVisualState(rpDescriptor)); - rDevice.SetFillColor(Color(nColor & 0x00ffffff)); - double nTransparency (COLORDATA_TRANSPARENCY(nColor)/255.0); - rDevice.DrawTransparent( - ::basegfx::B2DPolyPolygon( - ::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), - CornerRadius/aBox.GetWidth(), - CornerRadius/aBox.GetHeight())), - nTransparency); - if (rpDescriptor->HasState(model::PageDescriptor::ST_MouseOver)) { - rDevice.SetFillColor(Color(MouseOverColor & 0x00ffffff)); - nTransparency = COLORDATA_TRANSPARENCY(MouseOverColor)/255.0; - nTransparency *= 1-rpDescriptor->GetVisualState().GetVisualStateBlend(); - rDevice.DrawTransparent( - ::basegfx::B2DPolyPolygon( - ::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), - CornerRadius/aBox.GetWidth(), - CornerRadius/aBox.GetHeight())), - nTransparency); + rDevice.DrawBitmap( + aBox.TopLeft(), + maMouseOverBackground); + } + else if (rpDescriptor->HasState(model::PageDescriptor::ST_Selected)) + { + rDevice.DrawBitmap( + aBox.TopLeft(), + maSelectionBackground); + } + else + { + rDevice.DrawBitmap( + aBox.TopLeft(), + maNormalBackground); } - - rDevice.SetAntialiasing(nSavedAntialiasingMode); } @@ -254,7 +335,7 @@ void PageObjectPainter::PaintPreview ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const { - const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); @@ -276,6 +357,11 @@ void PageObjectPainter::PaintPreview ( rDevice.DrawBitmapEx(aBox.TopLeft(), aBitmap); } + // Draw border around preview. + --aBox.Left(); + --aBox.Top(); + ++aBox.Right(); + ++aBox.Bottom(); rDevice.SetLineColor(Color(0,0,0)); rDevice.SetFillColor(); rDevice.DrawRect(aBox); @@ -297,6 +383,7 @@ void PageObjectPainter::PaintPageNumber ( OSL_ASSERT(rpDescriptor->GetPage()!=NULL); const sal_Int32 nPageNumber ((rpDescriptor->GetPage()->GetPageNum() - 1) / 2 + 1); const String sPageNumber (String::CreateFromInt32(nPageNumber)); + rDevice.SetFont(*mpPageNumberFont); rDevice.SetTextColor(Color(0x0848a8f)); rDevice.DrawText(aBox.TopLeft(), sPageNumber); @@ -308,7 +395,7 @@ void PageObjectPainter::PaintPageNumber ( aBox.Top() -= 1; aBox.Right() += 2; aBox.Bottom() += 1; - rDevice.SetLineColor(Color(Azure)); + rDevice.SetLineColor(Color(mpTheme->GetColor(Theme::PageNumberBorder))); rDevice.SetFillColor(); rDevice.DrawRect(aBox); @@ -323,14 +410,18 @@ void PageObjectPainter::PaintTransitionEffect ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const { - const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( - rpDescriptor, - PageObjectLayouter::TransitionEffectIndicator, - PageObjectLayouter::WindowCoordinateSystem)); - - rDevice.DrawBitmapEx( - aBox.TopLeft(), - mpPageObjectLayouter->GetTransitionEffectIcon().GetBitmapEx()); + const SdPage* pPage = rpDescriptor->GetPage(); + if (pPage!=NULL && pPage->getTransitionType() > 0) + { + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::TransitionEffectIndicator, + PageObjectLayouter::WindowCoordinateSystem)); + + rDevice.DrawBitmapEx( + aBox.TopLeft(), + mpPageObjectLayouter->GetTransitionEffectIcon().GetBitmapEx()); + } } @@ -351,12 +442,12 @@ void PageObjectPainter::PaintButtons ( const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); - rDevice.SetLineColor(Color(Arsenic)); + rDevice.SetLineColor(); const double nCornerRadius(3); for (int nButtonIndex=0; nButtonIndex<3; ++nButtonIndex) { - Color aButtonFillColor (AirForceBlue); + Color aButtonFillColor (mpTheme->GetColor(Theme::ButtonBackground)); const Rectangle aBox ( mpPageObjectLayouter->GetBoundingBox( rpDescriptor, @@ -421,36 +512,267 @@ void PageObjectPainter::PaintButtons ( -ColorData PageObjectPainter::GetColorForVisualState ( - const model::SharedPageDescriptor& rpDescriptor) const +void PageObjectPainter::PrepareBackgrounds (OutputDevice& rDevice) +{ + if (maNormalBackground.IsEmpty()) + { + maNormalBackground = CreateBackgroundBitmap(rDevice, Theme::NormalPage); + maSelectionBackground = CreateBackgroundBitmap(rDevice, Theme::SelectedPage); + maMouseOverBackground = CreateBackgroundBitmap(rDevice, Theme::MouseOverPage); + } +} + + + + +Bitmap PageObjectPainter::CreateBackgroundBitmap( + const OutputDevice& rReferenceDevice, + const Theme::ColorType eColorType) const +{ + ::canvas::tools::ElapsedTime aTimer; + const double nStartTime (aTimer.getElapsedTime()); + + const Size aSize (mpPageObjectLayouter->GetPageObjectSize()); + VirtualDevice aBitmapDevice (rReferenceDevice); + aBitmapDevice.SetOutputSizePixel(aSize); + + OSL_TRACE("created bitmap after %fms",(aTimer.getElapsedTime() - nStartTime)*1000); + + // Paint the background with a linear gradient that starts some pixels + // below the top and ends some pixels above the bottom. +#if 1 + const sal_Int32 nDefaultConstantSize(aSize.Height()/4); + const sal_Int32 nMinimalGradientSize(40); + const sal_Int32 nHeight (aSize.Height()); + const sal_Int32 nY1 ( + ::std::max( + 0, + ::std::min( + nDefaultConstantSize, + (nHeight - nMinimalGradientSize)/2))); + const sal_Int32 nY2 (nHeight-nY1); + const Color aTopColor(mpTheme->GetColor(eColorType, Theme::Fill1)); + const Color aBottomColor(mpTheme->GetColor(eColorType, Theme::Fill2)); + for (sal_Int32 nY=0; nY=nY2) + aBitmapDevice.SetLineColor(aBottomColor); + else + { + Color aColor (aTopColor); + aColor.Merge(aBottomColor, 255 * (nY2-nY) / (nY2-nY1)); + aBitmapDevice.SetLineColor(aColor); + } + aBitmapDevice.DrawLine(Point(0,nY), Point(aSize.Width(),nY)); + } +#else + const Color aTopColor(mpTheme->GetColor(eColorType, Theme::Fill1)); + const Color aBottomColor(mpTheme->GetColor(eColorType, Theme::Fill2)); + Color aColor (aTopColor); + aColor.Merge(aBottomColor, 128); + aBitmapDevice.SetFillColor(aColor); + aBitmapDevice.SetLineColor(aColor); + aBitmapDevice.DrawRect(Rectangle(Point(0,0), aSize)); +#endif + + OSL_TRACE("filled background after %fms",(aTimer.getElapsedTime() - nStartTime)*1000); + + // Paint the border. + aBitmapDevice.SetFillColor(); + aBitmapDevice.SetLineColor(mpTheme->GetColor(eColorType, Theme::Border2)); + aBitmapDevice.DrawRect(Rectangle(Point(0,0),aSize)); + aBitmapDevice.SetLineColor(mpTheme->GetColor(eColorType, Theme::Border1)); + aBitmapDevice.DrawLine(Point(0,0),Point(aSize.Width()-1,0)); + + OSL_TRACE("painted border after %fms",(aTimer.getElapsedTime() - nStartTime)*1000); + + // Get bounding box of the preview around which a shadow is painted. + // Compensate for the border around the preview. + Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + model::SharedPageDescriptor(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + aBox.Left() -= 1; + aBox.Top() -= 1; + aBox.Right() += 1; + aBox.Bottom() += 1; + mpShadowPainter->PaintFrame(aBitmapDevice, aBox); + + OSL_TRACE("painted shadow border after %fms",(aTimer.getElapsedTime() - nStartTime)*1000); + + return aBitmapDevice.GetBitmap (Point(0,0),aSize); +} + + + + +//===== FramePainter ========================================================== + +FramePainter::FramePainter (const BitmapEx& rShadowBitmap) + : maShadowTopLeft(rShadowBitmap,-1,-1), + maShadowTop(rShadowBitmap,0,-1), + maShadowTopRight(rShadowBitmap,+1,-1), + maShadowLeft(rShadowBitmap,-1,0), + maShadowRight(rShadowBitmap,+1,0), + maShadowBottomLeft(rShadowBitmap,-1,+1), + maShadowBottom(rShadowBitmap,0,+1), + maShadowBottomRight(rShadowBitmap,+1,+1), + mbIsValid(false) +{ + if (rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height() + && (rShadowBitmap.GetSizePixel().Width()-1)%2 == 0 + && ((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 0) + { + mbIsValid = true; + } + else + { + OSL_ASSERT(rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height()); + OSL_ASSERT((rShadowBitmap.GetSizePixel().Width()-1)%2 == 0); + OSL_ASSERT(((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 0); + } +} + + + + +FramePainter::~FramePainter (void) +{ +} + + + + +void FramePainter::PaintFrame ( + OutputDevice& rDevice, + const Rectangle aBox) const +{ + // Paint the shadow. + maShadowTopLeft.PaintCorner(rDevice, aBox.TopLeft()); + maShadowTopRight.PaintCorner(rDevice, aBox.TopRight()); + maShadowBottomLeft.PaintCorner(rDevice, aBox.BottomLeft()); + maShadowBottomRight.PaintCorner(rDevice, aBox.BottomRight()); + maShadowLeft.PaintSide(rDevice, + aBox.TopLeft(), aBox.BottomLeft(), + maShadowTopLeft, maShadowBottomLeft); + maShadowRight.PaintSide(rDevice, + aBox.TopRight(), aBox.BottomRight(), + maShadowTopRight, maShadowBottomRight); + maShadowTop.PaintSide(rDevice, + aBox.TopLeft(), aBox.TopRight(), + maShadowTopLeft, maShadowTopRight); + maShadowBottom.PaintSide(rDevice, + aBox.BottomLeft(), aBox.BottomRight(), + maShadowBottomLeft, maShadowBottomRight); +} + + + + +//===== OffsetBitmap ========================================================== + +OffsetBitmap::OffsetBitmap ( + const BitmapEx& rBitmap, + const sal_Int32 nHorizontalPosition, + const sal_Int32 nVerticalPosition) + : maBitmap(), + maOffset() { - ColorData nColor; - switch (rpDescriptor->GetVisualState().GetCurrentVisualState()) + OSL_ASSERT(nHorizontalPosition>=-1 && nHorizontalPosition<=+1); + OSL_ASSERT(nVerticalPosition>=-1 && nVerticalPosition<=+1); + + const sal_Int32 nS (1); + const sal_Int32 nC (::std::max(0,(rBitmap.GetSizePixel().Width()-nS)/2)); + const sal_Int32 nO (nC/2); + + const Point aOrigin( + nHorizontalPosition<0 ? 0 : (nHorizontalPosition == 0 ? nC : nC+nS), + nVerticalPosition<0 ? 0 : (nVerticalPosition == 0 ? nC : nC+nS)); + const Size aSize( + nHorizontalPosition==0 ? nS : nC, + nVerticalPosition==0 ? nS : nC); + maBitmap = BitmapEx(rBitmap, aOrigin, aSize); + maOffset = Point( + nHorizontalPosition<0 ? -nO : nHorizontalPosition>0 ? -nO+1 : 0, + nVerticalPosition<0 ? -nO : nVerticalPosition>0 ? -nO+1 : 0); + + // Enlarge the side bitmaps so that painting the frame requires less + // paint calls. + const sal_Int32 nSideBitmapSize (64); + if (nHorizontalPosition == 0) + { + maBitmap.Scale(Size(nSideBitmapSize,aSize.Height()), BMP_SCALE_FAST); + } + else if (nVerticalPosition == 0) { - case model::VisualState::VS_Selected: - nColor = 0x80000000 | StellaBlue; - break; - - case model::VisualState::VS_Focused: - nColor = AndroidGreen; - break; - - case model::VisualState::VS_Current: - nColor = 0x80000000 | StellaBlue; - // aColor = mpProperties->GetSelectionColor(); - break; - - case model::VisualState::VS_Excluded: - nColor = 0xcc929ca2; - break; - - case model::VisualState::VS_None: - default: - nColor = OldLace;//0x80000000 | OldLace; - break; + maBitmap.Scale(Size(aSize.Width(), nSideBitmapSize), BMP_SCALE_FAST); } +} + + + - return nColor; +void OffsetBitmap::PaintCorner ( + OutputDevice& rDevice, + const Point& rAnchor) const +{ + rDevice.DrawBitmapEx(rAnchor+maOffset, maBitmap); +} + + + + +void OffsetBitmap::PaintSide ( + OutputDevice& rDevice, + const Point& rAnchor1, + const Point& rAnchor2, + const OffsetBitmap& rCornerBitmap1, + const OffsetBitmap& rCornerBitmap2) const +{ + const Size aBitmapSize (maBitmap.GetSizePixel()); + if (rAnchor1.Y() == rAnchor2.Y()) + { + // Side is horizontal. + const sal_Int32 nY (rAnchor1.Y() + maOffset.Y()); + const sal_Int32 nLeft ( + rAnchor1.X() + + rCornerBitmap1.maBitmap.GetSizePixel().Width() + + rCornerBitmap1.maOffset.X()); + const sal_Int32 nRight ( + rAnchor2.X() + + rCornerBitmap2.maOffset.X()\ + - 1); + for (sal_Int32 nX=nLeft; nX<=nRight; nX+=aBitmapSize.Width()) + rDevice.DrawBitmapEx( + Point(nX,nY), + Size(std::min(aBitmapSize.Width(), nRight-nX+1),aBitmapSize.Height()), + maBitmap); + } + else if (rAnchor1.X() == rAnchor2.X()) + { + // Side is vertical. + const sal_Int32 nX (rAnchor1.X() + maOffset.X()); + const sal_Int32 nTop ( + rAnchor1.Y() + + rCornerBitmap1.maBitmap.GetSizePixel().Height() + + rCornerBitmap1.maOffset.Y()); + const sal_Int32 nBottom ( + rAnchor2.Y() + + rCornerBitmap2.maOffset.Y() + - 1); + for (sal_Int32 nY=nTop; nY<=nBottom; nY+=aBitmapSize.Height()) + rDevice.DrawBitmapEx( + Point(nX,nY), + Size(aBitmapSize.Width(), std::min(aBitmapSize.Height(), nBottom-nY+1)), + maBitmap); + } + else + { + // Diagonal sides indicatee an error. + OSL_ASSERT(false); + } } diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx new file mode 100644 index 000000000000..c866a3bc6014 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -0,0 +1,242 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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 "view/SlsTheme.hxx" +#include "SlsIcons.hxx" +#include "controller/SlsProperties.hxx" +#include "sdresid.hxx" +#include +#include +#include + + +namespace sd { namespace slidesorter { namespace view { + +// Reds +#define Amber 0xff7e00 + +// Greens +#define AndroidGreen 0xa4c639 +#define AppleGreen 0x8db600 +#define Asparagus 0x87a96b + +// Blues +#define Azure 0x000fff +#define DarkCerulean 0x08457e +#define StellaBlue 0x009ee1 +#define AirForceBlue 0x5d8aa8 + +// Off white +#define OldLace 0xfdf5e6 +#define AntiqueWhite 0xfaebd7 + +// Off grays +#define Arsenic 0x3b444b + +const static ColorData SelectionFill1ColorData = 0xb7daf0; +const static ColorData SelectionFill2ColorData = 0x6db5e1; + +const static ColorData MouseOverFill1ColorData = 0x0e85cd; +const static ColorData MouseOverFill2ColorData = 0x044c99; + +const static ColorData Border1ColorData = 0x6db5e1; +const static ColorData Border2ColorData = 0x0e85cd; + +const static ColorData BackgroundColorData = 0xffffff; + +const static ColorData gnMouseOverColor = 0x59000000 | StellaBlue; + +const static double gnCornerRadius = 4.0; + +Theme::Theme (const ::boost::shared_ptr& rpProperties) + : maBackgroundColor(rpProperties->GetBackgroundColor().GetColor()), + maRawShadow(), + maInsertionIndicator() +{ + LocalResource aResource (IMG_ICONS); + + maRawShadow = Image(SdResId(IMAGE_SHADOW)).GetBitmapEx(); + maInsertionIndicator = Image(SdResId(IMAGE_INSERTION_INDICATOR_SELECT)).GetBitmapEx(); +} + + + + +void Theme::Update (const ::boost::shared_ptr& rpProperties) +{ + maBackgroundColor = rpProperties->GetBackgroundColor().GetColor(); +} + + +::boost::shared_ptr Theme::CreateFont ( + const FontType eType, + OutputDevice& rDevice) const +{ + ::boost::shared_ptr pFont; + + switch (eType) + { + case PageNumberFont: + pFont.reset(new Font(rDevice.GetFont())); + pFont->SetWeight(WEIGHT_BOLD); + break; + } + + return pFont; +} + + + + +ColorData Theme::GetColorForVisualState (const model::VisualState::State eState) const +{ + ColorData nColor; + switch (eState) + { + case model::VisualState::VS_Selected: + nColor = 0x80000000 | StellaBlue; + break; + + case model::VisualState::VS_Focused: + nColor = AndroidGreen; + break; + + case model::VisualState::VS_Current: + nColor = 0x80000000 | StellaBlue; + // aColor = mpProperties->GetSelectionColor(); + break; + + case model::VisualState::VS_Excluded: + nColor = 0xcc929ca2; + break; + + case model::VisualState::VS_None: + default: + nColor = 0x80000000 | AntiqueWhite; + break; + } + + return nColor; +} + + + + +ColorData Theme::GetColor ( + const ColorType eType, + const ColorClass eClass) +{ + switch(eType) + { + case Background: + return maBackgroundColor; + + case ButtonBackground: + return AirForceBlue; + + case MouseOverColor: + return gnMouseOverColor; + + case PageNumberBorder: + return Azure; + + case Selection: + return StellaBlue; + + case NormalPage: + switch (eClass) + { + case Border1: + case Border2: + return maBackgroundColor; + + case Fill1: + case Fill2: + return maBackgroundColor; + } + break; + + case SelectedPage: + switch (eClass) + { + case Border1: + return Border1ColorData; + + case Border2: + return Border2ColorData; + + case Fill1: + return SelectionFill1ColorData; + + case Fill2: + return SelectionFill2ColorData; + } + break; + + case MouseOverPage: + switch (eClass) + { + case Border1: + return Border1ColorData; + + case Border2: + return Border2ColorData; + + case Fill1: + return MouseOverFill1ColorData; + + case Fill2: + return MouseOverFill2ColorData; + } + break; + } + return 0; +} + + + + +BitmapEx Theme::GetIcon (const IconType eType) +{ + switch (eType) + { + case InsertionIndicator: + return maInsertionIndicator; + + case RawShadow: + return maRawShadow; + + default: + return BitmapEx(); + } +} + +} } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx index 3d997689dc45..d406a3c866b7 100644 --- a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx @@ -40,7 +40,7 @@ #include "model/SlsPageEnumeration.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" -#include "SlsIcons.hxx" +#include "view/SlsTheme.hxx" #include "cache/SlsPageCache.hxx" #include "ViewShell.hxx" #include "ViewShellBase.hxx" @@ -112,9 +112,9 @@ ViewOverlay::ViewOverlay ( const ::boost::shared_ptr& rpLayeredDevice) : mrSlideSorter(rSlideSorter), mpLayeredDevice(rpLayeredDevice), - mpSelectionRectangleOverlay(new SelectionRectangleOverlay(*this, 2)), - mpInsertionIndicatorOverlay(new InsertionIndicatorOverlay(*this, 3)), - mpSubstitutionOverlay(new SubstitutionOverlay(*this, 2)) + mpSelectionRectangleOverlay(new SelectionRectangleOverlay(*this, 3)), + mpInsertionIndicatorOverlay(new InsertionIndicatorOverlay(*this, 4)), + mpSubstitutionOverlay(new SubstitutionOverlay(*this, 3)) { } @@ -551,14 +551,8 @@ InsertionIndicatorOverlay::InsertionIndicatorOverlay ( const sal_Int32 nLayerIndex) : OverlayBase (rViewOverlay, nLayerIndex), maLocation(), - maIconWithBorder(), - maIcon(), - maMask() + maIcon(rViewOverlay.GetSlideSorter().GetTheme()->GetIcon(Theme::InsertionIndicator)) { - LocalResource aResource (IMG_ICONS); - maIconWithBorder = Image(SdResId(IMAGE_INSERTION_INDICATOR_SELECT)); - maIcon = Image(SdResId(IMAGE_INSERTION_INDICATOR_NORMAL)); - maMask = Image(SdResId(IMAGE_INSERTION_INDICATOR_MASK)); } @@ -568,8 +562,8 @@ void InsertionIndicatorOverlay::SetLocation (const Point& rLocation) { const Point aTopLeft ( rLocation - Point( - maIconWithBorder.GetSizePixel().Width()/2, - maIconWithBorder.GetSizePixel().Height()/2)); + maIcon.GetSizePixel().Width()/2, + maIcon.GetSizePixel().Height()/2)); if (maLocation != aTopLeft) { Invalidator aInvalidator (*this); @@ -589,9 +583,7 @@ void InsertionIndicatorOverlay::Paint ( if ( ! IsVisible()) return; - rDevice.DrawImage( - maLocation, - maIconWithBorder); + rDevice.DrawImage(maLocation, maIcon); } @@ -599,7 +591,7 @@ void InsertionIndicatorOverlay::Paint ( Rectangle InsertionIndicatorOverlay::GetBoundingBox (void) const { - return Rectangle(maLocation, maIconWithBorder.GetSizePixel()); + return Rectangle(maLocation, maIcon.GetSizePixel()); } diff --git a/sd/source/ui/slidesorter/view/makefile.mk b/sd/source/ui/slidesorter/view/makefile.mk index 0741b9e9551f..50988f783531 100644 --- a/sd/source/ui/slidesorter/view/makefile.mk +++ b/sd/source/ui/slidesorter/view/makefile.mk @@ -52,15 +52,17 @@ SRS1NAME=$(TARGET) SRC1FILES = \ SlsIcons.src -SLOFILES = \ - $(SLO)$/SlideSorterView.obj \ - $(SLO)$/SlsFontProvider.obj \ - $(SLO)$/SlsInsertAnimator.obj \ - $(SLO)$/SlsLayeredDevice.obj \ - $(SLO)$/SlsLayouter.obj \ - $(SLO)$/SlsPageObjectLayouter.obj \ - $(SLO)$/SlsPageObjectPainter.obj \ - $(SLO)$/SlsViewCacheContext.obj \ +SLOFILES = \ + $(SLO)$/SlideSorterView.obj \ + $(SLO)$/SlsFontProvider.obj \ + $(SLO)$/SlsInsertAnimator.obj \ + $(SLO)$/SlsLayeredDevice.obj \ + $(SLO)$/SlsLayouter.obj \ + $(SLO)$/SlsPageObjectLayouter.obj \ + $(SLO)$/SlsPageObjectPainter.obj \ + $(SLO)$/SlsSelectionPainter.obj \ + $(SLO)$/SlsTheme.obj \ + $(SLO)$/SlsViewCacheContext.obj \ $(SLO)$/SlsViewOverlay.obj # --- Tagets ------------------------------------------------------- diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 7effb79a00b1..05907426621b 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -695,9 +695,9 @@ long ViewShell::Notify(NotifyEvent& rNEvt, ::sd::Window* pWin) } -BOOL ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWin) +bool ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWin) { - BOOL bDone = FALSE; + bool bDone = false; switch( rCEvt.GetCommand() ) { @@ -747,7 +747,7 @@ BOOL ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWi Invalidate( SID_ATTR_ZOOM ); Invalidate( SID_ATTR_ZOOMSLIDER ); - bDone = TRUE; + bDone = true; } } else @@ -763,7 +763,7 @@ BOOL ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWi rCEvt.IsMouseEvent(),(const void *) &aWheelData ); bDone = pWin->HandleScrollCommand( aReWrite, mpHorizontalScrollBar.get(), - mpVerticalScrollBar.get()); + mpVerticalScrollBar.get()) == TRUE; } } } diff --git a/sd/util/makefile.mk b/sd/util/makefile.mk index 5c0c16e4a71e..9897a8d13045 100644 --- a/sd/util/makefile.mk +++ b/sd/util/makefile.mk @@ -90,7 +90,7 @@ SHL1STDLIBS+= \ $(CPPUHELPERLIB) \ $(CPPULIB) \ $(VOSLIB) \ - $(CANVASLIB) \ + $(CANVASTOOLSLIB) \ $(SALLIB) \ $(AVMEDIALIB) -- cgit v1.2.3 From a3d0b080670accda94caa0c8b6ad6369d47592c5 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 12 Feb 2010 15:40:43 +0100 Subject: renaissance1: #107215# Cleanup. --- .../ui/slidesorter/cache/SlsPageCacheManager.cxx | 5 +++- .../ui/slidesorter/inc/view/SlideSorterView.hxx | 1 - .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 2 +- sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 20 +++++++++++--- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 32 +--------------------- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 21 ++++---------- sd/source/ui/slidesorter/view/SlsTheme.cxx | 16 +++++++++-- sd/source/ui/slidesorter/view/makefile.mk | 1 - 8 files changed, 40 insertions(+), 58 deletions(-) diff --git a/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx b/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx index 4e079b48cc1a..773cad161093 100644 --- a/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx +++ b/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx @@ -328,7 +328,6 @@ void PageCacheManager::ReleaseCache (const ::boost::shared_ptr& rpCache) mpPageCaches->begin(), mpPageCaches->end(), PageCacheContainer::CompareWithCache(rpCache))); - OSL_ASSERT(iCacheToChange != mpPageCaches->end()); if (iCacheToChange != mpPageCaches->end()) { OSL_ASSERT(iCacheToChange->second == rpCache); @@ -345,6 +344,10 @@ void PageCacheManager::ReleaseCache (const ::boost::shared_ptr& rpCache) pResult = rpCache; } + else + { + OSL_ASSERT(iCacheToChange != mpPageCaches->end()); + } } return pResult; diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 4abdfdc328b1..997aa17ebf6c 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -199,7 +199,6 @@ public: void SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor); void SetButtonUnderMouse (const sal_Int32 nButtonIndex); - void AddVisualStateAnimation (const model::SharedPageDescriptor& rpDescriptor); bool SetState ( const model::SharedPageDescriptor& rpDescriptor, const model::PageDescriptor::State eState, diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index 36a7dde48eae..c73d0f5b7f24 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -97,7 +97,7 @@ private: void PrepareBackgrounds (OutputDevice& rDevice); Bitmap CreateBackgroundBitmap( const OutputDevice& rReferenceDevice, - const Theme::ColorType eType) const; + const Theme::GradientColorType eType) const; }; } } } // end of namespace sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index 6eed762a0c44..c8bdfd6e9882 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -76,15 +76,27 @@ public: ButtonBackground, MouseOverColor, PageNumberBorder, - Selection, + Selection + }; + ColorData GetColor (const ColorType eType); + + enum GradientColorType { NormalPage, SelectedPage, MouseOverPage }; - enum ColorClass { Border1, Border2, Fill1, Fill2, Other }; - ColorData GetColor (const ColorType eType, const ColorClass eClass = Other); + enum GradientColorClass { + Border1, + Border2, + Fill1, + Fill2 + }; + ColorData GetGradientColor ( + const GradientColorType eType, + const GradientColorClass eClass); - enum IconType { + enum IconType + { InsertionIndicator, RawShadow }; diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index ec3a83202e56..488defdfc0ce 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -38,7 +38,6 @@ #include "ViewShell.hxx" #include "SlsViewCacheContext.hxx" #include "SlsLayeredDevice.hxx" -#include "SlsSelectionPainter.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsPageObjectLayouter.hxx" #include "view/SlsPageObjectPainter.hxx" @@ -975,32 +974,6 @@ void SlideSorterView::SetButtonUnderMouse (const sal_Int32 nButtonIndex) -void SlideSorterView::AddVisualStateAnimation (const model::SharedPageDescriptor& rpDescriptor) -{ - // Stop a state animation for the given descriptor that is still running. - const Animator::AnimationId nId (rpDescriptor->GetVisualState().GetStateAnimationId()); - if (nId != Animator::NotAnAnimationId) - { - mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(nId); - } - - rpDescriptor->GetVisualState().SetStateAnimationId( - mrSlideSorter.GetController().GetAnimator()->AddAnimation( - ::boost::bind( - controller::AnimationFunction::ApplyVisualStateChange, - rpDescriptor, - ::boost::ref(*this), - ::boost::bind(AnimationFunction::FastInSlowOut_Sine, _1)), - 350, - ::boost::bind( - &VisualState::SetStateAnimationId, - ::boost::ref(rpDescriptor->GetVisualState()), - controller::Animator::NotAnAnimationId))); -} - - - - bool SlideSorterView::SetState ( const model::SharedPageDescriptor& rpDescriptor, const PageDescriptor::State eState, @@ -1013,15 +986,12 @@ bool SlideSorterView::SetState ( switch(eState) { case PageDescriptor::ST_Visible: - RequestRepaint(rpDescriptor); - break; - case PageDescriptor::ST_Selected: case PageDescriptor::ST_Focused: case PageDescriptor::ST_MouseOver: case PageDescriptor::ST_Current: case PageDescriptor::ST_Excluded: - AddVisualStateAnimation(rpDescriptor); + RequestRepaint(rpDescriptor); break; case PageDescriptor::ST_WasSelected: diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 41a9400c374c..ac605ecdbd5f 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -527,17 +527,12 @@ void PageObjectPainter::PrepareBackgrounds (OutputDevice& rDevice) Bitmap PageObjectPainter::CreateBackgroundBitmap( const OutputDevice& rReferenceDevice, - const Theme::ColorType eColorType) const + const Theme::GradientColorType eColorType) const { - ::canvas::tools::ElapsedTime aTimer; - const double nStartTime (aTimer.getElapsedTime()); - const Size aSize (mpPageObjectLayouter->GetPageObjectSize()); VirtualDevice aBitmapDevice (rReferenceDevice); aBitmapDevice.SetOutputSizePixel(aSize); - OSL_TRACE("created bitmap after %fms",(aTimer.getElapsedTime() - nStartTime)*1000); - // Paint the background with a linear gradient that starts some pixels // below the top and ends some pixels above the bottom. #if 1 @@ -551,8 +546,8 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( nDefaultConstantSize, (nHeight - nMinimalGradientSize)/2))); const sal_Int32 nY2 (nHeight-nY1); - const Color aTopColor(mpTheme->GetColor(eColorType, Theme::Fill1)); - const Color aBottomColor(mpTheme->GetColor(eColorType, Theme::Fill2)); + const Color aTopColor(mpTheme->GetGradientColor(eColorType, Theme::Fill1)); + const Color aBottomColor(mpTheme->GetGradientColor(eColorType, Theme::Fill2)); for (sal_Int32 nY=0; nYGetColor(eColorType, Theme::Border2)); + aBitmapDevice.SetLineColor(mpTheme->GetGradientColor(eColorType, Theme::Border2)); aBitmapDevice.DrawRect(Rectangle(Point(0,0),aSize)); - aBitmapDevice.SetLineColor(mpTheme->GetColor(eColorType, Theme::Border1)); + aBitmapDevice.SetLineColor(mpTheme->GetGradientColor(eColorType, Theme::Border1)); aBitmapDevice.DrawLine(Point(0,0),Point(aSize.Width()-1,0)); - OSL_TRACE("painted border after %fms",(aTimer.getElapsedTime() - nStartTime)*1000); - // Get bounding box of the preview around which a shadow is painted. // Compensate for the border around the preview. Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( @@ -600,8 +591,6 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( aBox.Bottom() += 1; mpShadowPainter->PaintFrame(aBitmapDevice, aBox); - OSL_TRACE("painted shadow border after %fms",(aTimer.getElapsedTime() - nStartTime)*1000); - return aBitmapDevice.GetBitmap (Point(0,0),aSize); } diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index c866a3bc6014..3c43c8917e70 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -150,9 +150,7 @@ ColorData Theme::GetColorForVisualState (const model::VisualState::State eState) -ColorData Theme::GetColor ( - const ColorType eType, - const ColorClass eClass) +ColorData Theme::GetColor (const ColorType eType) { switch(eType) { @@ -170,7 +168,19 @@ ColorData Theme::GetColor ( case Selection: return StellaBlue; + } + return 0; +} + + + +ColorData Theme::GetGradientColor ( + const GradientColorType eType, + const GradientColorClass eClass) +{ + switch(eType) + { case NormalPage: switch (eClass) { diff --git a/sd/source/ui/slidesorter/view/makefile.mk b/sd/source/ui/slidesorter/view/makefile.mk index 50988f783531..d7837b1f3189 100644 --- a/sd/source/ui/slidesorter/view/makefile.mk +++ b/sd/source/ui/slidesorter/view/makefile.mk @@ -60,7 +60,6 @@ SLOFILES = \ $(SLO)$/SlsLayouter.obj \ $(SLO)$/SlsPageObjectLayouter.obj \ $(SLO)$/SlsPageObjectPainter.obj \ - $(SLO)$/SlsSelectionPainter.obj \ $(SLO)$/SlsTheme.obj \ $(SLO)$/SlsViewCacheContext.obj \ $(SLO)$/SlsViewOverlay.obj -- cgit v1.2.3 From 1c239d78bc47f52b5d1341644cccb9835181be3d Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 12 Feb 2010 15:51:03 +0100 Subject: renaissance1: #107215# Resolved minor compilation problems. --- sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx | 2 +- .../ui/slidesorter/controller/SlsSelectionFunction.cxx | 9 +-------- .../ui/slidesorter/inc/view/SlsPageObjectPainter.hxx | 3 +-- sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 2 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 1 + sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx | 17 +++++++++-------- 6 files changed, 14 insertions(+), 20 deletions(-) diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index 519acebe1526..77c833e3872a 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -76,7 +76,7 @@ BitmapFactory::~BitmapFactory (void) const bool bDoSuperSampling) { Size aSize (rPixelSize); - bool bDo (true); + bool bDo (bDoSuperSampling); if (bDo) { aSize.Width() *= gnSuperSampleFactor; diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index d12fbe3bbfc0..362bd4abf17f 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -353,7 +353,6 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) (rEvent.GetButtons() & MOUSE_LEFT)!=0); } - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel()); if ( ! aRectangle.IsInside(aMousePosition) && mpSubstitutionHandler) @@ -952,7 +951,6 @@ sal_uInt32 SelectionFunction::EncodeState ( } // Detect whether we are dragging pages or dragging a selection rectangle. - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); if (mpSubstitutionHandler) nEventCode |= SUBSTITUTION_VISIBLE; if (mpMouseMultiSelector) @@ -1569,6 +1567,7 @@ SelectionFunction::MouseMultiSelector::MouseMultiSelector ( meSelectionMode(SM_Normal), maInitialSelection() { + (void)rMouseModelPosition; // Remember the current selection. model::PageEnumeration aPages ( model::PageEnumerationProvider::CreateAllPagesEnumeration( @@ -1835,8 +1834,6 @@ void RangeSelector::UpdateSelection (void) { view::SlideSorterView::DrawLock aLock (mrSlideSorter); - PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); - const sal_Int32 nIndexUnderMouse ( mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint ( maSecondCorner, @@ -1855,10 +1852,6 @@ void RangeSelector::UpdateSelection (void) { model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); - // Determine whether the page was selected before the rectangle - // selection was started. - const bool bWasSelected (pDescriptor->HasState(model::PageDescriptor::ST_WasSelected)); - UpdateSelectionState(pDescriptor, aRange.IsInside(nIndex)); } diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index c73d0f5b7f24..4b01376aaeeb 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -49,8 +49,6 @@ namespace sd { namespace slidesorter { namespace view { class Layouter; class PageObjectLayouter; -namespace { class FramePainter; } - class PageObjectPainter { @@ -74,6 +72,7 @@ private: BitmapEx maStartPresentationIcon; BitmapEx maShowSlideIcon; BitmapEx maNewSlideIcon; + class FramePainter; ::boost::scoped_ptr mpShadowPainter; Bitmap maNormalBackground; Bitmap maSelectionBackground; diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx index aba967ebdeda..05bb9791a200 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx @@ -215,7 +215,7 @@ void LayeredDevice::RegisterPainter ( const sal_Int32 nOldLayerCount (mpLayers->size()); mpLayers->resize(nLayer+1); - for (sal_Int32 nIndex=nOldLayerCount; nIndexsize(); ++nIndex) + for (size_t nIndex=nOldLayerCount; nIndexsize(); ++nIndex) (*mpLayers)[nIndex].reset(new Layer()); } diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 9eee19b796c2..ac5213f658c8 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -510,6 +510,7 @@ Range Layouter::GetSelectionRange ( const Point& rOther, const Range& rCurrentSelectionRange) const { + (void)rCurrentSelectionRange; sal_Int32 nIndexA (GetInsertionIndex(rAnchor, true)); sal_Int32 nIndexB (GetInsertionIndex(rOther, true)); diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index ac605ecdbd5f..f0edc65efd4a 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -194,7 +194,12 @@ private: Point maOffset; }; -class FramePainter +} // end of anonymous namespace + + + + +class PageObjectPainter::FramePainter { public: FramePainter (const BitmapEx& rBitmap); @@ -214,10 +219,6 @@ private: }; -} // end of anonymous namespace - - - //===== PageObjectPainter ===================================================== PageObjectPainter::PageObjectPainter ( @@ -599,7 +600,7 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( //===== FramePainter ========================================================== -FramePainter::FramePainter (const BitmapEx& rShadowBitmap) +PageObjectPainter::FramePainter::FramePainter (const BitmapEx& rShadowBitmap) : maShadowTopLeft(rShadowBitmap,-1,-1), maShadowTop(rShadowBitmap,0,-1), maShadowTopRight(rShadowBitmap,+1,-1), @@ -627,14 +628,14 @@ FramePainter::FramePainter (const BitmapEx& rShadowBitmap) -FramePainter::~FramePainter (void) +PageObjectPainter::FramePainter::~FramePainter (void) { } -void FramePainter::PaintFrame ( +void PageObjectPainter::FramePainter::PaintFrame ( OutputDevice& rDevice, const Rectangle aBox) const { -- cgit v1.2.3 From c81dae0990a762415e2e037b660dd0801e8a540d Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 12 Feb 2010 16:57:51 +0100 Subject: renaissance1: #107215# Added tooltips with slide names. --- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 22 ++++++++++++++++++++++ sd/source/ui/slidesorter/view/SlsLayouter.cxx | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 488defdfc0ce..1f77a40df57b 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -950,6 +950,28 @@ void SlideSorterView::SetPageUnderMouse (const model::SharedPageDescriptor& rpDe if (mpPageUnderMouse) SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true); + + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + ::rtl::OUString sText; + if (mpPageUnderMouse) + { + SdPage* pPage = mpPageUnderMouse->GetPage(); + if (pPage != NULL) + sText = pPage->GetName(); + else + { + OSL_ASSERT(mpPageUnderMouse->GetPage() != NULL); + } + if (sText.getLength() == 0) + { + sText = String(SdResId(STR_PAGE)); + sText += String::CreateFromInt32(mpPageUnderMouse->GetPageIndex()+1); + } + } + pWindow->SetQuickHelpText(sText); + } } } diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index ac5213f658c8..18552f5a51bd 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -563,7 +563,7 @@ Range Layouter::GetSelectionRange ( sal_Int32 Layouter::GetIndexAtPoint ( const Point& rPosition, - bool bIncludePageBorders) const + const bool bIncludePageBorders) const { sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), bIncludePageBorders, -- cgit v1.2.3 From b7fcd9d15b798ca928b9c6a565fca9a89fe20106 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 12 Feb 2010 17:18:45 +0100 Subject: renaissance1: #i107215# Fixed minor compilation problems. --- sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 2 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx index e90fb968ff7e..fa23bb08e251 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx @@ -284,7 +284,7 @@ public: */ sal_Int32 GetInsertionIndex ( const Point& rModelPosition, - bool bAllowVerticalPosition) const; + const bool bAllowVerticalPosition) const; /** Return whether the main orientation of the slides in the slide sorter is vertical, i.e. all slides are arranged in one column. diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 18552f5a51bd..5eab152419eb 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -452,9 +452,9 @@ Rectangle Layouter::GetPageBox (const sal_Int32 nObjectCount) const Point Layouter::GetInsertionMarkerLocation ( - sal_Int32 nIndex, - bool bVertical, - bool bLeftOrTop) const + const sal_Int32 nIndex, + const bool bVertical, + const bool bLeftOrTop) const { Rectangle aBox (GetPageObjectBox (nIndex)); Point aLocation = aBox.Center(); -- cgit v1.2.3 From 74501923447c8f4497e46fba6db196901ed03632 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 8 Mar 2010 11:54:53 +0100 Subject: renaissance1: #i107215# Fixed some minor compilation problems. --- sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx | 1 + sd/source/ui/slidesorter/controller/SlsAnimator.cxx | 7 +++++-- .../ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx | 2 -- sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index 8f70bd08b7ab..f700aa56369c 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -75,6 +75,7 @@ BitmapFactory::~BitmapFactory (void) const Size& rPixelSize, const bool bDoSuperSampling) { + (void)bDoSuperSampling; Size aSize (rPixelSize); bool bDo (false);//bDoSuperSampling); if (bDo) diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index 91c64a046cb5..1bb762c184c9 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -83,9 +83,9 @@ Animator::Animator (SlideSorter& rSlideSorter) maTimer(), mbIsDisposed(false), maAnimations(), + maElapsedTime(), mpDrawLock(), - mnNextAnimationId(0), - maElapsedTime() + mnNextAnimationId(0) { maTimer.SetTimeout(gnResolution); maTimer.SetTimeoutHdl(LINK(this,Animator,TimeoutHandler)); @@ -156,6 +156,8 @@ Animator::AnimationId Animator::AddInfiniteAnimation ( const AnimationFunctor& rAnimation, const double nDelta) { + (void)nDelta; + // When the animator is already disposed then ignore this call // silently (well, we show an assertion, but do not throw an exception.) OSL_ASSERT( ! mbIsDisposed); @@ -276,6 +278,7 @@ void Animator::CleanUpAnimationList (void) void Animator::RequestNextFrame (const double nFrameStart) { + (void)nFrameStart; if ( ! maTimer.IsActive()) { // Prevent redraws except for the ones in TimeoutHandler. While the diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 65a3ee5b54b2..d29748d01ae1 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -176,9 +176,7 @@ void InsertionIndicatorHandler::SetPosition ( const Point& rPoint, const Mode eMode) { - static const bool bAllowHorizontalInsertMarker = true; view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); - USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount()); const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition( rPoint, diff --git a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx index 5a0b7a209799..dcc6ccd0a822 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx @@ -214,7 +214,7 @@ Point InsertionIndicatorOverlay::PaintRepresentatives ( double nTransparency (0); for (sal_Int32 nIndex=2; nIndex>=0; --nIndex) { - if (rRepresentatives.size() <= nIndex) + if (rRepresentatives.size() <= sal_uInt32(nIndex)) continue; switch(nIndex) { -- cgit v1.2.3 From dce05d5b2c068c80cf26b76ae8d2d37736ff540a Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 15 Mar 2010 14:14:59 +0100 Subject: renaissance1: #i107215# Fixes of minor compilation problems. --- sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx | 2 +- sd/source/ui/slidesorter/controller/SlsSlotManager.cxx | 3 +-- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 1 + sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx index 5f98f3dc95f0..4c8bd0158461 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -41,7 +41,7 @@ #include "controller/SlsSelectionManager.hxx" #include "controller/SlsTransferable.hxx" #include "DrawDocShell.hxx" -#include "DrawDoc.hxx" +#include "drawdoc.hxx" #include "app.hrc" #include #include diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index c3f101fd60bb..3ddcc93a8dea 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -1078,7 +1078,6 @@ bool SlotManager::RenameSlideFromDrawViewShell( USHORT nPageId, const String & r void SlotManager::InsertSlide (SfxRequest& rRequest) { const sal_Int32 nInsertionIndex (GetInsertionPosition()); - USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount()); PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter); @@ -1175,7 +1174,7 @@ void SlotManager::DuplicateSelectedSlides (SfxRequest& rRequest) // Set the selection to the pages in aPagesToSelect. PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); rSelector.DeselectAllPages(); - for_each ( + ::std::for_each ( aPagesToSelect.begin(), aPagesToSelect.end(), ::boost::bind( diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 16da8620fb9b..9154a8f5310f 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -766,6 +766,7 @@ void SlideSorterView::CompleteRedraw ( const Region& rPaintArea, sdr::contact::ViewObjectContactRedirector* pRedirector) { + (void)pRedirector; #ifdef DEBUG_TIMING const double nStartTime (gaTimer.getElapsedTime()); OSL_TRACE("SlideSorterView::CompleteRedraw start at %f, %s", diff --git a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx index dcc6ccd0a822..e3326b5f5347 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx @@ -238,7 +238,6 @@ Point InsertionIndicatorOverlay::PaintRepresentatives ( ::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); -- cgit v1.2.3 From b5f80146f4f2d780b1d03249e6f5d7d2d27c6d37 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 17 Feb 2010 13:32:10 +0100 Subject: renaissance1: #i107215# Modified painting and layouting of page objects. --- .../ui/slidesorter/cache/SlsBitmapFactory.cxx | 17 +- .../controller/SlideSorterController.cxx | 7 + .../ui/slidesorter/controller/SlsAnimator.cxx | 118 +- .../ui/slidesorter/controller/SlsFocusManager.cxx | 9 + .../ui/slidesorter/controller/SlsProperties.cxx | 13 +- .../slidesorter/controller/SlsScrollBarManager.cxx | 5 +- .../controller/SlsSelectionFunction.cxx | 18 +- .../slidesorter/controller/SlsSelectionManager.cxx | 13 +- .../ui/slidesorter/inc/controller/SlsAnimator.hxx | 8 +- .../slidesorter/inc/controller/SlsProperties.hxx | 5 + .../inc/controller/SlsSelectionManager.hxx | 3 + .../slidesorter/inc/view/SlsPageObjectLayouter.hxx | 12 +- .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 7 + sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 15 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 7 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 6 +- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 106 +- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 60 +- .../slidesorter/view/SlsPageObjectViewContact.cxx | 143 -- .../view/SlsPageObjectViewObjectContact.cxx | 1421 -------------------- sd/source/ui/slidesorter/view/SlsTheme.cxx | 124 +- sd/source/ui/toolpanel/TaskPaneViewShell.cxx | 34 +- sd/source/ui/tools/PreviewRenderer.cxx | 4 +- 23 files changed, 375 insertions(+), 1780 deletions(-) delete mode 100644 sd/source/ui/slidesorter/view/SlsPageObjectViewContact.cxx delete mode 100644 sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index 77c833e3872a..596126c02b8b 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -44,6 +44,7 @@ #include #include +#include const static sal_Int32 gnSuperSampleFactor (2); @@ -56,7 +57,7 @@ namespace sd { namespace slidesorter { namespace cache { BitmapFactory::BitmapFactory (void) : maRenderer(NULL, false), - mbRemoveBorder(true) + mbRemoveBorder(false) { } @@ -92,7 +93,21 @@ BitmapFactory::~BitmapFactory (void) ::boost::shared_ptr pPreview (new BitmapEx(aPreview.GetBitmapEx())); if (mbRemoveBorder) + { + static sal_Int32 gnCounter (0); + SvFileStream aOut ( + ::rtl::OUString::createFromAscii("c:\\tmp\\image-") + +::rtl::OUString::valueOf(gnCounter) + +::rtl::OUString::createFromAscii(".png"), + STREAM_WRITE); + ::vcl::PNGWriter aWriter (*pPreview); + aWriter.Write(aOut); + ++gnCounter; + + OSL_ASSERT(pPreview->GetSizePixel() == aSize); pPreview->Crop(Rectangle(1,1,aSize.Width()-2,aSize.Height()-2)); + OSL_ASSERT(pPreview->GetSizePixel() == Size(aSize.Width()-2,aSize.Height()-2)); + } if (bDo) { #if 1 diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 8ee0f748fcd3..0f007284d2c0 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -54,6 +54,8 @@ #include "view/SlsViewOverlay.hxx" #include "view/SlsFontProvider.hxx" #include "view/SlsPageObjectLayouter.hxx" +#include "view/SlsPageObjectPainter.hxx" +#include "view/SlsTheme.hxx" #include "cache/SlsPageCache.hxx" #include "cache/SlsPageCacheManager.hxx" @@ -637,6 +639,11 @@ IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent) // When the system font has changed a layout has to be done. mrView.Resize(); FontProvider::Instance().Invalidate(); + + // Update theme colors. + mrSlideSorter.GetProperties()->HandleDataChangeEvent(); + mrSlideSorter.GetTheme()->Update(mrSlideSorter.GetProperties()); + mrView.GetPageObjectPainter()->SetTheme(mrSlideSorter.GetTheme()); } break; diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index 69be776179d3..a067428d50ab 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -48,15 +48,16 @@ class Animator::Animation public: Animation ( const Animator::AnimationFunctor& rAnimation, - const double nDelta, - const double nEnd, + const double nDuration, + const double nGlobalTime, const Animator::AnimationId nAnimationId, const Animator::FinishFunctor& rFinishFunctor); ~Animation (void); /** Run next animation step. If animation has reached its end it is expired. */ - bool Run (void); + bool Run (const double nGlobalTime); + /** Typically called when an animation has finished, but also from Animator::Disposed(). The finish functor is called and the animation is marked as expired to prevent another run. @@ -67,9 +68,9 @@ public: Animator::AnimationFunctor maAnimation; Animator::FinishFunctor maFinishFunctor; const Animator::AnimationId mnAnimationId; - double mnValue; + const double mnDuration; const double mnEnd; - const double mnDelta; + const double mnGlobalTimeAtStart; bool mbIsExpired; }; @@ -82,7 +83,8 @@ Animator::Animator (SlideSorter& rSlideSorter) mbIsDisposed(false), maAnimations(), mpDrawLock(), - mnNextAnimationId(0) + mnNextAnimationId(0), + maElapsedTime() { maTimer.SetTimeout(gnResolution); maTimer.SetTimeoutHdl(LINK(this,Animator,TimeoutHandler)); @@ -130,16 +132,16 @@ Animator::AnimationId Animator::AddAnimation ( if (mbIsDisposed) return -1; - const double nDelta = double(gnResolution) / double(nDuration); boost::shared_ptr pAnimation ( - new Animation(rAnimation, nDelta, 1.0, ++mnNextAnimationId, rFinishFunctor)); + new Animation( + rAnimation, + nDuration / 1000.0, + maElapsedTime.getElapsedTime(), + ++mnNextAnimationId, + rFinishFunctor)); maAnimations.push_back(pAnimation); - // Prevent redraws except for the ones in TimeoutHandler. - // While the Animator is active it will schedule repaints regularly. - // Repaints in between would only lead to visual artifacts. - mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter)); - maTimer.Start(); + RequestNextFrame(); return pAnimation->mnAnimationId; } @@ -158,14 +160,15 @@ Animator::AnimationId Animator::AddInfiniteAnimation ( return -1; boost::shared_ptr pAnimation ( - new Animation(rAnimation, nDelta, -1.0, mnNextAnimationId++, FinishFunctor())); + new Animation( + rAnimation, + -1, + maElapsedTime.getElapsedTime(), + mnNextAnimationId++, + FinishFunctor())); maAnimations.push_back(pAnimation); - // Prevent redraws except for the ones in TimeoutHandler. - // While the Animator is active it will schedule repaints regularly. - // Repaints in between would only lead to visual artifacts. - mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter)); - maTimer.Start(); + RequestNextFrame(); return pAnimation->mnAnimationId; } @@ -199,7 +202,7 @@ void Animator::RemoveAnimation (const Animator::AnimationId nId) -bool Animator::ProcessAnimations (void) +bool Animator::ProcessAnimations (const double nTime) { bool bExpired (false); @@ -212,7 +215,7 @@ bool Animator::ProcessAnimations (void) AnimationList::const_iterator iAnimation; for (iAnimation=aCopy.begin(); iAnimation!=aCopy.end(); ++iAnimation) { - bExpired |= (*iAnimation)->Run(); + bExpired |= (*iAnimation)->Run(nTime); } return bExpired; @@ -242,26 +245,34 @@ void Animator::CleanUpAnimationList (void) +void Animator::RequestNextFrame (const double nFrameStart) +{ + if ( ! maTimer.IsActive()) + { + // Prevent redraws except for the ones in TimeoutHandler. While the + // Animator is active it will schedule repaints regularly. Repaints + // in between would only lead to visual artifacts. + mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter)); + maTimer.Start(); + } +} + + + + IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) { if (mbIsDisposed) return 0; - OSL_TRACE("Animator timeout start"); - - if (ProcessAnimations()) + if (ProcessAnimations(maElapsedTime.getElapsedTime())) CleanUpAnimationList(); // Unlock the draw lock. This should lead to a repaint. mpDrawLock.reset(); if (maAnimations.size() > 0) - { - mpDrawLock.reset(new view::SlideSorterView::DrawLock(mrSlideSorter)); - maTimer.Start(); - } - - OSL_TRACE("Animator timeout end"); + RequestNextFrame(); return 0; } @@ -273,20 +284,26 @@ IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) Animator::Animation::Animation ( const Animator::AnimationFunctor& rAnimation, - const double nDelta, - const double nEnd, + const double nDuration, + const double nGlobalTime, const Animator::AnimationId nId, const Animator::FinishFunctor& rFinishFunctor) : maAnimation(rAnimation), maFinishFunctor(rFinishFunctor), mnAnimationId(nId), - mnValue(0), - mnEnd(nEnd), - mnDelta(nDelta), + mnDuration(nDuration), + mnEnd(nGlobalTime + nDuration), + mnGlobalTimeAtStart(nGlobalTime), mbIsExpired(false) { - maAnimation(mnValue); - mnValue = mnDelta; + if (mnDuration > 0) + maAnimation(0.0); + else if (mnDuration < 0) + maAnimation(nGlobalTime); + else + { + OSL_ASSERT(mnDuration != 0); + } } @@ -299,25 +316,30 @@ Animator::Animation::~Animation (void) -bool Animator::Animation::Run (void) +bool Animator::Animation::Run (const double nGlobalTime) { if ( ! mbIsExpired) { - if (mnEnd>=0 && mnValue>=mnEnd) + if (mnDuration > 0) { - maAnimation(mnEnd); - Expire(); - return true; + if (nGlobalTime >= mnEnd) + { + maAnimation(1.0); + Expire(); + } + else + { + maAnimation((nGlobalTime - mnGlobalTimeAtStart) / mnDuration); + } } - else + else if (mnDuration < 0) { - maAnimation(mnValue); - mnValue += mnDelta; - return false; + // Animations without end have to be expired by their owner. + maAnimation(nGlobalTime); } } - else - return true; + + return mbIsExpired; } diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index 0c0213e9e702..900658c4bcad 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -35,6 +35,7 @@ #include "PaneDockingWindow.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsSelectionManager.hxx" +#include "controller/SlsCurrentSlideManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" @@ -44,6 +45,8 @@ #include "Window.hxx" #include "sdpage.hxx" +#define UNIFY_FOCUS_AND_CURRENT_PAGE + namespace sd { namespace slidesorter { namespace controller { FocusManager::FocusManager (SlideSorter& rSlideSorter) @@ -164,7 +167,11 @@ void FocusManager::MoveFocus (FocusMoveDirection eDirection) } if (mbPageIsFocused) + { +#ifndef UNIFY_FOCUS_AND_CURRENT_PAGE ShowFocusIndicator(GetFocusedPageDescriptor(), true); +#endif + } } } @@ -288,6 +295,7 @@ void FocusManager::ShowFocusIndicator ( const model::SharedPageDescriptor& rpDescriptor, const bool bScrollToFocus) { +#ifndef UNIFY_FOCUS_AND_CURRENT_PAGE if (rpDescriptor.get() != NULL) { mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true); @@ -303,6 +311,7 @@ void FocusManager::ShowFocusIndicator ( mrSlideSorter.GetView().RequestRepaint (rpDescriptor); NotifyFocusChangeListeners(); } +#endif } diff --git a/sd/source/ui/slidesorter/controller/SlsProperties.cxx b/sd/source/ui/slidesorter/controller/SlsProperties.cxx index 829cc1b05368..48cc8a705cde 100644 --- a/sd/source/ui/slidesorter/controller/SlsProperties.cxx +++ b/sd/source/ui/slidesorter/controller/SlsProperties.cxx @@ -45,7 +45,7 @@ Properties::Properties (void) mbIsSuspendPreviewUpdatesDuringFullScreenPresentation(true), maBackgroundColor(Application::GetSettings().GetStyleSettings().GetWindowColor()), maTextColor(Application::GetSettings().GetStyleSettings().GetActiveTextColor()), - maSelectionColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()), + maSelectionColor(Application::GetSettings().GetStyleSettings().GetHighlightColor()), maHighlightColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()), mbIsUIReadOnly(false) { @@ -61,6 +61,17 @@ Properties::~Properties (void) +void Properties::HandleDataChangeEvent (void) +{ + maBackgroundColor = Application::GetSettings().GetStyleSettings().GetWindowColor(); + maTextColor = Application::GetSettings().GetStyleSettings().GetActiveTextColor(); + maSelectionColor = Application::GetSettings().GetStyleSettings().GetHighlightColor(); + maHighlightColor = Application::GetSettings().GetStyleSettings().GetMenuHighlightColor(); +} + + + + bool Properties::IsHighlightCurrentSlide (void) const { return mbIsHighlightCurrentSlide; diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index 5f4e2b3c1fb5..63daebe6544d 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -500,10 +500,11 @@ void ScrollBarManager::SetTop (const sal_Int32 nNewTop) // Flush pending repaints before scrolling to avoid temporary artifacts. mrSlideSorter.GetContentWindow()->Update(); + OSL_TRACE("setting top of vertical scroll bar to %d", nNewTop); mpVerticalScrollBar->SetThumbPos(nNewTop); mnVerticalPosition = double(nNewTop) / double(mpVerticalScrollBar->GetRange().Len()); - mrSlideSorter.GetContentWindow()->SetVisibleXY ( - mnHorizontalPosition, mnVerticalPosition); + mrSlideSorter.GetContentWindow()->SetVisibleXY (mnHorizontalPosition, mnVerticalPosition); + mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); } } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 362bd4abf17f..1c61a14ac261 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -353,16 +353,16 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) (rEvent.GetButtons() & MOUSE_LEFT)!=0); } - Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel()); - if ( ! aRectangle.IsInside(aMousePosition) - && mpSubstitutionHandler) + if (rEvent.IsLeaveWindow()) { - // Mouse left the window with pressed left button. Make it a drag. - StartDrag(aMousePosition); - // Mouse motion events are not sent to us while the mouse is outside - // the window and drag&drop is active. Therefore hide the - // substitution. - // mpSubstitutionHandler->Hide(); + // Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel()); + // if ( ! aRectangle.IsInside(aMousePosition) + if (mpSubstitutionHandler) + { + // Mouse left the window with pressed left button. Make it a drag. + StartDrag(aMousePosition); + } + mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); } else { diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index ff511b60625e..432d370234f1 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -105,7 +105,9 @@ SelectionManager::SelectionManager (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mrController(rSlideSorter.GetController()), maSelectionBeforeSwitch(), - mbIsMakeSelectionVisiblePending(true) + mbIsMakeSelectionVisiblePending(true), + mnInsertionPosition(-1), + mnAnimationId(Animator::NotAnAnimationId) { } @@ -440,9 +442,13 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) if (nNewTop != aVisibleArea.Top()) { if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) - mrController.GetAnimator()->AddAnimation( + { + if (mnAnimationId != Animator::NotAnAnimationId) + mrController.GetAnimator()->RemoveAnimation(mnAnimationId); + mnAnimationId = mrController.GetAnimator()->AddAnimation( VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop), 300); + } else VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop)(1.0); } @@ -644,10 +650,13 @@ void VerticalVisibleAreaScroller::operator() (const double nTime) { const double nLocalTime (maAccelerationFunction(nTime)); const sal_Int32 nNewTop (mnStart * (1.0 - nLocalTime) + mnEnd * nLocalTime); + mrSlideSorter.GetController().GetScrollBarManager().SetTop(nNewTop); + /* mrSlideSorter.GetViewShell()->Scroll( 0, nNewTop - mrSlideSorter.GetController().GetScrollBarManager().GetTop()); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); + */ } diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx index e9683e0dc075..6a63060316f1 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx @@ -34,6 +34,7 @@ #include "SlideSorter.hxx" #include "view/SlideSorterView.hxx" +#include #include #include #include @@ -99,6 +100,7 @@ private: class Animation; typedef ::std::vector > AnimationList; AnimationList maAnimations; + ::canvas::tools::ElapsedTime maElapsedTime; ::boost::scoped_ptr mpDrawLock; @@ -107,15 +109,19 @@ private: DECL_LINK(TimeoutHandler, Timer*); /** Execute one step of every active animation. + @param nTime + Time measured in milli seconds with some arbitrary reference point. @return When one or more animation has finished then is returned. Call CleanUpAnimationList() in this case. */ - bool ProcessAnimations (void); + bool ProcessAnimations (const double nTime); /** Remove animations that have expired. */ void CleanUpAnimationList (void); + + void RequestNextFrame (const double nFrameStart = 0); }; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx index 53a72a5ec6cf..15aa980aaca5 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx @@ -44,6 +44,11 @@ public: Properties (void); ~Properties (void); + /** Call this method after receiving a VCLEVENT_APPLICATION_DATACHANGED + event. + */ + void HandleDataChangeEvent (void); + /** When this method returns then the current slide is highlighted in the view. The default value is . */ diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx index 665d01a89987..47bcafe134f4 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx @@ -33,6 +33,7 @@ #define SD_SLIDESORTER_CONTROLLER_SELECTION_MANAGER_HXX #include "model/SlsSharedPageDescriptor.hxx" +#include "controller/SlsAnimator.hxx" #include #include #include @@ -175,6 +176,8 @@ private: */ sal_Int32 mnInsertionPosition; + Animator::AnimationId mnAnimationId; + /** Delete the given list of normal pages. This method is a helper function for DeleteSelectedPages(). @param rSelectedNormalPages diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx index 65f67efaeb22..026b60238d91 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx @@ -73,6 +73,8 @@ public: MouseOverIndicator, // Bounding box of the page number. PageNumber, + // Bounding box of the frame that sometimes is painted around the page number. + PageNumberFrame, // Bounding box of the pane name. Name, // Indicator whether or not there is a slide transition associated @@ -140,18 +142,12 @@ public: const Point& rWindowLocation); private: - /// Minimal border around the page number area. - static const sal_Int32 mnPageNumberOffset; - static const sal_Int32 mnOuterBorderWidth; - static const sal_Int32 mnInfoAreaMinWidth; - static const Size maButtonSize; - static const sal_Int32 mnButtonGap; - SharedSdWindow mpWindow; Size maPageObjectSize; double mnModelToWindowScale; Rectangle maPageObjectBoundingBox; Rectangle maPageNumberAreaBoundingBox; + Rectangle maPageNumberFrameBoundingBox; Rectangle maPreviewBoundingBox; Rectangle maTransitionEffectBoundingBox; Rectangle maButtonAreaBoundingBox; @@ -161,7 +157,7 @@ private: Rectangle CalculatePreviewBoundingBox ( Size& rPageObjectSize, const Size& rPreviewModelSize, - const sal_Int32 nInfoAreaWidth); + const sal_Int32 nPageNumberAreaWidth); }; diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index 4b01376aaeeb..ec42b3db4fd9 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -62,6 +62,13 @@ public: void NotifyResize (void); + /** Called when the theme changes, either because it is replaced with + another or because the system colors have changed. So, even when + the given theme is the same object as the one already in use by this + painter everything that depends on the theme is updated. + */ + void SetTheme (const ::boost::shared_ptr& rpTheme); + private: const Layouter& mrLayouter; ::boost::shared_ptr mpPageObjectLayouter; diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index c8bdfd6e9882..ad6a9ee7b2cb 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -76,7 +76,9 @@ public: ButtonBackground, MouseOverColor, PageNumberBorder, - Selection + PageNumberColor, + Selection, + PreviewBorder }; ColorData GetColor (const ColorType eType); @@ -103,7 +105,18 @@ public: BitmapEx GetIcon (const IconType eType); private: + class GradientDescriptor + { + public: + ColorData maFillColor1; + ColorData maFillColor2; + ColorData maBorderColor1; + ColorData maBorderColor2; + }; ColorData maBackgroundColor; + GradientDescriptor maNormalGradient; + GradientDescriptor maSelectedGradient; + GradientDescriptor maMouseOverGradient; BitmapEx maRawShadow; BitmapEx maInsertionIndicator; }; diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 1f77a40df57b..ceef51c8071b 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -525,7 +525,8 @@ void SlideSorterView::PostModelChange (void) model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); // The new page objects have to be scaled and positioned. - Layout (); + Layout(); + RequestRepaint(); } @@ -792,9 +793,9 @@ void SlideSorterView::CompleteRedraw ( sdr::contact::ViewObjectContactRedirector* pRedirector) { const double nStartTime (gaTimer.getElapsedTime()); - OSL_TRACE("SlideSorterView::CompleteRedraw start at %f, %d", + OSL_TRACE("SlideSorterView::CompleteRedraw start at %f, %s", nStartTime, - mnLockRedrawSmph); + mnLockRedrawSmph ? "locked" : ""); if (pDevice == NULL || pDevice!=mrSlideSorter.GetContentWindow().get()) return; diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 5eab152419eb..0f69e892779b 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -48,8 +48,8 @@ Layouter::Layouter (const SharedSdWindow& rpWindow) mnRightBorder(30), mnTopBorder(10), mnBottomBorder(10), - mnVerticalGap (20), - mnHorizontalGap (20), + mnVerticalGap (10), + mnHorizontalGap (10), mnMinimalWidth (100), mnPreferredWidth (200), mnMaximalWidth (300), @@ -477,7 +477,7 @@ Point Layouter::GetInsertionMarkerLocation ( if (bLeftOrTop) { // Above. - aLocation.setY(aBox.Top() - mnVerticalGap/2); + aLocation.setY(aBox.Top() - (mnVerticalGap+1)/2 - 1); } else { diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx index be5c5066863a..10cd7ca93ef6 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -39,12 +39,15 @@ namespace sd { namespace slidesorter { namespace view { -const sal_Int32 PageObjectLayouter::mnPageNumberOffset = 9; -const sal_Int32 PageObjectLayouter::mnOuterBorderWidth = 6; -const sal_Int32 PageObjectLayouter::mnInfoAreaMinWidth = 26; -const Size PageObjectLayouter::maButtonSize (32,32); -const sal_Int32 PageObjectLayouter::mnButtonGap (5); - +namespace { +const static sal_Int32 gnPageNumberOffset = 5; +const static sal_Int32 gnPageNumberFrameHorizontalOffset = 2; +const static sal_Int32 gnPageNumberFrameVerticalOffset = 1; +const static sal_Int32 gnOuterBorderWidth = 6; +const static sal_Int32 gnInfoAreaMinWidth = 26; +const static Size gaButtonSize (32,32); +const static sal_Int32 gnButtonGap (5); +} PageObjectLayouter::PageObjectLayouter ( const Size& rPageObjectWindowSize, @@ -63,37 +66,41 @@ PageObjectLayouter::PageObjectLayouter ( { const Size aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount)); - const int nMaximumBorderWidth (mnOuterBorderWidth); - - // Set up some bounding boxes relative to the page object origin. - - maPageNumberAreaBoundingBox = Rectangle( - mnPageNumberOffset, - nMaximumBorderWidth, - mnPageNumberOffset + aPageNumberAreaSize.Width(), - nMaximumBorderWidth + aPageNumberAreaSize.Height()); + const int nMaximumBorderWidth (gnOuterBorderWidth); maPreviewBoundingBox = CalculatePreviewBoundingBox( maPageObjectSize, Size(rPageSize.Width(), rPageSize.Height()), - ::std::min(aPageNumberAreaSize.Width(), mnInfoAreaMinWidth)); + aPageNumberAreaSize.Width()); maPageObjectBoundingBox = Rectangle(Point(0,0), maPageObjectSize); + maPageNumberAreaBoundingBox = Rectangle( + Point( + maPreviewBoundingBox.Left() + - gnPageNumberOffset + - gnPageNumberFrameHorizontalOffset + - aPageNumberAreaSize.Width(), + nMaximumBorderWidth), + aPageNumberAreaSize); + + maPageNumberFrameBoundingBox = Rectangle( + maPageNumberAreaBoundingBox.Left() - gnPageNumberFrameHorizontalOffset, + maPageNumberAreaBoundingBox.Top() - gnPageNumberFrameVerticalOffset, + maPageNumberAreaBoundingBox.Right() + gnPageNumberFrameHorizontalOffset, + maPageNumberAreaBoundingBox.Bottom() + gnPageNumberFrameVerticalOffset); + const Size aIconSize (maTransitionEffectIcon.GetSizePixel()); - const int nLeft (maPreviewBoundingBox.Left() - - mnPageNumberOffset - aIconSize.Width() - nMaximumBorderWidth); - const int nTop (maPreviewBoundingBox.Bottom() - aIconSize.Height()); maTransitionEffectBoundingBox = Rectangle( - nLeft, - nTop, - nLeft + aIconSize.Width(), - nTop + aIconSize.Height()); + Point( + (maPreviewBoundingBox.Left() - aIconSize.Width()) / 2, + maPreviewBoundingBox.Bottom() - aIconSize.Height()), + aIconSize); maButtonAreaBoundingBox = Rectangle( 0, - maPageObjectBoundingBox.Bottom() - maButtonSize.Height() - mnButtonGap, - maPageObjectBoundingBox.Right() - mnButtonGap, - maPageObjectBoundingBox.Bottom() - mnButtonGap); + maPageObjectBoundingBox.Bottom() - gaButtonSize.Height() - gnButtonGap, + maPageObjectBoundingBox.Right() - gnButtonGap, + maPageObjectBoundingBox.Bottom() - gnButtonGap); } @@ -109,42 +116,44 @@ PageObjectLayouter::~PageObjectLayouter(void) Rectangle PageObjectLayouter::CalculatePreviewBoundingBox ( Size& rPageObjectSize, const Size& rPageSize, - const sal_Int32 nInfoAreaWidth) + const sal_Int32 nPageNumberAreaWidth) { - const int nMaximumBorderWidth (mnOuterBorderWidth); - const int nLeftAreaWidth ( - 2*mnPageNumberOffset - + ::std::max( - nInfoAreaWidth, - maTransitionEffectIcon.GetSizePixel().Width())); - int nPreviewWidth; - int nPreviewHeight; + const sal_Int32 nIconWidth (maTransitionEffectIcon.GetSizePixel().Width()); + const sal_Int32 nLeftAreaWidth ( + ::std::max( + gnInfoAreaMinWidth, + 2*gnPageNumberOffset + + ::std::max( + nPageNumberAreaWidth + 2 * gnPageNumberFrameHorizontalOffset, + nIconWidth))); + sal_Int32 nPreviewWidth; + sal_Int32 nPreviewHeight; const double nPageAspectRatio (double(rPageSize.Width()) / double(rPageSize.Height())); if (rPageObjectSize.Height() == 0) { // Calculate height so that the preview fills the available // horizontal space completely while observing the aspect ratio of // the preview. - nPreviewWidth = rPageObjectSize.Width() - nLeftAreaWidth - 2*nMaximumBorderWidth - 1; + nPreviewWidth = rPageObjectSize.Width() - nLeftAreaWidth - gnOuterBorderWidth - 1; nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio); - rPageObjectSize.setHeight(nPreviewHeight + 2*nMaximumBorderWidth + 1); + rPageObjectSize.setHeight(nPreviewHeight + 2*gnOuterBorderWidth + 1); } else if (rPageObjectSize.Width() == 0) { // Calculate the width of the page object so that the preview fills // the available vertical space completely while observing the // aspect ratio of the preview. - nPreviewHeight = rPageObjectSize.Height() - 2*nMaximumBorderWidth - 1; + nPreviewHeight = rPageObjectSize.Height() - 2*gnOuterBorderWidth - 1; nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio); - rPageObjectSize.setWidth(nPreviewWidth + nLeftAreaWidth + 2*nMaximumBorderWidth + 1); + rPageObjectSize.setWidth(nPreviewWidth + nLeftAreaWidth + gnOuterBorderWidth + 1); } else { // The size of the page object is given. Calculate the size of the // preview. - nPreviewWidth = rPageObjectSize.Width() - nLeftAreaWidth - 2*nMaximumBorderWidth - 1; - nPreviewHeight = rPageObjectSize.Height() - 2*nMaximumBorderWidth - 1; + nPreviewWidth = rPageObjectSize.Width() - nLeftAreaWidth - gnOuterBorderWidth - 1; + nPreviewHeight = rPageObjectSize.Height() - gnOuterBorderWidth - 1; if (double(nPreviewWidth)/double(nPreviewHeight) > nPageAspectRatio) nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio); else @@ -152,9 +161,8 @@ Rectangle PageObjectLayouter::CalculatePreviewBoundingBox ( } // When the preview does not fill the available space completely then // place it flush right and vertically centered. - const int nLeft (rPageObjectSize.Width() - nMaximumBorderWidth - nPreviewWidth - 1); - const int nTop (nMaximumBorderWidth - + (rPageObjectSize.Height() - 2*nMaximumBorderWidth - nPreviewHeight)/2); + const int nLeft (rPageObjectSize.Width() - gnOuterBorderWidth - nPreviewWidth - 1); + const int nTop ((rPageObjectSize.Height() - nPreviewHeight)/2); return Rectangle( nLeft, nTop, @@ -187,6 +195,10 @@ Rectangle PageObjectLayouter::GetBoundingBox ( aBoundingBox = maPageNumberAreaBoundingBox; break; + case PageNumberFrame: + aBoundingBox = maPageNumberFrameBoundingBox; + break; + case Name: aBoundingBox = maPageNumberAreaBoundingBox; break; @@ -203,9 +215,9 @@ Rectangle PageObjectLayouter::GetBoundingBox ( aBoundingBox = Rectangle( maPageObjectBoundingBox.BottomRight() - Point( - (nIndex+1)*(maButtonSize.Width() + mnButtonGap), - maButtonSize.Height() + mnButtonGap), - maButtonSize); + (nIndex+1)*(gaButtonSize.Width() + gnButtonGap), + gaButtonSize.Height() + gnButtonGap), + gaButtonSize); break; } diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index f0edc65efd4a..6fd2fbf55bc3 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -300,6 +300,15 @@ void PageObjectPainter::NotifyResize (void) +void PageObjectPainter::SetTheme (const ::boost::shared_ptr& rpTheme) +{ + mpTheme = rpTheme; + NotifyResize(); +} + + + + void PageObjectPainter::PaintBackground ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const @@ -357,15 +366,6 @@ void PageObjectPainter::PaintPreview ( rDevice.DrawBitmapEx(aBox.TopLeft(), aBitmap); } - - // Draw border around preview. - --aBox.Left(); - --aBox.Top(); - ++aBox.Right(); - ++aBox.Bottom(); - rDevice.SetLineColor(Color(0,0,0)); - rDevice.SetFillColor(); - rDevice.DrawRect(aBox); } @@ -375,7 +375,7 @@ void PageObjectPainter::PaintPageNumber ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const { - Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::PageNumber, PageObjectLayouter::WindowCoordinateSystem)); @@ -385,22 +385,22 @@ void PageObjectPainter::PaintPageNumber ( const sal_Int32 nPageNumber ((rpDescriptor->GetPage()->GetPageNum() - 1) / 2 + 1); const String sPageNumber (String::CreateFromInt32(nPageNumber)); rDevice.SetFont(*mpPageNumberFont); - rDevice.SetTextColor(Color(0x0848a8f)); - rDevice.DrawText(aBox.TopLeft(), sPageNumber); + rDevice.SetTextColor(Color(mpTheme->GetColor(Theme::PageNumberColor))); + rDevice.DrawText(aBox, sPageNumber, TEXT_DRAW_RIGHT | TEXT_DRAW_VCENTER); if (rpDescriptor->GetVisualState().GetCurrentVisualState() == model::VisualState::VS_Excluded) { // Paint border around the number. - aBox.Left()-= 2; - aBox.Top() -= 1; - aBox.Right() += 2; - aBox.Bottom() += 1; + const Rectangle aFrameBox (mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::PageNumberFrame, + PageObjectLayouter::WindowCoordinateSystem)); rDevice.SetLineColor(Color(mpTheme->GetColor(Theme::PageNumberBorder))); rDevice.SetFillColor(); - rDevice.DrawRect(aBox); + rDevice.DrawRect(aFrameBox); - rDevice.DrawLine(aBox.TopLeft(), aBox.BottomRight()); + rDevice.DrawLine(aFrameBox.TopLeft(), aBox.BottomRight()); } } @@ -536,7 +536,6 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( // Paint the background with a linear gradient that starts some pixels // below the top and ends some pixels above the bottom. -#if 1 const sal_Int32 nDefaultConstantSize(aSize.Height()/4); const sal_Int32 nMinimalGradientSize(40); const sal_Int32 nHeight (aSize.Height()); @@ -563,15 +562,6 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( } aBitmapDevice.DrawLine(Point(0,nY), Point(aSize.Width(),nY)); } -#else - const Color aTopColor(mpTheme->GetColor(eColorType, Theme::Fill1)); - const Color aBottomColor(mpTheme->GetColor(eColorType, Theme::Fill2)); - Color aColor (aTopColor); - aColor.Merge(aBottomColor, 128); - aBitmapDevice.SetFillColor(aColor); - aBitmapDevice.SetLineColor(aColor); - aBitmapDevice.DrawRect(Rectangle(Point(0,0), aSize)); -#endif // Paint the border. aBitmapDevice.SetFillColor(); @@ -582,15 +572,17 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( // Get bounding box of the preview around which a shadow is painted. // Compensate for the border around the preview. - Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( model::SharedPageDescriptor(), PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem)); - aBox.Left() -= 1; - aBox.Top() -= 1; - aBox.Right() += 1; - aBox.Bottom() += 1; - mpShadowPainter->PaintFrame(aBitmapDevice, aBox); + 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::Background)); + aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::PreviewBorder)); + aBitmapDevice.DrawRect(aFrameBox); return aBitmapDevice.GetBitmap (Point(0,0),aSize); } diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectViewContact.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectViewContact.cxx deleted file mode 100644 index 5849140f8327..000000000000 --- a/sd/source/ui/slidesorter/view/SlsPageObjectViewContact.cxx +++ /dev/null @@ -1,143 +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: SlsPageObjectViewContact.cxx,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. - * - ************************************************************************/ - -#include "precompiled_sd.hxx" - -#include "view/SlsPageObjectViewContact.hxx" - -#include "model/SlsPageDescriptor.hxx" -#include "controller/SlsPageObjectFactory.hxx" - -#include -#include - -#include -#include - -using namespace ::sdr::contact; - -namespace sd { namespace slidesorter { namespace view { - - -PageObjectViewContact::PageObjectViewContact ( - SdrPageObj& rPageObj, - const model::SharedPageDescriptor& rpDescriptor) - : ViewContactOfPageObj (rPageObj), - mbInDestructor(false), - mpDescriptor(rpDescriptor) -{ -} - -PageObjectViewContact::~PageObjectViewContact (void) -{ - // remember that this instance is in destruction - mbInDestructor = true; -} - - - -ViewObjectContact& - PageObjectViewContact::CreateObjectSpecificViewObjectContact( - ObjectContact& rObjectContact) -{ - OSL_ASSERT(mpDescriptor.get()!=NULL); - - ViewObjectContact* pResult - = mpDescriptor->GetPageObjectFactory().CreateViewObjectContact ( - rObjectContact, - *this); - DBG_ASSERT (pResult!=NULL, - "PageObjectViewContact::CreateObjectSpecificViewObjectContact() was not able to create object."); - return *pResult; -} - -const SdrPage* PageObjectViewContact::GetPage (void) const -{ - // when this instance itself is in destruction, do no longer - // provide the referenced page to VOC childs of this OC. This - // happens e.g. in destructor which destroys all child-VOCs which - // may in their implementation still reference their VC from - // their own destructor - if (!mbInDestructor) - return GetReferencedPage(); - else - return NULL; -} - -void PageObjectViewContact::ActionChanged (void) -{ - ViewContactOfPageObj::ActionChanged(); -} - -Rectangle PageObjectViewContact::GetPageObjectBoundingBox (void) const -{ - // use model data directly here - OSL_ASSERT(mpDescriptor.get()!=NULL); - Rectangle aRetval(GetPageObject().GetLastBoundRect()); - const SvBorder aPageDescriptorBorder(mpDescriptor->GetModelBorder()); - - aRetval.Left() -= aPageDescriptorBorder.Left(); - aRetval.Top() -= aPageDescriptorBorder.Top(); - aRetval.Right() += aPageDescriptorBorder.Right(); - aRetval.Bottom() += aPageDescriptorBorder.Bottom(); - - return aRetval; -} - -SdrPageObj& PageObjectViewContact::GetPageObject (void) const -{ - return ViewContactOfPageObj::GetPageObj(); -} - -drawinglayer::primitive2d::Primitive2DSequence PageObjectViewContact::createViewIndependentPrimitive2DSequence() const -{ - // ceate graphical visualisation data. Since this is the view-independent version which should not be used, - // create a replacement graphic visualisation here. Use GetLastBoundRect to access the model data directly - // which is aOutRect for SdrPageObj. - OSL_ASSERT(mpDescriptor.get()!=NULL); - Rectangle aModelRectangle(GetPageObj().GetLastBoundRect()); - const SvBorder aBorder(mpDescriptor->GetModelBorder()); - - aModelRectangle.Left() -= aBorder.Left(); - aModelRectangle.Right() += aBorder.Right(); - aModelRectangle.Top() -= aBorder.Top(); - aModelRectangle.Bottom() += aBorder.Bottom(); - - const basegfx::B2DRange aModelRange(aModelRectangle.Left(), aModelRectangle.Top(), aModelRectangle.Right(), aModelRectangle.Bottom()); - const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aModelRange)); - const basegfx::BColor aYellow(1.0, 1.0, 0.0); - const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow)); - - return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); -} - -} } } // end of namespace ::sd::slidesorter::view - -// eof diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx deleted file mode 100644 index 8c3fd4532c4f..000000000000 --- a/sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx +++ /dev/null @@ -1,1421 +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: SlsPageObjectViewObjectContact.cxx,v $ - * $Revision: 1.23 $ - * - * 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/SlsPageObjectViewObjectContact.hxx" - -#include "controller/SlsProperties.hxx" -#include "view/SlideSorterView.hxx" -#include "view/SlsPageObjectViewContact.hxx" -#include "view/SlsPageObject.hxx" -#include "view/SlsFontProvider.hxx" -#include "model/SlsPageDescriptor.hxx" -#include "cache/SlsPageCache.hxx" -#include "cache/SlsPageCacheManager.hxx" -#include "res_bmp.hrc" -#include "tools/IconCache.hxx" -#include "PreviewRenderer.hxx" - -#include "sdpage.hxx" -#include "sdresid.hxx" -#include "glob.hrc" -#include "drawdoc.hxx" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace ::sdr::contact; -using namespace ::sd::slidesorter::model; - -using drawinglayer::primitive2d::Primitive2DReference; -using drawinglayer::primitive2d::Primitive2DSequence; - -namespace sd { namespace slidesorter { namespace view { - - -const sal_Int32 PageObjectViewObjectContact::mnSelectionIndicatorOffset = 2; -const sal_Int32 PageObjectViewObjectContact::mnSelectionIndicatorThickness = 3; -const sal_Int32 PageObjectViewObjectContact::mnFocusIndicatorOffset = 3; -const sal_Int32 PageObjectViewObjectContact::mnFadeEffectIndicatorOffset = 9; -const sal_Int32 PageObjectViewObjectContact::mnFadeEffectIndicatorSize = 14; -const sal_Int32 PageObjectViewObjectContact::mnPageNumberOffset = 9; -const sal_Int32 PageObjectViewObjectContact::mnMouseOverEffectOffset = 3; -const sal_Int32 PageObjectViewObjectContact::mnMouseOverEffectThickness = 1; - -PageObjectViewObjectContact::PageObjectViewObjectContact ( - ObjectContact& rObjectContact, - ViewContact& rViewContact, - const ::boost::shared_ptr& rpCache, - const ::boost::shared_ptr& rpProperties) - : ViewObjectContactOfPageObj(rObjectContact, rViewContact), - mbInDestructor(false), - mxCurrentPageContents(), - mpCache(rpCache), - mpProperties(rpProperties) -{ - SharedPageDescriptor pDescriptor (GetPageDescriptor()); - OSL_ASSERT(pDescriptor.get()!=NULL); - if (pDescriptor.get() != NULL) - pDescriptor->SetViewObjectContact(this); -} - - - - -PageObjectViewObjectContact::~PageObjectViewObjectContact (void) -{ - mbInDestructor = true; - - GetPageDescriptor()->SetViewObjectContact(NULL); - - if (mpCache.get() != NULL) - { - const SdrPage* pPage = GetPage(); - - if(pPage) - { - mpCache->ReleasePreviewBitmap(GetPage()); - } - } -} - - - - -void PageObjectViewObjectContact::SetCache (const ::boost::shared_ptr& rpCache) -{ - mpCache = rpCache; -} - - - - -Rectangle PageObjectViewObjectContact::GetBoundingBox ( - OutputDevice& rDevice, - BoundingBoxType eType, - CoordinateSystem eCoordinateSystem) const -{ - // Most of the bounding boxes are based on the bounding box of the preview. - // SdrPageObj is a SdrObject, so use SdrObject::aOutRect as model data - const PageObjectViewContact& rPaObVOC(static_cast(GetViewContact())); - Rectangle aBoundingBox(rPaObVOC.GetPageObject().GetLastBoundRect()); - - CoordinateSystem eCurrentCoordinateSystem (ModelCoordinateSystem); - switch(eType) - { - case PageObjectBoundingBox: - { - const SvBorder aPageDescriptorBorder(GetPageDescriptor()->GetModelBorder()); - aBoundingBox.Left() -= aPageDescriptorBorder.Left(); - aBoundingBox.Top() -= aPageDescriptorBorder.Top(); - aBoundingBox.Right() += aPageDescriptorBorder.Right(); - aBoundingBox.Bottom() += aPageDescriptorBorder.Bottom(); - break; - } - case PreviewBoundingBox: - { - // The aBoundingBox already has the right value. - break; - } - case MouseOverIndicatorBoundingBox: - { - const sal_Int32 nBorderWidth (mnMouseOverEffectOffset+mnMouseOverEffectThickness); - const Size aBorderSize (rDevice.PixelToLogic(Size(nBorderWidth,nBorderWidth))); - aBoundingBox.Left() -= aBorderSize.Width(); - aBoundingBox.Top() -= aBorderSize.Height(); - aBoundingBox.Right() += aBorderSize.Width(); - aBoundingBox.Bottom() += aBorderSize.Height(); - break; - } - case FocusIndicatorBoundingBox: - { - const sal_Int32 nBorderWidth (mnFocusIndicatorOffset+1); - const Size aBorderSize (rDevice.PixelToLogic(Size(nBorderWidth,nBorderWidth))); - aBoundingBox.Left() -= aBorderSize.Width(); - aBoundingBox.Top() -= aBorderSize.Height(); - aBoundingBox.Right() += aBorderSize.Width(); - aBoundingBox.Bottom() += aBorderSize.Height(); - break; - } - case SelectionIndicatorBoundingBox: - { - const sal_Int32 nBorderWidth(mnSelectionIndicatorOffset+mnSelectionIndicatorThickness); - const Size aBorderSize (rDevice.PixelToLogic(Size(nBorderWidth,nBorderWidth))); - aBoundingBox.Left() -= aBorderSize.Width(); - aBoundingBox.Top() -= aBorderSize.Height(); - aBoundingBox.Right() += aBorderSize.Width(); - aBoundingBox.Bottom() += aBorderSize.Height(); - break; - } - case PageNumberBoundingBox: - { - Size aModelOffset = rDevice.PixelToLogic(Size(mnPageNumberOffset,mnPageNumberOffset)); - Size aNumberSize (GetPageDescriptor()->GetPageNumberAreaModelSize()); - aBoundingBox = Rectangle ( - Point ( - aBoundingBox.Left() - aModelOffset.Width() - aNumberSize.Width(), - aBoundingBox.Top()), - aNumberSize); - break; - } - - case NameBoundingBox: - break; - - case FadeEffectIndicatorBoundingBox: - Size aModelOffset = rDevice.PixelToLogic(Size (0, mnFadeEffectIndicatorOffset)); - // Flush left just outside the selection rectangle. - aBoundingBox = Rectangle ( - Point ( - aBoundingBox.Left(), - aBoundingBox.Bottom() + aModelOffset.Height() - ), - rDevice.PixelToLogic ( - IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR).GetSizePixel()) - ); - break; - } - - // Make sure the bounding box uses the requested coordinate system. - if (eCurrentCoordinateSystem != eCoordinateSystem) - { - if (eCoordinateSystem == ModelCoordinateSystem) - aBoundingBox = Rectangle( - rDevice.PixelToLogic(aBoundingBox.TopLeft()), - rDevice.PixelToLogic(aBoundingBox.GetSize())); - else - aBoundingBox = Rectangle( - rDevice.LogicToPixel(aBoundingBox.TopLeft()), - rDevice.LogicToPixel(aBoundingBox.GetSize())); - } - return aBoundingBox; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -// example implementation for primitive usage for PageObjectViewObjectContact - -} } } // end of namespace ::sd::slidesorter::view - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sd { namespace slidesorter { namespace view { - -/////////////////////////////////////////////////////////////////////////////////////////////// -// All primitives for SdrPageObject visualisation are based on one range which describes -// the size of the inner rectangle for PagePreview visualisation. Use a common implementation -// class for all derived SdPageObjectPrimitives. The SdPageObjectBasePrimitive itself -// is pure virtual - -class SdPageObjectBasePrimitive : public drawinglayer::primitive2d::BufferedDecompositionPrimitive2D -{ -private: - // the inner range of the SdPageObject visualisation - basegfx::B2DRange maRange; - -public: - // constructor and destructor - SdPageObjectBasePrimitive(const basegfx::B2DRange& rRange); - virtual ~SdPageObjectBasePrimitive(); - - // data access - const basegfx::B2DRange& getPageObjectRange() const { return maRange; } - - // compare operator - virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const; -}; - -SdPageObjectBasePrimitive::SdPageObjectBasePrimitive(const basegfx::B2DRange& rRange) -: drawinglayer::primitive2d::BufferedDecompositionPrimitive2D(), - maRange(rRange) -{ -} - -SdPageObjectBasePrimitive::~SdPageObjectBasePrimitive() -{ -} - -bool SdPageObjectBasePrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const -{ - if(drawinglayer::primitive2d::BufferedDecompositionPrimitive2D::operator==(rPrimitive)) - { - const SdPageObjectBasePrimitive& rCompare = static_cast< const SdPageObjectBasePrimitive& >(rPrimitive); - return (getPageObjectRange() == rCompare.getPageObjectRange()); - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -// SdPageObjectPrimitive for selected visualisation - -class SdPageObjectPageBitmapPrimitive : public SdPageObjectBasePrimitive -{ -private: - // the bitmap containing the PagePreview - BitmapEx maBitmapEx; - -protected: - // method which is to be used to implement the local decomposition of a 2D primitive. - virtual Primitive2DSequence create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; - -public: - // constructor and destructor - SdPageObjectPageBitmapPrimitive( - const basegfx::B2DRange& rRange, - const BitmapEx& rBitmapEx); - ~SdPageObjectPageBitmapPrimitive(); - - // data access - const BitmapEx& getBitmapEx() const { return maBitmapEx; } - - // compare operator - virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const; - - // provide unique ID - DeclPrimitrive2DIDBlock() -}; - -Primitive2DSequence SdPageObjectPageBitmapPrimitive::create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const -{ - // add bitmap primitive - // to avoid scaling, use the Bitmap pixel size as primitive size - basegfx::B2DHomMatrix aBitmapTransform; - const Size aBitmapSize(getBitmapEx().GetSizePixel()); - const basegfx::B2DVector aBitmapSizeLogic(rViewInformation.getInverseObjectToViewTransformation() * - basegfx::B2DVector(aBitmapSize.getWidth() - 1, aBitmapSize.getHeight() - 1)); - - // short form for scale and translate transformation - aBitmapTransform.set(0L, 0L, aBitmapSizeLogic.getX()); - aBitmapTransform.set(1L, 1L, aBitmapSizeLogic.getY()); - aBitmapTransform.set(0L, 2L, getPageObjectRange().getMinX()); - aBitmapTransform.set(1L, 2L, getPageObjectRange().getMinY()); - - // add a BitmapPrimitive2D to the result - const Primitive2DReference xReference( - new drawinglayer::primitive2d::BitmapPrimitive2D(getBitmapEx(), aBitmapTransform)); - return Primitive2DSequence(&xReference, 1); -} - -SdPageObjectPageBitmapPrimitive::SdPageObjectPageBitmapPrimitive( - const basegfx::B2DRange& rRange, - const BitmapEx& rBitmapEx) -: SdPageObjectBasePrimitive(rRange), - maBitmapEx(rBitmapEx) -{ -} - -SdPageObjectPageBitmapPrimitive::~SdPageObjectPageBitmapPrimitive() -{ -} - -bool SdPageObjectPageBitmapPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const -{ - if(SdPageObjectBasePrimitive::operator==(rPrimitive)) - { - const SdPageObjectPageBitmapPrimitive& rCompare = static_cast< const SdPageObjectPageBitmapPrimitive& >(rPrimitive); - return (getBitmapEx() == rCompare.getBitmapEx()); - } - - return false; -} - -ImplPrimitrive2DIDBlock(SdPageObjectPageBitmapPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTPAGEBITMAPPRIMITIVE) - -/////////////////////////////////////////////////////////////////////////////////////////////// -// SdPageObjectPrimitive for selected visualisation - -class SdPageObjectSelectPrimitive : public SdPageObjectBasePrimitive -{ -private: - /// Gap between border of page object and inside of selection rectangle. - static const sal_Int32 mnSelectionIndicatorOffset; - - /// Thickness of the selection rectangle. - static const sal_Int32 mnSelectionIndicatorThickness; - -protected: - // method which is to be used to implement the local decomposition of a 2D primitive. - virtual Primitive2DSequence create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; - -public: - // constructor and destructor - SdPageObjectSelectPrimitive(const basegfx::B2DRange& rRange); - ~SdPageObjectSelectPrimitive(); - - // provide unique ID - DeclPrimitrive2DIDBlock() -}; - -const sal_Int32 SdPageObjectSelectPrimitive::mnSelectionIndicatorOffset(1); -const sal_Int32 SdPageObjectSelectPrimitive::mnSelectionIndicatorThickness(3); - -Primitive2DSequence SdPageObjectSelectPrimitive::create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const -{ - Primitive2DSequence xRetval(2); - - // since old Width/Height calculations always added a single pixel value, - // it is necessary to create a inner range which is one display unit less - // at the bottom right. - const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); - const basegfx::B2DRange aAdaptedInnerRange( - getPageObjectRange().getMinX(), getPageObjectRange().getMinY(), - getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY()); - - // PaintSelectionIndicator replacement. Grow by offset first - basegfx::B2DRange aDiscreteOuterRange(aAdaptedInnerRange); - aDiscreteOuterRange.grow(mnSelectionIndicatorOffset * aDiscretePixel.getX()); - - // Remember inner border. Make it one bigger in top left since polygons - // do not paint their lower-right corners. Since this is the inner polygon, - // the top-left corders are the ones to grow here - const basegfx::B2DRange aDiscreteInnerRange( - aDiscreteOuterRange.getMinimum() + aDiscretePixel, - aDiscreteOuterRange.getMaximum() - aDiscretePixel); - - // grow by line width - aDiscreteOuterRange.grow((mnSelectionIndicatorThickness - 1) * aDiscretePixel.getX()); - - // create a PolyPolygon from those ranges. For the outer polygon, round edges by - // giving a relative radius to the polygon creator (use mnSelectionIndicatorThickness here, too) - const double fPixelFactor(aDiscretePixel.getX() * (mnSelectionIndicatorThickness + 2.5)); - const double fRelativeRadiusX(fPixelFactor / ::std::max(aDiscreteOuterRange.getWidth(), 1.0)); - const double fRelativeRadiusY(fPixelFactor / ::std::max(aDiscreteOuterRange.getHeight(), 1.0)); - basegfx::B2DPolyPolygon aFramePolyPolygon; - const basegfx::B2DPolygon aRoundedOuterPolygon(basegfx::tools::createPolygonFromRect(aDiscreteOuterRange, fRelativeRadiusX, fRelativeRadiusY)); - - aFramePolyPolygon.append(aRoundedOuterPolygon); - aFramePolyPolygon.append(basegfx::tools::createPolygonFromRect(aDiscreteInnerRange)); - - // add colored PolyPolygon - const svtools::ColorConfig aColorConfig; - static bool bTestWithBrightColors(false); - const basegfx::BColor aFrameColor(bTestWithBrightColors ? basegfx::BColor(0,1,0) : Application::GetSettings().GetStyleSettings().GetMenuHighlightColor().getBColor()); - - xRetval[0] = Primitive2DReference( - new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(aFramePolyPolygon, aFrameColor)); - - // add aRoundedOuterPolygon again as non-filled line polygon to get the roundungs - // painted correctly - xRetval[1] = Primitive2DReference( - new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aRoundedOuterPolygon, aFrameColor)); - - return xRetval; -} - -SdPageObjectSelectPrimitive::SdPageObjectSelectPrimitive(const basegfx::B2DRange& rRange) -: SdPageObjectBasePrimitive(rRange) -{ -} - -SdPageObjectSelectPrimitive::~SdPageObjectSelectPrimitive() -{ -} - -ImplPrimitrive2DIDBlock(SdPageObjectSelectPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTSELECTPRIMITIVE) - -/////////////////////////////////////////////////////////////////////////////////////////////// -// SdPageObjectPrimitive for border around bitmap visualisation - -class SdPageObjectBorderPrimitive : public SdPageObjectBasePrimitive -{ -protected: - // method which is to be used to implement the local decomposition of a 2D primitive. - virtual Primitive2DSequence create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; - -public: - // constructor and destructor - SdPageObjectBorderPrimitive(const basegfx::B2DRange& rRange); - ~SdPageObjectBorderPrimitive(); - - // provide unique ID - DeclPrimitrive2DIDBlock() -}; - -Primitive2DSequence SdPageObjectBorderPrimitive::create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const -{ - // since old Width/Height calculations always added a single pixel value, - // it is necessary to create a inner range which is one display unit less - // at the bottom right. - const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); - const basegfx::B2DRange aAdaptedInnerRange( - getPageObjectRange().getMinX(), getPageObjectRange().getMinY(), - getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY()); - - // Paint_Border replacement. (use aBorderColor) - static bool bTestWithBrightColors(false); - const svtools::ColorConfig aColorConfig; - const basegfx::BColor aBorderColor(bTestWithBrightColors ? basegfx::BColor(1,0,0) : Color(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor).getBColor()); - - const Primitive2DReference xReference( - new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(basegfx::tools::createPolygonFromRect(aAdaptedInnerRange), aBorderColor)); - return Primitive2DSequence(&xReference, 1); -} - -SdPageObjectBorderPrimitive::SdPageObjectBorderPrimitive(const basegfx::B2DRange& rRange) -: SdPageObjectBasePrimitive(rRange) -{ -} - -SdPageObjectBorderPrimitive::~SdPageObjectBorderPrimitive() -{ -} - -ImplPrimitrive2DIDBlock(SdPageObjectBorderPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTBORDERPRIMITIVE) - -/////////////////////////////////////////////////////////////////////////////////////////////// -// SdPageObjectPrimitive for focus visualisation - -class SdPageObjectFocusPrimitive : public SdPageObjectBasePrimitive -{ -private: - /// Gap between border of page object and inside of focus rectangle. - static const sal_Int32 mnFocusIndicatorOffset; - const bool mbContrastToSelected; - -protected: - // method which is to be used to implement the local decomposition of a 2D primitive. - virtual Primitive2DSequence create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; - -public: - // constructor and destructor - SdPageObjectFocusPrimitive(const basegfx::B2DRange& rRange, const bool bContrast); - ~SdPageObjectFocusPrimitive(); - - // provide unique ID - DeclPrimitrive2DIDBlock() -}; - -const sal_Int32 SdPageObjectFocusPrimitive::mnFocusIndicatorOffset(2); - -Primitive2DSequence SdPageObjectFocusPrimitive::create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const -{ - Primitive2DSequence xRetval(2); - - // since old Width/Height calculations always added a single pixel value, - // it is necessary to create a inner range which is one display unit less - // at the bottom right. - const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); - const basegfx::B2DRange aAdaptedInnerRange( - getPageObjectRange().getMinX(), getPageObjectRange().getMinY(), - getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY()); - - // Paint_FocusIndicator replacement. (black and white). - // imitate Paint_DottedRectangle: First paint a white rectangle and above it a black dotted one - basegfx::B2DRange aFocusIndicatorRange(aAdaptedInnerRange); - aFocusIndicatorRange.grow(mnFocusIndicatorOffset * aDiscretePixel.getX()); - - // create polygon - const basegfx::B2DPolygon aIndicatorPolygon(basegfx::tools::createPolygonFromRect(aFocusIndicatorRange)); - - const StyleSettings& rStyleSettings(Application::GetSettings().GetStyleSettings()); - - // "background" rectangle - const Color aBackgroundColor(mbContrastToSelected ? rStyleSettings.GetMenuHighlightColor() : rStyleSettings.GetWindowColor()); - xRetval[0] = Primitive2DReference( - new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aIndicatorPolygon, Color(COL_WHITE).getBColor())); - - // dotted black rectangle with same geometry - ::std::vector< double > aDotDashArray; - - const sal_Int32 nFocusIndicatorWidth (3); - aDotDashArray.push_back(nFocusIndicatorWidth *aDiscretePixel.getX()); - aDotDashArray.push_back(nFocusIndicatorWidth * aDiscretePixel.getX()); - - // prepare line and stroke attributes - const Color aLineColor(mbContrastToSelected ? rStyleSettings.GetMenuHighlightTextColor() : rStyleSettings.GetWindowTextColor()); - const drawinglayer::attribute::LineAttribute aLineAttribute(aLineColor.getBColor()); - const drawinglayer::attribute::StrokeAttribute aStrokeAttribute( - aDotDashArray, 2.0 * nFocusIndicatorWidth * aDiscretePixel.getX()); - - - xRetval[1] = Primitive2DReference( - new drawinglayer::primitive2d::PolygonStrokePrimitive2D(aIndicatorPolygon, aLineAttribute, aStrokeAttribute)); - - return xRetval; -} - -SdPageObjectFocusPrimitive::SdPageObjectFocusPrimitive(const basegfx::B2DRange& rRange, const bool bContrast) - : SdPageObjectBasePrimitive(rRange), - mbContrastToSelected(bContrast) -{ -} - -SdPageObjectFocusPrimitive::~SdPageObjectFocusPrimitive() -{ -} - -ImplPrimitrive2DIDBlock(SdPageObjectFocusPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTFOCUSPRIMITIVE) - -/////////////////////////////////////////////////////////////////////////////////////////////// -// SdPageObjectPrimitive for fade effect visualisation - -class SdPageObjectFadeNameNumberPrimitive : public SdPageObjectBasePrimitive -{ -private: - /// Size of width and height of the fade effect indicator in pixels. - static const sal_Int32 mnFadeEffectIndicatorOffset; - - /// Size of width and height of the comments indicator in pixels. - static const sal_Int32 mnCommentsIndicatorOffset; - - /// Gap between border of page object and number rectangle. - static const sal_Int32 mnPageNumberOffset; - - /// the indicator bitmaps. Static since it is usable outside this primitive - /// for size comparisons - static BitmapEx* mpFadeEffectIconBitmap; - static BitmapEx* mpCommentsIconBitmap; - - /// page name, number and needed infos - String maPageName; - sal_uInt32 mnPageNumber; - Font maPageNameFont; - Size maPageNumberAreaModelSize; - - // bitfield - bool mbShowFadeEffectIcon : 1; - bool mbShowCommentsIcon : 1; - bool mbExcluded : 1; - - // private helpers - const BitmapEx& getFadeEffectIconBitmap() const; - const BitmapEx& getCommentsIconBitmap() const; - -protected: - // method which is to be used to implement the local decomposition of a 2D primitive. - virtual Primitive2DSequence create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; - -public: - // constructor and destructor - SdPageObjectFadeNameNumberPrimitive( - const basegfx::B2DRange& rRange, - const String& rPageName, - sal_uInt32 nPageNumber, - const Font& rPageNameFont, - const Size& rPageNumberAreaModelSize, - bool bShowFadeEffectIcon, - bool bShowCommentsIcon, - bool bExcluded); - ~SdPageObjectFadeNameNumberPrimitive(); - - // data access - const String& getPageName() const { return maPageName; } - sal_uInt32 getPageNumber() const { return mnPageNumber; } - const Font& getPageNameFont() const { return maPageNameFont; } - const Size& getPageNumberAreaModelSize() const { return maPageNumberAreaModelSize; } - bool getShowFadeEffectIcon() const { return mbShowFadeEffectIcon; } - bool getShowCommentsIcon() const { return mbShowCommentsIcon; } - bool getExcluded() const { return mbExcluded; } - - // compare operator - virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const; - - // provide unique ID - DeclPrimitrive2DIDBlock() -}; - -const sal_Int32 SdPageObjectFadeNameNumberPrimitive::mnFadeEffectIndicatorOffset(9); -const sal_Int32 SdPageObjectFadeNameNumberPrimitive::mnPageNumberOffset(9); -BitmapEx* SdPageObjectFadeNameNumberPrimitive::mpFadeEffectIconBitmap = 0; - -const BitmapEx& SdPageObjectFadeNameNumberPrimitive::getFadeEffectIconBitmap() const -{ - if(mpFadeEffectIconBitmap == NULL) - { - // prepare FadeEffectIconBitmap on demand - const sal_uInt16 nIconId(Application::GetSettings().GetStyleSettings().GetHighContrastMode() - ? BMP_FADE_EFFECT_INDICATOR_H - : BMP_FADE_EFFECT_INDICATOR); - const BitmapEx aFadeEffectIconBitmap(IconCache::Instance().GetIcon(nIconId).GetBitmapEx()); - const_cast< SdPageObjectFadeNameNumberPrimitive* >(this)->mpFadeEffectIconBitmap = new BitmapEx(aFadeEffectIconBitmap); - } - - return *mpFadeEffectIconBitmap; -} - - -const sal_Int32 SdPageObjectFadeNameNumberPrimitive::mnCommentsIndicatorOffset(9); -BitmapEx* SdPageObjectFadeNameNumberPrimitive::mpCommentsIconBitmap = 0; - -const BitmapEx& SdPageObjectFadeNameNumberPrimitive::getCommentsIconBitmap() const -{ - if(mpCommentsIconBitmap == NULL) - { - // prepare CommentsIconBitmap on demand - const sal_uInt16 nIconId(Application::GetSettings().GetStyleSettings().GetHighContrastMode() - ? BMP_COMMENTS_INDICATOR_H - : BMP_COMMENTS_INDICATOR); - const BitmapEx aCommentsIconBitmap(IconCache::Instance().GetIcon(nIconId).GetBitmapEx()); - const_cast< SdPageObjectFadeNameNumberPrimitive* >(this)->mpCommentsIconBitmap = new BitmapEx(aCommentsIconBitmap); - } - - return *mpCommentsIconBitmap; -} - -Primitive2DSequence SdPageObjectFadeNameNumberPrimitive::create2DDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const -{ - const xub_StrLen nTextLength(getPageName().Len()); - const sal_uInt32 nCount( - (getShowFadeEffectIcon() ? 1 : 0) + // FadeEffect icon - (nTextLength ? 1 : 0) + // PageName - 1 + // PageNumber (always) - (getExcluded() ? 2 : 0) // PageNumber crossed out - ); - sal_uInt32 nInsert(0); - Primitive2DSequence xRetval(nCount); - - // since old Width/Height calculations always added a single pixel value, - // it is necessary to create a inner range which is one display unit less - // at the bottom right. - const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0)); - const basegfx::B2DRange aAdaptedInnerRange( - getPageObjectRange().getMinX(), getPageObjectRange().getMinY(), - getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY()); - - // preapre TextLayouter - drawinglayer::primitive2d::TextLayouterDevice aTextLayouter; - aTextLayouter.setFont(getPageNameFont()); - - // get font attributes - basegfx::B2DVector aTextSizeAttribute; - const drawinglayer::attribute::FontAttribute aFontAttribute( - drawinglayer::primitive2d::getFontAttributeFromVclFont( - aTextSizeAttribute, - getPageNameFont(), - false, - false)); - - // prepare locale; this may need some more information in the future - const ::com::sun::star::lang::Locale aLocale; - - // prepare font color from System - const basegfx::BColor aFontColor(Application::GetSettings().GetStyleSettings().GetFontColor().getBColor()); - - if(getShowFadeEffectIcon()) - { - // prepare fFadeEffect Sizes - const basegfx::B2DVector aFadeEffectBitmapSizeLogic(rViewInformation.getInverseObjectToViewTransformation() * - basegfx::B2DVector( - getFadeEffectIconBitmap().GetSizePixel().getWidth() - 1, - getFadeEffectIconBitmap().GetSizePixel().getHeight() - 1)); - - // Paint_FadeEffectIndicator replacement. - // create transformation. To avoid bitmap scaling, use bitmap size as size - basegfx::B2DHomMatrix aBitmapTransform; - - // short form for scale and translate transformation - aBitmapTransform.set(0L, 0L, aFadeEffectBitmapSizeLogic.getX()); - aBitmapTransform.set(1L, 1L, aFadeEffectBitmapSizeLogic.getY()); - aBitmapTransform.set(0L, 2L, aAdaptedInnerRange.getMinX()); - aBitmapTransform.set(1L, 2L, aAdaptedInnerRange.getMaxY() + ((mnFadeEffectIndicatorOffset + 1) * aDiscretePixel.getX())); - - xRetval[nInsert++] = Primitive2DReference( - new drawinglayer::primitive2d::BitmapPrimitive2D(getFadeEffectIconBitmap(), aBitmapTransform)); - } - - if(nTextLength) - { - // prepare fFadeEffect Sizes since it consumes from text size - const basegfx::B2DVector aFadeEffectBitmapSizeLogic(rViewInformation.getInverseObjectToViewTransformation() * - basegfx::B2DVector( - getFadeEffectIconBitmap().GetSizePixel().getWidth() - 1, - getFadeEffectIconBitmap().GetSizePixel().getHeight() - 1)); - - // Paint_PageName replacement. Get text size - const double fTextWidth(aTextLayouter.getTextWidth(getPageName(), 0, nTextLength)); - const double fTextHeight(getPageNameFont().GetHeight()); - const double fFadeEffectWidth(aFadeEffectBitmapSizeLogic.getX() * 2.0); - const double fFadeEffectTextGap(((mnFadeEffectIndicatorOffset + 2) * aDiscretePixel.getX())); - String aPageName(getPageName()); - - // calculate text start position - double fStartX( - aAdaptedInnerRange.getMaxX() - - fTextWidth - + (aDiscretePixel.getX() * 3.0)); - const double fStartY( - aAdaptedInnerRange.getMaxY() - + fTextHeight - + fFadeEffectTextGap); - const bool bNeedClipping(fStartX < aAdaptedInnerRange.getMinX() + fFadeEffectWidth); - - // if text is too big, clip it - if(bNeedClipping) - { - // new left start - fStartX = aAdaptedInnerRange.getMinX() + fFadeEffectWidth; - - // find out how many characters to use - const double fAvailableLength(aAdaptedInnerRange.getWidth() - fFadeEffectWidth); - static const String aThreePoints(String::CreateFromAscii("...")); - const double fWidthThreePoints(aTextLayouter.getTextWidth(aThreePoints, 0, aThreePoints.Len())); - xub_StrLen a(1); - - for(; a < (xub_StrLen)nTextLength; a++) - { - const double fSnippetLength(aTextLayouter.getTextWidth(aPageName, 0, a)); - - if(fSnippetLength + fWidthThreePoints > fAvailableLength) - { - break; - } - } - - // build new string - aPageName = String(aPageName, 0, a - 1); - aPageName += aThreePoints; - } - - // fill text matrix - basegfx::B2DHomMatrix aTextMatrix; - - aTextMatrix.set(0, 0, aTextSizeAttribute.getX()); - aTextMatrix.set(1, 1, aTextSizeAttribute.getY()); - aTextMatrix.set(0, 2, fStartX); - aTextMatrix.set(1, 2, fStartY); - - // prepare DXTextArray (can be empty one) - const ::std::vector< double > aDXArray; - - // create Text primitive and add to target - xRetval[nInsert++] = Primitive2DReference( - new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( - aTextMatrix, - aPageName, - 0, - aPageName.Len(), - aDXArray, - aFontAttribute, - aLocale, - aFontColor)); - } - - { - // Paint_PageNumber replacement. Get the range where it shall be centered and prepare the string - const double fLeft(aAdaptedInnerRange.getMinX() - (mnPageNumberOffset * aDiscretePixel.getX()) - getPageNumberAreaModelSize().Width()); - const double fTop(aAdaptedInnerRange.getMinY()); - const basegfx::B2DRange aNumberRange(fLeft, fTop, - fLeft + getPageNumberAreaModelSize().Width(), fTop + getPageNumberAreaModelSize().Height()); - const String aPageNumber(String::CreateFromInt32(getPageNumber())); - const xub_StrLen nNumberLen(aPageNumber.Len()); - - // Get text size - const double fTextWidth(aTextLayouter.getTextWidth(aPageNumber, 0, nNumberLen)); - const double fTextHeight(getPageNameFont().GetHeight()); - - // get text start postion - const double fStartX(aNumberRange.getCenterX() - (fTextWidth / 2.0)); - const double fStartY(aNumberRange.getMinY() + fTextHeight + aDiscretePixel.getX()); - - // fill text matrix - basegfx::B2DHomMatrix aTextMatrix; - - aTextMatrix.set(0, 0, aTextSizeAttribute.getX()); - aTextMatrix.set(1, 1, aTextSizeAttribute.getY()); - aTextMatrix.set(0, 2, fStartX); - aTextMatrix.set(1, 2, fStartY); - - // prepare DXTextArray (can be empty one) - const ::std::vector< double > aDXArray; - - // create Text primitive - xRetval[nInsert++] = Primitive2DReference( - new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( - aTextMatrix, - aPageNumber, - 0, - nNumberLen, - aDXArray, - aFontAttribute, - aLocale, - aFontColor)); - - if(getExcluded()) - { - // create a box with strikethrough from top left to bottom right - const basegfx::BColor aActiveColor(Application::GetSettings().GetStyleSettings().GetActiveColor().getBColor()); - basegfx::B2DPolygon aStrikethrough; - - aStrikethrough.append(aNumberRange.getMinimum()); - aStrikethrough.append(aNumberRange.getMaximum()); - - xRetval[nInsert++] = Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( - basegfx::tools::createPolygonFromRect(aNumberRange), aActiveColor)); - - xRetval[nInsert++] = Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( - aStrikethrough, aActiveColor)); - } - } - - return xRetval; -} - -SdPageObjectFadeNameNumberPrimitive::SdPageObjectFadeNameNumberPrimitive( - const basegfx::B2DRange& rRange, - const String& rPageName, - sal_uInt32 nPageNumber, - const Font& rPageNameFont, - const Size& rPageNumberAreaModelSize, - bool bShowFadeEffectIcon, - bool bShowCommentsIcon, - bool bExcluded) -: SdPageObjectBasePrimitive(rRange), - maPageName(rPageName), - mnPageNumber(nPageNumber), - maPageNameFont(rPageNameFont), - maPageNumberAreaModelSize(rPageNumberAreaModelSize), - mbShowFadeEffectIcon(bShowFadeEffectIcon), - mbShowCommentsIcon(bShowCommentsIcon), - mbExcluded(bExcluded) -{ -} - -SdPageObjectFadeNameNumberPrimitive::~SdPageObjectFadeNameNumberPrimitive() -{ -} - -bool SdPageObjectFadeNameNumberPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const -{ - if(SdPageObjectBasePrimitive::operator==(rPrimitive)) - { - const SdPageObjectFadeNameNumberPrimitive& rCompare = static_cast< const SdPageObjectFadeNameNumberPrimitive& >(rPrimitive); - - return (getPageName() == rCompare.getPageName() - && getPageNumber() == rCompare.getPageNumber() - && getPageNameFont() == rCompare.getPageNameFont() - && getPageNumberAreaModelSize() == rCompare.getPageNumberAreaModelSize() - && getShowFadeEffectIcon() == rCompare.getShowFadeEffectIcon() - && getExcluded() == rCompare.getExcluded()); - } - - return false; -} - -ImplPrimitrive2DIDBlock(SdPageObjectFadeNameNumberPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTFADENAMENUMBERPRIMITIVE) - -/////////////////////////////////////////////////////////////////////////////////////////////// -// createPrimitive2DSequence -// -// This method will replace the whole painting mechanism. Task is no longer to paint stuff to an OutDev, -// but to provide the necessary geometrical information using primitives. - -Primitive2DSequence PageObjectViewObjectContact::createPrimitive2DSequence(const sdr::contact::DisplayInfo& rDisplayInfo) const -{ - // OutputDevice* pDevice = rDisplayInfo.GetDIOutputDevice(); - OutputDevice* pDevice = GetObjectContact().TryToGetOutputDevice(); - - // get primitive vector from parent class. Do remember the contents for later use; this - // is done to create the page content renderer (see PagePrimitiveExtractor in svx) at the - // original object and to setup the draw hierarchy there so that changes to VCs of displayed - // objects will lead to InvalidatePartOfView-calls which will be forwarded from the helper-OC - // to this VOC in calling a ActionChanged(). - // - // This already produces the displayable page content as a primitive sequence, complete with - // embedding in the page visualizer, clipping if needed and object and aspect ratio - // preparations. It would thus be the base for creating the cached visualisation, too, - // by just painting extactly this primitive sequence. - // - // Currently, this slows down PagePane display heavily. Reason is that the current mechanism - // to react on a SdrObject change in an edit view is to react on the ModelChange and to completely - // reset the PagePane (delete SdrPageObjs, re-create and layout them). This works, but kicks - // the complete sequence of primitive creation at VOCs and VCs and their buffering out of - // memory each time. So there are two choices: - // - // 1, disable getting the sequence of primtives - // -> invalidate uses ModelChange - // -> cache repaint uses complete view creation and repainting - // - // 2, create and use the sequence of primitives - // -> invalidate would not need ModelChange, no destroy/recreate of SdrObjects, no rearrange, - // the invalidate and the following repaint would exactly update the SdrPages involved and - // use the DrawingLayer provided ActionChanged() invalidations over the VOCs and VCs - // -> cache repaint could use the here offered sequence of primitives to re-create the bitmap - // (just hand over the local member to the cache) - // - // For the moment i will use (1) and disable primitive creation for SdrPageObj contents here - - // const_cast< PageObjectViewObjectContact* >(this)->mxCurrentPageContents = ViewObjectContactOfPageObj::createPrimitive2DSequence(rDisplayInfo); - - // assert when this call is issued indirectly from the destructor of - // this instance. This is not allowed and needs to be looked at -#ifdef DBG_UTIL - if(mbInDestructor) - { - OSL_ENSURE(false, "Higher call inside PageObjectViewObjectContact in destructor (!)"); - } -#endif - - // Check if buffering can and shall be done. - if (pDevice != NULL - && !GetObjectContact().isOutputToPrinter() - && !GetObjectContact().isOutputToRecordingMetaFile() - && !mbInDestructor) - { - // get inner and outer logic rectangles. Use model data directly for creation. Do NOT use getBoundRect()/ - // getSnapRect() functionality; these will use the sequence of primitives in the long run itself. SdrPageObj - // is a SdrObject, so use SdrObject::aOutRect as model data. Access using GetLastBoundRect() to not execute anything - PageObjectViewContact& rPaObVOC(static_cast< PageObjectViewContact& >(GetViewContact())); - const Rectangle aInnerLogic(rPaObVOC.GetPageObject().GetLastBoundRect()); - - // get BitmapEx from cache. Do exactly the same as Paint_Preview() to avoid a repaint loop - // caused by slightly different pixel sizes of what the cache sees as pixel size and what is - // calculated here in discrete coordinates. This includes to not use LogicToPiyel on the Rectangle, - // but to do the same as the GetBoundingBox() implementation - const Rectangle aInnerPixel(Rectangle(pDevice->LogicToPixel(aInnerLogic.TopLeft()), pDevice->LogicToPixel(aInnerLogic.GetSize()))); - BitmapEx aBitmapEx(const_cast< PageObjectViewObjectContact* >(this)->GetPreview(rDisplayInfo, aInnerPixel)); - - // prepare inner range - const basegfx::B2DRange aInnerRange(aInnerLogic.Left(), aInnerLogic.Top(), aInnerLogic.Right(), aInnerLogic.Bottom()); - - // provide default parameters - String aPageName; - Font aPageNameFont; - sal_uInt32 nPageNumber(0); - Size aPageNumberAreaModelSize; - bool bShowFadeEffectIcon(false); - bool bShowCommentsIcon(false); - bool bExcluded(false); - - if(GetPage()) - { - const SdPage* pPage = static_cast(GetPage()); - - // decide if fade effect indicator will be painted - if(pPage->getTransitionType() > 0) - { - bShowFadeEffectIcon = true; - } - - bShowCommentsIcon = !pPage->getAnnotations().empty(); - - // prepare PageName, PageNumber, font and AreaModelSize - aPageName = pPage->GetName(); - aPageNameFont = *FontProvider::Instance().GetFont(*pDevice); - nPageNumber = ((pPage->GetPageNum() - 1) / 2) + 1; - aPageNumberAreaModelSize = GetPageDescriptor()->GetPageNumberAreaModelSize(); - - if(!aPageName.Len()) - { - aPageName = String(SdResId(STR_PAGE)); - aPageName += String::CreateFromInt32(nPageNumber); - } - - // decide if page is excluded - bExcluded = pPage->IsExcluded(); - } - - // create specialized primitives for focus, select and PagePreview itself - const bool bCreateBitmap(!aBitmapEx.IsEmpty()); - const bool bCreateFocused(GetPageDescriptor()->IsFocused()); - const bool bCreateSelected(GetPageDescriptor()->IsSelected()); - - const sal_uInt32 nCount( - (bCreateBitmap ? 1 : 0) + // bitmap itself - 1 + // border around bitmap (always) - 1 + // FadeEffect, PageName and PageNumber visualisation (always) - (bCreateFocused ? 1 : 0) + // create focused - (bCreateSelected ? 1 : 0) // create selected - ); - sal_uInt32 nInsert(0); - Primitive2DSequence xRetval(nCount); - - if(bCreateBitmap) - { - // add selection indicator if used - xRetval[nInsert++] = Primitive2DReference(new SdPageObjectPageBitmapPrimitive(aInnerRange, aBitmapEx)); - } - - if(true) - { - // add border (always) - xRetval[nInsert++] = Primitive2DReference(new SdPageObjectBorderPrimitive(aInnerRange)); - } - - if(true) - { - // add fade effext, page name and number if used - xRetval[nInsert++] = Primitive2DReference(new SdPageObjectFadeNameNumberPrimitive( - aInnerRange, - aPageName, - nPageNumber, - aPageNameFont, - aPageNumberAreaModelSize, - bShowFadeEffectIcon, - bShowCommentsIcon, - bExcluded)); - } - - if(bCreateSelected) - { - // add selection indicator if used - xRetval[nInsert++] = Primitive2DReference(new SdPageObjectSelectPrimitive(aInnerRange)); - } - - if(bCreateFocused) - { - // add focus indicator if used - xRetval[nInsert++] = Primitive2DReference(new SdPageObjectFocusPrimitive(aInnerRange, bCreateSelected)); - } - - return xRetval; - } - else - { - // Call parent. Output to printer or metafile will use vector data, not cached bitmaps - return ViewObjectContactOfPageObj::createPrimitive2DSequence(rDisplayInfo); - } -} - -BitmapEx PageObjectViewObjectContact::CreatePreview (const DisplayInfo& /*rDisplayInfo*/) -{ - const SdPage* pPage = static_cast(GetPage()); - OutputDevice* pDevice = GetObjectContact().TryToGetOutputDevice(); - - if(pDevice) - { - Rectangle aPreviewPixelBox (GetBoundingBox(*pDevice,PreviewBoundingBox,PixelCoordinateSystem)); - - PreviewRenderer aRenderer (pDevice); - Image aPreview (aRenderer.RenderPage( - pPage, - aPreviewPixelBox.GetSize(), - String())); - - return aPreview.GetBitmapEx(); - } - else - { - return BitmapEx(); - } -} - - - - -BitmapEx PageObjectViewObjectContact::GetPreview ( - const DisplayInfo& rDisplayInfo, - const Rectangle& rNewSizePixel) -{ - BitmapEx aBitmap; - - try - { - // assert when this call is issued indirectly from the destructor of - // this instance. This is not allowed and needs to be looked at - OSL_ENSURE(!mbInDestructor, "Higher call inside PageObjectViewObjectContact in destructor (!)"); - - if (!mbInDestructor) - { - if (mpCache != NULL) - { - aBitmap = mpCache->GetPreviewBitmap( - GetPage(), - rNewSizePixel.GetSize()); - mpCache->SetPreciousFlag(GetPage(), true); - } - else - aBitmap = CreatePreview(rDisplayInfo); - } - } - catch (const ::com::sun::star::uno::Exception&) - { - OSL_TRACE("PageObjectViewObjectContact::GetPreview: caught exception"); - } - - return aBitmap; -} - - - - -const SdrPage* PageObjectViewObjectContact::GetPage (void) const -{ - return static_cast(GetViewContact()).GetPage(); -} - - - - -void PageObjectViewObjectContact::ActionChanged (void) -{ - // Even when we are called from destructor we still have to invalide - // the preview bitmap in the cache. - const SdrPage* pPage = GetPage(); - - if(pPage) - { - SdDrawDocument* pDocument = dynamic_cast(pPage->GetModel()); - if (mpCache!=NULL && pPage!=NULL && pDocument!=NULL) - { - cache::PageCacheManager::Instance()->InvalidatePreviewBitmap( - pDocument->getUnoModel(), - pPage); - } - } - - // call parent - ViewObjectContactOfPageObj::ActionChanged(); -} - -////////////////////////////////////////////////////////////////////////////// -// helper MouseOverEffectPrimitive -// -// Used to allow view-dependent primitive definition. For that purpose, the -// initially created primitive (here: in createMouseOverEffectPrimitive2DSequence()) -// always has to be view-independent, but the decomposition is made view-dependent. -// Very simple primitive which just remembers the discrete data and applies -// it at decomposition time. - -class MouseOverEffectPrimitive : public drawinglayer::primitive2d::BufferedDecompositionPrimitive2D -{ -private: - basegfx::B2DRange maLogicRange; - sal_uInt32 mnDiscreteOffset; - sal_uInt32 mnDiscreteWidth; - basegfx::BColor maRGBColor; - -protected: - virtual drawinglayer::primitive2d::Primitive2DSequence create2DDecomposition( - const drawinglayer::geometry::ViewInformation2D& rViewInformation) const; - -public: - MouseOverEffectPrimitive( - const basegfx::B2DRange& rLogicRange, - sal_uInt32 nDiscreteOffset, - sal_uInt32 nDiscreteWidth, - const basegfx::BColor& rRGBColor) - : drawinglayer::primitive2d::BufferedDecompositionPrimitive2D(), - maLogicRange(rLogicRange), - mnDiscreteOffset(nDiscreteOffset), - mnDiscreteWidth(nDiscreteWidth), - maRGBColor(rRGBColor) - {} - - // data access - const basegfx::B2DRange& getLogicRange() const { return maLogicRange; } - sal_uInt32 getDiscreteOffset() const { return mnDiscreteOffset; } - sal_uInt32 getDiscreteWidth() const { return mnDiscreteWidth; } - const basegfx::BColor& getRGBColor() const { return maRGBColor; } - - virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const; - - DeclPrimitrive2DIDBlock() -}; - -drawinglayer::primitive2d::Primitive2DSequence MouseOverEffectPrimitive::create2DDecomposition( - const drawinglayer::geometry::ViewInformation2D& rViewInformation) const -{ - // get logic sizes in object coordinate system - const double fDiscreteWidth((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength()); - const double fOffset(fDiscreteWidth * getDiscreteOffset()); - const double fWidth(fDiscreteWidth * getDiscreteWidth()); - - // create range (one pixel less to get a good fitting) - basegfx::B2DRange aRange( - getLogicRange().getMinimum(), - getLogicRange().getMaximum() - basegfx::B2DTuple(fDiscreteWidth, fDiscreteWidth)); - - // grow range - aRange.grow(fOffset - (fWidth * 0.5)); - - // create fat line with parameters. The formerly hand-painted edge - // roundings will now be done using rounded edges of this fat line - const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aRange)); - const drawinglayer::attribute::LineAttribute aLineAttribute(getRGBColor(), fWidth); - const drawinglayer::primitive2d::Primitive2DReference xReference( - new drawinglayer::primitive2d::PolygonStrokePrimitive2D( - aPolygon, - aLineAttribute)); - - return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); -} - -bool MouseOverEffectPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const -{ - if(drawinglayer::primitive2d::BufferedDecompositionPrimitive2D::operator==(rPrimitive)) - { - const MouseOverEffectPrimitive& rCompare = static_cast< const MouseOverEffectPrimitive& >(rPrimitive); - - return (getLogicRange() == rCompare.getLogicRange() - && getDiscreteOffset() == rCompare.getDiscreteOffset() - && getDiscreteWidth() == rCompare.getDiscreteWidth() - && getRGBColor() == rCompare.getRGBColor()); - } - - return false; -} - -ImplPrimitrive2DIDBlock(MouseOverEffectPrimitive, PRIMITIVE2D_ID_SDMOUSEOVEREFFECTPRIMITIVE) - -////////////////////////////////////////////////////////////////////////////// - -drawinglayer::primitive2d::Primitive2DSequence PageObjectViewObjectContact::createMouseOverEffectPrimitive2DSequence() -{ - drawinglayer::primitive2d::Primitive2DSequence aRetval; - - if(GetPageDescriptor()->IsSelected() && mpProperties.get() && mpProperties->IsShowSelection()) - { - // When the selection frame is visualized the mouse over frame is not - // visible and does not have to be created. - } - else - { - const PageObjectViewContact& rPaObVOC(static_cast(GetViewContact())); - const Rectangle aBoundingBox(rPaObVOC.GetPageObject().GetLastBoundRect()); - const basegfx::B2DRange aLogicRange(aBoundingBox.Left(), aBoundingBox.Top(), aBoundingBox.Right(), aBoundingBox.Bottom()); - const basegfx::BColor aSelectionColor(mpProperties->GetSelectionColor().getBColor()); - const drawinglayer::primitive2d::Primitive2DReference aReference( - new MouseOverEffectPrimitive( - aLogicRange, - mnMouseOverEffectOffset, - mnMouseOverEffectThickness, - aSelectionColor)); - - aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); - } - - return aRetval; -} - - - - -SvBorder PageObjectViewObjectContact::CalculatePageModelBorder ( - OutputDevice* pDevice, - int nPageCount) -{ - SvBorder aModelBorder; - - if (pDevice != NULL) - { - // 1. Initialize the border with the values that do not depend on - // the device. - Size aTopLeftBorders (pDevice->PixelToLogic (Size ( - mnPageNumberOffset+1, - mnSelectionIndicatorOffset + mnSelectionIndicatorThickness))); - Size aBottomRightBorders (pDevice->PixelToLogic (Size ( - mnSelectionIndicatorOffset + mnSelectionIndicatorThickness, - mnFadeEffectIndicatorOffset))); - aModelBorder = SvBorder ( - aTopLeftBorders.Width(), - aTopLeftBorders.Height(), - aBottomRightBorders.Width(), - aBottomRightBorders.Height()); - - - // 2. Add the device dependent values. - - // Calculate the area of the page number. - Size aPageNumberModelSize ( - CalculatePageNumberAreaModelSize (pDevice, nPageCount)); - - // Update the border. - aModelBorder.Left() += aPageNumberModelSize.Width(); - // The height of the page number area is the same as the height of - // the page name area. - aModelBorder.Bottom() += aPageNumberModelSize.Height(); - } - - return aModelBorder; -} - - - - -Size PageObjectViewObjectContact::CalculatePageNumberAreaModelSize ( - OutputDevice* pDevice, - int nPageCount) -{ - // Set the correct font. - Font aOriginalFont (pDevice->GetFont()); - pDevice->SetFont(*FontProvider::Instance().GetFont(*pDevice)); - - String sPageNumberTemplate; - if (nPageCount < 10) - sPageNumberTemplate = String::CreateFromAscii("9"); - else if (nPageCount < 100) - sPageNumberTemplate = String::CreateFromAscii("99"); - else if (nPageCount < 200) - // Just for the case that 1 is narrower than 9. - sPageNumberTemplate = String::CreateFromAscii("199"); - else if (nPageCount < 1000) - sPageNumberTemplate = String::CreateFromAscii("999"); - else - sPageNumberTemplate = String::CreateFromAscii("9999"); - // More then 9999 pages are not handled. - - Size aSize ( - pDevice->GetTextWidth (sPageNumberTemplate), - pDevice->GetTextHeight ()); - - pDevice->SetFont (aOriginalFont); - - return aSize; -} - - - - -model::SharedPageDescriptor - PageObjectViewObjectContact::GetPageDescriptor (void) const -{ - PageObjectViewContact& rViewContact ( - static_cast(GetViewContact())); - PageObject& rPageObject ( - static_cast(rViewContact.GetPageObject())); - return rPageObject.GetDescriptor(); -} - - - -} } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index 3c43c8917e70..ddc1e4ccd543 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -37,6 +37,7 @@ #include #include +#define USE_SYSTEM_SELECTION_COLOR namespace sd { namespace slidesorter { namespace view { @@ -61,14 +62,6 @@ namespace sd { namespace slidesorter { namespace view { // Off grays #define Arsenic 0x3b444b -const static ColorData SelectionFill1ColorData = 0xb7daf0; -const static ColorData SelectionFill2ColorData = 0x6db5e1; - -const static ColorData MouseOverFill1ColorData = 0x0e85cd; -const static ColorData MouseOverFill2ColorData = 0x044c99; - -const static ColorData Border1ColorData = 0x6db5e1; -const static ColorData Border2ColorData = 0x0e85cd; const static ColorData BackgroundColorData = 0xffffff; @@ -76,8 +69,25 @@ const static ColorData gnMouseOverColor = 0x59000000 | StellaBlue; const static double gnCornerRadius = 4.0; + +ColorData ChangeLuminance (const ColorData aColorData, const int nValue) +{ + Color aColor (aColorData); + if (nValue > 0) + aColor.IncreaseLuminance(nValue); + else + aColor.DecreaseLuminance(-nValue); + return aColor.GetColor(); +} + + + + Theme::Theme (const ::boost::shared_ptr& rpProperties) : maBackgroundColor(rpProperties->GetBackgroundColor().GetColor()), + maNormalGradient(), + maSelectedGradient(), + maMouseOverGradient(), maRawShadow(), maInsertionIndicator() { @@ -85,6 +95,8 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) maRawShadow = Image(SdResId(IMAGE_SHADOW)).GetBitmapEx(); maInsertionIndicator = Image(SdResId(IMAGE_INSERTION_INDICATOR_SELECT)).GetBitmapEx(); + + Update(rpProperties); } @@ -93,9 +105,40 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) void Theme::Update (const ::boost::shared_ptr& rpProperties) { maBackgroundColor = rpProperties->GetBackgroundColor().GetColor(); +#ifdef USE_SYSTEM_SELECTION_COLOR + const ColorData aSelectionColor (rpProperties->GetSelectionColor().GetColor()); + maSelectedGradient.maFillColor1 = ChangeLuminance(aSelectionColor, +50); + maSelectedGradient.maFillColor2 = ChangeLuminance(aSelectionColor, -10); + maSelectedGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, -10); + maSelectedGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, -30); + + maMouseOverGradient.maFillColor1 = ChangeLuminance(aSelectionColor, -30); + maMouseOverGradient.maFillColor2 = ChangeLuminance(aSelectionColor, -90); + maMouseOverGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, -30); + maMouseOverGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, -10); + +#else + + maSelectedGradient.maFillColor1 = 0xb7daf0; + maSelectedGradient.maFillColor2 = 0x6db5e1; + maSelectedGradient.maBorderColor1 = 0x6db5e1; + maSelectedGradient.maBorderColor2 = 0x0e85cd; + + maMouseOverGradient.maFillColor1 = 0x0e85cd; + maMouseOverGradient.maFillColor2 = 0x044c99; + maMouseOverGradient.maBorderColor1 = 0x6db5e1; + maMouseOverGradient.maBorderColor2 = 0x0e85cd; +#endif + + maNormalGradient.maFillColor1 = maBackgroundColor; + maNormalGradient.maFillColor2 = maBackgroundColor; + maNormalGradient.maBorderColor1 = maBackgroundColor; + maNormalGradient.maBorderColor2 = maBackgroundColor; } + + ::boost::shared_ptr Theme::CreateFont ( const FontType eType, OutputDevice& rDevice) const @@ -166,8 +209,14 @@ ColorData Theme::GetColor (const ColorType eType) case PageNumberBorder: return Azure; + case PageNumberColor: + return 0x0848a8f; + case Selection: return StellaBlue; + + case PreviewBorder: + return 0x000000; } return 0; } @@ -179,55 +228,40 @@ ColorData Theme::GetGradientColor ( const GradientColorType eType, const GradientColorClass eClass) { + GradientDescriptor* pDescriptor = NULL; switch(eType) { case NormalPage: - switch (eClass) - { - case Border1: - case Border2: - return maBackgroundColor; - - case Fill1: - case Fill2: - return maBackgroundColor; - } + pDescriptor = &maNormalGradient; break; case SelectedPage: - switch (eClass) - { - case Border1: - return Border1ColorData; - - case Border2: - return Border2ColorData; - - case Fill1: - return SelectionFill1ColorData; - - case Fill2: - return SelectionFill2ColorData; - } + pDescriptor = &maSelectedGradient; break; case MouseOverPage: - switch (eClass) - { - case Border1: - return Border1ColorData; - - case Border2: - return Border2ColorData; - - case Fill1: - return MouseOverFill1ColorData; + pDescriptor = &maMouseOverGradient; + break; - case Fill2: - return MouseOverFill2ColorData; - } + default: + OSL_ASSERT(false); break; } + + if (pDescriptor != NULL) + { + switch (eClass) + { + case Border1: return pDescriptor->maBorderColor1; + case Border2: return pDescriptor->maBorderColor2; + case Fill1: return pDescriptor->maFillColor1; + case Fill2: return pDescriptor->maFillColor2; + + default: + OSL_ASSERT(false); + break; + } + } return 0; } diff --git a/sd/source/ui/toolpanel/TaskPaneViewShell.cxx b/sd/source/ui/toolpanel/TaskPaneViewShell.cxx index 2d1475ca980c..287298fdca9b 100644 --- a/sd/source/ui/toolpanel/TaskPaneViewShell.cxx +++ b/sd/source/ui/toolpanel/TaskPaneViewShell.cxx @@ -89,7 +89,8 @@ #ifdef SHOW_TEST_PANEL #include "TestPanel.hxx" #endif -//#define SHOW_COLOR_MENU + +#define SHOW_COLOR_MENU #ifdef SHOW_COLOR_MENU #include "TestMenu.hxx" #endif @@ -191,6 +192,7 @@ public: class ResourceActivationClickHandler { public: + ResourceActivationClickHandler (void); ResourceActivationClickHandler ( const ::boost::shared_ptr& rpFrameworkHelper, const Reference& rxResourceId, @@ -200,7 +202,7 @@ public: private: ::boost::shared_ptr mpFrameworkHelper; Reference mxResourceId; - ControlContainer& mrControlContainer; + ControlContainer* mpControlContainer; }; } // end of anonymouse namespace @@ -299,7 +301,8 @@ void TaskPaneViewShell::Implementation::Setup ( pToolPanel->AddControl ( ColorMenu::CreateControlFactory(), String::CreateFromAscii ("Color Test Menu"), - 0); + 0, + ResourceActivationClickHandler()); #endif #ifdef SHOW_TEST_PANEL @@ -866,13 +869,23 @@ void PanelActivation::operator() (bool) //===== ResourceActivationClickHandler ======================================== +ResourceActivationClickHandler::ResourceActivationClickHandler (void) + : mpFrameworkHelper(), + mxResourceId(), + mpControlContainer(NULL) +{ +} + + + + ResourceActivationClickHandler::ResourceActivationClickHandler ( const ::boost::shared_ptr& rpFrameworkHelper, const Reference& rxResourceId, ControlContainer& rControlContainer) : mpFrameworkHelper(rpFrameworkHelper), mxResourceId(rxResourceId), - mrControlContainer(rControlContainer) + mpControlContainer(&rControlContainer) { } @@ -881,11 +894,14 @@ ResourceActivationClickHandler::ResourceActivationClickHandler ( void ResourceActivationClickHandler::operator () (TitledControl& rTitledControl) { - mrControlContainer.SetExpansionState ( - &rTitledControl, - ControlContainer::ES_EXPAND); - mpFrameworkHelper->GetConfigurationController()->requestResourceActivation( - mxResourceId, drawing::framework::ResourceActivationMode_REPLACE); + if (mxResourceId.is() && mpFrameworkHelper && mpControlContainer!=NULL) + { + mpControlContainer->SetExpansionState ( + &rTitledControl, + ControlContainer::ES_EXPAND); + mpFrameworkHelper->GetConfigurationController()->requestResourceActivation( + mxResourceId, drawing::framework::ResourceActivationMode_REPLACE); + } } diff --git a/sd/source/ui/tools/PreviewRenderer.cxx b/sd/source/ui/tools/PreviewRenderer.cxx index 770ca7fabf6c..4a166b74e1a1 100644 --- a/sd/source/ui/tools/PreviewRenderer.cxx +++ b/sd/source/ui/tools/PreviewRenderer.cxx @@ -418,8 +418,8 @@ void PreviewRenderer::ProvideView (DrawDocShell* pDocShell) } mpView->SetPreviewRenderer( sal_True ); mpView->SetBordVisible(FALSE); - mpView->SetPageBorderVisible(FALSE); - mpView->SetPageVisible(TRUE); + mpView->SetPageBorderVisible(TRUE); + mpView->SetPageVisible(FALSE); } -- cgit v1.2.3 From 70ebb85a47952a76a58577e1d85f3db3f091d4a4 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 17 Feb 2010 15:08:33 +0100 Subject: renaissance1: #i107215# Modifying the selection may change the current slide. --- .../ui/slidesorter/controller/SlsPageSelector.cxx | 69 +++++++++++++++++++++- .../controller/SlsSelectionFunction.cxx | 23 ++++++-- .../slidesorter/inc/controller/SlsPageSelector.hxx | 25 +++++++- 3 files changed, 107 insertions(+), 10 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index d715acfec252..1a57ff03cc8d 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -37,6 +37,7 @@ #include "controller/SlideSorterController.hxx" #include "controller/SlsSelectionManager.hxx" #include "controller/SlsAnimator.hxx" +#include "controller/SlsCurrentSlideManager.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlideSorterModel.hxx" @@ -66,7 +67,9 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter) mnBroadcastDisableLevel(0), mbSelectionChangeBroadcastPending(false), mpMostRecentlySelectedPage(), - mpSelectionAnchor() + mpSelectionAnchor(), + mpCurrentPage(), + mnUpdateLockCount(0) { CountSelectedPages (); } @@ -79,6 +82,7 @@ void PageSelector::SelectAllPages (void) int nPageCount = mrModel.GetPageCount(); for (int nPageIndex=0; nPageIndexSelectionHasChanged(); } + + UpdateCurrentPage(); } @@ -167,6 +173,7 @@ void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor) mbSelectionChangeBroadcastPending = true; else mrController.GetSelectionManager()->SelectionHasChanged(); + UpdateCurrentPage(); } } @@ -207,6 +214,7 @@ void PageSelector::DeselectPage (const SharedPageDescriptor& rpDescriptor) mbSelectionChangeBroadcastPending = true; else mrController.GetSelectionManager()->SelectionHasChanged(); + UpdateCurrentPage(); } } @@ -329,11 +337,68 @@ void PageSelector::DisableBroadcasting (void) -void PageSelector::SetPageSelection (const ::boost::shared_ptr& rpSelection) +void PageSelector::SetPageSelection ( + const ::boost::shared_ptr& rpSelection, + const bool bUpdateCurrentPage) { PageSelection::const_iterator iPage; for (iPage=rpSelection->begin(); iPage!=rpSelection->end(); ++iPage) SelectPage(*iPage); + if (bUpdateCurrentPage) + UpdateCurrentPage(); +} + + + + +void PageSelector::UpdateCurrentPage (void) +{ + // Make the first selected page the current page. + if (mnUpdateLockCount == 0) + { + const sal_Int32 nPageCount (GetPageCount()); + for (sal_Int32 nIndex=0; nIndexHasState(PageDescriptor::ST_Selected)) + { + // Switching the current slide normally sets also the + // selection to just the new current slide. To prevent that + // here we store and at the end of this scope restore the + // current selection. + ::boost::shared_ptr pSelection (GetPageSelection()); + mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); + // Restore the selection and prevent a recursive call to + // UpdateCurrentPage(). + SetPageSelection(pSelection, false); + return; + } + } + } + + // No page is selected. Do not change the current slide. +} + + + + +//===== PageSelector::UpdateLock ============================================== + +PageSelector::UpdateLock::UpdateLock (SlideSorter& rSlideSorter) + : mrSelector(rSlideSorter.GetController().GetPageSelector()) +{ + ++mrSelector.mnUpdateLockCount; +} + + + + +PageSelector::UpdateLock::~UpdateLock (void) +{ + --mrSelector.mnUpdateLockCount; + OSL_ASSERT(mrSelector.mnUpdateLockCount >= 0); + if (mrSelector.mnUpdateLockCount == 0) + mrSelector.UpdateCurrentPage(); } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 1c61a14ac261..2d6c5a37b234 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -429,6 +429,7 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) { + PageSelector::UpdateLock aLock (mrSlideSorter); FocusManager& rFocusManager (mrController.GetFocusManager()); BOOL bResult = FALSE; @@ -596,15 +597,15 @@ void SelectionFunction::MoveFocus ( mrController.GetFocusManager().MoveFocus(eDirection); - // When shift is pressed then select all pages in the range between the - // currently and the previously focused pages, including them. + PageSelector& rSelector (mrController.GetPageSelector()); + model::SharedPageDescriptor pFocusedDescriptor ( + mrController.GetFocusManager().GetFocusedPageDescriptor()); if (bIsShiftDown) { - model::SharedPageDescriptor pFocusedDescriptor ( - mrController.GetFocusManager().GetFocusedPageDescriptor()); + // When shift is pressed then select all pages in the range between + // the currently and the previously focused pages, including them. if (pFocusedDescriptor) { - PageSelector& rSelector (mrController.GetPageSelector()); sal_Int32 nPageRangeEnd (pFocusedDescriptor->GetPageIndex()); model::PageEnumeration aPages ( model::PageEnumerationProvider::CreateAllPagesEnumeration( @@ -628,6 +629,12 @@ void SelectionFunction::MoveFocus ( } } } + else + { + // Without shift just select the focused page. + rSelector.DeselectAllPages(); + mrController.GetPageSelector().SelectPage(pFocusedDescriptor); + } } @@ -762,6 +769,7 @@ void SelectionFunction::DeselectAllPages (void) void SelectionFunction::RangeSelect (const model::SharedPageDescriptor& rpDescriptor) { + PageSelector::UpdateLock aLock (mrSlideSorter); PageSelector& rSelector (mrController.GetPageSelector()); model::SharedPageDescriptor pAnchor (rSelector.GetSelectionAnchor()); @@ -1028,6 +1036,7 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) bool bMakeSelectionVisible (true); mrController.GetPageSelector().DisableBroadcasting(); + PageSelector::UpdateLock aLock (mrSlideSorter); // 2b. With the event code determine the type of operation with which to // react to the event. @@ -1298,6 +1307,7 @@ void SelectionFunction::ProcessButtonClick ( { OSL_ASSERT(rpDescriptor); + PageSelector::UpdateLock aLock (mrSlideSorter); PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); switch (nButtonIndex) { @@ -1759,7 +1769,8 @@ void RectangleSelector::UpdateSelection (void) view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); if (rOverlay.GetSelectionRectangleOverlay()->IsVisible()) { - view::SlideSorterView::DrawLock aLock (mrSlideSorter); + view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); + PageSelector::UpdateLock aPageSelectorUpdateLock (mrSlideSorter); // Select all pages whose page object lies completly or partially // inside the selection rectangle. diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index 7c6616674328..e83cf76511a2 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -160,10 +160,29 @@ public: the last call to GetPageSelection() it is still valid to call this method with the selection. When pages have been inserted or removed the result may be unexpected. + @param bUpdateCurrentPage + When (the default value) then after setting the + selection update the current page to the first page of the + selection. + When called from withing UpdateCurrentPage() then this flag is + used to prevent a recursion loop. */ - void SetPageSelection (const ::boost::shared_ptr& rSelection); + void SetPageSelection ( + const ::boost::shared_ptr& rSelection, + const bool bUpdateCurrentPage = true); - void UpdateCurrentPage (const model::SharedPageDescriptor& rCurrentPageDescriptor); + /** Use the UpdateLock whenever you do a complex selection, i.e. call + more than one method in a row. An active lock prevents intermediate + changes of the current slide. + */ + class UpdateLock + { + public: + UpdateLock (SlideSorter& rSlideSorter); + ~UpdateLock (void); + private: + PageSelector& mrSelector; + }; private: model::SlideSorterModel& mrModel; @@ -176,8 +195,10 @@ private: /// Anchor for a range selection. model::SharedPageDescriptor mpSelectionAnchor; model::SharedPageDescriptor mpCurrentPage; + sal_Int32 mnUpdateLockCount; void CountSelectedPages (void); + void UpdateCurrentPage (void); }; } } } // end of namespace ::sd::slidesorter::controller -- cgit v1.2.3 From e1f5c8ef3c5bb207946f23c3769f9cd6e536c362 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 17 Feb 2010 18:06:39 +0100 Subject: renaissance1: #i107215# Added detection for assignment of master pages. --- .../ui/slidesorter/cache/SlsBitmapFactory.cxx | 2 +- .../controller/SlideSorterController.cxx | 18 +++++++++++++ .../ui/slidesorter/controller/SlsListener.cxx | 31 ++++++++++++++++++++-- .../inc/controller/SlideSorterController.hxx | 2 ++ .../ui/slidesorter/inc/model/SlsPageDescriptor.hxx | 4 +++ .../ui/slidesorter/model/SlsPageDescriptor.cxx | 21 +++++++++++++++ 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index 596126c02b8b..a8c62b203a13 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -77,7 +77,7 @@ BitmapFactory::~BitmapFactory (void) const bool bDoSuperSampling) { Size aSize (rPixelSize); - bool bDo (bDoSuperSampling); + bool bDo (false);//bDoSuperSampling); if (bDo) { aSize.Width() *= gnSuperSampleFactor; diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 0f007284d2c0..a48fb568577b 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -1039,6 +1039,24 @@ void SlideSorterController::SetDocumentSlides (const ReferenceUpdateMasterPage()) + { + mrView.GetPreviewCache()->InvalidatePreviewBitmap ( + pDescriptor->GetPage(), + true); + } + } +} + + + + //===== SlideSorterController::ModelChangeLock ================================ SlideSorterController::ModelChangeLock::ModelChangeLock ( diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 8d6868c65728..71e93fee500e 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -42,6 +42,7 @@ #include "view/SlideSorterView.hxx" #include "cache/SlsPageCache.hxx" #include "drawdoc.hxx" +#include "DrawDocShell.hxx" #include "glob.hrc" #include "ViewShellBase.hxx" @@ -78,7 +79,8 @@ Listener::Listener ( mxFrameWeak(), mpModelChangeLock() { - StartListening (*mrSlideSorter.GetModel().GetDocument()); + StartListening(*mrSlideSorter.GetModel().GetDocument()); + StartListening(*mrSlideSorter.GetModel().GetDocument()->GetDocSh()); mbListeningToDocument = true; // Connect to the UNO document. @@ -160,7 +162,8 @@ void Listener::ReleaseListeners (void) { if (mbListeningToDocument) { - EndListening (*mrSlideSorter.GetModel().GetDocument()); + EndListening(*mrSlideSorter.GetModel().GetDocument()->GetDocSh()); + EndListening(*mrSlideSorter.GetModel().GetDocument()); mbListeningToDocument = false; } @@ -370,6 +373,16 @@ void Listener::Notify ( break; } } + else if (rHint.ISA(SfxSimpleHint)) + { + SfxSimpleHint& rSfxSimpleHint (*PTR_CAST(SfxSimpleHint,&rHint)); + switch (rSfxSimpleHint.GetId()) + { + case SFX_HINT_DOCCHANGED: + mrController.CheckForMasterPageAssignment(); + break; + } + } } @@ -421,6 +434,20 @@ IMPL_LINK(Listener, EventMultiplexerCallback, ::sd::tools::EventMultiplexerEvent DisconnectFromController(); break; + case tools::EventMultiplexerEvent::EID_SHAPE_CHANGED: + case tools::EventMultiplexerEvent::EID_SHAPE_INSERTED: + case tools::EventMultiplexerEvent::EID_SHAPE_REMOVED: + { + const SdrPage* pPage = static_cast(pEvent->mpUserData); + if (pPage != NULL) + { + mrSlideSorter.GetView().GetPreviewCache()->InvalidatePreviewBitmap( + pPage, + true); + } + } + break; + default: break; } diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index d1266efae992..bffb7d4574ba 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -252,6 +252,8 @@ public: */ ::boost::shared_ptr GetAnimator (void) const; + void CheckForMasterPageAssignment (void); + private: SlideSorter& mrSlideSorter; model::SlideSorterModel& mrModel; diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx index 34c092e4b3f8..c7f3eb159899 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx @@ -42,6 +42,7 @@ #include class SdPage; +class SdrPage; namespace sdr { namespace contact { class ObjectContact; @@ -110,6 +111,8 @@ public: */ sal_Int32 GetPageIndex (void) const; + bool UpdateMasterPage (void); + enum State { ST_Visible, ST_Selected, ST_WasSelected, ST_Focused, ST_MouseOver, ST_Current, ST_Excluded }; @@ -137,6 +140,7 @@ public: private: SdPage* mpPage; css::uno::Reference mxPage; + SdrPage const* mpMasterPage; /** This index is displayed as page number in the view. It may or may not be the actual page index. */ diff --git a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx index 2e5e9b08f905..47cffb132174 100644 --- a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx @@ -51,6 +51,7 @@ PageDescriptor::PageDescriptor ( const sal_Int32 nIndex) : mpPage(pPage), mxPage(rxPage), + mpMasterPage(NULL), mnIndex(nIndex), mbIsSelected(false), mbWasSelected(false), @@ -61,7 +62,10 @@ PageDescriptor::PageDescriptor ( maBoundingBox(), maVisualState(nIndex) { + OSL_ASSERT(mpPage); OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage)); + if (mpPage != NULL) + mpMasterPage = &mpPage->TRG_GetMasterPage(); } @@ -98,6 +102,23 @@ sal_Int32 PageDescriptor::GetPageIndex (void) const +bool PageDescriptor::UpdateMasterPage (void) +{ + const SdrPage* pMaster = NULL; + if (mpPage != NULL) + pMaster = &mpPage->TRG_GetMasterPage(); + if (mpMasterPage != pMaster) + { + mpMasterPage = pMaster; + return true; + } + else + return false; +} + + + + bool PageDescriptor::HasState (const State eState) const { switch (eState) -- cgit v1.2.3 From b237fdf1e2fa89da26fb94839d3010b6a0091733 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 17 Feb 2010 18:49:32 +0100 Subject: renaissance1: #i107215# Added detection for changes of master pages. --- .../ui/slidesorter/controller/SlsListener.cxx | 46 +++++++++++++++++----- .../ui/slidesorter/controller/SlsListener.hxx | 6 +++ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 71e93fee500e..703d44a9533f 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -39,6 +39,7 @@ #include "controller/SlsPageSelector.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "model/SlideSorterModel.hxx" +#include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" #include "cache/SlsPageCache.hxx" #include "drawdoc.hxx" @@ -437,16 +438,8 @@ IMPL_LINK(Listener, EventMultiplexerCallback, ::sd::tools::EventMultiplexerEvent case tools::EventMultiplexerEvent::EID_SHAPE_CHANGED: case tools::EventMultiplexerEvent::EID_SHAPE_INSERTED: case tools::EventMultiplexerEvent::EID_SHAPE_REMOVED: - { - const SdrPage* pPage = static_cast(pEvent->mpUserData); - if (pPage != NULL) - { - mrSlideSorter.GetView().GetPreviewCache()->InvalidatePreviewBitmap( - pPage, - true); - } - } - break; + HandleShapeModification(static_cast(pEvent->mpUserData)); + break; default: break; @@ -629,6 +622,39 @@ void Listener::UpdateEditMode (void) +void Listener::HandleShapeModification (const SdrPage* pPage) +{ + if (pPage == NULL) + return; + + if (pPage->IsMasterPage()) + { + // Invalidate the bitmaps of all pages that are linked to + // this master page. + model::PageEnumeration aAllPages ( + model::PageEnumerationProvider::CreateAllPagesEnumeration( + mrSlideSorter.GetModel())); + while (aAllPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); + SdrPage* pCandidate = pDescriptor->GetPage(); + if (pCandidate!=NULL && &pCandidate->TRG_GetMasterPage() == pPage) + mrSlideSorter.GetView().GetPreviewCache()->InvalidatePreviewBitmap( + pCandidate, + true); + } + } + else + { + mrSlideSorter.GetView().GetPreviewCache()->InvalidatePreviewBitmap( + pPage, + true); + } +} + + + + void Listener::ThrowIfDisposed (void) throw (::com::sun::star::lang::DisposedException) { diff --git a/sd/source/ui/slidesorter/controller/SlsListener.hxx b/sd/source/ui/slidesorter/controller/SlsListener.hxx index 6ace8ebdd370..072349e5d247 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.hxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.hxx @@ -174,6 +174,12 @@ private: */ void UpdateEditMode (void); + /** Handle a modification to a shape on the given page. + When this is a regular page then update its preview. When it is a + master page then update the previews of all pages linked to it. + */ + void HandleShapeModification (const SdrPage* pPage); + /** This method throws a DisposedException when the object has already been disposed. */ -- cgit v1.2.3 From f5d2c01dda56f7544a88e5b85156bae2c71e2a89 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Thu, 18 Feb 2010 15:20:15 +0100 Subject: renaissance1: #i107215# Improved selection handling. --- sd/source/ui/slidesorter/controller/SlsFocusManager.cxx | 6 ++---- sd/source/ui/slidesorter/controller/SlsPageSelector.cxx | 14 ++++++++++++++ .../ui/slidesorter/controller/SlsSelectionFunction.cxx | 4 ++++ .../ui/slidesorter/controller/SlsSelectionManager.cxx | 4 +++- .../ui/slidesorter/inc/controller/SlsPageSelector.hxx | 5 +++++ sd/source/ui/tools/PreviewRenderer.cxx | 11 ++++++----- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index 900658c4bcad..f633060e4dc7 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -168,9 +168,7 @@ void FocusManager::MoveFocus (FocusMoveDirection eDirection) if (mbPageIsFocused) { -#ifndef UNIFY_FOCUS_AND_CURRENT_PAGE ShowFocusIndicator(GetFocusedPageDescriptor(), true); -#endif } } } @@ -295,7 +293,6 @@ void FocusManager::ShowFocusIndicator ( const model::SharedPageDescriptor& rpDescriptor, const bool bScrollToFocus) { -#ifndef UNIFY_FOCUS_AND_CURRENT_PAGE if (rpDescriptor.get() != NULL) { mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true); @@ -308,10 +305,11 @@ void FocusManager::ShowFocusIndicator ( GetFocusedPageDescriptor()->GetBoundingBox()); } +#ifndef UNIFY_FOCUS_AND_CURRENT_PAGE mrSlideSorter.GetView().RequestRepaint (rpDescriptor); +#endif NotifyFocusChangeListeners(); } -#endif } diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index 1a57ff03cc8d..73b5048b1615 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -273,6 +273,14 @@ SharedPageDescriptor PageSelector::GetMostRecentlySelectedPage (void) const +void PageSelector::SetMostRecentlySelectedPage (const model::SharedPageDescriptor& rpDescriptor) +{ + mpMostRecentlySelectedPage = rpDescriptor; +} + + + + SharedPageDescriptor PageSelector::GetSelectionAnchor (void) const { return mpSelectionAnchor; @@ -367,10 +375,16 @@ void PageSelector::UpdateCurrentPage (void) // here we store and at the end of this scope restore the // current selection. ::boost::shared_ptr pSelection (GetPageSelection()); + SharedPageDescriptor pRecentSelection (GetMostRecentlySelectedPage()); + mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); + // Restore the selection and prevent a recursive call to // UpdateCurrentPage(). SetPageSelection(pSelection, false); + // Restore the most recently selected page. Important for + // making the right part of the selection visible. + mpMostRecentlySelectedPage = pRecentSelection; return; } } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 2d6c5a37b234..620c8efca908 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -635,6 +635,10 @@ void SelectionFunction::MoveFocus ( rSelector.DeselectAllPages(); mrController.GetPageSelector().SelectPage(pFocusedDescriptor); } + + // Mark the currently focused page as last selected so that it is made + // visible on the next paint. + mrController.GetPageSelector().SetMostRecentlySelectedPage(pFocusedDescriptor); } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 432d370234f1..3a22668a76e3 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -578,7 +578,9 @@ Rectangle SelectionManager::ResolveLargeSelection ( } OSL_ASSERT(pRepresentative.get() != NULL); - return pRepresentative->GetBoundingBox(); + return mrSlideSorter.GetView().GetLayouter().GetPageObjectBox( + pRepresentative->GetPageIndex(), + true); } diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index e83cf76511a2..d618b1feeb50 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -134,6 +134,11 @@ public: */ model::SharedPageDescriptor GetMostRecentlySelectedPage (void) const; + /** Mark the given page as the most recently selected. Use this method + when the selection does not really change but the focus does. + */ + void SetMostRecentlySelectedPage (const model::SharedPageDescriptor& rpDescriptor); + /** Return the anchor for a range selection. This usually is the first selected page after all pages have been deselected. @return diff --git a/sd/source/ui/tools/PreviewRenderer.cxx b/sd/source/ui/tools/PreviewRenderer.cxx index 4a166b74e1a1..6b9e41f45371 100644 --- a/sd/source/ui/tools/PreviewRenderer.cxx +++ b/sd/source/ui/tools/PreviewRenderer.cxx @@ -46,6 +46,9 @@ #include #include +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + namespace sd { @@ -301,7 +304,7 @@ void PreviewRenderer::PaintPage (const SdPage* pPage) try { - mpView->CompleteRedraw (mpPreviewDevice.get(), aRegion); + mpView->CompleteRedraw(mpPreviewDevice.get(), aRegion); } catch (const ::com::sun::star::uno::Exception&) { @@ -416,10 +419,8 @@ void PreviewRenderer::ProvideView (DrawDocShell* pDocShell) { mpView.reset (new DrawView (pDocShell, mpPreviewDevice.get(), NULL)); } - mpView->SetPreviewRenderer( sal_True ); - mpView->SetBordVisible(FALSE); - mpView->SetPageBorderVisible(TRUE); - mpView->SetPageVisible(FALSE); + mpView->SetPreviewRenderer(true); + mpView->SetPagePaintingAllowed(false); } -- cgit v1.2.3 From 2318e08d02cd3570f0b89a85ebd7fbac8b233ca4 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 19 Feb 2010 11:59:56 +0100 Subject: renaissance1: #i107215# Integrated preview border into shadow bitmap. --- sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx | 4 ++-- sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx | 10 ++++++---- sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx | 3 ++- sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx | 2 +- sd/source/ui/tools/PreviewRenderer.cxx | 9 +++++++++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx index 47cffb132174..4977a7faa882 100644 --- a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx @@ -64,7 +64,7 @@ PageDescriptor::PageDescriptor ( { OSL_ASSERT(mpPage); OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage)); - if (mpPage != NULL) + if (mpPage!=NULL && !mpPage->IsMasterPage()) mpMasterPage = &mpPage->TRG_GetMasterPage(); } @@ -105,7 +105,7 @@ sal_Int32 PageDescriptor::GetPageIndex (void) const bool PageDescriptor::UpdateMasterPage (void) { const SdrPage* pMaster = NULL; - if (mpPage != NULL) + if (mpPage!=NULL && !mpPage->IsMasterPage()) pMaster = &mpPage->TRG_GetMasterPage(); if (mpMasterPage != pMaster) { diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 6fd2fbf55bc3..93ef120e21bf 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -580,9 +580,11 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox); // Clear the area where the preview will later be painted. + /* aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::Background)); aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::PreviewBorder)); aBitmapDevice.DrawRect(aFrameBox); + */ return aBitmapDevice.GetBitmap (Point(0,0),aSize); } @@ -605,7 +607,7 @@ PageObjectPainter::FramePainter::FramePainter (const BitmapEx& rShadowBitmap) { if (rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height() && (rShadowBitmap.GetSizePixel().Width()-1)%2 == 0 - && ((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 0) + && ((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1) { mbIsValid = true; } @@ -613,7 +615,7 @@ PageObjectPainter::FramePainter::FramePainter (const BitmapEx& rShadowBitmap) { OSL_ASSERT(rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height()); OSL_ASSERT((rShadowBitmap.GetSizePixel().Width()-1)%2 == 0); - OSL_ASSERT(((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 0); + OSL_ASSERT(((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1); } } @@ -677,8 +679,8 @@ OffsetBitmap::OffsetBitmap ( nVerticalPosition==0 ? nS : nC); maBitmap = BitmapEx(rBitmap, aOrigin, aSize); maOffset = Point( - nHorizontalPosition<0 ? -nO : nHorizontalPosition>0 ? -nO+1 : 0, - nVerticalPosition<0 ? -nO : nVerticalPosition>0 ? -nO+1 : 0); + nHorizontalPosition<0 ? -nO : nHorizontalPosition>0 ? -nO : 0, + nVerticalPosition<0 ? -nO : nVerticalPosition>0 ? -nO : 0); // Enlarge the side bitmaps so that painting the frame requires less // paint calls. diff --git a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx index 7389887efe1e..aed87ce7cc82 100644 --- a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx @@ -102,7 +102,8 @@ bool ViewCacheContext::IsIdle (void) bool ViewCacheContext::IsVisible (cache::CacheKey aKey) { - return GetDescriptor(aKey)->HasState(model::PageDescriptor::ST_Visible); + const model::SharedPageDescriptor pDescriptor (GetDescriptor(aKey)); + return pDescriptor && pDescriptor->HasState(model::PageDescriptor::ST_Visible); } diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx b/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx index f4027ba6d204..d1175d386b68 100644 --- a/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx +++ b/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx @@ -156,7 +156,7 @@ bool MasterPageContainerQueue::RequestPreview (const SharedMasterPageDescriptor& PreviewCreationRequest::CompareToken(rpDescriptor->maToken))); // When a request for the same token exists then the lowest of the // two priorities is used. - if (HasRequest(rpDescriptor->maToken)) + if (iRequest != mpRequestQueue->end()) if (iRequest->mnPriority < nPriority) { mpRequestQueue->erase(iRequest); diff --git a/sd/source/ui/tools/PreviewRenderer.cxx b/sd/source/ui/tools/PreviewRenderer.cxx index 6b9e41f45371..bf4196667ef3 100644 --- a/sd/source/ui/tools/PreviewRenderer.cxx +++ b/sd/source/ui/tools/PreviewRenderer.cxx @@ -420,7 +420,16 @@ void PreviewRenderer::ProvideView (DrawDocShell* pDocShell) mpView.reset (new DrawView (pDocShell, mpPreviewDevice.get(), NULL)); } mpView->SetPreviewRenderer(true); +#if 1 + mpView->SetPageVisible(false); + mpView->SetPageBorderVisible(true); + mpView->SetBordVisible(false); +#else + // This works in the slide sorter but prevents the master page + // background being painted in the list of current master pages in the + // task manager. mpView->SetPagePaintingAllowed(false); +#endif } -- cgit v1.2.3 From 3c7bf4b67dbe92880d3cb8b7fb24a882651a7ba1 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Tue, 23 Feb 2010 16:56:05 +0100 Subject: renaissance1: #i107215# Improved drag and drop. --- .../controller/SlideSorterController.cxx | 15 +- .../ui/slidesorter/controller/SlsAnimator.cxx | 8 +- .../ui/slidesorter/controller/SlsClipboard.cxx | 37 ++- .../controller/SlsCurrentSlideManager.cxx | 2 +- .../controller/SlsInsertionIndicatorHandler.cxx | 65 ++++- .../ui/slidesorter/controller/SlsPageSelector.cxx | 62 +++-- .../controller/SlsSelectionFunction.cxx | 291 ++++++++------------- .../controller/SlsSubstitutionHandler.cxx | 240 +++++++++++++++++ .../controller/SlsSubstitutionHandler.hxx | 104 ++++++++ .../ui/slidesorter/controller/SlsTransferable.cxx | 15 +- .../ui/slidesorter/controller/SlsTransferable.hxx | 9 +- sd/source/ui/slidesorter/controller/makefile.mk | 4 +- .../inc/controller/SlideSorterController.hxx | 7 + .../controller/SlsInsertionIndicatorHandler.hxx | 24 +- .../slidesorter/inc/controller/SlsPageSelector.hxx | 3 +- .../inc/controller/SlsSelectionFunction.hxx | 16 +- .../ui/slidesorter/inc/model/SlsPageDescriptor.hxx | 16 +- sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 3 +- .../ui/slidesorter/inc/view/SlsViewOverlay.hxx | 26 +- .../ui/slidesorter/model/SlsPageDescriptor.cxx | 6 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 2 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 28 +- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 2 +- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 6 +- sd/source/ui/slidesorter/view/SlsTheme.cxx | 3 - sd/source/ui/slidesorter/view/SlsViewOverlay.cxx | 128 +++++++-- 26 files changed, 801 insertions(+), 321 deletions(-) create mode 100644 sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx create mode 100644 sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index a48fb568577b..67a08fcd41ee 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -440,7 +440,9 @@ bool SlideSorterController::Command ( // indicator so that the user knows where a page insertion // would take place. GetInsertionIndicatorHandler()->Start( - pWindow->PixelToLogic(rEvent.GetMousePosPixel())); + pWindow->PixelToLogic(rEvent.GetMousePosPixel()), + InsertionIndicatorHandler::MoveMode, + false); } pWindow->ReleaseMouse(); @@ -863,6 +865,15 @@ FunctionReference SlideSorterController::CreateSelectionFunction (SfxRequest& rR +::rtl::Reference SlideSorterController::GetCurrentSelectionFunction (void) +{ + FunctionReference pFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction()); + return ::rtl::Reference(dynamic_cast(pFunction.get())); +} + + + + void SlideSorterController::PrepareEditModeChange (void) { // Before we throw away the page descriptors we prepare for selecting @@ -1041,6 +1052,8 @@ void SlideSorterController::SetDocumentSlides (const Reference we do not have to suppress painting + // anymore. + mpDrawLock.reset(); + } } diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 2c44ffc6d754..2f9397c7e8fe 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -367,11 +367,17 @@ void Clipboard::CreateSlideTransferable ( { mrSlideSorter.GetView().BrkAction(); SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument(); + ::boost::shared_ptr pSubstitutionHandler; + ::rtl::Reference pSelectionFunction ( + mrSlideSorter.GetController().GetCurrentSelectionFunction()); + if (pSelectionFunction.is()) + pSubstitutionHandler = pSelectionFunction->GetSubstitutionHandler(); SdTransferable* pTransferable = new Transferable ( pDocument, NULL, FALSE, - dynamic_cast(mrSlideSorter.GetViewShell())); + dynamic_cast(mrSlideSorter.GetViewShell()), + pSubstitutionHandler); if (bDrag) SD_MOD()->pTransferDrag = pTransferable; @@ -433,7 +439,9 @@ void Clipboard::StartDrag ( mbUpdateSelectionPending = false; CreateSlideTransferable(pWindow, TRUE); - mrController.GetInsertionIndicatorHandler()->UpdatePosition(rPosition); + mrController.GetInsertionIndicatorHandler()->UpdatePosition( + rPosition, + InsertionIndicatorHandler::UnknownMode); } @@ -442,8 +450,9 @@ void Clipboard::StartDrag ( void Clipboard::DragFinished (sal_Int8 nDropAction) { // Hide the substitution display and insertion indicator. - mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay()->SetIsVisible(false); - mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(); + ::rtl::Reference pFunction (mrController.GetCurrentSelectionFunction()); + if (pFunction.is()) + pFunction->NotifyDragFinished(); SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; @@ -467,7 +476,8 @@ void Clipboard::DragFinished (sal_Int8 nDropAction) mrController.GetSelectionManager()->DeleteSelectedPages (); } - SelectPages(); + if (nDropAction != DND_ACTION_NONE) + SelectPages(); } @@ -527,7 +537,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); + mrController.GetInsertionIndicatorHandler()->UpdatePosition( + aPosition, + rEvent.maDragEvent.DropAction); rOverlay.GetSubstitutionOverlay()->SetPosition(aPosition); // Scroll the window when the mouse reaches the window border. @@ -580,10 +592,10 @@ sal_Int8 Clipboard::ExecuteDrop ( || ( nXOffset >= 2 && nYOffset >= 2 ); // Get insertion position and then turn off the insertion indicator. - mrController.GetInsertionIndicatorHandler()->UpdatePosition(aEventModelPosition); + mrController.GetInsertionIndicatorHandler()->UpdatePosition( + aEventModelPosition, + rEvent.mnAction); USHORT nIndex = DetermineInsertPosition(*pDragTransferable); - OSL_TRACE ("Clipboard::AcceptDrop() called for index %d", - nIndex); mrController.GetInsertionIndicatorHandler()->End(); if (bContinue) @@ -617,6 +629,13 @@ sal_Int8 Clipboard::ExecuteDrop ( nResult = rEvent.mnAction; } } + + // Notify the receiving selection function that drag-and-drop is + // finished and the substitution handler can be released. + ::rtl::Reference pFunction ( + mrController.GetCurrentSelectionFunction()); + if (pFunction.is()) + pFunction->NotifyDragFinished(); } break; diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx index 2f97124d8576..e2ed42cb9aee 100644 --- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx @@ -134,7 +134,7 @@ void CurrentSlideManager::SwitchCurrentSlide (const sal_Int32 nSlideIndex) void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDescriptor) { - if (rpDescriptor.get() != NULL) + if (rpDescriptor.get() != NULL && mpCurrentSlide!=rpDescriptor) { ReleaseCurrentSlide(); AcquireCurrentSlide((rpDescriptor->GetPage()->GetPageNum()-1)/2); diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 04c505d72b5c..5dd7cf359490 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -37,9 +37,11 @@ #include "view/SlsLayouter.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" +#include #include "SlideSorter.hxx" +using namespace ::com::sun::star::datatransfer::dnd::DNDConstants; namespace sd { namespace slidesorter { namespace controller { @@ -51,8 +53,10 @@ InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter) mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()), mnInsertionIndex(-1), mbIsBeforePage(false), + meMode(MoveMode), mbIsActive(false), - mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()) + mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()), + mbIsOverSourceView(true) { } @@ -66,7 +70,10 @@ InsertionIndicatorHandler::~InsertionIndicatorHandler (void) -void InsertionIndicatorHandler::Start (const Point& rMouseModelPosition) +void InsertionIndicatorHandler::Start ( + const Point& rMouseModelPosition, + const Mode eMode, + const bool bIsOverSourceView) { if (mbIsActive) { @@ -77,15 +84,32 @@ void InsertionIndicatorHandler::Start (const Point& rMouseModelPosition) if (mbIsReadOnly) return; - SetPosition(rMouseModelPosition); + SetPosition(rMouseModelPosition, eMode); mbIsActive = true; + mbIsOverSourceView = bIsOverSourceView; } -void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition) +InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction ( + const sal_Int8 nDndAction) +{ + switch (nDndAction & (ACTION_COPY | ACTION_MOVE | ACTION_LINK)) + { + case ACTION_COPY: return CopyMode; + case ACTION_MOVE: return MoveMode; + default: return UnknownMode; + } +} + + + + +void InsertionIndicatorHandler::UpdatePosition ( + const Point& rMouseModelPosition, + const Mode eMode) { if ( ! mbIsActive) return; @@ -93,7 +117,17 @@ void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition if (mbIsReadOnly) return; - SetPosition(rMouseModelPosition); + SetPosition(rMouseModelPosition, eMode); +} + + + + +void InsertionIndicatorHandler::UpdatePosition ( + const Point& rMouseModelPosition, + const sal_Int8 nDndAction) +{ + UpdatePosition(rMouseModelPosition, GetModeFromDndAction(nDndAction)); } @@ -136,7 +170,9 @@ sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const -void InsertionIndicatorHandler::SetPosition (const Point& rPoint) +void InsertionIndicatorHandler::SetPosition ( + const Point& rPoint, + const Mode eMode) { static const bool bAllowHorizontalInsertMarker = true; view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); @@ -183,11 +219,14 @@ void InsertionIndicatorHandler::SetPosition (const Point& rPoint) nInsertionIndex += 1; } - if (mnInsertionIndex!=nInsertionIndex || mbIsBeforePage!=bIsBeforePage) + if (mnInsertionIndex!=nInsertionIndex + || mbIsBeforePage!=bIsBeforePage + || meMode!=eMode) { mnInsertionIndex = nInsertionIndex; mbIsBeforePage = bIsBeforePage; - mbIsInsertionTrivial = IsInsertionTrivial(); + meMode = eMode; + mbIsInsertionTrivial = IsInsertionTrivial(eMode); mpInsertionIndicatorOverlay->SetLocation( rLayouter.GetInsertionMarkerLocation ( @@ -223,8 +262,16 @@ void InsertionIndicatorHandler::SetPosition (const Point& rPoint) -bool InsertionIndicatorHandler::IsInsertionTrivial (void) const +bool InsertionIndicatorHandler::IsInsertionTrivial (const Mode eMode) const { + if (eMode == CopyMode) + return false; + else if (eMode == UnknownMode) + return true; + + if ( ! mbIsOverSourceView) + return false; + // Iterate over all selected pages and check whether there are // holes. While we do this we remember the indices of the first and // last selected page as preparation for the next step. diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index 73b5048b1615..25767bee7b9a 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -57,6 +57,7 @@ using namespace ::com::sun::star::uno; using namespace ::sd::slidesorter::model; using namespace ::sd::slidesorter::view; + namespace sd { namespace slidesorter { namespace controller { PageSelector::PageSelector (SlideSorter& rSlideSorter) @@ -69,7 +70,8 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter) mpMostRecentlySelectedPage(), mpSelectionAnchor(), mpCurrentPage(), - mnUpdateLockCount(0) + mnUpdateLockCount(0), + mbIsUpdateCurrentPagePending(false) { CountSelectedPages (); } @@ -82,7 +84,6 @@ void PageSelector::SelectAllPages (void) int nPageCount = mrModel.GetPageCount(); for (int nPageIndex=0; nPageIndex 0) + { + mbIsUpdateCurrentPagePending = true; + return; + } + + if ( ! mbIsUpdateCurrentPagePending && bUpdateOnlyWhenPending) + return; + + mbIsUpdateCurrentPagePending = false; + // Make the first selected page the current page. - if (mnUpdateLockCount == 0) + const sal_Int32 nPageCount (GetPageCount()); + for (sal_Int32 nIndex=0; nIndexHasState(PageDescriptor::ST_Selected)) { - SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex)); - if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected)) - { - // Switching the current slide normally sets also the - // selection to just the new current slide. To prevent that - // here we store and at the end of this scope restore the - // current selection. - ::boost::shared_ptr pSelection (GetPageSelection()); - SharedPageDescriptor pRecentSelection (GetMostRecentlySelectedPage()); - - mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); - - // Restore the selection and prevent a recursive call to - // UpdateCurrentPage(). - SetPageSelection(pSelection, false); - // Restore the most recently selected page. Important for - // making the right part of the selection visible. - mpMostRecentlySelectedPage = pRecentSelection; - return; - } + // Switching the current slide normally sets also the selection + // to just the new current slide. To prevent that here we store + // and at the end of this scope restore the current selection. + ::boost::shared_ptr pSelection (GetPageSelection()); + SharedPageDescriptor pRecentSelection (GetMostRecentlySelectedPage()); + + mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); + + // Restore the selection and prevent a recursive call to + // UpdateCurrentPage(). + SetPageSelection(pSelection, false); + // Restore the most recently selected page. Important for + // making the right part of the selection visible. + mpMostRecentlySelectedPage = pRecentSelection; + return; } } @@ -412,7 +420,7 @@ PageSelector::UpdateLock::~UpdateLock (void) --mrSelector.mnUpdateLockCount; OSL_ASSERT(mrSelector.mnUpdateLockCount >= 0); if (mrSelector.mnUpdateLockCount == 0) - mrSelector.UpdateCurrentPage(); + mrSelector.UpdateCurrentPage(true); } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 620c8efca908..203cc087df56 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -34,6 +34,8 @@ #include "SlideSorter.hxx" #include "SlideSorterViewShell.hxx" +#include "SlsSubstitutionHandler.hxx" +#include "SlsTransferable.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsPageSelector.hxx" #include "controller/SlsFocusManager.hxx" @@ -43,6 +45,7 @@ #include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsSelectionManager.hxx" #include "controller/SlsProperties.hxx" +#include "controller/SlsProperties.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" @@ -57,6 +60,8 @@ #include "Window.hxx" #include "sdpage.hxx" #include "drawdoc.hxx" +#include "DrawDocShell.hxx" +#include "sdxfer.hxx" #include "ViewShell.hxx" #include "ViewShellBase.hxx" #include "FrameView.hxx" @@ -108,49 +113,6 @@ static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIF namespace sd { namespace slidesorter { namespace controller { -/** 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. -*/ -class SelectionFunction::SubstitutionHandler -{ -public: - /** Create a substitution display of the currently selected pages and - use the given position as the anchor point. - */ - SubstitutionHandler ( - SlideSorter& rSlideSorter, - const model::SharedPageDescriptor& rpHitDescriptor, - const Point& rMouseModelPosition); - ~SubstitutionHandler (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. - */ - void Dispose (void); - - /** Move the substitution display by the distance the mouse has - travelled since the last call to this method or to - CreateSubstitution(). The given point becomes the new anchor. - */ - void UpdatePosition ( - const Point& rMousePosition, - const bool bAllowAutoScroll = true); - -private: - SlideSorter& mrSlideSorter; - model::SharedPageDescriptor mpHitDescriptor; - sal_Int32 mnInsertionIndex; - - /** Move the substitution display of the currently selected pages. - */ - void Process (void); -}; - - - class SelectionFunction::MouseMultiSelector { @@ -241,13 +203,13 @@ namespace { class SelectionFunction::EventDescriptor { public: - Point maMousePosition; Point maMouseModelPosition; ::boost::weak_ptr mpHitDescriptor; SdrPage* mpHitPage; sal_uInt32 mnEventCode; sal_Int32 mnButtonIndex; + InsertionIndicatorHandler::Mode meDragMode; EventDescriptor ( sal_uInt32 nEventType, @@ -260,6 +222,8 @@ public: const AcceptDropEvent& rEvent, SlideSorter& rSlideSorter); EventDescriptor (const EventDescriptor& rDescriptor); + + void SetDragMode (const InsertionIndicatorHandler::Mode eMode); }; @@ -290,6 +254,9 @@ SelectionFunction::SelectionFunction ( aDragTimer.SetTimeoutHdl(LINK(this, SelectionFunction, DragSlideHdl)); } + + + SelectionFunction::~SelectionFunction (void) { aDragTimer.Stop(); @@ -353,14 +320,18 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) (rEvent.GetButtons() & MOUSE_LEFT)!=0); } - if (rEvent.IsLeaveWindow()) + // Detect the mouse leaving the window. When not button is pressed then + // we can call IsLeaveWindow at the event. Otherwise we have to make an + // explicit test. + if (rEvent.IsLeaveWindow() + || ! Rectangle(Point(0,0),mpWindow->GetOutputSizePixel()).IsInside(aMousePosition)) { - // Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel()); - // if ( ! aRectangle.IsInside(aMousePosition) if (mpSubstitutionHandler) { // Mouse left the window with pressed left button. Make it a drag. - StartDrag(aMousePosition); + StartDrag(aMousePosition, InsertionIndicatorHandler::MoveMode); + mpSubstitutionHandler->Hide(); + mpSubstitutionHandler.reset(); } mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); } @@ -404,18 +375,59 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent) void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) { + if (rEvent.mbLeaving) + { + if (mpSubstitutionHandler) + { + // Disconnect the substitution handler from this selection function. + mpSubstitutionHandler->Hide(); + mpSubstitutionHandler->SetTargetSlideSorter(); + mpSubstitutionHandler.reset(); + } + } + else if ( ! mpSubstitutionHandler) + { + 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)); + } + // 1. Compute some frequently used values relating to the event. ::std::auto_ptr pEventDescriptor ( new EventDescriptor(rEvent, mrSlideSorter)); // 2. Detect whether we are dragging pages or dragging a selection rectangle. view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - if (rOverlay.GetSubstitutionOverlay()->IsVisible()) + if (mpSubstitutionHandler) pEventDescriptor->mnEventCode |= SUBSTITUTION_VISIBLE; if (mpMouseMultiSelector) pEventDescriptor->mnEventCode |= RECTANGLE_VISIBLE; - // 3. Process the event. + // 3. Set the drag mode. + pEventDescriptor->SetDragMode( + InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction)); + + // 4. Process the event. EventPreprocessing(*pEventDescriptor); if ( ! EventProcessing(*pEventDescriptor)) { @@ -427,6 +439,27 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) +void SelectionFunction::NotifyDragFinished (void) +{ + if (mpSubstitutionHandler) + { + mpSubstitutionHandler->Dispose(); + mpSubstitutionHandler.reset(); + } + mrController.GetInsertionIndicatorHandler()->End(); +} + + + + +::boost::shared_ptr SelectionFunction::GetSubstitutionHandler (void) const +{ + return mpSubstitutionHandler; +} + + + + BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) { PageSelector::UpdateLock aLock (mrSlideSorter); @@ -717,14 +750,16 @@ void SelectionFunction::StartDragTimer (void) IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG ) { - StartDrag(aMDPos); + StartDrag(aMDPos, InsertionIndicatorHandler::MoveMode); return 0; } -void SelectionFunction::StartDrag (const Point& rMousePosition) +void SelectionFunction::StartDrag ( + const Point& rMousePosition, + const InsertionIndicatorHandler::Mode eMode) { if (mbPageHit && ! mrSlideSorter.GetProperties()->IsUIReadOnly()) @@ -736,7 +771,9 @@ void SelectionFunction::StartDrag (const Point& rMousePosition) mrSlideSorter.GetController().GetPageAt(rMousePosition), rMousePosition)); else - mpSubstitutionHandler->UpdatePosition(rMousePosition); + mpSubstitutionHandler->UpdatePosition( + rMousePosition, + eMode); mbPageHit = false; mpWindow->ReleaseMouse(); @@ -1053,16 +1090,21 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) switch (rDescriptor.mnEventCode & (SUBSTITUTION_VISIBLE | RECTANGLE_VISIBLE)) { 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); - mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition); + StartDrag(rDescriptor.maMousePosition, InsertionIndicatorHandler::CopyMode); + mpSubstitutionHandler->UpdatePosition( + rDescriptor.maMousePosition, + rDescriptor.meDragMode); } else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG)) { - mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition); + mpSubstitutionHandler->UpdatePosition( + rDescriptor.maMousePosition, + rDescriptor.meDragMode); } else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON)) { @@ -1395,7 +1437,8 @@ SelectionFunction::EventDescriptor::EventDescriptor ( mpHitDescriptor(), mpHitPage(), mnEventCode(0), - mnButtonIndex(-1) + mnButtonIndex(-1), + meDragMode(InsertionIndicatorHandler::MoveMode) { model::SharedPageDescriptor pHitDescriptor ( rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); @@ -1418,7 +1461,8 @@ SelectionFunction::EventDescriptor::EventDescriptor ( mpHitDescriptor(), mpHitPage(), mnEventCode(MOUSE_DRAG), - mnButtonIndex(-1) + mnButtonIndex(-1), + meDragMode(InsertionIndicatorHandler::MoveMode) { SharedSdWindow pWindow (rSlideSorter.GetContentWindow()); @@ -1441,132 +1485,17 @@ SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDes mpHitDescriptor(rDescriptor.mpHitDescriptor), mpHitPage(rDescriptor.mpHitPage), mnEventCode(rDescriptor.mnEventCode), - mnButtonIndex(rDescriptor.mnButtonIndex) + mnButtonIndex(rDescriptor.mnButtonIndex), + meDragMode(InsertionIndicatorHandler::MoveMode) { } -//===== SubstitutionHandler =================================================== - -SelectionFunction::SubstitutionHandler::SubstitutionHandler ( - SlideSorter& rSlideSorter, - const model::SharedPageDescriptor& rpHitDescriptor, - const Point& rMouseModelPosition) - : mrSlideSorter(rSlideSorter), - mpHitDescriptor(rpHitDescriptor), - mnInsertionIndex(-1) -{ - mnInsertionIndex = -1; - - // No Drag-and-Drop for master pages. - if (mrSlideSorter.GetModel().GetEditMode() != EM_PAGE) - return; - - if (mrSlideSorter.GetProperties()->IsUIReadOnly()) - return; - - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - - if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible()) - { - // Show a new substitution for the selected page objects. - model::PageEnumeration aSelectedPages( - model::PageEnumerationProvider::CreateSelectedPagesEnumeration( - mrSlideSorter.GetModel())); - rOverlay.GetSubstitutionOverlay()->Create( - aSelectedPages, - rMouseModelPosition, - mpHitDescriptor); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); - mrSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(rMouseModelPosition); - } -} - - - - -SelectionFunction::SubstitutionHandler::~SubstitutionHandler (void) +void SelectionFunction::EventDescriptor::SetDragMode (const InsertionIndicatorHandler::Mode eMode) { - Process(); - - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - rOverlay.GetSubstitutionOverlay()->Clear(); - mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(); - mpHitDescriptor.reset(); -} - - - - -void SelectionFunction::SubstitutionHandler::Dispose (void) -{ - mnInsertionIndex = -1; -} - - - - -void SelectionFunction::SubstitutionHandler::UpdatePosition ( - const Point& rMousePosition, - const bool bAllowAutoScroll) -{ - if (mrSlideSorter.GetProperties()->IsUIReadOnly()) - return; - - // Convert window coordinates into model coordinates (we need the - // window coordinates for auto-scrolling because that remains - // constant while scrolling.) - SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); - - if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll( - rMousePosition, - ::boost::bind( - &SelectionFunction::SubstitutionHandler::UpdatePosition, - this, - rMousePosition, - false)))) - { - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); - - // Move the existing substitution to the new position. - rOverlay.GetSubstitutionOverlay()->SetPosition(aMouseModelPosition); - - mrSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdatePosition( - aMouseModelPosition); - - // Remember the new insertion index. - if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial()) - mnInsertionIndex = -1; - else - mnInsertionIndex = mrSlideSorter.GetController().GetInsertionIndicatorHandler() - ->GetInsertionPageIndex(); - } -} - - - - -void SelectionFunction::SubstitutionHandler::Process (void) -{ - if (mrSlideSorter.GetProperties()->IsUIReadOnly()) - return; - - if (mnInsertionIndex >= 0) - { - // Tell the model to move the selected pages behind the one with the - // index mnInsertionIndex which first has to transformed into an index - // understandable by the document. - USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1; - mrSlideSorter.GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex); - - ViewShell* pViewShell = mrSlideSorter.GetViewShell(); - if (pViewShell != NULL) - pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE); - } + meDragMode = eMode; } @@ -1849,11 +1778,14 @@ void RangeSelector::UpdateSelection (void) { view::SlideSorterView::DrawLock aLock (mrSlideSorter); + model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); + const sal_Int32 nPageCount (rModel.GetPageCount()); + const sal_Int32 nIndexUnderMouse ( mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint ( maSecondCorner, false)); - if (nIndexUnderMouse >= 0) + if (nIndexUnderMouse>=0 && nIndexUnderMouse + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "SlsSubstitutionHandler.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 "app.hrc" +#include +#include + +namespace sd { namespace slidesorter { namespace controller { + +SubstitutionHandler::SubstitutionHandler ( + SlideSorter& rSlideSorter, + const model::SharedPageDescriptor& rpHitDescriptor, + const Point& rMouseModelPosition) + : mpTargetSlideSorter(&rSlideSorter), + mpHitDescriptor(rpHitDescriptor), + mnInsertionIndex(-1) +{ + // No Drag-and-Drop for master pages. + if (rSlideSorter.GetModel().GetEditMode() != EM_PAGE) + return; + + view::ViewOverlay& rOverlay (rSlideSorter.GetView().GetOverlay()); + + if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible()) + { + // Show a new substitution for the selected page objects. + model::PageEnumeration aSelectedPages( + model::PageEnumerationProvider::CreateSelectedPagesEnumeration( + rSlideSorter.GetModel())); + rOverlay.GetSubstitutionOverlay()->Create( + aSelectedPages, + rMouseModelPosition, + mpHitDescriptor); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); + rSlideSorter.GetController().GetInsertionIndicatorHandler()->Start( + rMouseModelPosition, + InsertionIndicatorHandler::MoveMode, + true); + } +} + + + + +SubstitutionHandler::~SubstitutionHandler (void) +{ + if (mpTargetSlideSorter != NULL) + mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll(); + + Process(); + + 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) +{ + mnInsertionIndex = -1; +} + + + + +void SubstitutionHandler::UpdatePosition ( + const Point& rMousePosition, + const InsertionIndicatorHandler::Mode eMode, + const bool bAllowAutoScroll) +{ + if (mpTargetSlideSorter == NULL) + return; + + if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly()) + return; + + // Convert window coordinates into model coordinates (we need the + // window coordinates for auto-scrolling because that remains + // constant while scrolling.) + SharedSdWindow pWindow (mpTargetSlideSorter->GetContentWindow()); + const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + + if ( ! (bAllowAutoScroll + && mpTargetSlideSorter->GetController().GetScrollBarManager().AutoScroll( + rMousePosition, + ::boost::bind( + &SubstitutionHandler::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); + + // Remember the new insertion index. + if (mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial(eMode)) + mnInsertionIndex = -1; + else + mnInsertionIndex = mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler() + ->GetInsertionPageIndex(); + } +} + + + + +void SubstitutionHandler::Process (void) +{ + if (mpTargetSlideSorter == NULL) + return; + + if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly()) + return; + + if (mnInsertionIndex >= 0) + { + // Tell the model to move the selected pages behind the one with the + // index mnInsertionIndex which first has to transformed into an index + // understandable by the document. + USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1; + mpTargetSlideSorter->GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex); + + ViewShell* pViewShell = mpTargetSlideSorter->GetViewShell(); + if (pViewShell != NULL) + pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE); + } +} + + + + +void SubstitutionHandler::Show (void) +{ + if (mpTargetSlideSorter != NULL) + { + view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); + } +} + + + + +void SubstitutionHandler::Hide (void) +{ + if (mpTargetSlideSorter != NULL) + { + view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); + rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); + } +} + + + + +void SubstitutionHandler::SetTargetSlideSorter ( + SlideSorter* pSlideSorter, + const Point aMousePosition, + const InsertionIndicatorHandler::Mode eMode, + const bool bIsOverSourceView) +{ + if (mpTargetSlideSorter != NULL) + { + mpOverlayState = mpTargetSlideSorter->GetView().GetOverlay().GetSubstitutionOverlay() + ->GetInternalState(); + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); + } + + mpTargetSlideSorter = pSlideSorter; + + if (mpTargetSlideSorter != NULL) + { + mpTargetSlideSorter->GetView().GetOverlay().GetSubstitutionOverlay()->SetInternalState( + mpOverlayState); + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start( + aMousePosition, + eMode, + bIsOverSourceView); + } +} + + + +} } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx new file mode 100644 index 000000000000..da1a2ad0bd52 --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * 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: 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 + * 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_SUBSTITUTION_HANDLER_HXX +#define SD_SLIDESORTER_SUBSTITUTION_HANDLER_HXX + +#include + +#include "model/SlsSharedPageDescriptor.hxx" +#include "view/SlsViewOverlay.hxx" +#include "controller/SlsInsertionIndicatorHandler.hxx" + +namespace sd { namespace slidesorter { +class SlideSorter; +} } + + + +namespace sd { namespace slidesorter { namespace controller { + + +/** 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. +*/ +class SubstitutionHandler +{ +public: + /** Create a substitution display of the currently selected pages and + use the given position as the anchor point. + */ + SubstitutionHandler ( + SlideSorter& rSlideSorter, + const model::SharedPageDescriptor& rpHitDescriptor, + const Point& rMouseModelPosition); + ~SubstitutionHandler (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. + */ + void Dispose (void); + + /** Move the substitution display by the distance the mouse has + travelled since the last call to this method or to + CreateSubstitution(). The given point becomes the new anchor. + */ + void UpdatePosition ( + const Point& rMousePosition, + const InsertionIndicatorHandler::Mode eMode, + const bool bAllowAutoScroll = true); + + void Show (void); + void Hide (void); + void SetTargetSlideSorter ( + SlideSorter* pSlideSorter = NULL, + const Point aMousePosition = Point(0,0), + const InsertionIndicatorHandler::Mode eMode = InsertionIndicatorHandler::UnknownMode, + const bool bIsOverSourceView = false); + +private: + SlideSorter* mpTargetSlideSorter; + view::SubstitutionOverlay::SharedInternalState mpOverlayState; + model::SharedPageDescriptor mpHitDescriptor; + sal_Int32 mnInsertionIndex; + + /** Move the substitution display of the currently selected pages. + */ + void Process (void); +}; + + + +} } } // end of namespace ::sd::slidesorter::controller + +#endif diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.cxx b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx index f072f6815285..e9c6f58b1289 100644 --- a/sd/source/ui/slidesorter/controller/SlsTransferable.cxx +++ b/sd/source/ui/slidesorter/controller/SlsTransferable.cxx @@ -42,9 +42,11 @@ Transferable::Transferable ( SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, BOOL bInitOnGetData, - SlideSorterViewShell* pViewShell) + SlideSorterViewShell* pViewShell, + const ::boost::shared_ptr& rpSubstitutionHandler) : SdTransferable (pSrcDoc, pWorkView, bInitOnGetData), - mpViewShell(pViewShell) + mpViewShell(pViewShell), + mpSubstitutionHandler(rpSubstitutionHandler) { if (mpViewShell != NULL) StartListening(*mpViewShell); @@ -52,6 +54,7 @@ Transferable::Transferable ( + Transferable::~Transferable (void) { if (mpViewShell != NULL) @@ -65,6 +68,7 @@ void Transferable::DragFinished (sal_Int8 nDropAction) { if (mpViewShell != NULL) mpViewShell->DragFinished(nDropAction); + mpSubstitutionHandler.reset(); } @@ -92,4 +96,11 @@ void Transferable::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) +::boost::shared_ptr Transferable::GetSubstitutionHandler (void) const +{ + return mpSubstitutionHandler; +} + + + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx b/sd/source/ui/slidesorter/controller/SlsTransferable.hxx index 2dd02e068ade..3929e71176ff 100644 --- a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx +++ b/sd/source/ui/slidesorter/controller/SlsTransferable.hxx @@ -45,6 +45,9 @@ namespace sd 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. */ @@ -56,14 +59,18 @@ public: SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, BOOL bInitOnGetData, - SlideSorterViewShell* pViewShell); + SlideSorterViewShell* pViewShell, + const ::boost::shared_ptr& rpSubstitutionHandler); virtual ~Transferable (void); virtual void DragFinished (sal_Int8 nDropAction); + ::boost::shared_ptr GetSubstitutionHandler (void) const; + private: SlideSorterViewShell* mpViewShell; + ::boost::shared_ptr mpSubstitutionHandler; virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); }; diff --git a/sd/source/ui/slidesorter/controller/makefile.mk b/sd/source/ui/slidesorter/controller/makefile.mk index be1e56464d59..6f48104fdd9c 100644 --- a/sd/source/ui/slidesorter/controller/makefile.mk +++ b/sd/source/ui/slidesorter/controller/makefile.mk @@ -62,11 +62,9 @@ SLOFILES = \ $(SLO)$/SlsSelectionFunction.obj \ $(SLO)$/SlsSelectionManager.obj \ $(SLO)$/SlsSlotManager.obj \ + $(SLO)$/SlsSubstitutionHandler.obj \ $(SLO)$/SlsTransferable.obj -EXCEPTIONSFILES= \ - $(SLO)$/SlideSorterController.obj - # --- Tagets ------------------------------------------------------- .INCLUDE : target.mk diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index bffb7d4574ba..ef5b07d8d670 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -68,6 +68,7 @@ class InsertionIndicatorHandler; class Listener; class PageSelector; class ScrollBarManager; +class SelectionFunction; class SelectionManager; class SlotManager; @@ -207,6 +208,12 @@ public: */ virtual FunctionReference CreateSelectionFunction (SfxRequest& rRequest); + /** When the current function of the view shell is the slide sorter + selection function then return a reference to it. Otherwise return + an empty reference. + */ + ::rtl::Reference GetCurrentSelectionFunction (void); + /** Prepare for a change of the edit mode. Depending on the current edit mode we may save the selection so that it can be restored when later changing back to the current edit mode. diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx index 006cf0083ed9..e50f7c3234eb 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -52,13 +52,24 @@ public: InsertionIndicatorHandler (SlideSorter& rSlideSorter); ~InsertionIndicatorHandler (void); + enum Mode { CopyMode, MoveMode, UnknownMode }; + static Mode GetModeFromDndAction (const sal_Int8 nMode); + /** Activate the insertion marker at the given coordinates. */ - void Start (const Point& rMouseModelPosition); + void Start ( + const Point& rMouseModelPosition, + const Mode eMode, + const bool bIsOverSourceView); /** Set the position of the insertion marker to the given coordinates. */ - void UpdatePosition (const Point& rMouseModelPosition); + void UpdatePosition ( + const Point& rMouseModelPosition, + const Mode eMode); + void UpdatePosition ( + const Point& rMouseModelPosition, + const sal_Int8 nDndAction); /** Deactivate the insertion marker. */ @@ -73,12 +84,13 @@ public: */ sal_Int32 GetInsertionPageIndex (void) const; + /** Determine whether moving the current selection to the current position of the insertion marker would alter the document. This 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 (void) const; + bool IsInsertionTrivial (const Mode eMode) const; private: SlideSorter& mrSlideSorter; @@ -86,11 +98,15 @@ private: ::boost::shared_ptr mpInsertionIndicatorOverlay; sal_Int32 mnInsertionIndex; bool mbIsBeforePage; + Mode meMode; bool mbIsInsertionTrivial; bool mbIsActive; bool mbIsReadOnly; + bool mbIsOverSourceView; - void SetPosition (const Point& rPoint); + void SetPosition ( + const Point& rPoint, + const Mode eMode); ::boost::shared_ptr GetInsertAnimator (void); }; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index d618b1feeb50..0d22127a819e 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -201,9 +201,10 @@ private: model::SharedPageDescriptor mpSelectionAnchor; model::SharedPageDescriptor mpCurrentPage; sal_Int32 mnUpdateLockCount; + bool mbIsUpdateCurrentPagePending; void CountSelectedPages (void); - void UpdateCurrentPage (void); + void UpdateCurrentPage (const bool bUpdateOnlyWhenPending = false); }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index d1b8fedd1143..0eb5710e8bbd 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -33,6 +33,7 @@ #include "model/SlsSharedPageDescriptor.hxx" #include "controller/SlsFocusManager.hxx" +#include "controller/SlsInsertionIndicatorHandler.hxx" #include "fupoor.hxx" #include #include @@ -51,6 +52,8 @@ class SlideSorter; namespace sd { namespace slidesorter { namespace controller { class SlideSorterController; +class SubstitutionHandler; + class SelectionFunction : public FuPoor, @@ -93,6 +96,12 @@ public: void MouseDragged (const AcceptDropEvent& rEvent); + /** Turn of substitution display and insertion indicator. + */ + void NotifyDragFinished (void); + + ::boost::shared_ptr GetSubstitutionHandler (void) const; + class MouseMultiSelector; protected: @@ -106,7 +115,6 @@ protected: virtual ~SelectionFunction(); private: - class SubstitutionHandler; class EventDescriptor; /// Set in MouseButtonDown this flag indicates that a page has been hit. @@ -127,7 +135,7 @@ private: */ bool mbProcessingMouseButtonDown; - ::boost::scoped_ptr mpSubstitutionHandler; + ::boost::shared_ptr mpSubstitutionHandler; ::boost::scoped_ptr mpMouseMultiSelector; /** Remember where the left mouse button was pressed. @@ -143,7 +151,9 @@ private: sal_Int32 mnShiftKeySelectionAnchor; DECL_LINK( DragSlideHdl, Timer* ); - void StartDrag (const Point& rMousePosition); + void StartDrag ( + const Point& rMousePosition, + const InsertionIndicatorHandler::Mode eMode); /** Set the selection to exactly the specified page and also set it as the current page. diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx index c7f3eb159899..105f4ca89f13 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx @@ -40,23 +40,12 @@ #include #include +#include + class SdPage; class SdrPage; -namespace sdr { namespace contact { -class ObjectContact; -} } - -namespace sd { namespace slidesorter { namespace view { -class PageObject; -class PageObjectViewObjectContact; -} } } - -namespace sd { namespace slidesorter { namespace controller { -class PageObjectFactory; -} } } - namespace sd { namespace slidesorter { namespace model { class SlideRenderer; @@ -141,6 +130,7 @@ private: SdPage* mpPage; css::uno::Reference mxPage; SdrPage const* mpMasterPage; + /** This index is displayed as page number in the view. It may or may not be the actual page index. */ diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index ad6a9ee7b2cb..851f8c4ffc49 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -77,8 +77,7 @@ public: MouseOverColor, PageNumberBorder, PageNumberColor, - Selection, - PreviewBorder + Selection }; ColorData GetColor (const ColorType eType); diff --git a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx b/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx index 911160501935..b918da47bf8f 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx @@ -126,9 +126,11 @@ public: */ void Create ( model::PageEnumeration& rSelection, - const Point& rPosition, + const Point& rAnchor, const model::SharedPageDescriptor& rpHitDescriptor); + void SetAnchor (const Point& rAnchor); + /** Clear the substitution display. Until the next call of Create() no substution is painted. */ @@ -136,7 +138,7 @@ public: /** Move the substitution display by the given amount of pixels. */ - void Move (const Point& rOffset); + void Move (const Point& rPositionOffset); void SetPosition (const Point& rPosition); Point GetPosition (void) const; @@ -144,12 +146,19 @@ public: OutputDevice& rDevice, const Rectangle& rRepaintArea); + class InternalState; + typedef ::boost::shared_ptr SharedInternalState; + SharedInternalState GetInternalState (void) const; + void SetInternalState (const SharedInternalState& rpState); + protected: virtual Rectangle GetBoundingBox (void) const; private: + /** The current position can be set by calling SetPosition() or Move(). + */ Point maPosition; - Point maTranslation; + /** 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 @@ -160,16 +169,7 @@ private: static const sal_Int32 mnSideTransparency; static const sal_Int32 mnCornerTransparency; - class ItemDescriptor - { - public: - BitmapEx maImage; - Point maLocation; - double mnTransparency; - basegfx::B2DPolygon maShape; - }; - ::std::vector maItems; - Rectangle maBoundingBox; + SharedInternalState mpState; }; diff --git a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx index 4977a7faa882..2b7a2832a5f8 100644 --- a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx @@ -39,12 +39,14 @@ #include #include #include +#include using namespace ::com::sun::star::uno; using namespace ::com::sun::star; namespace sd { namespace slidesorter { namespace model { + PageDescriptor::PageDescriptor ( const Reference& rxPage, SdPage* pPage, @@ -64,7 +66,7 @@ PageDescriptor::PageDescriptor ( { OSL_ASSERT(mpPage); OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage)); - if (mpPage!=NULL && !mpPage->IsMasterPage()) + if (mpPage!=NULL && mpPage->TRG_HasMasterPage()) mpMasterPage = &mpPage->TRG_GetMasterPage(); } @@ -105,7 +107,7 @@ sal_Int32 PageDescriptor::GetPageIndex (void) const bool PageDescriptor::UpdateMasterPage (void) { const SdrPage* pMaster = NULL; - if (mpPage!=NULL && !mpPage->IsMasterPage()) + if (mpPage!=NULL && mpPage->TRG_HasMasterPage()) pMaster = &mpPage->TRG_GetMasterPage(); if (mpMasterPage != pMaster) { diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 97d2b563906d..992f65d03692 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -601,7 +601,7 @@ void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView) // sorter is displayed in a side pane then we ignore the value // of the frame view and adapt the number of columns // automatically to the window width. - rView.GetLayouter().SetColumnCount(1,5); + rView.GetLayouter().SetColumnCount(1,1); } else rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow); diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 0f69e892779b..4ad682486f1a 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -40,21 +40,21 @@ namespace sd { namespace slidesorter { namespace view { Layouter::Layouter (const SharedSdWindow& rpWindow) : mpWindow(rpWindow), - mnRequestedLeftBorder(35), - mnRequestedRightBorder(35), - mnRequestedTopBorder(10), - mnRequestedBottomBorder(10), - mnLeftBorder(30), - mnRightBorder(30), - mnTopBorder(10), - mnBottomBorder(10), + mnRequestedLeftBorder(5), + mnRequestedRightBorder(5), + mnRequestedTopBorder(5), + mnRequestedBottomBorder(5), + mnLeftBorder(5), + mnRightBorder(5), + mnTopBorder(5), + mnBottomBorder(5), mnVerticalGap (10), - mnHorizontalGap (10), - mnMinimalWidth (100), - mnPreferredWidth (200), - mnMaximalWidth (300), - mnMinimalColumnCount (1), - mnMaximalColumnCount (5), + mnHorizontalGap(10), + mnMinimalWidth(100), + mnPreferredWidth(200), + mnMaximalWidth(300), + mnMinimalColumnCount(1), + mnMaximalColumnCount(1), mnPageCount(0), mnColumnCount(1), mnRowCount(0), diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx index 10cd7ca93ef6..2b89006dc9ea 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -43,7 +43,7 @@ namespace { const static sal_Int32 gnPageNumberOffset = 5; const static sal_Int32 gnPageNumberFrameHorizontalOffset = 2; const static sal_Int32 gnPageNumberFrameVerticalOffset = 1; -const static sal_Int32 gnOuterBorderWidth = 6; +const static sal_Int32 gnOuterBorderWidth = 5; const static sal_Int32 gnInfoAreaMinWidth = 26; const static Size gaButtonSize (32,32); const static sal_Int32 gnButtonGap (5); diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 93ef120e21bf..9921e3ca070c 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -580,11 +580,9 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox); // Clear the area where the preview will later be painted. - /* aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::Background)); - aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::PreviewBorder)); - aBitmapDevice.DrawRect(aFrameBox); - */ + aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::Background)); + aBitmapDevice.DrawRect(aBox); return aBitmapDevice.GetBitmap (Point(0,0),aSize); } diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index ddc1e4ccd543..a40dda166eee 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -214,9 +214,6 @@ ColorData Theme::GetColor (const ColorType eType) case Selection: return StellaBlue; - - case PreviewBorder: - return 0x000000; } return 0; } diff --git a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx index d406a3c866b7..8f8357ffb934 100644 --- a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx @@ -105,6 +105,41 @@ Rectangle ConvertRectangle (const B2DRectangle& rBox) namespace sd { namespace slidesorter { namespace view { +//===== SubstitutionOverlay::InternalState ==================================== + +class ItemDescriptor +{ +public: + BitmapEx maImage; + Point maLocation; + double mnTransparency; + basegfx::B2DPolygon maShape; +}; + +class SubstitutionOverlay::InternalState +{ +public: + /** The set of items that is displayed as substitution of the selected + pages. Note that the number of items may differ from the number of + selected pages because only the selected pages in the neighborhood + of the anchor page are included. + */ + ::std::vector maItems; + + /** Bounding box of all items in maItems at their original location. + */ + Rectangle maBoundingBox; + + /** The anchor position of the substitution is the paint that, after + translation, is mapped onto the current position. + */ + Point maAnchor; + +}; + + + + //===== ViewOverlay ========================================================= ViewOverlay::ViewOverlay ( @@ -293,9 +328,7 @@ SubstitutionOverlay::SubstitutionOverlay ( const sal_Int32 nLayerIndex) : OverlayBase(rViewOverlay, nLayerIndex), maPosition(0,0), - maTranslation(0,0), - maItems(), - maBoundingBox() + mpState(new InternalState()) { } @@ -311,11 +344,13 @@ SubstitutionOverlay::~SubstitutionOverlay (void) void SubstitutionOverlay::Create ( model::PageEnumeration& rSelection, - const Point& rPosition, + const Point& rAnchor, const model::SharedPageDescriptor& rpHitDescriptor) { - maPosition = rPosition; - maTranslation = Point(0,0); + OSL_ASSERT(mpState); + + mpState->maAnchor = rAnchor; + maPosition = rAnchor; ::boost::shared_ptr pPreviewCache ( mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache()); @@ -330,7 +365,7 @@ void SubstitutionOverlay::Create ( ? rLayouter.GetColumn(rpHitDescriptor->GetPageIndex()) : -1); - maItems.clear(); + mpState->maItems.clear(); while (rSelection.HasMoreElements()) { model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement()); @@ -357,7 +392,7 @@ void SubstitutionOverlay::Create ( } const Rectangle aBox (pDescriptor->GetBoundingBox()); - maBoundingBox.Union(aBox); + mpState->maBoundingBox.Union(aBox); basegfx::B2DRectangle aB2DBox( aBox.Left(), aBox.Top(), @@ -367,19 +402,20 @@ void SubstitutionOverlay::Create ( const Bitmap aBitmap (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap()); AlphaMask aMask (aBitmap.GetSizePixel()); aMask.Erase(nTransparency); - maItems.push_back(ItemDescriptor()); - maItems.back().maImage = BitmapEx( + mpState->maItems.push_back(ItemDescriptor()); + ItemDescriptor& rNewItem (mpState->maItems.back()); + rNewItem.maImage = BitmapEx( aBitmap, aMask); - maItems.back().maLocation = pPageObjectLayouter->GetBoundingBox( + rNewItem.maLocation = pPageObjectLayouter->GetBoundingBox( pDescriptor, PageObjectLayouter::Preview, PageObjectLayouter::WindowCoordinateSystem).TopLeft(); - maItems.back().mnTransparency = nTransparency/255.0; - maItems.back().maShape = basegfx::tools::createPolygonFromRect(aB2DBox); + rNewItem.mnTransparency = nTransparency/255.0; + rNewItem.maShape = basegfx::tools::createPolygonFromRect(aB2DBox); } - SetIsVisible(maItems.size() > 0); + SetIsVisible(mpState->maItems.size() > 0); } @@ -388,19 +424,32 @@ void SubstitutionOverlay::Create ( void SubstitutionOverlay::Clear (void) { SetIsVisible(false); - maItems.clear(); + mpState.reset(new InternalState()); } -void SubstitutionOverlay::Move (const Point& rOffset) +void SubstitutionOverlay::SetAnchor (const Point& rAnchor) { - Invalidator aInvalidator (*this); + OSL_ASSERT(mpState); + if (mpState->maAnchor != rAnchor) + { + Invalidator aInvalidator (*this); + mpState->maAnchor = rAnchor; + } +} + + - maPosition += rOffset; - maTranslation += rOffset; - maBoundingBox.Move(rOffset.X(), rOffset.Y()); + +void SubstitutionOverlay::Move (const Point& rOffset) +{ + if (rOffset != Point(0,0)) + { + Invalidator aInvalidator (*this); + maPosition += rOffset; + } } @@ -408,7 +457,11 @@ void SubstitutionOverlay::Move (const Point& rOffset) void SubstitutionOverlay::SetPosition (const Point& rPosition) { - Move(rPosition - GetPosition()); + if (maPosition != rPosition) + { + Invalidator aInvalidator (*this); + maPosition = rPosition; + } } @@ -427,26 +480,28 @@ void SubstitutionOverlay::Paint ( const Rectangle& rRepaintArea) { (void)rRepaintArea; + OSL_ASSERT(mpState); if ( ! IsVisible()) return; + const Point aOffset (maPosition - mpState->maAnchor); basegfx::B2DHomMatrix aTranslation; - aTranslation.translate(maTranslation.X(), maTranslation.Y()); + aTranslation.translate(aOffset.X(), aOffset.Y()); rDevice.SetFillColor(Color(AirForceBlue)); rDevice.SetLineColor(); for (::std::vector::const_iterator - iItem(maItems.begin()), - iEnd(maItems.end()); + iItem(mpState->maItems.begin()), + iEnd(mpState->maItems.end()); iItem!=iEnd; ++iItem) { ::basegfx::B2DPolyPolygon aPolygon (iItem->maShape); aPolygon.transform(aTranslation); rDevice.DrawTransparent(aPolygon, iItem->mnTransparency); - rDevice.DrawBitmapEx(iItem->maLocation+maTranslation, iItem->maImage); + rDevice.DrawBitmapEx(iItem->maLocation+aOffset, iItem->maImage); } } @@ -455,7 +510,28 @@ void SubstitutionOverlay::Paint ( Rectangle SubstitutionOverlay::GetBoundingBox (void) const { - return maBoundingBox; + OSL_ASSERT(mpState); + + Rectangle aBox (mpState->maBoundingBox); + aBox.Move(maPosition.X() - mpState->maAnchor.X(), maPosition.Y() - mpState->maAnchor.Y()); + return aBox; +} + + + + +SubstitutionOverlay::SharedInternalState SubstitutionOverlay::GetInternalState (void) const +{ + return mpState; +} + + + + +void SubstitutionOverlay::SetInternalState (const SharedInternalState& rpState) +{ + if (rpState) + mpState = rpState; } -- cgit v1.2.3 From 1fbf7cba10381a461245d599ecedaa1cb7958f72 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Tue, 23 Feb 2010 18:31:24 +0100 Subject: renaissance1: #i107215# Focus can be moved with Ctrl+Cursor Keys. --- .../ui/slidesorter/controller/SlsFocusManager.cxx | 8 ++--- .../controller/SlsSelectionFunction.cxx | 23 ++++++++----- .../inc/controller/SlsSelectionFunction.hxx | 3 +- .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 5 +++ sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 2 ++ .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 40 +++++++++++++++++----- sd/source/ui/slidesorter/view/SlsTheme.cxx | 24 ++++++++++--- 7 files changed, 79 insertions(+), 26 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index f633060e4dc7..62adb2d939ec 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -302,12 +302,12 @@ void FocusManager::ShowFocusIndicator ( // Scroll the focused page object into the visible area and repaint // it, so that the focus indicator becomes visible. mrSlideSorter.GetController().GetSelectionManager()->MakeRectangleVisible ( - GetFocusedPageDescriptor()->GetBoundingBox()); + mrSlideSorter.GetView().GetLayouter().GetPageObjectBox( + rpDescriptor->GetPageIndex(), true)); } -#ifndef UNIFY_FOCUS_AND_CURRENT_PAGE - mrSlideSorter.GetView().RequestRepaint (rpDescriptor); -#endif + mrSlideSorter.GetView().RequestRepaint(rpDescriptor); + NotifyFocusChangeListeners(); } } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 203cc087df56..b4e8f8e919b3 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -466,7 +466,8 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) FocusManager& rFocusManager (mrController.GetFocusManager()); BOOL bResult = FALSE; - switch (rEvent.GetKeyCode().GetCode()) + const KeyCode& rCode (rEvent.GetKeyCode()); + switch (rCode.GetCode()) { case KEY_RETURN: if (rFocusManager.HasFocus()) @@ -485,7 +486,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) if ( ! rFocusManager.IsFocusShowing()) rFocusManager.ShowFocus(); else - if (rEvent.GetKeyCode().IsShift()) + if (rCode.IsShift()) rFocusManager.MoveFocus (FocusManager::FMD_LEFT); else rFocusManager.MoveFocus (FocusManager::FMD_RIGHT); @@ -527,25 +528,25 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) // Move the focus indicator left. case KEY_LEFT: - MoveFocus(FocusManager::FMD_LEFT, rEvent.GetKeyCode().IsShift()); + MoveFocus(FocusManager::FMD_LEFT, rCode.IsShift(), rCode.IsMod1()); bResult = TRUE; break; // Move the focus indicator right. case KEY_RIGHT: - MoveFocus(FocusManager::FMD_RIGHT, rEvent.GetKeyCode().IsShift()); + MoveFocus(FocusManager::FMD_RIGHT, rCode.IsShift(), rCode.IsMod1()); bResult = TRUE; break; // Move the focus indicator up. case KEY_UP: - MoveFocus(FocusManager::FMD_UP, rEvent.GetKeyCode().IsShift()); + MoveFocus(FocusManager::FMD_UP, rCode.IsShift(), rCode.IsMod1()); bResult = TRUE; break; // Move the focus indicator down. case KEY_DOWN: - MoveFocus(FocusManager::FMD_DOWN, rEvent.GetKeyCode().IsShift()); + MoveFocus(FocusManager::FMD_DOWN, rCode.IsShift(), rCode.IsMod1()); bResult = TRUE; break; @@ -590,7 +591,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) break; case KEY_F10: - if (rEvent.GetKeyCode().IsShift()) + if (rCode.IsShift()) { DeselectAllPages(); mrController.GetPageSelector().SelectPage( @@ -613,7 +614,8 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) void SelectionFunction::MoveFocus ( const FocusManager::FocusMoveDirection eDirection, - const bool bIsShiftDown) + const bool bIsShiftDown, + const bool bIsControlDown) { // Remember the anchor of shift key multi selection. if (bIsShiftDown) @@ -662,6 +664,11 @@ void SelectionFunction::MoveFocus ( } } } + else if (bIsControlDown) + { + // When control is pressed then do not alter the selection or the + // current page, just move the focus. + } else { // Without shift just select the focused page. diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index 0eb5710e8bbd..c6b9834d3f5f 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -233,7 +233,8 @@ private: void MoveFocus ( const FocusManager::FocusMoveDirection eDirection, - const bool bIsShiftDown); + const bool bIsShiftDown, + const bool bIsControlDown); }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index ec42b3db4fd9..586ee7474fb8 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -83,6 +83,7 @@ private: ::boost::scoped_ptr mpShadowPainter; Bitmap maNormalBackground; Bitmap maSelectionBackground; + Bitmap maFocusedSelectionBackground; Bitmap maMouseOverBackground; void PaintBackground ( @@ -101,6 +102,10 @@ private: OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const; void PrepareBackgrounds (OutputDevice& rDevice); + void PaintBorder ( + OutputDevice& rDevice, + const Theme::GradientColorType eColorType, + const Rectangle& rBox) const; Bitmap CreateBackgroundBitmap( const OutputDevice& rReferenceDevice, const Theme::GradientColorType eType) const; diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index 851f8c4ffc49..5cadda3fafdf 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -84,6 +84,7 @@ public: enum GradientColorType { NormalPage, SelectedPage, + SelectedAndFocusedPage, MouseOverPage }; enum GradientColorClass { @@ -115,6 +116,7 @@ private: ColorData maBackgroundColor; GradientDescriptor maNormalGradient; GradientDescriptor maSelectedGradient; + GradientDescriptor maSelectedAndFocusedGradient; GradientDescriptor maMouseOverGradient; BitmapEx maRawShadow; BitmapEx maInsertionIndicator; diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 9921e3ca070c..0a83736aa689 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -235,6 +235,7 @@ PageObjectPainter::PageObjectPainter ( mpShadowPainter(), maNormalBackground(), maSelectionBackground(), + maFocusedSelectionBackground(), maMouseOverBackground() { LocalResource aResource (IMG_ICONS); @@ -294,6 +295,7 @@ void PageObjectPainter::NotifyResize (void) { maNormalBackground.SetEmpty(); maSelectionBackground.SetEmpty(); + maFocusedSelectionBackground.SetEmpty(); maMouseOverBackground.SetEmpty(); } @@ -326,15 +328,22 @@ void PageObjectPainter::PaintBackground ( } else if (rpDescriptor->HasState(model::PageDescriptor::ST_Selected)) { - rDevice.DrawBitmap( - aBox.TopLeft(), - maSelectionBackground); + if (rpDescriptor->HasState(model::PageDescriptor::ST_Focused)) + rDevice.DrawBitmap( + aBox.TopLeft(), + maFocusedSelectionBackground); + else + rDevice.DrawBitmap( + aBox.TopLeft(), + maSelectionBackground); } else { rDevice.DrawBitmap( aBox.TopLeft(), maNormalBackground); + if (rpDescriptor->HasState(model::PageDescriptor::ST_Focused)) + PaintBorder(rDevice, Theme::SelectedPage, aBox); } } @@ -519,6 +528,8 @@ void PageObjectPainter::PrepareBackgrounds (OutputDevice& rDevice) { maNormalBackground = CreateBackgroundBitmap(rDevice, Theme::NormalPage); maSelectionBackground = CreateBackgroundBitmap(rDevice, Theme::SelectedPage); + maFocusedSelectionBackground = CreateBackgroundBitmap( + rDevice, Theme::SelectedAndFocusedPage); maMouseOverBackground = CreateBackgroundBitmap(rDevice, Theme::MouseOverPage); } } @@ -563,12 +574,7 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( aBitmapDevice.DrawLine(Point(0,nY), Point(aSize.Width(),nY)); } - // Paint the border. - aBitmapDevice.SetFillColor(); - aBitmapDevice.SetLineColor(mpTheme->GetGradientColor(eColorType, Theme::Border2)); - aBitmapDevice.DrawRect(Rectangle(Point(0,0),aSize)); - aBitmapDevice.SetLineColor(mpTheme->GetGradientColor(eColorType, Theme::Border1)); - aBitmapDevice.DrawLine(Point(0,0),Point(aSize.Width()-1,0)); + PaintBorder(aBitmapDevice, eColorType, Rectangle(Point(0,0), aSize)); // Get bounding box of the preview around which a shadow is painted. // Compensate for the border around the preview. @@ -590,6 +596,22 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( +void PageObjectPainter::PaintBorder ( + OutputDevice& rDevice, + const Theme::GradientColorType eColorType, + const Rectangle& rBox) const +{ + const Size aSize (mpPageObjectLayouter->GetPageObjectSize()); + rDevice.SetFillColor(); + rDevice.SetLineColor(mpTheme->GetGradientColor(eColorType, Theme::Border2)); + rDevice.DrawRect(rBox); + rDevice.SetLineColor(mpTheme->GetGradientColor(eColorType, Theme::Border1)); + rDevice.DrawLine(rBox.TopLeft(), rBox.TopRight()); +} + + + + //===== FramePainter ========================================================== PageObjectPainter::FramePainter::FramePainter (const BitmapEx& rShadowBitmap) diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index a40dda166eee..5fa5300bd213 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -87,6 +87,7 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) : maBackgroundColor(rpProperties->GetBackgroundColor().GetColor()), maNormalGradient(), maSelectedGradient(), + maSelectedAndFocusedGradient(), maMouseOverGradient(), maRawShadow(), maInsertionIndicator() @@ -107,15 +108,21 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert maBackgroundColor = rpProperties->GetBackgroundColor().GetColor(); #ifdef USE_SYSTEM_SELECTION_COLOR const ColorData aSelectionColor (rpProperties->GetSelectionColor().GetColor()); + maSelectedGradient.maFillColor1 = ChangeLuminance(aSelectionColor, +50); maSelectedGradient.maFillColor2 = ChangeLuminance(aSelectionColor, -10); maSelectedGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, -10); maSelectedGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, -30); - maMouseOverGradient.maFillColor1 = ChangeLuminance(aSelectionColor, -30); - maMouseOverGradient.maFillColor2 = ChangeLuminance(aSelectionColor, -90); - maMouseOverGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, -30); - maMouseOverGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, -10); + maSelectedAndFocusedGradient.maFillColor1 = ChangeLuminance(aSelectionColor, +30); + maSelectedAndFocusedGradient.maFillColor2 = ChangeLuminance(aSelectionColor, -30); + maSelectedAndFocusedGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, -30); + maSelectedAndFocusedGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, -50); + + maMouseOverGradient.maFillColor1 = ChangeLuminance(aSelectionColor, +90); + maMouseOverGradient.maFillColor2 = ChangeLuminance(aSelectionColor, +30); + maMouseOverGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, +10); + maMouseOverGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, +30); #else @@ -124,6 +131,11 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert maSelectedGradient.maBorderColor1 = 0x6db5e1; maSelectedGradient.maBorderColor2 = 0x0e85cd; + maSelectedAndFocusedGradient.maFillColor1 = 0xb7daf0; + maSelectedAndFocusedGradient.maFillColor2 = 0x6db5e1; + maSelectedAndFocusedGradient.maBorderColor1 = 0x6db5e1; + maSelectedAndFocusedGradient.maBorderColor2 = 0x0e85cd; + maMouseOverGradient.maFillColor1 = 0x0e85cd; maMouseOverGradient.maFillColor2 = 0x044c99; maMouseOverGradient.maBorderColor1 = 0x6db5e1; @@ -236,6 +248,10 @@ ColorData Theme::GetGradientColor ( pDescriptor = &maSelectedGradient; break; + case SelectedAndFocusedPage: + pDescriptor = &maSelectedAndFocusedGradient; + break; + case MouseOverPage: pDescriptor = &maMouseOverGradient; break; -- cgit v1.2.3 From 530eea93535c9ca85349913dad05143441cc7bd7 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 24 Feb 2010 11:06:37 +0100 Subject: renaissance1: #i107215# Restore mouse over state after model change. --- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index ceef51c8071b..a8e648d4c37e 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -476,14 +476,6 @@ void SlideSorterView::ModelHasChanged (void) { // Ignore this call. Rely on hints sent by the model to get informed of // model changes. - /* - if (mbModelChangedWhileModifyEnabled) - { - controller::SlideSorterController::ModelChangeLock alock( mrSlideSorter.GetController() ); - mrSlideSorter.GetController().HandleModelChange(); - LocalModelHasChanged(); - } - */ } @@ -507,8 +499,7 @@ void SlideSorterView::LocalModelHasChanged(void) void SlideSorterView::PreModelChange (void) { - // Reset the slide under the mouse. It will be set to the correct slide - // on the next mouse motion. + // Reset the slide under the mouse. It will be re-set in PostModelChange(). SetPageUnderMouse(SharedPageDescriptor()); } @@ -527,6 +518,16 @@ void SlideSorterView::PostModelChange (void) // The new page objects have to be scaled and positioned. Layout(); RequestRepaint(); + + // Restore the mouse over state. + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + const Window::PointerState aPointerState (pWindow->GetPointerState()); + UpdatePageUnderMouse ( + aPointerState.maPos, + (aPointerState.mnState & MOUSE_LEFT)!=0); + } } -- cgit v1.2.3 From f1a49de1365676c852a766617c35614d14f899d8 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Thu, 25 Feb 2010 16:51:49 +0100 Subject: renaissance1: #i107215# Improved focus and selection handling. --- sd/source/ui/dlg/PaneDockingWindow.cxx | 17 +++++++++-- sd/source/ui/dlg/PaneDockingWindow.src | 3 -- sd/source/ui/inc/PaneDockingWindow.hxx | 1 + .../controller/SlideSorterController.cxx | 2 +- .../ui/slidesorter/controller/SlsClipboard.cxx | 14 +++++---- .../controller/SlsCurrentSlideManager.cxx | 5 +++- .../ui/slidesorter/controller/SlsListener.cxx | 6 ++-- .../ui/slidesorter/controller/SlsPageSelector.cxx | 35 +++++++++++++++++++--- .../controller/SlsSelectionFunction.cxx | 19 +++++++----- .../slidesorter/controller/SlsSelectionManager.cxx | 26 ++++++++++++++-- .../slidesorter/inc/controller/SlsPageSelector.hxx | 11 +++++-- .../ui/slidesorter/inc/model/SlsPageDescriptor.hxx | 7 ++++- .../ui/slidesorter/model/SlsPageDescriptor.cxx | 18 ++++++++++- 13 files changed, 130 insertions(+), 34 deletions(-) diff --git a/sd/source/ui/dlg/PaneDockingWindow.cxx b/sd/source/ui/dlg/PaneDockingWindow.cxx index 2aa6039cfb76..b2f17bc0ab2a 100644 --- a/sd/source/ui/dlg/PaneDockingWindow.cxx +++ b/sd/source/ui/dlg/PaneDockingWindow.cxx @@ -39,6 +39,7 @@ #include #include #include +#include #include "framework/FrameworkHelper.hxx" using namespace ::com::sun::star; @@ -58,8 +59,7 @@ PaneDockingWindow::PaneDockingWindow ( _pBindings, pChildWindow, pParent, - rResId - ), + rResId), msPaneURL(rsPaneURL), msTitle(rsTitle), mpTitleToolBox(), @@ -397,6 +397,18 @@ void PaneDockingWindow::DataChanged (const DataChangedEvent& rEvent) +void PaneDockingWindow::MouseButtonDown (const MouseEvent& rEvent) +{ + if (rEvent.GetButtons() == MOUSE_LEFT && mpContentWindow) + { + mpContentWindow->GrabFocus(); + } + SfxDockingWindow::MouseButtonDown(rEvent); +} + + + + ::Window* PaneDockingWindow::GetContentWindow (void) { return mpContentWindow.get(); @@ -411,4 +423,5 @@ void PaneDockingWindow::DataChanged (const DataChangedEvent& rEvent) } + } // end of namespace ::sd diff --git a/sd/source/ui/dlg/PaneDockingWindow.src b/sd/source/ui/dlg/PaneDockingWindow.src index b66ef778f903..3b4703009b17 100644 --- a/sd/source/ui/dlg/PaneDockingWindow.src +++ b/sd/source/ui/dlg/PaneDockingWindow.src @@ -32,7 +32,6 @@ DockingWindow FLT_LEFT_PANE_IMPRESS_DOCKING_WINDOW { - // HelpID = SID_EFFECT_WIN ; Border = TRUE ; Hide = TRUE ; SVLook = TRUE ; @@ -48,7 +47,6 @@ DockingWindow FLT_LEFT_PANE_IMPRESS_DOCKING_WINDOW DockingWindow FLT_LEFT_PANE_DRAW_DOCKING_WINDOW { - // HelpID = SID_EFFECT_WIN ; Border = TRUE ; Hide = TRUE ; SVLook = TRUE ; @@ -64,7 +62,6 @@ DockingWindow FLT_LEFT_PANE_DRAW_DOCKING_WINDOW DockingWindow FLT_RIGHT_PANE_DOCKING_WINDOW { - // HelpID = SID_EFFECT_WIN ; Border = TRUE ; Hide = TRUE ; SVLook = TRUE ; diff --git a/sd/source/ui/inc/PaneDockingWindow.hxx b/sd/source/ui/inc/PaneDockingWindow.hxx index 138e5c4132c5..c61f0e8d774c 100644 --- a/sd/source/ui/inc/PaneDockingWindow.hxx +++ b/sd/source/ui/inc/PaneDockingWindow.hxx @@ -79,6 +79,7 @@ public: virtual long Notify( NotifyEvent& rNEvt ); virtual void StateChanged( StateChangedType nType ); virtual void DataChanged( const DataChangedEvent& rDCEvt ); + virtual void MouseButtonDown (const MouseEvent& rEvent); /** Initializing the title tool box either creates a new title tool box or clears all items from an existing one. A closer is added as only diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 67a08fcd41ee..fc7aa6ff738c 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -177,7 +177,7 @@ void SlideSorterController::Init (void) mpListener = new Listener(mrSlideSorter); - mpPageSelector->UpdateAllPages(); + mpPageSelector->GetCoreSelection(); GetSelectionManager()->SelectionHasChanged(); } diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 2f9397c7e8fe..47bf42b826d0 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -508,12 +508,16 @@ sal_Int8 Clipboard::AcceptDrop ( { sal_Int8 nResult = DND_ACTION_NONE; - FunctionReference rFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction()); - SelectionFunction* pSelectionFunction = dynamic_cast(rFunction.get()); - if (pSelectionFunction != NULL) - pSelectionFunction->MouseDragged(rEvent); + const Clipboard::DropType eDropType (IsDropAccepted()); + if (eDropType != DT_NONE) + { + FunctionReference rFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction()); + SelectionFunction* pSelectionFunction = dynamic_cast(rFunction.get()); + if (pSelectionFunction != NULL) + pSelectionFunction->MouseDragged(rEvent); + } - switch (IsDropAccepted()) + switch (eDropType) { case DT_PAGE: { diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx index e2ed42cb9aee..ee79c5662219 100644 --- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx @@ -37,6 +37,7 @@ #include "controller/SlsPageSelector.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsCurrentSlideManager.hxx" +#include "controller/SlsFocusManager.hxx" #include "view/SlideSorterView.hxx" #include "ViewShellBase.hxx" #include "ViewShell.hxx" @@ -145,6 +146,7 @@ void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDesc FrameView* pFrameView = pViewShell->GetFrameView(); if (pFrameView != NULL) pFrameView->SetSelectedPage(sal::static_int_cast(mnCurrentSlideIndex)); + mrSlideSorter.GetController().GetPageSelector().SetCoreSelection(); } else { @@ -154,8 +156,9 @@ void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDesc // changes). Therefore, we call DrawViewShell::SwitchPage(), // too. SetCurrentSlideAtViewShellBase(rpDescriptor); - SetCurrentSlideAtXController(rpDescriptor); } + SetCurrentSlideAtXController(rpDescriptor); + mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(rpDescriptor); } } diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 703d44a9533f..34154fb36e3c 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -425,7 +425,7 @@ IMPL_LINK(Listener, EventMultiplexerCallback, ::sd::tools::EventMultiplexerEvent case tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED: { ConnectToController(); - mrController.GetPageSelector().UpdateAllPages(); + mrController.GetPageSelector().GetCoreSelection(); UpdateEditMode(); } break; @@ -514,7 +514,7 @@ void SAL_CALL Listener::propertyChange ( String(RTL_CONSTASCII_USTRINGPARAM("Number"))); sal_Int32 nCurrentPage = 0; aPageNumber >>= nCurrentPage; - mrController.GetPageSelector().UpdateAllPages (); + mrController.GetPageSelector().GetCoreSelection(); // The selection is already set but we call SelectPage() // nevertheless in order to make the new current page the // last recently selected page of the PageSelector. This is @@ -561,7 +561,7 @@ void SAL_CALL Listener::frameAction (const frame::FrameActionEvent& rEvent) case frame::FrameAction_COMPONENT_REATTACHED: { ConnectToController(); - mrController.GetPageSelector().UpdateAllPages(); + mrController.GetPageSelector().GetCoreSelection(); UpdateEditMode(); } break; diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index 25767bee7b9a..058cbb343e92 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -81,6 +81,8 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter) void PageSelector::SelectAllPages (void) { + PageSelector::UpdateLock aLock (*this); + int nPageCount = mrModel.GetPageCount(); for (int nPageIndex=0; nPageIndexUpdateSelection()) + if (pDescriptor->GetCoreSelection()) { mrSlideSorter.GetView().RequestRepaint(pDescriptor); bSelectionHasChanged = true; @@ -130,8 +136,20 @@ void PageSelector::UpdateAllPages (void) else mrController.GetSelectionManager()->SelectionHasChanged(); } +} + + - UpdateCurrentPage(); + +void PageSelector::SetCoreSelection (void) +{ + model::PageEnumeration aAllPages ( + model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); + while (aAllPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); + pDescriptor->SetCoreSelection(); + } } @@ -260,7 +278,7 @@ void PageSelector::PrepareModelChange (void) void PageSelector::HandleModelChange (void) { - UpdateAllPages(); + GetCoreSelection(); } @@ -415,6 +433,15 @@ PageSelector::UpdateLock::UpdateLock (SlideSorter& rSlideSorter) +PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector) + : mrSelector(rSelector) +{ + ++mrSelector.mnUpdateLockCount; +} + + + + PageSelector::UpdateLock::~UpdateLock (void) { --mrSelector.mnUpdateLockCount; diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index b4e8f8e919b3..630eebffd27a 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -484,17 +484,20 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) case KEY_TAB: if ( ! rFocusManager.IsFocusShowing()) + { rFocusManager.ShowFocus(); - else - if (rCode.IsShift()) - rFocusManager.MoveFocus (FocusManager::FMD_LEFT); - else - rFocusManager.MoveFocus (FocusManager::FMD_RIGHT); - bResult = TRUE; + bResult = TRUE; + } break; case KEY_ESCAPE: - rFocusManager.SetFocusToToolBox(); + // When there is an active multiselection or drag-and-drop + // operation then stop that. Otherwise transfer the focus to + // the tool box. + + if ( ! (mpSubstitutionHandler || mpMouseMultiSelector)) + rFocusManager.SetFocusToToolBox(); + if (mpSubstitutionHandler) { mpSubstitutionHandler->Dispose(); @@ -512,7 +515,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) { // Toggle the selection state. model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor()); - if (pDescriptor.get() != NULL) + if (pDescriptor && rCode.IsMod1()) { // Doing a multi selection by default. Can we ask the event // for the state of the shift key? diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 3a22668a76e3..871880390f3f 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -123,7 +123,11 @@ SelectionManager::~SelectionManager (void) void SelectionManager::DeleteSelectedPages (void) { + // Create some locks to prevent updates of the model, view, selection + // state while modifying any of them. SlideSorterController::ModelChangeLock aLock (mrController); + SlideSorterView::DrawLock aDrawLock (mrSlideSorter); + PageSelector::UpdateLock aSelectionLock (mrSlideSorter); // Hide focus. bool bIsFocusShowing = mrController.GetFocusManager().IsFocusShowing(); @@ -135,8 +139,19 @@ void SelectionManager::DeleteSelectedPages (void) model::PageEnumeration aPageEnumeration ( PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); ::std::vector aSelectedPages; + sal_Int32 nLastPageIndex (-1); while (aPageEnumeration.HasMoreElements()) - aSelectedPages.push_back (aPageEnumeration.GetNextElement()->GetPage()); + { + SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); + aSelectedPages.push_back(pDescriptor->GetPage()); + nLastPageIndex = pDescriptor->GetPageIndex(); + } + if (aSelectedPages.empty()) + return; + + // Determine the slide to select (and thereby make the current slide) + // after the deletion. + sal_Int32 nNewCurrentSlide (nLastPageIndex - aSelectedPages.size() + 1); // The actual deletion of the selected pages is done in one of two // helper functions. They are specialized for normal respectively for @@ -153,8 +168,13 @@ void SelectionManager::DeleteSelectedPages (void) // Show focus and move it to next valid location. if (bIsFocusShowing) - mrController.GetFocusManager().ToggleFocus (); - mrController.GetFocusManager().MoveFocus (FocusManager::FMD_NONE); + mrController.GetFocusManager().ToggleFocus(); + + // Set the new current slide. + if (nNewCurrentSlide >= mrSlideSorter.GetModel().GetPageCount()) + nNewCurrentSlide = mrSlideSorter.GetModel().GetPageCount()-1; + mrController.GetPageSelector().SelectPage(nNewCurrentSlide); + mrController.GetFocusManager().SetFocusedPage(nNewCurrentSlide); } diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index 0d22127a819e..b301b5a97352 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -72,11 +72,17 @@ public: void SelectAllPages (void); void DeselectAllPages (void); + /** Update the selection state of all page descriptors to be the same as - that of the pages of the SdDrawDocument they describe and issue + that of the corresponding pages of the SdPage objects and issue redraw requests where necessary. */ - void UpdateAllPages (void); + void GetCoreSelection (void); + + /** Update the selection state of the SdPage objects to be the same as + that of the correspinding page descriptors. + */ + void SetCoreSelection (void); void SelectPage (int nPageIndex); /** Select the descriptor that is associated with the given page. @@ -184,6 +190,7 @@ public: { public: UpdateLock (SlideSorter& rSlideSorter); + UpdateLock (PageSelector& rPageSelector); ~UpdateLock (void); private: PageSelector& mrSelector; diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx index 105f4ca89f13..58263719197c 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx @@ -118,7 +118,12 @@ public: returned. When they were the same this method returns . */ - bool UpdateSelection (void); + bool GetCoreSelection (void); + + /** Set the selection flags of the SdPage objects to the corresponding + selection states of the page descriptors. + */ + void SetCoreSelection (void); VisualState& GetVisualState (void); diff --git a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx index 2b7a2832a5f8..13a436c6f035 100644 --- a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx @@ -224,7 +224,7 @@ VisualState& PageDescriptor::GetVisualState (void) -bool PageDescriptor::UpdateSelection (void) +bool PageDescriptor::GetCoreSelection (void) { if (mpPage!=NULL && (mpPage->IsSelected()==TRUE) != mbIsSelected) return SetState(ST_Selected, !mbIsSelected); @@ -235,6 +235,22 @@ bool PageDescriptor::UpdateSelection (void) +void PageDescriptor::SetCoreSelection (void) +{ + if (mpPage != NULL) + if (HasState(ST_Selected)) + mpPage->SetSelected(TRUE); + else + mpPage->SetSelected(FALSE); + else + { + OSL_ASSERT(mpPage!=NULL); + } +} + + + + Rectangle PageDescriptor::GetBoundingBox (void) const { Rectangle aBox (maBoundingBox); -- cgit v1.2.3 From efc8b0f870e318fd790c0258dbd0c92dc7cd83fa Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Tue, 2 Mar 2010 15:54:17 +0100 Subject: renaissance1: #i107215# Modified display of substitution and insertion indicator. --- .../ui/slidesorter/cache/SlsBitmapFactory.cxx | 24 +- .../ui/slidesorter/cache/SlsBitmapFactory.hxx | 1 - .../controller/SlideSorterController.cxx | 1 + .../controller/SlsAnimationFunction.cxx | 9 + .../ui/slidesorter/controller/SlsAnimator.cxx | 20 +- .../controller/SlsInsertionIndicatorHandler.cxx | 124 +++---- .../slidesorter/controller/SlsScrollBarManager.cxx | 10 +- .../controller/SlsSelectionFunction.cxx | 34 +- .../slidesorter/controller/SlsSelectionManager.cxx | 2 + .../controller/SlsSubstitutionHandler.cxx | 10 +- .../controller/SlsSubstitutionHandler.hxx | 1 - .../inc/controller/SlsAnimationFunction.hxx | 5 + .../ui/slidesorter/inc/controller/SlsAnimator.hxx | 3 + .../controller/SlsInsertionIndicatorHandler.hxx | 9 +- .../inc/controller/SlsSelectionFunction.hxx | 13 +- .../ui/slidesorter/inc/view/SlsInsertAnimator.hxx | 6 +- sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 80 ++-- .../slidesorter/inc/view/SlsPageObjectLayouter.hxx | 6 + .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 3 +- sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 23 +- .../ui/slidesorter/inc/view/SlsViewOverlay.hxx | 44 ++- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 8 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 37 +- sd/source/ui/slidesorter/view/SlsFramePainter.cxx | 219 +++++++++++ sd/source/ui/slidesorter/view/SlsFramePainter.hxx | 137 +++++++ sd/source/ui/slidesorter/view/SlsIcons.hrc | 1 + sd/source/ui/slidesorter/view/SlsIcons.src | 5 + .../ui/slidesorter/view/SlsInsertAnimator.cxx | 134 ++++--- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 188 +++++----- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 26 +- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 286 +-------------- sd/source/ui/slidesorter/view/SlsTheme.cxx | 49 ++- .../ui/slidesorter/view/SlsViewCacheContext.cxx | 2 - sd/source/ui/slidesorter/view/SlsViewOverlay.cxx | 407 ++++++++++++--------- sd/source/ui/slidesorter/view/makefile.mk | 1 + 35 files changed, 1110 insertions(+), 818 deletions(-) create mode 100644 sd/source/ui/slidesorter/view/SlsFramePainter.cxx create mode 100644 sd/source/ui/slidesorter/view/SlsFramePainter.hxx diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index a8c62b203a13..8f70bd08b7ab 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -56,8 +56,7 @@ class PageObjectViewObjectContact; namespace sd { namespace slidesorter { namespace cache { BitmapFactory::BitmapFactory (void) - : maRenderer(NULL, false), - mbRemoveBorder(false) + : maRenderer(NULL, false) { } @@ -83,31 +82,10 @@ BitmapFactory::~BitmapFactory (void) aSize.Width() *= gnSuperSampleFactor; aSize.Height() *= gnSuperSampleFactor; } - if (mbRemoveBorder) - { - aSize.Width() += 2; - aSize.Height() += 2; - } const Image aPreview (maRenderer.RenderPage (&rPage, aSize, String())); ::boost::shared_ptr pPreview (new BitmapEx(aPreview.GetBitmapEx())); - if (mbRemoveBorder) - { - static sal_Int32 gnCounter (0); - SvFileStream aOut ( - ::rtl::OUString::createFromAscii("c:\\tmp\\image-") - +::rtl::OUString::valueOf(gnCounter) - +::rtl::OUString::createFromAscii(".png"), - STREAM_WRITE); - ::vcl::PNGWriter aWriter (*pPreview); - aWriter.Write(aOut); - ++gnCounter; - - OSL_ASSERT(pPreview->GetSizePixel() == aSize); - pPreview->Crop(Rectangle(1,1,aSize.Width()-2,aSize.Height()-2)); - OSL_ASSERT(pPreview->GetSizePixel() == Size(aSize.Width()-2,aSize.Height()-2)); - } if (bDo) { #if 1 diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx index 6da0aabfe3d2..51d7d1c60f1b 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx @@ -61,7 +61,6 @@ public: private: PreviewRenderer maRenderer; - const bool mbRemoveBorder; }; diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index fc7aa6ff738c..30513d6dc19c 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -443,6 +443,7 @@ bool SlideSorterController::Command ( pWindow->PixelToLogic(rEvent.GetMousePosPixel()), InsertionIndicatorHandler::MoveMode, false); + GetInsertionIndicatorHandler()->UpdateIndicatorIcon(); } pWindow->ReleaseMouse(); diff --git a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx index d86b0811348e..6517ad96ecbd 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx @@ -41,6 +41,15 @@ namespace sd { namespace slidesorter { namespace controller { +double AnimationFunction::Linear (const double nTime) +{ + OSL_ASSERT(nTime>=0.0 && nTime<=1.0); + return nTime; +} + + + + double AnimationFunction::FastInSlowOut_Sine (const double nTime) { OSL_ASSERT(nTime>=0.0 && nTime<=1.0); diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index b703d192e894..052c154aa8b3 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -48,6 +48,7 @@ class Animator::Animation public: Animation ( const Animator::AnimationFunctor& rAnimation, + const double nStartOffset, const double nDuration, const double nGlobalTime, const Animator::AnimationId nAnimationId, @@ -123,6 +124,7 @@ void Animator::Dispose (void) Animator::AnimationId Animator::AddAnimation ( const AnimationFunctor& rAnimation, + const sal_Int32 nStartOffset, const sal_Int32 nDuration, const FinishFunctor& rFinishFunctor) { @@ -135,6 +137,7 @@ Animator::AnimationId Animator::AddAnimation ( boost::shared_ptr pAnimation ( new Animation( rAnimation, + nStartOffset / 1000.0, nDuration / 1000.0, maElapsedTime.getElapsedTime(), ++mnNextAnimationId, @@ -162,6 +165,7 @@ Animator::AnimationId Animator::AddInfiniteAnimation ( boost::shared_ptr pAnimation ( new Animation( rAnimation, + 0, -1, maElapsedTime.getElapsedTime(), mnNextAnimationId++, @@ -290,6 +294,7 @@ IMPL_LINK(Animator, TimeoutHandler, Timer*, EMPTYARG) Animator::Animation::Animation ( const Animator::AnimationFunctor& rAnimation, + const double nStartOffset, const double nDuration, const double nGlobalTime, const Animator::AnimationId nId, @@ -298,18 +303,11 @@ Animator::Animation::Animation ( maFinishFunctor(rFinishFunctor), mnAnimationId(nId), mnDuration(nDuration), - mnEnd(nGlobalTime + nDuration), - mnGlobalTimeAtStart(nGlobalTime), + mnEnd(nGlobalTime + nDuration + nStartOffset), + mnGlobalTimeAtStart(nGlobalTime + nStartOffset), mbIsExpired(false) { - if (mnDuration > 0) - maAnimation(0.0); - else if (mnDuration < 0) - maAnimation(nGlobalTime); - else - { - OSL_ASSERT(mnDuration != 0); - } + Run(nGlobalTime); } @@ -333,7 +331,7 @@ bool Animator::Animation::Run (const double nGlobalTime) maAnimation(1.0); Expire(); } - else + else if (nGlobalTime >= mnGlobalTimeAtStart) { maAnimation((nGlobalTime - mnGlobalTimeAtStart) / mnDuration); } diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 5dd7cf359490..3421cb470e2f 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -52,11 +52,12 @@ InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter) mpInsertionIndicatorOverlay( mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()), mnInsertionIndex(-1), - mbIsBeforePage(false), + maVisualInsertionIndices(-1,-1), meMode(MoveMode), mbIsActive(false), mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()), - mbIsOverSourceView(true) + mbIsOverSourceView(true), + maIconSize(0,0) { } @@ -93,6 +94,24 @@ void InsertionIndicatorHandler::Start ( +void InsertionIndicatorHandler::UpdateIndicatorIcon ( + model::PageEnumeration& rEnumeration) +{ + mpInsertionIndicatorOverlay->Create(rEnumeration); + maIconSize = mpInsertionIndicatorOverlay->GetSize(); +} + + + + +void InsertionIndicatorHandler::UpdateIndicatorIcon (void) +{ + mpInsertionIndicatorOverlay->Create(); +} + + + + InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction ( const sal_Int8 nDndAction) { @@ -141,7 +160,7 @@ void InsertionIndicatorHandler::End (void) if (mbIsReadOnly) return; - GetInsertAnimator()->SetInsertPosition(-1, false); + GetInsertAnimator()->SetInsertPosition(-1, Pair(-1,-1), Size(0,0)); mbIsActive = false; mpInsertionIndicatorOverlay->SetIsVisible(false); @@ -178,74 +197,55 @@ void InsertionIndicatorHandler::SetPosition ( view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount()); - sal_Int32 nInsertionIndex = rLayouter.GetInsertionIndex (rPoint, - bAllowHorizontalInsertMarker); - if (nInsertionIndex >= nPageCount) - nInsertionIndex = nPageCount-1; - sal_Int32 nDrawIndex = nInsertionIndex; - - bool bVertical = false; - bool bIsBeforePage = false; - if (nInsertionIndex >= 0) + sal_Int32 nInsertionIndex (mnInsertionIndex); + Pair aVisualInsertionIndices (maVisualInsertionIndices); + if (rLayouter.GetColumnCount() == 1) { - // Now that we know where to insert, we still have to determine - // where to draw the marker. There are two decisions to make: - // 1. Draw a vertical or a horizontal insert marker. - // The horizontal one may only be chosen when there is only one - // column. - // 2. The vertical (standard) insert marker may be painted left to - // the insert page or right of the previous one. When both pages - // are in the same row this makes no difference. Otherwise the - // posiotions are at the left and right ends of two rows. - - Point aPageCenter (rLayouter.GetPageObjectBox ( - nInsertionIndex).Center()); - - if (bAllowHorizontalInsertMarker - && rLayouter.GetColumnCount() == 1) - { - bVertical = false; - bIsBeforePage = (rPoint.Y() <= aPageCenter.Y()); - } - else - { - bVertical = true; - bIsBeforePage = (rPoint.X() <= aPageCenter.X()); - } - - // Add one when the mark was painted below or to the right of the - // page object. - if ( ! bIsBeforePage) - nInsertionIndex += 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; } - if (mnInsertionIndex!=nInsertionIndex - || mbIsBeforePage!=bIsBeforePage - || meMode!=eMode) + if (mnInsertionIndex != nInsertionIndex + || maVisualInsertionIndices != aVisualInsertionIndices + || meMode != eMode + || ! mpInsertionIndicatorOverlay->IsVisible()) { mnInsertionIndex = nInsertionIndex; - mbIsBeforePage = bIsBeforePage; + maVisualInsertionIndices = aVisualInsertionIndices; meMode = eMode; mbIsInsertionTrivial = IsInsertionTrivial(eMode); - mpInsertionIndicatorOverlay->SetLocation( - rLayouter.GetInsertionMarkerLocation ( - nDrawIndex, - bVertical, - mbIsBeforePage)); - } + const Point aIndicatorLocation ( + rLayouter.GetInsertionIndicatorLocation( + maVisualInsertionIndices, + maIconSize)); + mpInsertionIndicatorOverlay->SetLocation(aIndicatorLocation); - if (mnInsertionIndex>=0 && ! mbIsInsertionTrivial) - { - GetInsertAnimator()->SetInsertPosition( - mnInsertionIndex, - mbIsBeforePage); - mpInsertionIndicatorOverlay->SetIsVisible(true); - } - else - { - GetInsertAnimator()->Reset(); - mpInsertionIndicatorOverlay->SetIsVisible(false); + if (mnInsertionIndex>=0 && ! mbIsInsertionTrivial) + { + GetInsertAnimator()->SetInsertPosition( + mnInsertionIndex, + maVisualInsertionIndices, + maIconSize); + mpInsertionIndicatorOverlay->SetIsVisible(true); + } + else + { + GetInsertAnimator()->Reset(); + mpInsertionIndicatorOverlay->SetIsVisible(false); + } } } diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index 63daebe6544d..d1f70d633d2a 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -39,6 +39,7 @@ #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsViewOverlay.hxx" +#include "view/SlsTheme.hxx" #include "Window.hxx" #include "sdpage.hxx" @@ -333,14 +334,7 @@ IMPL_LINK(ScrollBarManager, VerticalScrollBarHandler, ScrollBar*, pScrollBar) double nRelativePosition = double(pScrollBar->GetThumbPos()) / double(pScrollBar->GetRange().Len()); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetContentWindow()->SetVisibleXY ( - -1, - nRelativePosition); - /* - mrSlideSorter.GetView().UpdatePageUnderMouse( - aMousePosition, - (rEvent.GetButtons() & MOUSE_LEFT)!=0); - */ + mrSlideSorter.GetContentWindow()->SetVisibleXY (-1, nRelativePosition); } return TRUE; } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 630eebffd27a..9be9063c7d3b 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -306,19 +306,7 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) aDragTimer.Stop(); } - - // In some modes (dragging, moving) the mouse over indicator is only - // annoying. Turn it off in these cases. - if (mpSubstitutionHandler || mpMouseMultiSelector) - { - mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); - } - else - { - mrSlideSorter.GetView().UpdatePageUnderMouse( - aMousePosition, - (rEvent.GetButtons() & MOUSE_LEFT)!=0); - } + UpdatePageUnderMouse(aMousePosition, (rEvent.GetButtons() & MOUSE_LEFT)!=0); // Detect the mouse leaving the window. When not button is pressed then // we can call IsLeaveWindow at the event. Otherwise we have to make an @@ -808,6 +796,21 @@ bool SelectionFunction::cancel (void) +void SelectionFunction::UpdatePageUnderMouse ( + const Point& rMousePosition, + const bool bIsMouseButtonDown) +{ + // In some modes (dragging, moving) the mouse over indicator is only + // annoying. Turn it off in these cases. + if (mpSubstitutionHandler || mpMouseMultiSelector) + mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); + else + mrSlideSorter.GetView().UpdatePageUnderMouse(rMousePosition, bIsMouseButtonDown); +} + + + + void SelectionFunction::DeselectAllPages (void) { mbIsDeselectionPending = false; @@ -1261,6 +1264,11 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor) 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. diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 871880390f3f..43f1de2b1f02 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -467,6 +467,7 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) mrController.GetAnimator()->RemoveAnimation(mnAnimationId); mnAnimationId = mrController.GetAnimator()->AddAnimation( VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop), + 0, 300); } else @@ -505,6 +506,7 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) mrController.GetAnimator()->AddAnimation( HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft), + 0, 300); else HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft)(1.0); diff --git a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx index 8ac921f13eb3..bd2ec1434a29 100644 --- a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx @@ -69,15 +69,13 @@ SubstitutionHandler::SubstitutionHandler ( model::PageEnumeration aSelectedPages( model::PageEnumerationProvider::CreateSelectedPagesEnumeration( rSlideSorter.GetModel())); - rOverlay.GetSubstitutionOverlay()->Create( - aSelectedPages, - rMouseModelPosition, - mpHitDescriptor); rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); rSlideSorter.GetController().GetInsertionIndicatorHandler()->Start( rMouseModelPosition, InsertionIndicatorHandler::MoveMode, true); + rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon( + aSelectedPages); } } @@ -217,8 +215,6 @@ void SubstitutionHandler::SetTargetSlideSorter ( { if (mpTargetSlideSorter != NULL) { - mpOverlayState = mpTargetSlideSorter->GetView().GetOverlay().GetSubstitutionOverlay() - ->GetInternalState(); mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); } @@ -226,8 +222,6 @@ void SubstitutionHandler::SetTargetSlideSorter ( if (mpTargetSlideSorter != NULL) { - mpTargetSlideSorter->GetView().GetOverlay().GetSubstitutionOverlay()->SetInternalState( - mpOverlayState); mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start( aMousePosition, eMode, diff --git a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx index da1a2ad0bd52..56bcf08fd7db 100644 --- a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx +++ b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx @@ -88,7 +88,6 @@ public: private: SlideSorter* mpTargetSlideSorter; - view::SubstitutionOverlay::SharedInternalState mpOverlayState; model::SharedPageDescriptor mpHitDescriptor; sal_Int32 mnInsertionIndex; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx index 7cd27573e72c..58fe0e9f3c3f 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx @@ -54,6 +54,11 @@ class AnimationFunction : private ::boost::noncopyable { public: + /** Acceleration function that maps [0,1] to [0,1] linearly, ie it + returns the given time value unaltered. + */ + static double Linear (const double nTime); + /** Acceleration function that maps [0,1] to [0,1]. Speed starts fast and ends slow following the sine function. */ diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx index 6a63060316f1..2972dab2d03a 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx @@ -74,11 +74,14 @@ public: the specified duration. @param rAnimation The animation operation. + @param nStartOffset + Time in milli seconds before the animation is started. @param nDuration The duration in milli seconds. */ AnimationId AddAnimation ( const AnimationFunctor& rAnimation, + const sal_Int32 nStartOffset, const sal_Int32 nDuration, const FinishFunctor& rFinishFunctor = FinishFunctor()); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx index e50f7c3234eb..a87ff4e3066e 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -34,6 +34,9 @@ #include "view/SlsInsertAnimator.hxx" namespace sd { namespace slidesorter { class SlideSorter; } } +namespace sd { namespace slidesorter { namespace model { +class PageEnumeration; +} } } namespace sd { namespace slidesorter { namespace view { class InsertAnimator; class InsertionIndicatorOverlay; @@ -62,6 +65,9 @@ public: const Mode eMode, const bool bIsOverSourceView); + void UpdateIndicatorIcon (model::PageEnumeration& rEnumeration); + void UpdateIndicatorIcon (void); + /** Set the position of the insertion marker to the given coordinates. */ void UpdatePosition ( @@ -97,12 +103,13 @@ private: ::boost::shared_ptr mpInsertAnimator; ::boost::shared_ptr mpInsertionIndicatorOverlay; sal_Int32 mnInsertionIndex; - bool mbIsBeforePage; + Pair maVisualInsertionIndices; Mode meMode; bool mbIsInsertionTrivial; bool mbIsActive; bool mbIsReadOnly; bool mbIsOverSourceView; + Size maIconSize; void SetPosition ( const Point& rPoint, diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index c6b9834d3f5f..33464fe10986 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -100,6 +100,15 @@ public: */ void NotifyDragFinished (void); + /** This is the higher level version of the + SlideSorterView::UpdatePageUnderMouse() method. + It does not update the page under the mouse when an operation is + active that (logically) captures the mouse. + */ + void UpdatePageUnderMouse ( + const Point& rMousePosition, + const bool bIsMouseButtonDown); + ::boost::shared_ptr GetSubstitutionHandler (void) const; class MouseMultiSelector; @@ -223,10 +232,6 @@ private: bool EventProcessing (const EventDescriptor& rEvent); void EventPostprocessing (const EventDescriptor& rEvent); - void UpdatePageUnderMouse ( - const Point& rMousePosition, - const bool bIsMouseButtonDown); - void ProcessButtonClick ( const model::SharedPageDescriptor& rpDescriptor, const sal_Int32 nButtonIndex); diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx index 7d5a8e5f21f5..e7175a5d6a07 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx @@ -47,9 +47,13 @@ class InsertAnimator public: InsertAnimator (SlideSorter& rSlideSorter); + /** Set the position at which we have to make room for the display of an + icon. + */ void SetInsertPosition ( const sal_Int32 nPageIndex, - const bool bInsertBefore); + const Pair& rVisualInsertionIndices, + const Size& rIconSize); void Reset (void); diff --git a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx index fa23bb08e251..57f5b03b932c 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx @@ -192,27 +192,19 @@ public: */ Rectangle GetPageBox (const sal_Int32 nObjectCount = -1) const; - /** Return the location of the center of the insertion marker that is + /** Return the location of the center of the insertion indicator that is specified by the parameters. - @param nIndex - Index of the page object from which the position of the marker - will be calculated. - @param bVertical - When then the insertion marker will be calculated with a - vertical orientation positioned to the left or right of the - specified page object. A horizontal orientation is indicated by - . In this case the marker will be positioned above or - below the page object. - @param bLeftOrTop - This flag indicates whether the insertion marker will be - positioned above or to the left () the page object. When - is given then the marker will be positioned below or to - the right of the page object. + @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 GetInsertionMarkerLocation ( - const sal_Int32 nIndex, - const bool bVertical, - const bool bLeftOrTop) const; + 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. @@ -222,25 +214,6 @@ public: */ Range GetRangeOfVisiblePageObjects (const Rectangle& rVisibleArea) const; - /** Return a pair of indices that point to the first and last slide in - the selection delimited by the two given points. The second point - may be located above and/or left of the anchor. - @param rAnchor - Location where the mouse button was pressed and the range - selection started. - @param rOther - Current location of the mouse. - @param rCurrentSelectionRange - Current range of the selection. - @return - The indices are sorted. When the first index is -1 then the - range is empty. - */ - Range GetSelectionRange ( - const Point& rAnchor, - const Point& rOther, - const Range& rCurrentSelectionRange) const; - /** Return the index of the page object that is rendered at the given point. @param rPosition @@ -262,17 +235,12 @@ public: /** 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. + a drag operation. This method assumes that pages are placed in a + single column. @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. - @param bAllowVerticalPosition - When this flag is then the vertical gaps between rows - may be taken into account for calculating the insertion index as - well as the horizontal gaps between columns. This will happen - only when there is only one column. - (better name, anyone?) @return Returns the page index, as accepted by the slide sorter model, of the page after which an insertion would take place. An index @@ -282,9 +250,23 @@ public: A value of -1 indicates that no valid insertion index exists for the given point. */ - sal_Int32 GetInsertionIndex ( - const Point& rModelPosition, - const bool bAllowVerticalPosition) const; + 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; /** Return whether the main orientation of the slides in the slide sorter is vertical, i.e. all slides are arranged in one column. @@ -385,6 +367,8 @@ private: GapMembership eGapMembership, sal_Int32 nIndex, sal_Int32 nGap) const; + + Rectangle GetPreviewBox (const sal_Int32 nIndex) const; }; } } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx index 026b60238d91..46f3881fe6da 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx @@ -124,6 +124,11 @@ public: const Part ePart, const CoordinateSystem eCoordinateSystem, const sal_Int32 nIndex = 0); + Rectangle GetBoundingBox ( + const Point& rPageObjectLocation, + const Part ePart, + const CoordinateSystem eCoordinateSystem, + const sal_Int32 nIndex = 0); /** Return the size in pixel of the whole page object. */ @@ -152,6 +157,7 @@ private: Rectangle maTransitionEffectBoundingBox; Rectangle maButtonAreaBoundingBox; const Image maTransitionEffectIcon; + const ::boost::shared_ptr mpPageNumberFont; Size GetPageNumberAreaSize (const int nPageCount); Rectangle CalculatePreviewBoundingBox ( diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index 586ee7474fb8..c67777418fc2 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -48,7 +48,7 @@ namespace sd { namespace slidesorter { namespace view { class Layouter; class PageObjectLayouter; - +class FramePainter; class PageObjectPainter { @@ -79,7 +79,6 @@ private: BitmapEx maStartPresentationIcon; BitmapEx maShowSlideIcon; BitmapEx maNewSlideIcon; - class FramePainter; ::boost::scoped_ptr mpShadowPainter; Bitmap maNormalBackground; Bitmap maSelectionBackground; diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index 5cadda3fafdf..83f1d75f5126 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -40,6 +40,7 @@ #include #include +#include namespace sd { namespace slidesorter { namespace controller { @@ -64,20 +65,25 @@ public: BitmapEx GetInsertIndicatorIcon (void) const; - enum FontType { PageNumberFont }; - ::boost::shared_ptr CreateFont ( + enum FontType { + PageNumberFont, + PageCountFont + }; + static ::boost::shared_ptr GetFont ( const FontType eType, - OutputDevice& rDevice) const; + const OutputDevice& rDevice); - ColorData GetColorForVisualState (const model::VisualState::State eState) const; + static ColorData GetColorForVisualState (const model::VisualState::State eState); enum ColorType { Background, + PageBackground, ButtonBackground, MouseOverColor, PageNumberBorder, PageNumberColor, - Selection + Selection, + PreviewBorder }; ColorData GetColor (const ColorType eType); @@ -99,8 +105,8 @@ public: enum IconType { - InsertionIndicator, - RawShadow + RawShadow, + RawInsertShadow }; BitmapEx GetIcon (const IconType eType); @@ -114,12 +120,13 @@ private: ColorData maBorderColor2; }; ColorData maBackgroundColor; + ColorData maPageBackgroundColor; GradientDescriptor maNormalGradient; GradientDescriptor maSelectedGradient; GradientDescriptor maSelectedAndFocusedGradient; GradientDescriptor maMouseOverGradient; BitmapEx maRawShadow; - BitmapEx maInsertionIndicator; + BitmapEx maRawInsertShadow; }; diff --git a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx b/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx index b918da47bf8f..3ecc1e5a6ee2 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include @@ -70,6 +70,8 @@ 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. @@ -120,15 +122,6 @@ public: SubstitutionOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer); virtual ~SubstitutionOverlay (void); - /** Setup the substitution display of the given set of selected pages. - The given mouse position is remembered so that it later can be - returned by GetPosition(). This is a convenience feature. - */ - void Create ( - model::PageEnumeration& rSelection, - const Point& rAnchor, - const model::SharedPageDescriptor& rpHitDescriptor); - void SetAnchor (const Point& rAnchor); /** Clear the substitution display. Until the next call of Create() no @@ -146,11 +139,6 @@ public: OutputDevice& rDevice, const Rectangle& rRepaintArea); - class InternalState; - typedef ::boost::shared_ptr SharedInternalState; - SharedInternalState GetInternalState (void) const; - void SetInternalState (const SharedInternalState& rpState); - protected: virtual Rectangle GetBoundingBox (void) const; @@ -168,8 +156,6 @@ private: static const sal_Int32 mnCenterTransparency; static const sal_Int32 mnSideTransparency; static const sal_Int32 mnCornerTransparency; - - SharedInternalState mpState; }; @@ -214,12 +200,20 @@ class InsertionIndicatorOverlay 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); @@ -236,7 +230,23 @@ private: */ 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; }; diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 992f65d03692..9aa348bcb03a 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -42,6 +42,7 @@ #include "controller/SlsSlotManager.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "controller/SlsSelectionManager.hxx" +#include "controller/SlsSelectionFunction.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" #include "model/SlideSorterModel.hxx" @@ -557,7 +558,12 @@ bool SlideSorterViewShell::HandleScrollCommand (const CommandEvent& rEvent, ::sd { OSL_ASSERT(mpSlideSorter.get()!=NULL); if (rEvent.GetCommand() == COMMAND_WHEEL) - mpSlideSorter->GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false); + { + ::rtl::Reference pFunction ( + mpSlideSorter->GetController().GetCurrentSelectionFunction()); + if (pFunction.is()) + pFunction->UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false); + } } return bDone; diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index a8e648d4c37e..34f0aee84d13 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -85,6 +85,10 @@ #include #include +//#define DEBUG_TIMING +#ifdef DEBUG_TIMING +#include +#endif using namespace std; using namespace ::sd::slidesorter::model; @@ -785,18 +789,27 @@ Rectangle SlideSorterView::GetModelArea (void) } +#ifdef DEBUG_TIMING static ::canvas::tools::ElapsedTime gaTimer; - +static const size_t gFrameTimeCount (10); +static size_t gFrameTimeIndex (0); +static ::std::vector gFrameTimes (gFrameTimeCount, 0); +static double gFrameTimeSum (0); +static const Rectangle gFrameTimeBox (10,10,150,20); +static double gnLastFrameStart = 0; +#endif void SlideSorterView::CompleteRedraw ( OutputDevice* pDevice, const Region& rPaintArea, sdr::contact::ViewObjectContactRedirector* pRedirector) { +#ifdef DEBUG_TIMING const double nStartTime (gaTimer.getElapsedTime()); OSL_TRACE("SlideSorterView::CompleteRedraw start at %f, %s", nStartTime, mnLockRedrawSmph ? "locked" : ""); +#endif if (pDevice == NULL || pDevice!=mrSlideSorter.GetContentWindow().get()) return; @@ -818,8 +831,25 @@ void SlideSorterView::CompleteRedraw ( View::CompleteRedraw(pDevice, rPaintArea, pRedirector); } +#ifdef DEBUG_TIMING const double nEndTime (gaTimer.getElapsedTime()); OSL_TRACE("SlideSorterView::CompleteRedraw end at %f after %fms", nEndTime, (nEndTime-nStartTime)*1000); + gFrameTimeSum -= gFrameTimes[gFrameTimeIndex]; + gFrameTimes[gFrameTimeIndex] = nStartTime - gnLastFrameStart; + gnLastFrameStart = nStartTime; + gFrameTimeSum += gFrameTimes[gFrameTimeIndex]; + gFrameTimeIndex = (gFrameTimeIndex+1) % gFrameTimeCount; + + + mrSlideSorter.GetContentWindow()->SetFillColor(COL_BLUE); + mrSlideSorter.GetContentWindow()->DrawRect(gFrameTimeBox); + mrSlideSorter.GetContentWindow()->SetTextColor(COL_WHITE); + mrSlideSorter.GetContentWindow()->DrawText( + gFrameTimeBox, + ::rtl::OUString::valueOf(1 / (gFrameTimeSum / gFrameTimeCount)), + TEXT_DRAW_RIGHT | TEXT_DRAW_VCENTER); + // mrSlideSorter.GetContentWindow()->Invalidate(gFrameTimeBox); +#endif } @@ -953,6 +983,8 @@ void SlideSorterView::SetPageUnderMouse (const model::SharedPageDescriptor& rpDe if (mpPageUnderMouse) SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true); + // Change the quick help text to display the name of the page under + // the mouse. SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { @@ -1041,7 +1073,7 @@ bool SlideSorterView::SetState ( AnimationFunction::Blend, nStartAlpha, nEndAlpha, - ::boost::bind(AnimationFunction::FastInSlowOut_Root, _1))); + ::boost::bind(AnimationFunction::Linear, _1))); rpDescriptor->GetVisualState().SetButtonAlphaAnimationId( mrSlideSorter.GetController().GetAnimator()->AddAnimation( ::boost::bind( @@ -1049,6 +1081,7 @@ bool SlideSorterView::SetState ( rpDescriptor, ::boost::ref(*this), ::boost::bind(aBlendFunctor, _1)), + bStateValue ? 500 : 0, 400, ::boost::bind( &VisualState::SetButtonAlphaAnimationId, diff --git a/sd/source/ui/slidesorter/view/SlsFramePainter.cxx b/sd/source/ui/slidesorter/view/SlsFramePainter.cxx new file mode 100644 index 000000000000..d8a147209922 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsFramePainter.cxx @@ -0,0 +1,219 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: baseprimitive2d.hxx,v $ + * + * $Revision: 1.8 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "SlsFramePainter.hxx" +#include + + +namespace sd { namespace slidesorter { namespace view { + +FramePainter::FramePainter (const BitmapEx& rShadowBitmap) + : maShadowTopLeft(rShadowBitmap,-1,-1), + maShadowTop(rShadowBitmap,0,-1), + maShadowTopRight(rShadowBitmap,+1,-1), + maShadowLeft(rShadowBitmap,-1,0), + maShadowRight(rShadowBitmap,+1,0), + maShadowBottomLeft(rShadowBitmap,-1,+1), + maShadowBottom(rShadowBitmap,0,+1), + maShadowBottomRight(rShadowBitmap,+1,+1), + mbIsValid(false) +{ + if (rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height() + && (rShadowBitmap.GetSizePixel().Width()-1)%2 == 0 + && ((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1) + { + mbIsValid = true; + } + else + { + OSL_ASSERT(rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height()); + OSL_ASSERT((rShadowBitmap.GetSizePixel().Width()-1)%2 == 0); + OSL_ASSERT(((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1); + } +} + + + + +FramePainter::~FramePainter (void) +{ +} + + + + +void FramePainter::PaintFrame ( + OutputDevice& rDevice, + const Rectangle aBox) const +{ + if ( ! mbIsValid) + return; + + // Paint the shadow. + maShadowTopLeft.PaintCorner(rDevice, aBox.TopLeft()); + maShadowTopRight.PaintCorner(rDevice, aBox.TopRight()); + maShadowBottomLeft.PaintCorner(rDevice, aBox.BottomLeft()); + maShadowBottomRight.PaintCorner(rDevice, aBox.BottomRight()); + maShadowLeft.PaintSide(rDevice, + aBox.TopLeft(), aBox.BottomLeft(), + maShadowTopLeft, maShadowBottomLeft); + maShadowRight.PaintSide(rDevice, + aBox.TopRight(), aBox.BottomRight(), + maShadowTopRight, maShadowBottomRight); + maShadowTop.PaintSide(rDevice, + aBox.TopLeft(), aBox.TopRight(), + maShadowTopLeft, maShadowTopRight); + maShadowBottom.PaintSide(rDevice, + aBox.BottomLeft(), aBox.BottomRight(), + maShadowBottomLeft, maShadowBottomRight); +} + + + + +//===== OffsetBitmap ========================================================== + +OffsetBitmap::OffsetBitmap ( + const BitmapEx& rBitmap, + const sal_Int32 nHorizontalPosition, + const sal_Int32 nVerticalPosition) + : maBitmap(), + maOffset() +{ + OSL_ASSERT(nHorizontalPosition>=-1 && nHorizontalPosition<=+1); + OSL_ASSERT(nVerticalPosition>=-1 && nVerticalPosition<=+1); + + const sal_Int32 nS (1); + const sal_Int32 nC (::std::max(0,(rBitmap.GetSizePixel().Width()-nS)/2)); + const sal_Int32 nO (nC/2); + + const Point aOrigin( + nHorizontalPosition<0 ? 0 : (nHorizontalPosition == 0 ? nC : nC+nS), + nVerticalPosition<0 ? 0 : (nVerticalPosition == 0 ? nC : nC+nS)); + const Size aSize( + nHorizontalPosition==0 ? nS : nC, + nVerticalPosition==0 ? nS : nC); + maBitmap = BitmapEx(rBitmap, aOrigin, aSize); + if (maBitmap.IsEmpty()) + return; + maOffset = Point( + nHorizontalPosition<0 ? -nO : nHorizontalPosition>0 ? -nO : 0, + nVerticalPosition<0 ? -nO : nVerticalPosition>0 ? -nO : 0); + + // Enlarge the side bitmaps so that painting the frame requires less + // paint calls. + const sal_Int32 nSideBitmapSize (64); + 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); + } +} + + + + +void OffsetBitmap::PaintCorner ( + OutputDevice& rDevice, + const Point& rAnchor) const +{ + if ( ! maBitmap.IsEmpty()) + rDevice.DrawBitmapEx(rAnchor+maOffset, maBitmap); +} + + + + +void OffsetBitmap::PaintSide ( + OutputDevice& rDevice, + const Point& rAnchor1, + const Point& rAnchor2, + const OffsetBitmap& rCornerBitmap1, + const OffsetBitmap& rCornerBitmap2) const +{ + if (maBitmap.IsEmpty()) + return; + + const Size aBitmapSize (maBitmap.GetSizePixel()); + if (rAnchor1.Y() == rAnchor2.Y()) + { + // Side is horizontal. + const sal_Int32 nY (rAnchor1.Y() + maOffset.Y()); + const sal_Int32 nLeft ( + rAnchor1.X() + + rCornerBitmap1.maBitmap.GetSizePixel().Width() + + rCornerBitmap1.maOffset.X()); + const sal_Int32 nRight ( + rAnchor2.X() + + rCornerBitmap2.maOffset.X()\ + - 1); + for (sal_Int32 nX=nLeft; nX<=nRight; nX+=aBitmapSize.Width()) + rDevice.DrawBitmapEx( + Point(nX,nY), + Size(std::min(aBitmapSize.Width(), nRight-nX+1),aBitmapSize.Height()), + maBitmap); + } + else if (rAnchor1.X() == rAnchor2.X()) + { + // Side is vertical. + const sal_Int32 nX (rAnchor1.X() + maOffset.X()); + const sal_Int32 nTop ( + rAnchor1.Y() + + rCornerBitmap1.maBitmap.GetSizePixel().Height() + + rCornerBitmap1.maOffset.Y()); + const sal_Int32 nBottom ( + rAnchor2.Y() + + rCornerBitmap2.maOffset.Y() + - 1); + for (sal_Int32 nY=nTop; nY<=nBottom; nY+=aBitmapSize.Height()) + rDevice.DrawBitmapEx( + Point(nX,nY), + Size(aBitmapSize.Width(), std::min(aBitmapSize.Height(), nBottom-nY+1)), + maBitmap); + } + else + { + // Diagonal sides indicatee an error. + OSL_ASSERT(false); + } +} + + +} } } // end of namespace sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsFramePainter.hxx b/sd/source/ui/slidesorter/view/SlsFramePainter.hxx new file mode 100644 index 000000000000..9df2e4183573 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsFramePainter.hxx @@ -0,0 +1,137 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: baseprimitive2d.hxx,v $ + * + * $Revision: 1.8 $ + * + * last change: $Author: aw $ $Date: 2008-05-27 14:11:16 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef SD_SLIDESORTER_VIEW_FRAME_PAINTER_HXX +#define SD_SLIDESORTER_VIEW_FRAME_PAINTER_HXX + +#include + + +namespace sd { namespace slidesorter { namespace view { + +namespace { + +/** Bitmap with offset that is used when the bitmap is painted. The bitmap +*/ +class OffsetBitmap +{ +public: + /** Create one of the eight shadow bitmaps from one that combines them + all. This larger bitmap is expected to have dimension NxN with + N=1+2*M. Of this larger bitmap there are created four corner + bitmaps of size 2*M x 2*M and four side bitmaps of sizes 1xM (top + and bottom) and Mx1 (left and right). The corner bitmaps have each + one quadrant of size MxM that is painted under the interior of the + frame. + @param rBitmap + The larger bitmap of which the eight shadow bitmaps are cut out + from. + @param nHorizontalPosition + Valid values are -1 (left), 0 (center), and +1 (right). + @param nVerticalPosition + Valid values are -1 (top), 0 (center), and +1 (bottom). + */ + OffsetBitmap ( + const BitmapEx& rBitmap, + const sal_Int32 nHorizontalPosition, + const sal_Int32 nVerticalPosition); + + /** Create bitmap and offset from the given values. Corner bitmaps are + constructed with the given width and height. Side bitmaps are + stretched along one axis to reduce the paint calls when the sides of + a frame are painted. + @param rBitmap + The larger bitmap that contains the four corner bitmaps and the + four side bitmaps. + */ + void SetBitmap ( + const BitmapEx& rBitmap, + const sal_Int32 nOriginX, + const sal_Int32 nOriginY, + const sal_Int32 nWidth, + const sal_Int32 nHeight, + const sal_Int32 nOffsetX, + const sal_Int32 nOffsetY); + + /** Use the given device to paint the bitmap at the location that is the + sum of the given anchor and the internal offset. + */ + void PaintCorner (OutputDevice& rDevice, const Point& rAnchor) const; + + /** Use the given device to paint the bitmap stretched between the two + given locations. Offsets of the adjacent corner bitmaps and the + offset of the side bitmap are used to determine the area that is to + be filled with the side bitmap. + */ + void PaintSide ( + OutputDevice& rDevice, + const Point& rAnchor1, + const Point& rAnchor2, + const OffsetBitmap& rCornerBitmap1, + const OffsetBitmap& rCornerBitmap2) const; + +private: + BitmapEx maBitmap; + Point maOffset; +}; + +} // end of anonymous namespace + + + + +class FramePainter +{ +public: + FramePainter (const BitmapEx& rBitmap); + ~FramePainter (void); + void PaintFrame (OutputDevice&rDevice, const Rectangle aBox) const; + +private: + OffsetBitmap maShadowTopLeft; + OffsetBitmap maShadowTop; + OffsetBitmap maShadowTopRight; + OffsetBitmap maShadowLeft; + OffsetBitmap maShadowRight; + OffsetBitmap maShadowBottomLeft; + OffsetBitmap maShadowBottom; + OffsetBitmap maShadowBottomRight; + bool mbIsValid; +}; + + +} } } // end of namespace sd::slidesorter::view + +#endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hrc b/sd/source/ui/slidesorter/view/SlsIcons.hrc index cb0fe634f501..afde6145ab49 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.hrc +++ b/sd/source/ui/slidesorter/view/SlsIcons.hrc @@ -43,5 +43,6 @@ #define IMAGE_NEW_SLIDE 6 #define IMAGE_SHADOW 10 +#define IMAGE_INSERT_SHADOW 11 #endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.src b/sd/source/ui/slidesorter/view/SlsIcons.src index facd4138b574..834e0b2caa9a 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.src +++ b/sd/source/ui/slidesorter/view/SlsIcons.src @@ -66,4 +66,9 @@ Resource IMG_ICONS { ImageBitmap = Bitmap { File = "slide_sorter_shadow.png" ; }; }; + + Image IMAGE_INSERT_SHADOW + { + ImageBitmap = Bitmap { File = "slide_sorter_insert_shadow.png" ; }; + }; }; diff --git a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx index 3376fc9e0c6c..6ae6e872df86 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx @@ -76,8 +76,8 @@ public: void UpdateOffsets( const sal_Int32 nInsertIndex, - const Point& rLeadingOffset, - const Point& rTrailingOffset); + const Size& rRequiredSpace, + const view::Layouter& GetLayouter); /// Index of the row or column that this run represents. sal_Int32 mnRunIndex; @@ -133,7 +133,8 @@ public: void SetInsertPosition ( const sal_Int32 nPageIndex, - const bool bInsertBefore); + const Pair& rVisualInsertionIndices, + const Size& rIconSize); void Reset (void); @@ -152,13 +153,12 @@ private: /// The current insertion index. The special value -1 means that there /// is no current insertion index. sal_Int32 mnCurrentInsertPosition; - bool mbCurrentInsertBefore; + Pair maVisualInsertionIndices; void StopAnimation (void); SharedPageObjectRun GetRun ( view::Layouter& rLayouter, - const sal_Int32 nPageIndex, - const bool bInsertBefore, + const sal_Int32 nRowIndex, const bool bCreate = true); RunContainer::iterator FindRun (const sal_Int32 nRunIndex) const; }; @@ -179,9 +179,10 @@ InsertAnimator::InsertAnimator (SlideSorter& rSlideSorter) void InsertAnimator::SetInsertPosition ( const sal_Int32 nPageIndex, - const bool bInsertBefore) + const Pair& rVisualInsertionIndices, + const Size& rIconSize) { - mpImplementation->SetInsertPosition(nPageIndex, bInsertBefore); + mpImplementation->SetInsertPosition(nPageIndex, rVisualInsertionIndices, rIconSize); } @@ -203,7 +204,7 @@ InsertAnimator::Implementation::Implementation (SlideSorter& rSlideSorter) mpAnimator(rSlideSorter.GetController().GetAnimator()), maRuns(), mnCurrentInsertPosition(-1), - mbCurrentInsertBefore(false) + maVisualInsertionIndices() { } @@ -220,17 +221,16 @@ InsertAnimator::Implementation::~Implementation (void) void InsertAnimator::Implementation::SetInsertPosition ( const sal_Int32 nPageIndex, - const bool bInsertBefore) + const Pair& rVisualInsertionIndices, + const Size& rIconSize) { - if (nPageIndex==mnCurrentInsertPosition && bInsertBefore==mbCurrentInsertBefore) + if (nPageIndex==mnCurrentInsertPosition && rVisualInsertionIndices==maVisualInsertionIndices) return; - SharedPageObjectRun pOldRun ( - GetRun(mrView.GetLayouter(), mnCurrentInsertPosition, mbCurrentInsertBefore)); - SharedPageObjectRun pCurrentRun ( - GetRun(mrView.GetLayouter(), nPageIndex, bInsertBefore)); + SharedPageObjectRun pOldRun (GetRun(mrView.GetLayouter(), maVisualInsertionIndices.A())); + SharedPageObjectRun pCurrentRun (GetRun(mrView.GetLayouter(), rVisualInsertionIndices.A())); mnCurrentInsertPosition = nPageIndex; - mbCurrentInsertBefore = bInsertBefore; + maVisualInsertionIndices = rVisualInsertionIndices; // 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 +238,7 @@ void InsertAnimator::Implementation::SetInsertPosition ( { if (pOldRun) { - pOldRun->UpdateOffsets(-1, Point(0,0), Point(0,0)); + pOldRun->UpdateOffsets(-1, Size(0,0), mrView.GetLayouter()); maRuns.insert(pOldRun); } } @@ -247,9 +247,9 @@ void InsertAnimator::Implementation::SetInsertPosition ( { const sal_Int32 nColumnCount (mrView.GetLayouter().GetColumnCount()); pCurrentRun->UpdateOffsets( - mnCurrentInsertPosition, - nColumnCount > 1 ? Point(-20,0) : Point(0,-20), - nColumnCount > 1 ? Point(+20,0) : Point(0,+20)); + nColumnCount > 1 ? maVisualInsertionIndices.B() : maVisualInsertionIndices.A(), + nColumnCount > 1 ? Size(rIconSize.Width(),0) : Size(0, rIconSize.Height()), + mrView.GetLayouter()); maRuns.insert(pCurrentRun); } } @@ -259,7 +259,7 @@ void InsertAnimator::Implementation::SetInsertPosition ( void InsertAnimator::Implementation::Reset (void) { - SetInsertPosition(-1, false); + SetInsertPosition(-1, Pair(-1,-1), Size(0,0)); } @@ -267,11 +267,10 @@ void InsertAnimator::Implementation::Reset (void) SharedPageObjectRun InsertAnimator::Implementation::GetRun ( view::Layouter& rLayouter, - const sal_Int32 nPageIndex, - const bool bInsertBefore, + const sal_Int32 nRowIndex, const bool bCreate) { - if (nPageIndex < 0) + if (nRowIndex < 0) return SharedPageObjectRun(); RunContainer::iterator iRun (maRuns.end()); @@ -288,24 +287,17 @@ SharedPageObjectRun InsertAnimator::Implementation::GetRun ( } else { - // Look up the row that contains the insert position (take into - // acount the flag that states whether the indicator is to place - // before or after the page object at that position.) - int nIndex (nPageIndex); - if ( ! bInsertBefore && nPageIndex > 0) - --nIndex; - const sal_Int32 nRow (rLayouter.GetRow(nIndex)); - iRun = FindRun(nRow); + iRun = FindRun(nRowIndex); if (iRun == maRuns.end() && bCreate) { // Create a new run. - const sal_Int32 nStartIndex (rLayouter.GetIndex(nRow,0)); - const sal_Int32 nEndIndex (rLayouter.GetIndex(nRow, rLayouter.GetColumnCount()-1)); + const sal_Int32 nStartIndex (rLayouter.GetIndex(nRowIndex,0)); + const sal_Int32 nEndIndex (rLayouter.GetIndex(nRowIndex,rLayouter.GetColumnCount()-1)); if (nStartIndex <= nEndIndex) { iRun = maRuns.insert(SharedPageObjectRun(new PageObjectRun( *this, - nRow, + nRowIndex, nStartIndex, nEndIndex))).first; OSL_ASSERT(iRun != maRuns.end()); @@ -373,7 +365,7 @@ PageObjectRun::PageObjectRun ( mrAnimatorAccess(rAnimatorAccess), maAccelerationFunction( controller::AnimationParametricFunction( - controller::AnimationBezierFunction (0.1,0.6))) + controller::AnimationBezierFunction (0.1,0.7))) { maStartOffset.resize(nEndIndex - nStartIndex + 1); maEndOffset.resize(nEndIndex - nStartIndex + 1); @@ -391,22 +383,75 @@ PageObjectRun::~PageObjectRun (void) void PageObjectRun::UpdateOffsets( const sal_Int32 nInsertIndex, - const Point& rLeadingOffset, - const Point& rTrailingOffset) + const Size& rRequiredSpace, + const view::Layouter& rLayouter) { if (nInsertIndex != mnInsertIndex) { mnInsertIndex = nInsertIndex; model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel()); - for (sal_Int32 nIndex=mnStartIndex; nIndex<=mnEndIndex; ++nIndex) + Point aLeadingOffset; + Point aTrailingOffset; + const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1); + const bool bUseX (rLayouter.GetColumnCount() > 1); + if (mnInsertIndex == 0) + { + const Rectangle aInnerBox (rLayouter.GetPageObjectLayouter()->GetBoundingBox( + Point(0,0), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + const Point aAvailableSpace (aInnerBox.TopLeft()); + if (bUseX) + aTrailingOffset.X() = ::std::max(0L, rRequiredSpace.Width()-aAvailableSpace.X()); + else + aTrailingOffset.Y() = ::std::max(0L, rRequiredSpace.Height()-aAvailableSpace.Y()); + } + else if (mnInsertIndex == nRunLength) + { + const Rectangle aOuterBox (rLayouter.GetPageObjectBox(mnEndIndex)); + const Rectangle aInnerBox (rLayouter.GetPageObjectLayouter()->GetBoundingBox( + aOuterBox.TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + const Point aAvailableSpace (aOuterBox.BottomRight() - aInnerBox.BottomRight()); + if (bUseX) + aLeadingOffset.X() = ::std::min(0L, aAvailableSpace.X()-rRequiredSpace.Width()); + else + aLeadingOffset.Y() = ::std::min(0L, aAvailableSpace.Y()-rRequiredSpace.Height()); + } + else if (mnInsertIndex > 0) + { + const Rectangle aBox1 (rLayouter.GetPageObjectLayouter()->GetBoundingBox( + rModel.GetPageDescriptor(mnStartIndex + nInsertIndex - 1), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + const Rectangle aBox2 (rLayouter.GetPageObjectLayouter()->GetBoundingBox( + rModel.GetPageDescriptor(mnStartIndex + nInsertIndex), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + const Size aDelta ( + bUseX ? aBox2.Left() - aBox1.Right() - 1 : 0, + bUseX ? 0 : aBox2.Top() - aBox1.Bottom() - 1); + if (aDelta.Width() < rRequiredSpace.Width()) + { + aLeadingOffset.X() = (aDelta.Width()-rRequiredSpace.Width()-1)/2; + aTrailingOffset.X() = rRequiredSpace.Width()-aDelta.Width()+aLeadingOffset.X(); + } + if (aDelta.Height() < rRequiredSpace.Height()) + { + aLeadingOffset.Y() = (aDelta.Height()-rRequiredSpace.Height()-1)/2; + aTrailingOffset.Y() = rRequiredSpace.Height()-aDelta.Height()+aLeadingOffset.Y(); + } + } + for (sal_Int32 nIndex=0; nIndexGetVisualState().GetLocationOffset(); - maEndOffset[nIndex-mnStartIndex] = nIndex < nInsertIndex - ? rLeadingOffset - : rTrailingOffset; + maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset(); + maEndOffset[nIndex] = nIndex < nInsertIndex + ? aLeadingOffset + : aTrailingOffset; } RestartAnimation(); } @@ -426,6 +471,7 @@ void PageObjectRun::RestartAnimation (void) // Restart the animation. mnAnimationId = mrAnimatorAccess.GetAnimator()->AddAnimation( ::boost::ref(*this), + 0, 300, ::boost::bind(&AnimatorAccess::RemoveRun, ::boost::ref(mrAnimatorAccess), this)); } diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 4ad682486f1a..5651e21a7696 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -451,42 +451,98 @@ Rectangle Layouter::GetPageBox (const sal_Int32 nObjectCount) const -Point Layouter::GetInsertionMarkerLocation ( - const sal_Int32 nIndex, - const bool bVertical, - const bool bLeftOrTop) const +Rectangle Layouter::GetPreviewBox (const sal_Int32 nIndex) const { - Rectangle aBox (GetPageObjectBox (nIndex)); - Point aLocation = aBox.Center(); + return mpPageObjectLayouter->GetBoundingBox( + GetPageObjectBox(nIndex).TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem); +} + + - if (bVertical) + +Point Layouter::GetInsertionIndicatorLocation ( + const Pair& rVisualIndices, + const Size& rIndicatorSize) const +{ + if (rVisualIndices.B() < 0) { - if (bLeftOrTop) + // Place indicator between rows of a single column of pages. + + if (rVisualIndices.A() == 0) { - // Left. - aLocation.setX(aBox.Left() - (mnHorizontalGap+1)/2 - 1); + // Place indicator at the top of the column. + const Rectangle aOuterBox (GetPageObjectBox(0)); + const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( + aOuterBox.TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + return Point(aPreviewBox.Center().X(), aOuterBox.Top()+rIndicatorSize.Height()/2); + } + else if (rVisualIndices.A() == mnRowCount) + { + // 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); } else { - // Right. - aLocation.setX(aBox.Right() + mnHorizontalGap/2); + // Place indicator between two rows. + const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox( + GetPageObjectBox(rVisualIndices.A()-1).TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox( + GetPageObjectBox(rVisualIndices.A()).TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + return (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; } } else { - if (bLeftOrTop) + // Place indicator between columns in one row. + const sal_Int32 nIndex (rVisualIndices.A() * mnColumnCount + rVisualIndices.B()); + + if (rVisualIndices.B() == 0) { - // Above. - aLocation.setY(aBox.Top() - (mnVerticalGap+1)/2 - 1); + // Place indicator at the left of the row. + const Rectangle aOuterBox (GetPageObjectBox(nIndex)); + const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( + aOuterBox.TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + return Point(aOuterBox.Left()+rIndicatorSize.Width()/2, aPreviewBox.Center().Y()); + } + else if (rVisualIndices.B() == mnColumnCount) + { + // Place indicator at the end of the row. + const Rectangle aOuterBox (GetPageObjectBox(nIndex-1)); + const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( + aOuterBox.TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + return Point(aOuterBox.Right()-rIndicatorSize.Width()/2, aPreviewBox.Center().Y()); } else { - // Below. - aLocation.setY(aBox.Bottom() + mnVerticalGap/2); + // Place indicator between two columns. + const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox( + GetPageObjectBox(nIndex-1).TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox( + GetPageObjectBox(nIndex).TopLeft(), + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + return (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; } } - - return aLocation; } @@ -505,62 +561,6 @@ Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) con -Range Layouter::GetSelectionRange ( - const Point& rAnchor, - const Point& rOther, - const Range& rCurrentSelectionRange) const -{ - (void)rCurrentSelectionRange; - sal_Int32 nIndexA (GetInsertionIndex(rAnchor, true)); - sal_Int32 nIndexB (GetInsertionIndex(rOther, true)); - - // When either of the locations does not lie over a page then we may - // have to adapt the start or end index. - Rectangle aBoxA (GetPageObjectBox(nIndexA)); - Rectangle aBoxB (GetPageObjectBox(nIndexB)); - if (nIndexA > nIndexB) - { - ::std::swap(nIndexA,nIndexB); - ::std::swap(aBoxA, aBoxB); - } - - if (mnColumnCount == 1) - { - // Vertical arrangement of pages. - if (nIndexA <= nIndexB) - { - if (rOther.Y() < aBoxB.Top()) - --nIndexB; - } - else - { - if (rOther.Y() > aBoxB.Bottom()) - --nIndexA; - } - } - else - { - // Horizontal arrangement of pages. - if (nIndexA <= nIndexB) - { - if (rOther.X() < aBoxB.Left()) - --nIndexB; - } - else - { - if (rOther.X() > aBoxB.Right()) - --nIndexA; - } - } - - return Range( - ::std::min(nIndexA, nIndexB), - ::std::min(mnPageCount-1, ::std::max(nIndexA, nIndexB))); -} - - - - sal_Int32 Layouter::GetIndexAtPoint ( const Point& rPosition, const bool bIncludePageBorders) const @@ -581,32 +581,26 @@ sal_Int32 Layouter::GetIndexAtPoint ( -/** Calculation of the insertion index: - 1. Determine the row. rPoint has to be in the row between upper and - lower border. If it is in a horizontal gap or border an invalid - insertion index (-1, which is a valid return value) will be returned. - 2. Determine the column. Here both vertical borders and vertical gaps - will yield valid return values. The horizontal positions between the - center of page objects in column i and the center of page objects in - column i+1 will return column i+1 as insertion index. - - When there is only one column and bAllowVerticalPosition is true than - take the vertical areas between rows into account as well. -*/ -sal_Int32 Layouter::GetInsertionIndex ( - const Point& rPosition, - bool bAllowVerticalPosition) const +sal_Int32 Layouter::GetVerticalInsertionIndex (const Point& rPosition) const { - sal_Int32 nIndex = -1; + OSL_ASSERT(mnColumnCount == 1); - sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), true, - (mnColumnCount==1 && bAllowVerticalPosition) ? GM_BOTH : GM_BOTH); - sal_Int32 nColumn = GetColumnAtPosition (rPosition.X(), true, GM_BOTH); + const sal_Int32 nY = rPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; + const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); + return nY / nRowHeight; +} - if (nRow >= 0 && nColumn >= 0) - nIndex = nRow * mnColumnCount + nColumn; - return nIndex; + + +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); } diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx index 2b89006dc9ea..8075464d92ff 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -29,10 +29,13 @@ * ************************************************************************/ +#include "precompiled_sd.hxx" + #include "view/SlsPageObjectLayouter.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlsFontProvider.hxx" +#include "view/SlsTheme.hxx" #include "tools/IconCache.hxx" #include "Window.hxx" #include "res_bmp.hrc" @@ -62,7 +65,8 @@ PageObjectLayouter::PageObjectLayouter ( maPreviewBoundingBox(), maTransitionEffectBoundingBox(), maButtonAreaBoundingBox(), - maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)) + maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)), + mpPageNumberFont(Theme::GetFont(Theme::PageNumberFont, *rpWindow)) { const Size aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount)); @@ -178,6 +182,19 @@ Rectangle PageObjectLayouter::GetBoundingBox ( const Part ePart, const CoordinateSystem eCoordinateSystem, const sal_Int32 nIndex) +{ + Point aLocation (rpPageDescriptor ? rpPageDescriptor->GetLocation() : Point(0,0)); + return GetBoundingBox(aLocation, ePart, eCoordinateSystem, nIndex); +} + + + + +Rectangle PageObjectLayouter::GetBoundingBox ( + const Point& rPageObjectLocation, + const Part ePart, + const CoordinateSystem eCoordinateSystem, + const sal_Int32 nIndex) { Rectangle aBoundingBox; switch (ePart) @@ -221,11 +238,11 @@ Rectangle PageObjectLayouter::GetBoundingBox ( break; } - Point aLocation (rpPageDescriptor ? rpPageDescriptor->GetLocation() : Point(0,0)); + Point aLocation (rPageObjectLocation); if (eCoordinateSystem == ScreenCoordinateSystem) aLocation += mpWindow->GetMapMode().GetOrigin(); - return Rectangle( + return Rectangle( aBoundingBox.TopLeft() + aLocation, aBoundingBox.BottomRight() + aLocation); } @@ -255,7 +272,8 @@ Size PageObjectLayouter::GetPageNumberAreaSize (const int nPageCount) // Set the correct font. Font aOriginalFont (mpWindow->GetFont()); - mpWindow->SetFont(*FontProvider::Instance().GetFont(*mpWindow)); + if (mpPageNumberFont) + mpWindow->SetFont(*mpPageNumberFont); String sPageNumberTemplate; if (nPageCount < 10) diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 0a83736aa689..e417dba20882 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -33,6 +33,8 @@ * ************************************************************************/ +#include "precompiled_sd.hxx" + #include "view/SlsPageObjectPainter.hxx" #include "model/SlsPageDescriptor.hxx" @@ -41,6 +43,7 @@ #include "view/SlsLayouter.hxx" #include "view/SlsTheme.hxx" #include "SlsIcons.hxx" +#include "SlsFramePainter.hxx" #include "cache/SlsPageCache.hxx" #include "controller/SlsProperties.hxx" #include "Window.hxx" @@ -129,96 +132,11 @@ void AdaptTransparency (AlphaMask& rMask, const double nAlpha) } } - -/** Bitmap with offset that is used when the bitmap is painted. The bitmap -*/ -class OffsetBitmap -{ -public: - /** Create one of the eight shadow bitmaps from one that combines them - all. This larger bitmap is expected to have dimension NxN with - N=1+2*M. Of this larger bitmap there are created four corner - bitmaps of size 2*M x 2*M and four side bitmaps of sizes 1xM (top - and bottom) and Mx1 (left and right). The corner bitmaps have each - one quadrant of size MxM that is painted under the interior of the - frame. - @param rBitmap - The larger bitmap of which the eight shadow bitmaps are cut out - from. - @param nHorizontalPosition - Valid values are -1 (left), 0 (center), and +1 (right). - @param nVerticalPosition - Valid values are -1 (top), 0 (center), and +1 (bottom). - */ - OffsetBitmap ( - const BitmapEx& rBitmap, - const sal_Int32 nHorizontalPosition, - const sal_Int32 nVerticalPosition); - - /** Create bitmap and offset from the given values. Corner bitmaps are - constructed with the given width and height. Side bitmaps are - stretched along one axis to reduce the paint calls when the sides of - a frame are painted. - @param rBitmap - The larger bitmap that contains the four corner bitmaps and the - four side bitmaps. - */ - void SetBitmap ( - const BitmapEx& rBitmap, - const sal_Int32 nOriginX, - const sal_Int32 nOriginY, - const sal_Int32 nWidth, - const sal_Int32 nHeight, - const sal_Int32 nOffsetX, - const sal_Int32 nOffsetY); - - /** Use the given device to paint the bitmap at the location that is the - sum of the given anchor and the internal offset. - */ - void PaintCorner (OutputDevice& rDevice, const Point& rAnchor) const; - - /** Use the given device to paint the bitmap stretched between the two - given locations. Offsets of the adjacent corner bitmaps and the - offset of the side bitmap are used to determine the area that is to - be filled with the side bitmap. - */ - void PaintSide ( - OutputDevice& rDevice, - const Point& rAnchor1, - const Point& rAnchor2, - const OffsetBitmap& rCornerBitmap1, - const OffsetBitmap& rCornerBitmap2) const; - -private: - BitmapEx maBitmap; - Point maOffset; -}; - } // end of anonymous namespace -class PageObjectPainter::FramePainter -{ -public: - FramePainter (const BitmapEx& rBitmap); - ~FramePainter (void); - void PaintFrame (OutputDevice&rDevice, const Rectangle aBox) const; - -private: - OffsetBitmap maShadowTopLeft; - OffsetBitmap maShadowTop; - OffsetBitmap maShadowTopRight; - OffsetBitmap maShadowLeft; - OffsetBitmap maShadowRight; - OffsetBitmap maShadowBottomLeft; - OffsetBitmap maShadowBottom; - OffsetBitmap maShadowBottomRight; - bool mbIsValid; -}; - - //===== PageObjectPainter ===================================================== PageObjectPainter::PageObjectPainter ( @@ -228,7 +146,7 @@ PageObjectPainter::PageObjectPainter ( mpCache(rSlideSorter.GetView().GetPreviewCache()), mpProperties(rSlideSorter.GetProperties()), mpTheme(rSlideSorter.GetTheme()), - mpPageNumberFont(), + mpPageNumberFont(Theme::GetFont(Theme::PageNumberFont, *rSlideSorter.GetContentWindow())), maStartPresentationIcon(), maShowSlideIcon(), maNewSlideIcon(), @@ -270,8 +188,6 @@ void PageObjectPainter::PaintPageObject ( return; } - if ( ! mpPageNumberFont) - mpPageNumberFont = mpTheme->CreateFont(Theme::PageNumberFont, rDevice); PrepareBackgrounds(rDevice); // Turn off antialiasing to avoid the bitmaps from being shifted by @@ -365,16 +281,21 @@ void PageObjectPainter::PaintPreview ( BitmapEx aBitmap (mpCache->GetPreviewBitmap(pPage)); mpCache->SetPreciousFlag(pPage, true); - if (rpDescriptor->GetVisualState().GetCurrentVisualState() - == model::VisualState::VS_Excluded) - { - AlphaMask aMask (aBitmap.GetSizePixel()); - aMask.Erase(128); - aBitmap = BitmapEx(aBitmap.GetBitmap(), aMask); - } - rDevice.DrawBitmapEx(aBox.TopLeft(), aBitmap); } + + if (rpDescriptor->GetVisualState().GetCurrentVisualState() + == model::VisualState::VS_Excluded) + { + rDevice.SetFillColor(COL_BLACK); + 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); + } } @@ -586,8 +507,8 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox); // Clear the area where the preview will later be painted. - aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::Background)); - aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::Background)); + aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::PageBackground)); + aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::PageBackground)); aBitmapDevice.DrawRect(aBox); return aBitmapDevice.GetBitmap (Point(0,0),aSize); @@ -611,173 +532,4 @@ void PageObjectPainter::PaintBorder ( - -//===== FramePainter ========================================================== - -PageObjectPainter::FramePainter::FramePainter (const BitmapEx& rShadowBitmap) - : maShadowTopLeft(rShadowBitmap,-1,-1), - maShadowTop(rShadowBitmap,0,-1), - maShadowTopRight(rShadowBitmap,+1,-1), - maShadowLeft(rShadowBitmap,-1,0), - maShadowRight(rShadowBitmap,+1,0), - maShadowBottomLeft(rShadowBitmap,-1,+1), - maShadowBottom(rShadowBitmap,0,+1), - maShadowBottomRight(rShadowBitmap,+1,+1), - mbIsValid(false) -{ - if (rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height() - && (rShadowBitmap.GetSizePixel().Width()-1)%2 == 0 - && ((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1) - { - mbIsValid = true; - } - else - { - OSL_ASSERT(rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height()); - OSL_ASSERT((rShadowBitmap.GetSizePixel().Width()-1)%2 == 0); - OSL_ASSERT(((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1); - } -} - - - - -PageObjectPainter::FramePainter::~FramePainter (void) -{ -} - - - - -void PageObjectPainter::FramePainter::PaintFrame ( - OutputDevice& rDevice, - const Rectangle aBox) const -{ - // Paint the shadow. - maShadowTopLeft.PaintCorner(rDevice, aBox.TopLeft()); - maShadowTopRight.PaintCorner(rDevice, aBox.TopRight()); - maShadowBottomLeft.PaintCorner(rDevice, aBox.BottomLeft()); - maShadowBottomRight.PaintCorner(rDevice, aBox.BottomRight()); - maShadowLeft.PaintSide(rDevice, - aBox.TopLeft(), aBox.BottomLeft(), - maShadowTopLeft, maShadowBottomLeft); - maShadowRight.PaintSide(rDevice, - aBox.TopRight(), aBox.BottomRight(), - maShadowTopRight, maShadowBottomRight); - maShadowTop.PaintSide(rDevice, - aBox.TopLeft(), aBox.TopRight(), - maShadowTopLeft, maShadowTopRight); - maShadowBottom.PaintSide(rDevice, - aBox.BottomLeft(), aBox.BottomRight(), - maShadowBottomLeft, maShadowBottomRight); -} - - - - -//===== OffsetBitmap ========================================================== - -OffsetBitmap::OffsetBitmap ( - const BitmapEx& rBitmap, - const sal_Int32 nHorizontalPosition, - const sal_Int32 nVerticalPosition) - : maBitmap(), - maOffset() -{ - OSL_ASSERT(nHorizontalPosition>=-1 && nHorizontalPosition<=+1); - OSL_ASSERT(nVerticalPosition>=-1 && nVerticalPosition<=+1); - - const sal_Int32 nS (1); - const sal_Int32 nC (::std::max(0,(rBitmap.GetSizePixel().Width()-nS)/2)); - const sal_Int32 nO (nC/2); - - const Point aOrigin( - nHorizontalPosition<0 ? 0 : (nHorizontalPosition == 0 ? nC : nC+nS), - nVerticalPosition<0 ? 0 : (nVerticalPosition == 0 ? nC : nC+nS)); - const Size aSize( - nHorizontalPosition==0 ? nS : nC, - nVerticalPosition==0 ? nS : nC); - maBitmap = BitmapEx(rBitmap, aOrigin, aSize); - maOffset = Point( - nHorizontalPosition<0 ? -nO : nHorizontalPosition>0 ? -nO : 0, - nVerticalPosition<0 ? -nO : nVerticalPosition>0 ? -nO : 0); - - // Enlarge the side bitmaps so that painting the frame requires less - // paint calls. - const sal_Int32 nSideBitmapSize (64); - 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); - } -} - - - - -void OffsetBitmap::PaintCorner ( - OutputDevice& rDevice, - const Point& rAnchor) const -{ - rDevice.DrawBitmapEx(rAnchor+maOffset, maBitmap); -} - - - - -void OffsetBitmap::PaintSide ( - OutputDevice& rDevice, - const Point& rAnchor1, - const Point& rAnchor2, - const OffsetBitmap& rCornerBitmap1, - const OffsetBitmap& rCornerBitmap2) const -{ - const Size aBitmapSize (maBitmap.GetSizePixel()); - if (rAnchor1.Y() == rAnchor2.Y()) - { - // Side is horizontal. - const sal_Int32 nY (rAnchor1.Y() + maOffset.Y()); - const sal_Int32 nLeft ( - rAnchor1.X() - + rCornerBitmap1.maBitmap.GetSizePixel().Width() - + rCornerBitmap1.maOffset.X()); - const sal_Int32 nRight ( - rAnchor2.X() - + rCornerBitmap2.maOffset.X()\ - - 1); - for (sal_Int32 nX=nLeft; nX<=nRight; nX+=aBitmapSize.Width()) - rDevice.DrawBitmapEx( - Point(nX,nY), - Size(std::min(aBitmapSize.Width(), nRight-nX+1),aBitmapSize.Height()), - maBitmap); - } - else if (rAnchor1.X() == rAnchor2.X()) - { - // Side is vertical. - const sal_Int32 nX (rAnchor1.X() + maOffset.X()); - const sal_Int32 nTop ( - rAnchor1.Y() - + rCornerBitmap1.maBitmap.GetSizePixel().Height() - + rCornerBitmap1.maOffset.Y()); - const sal_Int32 nBottom ( - rAnchor2.Y() - + rCornerBitmap2.maOffset.Y() - - 1); - for (sal_Int32 nY=nTop; nY<=nBottom; nY+=aBitmapSize.Height()) - rDevice.DrawBitmapEx( - Point(nX,nY), - Size(aBitmapSize.Width(), std::min(aBitmapSize.Height(), nBottom-nY+1)), - maBitmap); - } - else - { - // Diagonal sides indicatee an error. - OSL_ASSERT(false); - } -} - - } } } // end of namespace sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index 5fa5300bd213..37b2fcb09b21 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -36,6 +36,8 @@ #include #include #include +#include +#include #define USE_SYSTEM_SELECTION_COLOR @@ -85,17 +87,18 @@ ColorData ChangeLuminance (const ColorData aColorData, const int nValue) Theme::Theme (const ::boost::shared_ptr& rpProperties) : maBackgroundColor(rpProperties->GetBackgroundColor().GetColor()), + maPageBackgroundColor(COL_WHITE), maNormalGradient(), maSelectedGradient(), maSelectedAndFocusedGradient(), maMouseOverGradient(), maRawShadow(), - maInsertionIndicator() + maRawInsertShadow() { LocalResource aResource (IMG_ICONS); maRawShadow = Image(SdResId(IMAGE_SHADOW)).GetBitmapEx(); - maInsertionIndicator = Image(SdResId(IMAGE_INSERTION_INDICATOR_SELECT)).GetBitmapEx(); + maRawInsertShadow = Image(SdResId(IMAGE_INSERT_SHADOW)).GetBitmapEx(); Update(rpProperties); } @@ -106,6 +109,8 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) void Theme::Update (const ::boost::shared_ptr& rpProperties) { maBackgroundColor = rpProperties->GetBackgroundColor().GetColor(); + maPageBackgroundColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor; + #ifdef USE_SYSTEM_SELECTION_COLOR const ColorData aSelectionColor (rpProperties->GetSelectionColor().GetColor()); @@ -151,18 +156,37 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert -::boost::shared_ptr Theme::CreateFont ( +::boost::shared_ptr Theme::GetFont ( const FontType eType, - OutputDevice& rDevice) const + const OutputDevice& rDevice) { ::boost::shared_ptr pFont; switch (eType) { case PageNumberFont: - pFont.reset(new Font(rDevice.GetFont())); + pFont.reset(new Font(Application::GetSettings().GetStyleSettings().GetAppFont())); + pFont->SetTransparent(TRUE); pFont->SetWeight(WEIGHT_BOLD); break; + + case PageCountFont: + pFont.reset(new Font(Application::GetSettings().GetStyleSettings().GetAppFont())); + pFont->SetTransparent(TRUE); + pFont->SetWeight(WEIGHT_NORMAL); + const Size aSize (pFont->GetSize()); + pFont->SetSize(Size(aSize.Width()*4/3, aSize.Height()*4/3)); + break; + } + + if (pFont) + { + // Transform the point size to pixel size. + const MapMode aFontMapMode (MAP_POINT); + const Size aFontSize (rDevice.LogicToPixel(pFont->GetSize(), aFontMapMode)); + + // Transform the font size to the logical coordinates of the device. + pFont->SetSize(rDevice.PixelToLogic(aFontSize)); } return pFont; @@ -171,7 +195,7 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert -ColorData Theme::GetColorForVisualState (const model::VisualState::State eState) const +ColorData Theme::GetColorForVisualState (const model::VisualState::State eState) { ColorData nColor; switch (eState) @@ -190,7 +214,7 @@ ColorData Theme::GetColorForVisualState (const model::VisualState::State eState) break; case model::VisualState::VS_Excluded: - nColor = 0xcc929ca2; + nColor = 0x88000000; break; case model::VisualState::VS_None: @@ -212,6 +236,8 @@ ColorData Theme::GetColor (const ColorType eType) case Background: return maBackgroundColor; + case PageBackground: + case ButtonBackground: return AirForceBlue; @@ -226,6 +252,9 @@ ColorData Theme::GetColor (const ColorType eType) case Selection: return StellaBlue; + + case PreviewBorder: + return 0x949599; } return 0; } @@ -285,12 +314,12 @@ BitmapEx Theme::GetIcon (const IconType eType) { switch (eType) { - case InsertionIndicator: - return maInsertionIndicator; - case RawShadow: return maRawShadow; + case RawInsertShadow: + return maRawInsertShadow; + default: return BitmapEx(); } diff --git a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx index aed87ce7cc82..64a35daa4295 100644 --- a/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewCacheContext.cxx @@ -28,8 +28,6 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_sd.hxx" #include "precompiled_sd.hxx" diff --git a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx index 8f8357ffb934..c09c076cd807 100644 --- a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx @@ -35,6 +35,7 @@ #include "SlideSorter.hxx" #include "SlideSorterViewShell.hxx" #include "SlsLayeredDevice.hxx" +#include "SlsFramePainter.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumeration.hxx" @@ -63,7 +64,8 @@ #include #include #include - +#include +#include #include #include @@ -74,10 +76,10 @@ using namespace ::basegfx; namespace { -#define AirForceBlue 0x5d8aa8 -#define Arsenic 0x3b444b #define Amber 0x007fff -#define Charcoal 0x36454f + +static const double gnPreviewOffsetScale = 1.0 / 8.0; + Rectangle GrowRectangle (const Rectangle& rBox, const sal_Int32 nOffset) @@ -99,46 +101,13 @@ Rectangle ConvertRectangle (const B2DRectangle& rBox) 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 { -//===== SubstitutionOverlay::InternalState ==================================== - -class ItemDescriptor -{ -public: - BitmapEx maImage; - Point maLocation; - double mnTransparency; - basegfx::B2DPolygon maShape; -}; - -class SubstitutionOverlay::InternalState -{ -public: - /** The set of items that is displayed as substitution of the selected - pages. Note that the number of items may differ from the number of - selected pages because only the selected pages in the neighborhood - of the anchor page are included. - */ - ::std::vector maItems; - - /** Bounding box of all items in maItems at their original location. - */ - Rectangle maBoundingBox; - - /** The anchor position of the substitution is the paint that, after - translation, is mapped onto the current position. - */ - Point maAnchor; - -}; - - - //===== ViewOverlay ========================================================= @@ -327,8 +296,7 @@ SubstitutionOverlay::SubstitutionOverlay ( ViewOverlay& rViewOverlay, const sal_Int32 nLayerIndex) : OverlayBase(rViewOverlay, nLayerIndex), - maPosition(0,0), - mpState(new InternalState()) + maPosition(0,0) { } @@ -342,89 +310,9 @@ SubstitutionOverlay::~SubstitutionOverlay (void) -void SubstitutionOverlay::Create ( - model::PageEnumeration& rSelection, - const Point& rAnchor, - const model::SharedPageDescriptor& rpHitDescriptor) -{ - OSL_ASSERT(mpState); - - mpState->maAnchor = rAnchor; - maPosition = rAnchor; - - ::boost::shared_ptr pPreviewCache ( - mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache()); - view::Layouter& rLayouter (mrViewOverlay.GetSlideSorter().GetView().GetLayouter()); - ::boost::shared_ptr pPageObjectLayouter ( - rLayouter.GetPageObjectLayouter()); - - const sal_Int32 nRow0 (rpHitDescriptor - ? rLayouter.GetRow(rpHitDescriptor->GetPageIndex()) - : -1); - const sal_Int32 nColumn0 (rpHitDescriptor - ? rLayouter.GetColumn(rpHitDescriptor->GetPageIndex()) - : -1); - - mpState->maItems.clear(); - while (rSelection.HasMoreElements()) - { - model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement()); - - sal_uInt8 nTransparency (128); - - // Calculate distance between current page object and the one under - // the mouse. - if (nRow0>=0 || nColumn0>=0) - { - const sal_Int32 nRow (rLayouter.GetRow(pDescriptor->GetPageIndex())); - const sal_Int32 nColumn (rLayouter.GetColumn(pDescriptor->GetPageIndex())); - - const sal_Int32 nRowDistance (abs(nRow - nRow0)); - const sal_Int32 nColumnDistance (abs(nColumn - nColumn0)); - if (nRowDistance>1 || nColumnDistance>1) - continue; - if (nRowDistance!=0 && nColumnDistance!=0) - nTransparency = 255 * mnCornerTransparency / 100; - else if (nRowDistance!=0 || nColumnDistance!=0) - nTransparency = 255 * mnSideTransparency / 100; - else - nTransparency = 255 * mnCenterTransparency / 100; - } - - const Rectangle aBox (pDescriptor->GetBoundingBox()); - mpState->maBoundingBox.Union(aBox); - basegfx::B2DRectangle aB2DBox( - aBox.Left(), - aBox.Top(), - aBox.Right(), - aBox.Bottom()); - - const Bitmap aBitmap (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap()); - AlphaMask aMask (aBitmap.GetSizePixel()); - aMask.Erase(nTransparency); - mpState->maItems.push_back(ItemDescriptor()); - ItemDescriptor& rNewItem (mpState->maItems.back()); - rNewItem.maImage = BitmapEx( - aBitmap, - aMask); - rNewItem.maLocation = pPageObjectLayouter->GetBoundingBox( - pDescriptor, - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem).TopLeft(); - rNewItem.mnTransparency = nTransparency/255.0; - rNewItem.maShape = basegfx::tools::createPolygonFromRect(aB2DBox); - } - - SetIsVisible(mpState->maItems.size() > 0); -} - - - - void SubstitutionOverlay::Clear (void) { SetIsVisible(false); - mpState.reset(new InternalState()); } @@ -432,12 +320,7 @@ void SubstitutionOverlay::Clear (void) void SubstitutionOverlay::SetAnchor (const Point& rAnchor) { - OSL_ASSERT(mpState); - if (mpState->maAnchor != rAnchor) - { - Invalidator aInvalidator (*this); - mpState->maAnchor = rAnchor; - } + (void)rAnchor; } @@ -445,11 +328,7 @@ void SubstitutionOverlay::SetAnchor (const Point& rAnchor) void SubstitutionOverlay::Move (const Point& rOffset) { - if (rOffset != Point(0,0)) - { - Invalidator aInvalidator (*this); - maPosition += rOffset; - } + (void)rOffset; } @@ -457,11 +336,7 @@ void SubstitutionOverlay::Move (const Point& rOffset) void SubstitutionOverlay::SetPosition (const Point& rPosition) { - if (maPosition != rPosition) - { - Invalidator aInvalidator (*this); - maPosition = rPosition; - } + (void)rPosition; } @@ -469,7 +344,7 @@ void SubstitutionOverlay::SetPosition (const Point& rPosition) Point SubstitutionOverlay::GetPosition (void) const { - return maPosition; + return Point(0,0); } @@ -479,30 +354,8 @@ void SubstitutionOverlay::Paint ( OutputDevice& rDevice, const Rectangle& rRepaintArea) { + (void)rDevice; (void)rRepaintArea; - OSL_ASSERT(mpState); - - if ( ! IsVisible()) - return; - - const Point aOffset (maPosition - mpState->maAnchor); - basegfx::B2DHomMatrix aTranslation; - aTranslation.translate(aOffset.X(), aOffset.Y()); - - rDevice.SetFillColor(Color(AirForceBlue)); - rDevice.SetLineColor(); - - for (::std::vector::const_iterator - iItem(mpState->maItems.begin()), - iEnd(mpState->maItems.end()); - iItem!=iEnd; - ++iItem) - { - ::basegfx::B2DPolyPolygon aPolygon (iItem->maShape); - aPolygon.transform(aTranslation); - rDevice.DrawTransparent(aPolygon, iItem->mnTransparency); - rDevice.DrawBitmapEx(iItem->maLocation+aOffset, iItem->maImage); - } } @@ -510,28 +363,7 @@ void SubstitutionOverlay::Paint ( Rectangle SubstitutionOverlay::GetBoundingBox (void) const { - OSL_ASSERT(mpState); - - Rectangle aBox (mpState->maBoundingBox); - aBox.Move(maPosition.X() - mpState->maAnchor.X(), maPosition.Y() - mpState->maAnchor.Y()); - return aBox; -} - - - - -SubstitutionOverlay::SharedInternalState SubstitutionOverlay::GetInternalState (void) const -{ - return mpState; -} - - - - -void SubstitutionOverlay::SetInternalState (const SharedInternalState& rpState) -{ - if (rpState) - mpState = rpState; + return Rectangle(); } @@ -622,12 +454,212 @@ Rectangle SelectionRectangleOverlay::GetBoundingBox (void) const //===== InsertionIndicatorOverlay =========================================== +const static sal_Int32 gnShadowBorder = 3; + InsertionIndicatorOverlay::InsertionIndicatorOverlay ( ViewOverlay& rViewOverlay, const sal_Int32 nLayerIndex) : OverlayBase (rViewOverlay, nLayerIndex), maLocation(), - maIcon(rViewOverlay.GetSlideSorter().GetTheme()->GetIcon(Theme::InsertionIndicator)) + 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) { } @@ -673,5 +705,14 @@ Rectangle InsertionIndicatorOverlay::GetBoundingBox (void) const +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 d7837b1f3189..6e0d0cc0761f 100644 --- a/sd/source/ui/slidesorter/view/makefile.mk +++ b/sd/source/ui/slidesorter/view/makefile.mk @@ -55,6 +55,7 @@ SRC1FILES = \ SLOFILES = \ $(SLO)$/SlideSorterView.obj \ $(SLO)$/SlsFontProvider.obj \ + $(SLO)$/SlsFramePainter.obj \ $(SLO)$/SlsInsertAnimator.obj \ $(SLO)$/SlsLayeredDevice.obj \ $(SLO)$/SlsLayouter.obj \ -- cgit v1.2.3 From 6be133ca030d0e53c2c36de64a6f3b0d7f5a827d Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Tue, 2 Mar 2010 16:46:27 +0100 Subject: renaissance1: #i107215# Removed anonymous namespace from FramePainter header. --- sd/source/ui/slidesorter/view/SlsFramePainter.cxx | 8 +- sd/source/ui/slidesorter/view/SlsFramePainter.hxx | 116 +++++++++------------- 2 files changed, 49 insertions(+), 75 deletions(-) diff --git a/sd/source/ui/slidesorter/view/SlsFramePainter.cxx b/sd/source/ui/slidesorter/view/SlsFramePainter.cxx index d8a147209922..a037f2c5f8c2 100644 --- a/sd/source/ui/slidesorter/view/SlsFramePainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsFramePainter.cxx @@ -105,9 +105,9 @@ void FramePainter::PaintFrame ( -//===== OffsetBitmap ========================================================== +//===== FramePainter::OffsetBitmap ============================================ -OffsetBitmap::OffsetBitmap ( +FramePainter::OffsetBitmap::OffsetBitmap ( const BitmapEx& rBitmap, const sal_Int32 nHorizontalPosition, const sal_Int32 nVerticalPosition) @@ -150,7 +150,7 @@ OffsetBitmap::OffsetBitmap ( -void OffsetBitmap::PaintCorner ( +void FramePainter::OffsetBitmap::PaintCorner ( OutputDevice& rDevice, const Point& rAnchor) const { @@ -161,7 +161,7 @@ void OffsetBitmap::PaintCorner ( -void OffsetBitmap::PaintSide ( +void FramePainter::OffsetBitmap::PaintSide ( OutputDevice& rDevice, const Point& rAnchor1, const Point& rAnchor2, diff --git a/sd/source/ui/slidesorter/view/SlsFramePainter.hxx b/sd/source/ui/slidesorter/view/SlsFramePainter.hxx index 9df2e4183573..7d0aa7a94e70 100644 --- a/sd/source/ui/slidesorter/view/SlsFramePainter.hxx +++ b/sd/source/ui/slidesorter/view/SlsFramePainter.hxx @@ -41,77 +41,6 @@ namespace sd { namespace slidesorter { namespace view { -namespace { - -/** Bitmap with offset that is used when the bitmap is painted. The bitmap -*/ -class OffsetBitmap -{ -public: - /** Create one of the eight shadow bitmaps from one that combines them - all. This larger bitmap is expected to have dimension NxN with - N=1+2*M. Of this larger bitmap there are created four corner - bitmaps of size 2*M x 2*M and four side bitmaps of sizes 1xM (top - and bottom) and Mx1 (left and right). The corner bitmaps have each - one quadrant of size MxM that is painted under the interior of the - frame. - @param rBitmap - The larger bitmap of which the eight shadow bitmaps are cut out - from. - @param nHorizontalPosition - Valid values are -1 (left), 0 (center), and +1 (right). - @param nVerticalPosition - Valid values are -1 (top), 0 (center), and +1 (bottom). - */ - OffsetBitmap ( - const BitmapEx& rBitmap, - const sal_Int32 nHorizontalPosition, - const sal_Int32 nVerticalPosition); - - /** Create bitmap and offset from the given values. Corner bitmaps are - constructed with the given width and height. Side bitmaps are - stretched along one axis to reduce the paint calls when the sides of - a frame are painted. - @param rBitmap - The larger bitmap that contains the four corner bitmaps and the - four side bitmaps. - */ - void SetBitmap ( - const BitmapEx& rBitmap, - const sal_Int32 nOriginX, - const sal_Int32 nOriginY, - const sal_Int32 nWidth, - const sal_Int32 nHeight, - const sal_Int32 nOffsetX, - const sal_Int32 nOffsetY); - - /** Use the given device to paint the bitmap at the location that is the - sum of the given anchor and the internal offset. - */ - void PaintCorner (OutputDevice& rDevice, const Point& rAnchor) const; - - /** Use the given device to paint the bitmap stretched between the two - given locations. Offsets of the adjacent corner bitmaps and the - offset of the side bitmap are used to determine the area that is to - be filled with the side bitmap. - */ - void PaintSide ( - OutputDevice& rDevice, - const Point& rAnchor1, - const Point& rAnchor2, - const OffsetBitmap& rCornerBitmap1, - const OffsetBitmap& rCornerBitmap2) const; - -private: - BitmapEx maBitmap; - Point maOffset; -}; - -} // end of anonymous namespace - - - - class FramePainter { public: @@ -120,6 +49,51 @@ public: void PaintFrame (OutputDevice&rDevice, const Rectangle aBox) const; private: + /** Bitmap with offset that is used when the bitmap is painted. The bitmap + */ + class OffsetBitmap { + public: + /** Create one of the eight shadow bitmaps from one that combines + them all. This larger bitmap is expected to have dimension NxN + with N=1+2*M. Of this larger bitmap there are created four + corner bitmaps of size 2*M x 2*M and four side bitmaps of sizes + 1xM (top and bottom) and Mx1 (left and right). The corner + bitmaps have each one quadrant of size MxM that is painted under + the interior of the frame. + @param rBitmap + The larger bitmap of which the eight shadow bitmaps are cut + out from. + @param nHorizontalPosition + Valid values are -1 (left), 0 (center), and +1 (right). + @param nVerticalPosition + Valid values are -1 (top), 0 (center), and +1 (bottom). + */ + OffsetBitmap ( + const BitmapEx& rBitmap, + const sal_Int32 nHorizontalPosition, + const sal_Int32 nVerticalPosition); + + /** Use the given device to paint the bitmap at the location that is + the sum of the given anchor and the internal offset. + */ + void PaintCorner (OutputDevice& rDevice, const Point& rAnchor) const; + + /** Use the given device to paint the bitmap stretched between the + two given locations. Offsets of the adjacent corner bitmaps and + the offset of the side bitmap are used to determine the area + that is to be filled with the side bitmap. + */ + void PaintSide ( + OutputDevice& rDevice, + const Point& rAnchor1, + const Point& rAnchor2, + const OffsetBitmap& rCornerBitmap1, + const OffsetBitmap& rCornerBitmap2) const; + + private: + BitmapEx maBitmap; + Point maOffset; + }; OffsetBitmap maShadowTopLeft; OffsetBitmap maShadowTop; OffsetBitmap maShadowTopRight; -- cgit v1.2.3 From c87f10322a175f7d45ee20db236b69befa64d277 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 3 Mar 2010 13:21:37 +0100 Subject: renaissance1: #i107215# Obeying application background color. --- sd/source/ui/slidesorter/controller/SlsListener.cxx | 21 ++++++++++++++------- .../ui/slidesorter/inc/view/SlideSorterView.hxx | 4 ++++ sd/source/ui/slidesorter/view/SlideSorterView.cxx | 18 ++++++++++++++++-- sd/source/ui/tools/PreviewRenderer.cxx | 17 +++++++++++------ 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 34154fb36e3c..38348a4fdb6e 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -42,6 +42,7 @@ #include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" #include "cache/SlsPageCache.hxx" +#include "cache/SlsPageCacheManager.hxx" #include "drawdoc.hxx" #include "DrawDocShell.hxx" @@ -634,14 +635,20 @@ void Listener::HandleShapeModification (const SdrPage* pPage) model::PageEnumeration aAllPages ( model::PageEnumerationProvider::CreateAllPagesEnumeration( mrSlideSorter.GetModel())); - while (aAllPages.HasMoreElements()) + ::boost::shared_ptr pCacheManager ( + cache::PageCacheManager::Instance()); + if (pCacheManager) { - model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); - SdrPage* pCandidate = pDescriptor->GetPage(); - if (pCandidate!=NULL && &pCandidate->TRG_GetMasterPage() == pPage) - mrSlideSorter.GetView().GetPreviewCache()->InvalidatePreviewBitmap( - pCandidate, - true); + while (aAllPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aAllPages.GetNextElement()); + SdrPage* pCandidate = pDescriptor->GetPage(); + if (pCandidate!=NULL && &pCandidate->TRG_GetMasterPage() == pPage) + pCacheManager->InvalidatePreviewBitmap( + mrSlideSorter.GetModel().GetDocument()->getUnoModel(), + pCandidate); + mrSlideSorter.GetView().GetPreviewCache()->RequestPreviewBitmap(pCandidate); + } } } else diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 997aa17ebf6c..0b270ff329b3 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -146,6 +146,10 @@ public: sdr::contact::ViewObjectContactRedirector* pRedirector = NULL); void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea); + virtual void ConfigurationChanged ( + utl::ConfigurationBroadcaster* pBroadcaster, + sal_uInt32 nHint); + void Layout (void); /** This tells the view that it has to re-determine the visibility of the page objects before painting them the next time. diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 34f0aee84d13..22e3c05eff6c 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -322,12 +322,12 @@ TYPEINIT1(SlideSorterView, ::sd::View); SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) : ::sd::View ( rSlideSorter.GetModel().GetDocument(), - NULL, + rSlideSorter.GetContentWindow().get(), rSlideSorter.GetViewShell()), mrSlideSorter(rSlideSorter), mrModel(rSlideSorter.GetModel()), mbIsDisposed(false), - mpLayouter (new Layouter (rSlideSorter.GetContentWindow())), + mpLayouter (new Layouter(rSlideSorter.GetContentWindow())), mbPageObjectVisibilitiesValid (false), mpPreviewCache(), mpLayeredDevice(new LayeredDevice(rSlideSorter.GetContentWindow())), @@ -886,6 +886,20 @@ void SlideSorterView::Paint ( +void SlideSorterView::ConfigurationChanged ( + utl::ConfigurationBroadcaster* pBroadcaster, + sal_uInt32 nHint) +{ + // Some changes of the configuration (some of the colors for example) + // may affect the previews. Throw away the old ones and create new ones. + cache::PageCacheManager::Instance()->InvalidateAllCaches(); + + ::sd::View::ConfigurationChanged(pBroadcaster, nHint); +} + + + + ::boost::shared_ptr SlideSorterView::GetPreviewCache (void) { SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); diff --git a/sd/source/ui/tools/PreviewRenderer.cxx b/sd/source/ui/tools/PreviewRenderer.cxx index bf4196667ef3..7e1c2a7f9f63 100644 --- a/sd/source/ui/tools/PreviewRenderer.cxx +++ b/sd/source/ui/tools/PreviewRenderer.cxx @@ -71,7 +71,10 @@ PreviewRenderer::PreviewRenderer ( mpPreviewDevice->SetBackground(pTemplate->GetBackground()); } else - mpPreviewDevice->SetBackground(Wallpaper(COL_WHITE)); + { + mpPreviewDevice->SetBackground(Wallpaper( + Application::GetSettings().GetStyleSettings().GetWindowColor())); + } } @@ -159,8 +162,8 @@ Image PreviewRenderer::RenderSubstitution ( mpPreviewDevice->SetOutputSizePixel(rPreviewPixelSize); // Adjust contrast mode. - bool bUseContrast = Application::GetSettings().GetStyleSettings(). - GetHighContrastMode(); + const bool bUseContrast ( + Application::GetSettings().GetStyleSettings().GetHighContrastMode()); mpPreviewDevice->SetDrawMode (bUseContrast ? ViewShell::OUTPUT_DRAWMODE_CONTRAST : ViewShell::OUTPUT_DRAWMODE_COLOR); @@ -169,7 +172,7 @@ Image PreviewRenderer::RenderSubstitution ( // visible. MapMode aMapMode (mpPreviewDevice->GetMapMode()); aMapMode.SetMapUnit(MAP_100TH_MM); - double nFinalScale (25.0 * rPreviewPixelSize.Width() / 28000.0); + const double nFinalScale (25.0 * rPreviewPixelSize.Width() / 28000.0); aMapMode.SetScaleX(nFinalScale); aMapMode.SetScaleY(nFinalScale); const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0); @@ -178,7 +181,7 @@ Image PreviewRenderer::RenderSubstitution ( mpPreviewDevice->SetMapMode (aMapMode); // Clear the background. - Rectangle aPaintRectangle ( + const Rectangle aPaintRectangle ( Point(0,0), mpPreviewDevice->GetOutputSizePixel()); mpPreviewDevice->EnableMapMode(FALSE); @@ -192,7 +195,7 @@ Image PreviewRenderer::RenderSubstitution ( PaintSubstitutionText (rSubstitutionText); PaintFrame(); - Size aSize (mpPreviewDevice->GetOutputSizePixel()); + const Size aSize (mpPreviewDevice->GetOutputSizePixel()); aPreview = mpPreviewDevice->GetBitmap ( mpPreviewDevice->PixelToLogic(Point(0,0)), mpPreviewDevice->PixelToLogic(aSize)); @@ -266,6 +269,8 @@ bool PreviewRenderer::Initialize ( rOutliner.SetDefaultLanguage(pDocument->GetLanguage(EE_CHAR_LANGUAGE)); mpView->SetApplicationBackgroundColor( Color(aColorConfig.GetColorValue(svtools::APPBACKGROUND).nColor)); + mpPreviewDevice->SetBackground(Wallpaper(aPageBackgroundColor)); + mpPreviewDevice->Erase(); bSuccess = true; } -- cgit v1.2.3 From 4b83a7fe5714eb9a1d208502a18e33da35772ece Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 8 Mar 2010 11:34:08 +0100 Subject: renaissance1: #i107215# Improved handling of transferables. --- .../controller/SlideSorterController.cxx | 20 +- .../ui/slidesorter/controller/SlsAnimator.cxx | 19 + .../ui/slidesorter/controller/SlsClipboard.cxx | 33 +- .../controller/SlsCurrentSlideManager.cxx | 2 + .../controller/SlsDragAndDropContext.cxx | 247 +++++++ .../controller/SlsDragAndDropContext.hxx | 111 +++ .../controller/SlsInsertionIndicatorHandler.cxx | 108 +-- .../slidesorter/controller/SlsScrollBarManager.cxx | 1 - .../controller/SlsSelectionFunction.cxx | 744 ++++++++------------- .../slidesorter/controller/SlsSelectionManager.cxx | 20 +- .../ui/slidesorter/controller/SlsSlotManager.cxx | 4 +- .../controller/SlsSubstitutionHandler.cxx | 234 ------- .../controller/SlsSubstitutionHandler.hxx | 103 --- .../ui/slidesorter/controller/SlsTransferable.cxx | 12 +- .../ui/slidesorter/controller/SlsTransferable.hxx | 80 --- sd/source/ui/slidesorter/controller/makefile.mk | 2 +- .../ui/slidesorter/inc/controller/SlsAnimator.hxx | 6 + .../controller/SlsInsertionIndicatorHandler.hxx | 30 +- .../inc/controller/SlsSelectionFunction.hxx | 32 +- .../slidesorter/inc/controller/SlsTransferable.hxx | 73 ++ .../ui/slidesorter/inc/view/SlideSorterView.hxx | 14 +- .../ui/slidesorter/inc/view/SlsInsertAnimator.hxx | 6 +- .../inc/view/SlsInsertionIndicatorOverlay.hxx | 130 ++++ sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 103 +-- .../ui/slidesorter/inc/view/SlsViewOverlay.hxx | 293 -------- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 21 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 15 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 55 +- sd/source/ui/slidesorter/view/SlsFramePainter.cxx | 29 +- sd/source/ui/slidesorter/view/SlsFramePainter.hxx | 11 + .../ui/slidesorter/view/SlsInsertAnimator.cxx | 102 +-- .../view/SlsInsertionIndicatorOverlay.cxx | 449 +++++++++++++ sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx | 1 + sd/source/ui/slidesorter/view/SlsLayouter.cxx | 204 ++++-- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 9 +- sd/source/ui/slidesorter/view/SlsViewOverlay.cxx | 718 -------------------- sd/source/ui/slidesorter/view/makefile.mk | 4 +- sd/source/ui/toolpanel/TaskPaneViewShell.cxx | 2 +- 38 files changed, 1820 insertions(+), 2227 deletions(-) create mode 100644 sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx create mode 100644 sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx delete mode 100644 sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx delete mode 100644 sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx delete mode 100644 sd/source/ui/slidesorter/controller/SlsTransferable.hxx create mode 100644 sd/source/ui/slidesorter/inc/controller/SlsTransferable.hxx create mode 100644 sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx delete mode 100644 sd/source/ui/slidesorter/inc/view/SlsViewOverlay.hxx create mode 100644 sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx delete mode 100644 sd/source/ui/slidesorter/view/SlsViewOverlay.cxx 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/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx new file mode 100644 index 000000000000..8915addc5cba --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -0,0 +1,247 @@ +/************************************************************************* + * + * 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 "SlsDragAndDropContext.hxx" + +#include "SlideSorter.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageEnumerationProvider.hxx" +#include "view/SlideSorterView.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 { + +DragAndDropContext::DragAndDropContext ( + SlideSorter& rSlideSorter, + const Transferable* pTransferable) + : mpTargetSlideSorter(&rSlideSorter), + mnInsertionIndex(-1) +{ + ::std::vector aPages; + + // No Drag-and-Drop for master pages. + if (rSlideSorter.GetModel().GetEditMode() != EM_PAGE) + return; + + rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon( + dynamic_cast(SD_MOD()->pTransferDrag)); +} + + + + +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(); nIndex(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; + } +} + + + + +DragAndDropContext::~DragAndDropContext (void) +{ + if (mpTargetSlideSorter != NULL) + mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll(); + + Process(); + + if (mpTargetSlideSorter != NULL) + { + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); + } +} + + + + +void DragAndDropContext::Dispose (void) +{ + mnInsertionIndex = -1; +} + + + + +void DragAndDropContext::UpdatePosition ( + const Point& rMousePosition, + const InsertionIndicatorHandler::Mode eMode, + const bool bAllowAutoScroll) +{ + if (mpTargetSlideSorter == NULL) + return; + + if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly()) + return; + + // Convert window coordinates into model coordinates (we need the + // window coordinates for auto-scrolling because that remains + // 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( + &DragAndDropContext::UpdatePosition, this, rMousePosition, eMode, false)))) + { + pInsertionIndicatorHandler->UpdatePosition(aMouseModelPosition, eMode); + + // Remember the new insertion index. + mnInsertionIndex = pInsertionIndicatorHandler->GetInsertionPageIndex(); + if (pInsertionIndicatorHandler->IsInsertionTrivial(mnInsertionIndex, eMode)) + mnInsertionIndex = -1; + } +} + + + + +void DragAndDropContext::Process (void) +{ + if (mpTargetSlideSorter == NULL) + return; + + if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly()) + return; + + if (mnInsertionIndex >= 0) + { + // Tell the model to move the selected pages behind the one with the + // index mnInsertionIndex which first has to transformed into an index + // understandable by the document. + USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1; + mpTargetSlideSorter->GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex); + + ViewShell* pViewShell = mpTargetSlideSorter->GetViewShell(); + if (pViewShell != NULL) + pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE); + } +} + + + + +void DragAndDropContext::Show (void) +{ +} + + + + +void DragAndDropContext::Hide (void) +{ +} + + + + +void DragAndDropContext::SetTargetSlideSorter ( + SlideSorter* pSlideSorter, + const Point aMousePosition, + const InsertionIndicatorHandler::Mode eMode, + const bool bIsOverSourceView) +{ + if (mpTargetSlideSorter != NULL) + { + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); + } + + mpTargetSlideSorter = pSlideSorter; + + if (mpTargetSlideSorter != NULL) + { + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start( + bIsOverSourceView); + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->UpdatePosition( + aMousePosition, + eMode); + + } +} + + + +} } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx new file mode 100644 index 000000000000..a23071273202 --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * 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_SUBSTITUTION_HANDLER_HXX +#define SD_SLIDESORTER_SUBSTITUTION_HANDLER_HXX + +#include + +#include "model/SlsSharedPageDescriptor.hxx" +#include "controller/SlsInsertionIndicatorHandler.hxx" +#include + + +namespace sd { namespace slidesorter { +class SlideSorter; +} } + + + +namespace sd { namespace slidesorter { namespace controller { + +class Transferable; + + +/** 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 DragAndDropContext +{ +public: + /** Create a substitution display of the currently selected pages or, + when provided, the pages in the transferable. + */ + DragAndDropContext ( + SlideSorter& rSlideSorter, + 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 + DragAndDropContext object is destroyed. + */ + void Dispose (void); + + /** Move the substitution display by the distance the mouse has + travelled since the last call to this method or to + CreateSubstitution(). The given point becomes the new anchor. + */ + void UpdatePosition ( + const Point& rMousePosition, + const InsertionIndicatorHandler::Mode eMode, + const bool bAllowAutoScroll = true); + + void Show (void); + void Hide (void); + void SetTargetSlideSorter ( + SlideSorter* pSlideSorter = NULL, + const Point aMousePosition = Point(0,0), + const InsertionIndicatorHandler::Mode eMode = InsertionIndicatorHandler::UnknownMode, + const bool bIsOverSourceView = false); + +private: + SlideSorter* mpTargetSlideSorter; + 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); +}; + + + +} } } // end of namespace ::sd::slidesorter::controller + +#endif 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) { - if (rDescriptor.mnEventCode & BUTTON_UP) + 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)) { - view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); + // 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); + } +} - 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"); + + +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) + { + mpWindow->ReleaseMouse(); // 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/SlsSubstitutionHandler.cxx b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx deleted file mode 100644 index bd2ec1434a29..000000000000 --- a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.cxx +++ /dev/null @@ -1,234 +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: 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 - * 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 "SlsSubstitutionHandler.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 "app.hrc" -#include -#include - -namespace sd { namespace slidesorter { namespace controller { - -SubstitutionHandler::SubstitutionHandler ( - SlideSorter& rSlideSorter, - const model::SharedPageDescriptor& rpHitDescriptor, - const Point& rMouseModelPosition) - : mpTargetSlideSorter(&rSlideSorter), - mpHitDescriptor(rpHitDescriptor), - mnInsertionIndex(-1) -{ - // No Drag-and-Drop for master pages. - if (rSlideSorter.GetModel().GetEditMode() != EM_PAGE) - return; - - view::ViewOverlay& rOverlay (rSlideSorter.GetView().GetOverlay()); - - if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible()) - { - // Show a new substitution for the selected page objects. - model::PageEnumeration aSelectedPages( - model::PageEnumerationProvider::CreateSelectedPagesEnumeration( - rSlideSorter.GetModel())); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); - rSlideSorter.GetController().GetInsertionIndicatorHandler()->Start( - rMouseModelPosition, - InsertionIndicatorHandler::MoveMode, - true); - rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon( - aSelectedPages); - } -} - - - - -SubstitutionHandler::~SubstitutionHandler (void) -{ - if (mpTargetSlideSorter != NULL) - mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll(); - - Process(); - - 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) -{ - mnInsertionIndex = -1; -} - - - - -void SubstitutionHandler::UpdatePosition ( - const Point& rMousePosition, - const InsertionIndicatorHandler::Mode eMode, - const bool bAllowAutoScroll) -{ - if (mpTargetSlideSorter == NULL) - return; - - if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly()) - return; - - // Convert window coordinates into model coordinates (we need the - // window coordinates for auto-scrolling because that remains - // constant while scrolling.) - SharedSdWindow pWindow (mpTargetSlideSorter->GetContentWindow()); - const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); - - if ( ! (bAllowAutoScroll - && mpTargetSlideSorter->GetController().GetScrollBarManager().AutoScroll( - rMousePosition, - ::boost::bind( - &SubstitutionHandler::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); - - // Remember the new insertion index. - if (mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial(eMode)) - mnInsertionIndex = -1; - else - mnInsertionIndex = mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler() - ->GetInsertionPageIndex(); - } -} - - - - -void SubstitutionHandler::Process (void) -{ - if (mpTargetSlideSorter == NULL) - return; - - if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly()) - return; - - if (mnInsertionIndex >= 0) - { - // Tell the model to move the selected pages behind the one with the - // index mnInsertionIndex which first has to transformed into an index - // understandable by the document. - USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1; - mpTargetSlideSorter->GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex); - - ViewShell* pViewShell = mpTargetSlideSorter->GetViewShell(); - if (pViewShell != NULL) - pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE); - } -} - - - - -void SubstitutionHandler::Show (void) -{ - if (mpTargetSlideSorter != NULL) - { - view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(true); - } -} - - - - -void SubstitutionHandler::Hide (void) -{ - if (mpTargetSlideSorter != NULL) - { - view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay()); - rOverlay.GetSubstitutionOverlay()->SetIsVisible(false); - } -} - - - - -void SubstitutionHandler::SetTargetSlideSorter ( - SlideSorter* pSlideSorter, - const Point aMousePosition, - const InsertionIndicatorHandler::Mode eMode, - const bool bIsOverSourceView) -{ - if (mpTargetSlideSorter != NULL) - { - mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); - } - - mpTargetSlideSorter = pSlideSorter; - - if (mpTargetSlideSorter != NULL) - { - mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start( - aMousePosition, - eMode, - bIsOverSourceView); - } -} - - - -} } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx b/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx deleted file mode 100644 index 56bcf08fd7db..000000000000 --- a/sd/source/ui/slidesorter/controller/SlsSubstitutionHandler.hxx +++ /dev/null @@ -1,103 +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: 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 - * 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_SUBSTITUTION_HANDLER_HXX -#define SD_SLIDESORTER_SUBSTITUTION_HANDLER_HXX - -#include - -#include "model/SlsSharedPageDescriptor.hxx" -#include "view/SlsViewOverlay.hxx" -#include "controller/SlsInsertionIndicatorHandler.hxx" - -namespace sd { namespace slidesorter { -class SlideSorter; -} } - - - -namespace sd { namespace slidesorter { namespace controller { - - -/** 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. -*/ -class SubstitutionHandler -{ -public: - /** Create a substitution display of the currently selected pages and - use the given position as the anchor point. - */ - SubstitutionHandler ( - SlideSorter& rSlideSorter, - const model::SharedPageDescriptor& rpHitDescriptor, - const Point& rMouseModelPosition); - ~SubstitutionHandler (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. - */ - void Dispose (void); - - /** Move the substitution display by the distance the mouse has - travelled since the last call to this method or to - CreateSubstitution(). The given point becomes the new anchor. - */ - void UpdatePosition ( - const Point& rMousePosition, - const InsertionIndicatorHandler::Mode eMode, - const bool bAllowAutoScroll = true); - - void Show (void); - void Hide (void); - void SetTargetSlideSorter ( - SlideSorter* pSlideSorter = NULL, - const Point aMousePosition = Point(0,0), - const InsertionIndicatorHandler::Mode eMode = InsertionIndicatorHandler::UnknownMode, - const bool bIsOverSourceView = false); - -private: - SlideSorter* mpTargetSlideSorter; - model::SharedPageDescriptor mpHitDescriptor; - sal_Int32 mnInsertionIndex; - - /** Move the substitution display of the currently selected pages. - */ - void Process (void); -}; - - - -} } } // end of namespace ::sd::slidesorter::controller - -#endif 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/SlsTransferable.hxx b/sd/source/ui/slidesorter/controller/SlsTransferable.hxx deleted file mode 100644 index 3929e71176ff..000000000000 --- a/sd/source/ui/slidesorter/controller/SlsTransferable.hxx +++ /dev/null @@ -1,80 +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: SlsTransferable.hxx,v $ - * $Revision: 1.5 $ - * - * 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_TRANSFERABLE_HXX -#define SD_SLIDESORTER_TRANSFERABLE_HXX - -#include "sdxfer.hxx" - -class SdDrawDocument; -namespace sd -{ - class pWorkView; - 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. -*/ -class Transferable - : public SdTransferable -{ -public: - Transferable ( - SdDrawDocument* pSrcDoc, - ::sd::View* pWorkView, - BOOL bInitOnGetData, - SlideSorterViewShell* pViewShell, - const ::boost::shared_ptr& rpSubstitutionHandler); - - virtual ~Transferable (void); - - virtual void DragFinished (sal_Int8 nDropAction); - - ::boost::shared_ptr GetSubstitutionHandler (void) const; - -private: - SlideSorterViewShell* mpViewShell; - ::boost::shared_ptr mpSubstitutionHandler; - - virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); -}; - -} } } // end of namespace ::sd::slidesorter::controller - -#endif 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); + + /** Deactivate the insertion marker. + */ + void End (void); - void UpdateIndicatorIcon (model::PageEnumeration& rEnumeration); - void UpdateIndicatorIcon (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/inc/controller/SlsTransferable.hxx b/sd/source/ui/slidesorter/inc/controller/SlsTransferable.hxx new file mode 100644 index 000000000000..51a804c92024 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/controller/SlsTransferable.hxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * 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: SlsTransferable.hxx,v $ + * $Revision: 1.5 $ + * + * 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_TRANSFERABLE_HXX +#define SD_SLIDESORTER_TRANSFERABLE_HXX + +#include "sdxfer.hxx" + +class SdDrawDocument; +namespace sd { namespace slidesorter { +class SlideSorterViewShell; +} } + +namespace sd { namespace slidesorter { namespace controller { + + +/** This class exists to have DragFinished call the correct object: the + SlideSorterViewShell instead of the old SlideView. +*/ +class Transferable + : public SdTransferable +{ +public: + Transferable ( + SdDrawDocument* pSrcDoc, + ::sd::View* pWorkView, + BOOL bInitOnGetData, + SlideSorterViewShell* pViewShell, + const ::std::vector& rRepresentatives); + + virtual ~Transferable (void); + + virtual void DragFinished (sal_Int8 nDropAction); + + const ::std::vector& GetRepresentatives (void) const; + +private: + SlideSorterViewShell* mpViewShell; + const ::std::vector maRepresentatives; + + virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); +}; + +} } } // end of namespace ::sd::slidesorter::controller + +#endif 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. - @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. - */ - 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. + /** 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 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. + @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. */ - 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 -- cgit v1.2.3 From eb7f569c3a52b9810156798a4915701257c3800f Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 8 Mar 2010 13:19:28 +0100 Subject: renaissance1: #i107215# Improved handling of transferables. --- .../ui/slidesorter/controller/SlsDragAndDropContext.cxx | 4 +--- .../ui/slidesorter/controller/SlsDragAndDropContext.hxx | 7 +------ sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx | 12 ++++++------ 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx index 8915addc5cba..2d0d79483d19 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -48,9 +48,7 @@ namespace sd { namespace slidesorter { namespace controller { -DragAndDropContext::DragAndDropContext ( - SlideSorter& rSlideSorter, - const Transferable* pTransferable) +DragAndDropContext::DragAndDropContext (SlideSorter& rSlideSorter) : mpTargetSlideSorter(&rSlideSorter), mnInsertionIndex(-1) { diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx index a23071273202..26df6f2c04a1 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx @@ -43,9 +43,6 @@ class SlideSorter; namespace sd { namespace slidesorter { namespace controller { -class Transferable; - - /** 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. @@ -56,9 +53,7 @@ public: /** Create a substitution display of the currently selected pages or, when provided, the pages in the transferable. */ - DragAndDropContext ( - SlideSorter& rSlideSorter, - const Transferable* pTransferable); + DragAndDropContext (SlideSorter& rSlideSorter); ~DragAndDropContext (void); /** Call this method (for example as reaction to ESC key press) to avoid diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 209fd986af16..ea4f10e14107 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -108,6 +108,7 @@ static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIF } // end of anonymous namespace +#define ONLY_PREVIEW_TRIGGERS_MOUSE_OVER namespace sd { namespace slidesorter { namespace controller { @@ -339,13 +340,12 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) } else if ( ! mpDragAndDropContext) { - const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; // Connect the substitution handler to this selection function. - mpDragAndDropContext.reset(new DragAndDropContext( - mrSlideSorter, - dynamic_cast(pDragTransferable))); + mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter)); + const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; mrController.GetInsertionIndicatorHandler()->Start( - pDragTransferable->GetView()==&mrSlideSorter.GetView()); + pDragTransferable != NULL + && pDragTransferable->GetView()==&mrSlideSorter.GetView()); mpDragAndDropContext->UpdatePosition( rEvent.maPosPixel, InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction)); @@ -698,7 +698,7 @@ void SelectionFunction::StartDrag ( if ( ! mpDragAndDropContext) { - mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter, NULL)); + mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter)); mrController.GetInsertionIndicatorHandler()->Start(true); } mpDragAndDropContext->UpdatePosition(rMousePosition, eMode); -- cgit v1.2.3 From 9c1e4f81d79eb618e1f9b088ec08faffd539e81f Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 8 Mar 2010 18:29:19 +0100 Subject: renaissance1: #i107215# Fixed drag-and-drop. --- .../controller/SlideSorterController.cxx | 16 +++++ .../ui/slidesorter/controller/SlsClipboard.cxx | 16 ++--- .../controller/SlsDragAndDropContext.cxx | 1 - .../controller/SlsInsertionIndicatorHandler.cxx | 18 +++-- .../ui/slidesorter/controller/SlsProperties.cxx | 19 ++++- .../controller/SlsSelectionFunction.cxx | 83 ++++++++-------------- .../inc/controller/SlideSorterController.hxx | 3 +- .../slidesorter/inc/controller/SlsProperties.hxx | 8 +++ .../inc/controller/SlsSelectionFunction.hxx | 4 +- 9 files changed, 92 insertions(+), 76 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index c32e814f8768..e5a78bd1caac 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -230,8 +230,24 @@ model::SharedPageDescriptor SlideSorterController::GetPageAt ( sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aPixelPosition)); model::SharedPageDescriptor pDescriptorAtPoint; if (nHitPageIndex >= 0) + { pDescriptorAtPoint = mrModel.GetPageDescriptor(nHitPageIndex); + if (pDescriptorAtPoint + && mrSlideSorter.GetProperties()->IsOnlyPreviewTriggersMouseOver() + && ! pDescriptorAtPoint->HasState(PageDescriptor::ST_Selected)) + { + // Make sure that the mouse is over the preview area. + if ( ! mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox( + pDescriptorAtPoint, + view::PageObjectLayouter::Preview, + view::PageObjectLayouter::WindowCoordinateSystem).IsInside(aPixelPosition)) + { + pDescriptorAtPoint.reset(); + } + } + } + return pDescriptorAtPoint; } diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 453c1e69e81c..3213a3ce1bdc 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -528,13 +528,6 @@ sal_Int8 Clipboard::AcceptDrop ( sal_Int8 nResult = DND_ACTION_NONE; const Clipboard::DropType eDropType (IsDropAccepted()); - if (eDropType != DT_NONE) - { - FunctionReference rFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction()); - SelectionFunction* pSelectionFunction = dynamic_cast(rFunction.get()); - if (pSelectionFunction != NULL) - pSelectionFunction->MouseDragged(rEvent); - } switch (eDropType) { @@ -559,9 +552,10 @@ sal_Int8 Clipboard::AcceptDrop ( // Show the insertion marker and the substitution for a drop. Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel); - mrController.GetInsertionIndicatorHandler()->UpdatePosition( - aPosition, - rEvent.maDragEvent.DropAction); + SelectionFunction* pSelectionFunction = dynamic_cast( + mrSlideSorter.GetViewShell()->GetCurrentFunction().get()); + if (pSelectionFunction != NULL) + pSelectionFunction->MouseDragged(rEvent, nResult); // Scroll the window when the mouse reaches the window border. // mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel); @@ -617,7 +611,6 @@ sal_Int8 Clipboard::ExecuteDrop ( aEventModelPosition, rEvent.mnAction); USHORT nIndex = DetermineInsertPosition(*pDragTransferable); - mrController.GetInsertionIndicatorHandler()->End(); if (bContinue) { @@ -650,6 +643,7 @@ sal_Int8 Clipboard::ExecuteDrop ( nResult = rEvent.mnAction; } } + mrController.GetInsertionIndicatorHandler()->End(); // Notify the receiving selection function that drag-and-drop is // finished and the substitution handler can be released. diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx index 2d0d79483d19..21b3f3f5b942 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -241,5 +241,4 @@ void DragAndDropContext::SetTargetSlideSorter ( } - } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index d29748d01ae1..6b6c8916ebf7 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -98,6 +98,9 @@ void InsertionIndicatorHandler::End (void) GetInsertAnimator()->Reset(); mbIsActive = false; + maInsertPosition = view::InsertPosition(); + meMode = UnknownMode; + mpInsertionIndicatorOverlay->Hide(); } @@ -116,12 +119,12 @@ void InsertionIndicatorHandler::UpdateIndicatorIcon (const Transferable* pTransf InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction ( const sal_Int8 nDndAction) { - switch (nDndAction & (ACTION_COPY | ACTION_MOVE | ACTION_LINK)) - { - case ACTION_COPY: return CopyMode; - case ACTION_MOVE: return MoveMode; - default: return UnknownMode; - } + if ((nDndAction & ACTION_MOVE) != 0) + return MoveMode; + else if ((nDndAction & ACTION_COPY) != 0) + return CopyMode; + else + return UnknownMode; } @@ -184,7 +187,8 @@ void InsertionIndicatorHandler::SetPosition ( if (maInsertPosition != aInsertPosition || meMode != eMode - || ! mpInsertionIndicatorOverlay->IsVisible()) + // || ! mpInsertionIndicatorOverlay->IsVisible() + ) { maInsertPosition = aInsertPosition; meMode = eMode; diff --git a/sd/source/ui/slidesorter/controller/SlsProperties.cxx b/sd/source/ui/slidesorter/controller/SlsProperties.cxx index 48cc8a705cde..81aa9f0f3160 100644 --- a/sd/source/ui/slidesorter/controller/SlsProperties.cxx +++ b/sd/source/ui/slidesorter/controller/SlsProperties.cxx @@ -47,7 +47,8 @@ Properties::Properties (void) maTextColor(Application::GetSettings().GetStyleSettings().GetActiveTextColor()), maSelectionColor(Application::GetSettings().GetStyleSettings().GetHighlightColor()), maHighlightColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()), - mbIsUIReadOnly(false) + mbIsUIReadOnly(false), + mbIsOnlyPreviewTriggersMouseOver(true) { } @@ -245,4 +246,20 @@ void Properties::SetUIReadOnly (const bool bIsUIReadOnly) } + + +bool Properties::IsOnlyPreviewTriggersMouseOver (void) const +{ + return mbIsOnlyPreviewTriggersMouseOver; +} + + + + +void Properties::SetOnlyPreviewTriggersMouseOver (const bool bFlag) +{ + mbIsOnlyPreviewTriggersMouseOver = bFlag; +} + + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index ea4f10e14107..02d484e7223e 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -194,14 +194,11 @@ public: EventDescriptor ( sal_uInt32 nEventType, - const MouseEvent& rEvent, + const Point& rMousePosition, SlideSorter& rSlideSorter); EventDescriptor ( const KeyEvent& rEvent, SlideSorter& rSlideSorter); - EventDescriptor ( - const AcceptDropEvent& rEvent, - SlideSorter& rSlideSorter); EventDescriptor (const EventDescriptor& rDescriptor); void SetDragMode (const InsertionIndicatorHandler::Mode eMode); @@ -262,7 +259,7 @@ BOOL SelectionFunction::MouseButtonDown (const MouseEvent& rEvent) aMDPos = rEvent.GetPosPixel(); mbProcessingMouseButtonDown = true; - mpWindow->CaptureMouse(); + // mpWindow->CaptureMouse(); ProcessMouseEvent(BUTTON_DOWN, rEvent); @@ -312,9 +309,6 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent) { mrController.GetScrollBarManager().StopAutoScroll (); - // #95491# remember button state for creation of own MouseEvents - SetMouseButtonCode (rEvent.GetButtons()); - ProcessMouseEvent(BUTTON_UP, rEvent); mbProcessingMouseButtonDown = false; @@ -326,8 +320,12 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent) -void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) +void SelectionFunction::MouseDragged ( + const AcceptDropEvent& rEvent, + const sal_Int8 nDragAction) { + const InsertionIndicatorHandler::Mode eMode ( + InsertionIndicatorHandler::GetModeFromDndAction(nDragAction));//rEvent.mnAction)); if (rEvent.mbLeaving) { if (mpDragAndDropContext) @@ -346,14 +344,12 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) mrController.GetInsertionIndicatorHandler()->Start( pDragTransferable != NULL && pDragTransferable->GetView()==&mrSlideSorter.GetView()); - mpDragAndDropContext->UpdatePosition( - rEvent.maPosPixel, - InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction)); + mpDragAndDropContext->UpdatePosition(rEvent.maPosPixel, eMode); } // 1. Compute some frequently used values relating to the event. ::std::auto_ptr pEventDescriptor ( - new EventDescriptor(rEvent, mrSlideSorter)); + new EventDescriptor(MOUSE_DRAG, rEvent.maPosPixel, mrSlideSorter)); // 2. Detect whether we are dragging pages or dragging a selection rectangle. if (mpDragAndDropContext) @@ -362,8 +358,7 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) pEventDescriptor->mnEventCode |= MULTI_SELECTOR; // 3. Set the drag mode. - pEventDescriptor->SetDragMode( - InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction)); + pEventDescriptor->SetDragMode(eMode); // 4. Process the event. if ( ! ProcessEvent(*pEventDescriptor)) @@ -687,6 +682,14 @@ void SelectionFunction::StartDrag ( const Point& rMousePosition, const InsertionIndicatorHandler::Mode eMode) { + // Do not start a drag-and-drop operation when one is already active. + // (when dragging pages from one document into another, pressing a + // modifier key can trigger a MouseMotion event in the originating + // window (focus still in there). Together with the mouse button pressed + // (drag-and-drop is active) this triggers the start of drag-and-drop.) + if (SD_MOD()->pTransferDrag != NULL) + return; + if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { if (mrSlideSorter.GetViewShell() != NULL) @@ -817,7 +820,7 @@ void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEve // 1. Compute some frequently used values relating to the event. ::std::auto_ptr pEventDescriptor ( - new EventDescriptor(nEventType, rEvent, mrSlideSorter)); + new EventDescriptor(nEventType, rEvent.GetPosPixel(), mrSlideSorter)); // 2. Compute a numerical code that describes the event and that is used // for fast look-up of the associated reaction. @@ -1016,11 +1019,9 @@ void SelectionFunction::ProcessEventWhileDragActive (EventDescriptor& rDescripto // 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); + // mpDragAndDropContext->UpdatePosition( + // rDescriptor.maMousePosition, + // rDescriptor.meDragMode); } else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG)) { @@ -1176,6 +1177,10 @@ void SelectionFunction::ProcessMouseMotionEvent (const EventDescriptor& rDescrip { switch (rDescriptor.mnEventCode) { + case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE): + SetCurrentPage(rDescriptor.mpHitDescriptor); + // Fallthrough + // A mouse motion without visible substitution starts that. case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE): StartDrag( @@ -1305,19 +1310,16 @@ void SelectionFunction::ProcessButtonClick ( SelectionFunction::EventDescriptor::EventDescriptor ( sal_uInt32 nEventType, - const MouseEvent& rEvent, + const Point& rMousePosition, SlideSorter& rSlideSorter) - : maMousePosition(), + : maMousePosition(rMousePosition), maMouseModelPosition(), mpHitDescriptor(), mpHitPage(), mnEventCode(nEventType), mnButtonIndex(-1) { - SharedSdWindow pWindow (rSlideSorter.GetContentWindow()); - - maMousePosition = rEvent.GetPosPixel(); - maMouseModelPosition = pWindow->PixelToLogic(maMousePosition); + maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition); mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition); if (mpHitDescriptor) { @@ -1359,33 +1361,6 @@ SelectionFunction::EventDescriptor::EventDescriptor ( -SelectionFunction::EventDescriptor::EventDescriptor ( - const AcceptDropEvent& rEvent, - SlideSorter& rSlideSorter) - : maMousePosition(rEvent.maPosPixel), - maMouseModelPosition(), - mpHitDescriptor(), - mpHitPage(), - mnEventCode(MOUSE_DRAG), - mnButtonIndex(-1), - meDragMode(InsertionIndicatorHandler::MoveMode), - mbMakeSelectionVisible(true) -{ - SharedSdWindow pWindow (rSlideSorter.GetContentWindow()); - - maMouseModelPosition = pWindow->PixelToLogic(maMousePosition); - model::SharedPageDescriptor pHitDescriptor ( - rSlideSorter.GetController().GetPageAt(maMousePosition)); - if (pHitDescriptor.get() != NULL) - { - mpHitDescriptor = pHitDescriptor; - mpHitPage = pHitDescriptor->GetPage(); - } -} - - - - SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDescriptor) : maMousePosition(rDescriptor.maMousePosition), maMouseModelPosition(rDescriptor.maMouseModelPosition), diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index ef5b07d8d670..db72a7e54deb 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -114,7 +114,8 @@ public: SlideSorter& GetSlideSorter (void) const; /** Return the descriptor of the page that is rendered under the - given position. + given position. This takes the IsOnlyPreviewTriggersMouseOver + property into account. @return Returns a pointer to a page descriptor instead of a reference because when no page is found at the position diff --git a/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx index 15aa980aaca5..d850d1779c51 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx @@ -117,6 +117,13 @@ public: bool IsUIReadOnly (void) const; void SetUIReadOnly (const bool bIsUIReadOnly); + /** The mouse over effect (and whether a mouse motion starts a multi + selection or a drag-and-drop) can be triggered by just the preview + area or the whole page object area. + */ + bool IsOnlyPreviewTriggersMouseOver (void) const; + void SetOnlyPreviewTriggersMouseOver (const bool bFlag); + private: bool mbIsHighlightCurrentSlide; bool mbIsShowSelection; @@ -129,6 +136,7 @@ private: Color maSelectionColor; Color maHighlightColor; bool mbIsUIReadOnly; + bool mbIsOnlyPreviewTriggersMouseOver; }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index 8a354697ceff..71315adbbb1c 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -94,7 +94,9 @@ public: */ virtual bool cancel(); - void MouseDragged (const AcceptDropEvent& rEvent); + void MouseDragged ( + const AcceptDropEvent& rEvent, + const sal_Int8 nDragAction); /** Turn of substitution display and insertion indicator. */ -- cgit v1.2.3 From 538a067d216e87d2f01b144eb7e711ce0dca93b4 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 10 Mar 2010 17:33:53 +0100 Subject: renaissance1: #i107215# Improved calculation of insertion indicator, excluded pages. --- .../accessibility/AccessibleSlideSorterObject.cxx | 2 +- .../controller/SlideSorterController.cxx | 24 +- .../ui/slidesorter/controller/SlsAnimator.cxx | 6 +- .../controller/SlsInsertionIndicatorHandler.cxx | 3 +- .../ui/slidesorter/controller/SlsSlotManager.cxx | 4 +- .../inc/controller/SlideSorterController.hxx | 8 - .../ui/slidesorter/inc/model/SlsPageDescriptor.hxx | 2 +- .../ui/slidesorter/inc/view/SlideSorterView.hxx | 15 +- sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 39 ++- .../slidesorter/inc/view/SlsPageObjectLayouter.hxx | 13 +- sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 4 +- .../ui/slidesorter/model/SlsPageDescriptor.cxx | 7 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 18 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 129 +++++----- sd/source/ui/slidesorter/view/SlsIcons.hrc | 1 + sd/source/ui/slidesorter/view/SlsIcons.src | 5 + .../ui/slidesorter/view/SlsInsertAnimator.cxx | 93 +++---- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 267 ++++++++++++--------- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 10 +- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 40 +-- sd/source/ui/slidesorter/view/SlsTheme.cxx | 6 +- 21 files changed, 373 insertions(+), 323 deletions(-) diff --git a/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx b/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx index 41804bc8bdbc..4ded92d9eddf 100644 --- a/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx +++ b/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx @@ -398,7 +398,7 @@ awt::Rectangle SAL_CALL AccessibleSlideSorterObject::getBounds (void) mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox( mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber), ::sd::slidesorter::view::PageObjectLayouter::PageObject, - ::sd::slidesorter::view::PageObjectLayouter::ScreenCoordinateSystem)); + ::sd::slidesorter::view::PageObjectLayouter::WindowCoordinateSystem)); if (mxParent.is()) { diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index e5a78bd1caac..8b32a3c34c5c 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -225,14 +225,16 @@ SlideSorter& SlideSorterController::GetSlideSorter (void) const model::SharedPageDescriptor SlideSorterController::GetPageAt ( - const Point& aPixelPosition) + const Point& aWindowPosition) { - sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aPixelPosition)); + sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aWindowPosition)); model::SharedPageDescriptor pDescriptorAtPoint; if (nHitPageIndex >= 0) { pDescriptorAtPoint = mrModel.GetPageDescriptor(nHitPageIndex); + // Depending on a property we may have to check that the mouse is no + // just over the page object but over the preview area. if (pDescriptorAtPoint && mrSlideSorter.GetProperties()->IsOnlyPreviewTriggersMouseOver() && ! pDescriptorAtPoint->HasState(PageDescriptor::ST_Selected)) @@ -241,7 +243,7 @@ model::SharedPageDescriptor SlideSorterController::GetPageAt ( if ( ! mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox( pDescriptorAtPoint, view::PageObjectLayouter::Preview, - view::PageObjectLayouter::WindowCoordinateSystem).IsInside(aPixelPosition)) + view::PageObjectLayouter::WindowCoordinateSystem).IsInside(aWindowPosition)) { pDescriptorAtPoint.reset(); } @@ -254,20 +256,6 @@ model::SharedPageDescriptor SlideSorterController::GetPageAt ( -model::SharedPageDescriptor SlideSorterController::GetFadePageAt ( - const Point& aPixelPosition) -{ - sal_Int32 nHitPageIndex (mrView.GetFadePageIndexAtPoint(aPixelPosition)); - model::SharedPageDescriptor pDescriptorAtPoint; - if (nHitPageIndex >= 0) - pDescriptorAtPoint = mrModel.GetPageDescriptor(nHitPageIndex); - - return pDescriptorAtPoint; -} - - - - PageSelector& SlideSorterController::GetPageSelector (void) { OSL_ASSERT(mpPageSelector.get()!=NULL); @@ -489,7 +477,7 @@ bool SlideSorterController::Command ( mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox ( pDescriptor, PageObjectLayouter::PageObject, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); Point aCenter (aBBox.Center()); mbIsContextMenuOpen = true; if (pViewShell != NULL) diff --git a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx index 1bb762c184c9..4e5a236ccde0 100644 --- a/sd/source/ui/slidesorter/controller/SlsAnimator.cxx +++ b/sd/source/ui/slidesorter/controller/SlsAnimator.cxx @@ -116,7 +116,11 @@ void Animator::Dispose (void) (*iAnimation)->Expire(); maTimer.Stop(); - mpDrawLock.reset(); + if (mpDrawLock) + { + mpDrawLock->Dispose(); + mpDrawLock.reset(); + } } diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 6b6c8916ebf7..14e792d8f5cc 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -183,7 +183,8 @@ void InsertionIndicatorHandler::SetPosition ( const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition( rPoint, - maIconSize)); + maIconSize, + mrSlideSorter.GetModel())); if (maInsertPosition != aInsertPosition || meMode != eMode diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 13439f9a80db..8f1d6722cec0 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -389,7 +389,7 @@ void SlotManager::FuSupport (SfxRequest& rRequest) break; } - case SID_UNDO : + case SID_UNDO: { SlideSorterViewShell* pViewShell = dynamic_cast(mrSlideSorter.GetViewShell()); @@ -398,7 +398,7 @@ void SlotManager::FuSupport (SfxRequest& rRequest) break; } - case SID_REDO : + case SID_REDO: { SlideSorterViewShell* pViewShell = dynamic_cast(mrSlideSorter.GetViewShell()); diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index db72a7e54deb..58440f05f8bb 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -123,14 +123,6 @@ public: */ model::SharedPageDescriptor GetPageAt (const Point& rPixelPosition); - /** Return the descriptor of the page that is associated to the page - visible fade symbol at the given position. - @return - When the given position is not over a visible page fade symbol - then NULL is returned. - */ - model::SharedPageDescriptor GetFadePageAt (const Point& rPixelPosition); - PageSelector& GetPageSelector (void); FocusManager& GetFocusManager (void); controller::Clipboard& GetClipboard (void); diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx index 58263719197c..872cc1743369 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx @@ -128,7 +128,7 @@ public: VisualState& GetVisualState (void); Rectangle GetBoundingBox (void) const; - Point GetLocation (void) const; + Point GetLocation (const bool bIgnoreLocation = false) const; void SetBoundingBox (const Rectangle& rBoundingBox); private: diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index a6b1a389e5e4..14ee98ffd693 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -106,7 +106,6 @@ public: given position. */ sal_Int32 GetPageIndexAtPoint (const Point& rPosition) const; - sal_Int32 GetFadePageIndexAtPoint (const Point& rPosition) const; view::Layouter& GetLayouter (void); @@ -193,14 +192,18 @@ public: void UpdatePageUnderMouse ( const Point& rMousePosition, - const bool bIsMouseButtonDown); - void SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor); + const bool bIsMouseButtonDown, + const bool bAnimate = true); + void SetPageUnderMouse ( + const model::SharedPageDescriptor& rpDescriptor, + const bool bAnimate = true); void SetButtonUnderMouse (const sal_Int32 nButtonIndex); bool SetState ( const model::SharedPageDescriptor& rpDescriptor, const model::PageDescriptor::State eState, - const bool bStateValue); + const bool bStateValue, + const bool bAnimate = true); ::boost::shared_ptr GetPageObjectPainter (void); ::boost::shared_ptr GetLayeredDevice (void) const; @@ -211,6 +214,10 @@ public: DrawLock (view::SlideSorterView& rView, const SharedSdWindow& rpWindow); DrawLock (SlideSorter& rSlideSorter); ~DrawLock (void); + /** When the DrawLock is disposed then it will not request a repaint + on destruction. + */ + void Dispose (void); private: view::SlideSorterView& mrView; SharedSdWindow mpWindow; diff --git a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx index 228da649c3eb..12bc67aa5e4b 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx @@ -39,6 +39,7 @@ #include #include + class MapMode; class OutputDevice; class Size; @@ -228,7 +229,7 @@ public: 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 + @param rModelPosition 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. @@ -236,10 +237,15 @@ public: 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. + @param rModel + The model is used to get access to the selection states of the + pages. This in turn is used to determine the visual bounding + boxes. */ InsertPosition GetInsertPosition ( const Point& rModelPosition, - const Size& rIndicatorSize) const; + const Size& rIndicatorSize, + model::SlideSorterModel& rModel) const; /** Return whether the main orientation of the slides in the slide sorter is vertical, i.e. all slides are arranged in one column. @@ -349,7 +355,30 @@ private: sal_Int32 nIndex, sal_Int32 nGap) const; - Rectangle GetPreviewBox (const sal_Int32 nIndex) const; + /** Calculate the logical part of the insert position, i.e. the page + after whicht to insert. + */ + void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; + + /** Calculate the geometrical part of the insert position, i.e. the + location of where to display the insertion indicator and the + distances about which the leading and trailing pages have to be + moved to make room for the indicator. + */ + void CalculateGeometricPosition ( + InsertPosition& rPosition, + const Size& rIndicatorSize, + const bool bIsVertical, + model::SlideSorterModel& rModel) const; + + /** Return the bounding box of the preview or, when selected, of the page + object. Thus, it returns something like a visual bounding box. + */ + Rectangle GetInnerBoundingBox ( + model::SlideSorterModel& rModel, + const sal_Int32 nIndex) const; }; @@ -370,6 +399,8 @@ public: sal_Int32 GetColumn (void) const { return mnColumn; } sal_Int32 GetIndex (void) const { return mnIndex; } Point GetLocation (void) const { return maLocation; } + Point GetLeadingOffset (void) const { return maLeadingOffset; } + Point GetTrailingOffset (void) const { return maTrailingOffset; } bool IsAtRunStart (void) const { return mbIsAtRunStart; } bool IsAtRunEnd (void) const { return mbIsAtRunEnd; } bool IsExtraSpaceNeeded (void) const { return mbIsExtraSpaceNeeded; } @@ -379,6 +410,8 @@ private: sal_Int32 mnColumn; sal_Int32 mnIndex; Point maLocation; + Point maLeadingOffset; + Point maTrailingOffset; bool mbIsAtRunStart : 1; bool mbIsAtRunEnd : 1; bool mbIsExtraSpaceNeeded : 1; diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx index 46f3881fe6da..99ceee121b42 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx @@ -85,20 +85,13 @@ public: }; /** Two coordinate systems are supported. They differ only in translation not in scale. Both relate to pixel values in the window. - A position in the window coordinate system does not change when the window content is - scrolled up or down. In the screen coordinate system (relative + A position in the model coordinate system does not change when the window content is + scrolled up or down. In the window coordinate system (relative to the top left point of the window)scrolling leads to different values. - Example: Scroll up the point (0,0) in the the window coordinate - system by 20 pixels. It lies not inside the visible area of the - window anymore. Its screen coordinates are now (-20,0). - - WindowCoordinateSystem corresponds to the logic coordinate system of - class Window, while ScreenCoordinateSystem corresponds to its pixel - coordinate system. */ enum CoordinateSystem { WindowCoordinateSystem, - ScreenCoordinateSystem}; + ModelCoordinateSystem}; /** Return the bounding box of the page object or one of its graphical parts. diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index 83f1d75f5126..5b7241aaadc2 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -106,7 +106,8 @@ public: enum IconType { RawShadow, - RawInsertShadow + RawInsertShadow, + HideSlideOverlay }; BitmapEx GetIcon (const IconType eType); @@ -127,6 +128,7 @@ private: GradientDescriptor maMouseOverGradient; BitmapEx maRawShadow; BitmapEx maRawInsertShadow; + BitmapEx maHideSlideOverlay; }; diff --git a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx index 13a436c6f035..c93d6cfd12a2 100644 --- a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx @@ -262,9 +262,12 @@ Rectangle PageDescriptor::GetBoundingBox (void) const -Point PageDescriptor::GetLocation (void) const +Point PageDescriptor::GetLocation (const bool bIgnoreOffset) const { - return maBoundingBox.TopLeft() + maVisualState.GetLocationOffset(); + if (bIgnoreOffset) + return maBoundingBox.TopLeft(); + else + return maBoundingBox.TopLeft() + maVisualState.GetLocationOffset(); } diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index ac8340a7b7aa..4199afd7dc72 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -304,7 +304,12 @@ SlideSorter& SlideSorterViewShell::GetSlideSorter (void) const bool SlideSorterViewShell::RelocateToParentWindow (::Window* pParentWindow) { OSL_ASSERT(mpSlideSorter.get()!=NULL); - return mpSlideSorter->RelocateToWindow(pParentWindow); + if (pParentWindow == NULL) + WriteFrameViewData(); + const bool bSuccess (mpSlideSorter->RelocateToWindow(pParentWindow)); + if (pParentWindow != NULL) + ReadFrameViewData(mpFrameView); + return bSuccess; } @@ -546,8 +551,11 @@ void SlideSorterViewShell::Paint ( void SlideSorterViewShell::ArrangeGUIElements (void) { - OSL_ASSERT(mpSlideSorter.get()!=NULL); - mpSlideSorter->ArrangeGUIElements(maViewPos, maViewSize); + if (IsActive()) + { + OSL_ASSERT(mpSlideSorter.get()!=NULL); + mpSlideSorter->ArrangeGUIElements(maViewPos, maViewSize); + } } @@ -642,9 +650,11 @@ void SlideSorterViewShell::WriteFrameViewData() SdPage* pActualPage = GetActualPage(); if (pActualPage != NULL) { + if (IsMainViewShell()) + mpFrameView->SetSelectedPage((pActualPage->GetPageNum()- 1) / 2); + // else // The slide sorter is not expected to switch the current page // other then by double clicks. That is handled seperatly. - // mpFrameView->SetSelectedPage((pActualPage->GetPageNum()- 1) / 2); } else { diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index d7b510464f19..78bced29286b 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -404,14 +404,14 @@ void SlideSorterView::Dispose (void) -sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rPosition) const +sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rWindowPosition) const { sal_Int32 nIndex (-1); SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { - nIndex = mpLayouter->GetIndexAtPoint (pWindow->PixelToLogic (rPosition)); + nIndex = mpLayouter->GetIndexAtPoint(pWindow->PixelToLogic(rWindowPosition)); // Clip the page index against the page count. if (nIndex >= mrModel.GetPageCount()) @@ -424,45 +424,6 @@ sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rPosition) const -sal_Int32 SlideSorterView::GetFadePageIndexAtPoint ( - const Point& rPosition) const -{ - sal_Int32 nIndex (-1); - - SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - if (pWindow) - { - Point aModelPosition (pWindow->PixelToLogic (rPosition)); - nIndex = mpLayouter->GetIndexAtPoint( - aModelPosition, - true // Include page borders into hit test - ); - - // Clip the page index against the page count. - if (nIndex >= mrModel.GetPageCount()) - nIndex = -1; - - if (nIndex >= 0) - { - // Now test whether the given position is inside the area of the - // fade effect indicator. - const Rectangle aBox ( - mpLayouter->GetPageObjectLayouter()->GetBoundingBox( - mrModel.GetPageDescriptor(nIndex), - PageObjectLayouter::TransitionEffectIndicator, - PageObjectLayouter::WindowCoordinateSystem)); - const Point aPoint (aModelPosition.getX(), aModelPosition.getY()); - if ( ! aBox.IsInside(aPoint)) - nIndex = -1; - } - } - - return nIndex; -} - - - - Layouter& SlideSorterView::GetLayouter (void) { return *mpLayouter.get(); @@ -525,7 +486,8 @@ void SlideSorterView::PostModelChange (void) const Window::PointerState aPointerState (pWindow->GetPointerState()); UpdatePageUnderMouse ( aPointerState.maPos, - (aPointerState.mnState & MOUSE_LEFT)!=0); + (aPointerState.mnState & MOUSE_LEFT)!=0, + false); } } @@ -937,12 +899,13 @@ void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint void SlideSorterView::UpdatePageUnderMouse ( const Point& rMousePosition, - const bool bIsMouseButtonDown) + const bool bIsMouseButtonDown, + const bool bAnimate) { // Determine page under mouse and show the mouse over effect. model::SharedPageDescriptor pHitDescriptor ( mrSlideSorter.GetController().GetPageAt(rMousePosition)); - SetPageUnderMouse(pHitDescriptor); + SetPageUnderMouse(pHitDescriptor, bAnimate); // Handle the mouse being over any buttons. if (pHitDescriptor) @@ -966,7 +929,9 @@ void SlideSorterView::UpdatePageUnderMouse ( -void SlideSorterView::SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor) +void SlideSorterView::SetPageUnderMouse ( + const model::SharedPageDescriptor& rpDescriptor, + const bool bAnimate) { if (mpPageUnderMouse != rpDescriptor) { @@ -975,14 +940,14 @@ void SlideSorterView::SetPageUnderMouse (const model::SharedPageDescriptor& rpDe mpPageUnderMouse->GetVisualState().SetActiveButtonState( -1, model::VisualState::BS_Normal); - SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false); + SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false, bAnimate); } mpPageUnderMouse = rpDescriptor; SetButtonUnderMouse(-1); if (mpPageUnderMouse) - SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true); + SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true, bAnimate); // Change the quick help text to display the name of the page under // the mouse. @@ -1034,7 +999,8 @@ void SlideSorterView::SetButtonUnderMouse (const sal_Int32 nButtonIndex) bool SlideSorterView::SetState ( const model::SharedPageDescriptor& rpDescriptor, const PageDescriptor::State eState, - const bool bStateValue) + const bool bStateValue, + const bool bAnimate) { const bool bModified (rpDescriptor->SetState(eState, bStateValue)); if ( ! bModified) @@ -1059,36 +1025,42 @@ bool SlideSorterView::SetState ( // Fade in or out the buttons. if (eState == PageDescriptor::ST_MouseOver) { - // Stop a running animation. - const Animator::AnimationId nId ( - rpDescriptor->GetVisualState().GetButtonAlphaAnimationId()); - if (nId != Animator::NotAnAnimationId) + const double nEndAlpha (bStateValue ? 0.2 : 1.0); + if (bAnimate) { - mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(nId); - } + const double nStartAlpha (rpDescriptor->GetVisualState().GetButtonAlpha()); - const double nStartAlpha (rpDescriptor->GetVisualState().GetButtonAlpha()); - const double nEndAlpha (bStateValue ? 0.2 : 1.0); - const ::boost::function aBlendFunctor ( - ::boost::bind( - AnimationFunction::Blend, - nStartAlpha, - nEndAlpha, - ::boost::bind(AnimationFunction::Linear, _1))); - rpDescriptor->GetVisualState().SetButtonAlphaAnimationId( - mrSlideSorter.GetController().GetAnimator()->AddAnimation( - ::boost::bind( - AnimationFunction::ApplyButtonAlphaChange, - rpDescriptor, - ::boost::ref(*this), - ::boost::bind(aBlendFunctor, _1)), - bStateValue ? 500 : 0, - 400, + // Stop a running animation. + const Animator::AnimationId nId ( + rpDescriptor->GetVisualState().GetButtonAlphaAnimationId()); + if (nId != Animator::NotAnAnimationId) + mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(nId); + + const ::boost::function aBlendFunctor ( ::boost::bind( - &VisualState::SetButtonAlphaAnimationId, - ::boost::ref(rpDescriptor->GetVisualState()), - controller::Animator::NotAnAnimationId) - )); + AnimationFunction::Blend, + nStartAlpha, + nEndAlpha, + ::boost::bind(AnimationFunction::Linear, _1))); + rpDescriptor->GetVisualState().SetButtonAlphaAnimationId( + mrSlideSorter.GetController().GetAnimator()->AddAnimation( + ::boost::bind( + AnimationFunction::ApplyButtonAlphaChange, + rpDescriptor, + ::boost::ref(*this), + ::boost::bind(aBlendFunctor, _1)), + bStateValue ? 500 : 0, + 400, + ::boost::bind( + &VisualState::SetButtonAlphaAnimationId, + ::boost::ref(rpDescriptor->GetVisualState()), + controller::Animator::NotAnAnimationId) + )); + } + else + { + rpDescriptor->GetVisualState().SetButtonAlpha(nEndAlpha); + } } return bModified; @@ -1162,4 +1134,11 @@ SlideSorterView::DrawLock::~DrawLock (void) + +void SlideSorterView::DrawLock::Dispose (void) +{ + mpWindow.reset(); +} + + } } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hrc b/sd/source/ui/slidesorter/view/SlsIcons.hrc index afde6145ab49..240321d77475 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.hrc +++ b/sd/source/ui/slidesorter/view/SlsIcons.hrc @@ -44,5 +44,6 @@ #define IMAGE_SHADOW 10 #define IMAGE_INSERT_SHADOW 11 +#define IMAGE_HIDE_SLIDE_OVERLAY 12 #endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.src b/sd/source/ui/slidesorter/view/SlsIcons.src index 834e0b2caa9a..d8a5ffadc3ef 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.src +++ b/sd/source/ui/slidesorter/view/SlsIcons.src @@ -71,4 +71,9 @@ Resource IMG_ICONS { ImageBitmap = Bitmap { File = "slide_sorter_insert_shadow.png" ; }; }; + + Image IMAGE_HIDE_SLIDE_OVERLAY + { + ImageBitmap = Bitmap { File = "slide_sorter_hide_slide_overlay.png" ; }; + }; }; diff --git a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx index 5731f7c49de6..c7b210f93056 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx @@ -110,6 +110,9 @@ private: AnimatorAccess& mrAnimatorAccess; ::boost::function maAccelerationFunction; + Rectangle GetInnerBoundingBox ( + const view::Layouter& rLayouter, + const sal_Int32 nIndex) const; void RestartAnimation (void); }; typedef ::boost::shared_ptr SharedPageObjectRun; @@ -375,12 +378,37 @@ PageObjectRun::~PageObjectRun (void) +Rectangle PageObjectRun::GetInnerBoundingBox ( + const view::Layouter& rLayouter, + const sal_Int32 nIndex) const +{ + model::SharedPageDescriptor pDescriptor ( + mrAnimatorAccess.GetModel().GetPageDescriptor(nIndex)); + if (pDescriptor) + if (pDescriptor->HasState(model::PageDescriptor::ST_Selected)) + return rLayouter.GetPageObjectLayouter()->GetBoundingBox( + pDescriptor, + PageObjectLayouter::PageObject, + PageObjectLayouter::ModelCoordinateSystem); + else + return rLayouter.GetPageObjectLayouter()->GetBoundingBox( + pDescriptor, + PageObjectLayouter::Preview, + PageObjectLayouter::ModelCoordinateSystem); + else + return Rectangle(); +} + + + + void PageObjectRun::UpdateOffsets( const InsertPosition& rInsertPosition, const Size& rRequiredSpace, const view::Layouter& rLayouter) { - const sal_Int32 nLocalInsertIndex(rLayouter.GetColumnCount()==1 + const bool bIsVertical (rLayouter.GetColumnCount()==1); + const sal_Int32 nLocalInsertIndex(bIsVertical ? rInsertPosition.GetRow() : rInsertPosition.GetColumn()); if (nLocalInsertIndex != mnLocalInsertIndex) @@ -388,70 +416,19 @@ void PageObjectRun::UpdateOffsets( mnLocalInsertIndex = nLocalInsertIndex; model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel()); - Point aLeadingOffset; - Point aTrailingOffset; - const bool bUseX (rLayouter.GetColumnCount() > 1); 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, - PageObjectLayouter::WindowCoordinateSystem)); - const Point aAvailableSpace (aInnerBox.TopLeft()); - if (bUseX) - aTrailingOffset.X() = ::std::max(0L, rRequiredSpace.Width()-aAvailableSpace.X()); - else - aTrailingOffset.Y() = ::std::max(0L, rRequiredSpace.Height()-aAvailableSpace.Y()); - } - 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(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - const Point aAvailableSpace (aOuterBox.BottomRight() - aInnerBox.BottomRight()); - if (bUseX) - aLeadingOffset.X() = ::std::min(0L, aAvailableSpace.X()-rRequiredSpace.Width()); - else - aLeadingOffset.Y() = ::std::min(0L, aAvailableSpace.Y()-rRequiredSpace.Height()); - } - else if ( ! rInsertPosition.IsAtRunEnd()) - { - // Insertion position is somewhere in the middle of the run. - const Rectangle aBox1 (rLayouter.GetPageObjectLayouter()->GetBoundingBox( - rModel.GetPageDescriptor(mnStartIndex + mnLocalInsertIndex - 1), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - const Rectangle aBox2 (rLayouter.GetPageObjectLayouter()->GetBoundingBox( - rModel.GetPageDescriptor(mnStartIndex + mnLocalInsertIndex), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - const Size aDelta ( - bUseX ? aBox2.Left() - aBox1.Right() - 1 : 0, - bUseX ? 0 : aBox2.Top() - aBox1.Bottom() - 1); - if (aDelta.Width() < rRequiredSpace.Width()) - { - aLeadingOffset.X() = (aDelta.Width()-rRequiredSpace.Width()-1)/2; - aTrailingOffset.X() = rRequiredSpace.Width()-aDelta.Width()+aLeadingOffset.X(); - } - if (aDelta.Height() < rRequiredSpace.Height()) - { - aLeadingOffset.Y() = (aDelta.Height()-rRequiredSpace.Height()-1)/2; - aTrailingOffset.Y() = rRequiredSpace.Height()-aDelta.Height()+aLeadingOffset.Y(); - } - } for (sal_Int32 nIndex=0; nIndexGetVisualState().GetLocationOffset(); maEndOffset[nIndex] = nIndex < mnLocalInsertIndex - ? aLeadingOffset - : aTrailingOffset; + ? rInsertPosition.GetLeadingOffset() + : rInsertPosition.GetTrailingOffset(); + if (bIsVertical) + maEndOffset[nIndex].X() = 0; + else + maEndOffset[nIndex].Y() = 0; } RestartAnimation(); } diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 1ed176d0fcae..156ebaac8b7d 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -31,6 +31,8 @@ #include "precompiled_sd.hxx" #include "view/SlsLayouter.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageDescriptor.hxx" #include "Window.hxx" #include @@ -462,161 +464,200 @@ Rectangle Layouter::GetPageBox (const sal_Int32 nObjectCount) const -Rectangle Layouter::GetPreviewBox (const sal_Int32 nIndex) const +InsertPosition Layouter::GetInsertPosition ( + const Point& rModelPosition, + const Size& rIndicatorSize, + model::SlideSorterModel& rModel) const { - return mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(nIndex).TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem); + InsertPosition aPosition; + CalculateLogicalInsertPosition(rModelPosition, aPosition); + CalculateGeometricPosition(aPosition, rIndicatorSize, GetColumnCount()==1, rModel); + return aPosition; } -InsertPosition Layouter::GetInsertPosition ( - const Point& rModelPosition, - const Size& rIndicatorSize) const +void Layouter::CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const { - 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); + rPosition.mnRow = ::std::min(mnPageCount, nY / nRowHeight); + rPosition.mnColumn = 0; + rPosition.mnIndex = rPosition.mnRow; + rPosition.mbIsAtRunStart = (rPosition.mnRow == 0); + rPosition.mbIsAtRunEnd = (rPosition.mnRow == mnRowCount); + rPosition.mbIsExtraSpaceNeeded = (rPosition.mnRow >= mnMaxRowCount); } else { - aPosition.mnRow = ::std::min( + rPosition.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; + rPosition.mnColumn = ::std::min(mnColumnCount, nX / nRowWidth); + rPosition.mnIndex = rPosition.mnRow * mnColumnCount + rPosition.mnColumn; - aPosition.mbIsAtRunStart = (aPosition.mnColumn == 0); - aPosition.mbIsAtRunEnd = (aPosition.mnColumn == mnColumnCount); + rPosition.mbIsAtRunStart = (rPosition.mnColumn == 0); + rPosition.mbIsAtRunEnd = (rPosition.mnColumn == mnColumnCount); - if (aPosition.mnIndex >= mnPageCount) + if (rPosition.mnIndex >= mnPageCount) { - aPosition.mnIndex = mnPageCount; - aPosition.mnRow = mnRowCount-1; - aPosition.mnColumn = mnPageCount%mnColumnCount; - aPosition.mbIsAtRunEnd = true; + rPosition.mnIndex = mnPageCount; + rPosition.mnRow = mnRowCount-1; + rPosition.mnColumn = mnPageCount%mnColumnCount; + rPosition.mbIsAtRunEnd = true; } - aPosition.mbIsExtraSpaceNeeded = (aPosition.mnColumn >= mnMaxColumnCount); + rPosition.mbIsExtraSpaceNeeded = (rPosition.mnColumn >= mnMaxColumnCount); } +} - // Determine visual position. - if (mnColumnCount == 1) - { - // Place indicator between rows of a single column of pages. - if (aPosition.mbIsAtRunStart) + + +void Layouter::CalculateGeometricPosition ( + InsertPosition& rPosition, + const Size& rIndicatorSize, + const bool bIsVertical, + model::SlideSorterModel& rModel) const +{ + // 1. Determine right/bottom of the leading page and the left/top of the + // trailing page object and how to distribute the missing space. + sal_Int32 nLeadingLocation (0); + sal_Int32 nTrailingLocation (0); + bool bIsLeadingFixed (false); + bool bIsTrailingFixed (false); + sal_Int32 nSecondaryLocation (0); + + if (rPosition.mbIsAtRunStart) + { + // Place indicator at the top of the column. + const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex)); + const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex)); + if (bIsVertical) { - // Place indicator at the top of the column. - const Rectangle aOuterBox (GetPageObjectBox(0)); - const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( - aOuterBox.TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - aPosition.maLocation.X() = aPreviewBox.Center().X(); - aPosition.maLocation.Y() = aOuterBox.Top()+rIndicatorSize.Height()/2; + nLeadingLocation = aOuterBox.Top(); + nTrailingLocation = aInnerBox.Top(); + nSecondaryLocation = aInnerBox.Center().X(); } - else if (aPosition.mbIsAtRunEnd) + else { - const Rectangle aOuterBox (GetPageObjectBox(mnRowCount-1)); - const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( - aOuterBox.TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - 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; - } + nLeadingLocation = aOuterBox.Left(); + nTrailingLocation = aInnerBox.Left(); + nSecondaryLocation = aInnerBox.Center().Y(); + } + bIsLeadingFixed = true; + } + else if (rPosition.mbIsAtRunEnd) + { + // Place indicator at the bottom/right of the column/row. + + const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex-1)); + const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex-1)); + if (bIsVertical) + { + nLeadingLocation = aInnerBox.Bottom(); + nTrailingLocation = aOuterBox.Bottom(); + nSecondaryLocation = aInnerBox.Center().X(); } else { - // Place indicator between two rows. - const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(aPosition.mnRow-1).TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(aPosition.mnRow).TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - aPosition.maLocation = (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; + nLeadingLocation = aInnerBox.Right(); + nTrailingLocation = aOuterBox.Right(); + nSecondaryLocation = aInnerBox.Center().Y(); } + bIsTrailingFixed = true; + if ( ! rPosition.mbIsExtraSpaceNeeded) + bIsLeadingFixed = true; } else { - // Place indicator between columns in one row. - if (aPosition.mbIsAtRunStart) - { - // Place indicator at the left of the row. - const Rectangle aOuterBox (GetPageObjectBox(aPosition.mnIndex)); - const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( - aOuterBox.TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - aPosition.maLocation.X() = aOuterBox.Left()+rIndicatorSize.Width()/2; - aPosition.maLocation.Y() = aPreviewBox.Center().Y(); - } - else if (aPosition.mbIsAtRunEnd) + // Place indicator between two rows/columns. + const Rectangle aBox1 (GetInnerBoundingBox(rModel, rPosition.mnIndex-1)); + const Rectangle aBox2 (GetInnerBoundingBox(rModel, rPosition.mnIndex)); + if (bIsVertical) { - const Rectangle aOuterBox (GetPageObjectBox(aPosition.mnIndex-1)); - const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( - aOuterBox.TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - 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(); - } + nLeadingLocation = aBox1.Bottom(); + nTrailingLocation = aBox2.Top(); + nSecondaryLocation = (aBox1.Center().X() + aBox2.Center().X()) / 2; } else { - // Place indicator between two columns. - const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(aPosition.mnIndex-1).TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox( - GetPageObjectBox(aPosition.mnIndex).TopLeft(), - PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); - aPosition.maLocation = (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2; + nLeadingLocation = aBox1.Right(); + nTrailingLocation = aBox2.Left(); + nSecondaryLocation = (aBox1.Center().Y() + aBox2.Center().Y()) / 2; } } - return aPosition; + // 2. Calculate the location of the insert indicator and the offsets of + // leading and trailing pages. + const sal_Int32 nAvailableSpace (nTrailingLocation - nLeadingLocation); + const sal_Int32 nRequiredSpace (bIsVertical ? rIndicatorSize.Height():rIndicatorSize.Width()); + const sal_Int32 nMissingSpace (::std::max(sal_Int32(0), nRequiredSpace - nAvailableSpace)); + sal_Int32 nPrimaryLocation (0); + sal_Int32 nLeadingOffset (0); + sal_Int32 nTrailingOffset (0); + if (bIsLeadingFixed) + { + nPrimaryLocation = nLeadingLocation + nRequiredSpace/2; + if ( ! bIsTrailingFixed) + nTrailingOffset = nMissingSpace; + } + else if (bIsTrailingFixed) + { + nPrimaryLocation = nTrailingLocation - nRequiredSpace/2; + nLeadingOffset = -nMissingSpace; + } + else + { + nPrimaryLocation = (nLeadingLocation + nTrailingLocation) /2; + nLeadingOffset = -nMissingSpace/2; + nTrailingOffset = nMissingSpace + nLeadingOffset; + } + + if (bIsVertical) + { + rPosition.maLocation = Point(nSecondaryLocation, nPrimaryLocation); + rPosition.maLeadingOffset = Point(0, nLeadingOffset); + rPosition.maTrailingOffset = Point(0, nTrailingOffset); + } + else + { + rPosition.maLocation = Point(nPrimaryLocation, nSecondaryLocation); + rPosition.maLeadingOffset = Point(nLeadingOffset, 0); + rPosition.maTrailingOffset = Point(nTrailingOffset, 0); + } +} + + + + +Rectangle Layouter::GetInnerBoundingBox ( + model::SlideSorterModel& rModel, + const sal_Int32 nIndex) const +{ + model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); + if ( ! pDescriptor) + return Rectangle(); + + const Point aLocation (pDescriptor->GetLocation(true)); + if (pDescriptor->HasState(model::PageDescriptor::ST_Selected)) + return GetPageObjectLayouter()->GetBoundingBox( + aLocation, + PageObjectLayouter::PageObject, + PageObjectLayouter::ModelCoordinateSystem); + else + return GetPageObjectLayouter()->GetBoundingBox( + aLocation, + PageObjectLayouter::Preview, + PageObjectLayouter::ModelCoordinateSystem); } @@ -809,6 +850,8 @@ InsertPosition::InsertPosition (void) mnColumn(-1), mnIndex(-1), maLocation(0,0), + maLeadingOffset(0,0), + maTrailingOffset(0,0), mbIsAtRunStart(false), mbIsAtRunEnd(false), mbIsExtraSpaceNeeded(false) @@ -826,6 +869,8 @@ InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition mnColumn = rInsertPosition.mnColumn; mnIndex = rInsertPosition.mnIndex; maLocation = rInsertPosition.maLocation; + maLeadingOffset = rInsertPosition.maLeadingOffset; + maTrailingOffset = rInsertPosition.maTrailingOffset; mbIsAtRunStart = rInsertPosition.mbIsAtRunStart; mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd; mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded; diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx index 8075464d92ff..61722bd25159 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -183,6 +183,7 @@ Rectangle PageObjectLayouter::GetBoundingBox ( const CoordinateSystem eCoordinateSystem, const sal_Int32 nIndex) { + OSL_ASSERT(rpPageDescriptor); Point aLocation (rpPageDescriptor ? rpPageDescriptor->GetLocation() : Point(0,0)); return GetBoundingBox(aLocation, ePart, eCoordinateSystem, nIndex); } @@ -238,8 +239,9 @@ Rectangle PageObjectLayouter::GetBoundingBox ( break; } + // Adapt coordinates to the requested coordinate system. Point aLocation (rPageObjectLocation); - if (eCoordinateSystem == ScreenCoordinateSystem) + if (eCoordinateSystem == WindowCoordinateSystem) aLocation += mpWindow->GetMapMode().GetOrigin(); return Rectangle( @@ -313,14 +315,14 @@ sal_Int32 PageObjectLayouter::GetButtonIndexAt ( const model::SharedPageDescriptor& rpPageDescriptor, const Point& rWindowLocation) { - if ( ! GetBoundingBox(rpPageDescriptor, ButtonArea, WindowCoordinateSystem) + if ( ! GetBoundingBox(rpPageDescriptor, ButtonArea, ModelCoordinateSystem) .IsInside(rWindowLocation)) { return -1; } for (sal_Int32 nIndex=0; nIndex<3; ++nIndex) { - if (GetBoundingBox(rpPageDescriptor, Button, WindowCoordinateSystem, nIndex) + if (GetBoundingBox(rpPageDescriptor, Button, ModelCoordinateSystem, nIndex) .IsInside(rWindowLocation)) { return nIndex; @@ -329,6 +331,4 @@ sal_Int32 PageObjectLayouter::GetButtonIndexAt ( return -1; } - - } } } // end of namespace ::sd::slidesorter::view diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 83ebcdaeb08c..f7f480cbe950 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -234,7 +234,7 @@ void PageObjectPainter::PaintBackground ( const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::PageObject, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); if (rpDescriptor->HasState(model::PageDescriptor::ST_MouseOver)) { @@ -273,12 +273,14 @@ void PageObjectPainter::PaintPreview ( Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); if (mpCache != NULL) { const SdrPage* pPage = rpDescriptor->GetPage(); BitmapEx aBitmap (mpCache->GetPreviewBitmap(pPage)); + if (aBitmap.GetSizePixel() != aBox.GetSize()) + aBitmap.Scale(aBox.GetSize()); mpCache->SetPreciousFlag(pPage, true); rDevice.DrawBitmapEx(aBox.TopLeft(), aBitmap); @@ -287,14 +289,18 @@ void PageObjectPainter::PaintPreview ( if (rpDescriptor->GetVisualState().GetCurrentVisualState() == model::VisualState::VS_Excluded) { - 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.3); + const Region aSavedClip (rDevice.GetClipRegion()); + + rDevice.IntersectClipRegion(aBox); + + const BitmapEx aOverlay (mpTheme->GetIcon(Theme::HideSlideOverlay)); + const sal_Int32 nIconWidth (aOverlay.GetSizePixel().Width()); + const sal_Int32 nIconHeight (aOverlay.GetSizePixel().Height()); + for (sal_Int32 nX=aBox.Left(); nXGetBoundingBox( rpDescriptor, PageObjectLayouter::PageNumber, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); // Paint the page number. OSL_ASSERT(rpDescriptor->GetPage()!=NULL); @@ -325,7 +331,7 @@ void PageObjectPainter::PaintPageNumber ( const Rectangle aFrameBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::PageNumberFrame, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); rDevice.SetLineColor(Color(mpTheme->GetColor(Theme::PageNumberBorder))); rDevice.SetFillColor(); rDevice.DrawRect(aFrameBox); @@ -347,7 +353,7 @@ void PageObjectPainter::PaintTransitionEffect ( const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::TransitionEffectIndicator, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); rDevice.DrawBitmapEx( aBox.TopLeft(), @@ -368,7 +374,7 @@ void PageObjectPainter::PaintButtons ( const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); @@ -383,7 +389,7 @@ void PageObjectPainter::PaintButtons ( mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::Button, - PageObjectLayouter::WindowCoordinateSystem, + PageObjectLayouter::ModelCoordinateSystem, nButtonIndex)); switch (rpDescriptor->GetVisualState().GetButtonState(nButtonIndex)) @@ -500,9 +506,9 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap( // Get bounding box of the preview around which a shadow is painted. // Compensate for the border around the preview. const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( - model::SharedPageDescriptor(), + Point(0,0), PageObjectLayouter::Preview, - PageObjectLayouter::WindowCoordinateSystem)); + PageObjectLayouter::ModelCoordinateSystem)); Rectangle aFrameBox (aBox.Left()-1,aBox.Top()-1,aBox.Right()+1,aBox.Bottom()+1); mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox); diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index 37b2fcb09b21..14b79afea1ff 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -99,6 +99,7 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) maRawShadow = Image(SdResId(IMAGE_SHADOW)).GetBitmapEx(); maRawInsertShadow = Image(SdResId(IMAGE_INSERT_SHADOW)).GetBitmapEx(); + maHideSlideOverlay = Image(SdResId(IMAGE_HIDE_SLIDE_OVERLAY)).GetBitmapEx(); Update(rpProperties); } @@ -175,7 +176,7 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert pFont->SetTransparent(TRUE); pFont->SetWeight(WEIGHT_NORMAL); const Size aSize (pFont->GetSize()); - pFont->SetSize(Size(aSize.Width()*4/3, aSize.Height()*4/3)); + pFont->SetSize(Size(aSize.Width()*5/3, aSize.Height()*5/3)); break; } @@ -320,6 +321,9 @@ BitmapEx Theme::GetIcon (const IconType eType) case RawInsertShadow: return maRawInsertShadow; + case HideSlideOverlay: + return maHideSlideOverlay; + default: return BitmapEx(); } -- cgit v1.2.3 From 6f93ca28fa19531c78dc6a4ddafa4258d1efacd9 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 10 Mar 2010 18:36:15 +0100 Subject: renaissance1: #i107215# Fixed horizontal scrolling. --- .../ui/framework/factories/BasicViewFactory.cxx | 16 ++- .../ui/framework/factories/BasicViewFactory.hxx | 6 +- sd/source/ui/inc/SlideSorterViewShell.hxx | 3 +- .../slidesorter/controller/SlsScrollBarManager.cxx | 50 +++---- .../slidesorter/controller/SlsSelectionManager.cxx | 147 +++++++-------------- .../inc/controller/SlsScrollBarManager.hxx | 11 +- .../ui/slidesorter/inc/view/SlideSorterView.hxx | 2 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 10 +- .../ui/slidesorter/view/SlsInsertAnimator.cxx | 8 +- 9 files changed, 98 insertions(+), 155 deletions(-) diff --git a/sd/source/ui/framework/factories/BasicViewFactory.cxx b/sd/source/ui/framework/factories/BasicViewFactory.cxx index 1477cb2ec4b8..16f52686c008 100644 --- a/sd/source/ui/framework/factories/BasicViewFactory.cxx +++ b/sd/source/ui/framework/factories/BasicViewFactory.cxx @@ -230,7 +230,7 @@ Reference SAL_CALL BasicViewFactory::createResource ( // When the requested view is not in the cache then create a new view. if (pDescriptor.get() == NULL) { - pDescriptor = CreateView(rxViewId, *pFrame, *pWindow, xPane, pFrameView); + pDescriptor = CreateView(rxViewId, *pFrame, *pWindow, xPane, pFrameView, bIsCenterPane); } if (pDescriptor.get() != NULL) @@ -354,7 +354,8 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence& aArguments) SfxViewFrame& rFrame, ::Window& rWindow, const Reference& rxPane, - FrameView* pFrameView) + FrameView* pFrameView, + const bool bIsCenterPane) { ::boost::shared_ptr pDescriptor (new ViewDescriptor()); @@ -362,13 +363,12 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence& aArguments) rxViewId, rFrame, rWindow, - pFrameView); + pFrameView, + bIsCenterPane); pDescriptor->mxViewId = rxViewId; if (pDescriptor->mpViewShell.get() != NULL) { - const bool bIsCenterPane ( - rxViewId->isBoundToURL(FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT)); pDescriptor->mpViewShell->Init(bIsCenterPane); mpBase->GetViewShellManager()->ActivateViewShell(pDescriptor->mpViewShell.get()); @@ -389,7 +389,8 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence& aArguments) const Reference& rxViewId, SfxViewFrame& rFrame, ::Window& rWindow, - FrameView* pFrameView) + FrameView* pFrameView, + const bool bIsCenterPane) { ::boost::shared_ptr pViewShell; const OUString& rsViewURL (rxViewId->getResourceURL()); @@ -465,7 +466,8 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence& aArguments) &rFrame, *mpBase, &rWindow, - pFrameView); + pFrameView, + bIsCenterPane); } return pViewShell; diff --git a/sd/source/ui/framework/factories/BasicViewFactory.hxx b/sd/source/ui/framework/factories/BasicViewFactory.hxx index 59d2826ac106..0a839f47b7a9 100644 --- a/sd/source/ui/framework/factories/BasicViewFactory.hxx +++ b/sd/source/ui/framework/factories/BasicViewFactory.hxx @@ -132,13 +132,15 @@ private: SfxViewFrame& rFrame, ::Window& rWindow, const css::uno::Reference& rxPane, - FrameView* pFrameView); + FrameView* pFrameView, + const bool bIsCenterView); ::boost::shared_ptr CreateViewShell ( const css::uno::Reference& rxViewId, SfxViewFrame& rFrame, ::Window& rWindow, - FrameView* pFrameView); + FrameView* pFrameView, + const bool bIsCenterView); void ActivateCenterView ( const ::boost::shared_ptr& rpDescriptor); diff --git a/sd/source/ui/inc/SlideSorterViewShell.hxx b/sd/source/ui/inc/SlideSorterViewShell.hxx index c861af9dfa21..70ab0b920673 100644 --- a/sd/source/ui/inc/SlideSorterViewShell.hxx +++ b/sd/source/ui/inc/SlideSorterViewShell.hxx @@ -66,7 +66,8 @@ public: SfxViewFrame* pFrame, ViewShellBase& rViewShellBase, ::Window* pParentWindow, - FrameView* pFrameView); + FrameView* pFrameView, + const bool bIsCenterPane); virtual ~SlideSorterViewShell (void); diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index d51693067f0e..63179c4dbcf9 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -485,20 +485,30 @@ bool ScrollBarManager::TestScrollBarVisibilities ( -void ScrollBarManager::SetTop (const sal_Int32 nNewTop) +void ScrollBarManager::SetTopLeft (const Point aNewTopLeft) { - if (mpVerticalScrollBar != NULL - && mpVerticalScrollBar->GetThumbPos() != nNewTop) - { - // Flush pending repaints before scrolling to avoid temporary artifacts. - mrSlideSorter.GetContentWindow()->Update(); + if ((mpVerticalScrollBar == NULL + || mpVerticalScrollBar->GetThumbPos() == aNewTopLeft.Y()) + && (mpHorizontalScrollBar == NULL + || mpHorizontalScrollBar->GetThumbPos() == aNewTopLeft.X())) + return; - OSL_TRACE("setting top of vertical scroll bar to %d", nNewTop); - mpVerticalScrollBar->SetThumbPos(nNewTop); - mnVerticalPosition = double(nNewTop) / double(mpVerticalScrollBar->GetRange().Len()); - mrSlideSorter.GetContentWindow()->SetVisibleXY (mnHorizontalPosition, mnVerticalPosition); - mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); + // Flush pending repaints before scrolling to avoid temporary artifacts. + mrSlideSorter.GetContentWindow()->Update(); + + if (mpVerticalScrollBar != NULL) + { + mpVerticalScrollBar->SetThumbPos(aNewTopLeft.Y()); + mnVerticalPosition = aNewTopLeft.Y() / double(mpVerticalScrollBar->GetRange().Len()); } + if (mpHorizontalScrollBar != NULL) + { + mpHorizontalScrollBar->SetThumbPos(aNewTopLeft.X()); + mnHorizontalPosition = aNewTopLeft.X() / double(mpHorizontalScrollBar->GetRange().Len()); + } + + mrSlideSorter.GetContentWindow()->SetVisibleXY (mnHorizontalPosition, mnVerticalPosition); + mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); } @@ -515,24 +525,6 @@ sal_Int32 ScrollBarManager::GetTop (void) const -void ScrollBarManager::SetLeft (const sal_Int32 nNewLeft) -{ - if (mpHorizontalScrollBar != NULL - && mpHorizontalScrollBar->GetThumbPos() != nNewLeft) - { - // Flush pending repaints before scrolling to avoid temporary artifacts. - mrSlideSorter.GetContentWindow()->Update(); - - mpHorizontalScrollBar->SetThumbPos(nNewLeft); - mnHorizontalPosition = double(nNewLeft) / double(mpHorizontalScrollBar->GetRange().Len()); - mrSlideSorter.GetContentWindow()->SetVisibleXY ( - mnHorizontalPosition, mnVerticalPosition); - } -} - - - - sal_Int32 ScrollBarManager::GetLeft (void) const { if (mpHorizontalScrollBar != NULL) diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index c7b8da6016a3..36262f22298a 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -72,28 +72,18 @@ namespace sd { namespace slidesorter { namespace controller { namespace { - class VerticalVisibleAreaScroller + class VisibleAreaScroller { public: - VerticalVisibleAreaScroller (SlideSorter& rSlideSorter, - const double nStart, const double nEnd); + VisibleAreaScroller ( + SlideSorter& rSlideSorter, + const Point aStart, + const Point aEnd); void operator() (const double nValue); private: SlideSorter& mrSlideSorter; - double mnStart; - const double mnEnd; - const ::boost::function maAccelerationFunction; - }; - class HorizontalVisibleAreaScroller - { - public: - HorizontalVisibleAreaScroller (SlideSorter& rSlideSorter, - const double nStart, const double nEnd); - void operator() (const double nValue); - private: - SlideSorter& mrSlideSorter; - double mnStart; - const double mnEnd; + Point maStart; + const Point maEnd; const ::boost::function maAccelerationFunction; }; } @@ -436,10 +426,12 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) Point(0,0), pWindow->GetOutputSizePixel()))); - if (mrSlideSorter.GetView().GetOrientation() == SlideSorterView::VERTICAL) + sal_Int32 nNewTop (aVisibleArea.Top()); + sal_Int32 nNewLeft (aVisibleArea.Left()); + + if (mrSlideSorter.GetView().GetOrientation() != SlideSorterView::HORIZONTAL) { // Scroll the visible area to make aSelectionBox visible. - sal_Int32 nNewTop (aVisibleArea.Top()); if (mrSlideSorter.GetProperties()->IsCenterSelection()) { nNewTop = rBox.Top() - (aVisibleArea.GetHeight() - rBox.GetHeight()) / 2; @@ -460,28 +452,11 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) if (nNewTop < aModelArea.Top()) nNewTop = aModelArea.Top(); - // Scroll. - if (nNewTop != aVisibleArea.Top()) - { - if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) - { - if (mnAnimationId != Animator::NotAnAnimationId) - mrController.GetAnimator()->RemoveAnimation(mnAnimationId); - mnAnimationId = mrController.GetAnimator()->AddAnimation( - VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop), - 0, - 300); - } - else - VerticalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Top(), nNewTop)(1.0); - } - - return Size(0,aVisibleArea.Top() - nNewTop); } - else + + if (mrSlideSorter.GetView().GetOrientation() != SlideSorterView::VERTICAL) { // Scroll the visible area to make aSelectionBox visible. - sal_Int32 nNewLeft (aVisibleArea.Left()); if (mrSlideSorter.GetProperties()->IsCenterSelection()) { nNewLeft = rBox.Left() - (aVisibleArea.GetWidth() - rBox.GetWidth()) / 2; @@ -501,21 +476,26 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) nNewLeft = aModelArea.GetWidth() - aVisibleArea.GetWidth(); if (nNewLeft < aModelArea.Left()) nNewLeft = aModelArea.Left(); + } - // Scroll. - if (nNewLeft != aVisibleArea.Left()) + // Scroll. + if (nNewTop != aVisibleArea.Top() || nNewLeft != aVisibleArea.Left()) + { + VisibleAreaScroller aAnimation( + mrSlideSorter, + aVisibleArea.TopLeft(), + Point(nNewLeft, nNewTop)); + if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) { - if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) - mrController.GetAnimator()->AddAnimation( - HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft), - 0, - 300); - else - HorizontalVisibleAreaScroller(mrSlideSorter, aVisibleArea.Left(), nNewLeft)(1.0); + if (mnAnimationId != Animator::NotAnAnimationId) + mrController.GetAnimator()->RemoveAnimation(mnAnimationId); + mnAnimationId = mrController.GetAnimator()->AddAnimation(aAnimation, 0, 300); } - - return Size(aVisibleArea.Left() - nNewLeft, 0); + else + aAnimation(1.0); } + + return Size(aVisibleArea.Left() - nNewLeft, aVisibleArea.Top() - nNewTop); } @@ -659,13 +639,13 @@ namespace { const static sal_Int32 gnMaxScrollDistance = 300; -VerticalVisibleAreaScroller::VerticalVisibleAreaScroller ( +VisibleAreaScroller::VisibleAreaScroller ( SlideSorter& rSlideSorter, - const double nStart, - const double nEnd) + const Point aStart, + const Point aEnd) : mrSlideSorter(rSlideSorter), - mnStart(nStart), - mnEnd(nEnd), + maStart(aStart), + maEnd(aEnd), maAccelerationFunction( controller::AnimationParametricFunction( controller::AnimationBezierFunction (0.1,0.6))) @@ -673,58 +653,27 @@ VerticalVisibleAreaScroller::VerticalVisibleAreaScroller ( // 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; + if (abs(aStart.X()-aEnd.X()) > gnMaxScrollDistance) + if (aStart.X() < aEnd.X()) + maStart.X() = aEnd.X()-gnMaxScrollDistance; else - mnStart = nEnd+gnMaxScrollDistance; -} - - - -void VerticalVisibleAreaScroller::operator() (const double nTime) -{ - const double nLocalTime (maAccelerationFunction(nTime)); - const sal_Int32 nNewTop (mnStart * (1.0 - nLocalTime) + mnEnd * nLocalTime); - mrSlideSorter.GetController().GetScrollBarManager().SetTop(nNewTop); - /* - mrSlideSorter.GetViewShell()->Scroll( - 0, - nNewTop - mrSlideSorter.GetController().GetScrollBarManager().GetTop()); - mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - */ -} - - - - -//===== HorizontalVisibleAreaScroller ========================================= - -HorizontalVisibleAreaScroller::HorizontalVisibleAreaScroller ( - SlideSorter& rSlideSorter, - const double nStart, - const double nEnd) - : mrSlideSorter(rSlideSorter), - mnStart(nStart), - mnEnd(nEnd), - maAccelerationFunction( - controller::AnimationParametricFunction( - controller::AnimationBezierFunction (0.1,0.6))) - -{ + maStart.X() = aEnd.X()+gnMaxScrollDistance; + if (abs(aStart.Y()-aEnd.Y()) > gnMaxScrollDistance) + if (aStart.Y() < aEnd.Y()) + maStart.Y() = aEnd.Y()-gnMaxScrollDistance; + else + maStart.Y() = aEnd.Y()+gnMaxScrollDistance; } - -void HorizontalVisibleAreaScroller::operator() (const double nTime) +void VisibleAreaScroller::operator() (const double nTime) { const double nLocalTime (maAccelerationFunction(nTime)); - const sal_Int32 nNewLeft (mnStart * (1.0 - nLocalTime) + mnEnd * nLocalTime); - mrSlideSorter.GetViewShell()->Scroll( - nNewLeft - mrSlideSorter.GetController().GetScrollBarManager().GetLeft(), - 0); - mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); + mrSlideSorter.GetController().GetScrollBarManager().SetTopLeft( + Point( + sal_Int32(0.5 + maStart.X() * (1.0 - nLocalTime) + maEnd.X() * nLocalTime), + sal_Int32 (0.5 + maStart.Y() * (1.0 - nLocalTime) + maEnd.Y() * nLocalTime))); } } // end of anonymous namespace diff --git a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx index 7c1f76bf1407..4c3a71e578d7 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx @@ -131,18 +131,13 @@ public: */ Rectangle PlaceScrollBars (const Rectangle& rAvailableArea); - /** Update the vertical scroll bar so that the visible area has the - given top value. + /** Update the vertical and horizontal scroll bars so that the visible + area has the given top and left values. */ - void SetTop (const sal_Int32 nTop); + void SetTopLeft (const Point aNewTopLeft); sal_Int32 GetTop (void) const; - /** Update the horizontal scroll bar so that the visible area has the - given left value. - */ - void SetLeft (const sal_Int32 nLeft); - sal_Int32 GetLeft (void) const; /** Return the width of the vertical scroll bar, which--when diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 14ee98ffd693..3f327edc471d 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -88,7 +88,7 @@ public: virtual ~SlideSorterView (void); void Dispose (void); - enum Orientation { HORIZONTAL, VERTICAL }; + enum Orientation { HORIZONTAL, VERTICAL, GRID }; void SetOrientation (const Orientation eOrientation); Orientation GetOrientation (void) const; diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 4199afd7dc72..4ce1420157fd 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -101,7 +101,8 @@ TYPEINIT1(SlideSorterViewShell, ViewShell); SfxViewFrame* pFrame, ViewShellBase& rViewShellBase, ::Window* pParentWindow, - FrameView* pFrameViewArgument) + FrameView* pFrameViewArgument, + const bool bIsCenterPane) { ::boost::shared_ptr pViewShell; try @@ -111,6 +112,13 @@ TYPEINIT1(SlideSorterViewShell, ViewShell); pViewShell->Initialize(); if (pViewShell->mpSlideSorter.get() == NULL) pViewShell.reset(); + + // The layout of slides depends on whether the slide sorter is + // displayed in the center or the side pane. + if (bIsCenterPane) + pViewShell->mpSlideSorter->GetView().SetOrientation(view::SlideSorterView::GRID); + else + pViewShell->mpSlideSorter->GetView().SetOrientation(view::SlideSorterView::VERTICAL); } catch(Exception&) { diff --git a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx index c7b210f93056..eb4e36f803bc 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx @@ -76,7 +76,6 @@ public: void UpdateOffsets( const InsertPosition& rInsertPosition, - const Size& rRequiredSpace, const view::Layouter& GetLayouter); void ResetOffsets (void); @@ -241,11 +240,7 @@ void InsertAnimator::Implementation::SetInsertPosition ( if (pCurrentRun) { - const sal_Int32 nColumnCount (mrView.GetLayouter().GetColumnCount()); - pCurrentRun->UpdateOffsets( - rInsertPosition, - nColumnCount > 1 ? Size(rIconSize.Width(),0) : Size(0, rIconSize.Height()), - mrView.GetLayouter()); + pCurrentRun->UpdateOffsets(rInsertPosition, mrView.GetLayouter()); maRuns.insert(pCurrentRun); } } @@ -404,7 +399,6 @@ Rectangle PageObjectRun::GetInnerBoundingBox ( void PageObjectRun::UpdateOffsets( const InsertPosition& rInsertPosition, - const Size& rRequiredSpace, const view::Layouter& rLayouter) { const bool bIsVertical (rLayouter.GetColumnCount()==1); -- cgit v1.2.3 From b11b474c8b478f5672b5b64d86ed76dde019d016 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Thu, 11 Mar 2010 10:13:42 +0100 Subject: renaissance1: #i107215# Made scroll animations more smooth. Update page under mouse when scrolling. --- .../slidesorter/controller/SlsSelectionManager.cxx | 21 +++++++++++++-------- .../inc/controller/SlsSelectionManager.hxx | 4 ++++ sd/source/ui/slidesorter/view/SlideSorterView.cxx | 18 +++++++----------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 36262f22298a..2430332aacac 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -97,7 +97,8 @@ SelectionManager::SelectionManager (SlideSorter& rSlideSorter) maSelectionBeforeSwitch(), mbIsMakeSelectionVisiblePending(true), mnInsertionPosition(-1), - mnAnimationId(Animator::NotAnAnimationId) + mnAnimationId(Animator::NotAnAnimationId), + maRequestedTopLeft() { } @@ -478,19 +479,22 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) nNewLeft = aModelArea.Left(); } - // Scroll. - if (nNewTop != aVisibleArea.Top() || nNewLeft != aVisibleArea.Left()) + // Scroll when the visible area is not already at the requested location + // and there is no active animation to scroll to it. + if ((nNewTop != aVisibleArea.Top() || nNewLeft != aVisibleArea.Left()) + && (mnAnimationId==Animator::NotAnAnimationId + || maRequestedTopLeft != Point(nNewLeft,nNewTop))) { + if (mnAnimationId != Animator::NotAnAnimationId) + mrController.GetAnimator()->RemoveAnimation(mnAnimationId); + + maRequestedTopLeft = Point(nNewLeft, nNewTop); VisibleAreaScroller aAnimation( mrSlideSorter, aVisibleArea.TopLeft(), - Point(nNewLeft, nNewTop)); + maRequestedTopLeft); if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) - { - if (mnAnimationId != Animator::NotAnAnimationId) - mrController.GetAnimator()->RemoveAnimation(mnAnimationId); mnAnimationId = mrController.GetAnimator()->AddAnimation(aAnimation, 0, 300); - } else aAnimation(1.0); } @@ -667,6 +671,7 @@ VisibleAreaScroller::VisibleAreaScroller ( + void VisibleAreaScroller::operator() (const double nTime) { const double nLocalTime (maAccelerationFunction(nTime)); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx index 47bcafe134f4..6ba0d0af0715 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx @@ -176,7 +176,11 @@ private: */ sal_Int32 mnInsertionPosition; + /** Animation id for a scroll animation the will eventually set the top + and left of the visible area to maRequestedTopLeft. + */ Animator::AnimationId mnAnimationId; + Point maRequestedTopLeft; /** Delete the given list of normal pages. This method is a helper function for DeleteSelectedPages(). diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 78bced29286b..b5a13811eac3 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -478,17 +478,6 @@ void SlideSorterView::PostModelChange (void) // The new page objects have to be scaled and positioned. Layout(); RequestRepaint(); - - // Restore the mouse over state. - SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - if (pWindow) - { - const Window::PointerState aPointerState (pWindow->GetPointerState()); - UpdatePageUnderMouse ( - aPointerState.maPos, - (aPointerState.mnState & MOUSE_LEFT)!=0, - false); - } } @@ -645,6 +634,13 @@ void SlideSorterView::DeterminePageObjectVisibilities (void) aRange.IsInside(nIndex)); } maVisiblePageRange = aRange; + + // Restore the mouse over state. + const Window::PointerState aPointerState (pWindow->GetPointerState()); + UpdatePageUnderMouse ( + aPointerState.maPos, + (aPointerState.mnState & MOUSE_LEFT)!=0, + false); } } -- cgit v1.2.3 From b21a5ef9255b086a639c0d615f104062f92f4ab9 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Thu, 11 Mar 2010 16:21:09 +0100 Subject: renaissance1: #i107215# Fixed drag-and-drop when used with auto-scrolling. Improved hide/show handling. --- sd/sdi/SlideSorterController.sdi | 5 + sd/source/ui/inc/ViewShell.hxx | 39 ++-- .../controller/SlsDragAndDropContext.cxx | 50 +---- .../controller/SlsDragAndDropContext.hxx | 4 - .../slidesorter/controller/SlsScrollBarManager.cxx | 4 +- .../controller/SlsSelectionFunction.cxx | 235 +++++++-------------- .../ui/slidesorter/controller/SlsSlotManager.cxx | 96 ++++++--- .../inc/controller/SlsSelectionFunction.hxx | 17 +- .../slidesorter/inc/controller/SlsSlotManager.hxx | 13 ++ .../ui/slidesorter/inc/model/SlideSorterModel.hxx | 14 ++ .../ui/slidesorter/inc/view/SlideSorterView.hxx | 7 + .../ui/slidesorter/model/SlideSorterModel.cxx | 34 +++ .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 5 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 110 +++++++--- sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 28 ++- sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx | 2 + 16 files changed, 358 insertions(+), 305 deletions(-) diff --git a/sd/sdi/SlideSorterController.sdi b/sd/sdi/SlideSorterController.sdi index ff64d80bd8af..8affd602f376 100644 --- a/sd/sdi/SlideSorterController.sdi +++ b/sd/sdi/SlideSorterController.sdi @@ -88,6 +88,11 @@ interface SlideSorterView ExecMethod = FuTemporary ; StateMethod = GetMenuState ; ] + SID_DUPLICATE_PAGE + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] SID_DELETE_PAGE [ ExecMethod = FuTemporary ; diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 84587e6464a3..130f4ed6cbcd 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -451,6 +451,26 @@ public: void AdaptDefaultsForChart( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > & xEmbObj ); + /** Depending on the given request create a new page or duplicate an + existing one. A new page is created behind the given slide. + @param rRequest + The request as passed to an Execute() method. Its arguments are + evaluated. Its slot id determines whether to create or + duplicate a slide. + @param pPage + This page is either duplicated or becomes the predecessor of the + new slide. If NULL a duplication request is ignored. A new + slide is inserted as first slide. + @return + The new slide is returned. If for some reason a new page can + not be created then NULL is returned. + */ + virtual SdPage* CreateOrDuplicatePage ( + SfxRequest& rRequest, + PageKind ePageKind, + SdPage* pPage); + + class Implementation; protected: @@ -549,25 +569,6 @@ protected: virtual void SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY ); - /** Depending on the given request create a new page or duplicate an - existing one. A new page is created behind the given slide. - @param rRequest - The request as passed to an Execute() method. Its arguments are - evaluated. Its slot id determines whether to create or - duplicate a slide. - @param pPage - This page is either duplicated or becomes the predecessor of the - new slide. If NULL a duplication request is ignored. A new - slide is inserted as first slide. - @return - The new slide is returned. If for some reason a new page can - not be created then NULL is returned. - */ - virtual SdPage* CreateOrDuplicatePage ( - SfxRequest& rRequest, - PageKind ePageKind, - SdPage* pPage); - private: ::Window* mpParentWindow; /** This window updater is used to keep all relevant windows up to date diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx index 21b3f3f5b942..5f98f3dc95f0 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -65,6 +65,14 @@ DragAndDropContext::DragAndDropContext (SlideSorter& rSlideSorter) +DragAndDropContext::~DragAndDropContext (void) +{ + SetTargetSlideSorter (NULL, Point(0,0), InsertionIndicatorHandler::UnknownMode, false); +} + + + + void DragAndDropContext::GetPagesFromBookmarks ( ::std::vector& rPages, sal_Int32& rnSelectionCount, @@ -116,22 +124,6 @@ void DragAndDropContext::GetPagesFromSelection ( -DragAndDropContext::~DragAndDropContext (void) -{ - if (mpTargetSlideSorter != NULL) - mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll(); - - Process(); - - if (mpTargetSlideSorter != NULL) - { - mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); - } -} - - - - void DragAndDropContext::Dispose (void) { mnInsertionIndex = -1; @@ -177,31 +169,6 @@ void DragAndDropContext::UpdatePosition ( -void DragAndDropContext::Process (void) -{ - if (mpTargetSlideSorter == NULL) - return; - - if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly()) - return; - - if (mnInsertionIndex >= 0) - { - // Tell the model to move the selected pages behind the one with the - // index mnInsertionIndex which first has to transformed into an index - // understandable by the document. - USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1; - mpTargetSlideSorter->GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex); - - ViewShell* pViewShell = mpTargetSlideSorter->GetViewShell(); - if (pViewShell != NULL) - pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE); - } -} - - - - void DragAndDropContext::Show (void) { } @@ -224,6 +191,7 @@ void DragAndDropContext::SetTargetSlideSorter ( { if (mpTargetSlideSorter != NULL) { + mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll(); mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); } diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx index 26df6f2c04a1..3f0a4e3547d7 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx @@ -93,10 +93,6 @@ private: ::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/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index 63179c4dbcf9..1537adec84b5 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -55,8 +55,8 @@ ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter) mnHorizontalPosition (0), mnVerticalPosition (0), maScrollBorder (20,20), - mnHorizontalScrollFactor (0.1), - mnVerticalScrollFactor (0.1), + mnHorizontalScrollFactor (0.15), + mnVerticalScrollFactor (0.25), mpScrollBarFiller(mrSlideSorter.GetScrollBarFiller()), maAutoScrollTimer(), maAutoScrollOffset(0,0), diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 02d484e7223e..8880100a918a 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -46,6 +46,7 @@ #include "controller/SlsSelectionManager.hxx" #include "controller/SlsProperties.hxx" #include "controller/SlsProperties.hxx" +#include "controller/SlsSlotManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" @@ -116,6 +117,8 @@ namespace sd { namespace slidesorter { namespace controller { class SelectionFunction::MouseMultiSelector { public: + /** Start a rectangle selection at the given position. + */ MouseMultiSelector ( SlideSorter& rSlideSorter, const Point& rMouseModelPosition); @@ -134,50 +137,23 @@ public: void SetSelectionMode (const SelectionMode eSelectionMode); void SetSelectionModeFromModifier (const sal_uInt32 nEventCode); -protected: +private: SlideSorter& mrSlideSorter; SelectionMode meSelectionMode; - ::std::set maInitialSelection; + Point maSecondCorner; + Pointer maSavedPointer; + sal_Int32 mnAnchorIndex; + sal_Int32 mnSecondIndex; - virtual void UpdateModelPosition (const Point& rMouseModelPosition) = 0; - virtual void UpdateSelection (void) = 0; + virtual void UpdateModelPosition (const Point& rMouseModelPosition); + virtual void UpdateSelection (void); void UpdateSelectionState ( const model::SharedPageDescriptor& rpDescriptor, const bool bIsInSelection) const; }; -namespace { - - class RangeSelector - : public SelectionFunction::MouseMultiSelector - { - public: - /** Start a rectangle selection at the given position. - */ - RangeSelector ( - SlideSorter& rSlideSorter, - const Point& rMouseModelPosition); - virtual ~RangeSelector (void); - - protected: - virtual void UpdateModelPosition (const Point& rMouseModelPosition); - - /** Select all pages that lie completly in the selection rectangle. - */ - virtual void UpdateSelection (void); - - private: - Point maAnchor; - Point maSecondCorner; - Pointer maSavedPointer; - sal_Int32 mnAnchorIndex; - sal_Int32 mnSecondIndex; - - Rectangle GetBoundingBox (void) const; - }; -} // end of anonymous namespace class SelectionFunction::EventDescriptor @@ -273,7 +249,10 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) { Point aMousePosition (rEvent.GetPosPixel()); - UpdatePageUnderMouse(aMousePosition, (rEvent.GetButtons() & MOUSE_LEFT)!=0); + mrSlideSorter.GetView().UpdatePageUnderMouse( + aMousePosition, + (rEvent.GetButtons() & MOUSE_LEFT)!=0, + true); // Detect the mouse leaving the window. When not button is pressed then // we can call IsLeaveWindow at the event. Otherwise we have to make an @@ -281,11 +260,7 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) if (rEvent.IsLeaveWindow() || ! Rectangle(Point(0,0),mpWindow->GetOutputSizePixel()).IsInside(aMousePosition)) { - if (mpDragAndDropContext) - { - mpDragAndDropContext->Hide(); - mpDragAndDropContext.reset(); - } + StopDragAndDrop(); mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); } else @@ -328,13 +303,7 @@ void SelectionFunction::MouseDragged ( InsertionIndicatorHandler::GetModeFromDndAction(nDragAction));//rEvent.mnAction)); if (rEvent.mbLeaving) { - if (mpDragAndDropContext) - { - // Disconnect the substitution handler from this selection function. - mpDragAndDropContext->Hide(); - mpDragAndDropContext->SetTargetSlideSorter(); - mpDragAndDropContext.reset(); - } + StopDragAndDrop(); } else if ( ! mpDragAndDropContext) { @@ -345,6 +314,7 @@ void SelectionFunction::MouseDragged ( pDragTransferable != NULL && pDragTransferable->GetView()==&mrSlideSorter.GetView()); mpDragAndDropContext->UpdatePosition(rEvent.maPosPixel, eMode); + UpdateMouseOverIndicationPermission(); } // 1. Compute some frequently used values relating to the event. @@ -373,12 +343,7 @@ void SelectionFunction::MouseDragged ( void SelectionFunction::NotifyDragFinished (void) { - if (mpDragAndDropContext) - { - mpDragAndDropContext->Dispose(); - mpDragAndDropContext.reset(); - } - mrController.GetInsertionIndicatorHandler()->End(); + StopDragAndDrop(); } @@ -430,15 +395,12 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) if ( ! (mpDragAndDropContext || mpMouseMultiSelector)) rFocusManager.SetFocusToToolBox(); - if (mpDragAndDropContext) - { - mpDragAndDropContext->Dispose(); - mpDragAndDropContext.reset(); - } + StopDragAndDrop(); if (mpMouseMultiSelector) { - mpMouseMultiSelector->RestoreInitialSelection(); - mpMouseMultiSelector.reset(); + mrSlideSorter.GetView().RequestRepaint( + mrSlideSorter.GetModel().RestoreSelection()); + StopMouseMultiSelection(); } bResult = TRUE; break; @@ -703,6 +665,7 @@ void SelectionFunction::StartDrag ( { mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter)); mrController.GetInsertionIndicatorHandler()->Start(true); + UpdateMouseOverIndicationPermission(); } mpDragAndDropContext->UpdatePosition(rMousePosition, eMode); mpWindow->ReleaseMouse(); @@ -721,16 +684,14 @@ bool SelectionFunction::cancel (void) -void SelectionFunction::UpdatePageUnderMouse ( - const Point& rMousePosition, - const bool bIsMouseButtonDown) +void SelectionFunction::UpdateMouseOverIndicationPermission (void) { + // In some modes (dragging, moving) the mouse over indicator is only // annoying. Turn it off in these cases. - if (mpDragAndDropContext || mpMouseMultiSelector) - mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); - else - mrSlideSorter.GetView().UpdatePageUnderMouse(rMousePosition, bIsMouseButtonDown); + mrSlideSorter.GetView().SetIsMouseOverIndicationAllowed( + ! mpDragAndDropContext + && ! mpMouseMultiSelector); } @@ -1034,7 +995,7 @@ void SelectionFunction::ProcessEventWhileDragActive (EventDescriptor& rDescripto // The following Process() call may lead to the desctruction // of rDescriptor.mpHitDescriptor so release our reference to it. rDescriptor.mpHitDescriptor.reset(); - mpDragAndDropContext.reset(); + StopDragAndDrop(); } } @@ -1056,13 +1017,13 @@ void SelectionFunction::ProcessEventWhileMultiSelectorActive (EventDescriptor& r } else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK)) { - mpMouseMultiSelector.reset(); + StopMouseMultiSelection(); } // Anything else stops the rectangle selection and the event is // processed again. else { - mpMouseMultiSelector.reset(); + StopMouseMultiSelection(); rDescriptor.mnEventCode &= ~MULTI_SELECTOR; ProcessEvent(rDescriptor); } @@ -1130,6 +1091,9 @@ void SelectionFunction::ProcessButtonDownEvent (EventDescriptor& rDescriptor) case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: // Fallthrough. case ANY_MODIFIER(BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): + // Remember the current selection so that when a multi selection + // is started, we can restore the previous selection. + mrSlideSorter.GetModel().SaveCurrentSelection(); DeselectAllPages(); break; } @@ -1194,8 +1158,9 @@ void SelectionFunction::ProcessMouseMotionEvent (const EventDescriptor& rDescrip case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): OSL_ASSERT(!mpMouseMultiSelector); mpMouseMultiSelector.reset( - new RangeSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); + new MouseMultiSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); + UpdateMouseOverIndicationPermission(); break; } } @@ -1281,14 +1246,13 @@ void SelectionFunction::ProcessButtonClick ( case 1: // Toggle exclusion state. - rSelector.DeselectAllPages(); - rSelector.SelectPage(rpDescriptor); - if (mrSlideSorter.GetViewShell() != NULL) - mrSlideSorter.GetViewShell()->GetDispatcher()->Execute( - rpDescriptor->HasState(model::PageDescriptor::ST_Excluded) - ? SID_SHOW_SLIDE - : SID_HIDE_SLIDE, - SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); + if ( ! rpDescriptor) + return; + mrSlideSorter.GetController().GetSlotManager()->ChangeSlideExclusionState( + (rpDescriptor->HasState(model::PageDescriptor::ST_Selected) + ? model::SharedPageDescriptor() + : rpDescriptor), + ! rpDescriptor->HasState(model::PageDescriptor::ST_Excluded)); break; case 0: @@ -1306,6 +1270,34 @@ void SelectionFunction::ProcessButtonClick ( +void SelectionFunction::StopDragAndDrop (void) +{ + if (mpDragAndDropContext) + { + // Disconnect the substitution handler from this selection function. + mpDragAndDropContext->Hide(); + mpDragAndDropContext->SetTargetSlideSorter(); + mpDragAndDropContext.reset(); + UpdateMouseOverIndicationPermission(); + } + mrController.GetInsertionIndicatorHandler()->End(); +} + + + + +void SelectionFunction::StopMouseMultiSelection (void) +{ + if (mpMouseMultiSelector) + { + mpMouseMultiSelector.reset(); + UpdateMouseOverIndicationPermission(); + } +} + + + + //===== EventDescriptor ======================================================= SelectionFunction::EventDescriptor::EventDescriptor ( @@ -1391,20 +1383,13 @@ SelectionFunction::MouseMultiSelector::MouseMultiSelector ( const Point& rMouseModelPosition) : mrSlideSorter(rSlideSorter), meSelectionMode(SM_Normal), - maInitialSelection() + maSecondCorner(rMouseModelPosition), + maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()), + mnAnchorIndex(-1), + mnSecondIndex(-1) { - (void)rMouseModelPosition; - // Remember the current selection. - model::PageEnumeration aPages ( - model::PageEnumerationProvider::CreateAllPagesEnumeration( - mrSlideSorter.GetModel())); - while (aPages.HasMoreElements()) - { - model::SharedPageDescriptor pDescriptor (aPages.GetNextElement()); - pDescriptor->SetState( - model::PageDescriptor::ST_WasSelected, - pDescriptor->HasState(model::PageDescriptor::ST_Selected)); - } + const Pointer aSelectionPointer (POINTER_TEXT); + mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer); } @@ -1412,26 +1397,7 @@ SelectionFunction::MouseMultiSelector::MouseMultiSelector ( SelectionFunction::MouseMultiSelector::~MouseMultiSelector (void) { -} - - - - -void SelectionFunction::MouseMultiSelector::RestoreInitialSelection (void) -{ - // Remember the current selection. - model::PageEnumeration aPages ( - model::PageEnumerationProvider::CreateAllPagesEnumeration( - mrSlideSorter.GetModel())); - view::SlideSorterView& rView (mrSlideSorter.GetView()); - while (aPages.HasMoreElements()) - { - model::SharedPageDescriptor pDescriptor (aPages.GetNextElement()); - pDescriptor->SetState( - model::PageDescriptor::ST_Selected, - pDescriptor->HasState(model::PageDescriptor::ST_WasSelected)); - rView.RequestRepaint(pDescriptor); - } + mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer); } @@ -1534,35 +1500,7 @@ void SelectionFunction::MouseMultiSelector::UpdateSelectionState ( -//===== RangeSelector ========================================================= - -namespace { - -RangeSelector::RangeSelector ( - SlideSorter& rSlideSorter, - const Point& rMouseModelPosition) - : MouseMultiSelector(rSlideSorter,rMouseModelPosition), - maAnchor(rMouseModelPosition), - maSecondCorner(rMouseModelPosition), - maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()), - mnAnchorIndex(-1) -{ - const Pointer aSelectionPointer (POINTER_TEXT); - mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer); -} - - - - -RangeSelector::~RangeSelector (void) -{ - mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer); -} - - - - -void RangeSelector::UpdateModelPosition (const Point& rMouseModelPosition) +void SelectionFunction::MouseMultiSelector::UpdateModelPosition (const Point& rMouseModelPosition) { maSecondCorner = rMouseModelPosition; UpdateSelection(); @@ -1571,7 +1509,7 @@ void RangeSelector::UpdateModelPosition (const Point& rMouseModelPosition) -void RangeSelector::UpdateSelection (void) +void SelectionFunction::MouseMultiSelector::UpdateSelection (void) { view::SlideSorterView::DrawLock aLock (mrSlideSorter); @@ -1606,17 +1544,4 @@ void RangeSelector::UpdateSelection (void) -Rectangle RangeSelector::GetBoundingBox (void) const -{ - return 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())); -} - - -} // end of anonymous namespace - - } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 8f1d6722cec0..ee0b542eaf25 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -96,6 +96,8 @@ #include #include +#include + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::presentation; @@ -109,8 +111,6 @@ namespace { */ enum SlideExclusionState {UNDEFINED, EXCLUDED, INCLUDED, MIXED}; -void ChangeSlideExclusionState (SlideSorter& rSlideSorter, SfxRequest& rRequest); - /** Return for the given set of slides whether they included are excluded from the slide show. */ @@ -155,8 +155,11 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) break; case SID_HIDE_SLIDE: + ChangeSlideExclusionState(model::SharedPageDescriptor(), true); + break; + case SID_SHOW_SLIDE: - ChangeSlideExclusionState(mrSlideSorter, rRequest); + ChangeSlideExclusionState(model::SharedPageDescriptor(), false); break; case SID_PAGES_PER_ROW: @@ -241,6 +244,11 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) rRequest.Done(); break; + case SID_DUPLICATE_PAGE: + DuplicateSelectedSlides(rRequest); + rRequest.Done(); + break; + case SID_DELETE_PAGE: case SID_DELETE_MASTER_PAGE: case SID_DELETE: // we need SID_CUT to handle the delete key @@ -1192,6 +1200,34 @@ void SlotManager::InsertSlide (SfxRequest& rRequest) +void SlotManager::DuplicateSelectedSlides (SfxRequest& rRequest) +{ + // Create a list of the pages that are to be duplicated. The process of + // duplication alters the selection. + ::std::vector aPagesToDuplicate; + model::PageEnumeration aSelectedPages ( + model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); + while (aSelectedPages.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); + if (pDescriptor && pDescriptor->GetPage()) + aPagesToDuplicate.push_back(pDescriptor->GetPage()); + } + + for_each ( + aPagesToDuplicate.begin(), + aPagesToDuplicate.end(), + ::boost::bind( + &ViewShell::CreateOrDuplicatePage, + mrSlideSorter.GetViewShell(), + ::boost::ref(rRequest), + PK_STANDARD, + _1)); +} + + + + void SlotManager::AssignTransitionEffect (void) { model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); @@ -1251,59 +1287,49 @@ IMPL_LINK(SlotManager, UserEventCallback, void*, EMPTYARG) -//----------------------------------------------------------------------------- - -namespace { - -void ChangeSlideExclusionState ( - SlideSorter& rSlideSorter, - SfxRequest& rRequest) +void SlotManager::ChangeSlideExclusionState ( + const model::SharedPageDescriptor& rpDescriptor, + const bool bExcludeSlide) { - model::PageEnumeration aSelectedPages ( - model::PageEnumerationProvider::CreateSelectedPagesEnumeration(rSlideSorter.GetModel())); - - SlideExclusionState eState (UNDEFINED); - - switch (rRequest.GetSlot()) + if (rpDescriptor) { - case SID_HIDE_SLIDE: - eState = EXCLUDED; - break; - - case SID_SHOW_SLIDE: - eState = INCLUDED; - break; - - default: - eState = UNDEFINED; - break; + mrSlideSorter.GetView().SetState( + rpDescriptor, + model::PageDescriptor::ST_Excluded, + bExcludeSlide); } - - if (eState != UNDEFINED) + else { - // Set status at the selected pages. - aSelectedPages.Rewind (); + model::PageEnumeration aSelectedPages ( + model::PageEnumerationProvider::CreateSelectedPagesEnumeration( + mrSlideSorter.GetModel())); while (aSelectedPages.HasMoreElements()) { model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); - rSlideSorter.GetView().SetState( + mrSlideSorter.GetView().SetState( pDescriptor, model::PageDescriptor::ST_Excluded, - eState==EXCLUDED); + bExcludeSlide); } } - SfxBindings& rBindings = rSlideSorter.GetViewShell()->GetViewFrame()->GetBindings(); + SfxBindings& rBindings (mrSlideSorter.GetViewShell()->GetViewFrame()->GetBindings()); rBindings.Invalidate(SID_PRESENTATION); rBindings.Invalidate(SID_REHEARSE_TIMINGS); rBindings.Invalidate(SID_HIDE_SLIDE); rBindings.Invalidate(SID_SHOW_SLIDE); - rSlideSorter.GetModel().GetDocument()->SetChanged(); + mrSlideSorter.GetModel().GetDocument()->SetChanged(); } +//----------------------------------------------------------------------------- + +namespace { + + + SlideExclusionState GetSlideExclusionState (model::PageEnumeration& rPageSet) { SlideExclusionState eState (UNDEFINED); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index 71315adbbb1c..a6995f88bdcd 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -102,19 +102,13 @@ public: */ void NotifyDragFinished (void); - /** This is the higher level version of the - SlideSorterView::UpdatePageUnderMouse() method. - It does not update the page under the mouse when an operation is - active that (logically) captures the mouse. + /** Call when drag-and-drop or multi selection is started or stopped in + order to update permission of mouse over indication. */ - void UpdatePageUnderMouse ( - const Point& rMousePosition, - const bool bIsMouseButtonDown); + void UpdateMouseOverIndicationPermission (void); ::boost::shared_ptr GetDragAndDropContext (void) const; - class MouseMultiSelector; - protected: SlideSorter& mrSlideSorter; SlideSorterController& mrController; @@ -144,6 +138,8 @@ private: bool mbProcessingMouseButtonDown; ::boost::shared_ptr mpDragAndDropContext; + + class MouseMultiSelector; ::boost::scoped_ptr mpMouseMultiSelector; /** Remember where the left mouse button was pressed. @@ -231,6 +227,9 @@ private: const FocusManager::FocusMoveDirection eDirection, const bool bIsShiftDown, const bool bIsControlDown); + + void StopDragAndDrop (void); + void StopMouseMultiSelection (void); }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx index 06e16c604500..e84262c8b677 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx @@ -30,6 +30,7 @@ #ifndef SD_SLIDESORTER_SLOT_MANAGER_HXX #define SD_SLIDESORTER_SLOT_MANAGER_HXX +#include "model/SlsSharedPageDescriptor.hxx" #include #include #include @@ -75,6 +76,16 @@ public: void ExecuteCommandAsynchronously (::std::auto_ptr pCommand); + /** Exclude or include one slide or all selected slides. + @param rpDescriptor + When the pointer is empty then apply the new state to all + selected pages. Otherwise apply the new state to just the + specified state. + */ + void ChangeSlideExclusionState ( + const model::SharedPageDescriptor& rpDescriptor, + const bool bExcludeSlide); + private: /// The controller for which we manage the slot calls. SlideSorter& mrSlideSorter; @@ -97,6 +108,8 @@ private: */ void InsertSlide (SfxRequest& rRequest); + void DuplicateSelectedSlides (SfxRequest& rRequest); + void AssignTransitionEffect (void); DECL_LINK(UserEventCallback, void*); diff --git a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx index e8fed3b423ce..84f0f11b8e2f 100644 --- a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx @@ -39,6 +39,7 @@ class SdDrawDocument; #include "pres.hxx" #include #include +#include #include #include @@ -196,6 +197,19 @@ public: bool IsReadOnly (void) const; + /** The current selection is saved by copying the ST_Selected state into + ST_WasSelected for slides. + */ + void SaveCurrentSelection (void); + + /** The current selection is restored from the ST_WasSelected state from + the slides. + @returns + The returned region has to be repainted to reflect the updated + selection states. + */ + Region RestoreSelection (void); + private: mutable ::osl::Mutex maMutex; SlideSorter& mrSlideSorter; diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 3f327edc471d..a9cad51af652 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -95,6 +95,7 @@ public: void RequestRepaint (void); void RequestRepaint (const model::SharedPageDescriptor& rDescriptor); void RequestRepaint (const Rectangle& rRepaintBox); + void RequestRepaint (const Region& rRepaintRegion); Rectangle GetModelArea (void); @@ -190,6 +191,11 @@ public: */ void AddSdrObject (SdrObject& rObject); + /** The page under the mouse is not highlighted in some contexts. Call + this method on context changes. + */ + void SetIsMouseOverIndicationAllowed (const bool bIsAllowed); + void UpdatePageUnderMouse (bool bAnimate); void UpdatePageUnderMouse ( const Point& rMousePosition, const bool bIsMouseButtonDown, @@ -241,6 +247,7 @@ private: Orientation meOrientation; ::boost::shared_ptr mpProperties; model::SharedPageDescriptor mpPageUnderMouse; + bool mbIsMouseOverIndicationAllowed; sal_Int32 mnButtonUnderMouse; ::boost::shared_ptr mpPageObjectPainter; ::boost::shared_ptr mpSelectionPainter; diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx index f60b8494edfd..ee5c0dfd45e0 100644 --- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx +++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx @@ -515,4 +515,38 @@ bool SlideSorterModel::IsReadOnly (void) const + +void SlideSorterModel::SaveCurrentSelection (void) +{ + PageEnumeration aPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this)); + while (aPages.HasMoreElements()) + { + SharedPageDescriptor pDescriptor (aPages.GetNextElement()); + pDescriptor->SetState( + PageDescriptor::ST_WasSelected, + pDescriptor->HasState(PageDescriptor::ST_Selected)); + } +} + + + + +Region SlideSorterModel::RestoreSelection (void) +{ + Region aRepaintRegion; + PageEnumeration aPages (PageEnumerationProvider::CreateAllPagesEnumeration(*this)); + while (aPages.HasMoreElements()) + { + SharedPageDescriptor pDescriptor (aPages.GetNextElement()); + if (pDescriptor->SetState( + PageDescriptor::ST_Selected, + pDescriptor->HasState(PageDescriptor::ST_WasSelected))) + { + aRepaintRegion.Union(pDescriptor->GetBoundingBox()); + } + } + return aRepaintRegion; +} + + } } } // end of namespace ::sd::slidesorter::model diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 4ce1420157fd..f9e93f775784 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -578,10 +578,7 @@ bool SlideSorterViewShell::HandleScrollCommand (const CommandEvent& rEvent, ::sd OSL_ASSERT(mpSlideSorter.get()!=NULL); if (rEvent.GetCommand() == COMMAND_WHEEL) { - ::rtl::Reference pFunction ( - mpSlideSorter->GetController().GetCurrentSelectionFunction()); - if (pFunction.is()) - pFunction->UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false); + mpSlideSorter->GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false); } } diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index b5a13811eac3..16da8620fb9b 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -337,6 +337,7 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) meOrientation(VERTICAL), mpProperties(rSlideSorter.GetProperties()), mpPageUnderMouse(), + mbIsMouseOverIndicationAllowed(true), mnButtonUnderMouse(-1), mpPageObjectPainter(), mpSelectionPainter() @@ -636,11 +637,7 @@ void SlideSorterView::DeterminePageObjectVisibilities (void) maVisiblePageRange = aRange; // Restore the mouse over state. - const Window::PointerState aPointerState (pWindow->GetPointerState()); - UpdatePageUnderMouse ( - aPointerState.maPos, - (aPointerState.mnState & MOUSE_LEFT)!=0, - false); + UpdatePageUnderMouse(false); } } @@ -735,6 +732,18 @@ void SlideSorterView::RequestRepaint (const Rectangle& rRepaintBox) +void SlideSorterView::RequestRepaint (const Region& rRepaintRegion) +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + pWindow->Invalidate(rRepaintRegion); + mpLayeredDevice->InvalidateAllLayers(rRepaintRegion); + } +} + + + Rectangle SlideSorterView::GetModelArea (void) { @@ -893,31 +902,66 @@ void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint +void SlideSorterView::SetIsMouseOverIndicationAllowed (const bool bIsAllowed) +{ + mbIsMouseOverIndicationAllowed = bIsAllowed; + if ( ! mbIsMouseOverIndicationAllowed) + SetPageUnderMouse(model::SharedPageDescriptor()); + else + UpdatePageUnderMouse(false); +} + + + + +void SlideSorterView::UpdatePageUnderMouse (bool bAnimate) +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + const Window::PointerState aPointerState (pWindow->GetPointerState()); + UpdatePageUnderMouse ( + aPointerState.maPos, + (aPointerState.mnState & MOUSE_LEFT)!=0, + bAnimate); + } +} + + + + void SlideSorterView::UpdatePageUnderMouse ( const Point& rMousePosition, const bool bIsMouseButtonDown, const bool bAnimate) { - // Determine page under mouse and show the mouse over effect. - model::SharedPageDescriptor pHitDescriptor ( - mrSlideSorter.GetController().GetPageAt(rMousePosition)); - SetPageUnderMouse(pHitDescriptor, bAnimate); - - // Handle the mouse being over any buttons. - if (pHitDescriptor) + if ( ! mbIsMouseOverIndicationAllowed) { - SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); - const sal_Int32 nButtonIndex ( - GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt ( - pHitDescriptor, - aMouseModelPosition)); - SetButtonUnderMouse(nButtonIndex); - if (bIsMouseButtonDown) + SetPageUnderMouse(model::SharedPageDescriptor()); + } + else + { + // Determine page under mouse and show the mouse over effect. + model::SharedPageDescriptor pHitDescriptor ( + mrSlideSorter.GetController().GetPageAt(rMousePosition)); + SetPageUnderMouse(pHitDescriptor, bAnimate); + + // Handle the mouse being over any buttons. + if (pHitDescriptor) { - pHitDescriptor->GetVisualState().SetActiveButtonState( - nButtonIndex, - model::VisualState::BS_Pressed); + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + const sal_Int32 nButtonIndex ( + GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt ( + pHitDescriptor, + aMouseModelPosition)); + SetButtonUnderMouse(nButtonIndex); + if (bIsMouseButtonDown) + { + pHitDescriptor->GetVisualState().SetActiveButtonState( + nButtonIndex, + model::VisualState::BS_Pressed); + } } } } @@ -998,7 +1042,11 @@ bool SlideSorterView::SetState ( const bool bStateValue, const bool bAnimate) { - const bool bModified (rpDescriptor->SetState(eState, bStateValue)); + model::SharedPageDescriptor pDescriptor (rpDescriptor); + if ( ! pDescriptor) + return false; + + const bool bModified (pDescriptor->SetState(eState, bStateValue)); if ( ! bModified) return false; @@ -1010,7 +1058,7 @@ bool SlideSorterView::SetState ( case PageDescriptor::ST_MouseOver: case PageDescriptor::ST_Current: case PageDescriptor::ST_Excluded: - RequestRepaint(rpDescriptor); + RequestRepaint(pDescriptor); break; case PageDescriptor::ST_WasSelected: @@ -1024,11 +1072,11 @@ bool SlideSorterView::SetState ( const double nEndAlpha (bStateValue ? 0.2 : 1.0); if (bAnimate) { - const double nStartAlpha (rpDescriptor->GetVisualState().GetButtonAlpha()); + const double nStartAlpha (pDescriptor->GetVisualState().GetButtonAlpha()); // Stop a running animation. const Animator::AnimationId nId ( - rpDescriptor->GetVisualState().GetButtonAlphaAnimationId()); + pDescriptor->GetVisualState().GetButtonAlphaAnimationId()); if (nId != Animator::NotAnAnimationId) mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(nId); @@ -1038,24 +1086,24 @@ bool SlideSorterView::SetState ( nStartAlpha, nEndAlpha, ::boost::bind(AnimationFunction::Linear, _1))); - rpDescriptor->GetVisualState().SetButtonAlphaAnimationId( + pDescriptor->GetVisualState().SetButtonAlphaAnimationId( mrSlideSorter.GetController().GetAnimator()->AddAnimation( ::boost::bind( AnimationFunction::ApplyButtonAlphaChange, - rpDescriptor, + pDescriptor, ::boost::ref(*this), ::boost::bind(aBlendFunctor, _1)), bStateValue ? 500 : 0, 400, ::boost::bind( &VisualState::SetButtonAlphaAnimationId, - ::boost::ref(rpDescriptor->GetVisualState()), + ::boost::ref(pDescriptor->GetVisualState()), controller::Animator::NotAnAnimationId) )); } else { - rpDescriptor->GetVisualState().SetButtonAlpha(nEndAlpha); + pDescriptor->GetVisualState().SetButtonAlpha(nEndAlpha); } } diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx index 05bb9791a200..b625e60865b6 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx @@ -110,7 +110,8 @@ public: ~Layer (void); void Initialize (const SharedSdWindow& rpTargetWindow); - void Invalidate (const Rectangle& rInvalidationBox); + void InvalidateRectangle (const Rectangle& rInvalidationBox); + void InvalidateRegion (const Region& rInvalidationRegion); void Validate (const MapMode& rMapMode); void Repaint ( OutputDevice& rTargetDevice, @@ -177,7 +178,7 @@ void LayeredDevice::Invalidate ( return; } - (*mpLayers)[nLayer]->Invalidate(rInvalidationArea); + (*mpLayers)[nLayer]->InvalidateRectangle(rInvalidationArea); } @@ -186,7 +187,16 @@ void LayeredDevice::Invalidate ( void LayeredDevice::InvalidateAllLayers (const Rectangle& rInvalidationArea) { for (sal_uInt32 nLayer=0; nLayersize(); ++nLayer) - (*mpLayers)[nLayer]->Invalidate(rInvalidationArea); + (*mpLayers)[nLayer]->InvalidateRectangle(rInvalidationArea); +} + + + + +void LayeredDevice::InvalidateAllLayers (const Region& rInvalidationRegion) +{ + for (sal_uInt32 nLayer=0; nLayersize(); ++nLayer) + (*mpLayers)[nLayer]->InvalidateRegion(rInvalidationRegion); } @@ -343,7 +353,7 @@ void LayeredDevice::HandleMapModeChange (void) ::std::for_each( mpLayers->begin(), mpLayers->end(), - ::boost::bind(&Layer::Invalidate, _1, ::boost::cref(aLogicWindowBox))); + ::boost::bind(&Layer::InvalidateRectangle, _1, ::boost::cref(aLogicWindowBox))); } else if (maSavedMapMode.GetOrigin() != rMapMode.GetOrigin()) { @@ -410,7 +420,7 @@ void Layer::Initialize (const SharedSdWindow& rpTargetWindow) -void Layer::Invalidate (const Rectangle& rInvalidationBox) +void Layer::InvalidateRectangle (const Rectangle& rInvalidationBox) { maInvalidationRegion.Union(rInvalidationBox); } @@ -418,6 +428,14 @@ void Layer::Invalidate (const Rectangle& rInvalidationBox) +void Layer::InvalidateRegion (const Region& rInvalidationRegion) +{ + maInvalidationRegion.Union(rInvalidationRegion); +} + + + + void Layer::Validate (const MapMode& rMapMode) { if (mpLayerDevice && ! maInvalidationRegion.IsEmpty()) diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx index 405da65cb8eb..b428ae7e427c 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx @@ -62,6 +62,8 @@ public: const sal_Int32 nLayer); void InvalidateAllLayers ( const Rectangle& rInvalidationBox); + void InvalidateAllLayers ( + const Region& rInvalidationRegion); void RegisterPainter ( const SharedILayerPainter& rPainter, -- cgit v1.2.3 From ab3853cc3cd60a0c9a98e20d00568fca99bb01dc Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Thu, 11 Mar 2010 18:35:45 +0100 Subject: renaissance1: #i107215# Duplicating several slides inserts them in single row after selection. --- sd/inc/drawdoc.hxx | 19 +++++++--- sd/source/core/drawdoc2.cxx | 34 +++++++++++------- sd/source/ui/inc/DrawViewShell.hxx | 3 +- sd/source/ui/inc/ViewShell.hxx | 6 +++- .../controller/SlsInsertionIndicatorHandler.cxx | 4 +-- .../controller/SlsSelectionFunction.cxx | 18 +++++++--- .../ui/slidesorter/controller/SlsSlotManager.cxx | 41 ++++++++++++++++++---- .../ui/slidesorter/inc/view/SlsInsertAnimator.hxx | 4 +-- .../ui/slidesorter/view/SlsInsertAnimator.cxx | 16 +++------ sd/source/ui/view/drviews2.cxx | 5 +-- sd/source/ui/view/viewshe3.cxx | 12 ++++--- 11 files changed, 108 insertions(+), 54 deletions(-) diff --git a/sd/inc/drawdoc.hxx b/sd/inc/drawdoc.hxx index 975722604df9..db8c37f6d95d 100644 --- a/sd/inc/drawdoc.hxx +++ b/sd/inc/drawdoc.hxx @@ -509,6 +509,9 @@ public: This flag indicates whether to show the background shape. @param bIsPageObj This flag indicates whether to show the shapes on the master page. + @param nInsertPosition + Position where to insert the standard page. When -1 then the + new page set is inserted after the current page. @return Returns an index of the inserted pages that can be used with the @@ -522,7 +525,8 @@ public: AutoLayout eStandardLayout, AutoLayout eNotesLayout, BOOL bIsPageBack, - BOOL bIsPageObj); + BOOL bIsPageObj, + const sal_Int32 nInsertPosition = -1); /** This method acts as a simplified front end for the more complex DuplicatePage() method. @@ -565,6 +569,9 @@ public: This flag indicates whether to show the background shape. @param bIsPageObj This flag indicates whether to show the shapes on the master page. + @param nInsertPosition + Position where to insert the standard page. When -1 then the + new page set is inserted after the current page. @return Returns an index of the inserted pages that can be used with the @@ -578,7 +585,8 @@ public: AutoLayout eStandardLayout, AutoLayout eNotesLayout, BOOL bIsPageBack, - BOOL bIsPageObj); + BOOL bIsPageObj, + const sal_Int32 nInsertPosition = -1); /** return the document fonts for latin, cjk and ctl according to the current languages set at this document */ @@ -636,6 +644,9 @@ private: The standard page to insert. @param pNotesPage The notes page to insert. + @param nInsertPosition + Position where to insert the standard page. When -1 then the + new page set is inserted after the current page. @return Returns an index of the inserted pages that can be used with the @@ -650,9 +661,9 @@ private: AutoLayout eNotesLayout, BOOL bIsPageBack, BOOL bIsPageObj, - SdPage* pStandardPage, - SdPage* pNotesPage); + SdPage* pNotesPage, + sal_Int32 nInsertPosition = -1); /** Set up a newly created page and insert it into the list of pages. @param pPreviousPage diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx index e208399d636f..eb279d639ce8 100644 --- a/sd/source/core/drawdoc2.cxx +++ b/sd/source/core/drawdoc2.cxx @@ -1384,7 +1384,8 @@ USHORT SdDrawDocument::CreatePage ( AutoLayout eStandardLayout, AutoLayout eNotesLayout, BOOL bIsPageBack, - BOOL bIsPageObj) + BOOL bIsPageObj, + const sal_Int32 nInsertPosition) { SdPage* pPreviousStandardPage; SdPage* pPreviousNotesPage; @@ -1452,22 +1453,24 @@ USHORT SdDrawDocument::CreatePage ( pNotesPage->setHeaderFooterSettings( pPreviousNotesPage->getHeaderFooterSettings() ); return InsertPageSet ( - pActualPage, ePageKind, + pActualPage, + ePageKind, sStandardPageName, sNotesPageName, eStandardLayout, eNotesLayout, bIsPageBack, bIsPageObj, - pStandardPage, - pNotesPage); + pNotesPage, + nInsertPosition); } -USHORT SdDrawDocument::DuplicatePage (USHORT nPageNum) +USHORT SdDrawDocument::DuplicatePage ( + const USHORT nPageNum) { PageKind ePageKind = PK_STANDARD; @@ -1503,7 +1506,8 @@ USHORT SdDrawDocument::DuplicatePage ( AutoLayout eStandardLayout, AutoLayout eNotesLayout, BOOL bIsPageBack, - BOOL bIsPageObj) + BOOL bIsPageObj, + const sal_Int32 nInsertPosition) { SdPage* pPreviousStandardPage; SdPage* pPreviousNotesPage; @@ -1530,16 +1534,17 @@ USHORT SdDrawDocument::DuplicatePage ( pNotesPage = (SdPage*) pPreviousNotesPage->Clone(); return InsertPageSet ( - pActualPage, ePageKind, + pActualPage, + ePageKind, sStandardPageName, sNotesPageName, eStandardLayout, eNotesLayout, bIsPageBack, bIsPageObj, - pStandardPage, - pNotesPage); + pNotesPage, + nInsertPosition); } @@ -1554,9 +1559,9 @@ USHORT SdDrawDocument::InsertPageSet ( AutoLayout eNotesLayout, BOOL bIsPageBack, BOOL bIsPageObj, - SdPage* pStandardPage, - SdPage* pNotesPage) + SdPage* pNotesPage, + sal_Int32 nInsertPosition) { SdPage* pPreviousStandardPage; SdPage* pPreviousNotesPage; @@ -1586,13 +1591,16 @@ USHORT SdDrawDocument::InsertPageSet ( eNotesLayout = pPreviousNotesPage->GetAutoLayout(); } + OSL_ASSERT(nNotesPageNum==nStandardPageNum+1); + if (nInsertPosition < 0) + nInsertPosition = nStandardPageNum; // Set up and insert the standard page. SetupNewPage ( pPreviousStandardPage, pStandardPage, aStandardPageName, - nStandardPageNum, + nInsertPosition, bIsPageBack, bIsPageObj); @@ -1602,7 +1610,7 @@ USHORT SdDrawDocument::InsertPageSet ( pPreviousNotesPage, pNotesPage, aNotesPageName, - nNotesPageNum, + nInsertPosition+1, bIsPageBack, bIsPageObj); diff --git a/sd/source/ui/inc/DrawViewShell.hxx b/sd/source/ui/inc/DrawViewShell.hxx index b9a3e062955b..f22352ab6f71 100644 --- a/sd/source/ui/inc/DrawViewShell.hxx +++ b/sd/source/ui/inc/DrawViewShell.hxx @@ -453,7 +453,8 @@ private: virtual SdPage* CreateOrDuplicatePage ( SfxRequest& rRequest, PageKind ePageKind, - SdPage* pPage); + SdPage* pPage, + const sal_Int32 nInsertPosition = -1); ::com::sun::star::uno::Reference< ::com::sun::star::scanner::XScannerManager > mxScannerManager; ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > mxScannerListener; diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 130f4ed6cbcd..068968f625d9 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -461,6 +461,9 @@ public: This page is either duplicated or becomes the predecessor of the new slide. If NULL a duplication request is ignored. A new slide is inserted as first slide. + @param nInsertPosition + When -1 (the default) then insert after pPage. Otherwise insert + before the given index (of a standard page). @return The new slide is returned. If for some reason a new page can not be created then NULL is returned. @@ -468,7 +471,8 @@ public: virtual SdPage* CreateOrDuplicatePage ( SfxRequest& rRequest, PageKind ePageKind, - SdPage* pPage); + SdPage* pPage, + const sal_Int32 nInsertPosition = -1); class Implementation; diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 14e792d8f5cc..252d645168fc 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -199,9 +199,7 @@ void InsertionIndicatorHandler::SetPosition ( { mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation()); - GetInsertAnimator()->SetInsertPosition( - maInsertPosition, - maIconSize); + GetInsertAnimator()->SetInsertPosition(maInsertPosition); mpInsertionIndicatorOverlay->Show(); } else diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 8880100a918a..c3b4f8f1fe2b 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -1245,9 +1245,9 @@ void SelectionFunction::ProcessButtonClick ( break; case 1: - // Toggle exclusion state. if ( ! rpDescriptor) return; + // Toggle exclusion state. mrSlideSorter.GetController().GetSlotManager()->ChangeSlideExclusionState( (rpDescriptor->HasState(model::PageDescriptor::ST_Selected) ? model::SharedPageDescriptor() @@ -1256,12 +1256,20 @@ void SelectionFunction::ProcessButtonClick ( break; case 0: - // Insert page after current page. - rSelector.DeselectAllPages(); - rSelector.SelectPage(rpDescriptor); + if ( ! rpDescriptor) + return; + // When the page under the button is not selected then set the + // selection to just this page. + if ( ! rpDescriptor->HasState(model::PageDescriptor::ST_Selected)) + { + rSelector.DeselectAllPages(); + rSelector.SelectPage(rpDescriptor); + } + // Duplicate the selected pages. Insert the new pages right + // after the current selection and select them if (mrSlideSorter.GetViewShell() != NULL) mrSlideSorter.GetViewShell()->GetDispatcher()->Execute( - SID_INSERTPAGE, + SID_DUPLICATE_PAGE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); break; } diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index ee0b542eaf25..7ea11e841a8e 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -1204,6 +1204,7 @@ void SlotManager::DuplicateSelectedSlides (SfxRequest& rRequest) { // Create a list of the pages that are to be duplicated. The process of // duplication alters the selection. + sal_Int32 nInsertPosition (0); ::std::vector aPagesToDuplicate; model::PageEnumeration aSelectedPages ( model::PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); @@ -1211,18 +1212,44 @@ void SlotManager::DuplicateSelectedSlides (SfxRequest& rRequest) { model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); if (pDescriptor && pDescriptor->GetPage()) + { aPagesToDuplicate.push_back(pDescriptor->GetPage()); + nInsertPosition = pDescriptor->GetPage()->GetPageNum()+2; + } } + // Duplicate the pages in aPagesToDuplicate and collect the newly + // created pages in aPagesToSelect. + const bool bUndo (aPagesToDuplicate.size()>1 && mrSlideSorter.GetView().IsUndoEnabled()); + if (bUndo) + mrSlideSorter.GetView().BegUndo(String(SdResId(STR_INSERTPAGE))); + + ::std::vector aPagesToSelect; + for(::std::vector::const_iterator + iPage(aPagesToDuplicate.begin()), + iEnd(aPagesToDuplicate.end()); + iPage!=iEnd; + ++iPage, nInsertPosition+=2) + { + aPagesToSelect.push_back( + mrSlideSorter.GetViewShell()->CreateOrDuplicatePage( + rRequest, PK_STANDARD, *iPage, nInsertPosition)); + } + aPagesToDuplicate.clear(); + + if (bUndo) + mrSlideSorter.GetView().EndUndo(); + + // Set the selection to the pages in aPagesToSelect. + PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); + rSelector.DeselectAllPages(); for_each ( - aPagesToDuplicate.begin(), - aPagesToDuplicate.end(), + aPagesToSelect.begin(), + aPagesToSelect.end(), ::boost::bind( - &ViewShell::CreateOrDuplicatePage, - mrSlideSorter.GetViewShell(), - ::boost::ref(rRequest), - PK_STANDARD, - _1)); + static_cast(&PageSelector::SelectPage), + rSelector, + _1)); } diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx index 52c88b6e42cf..affe0824bd8c 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx @@ -53,9 +53,7 @@ public: /** Set the position at which we have to make room for the display of an icon. */ - void SetInsertPosition ( - const InsertPosition& rInsertPosition, - const Size& rIconSize); + void SetInsertPosition (const InsertPosition& rInsertPosition); void Reset (void); diff --git a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx index eb4e36f803bc..2ecf8eab6498 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx @@ -134,9 +134,7 @@ public: Implementation (SlideSorter& rSlideSorter); virtual ~Implementation (void); - void SetInsertPosition ( - const InsertPosition& rInsertPosition, - const Size& rIconSize); + void SetInsertPosition (const InsertPosition& rInsertPosition); void Reset (void); @@ -176,11 +174,9 @@ InsertAnimator::InsertAnimator (SlideSorter& rSlideSorter) -void InsertAnimator::SetInsertPosition ( - const InsertPosition& rInsertPosition, - const Size& rIconSize) +void InsertAnimator::SetInsertPosition (const InsertPosition& rInsertPosition) { - mpImplementation->SetInsertPosition(rInsertPosition, rIconSize); + mpImplementation->SetInsertPosition(rInsertPosition); } @@ -216,9 +212,7 @@ InsertAnimator::Implementation::~Implementation (void) -void InsertAnimator::Implementation::SetInsertPosition ( - const InsertPosition& rInsertPosition, - const Size& rIconSize) +void InsertAnimator::Implementation::SetInsertPosition (const InsertPosition& rInsertPosition) { if (maInsertPosition == rInsertPosition) return; @@ -250,7 +244,7 @@ void InsertAnimator::Implementation::SetInsertPosition ( void InsertAnimator::Implementation::Reset (void) { - SetInsertPosition(InsertPosition(), Size(0,0)); + SetInsertPosition(InsertPosition()); } diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx index 12b81a01d3ba..6d3fda131a5a 100644 --- a/sd/source/ui/view/drviews2.cxx +++ b/sd/source/ui/view/drviews2.cxx @@ -1009,7 +1009,8 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) SdPage* DrawViewShell::CreateOrDuplicatePage ( SfxRequest& rRequest, PageKind ePageKind, - SdPage* pPage) + SdPage* pPage, + const sal_Int32 nInsertPosition) { SdPage* pNewPage = NULL; if (ePageKind == PK_STANDARD && meEditMode != EM_MASTERPAGE) @@ -1018,7 +1019,7 @@ SdPage* DrawViewShell::CreateOrDuplicatePage ( { mpDrawView->SdrEndTextEdit(); } - pNewPage = ViewShell::CreateOrDuplicatePage (rRequest, ePageKind, pPage); + pNewPage = ViewShell::CreateOrDuplicatePage (rRequest, ePageKind, pPage, nInsertPosition); } return pNewPage; } diff --git a/sd/source/ui/view/viewshe3.cxx b/sd/source/ui/view/viewshe3.cxx index 86e441939b0e..7eb225db44bb 100644 --- a/sd/source/ui/view/viewshe3.cxx +++ b/sd/source/ui/view/viewshe3.cxx @@ -218,7 +218,8 @@ void ViewShell::GetMenuState( SfxItemSet &rSet ) SdPage* ViewShell::CreateOrDuplicatePage ( SfxRequest& rRequest, PageKind ePageKind, - SdPage* pPage) + SdPage* pPage, + const sal_Int32 nInsertPosition) { USHORT nSId = rRequest.GetSlot(); SdDrawDocument* pDocument = GetDoc(); @@ -358,7 +359,8 @@ SdPage* ViewShell::CreateOrDuplicatePage ( eStandardLayout, eNotesLayout, bIsPageBack, - bIsPageObj); + bIsPageObj, + nInsertPosition); // Select exactly the new page. USHORT nPageCount (pDocument->GetSdPageCount(ePageKind)); for (USHORT i=0; i Date: Fri, 12 Mar 2010 11:01:36 +0100 Subject: renaissance1: #i107215# Prevent loop when bitmap is missing. --- sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index f7f480cbe950..19f7bc14b664 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -289,18 +289,20 @@ void PageObjectPainter::PaintPreview ( if (rpDescriptor->GetVisualState().GetCurrentVisualState() == model::VisualState::VS_Excluded) { - const Region aSavedClip (rDevice.GetClipRegion()); - - rDevice.IntersectClipRegion(aBox); - const BitmapEx aOverlay (mpTheme->GetIcon(Theme::HideSlideOverlay)); const sal_Int32 nIconWidth (aOverlay.GetSizePixel().Width()); const sal_Int32 nIconHeight (aOverlay.GetSizePixel().Height()); - for (sal_Int32 nX=aBox.Left(); nX0 && nIconHeight>0) + { + const Region aSavedClip (rDevice.GetClipRegion()); + rDevice.IntersectClipRegion(aBox); - rDevice.SetClipRegion(aSavedClip); + for (sal_Int32 nX=aBox.Left(); nX Date: Fri, 12 Mar 2010 14:02:52 +0100 Subject: renaissance1: #i107215# Keep insertion indicator visible when context menu is displayed. --- sd/sdi/SlideSorterController.sdi | 15 -------- .../controller/SlideSorterController.cxx | 14 ++++--- .../ui/slidesorter/controller/SlsClipboard.cxx | 12 ++++-- .../controller/SlsInsertionIndicatorHandler.cxx | 43 +++++++++++++++++++--- .../controller/SlsInsertionIndicatorHandler.hxx | 21 +++++++++++ 5 files changed, 76 insertions(+), 29 deletions(-) diff --git a/sd/sdi/SlideSorterController.sdi b/sd/sdi/SlideSorterController.sdi index 8affd602f376..449969ce5b96 100644 --- a/sd/sdi/SlideSorterController.sdi +++ b/sd/sdi/SlideSorterController.sdi @@ -240,21 +240,6 @@ interface SlideSorterView ExecMethod = FuTemporary ; StateMethod = GetMenuState ; ] - /* - SID_PRINTDOC // ole : no, status : ? - [ - StateMethod = GetMenuState ; - ] - SID_PRINTDOCDIRECT // ole : no, status : ? - [ - StateMethod = GetMenuState ; - ] - SID_SETUPPRINTER // ole : no, status : ? - [ - StateMethod = GetMenuState ; - ] -*/ - SID_OUTPUT_QUALITY_COLOR // ole : no, status : play rec [ ExecMethod = ExecCtrl ; diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 8b32a3c34c5c..e5076f0fa931 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -438,18 +438,22 @@ bool SlideSorterController::Command ( else nPopupId = RID_SLIDE_SORTER_MASTER_NOSEL_POPUP; } - + ::boost::scoped_ptr pContext; if (pPage == NULL) { // 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(false); - GetInsertionIndicatorHandler()->UpdatePosition( + mpInsertionIndicatorHandler->Start(false); + mpInsertionIndicatorHandler->UpdatePosition( pWindow->PixelToLogic(rEvent.GetMousePosPixel()), InsertionIndicatorHandler::MoveMode); - GetInsertionIndicatorHandler()->UpdateIndicatorIcon( + mpInsertionIndicatorHandler->UpdateIndicatorIcon( + dynamic_cast(SD_MOD()->pTransferClip)); + mpInsertionIndicatorHandler->UpdateIndicatorIcon( dynamic_cast(SD_MOD()->pTransferClip)); + pContext.reset(new InsertionIndicatorHandler::ForceShowContext( + mpInsertionIndicatorHandler)); } pWindow->ReleaseMouse(); @@ -496,8 +500,8 @@ bool SlideSorterController::Command ( // finds the right place to insert a new slide. GetSelectionManager()->SetInsertionPosition( GetInsertionIndicatorHandler()->GetInsertionPageIndex()); - GetInsertionIndicatorHandler()->End(); } + pContext.reset(); bEventHasBeenHandled = true; } break; diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 3213a3ce1bdc..7f74b600640a 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -236,10 +236,18 @@ sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow) mrController.GetInsertionIndicatorHandler()); if (pInsertionIndicatorHandler->IsActive()) { + // Use the insertion index of an active insertion indicator. nInsertPosition = pInsertionIndicatorHandler->GetInsertionPageIndex(); } + else if (mrController.GetSelectionManager()->GetInsertionPosition() >= 0) + { + // Use the insertion index of an insertion indicator that has been + // deactivated a short while ago. + nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition(); + } else if (mrController.GetFocusManager().IsFocusShowing()) { + // Use the focus to determine the insertion position. SdInsertPasteDlg aDialog (pWindow); if (aDialog.Execute() == RET_OK) { @@ -248,10 +256,6 @@ sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow) nInsertPosition ++; } } - else - { - nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition(); - } return nInsertPosition; } diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 252d645168fc..68f4f1d6b0e3 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -55,7 +55,8 @@ InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter) mbIsActive(false), mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()), mbIsOverSourceView(true), - maIconSize(0,0) + maIconSize(0,0), + mbIsForcedShow(false) { } @@ -89,10 +90,7 @@ void InsertionIndicatorHandler::Start (const bool bIsOverSourceView) void InsertionIndicatorHandler::End (void) { - if ( ! mbIsActive) - return; - - if (mbIsReadOnly) + if (mbIsForcedShow || ! mbIsActive || mbIsReadOnly) return; GetInsertAnimator()->Reset(); @@ -107,6 +105,23 @@ void InsertionIndicatorHandler::End (void) +void InsertionIndicatorHandler::ForceShow (void) +{ + mbIsForcedShow = true; +} + + + + +void InsertionIndicatorHandler::ForceEnd (void) +{ + mbIsForcedShow = false; + End(); +} + + + + void InsertionIndicatorHandler::UpdateIndicatorIcon (const Transferable* pTransferable) { mpInsertionIndicatorOverlay->Create(pTransferable); @@ -273,4 +288,22 @@ bool InsertionIndicatorHandler::IsInsertionTrivial ( + +//===== InsertionIndicatorHandler::ForceShowContext =========================== + +InsertionIndicatorHandler::ForceShowContext::ForceShowContext ( + const ::boost::shared_ptr& rpHandler) + : mpHandler(rpHandler) +{ + mpHandler->ForceShow(); +} + + + + +InsertionIndicatorHandler::ForceShowContext::~ForceShowContext (void) +{ + mpHandler->ForceEnd(); +} + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx index 53c8bdfd3d42..73f11e3e0e32 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -70,6 +70,15 @@ public: */ void End (void); + class ForceShowContext + { + public: + ForceShowContext (const ::boost::shared_ptr& rpHandler); + ~ForceShowContext (void); + private: + const ::boost::shared_ptr mpHandler; + }; + /** Update the indicator icon from the current transferable (from the clipboard or an active drag and drop operation.) */ @@ -114,11 +123,23 @@ private: bool mbIsReadOnly; bool mbIsOverSourceView; Size maIconSize; + bool mbIsForcedShow; void SetPosition ( const Point& rPoint, const Mode eMode); ::boost::shared_ptr GetInsertAnimator (void); + + /** Make the insertion indicator visible (that is the show part) and + keep it visible, even when the mouse leaves the window (that is the + force part). We need this when a context menu is displayed (mouse + over the popup menu triggers a mouse leave event) while the + insertion indicator remains visible in the background. + + In effect all calls to End() are ignored until ForceEnd() is called. + */ + void ForceShow (void); + void ForceEnd (void); }; -- cgit v1.2.3 From 6426d891e7cc9ca92b8e5b14f6c879846d024ecf Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 12 Mar 2010 17:03:08 +0100 Subject: renaissance1: #i107215# Added support for keys home/end. Fixed selection after inserting new slides. --- sd/source/ui/framework/tools/FrameworkHelper.cxx | 17 +- sd/source/ui/inc/framework/FrameworkHelper.hxx | 11 +- .../controller/SlideSorterController.cxx | 6 +- .../ui/slidesorter/controller/SlsPageSelector.cxx | 36 ++++ .../controller/SlsSelectionFunction.cxx | 76 +++++---- .../slidesorter/controller/SlsSelectionManager.cxx | 16 +- .../ui/slidesorter/controller/SlsSlotManager.cxx | 188 ++++++++++----------- .../slidesorter/inc/controller/SlsPageSelector.hxx | 40 +++-- .../inc/controller/SlsSelectionFunction.hxx | 7 + .../inc/controller/SlsSelectionManager.hxx | 7 +- .../slidesorter/inc/controller/SlsSlotManager.hxx | 5 + sd/source/ui/view/viewshe3.cxx | 3 +- 12 files changed, 246 insertions(+), 166 deletions(-) diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx b/sd/source/ui/framework/tools/FrameworkHelper.cxx index 4ce1bfebf6ee..90f0c278e9a1 100644 --- a/sd/source/ui/framework/tools/FrameworkHelper.cxx +++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx @@ -548,12 +548,27 @@ Reference FrameworkHelper::RequestView ( void FrameworkHelper::RequestTaskPanel ( - const OUString& rsTaskPanelURL) + const OUString& rsTaskPanelURL, + const bool bEnsureTaskPaneIsVisible) { try { if (mxConfigurationController.is()) { + // Check the existence of the task pane. + if ( ! bEnsureTaskPaneIsVisible) + { + Reference xConfiguration ( + mxConfigurationController->getCurrentConfiguration()); + if (xConfiguration.is()) + if ( ! xConfiguration->hasResource( + CreateResourceId(msTaskPaneURL, msRightPaneURL))) + { + // Task pane does is not active. Do not force it. + return; + } + } + // Create the resource id from URLs for the pane, the task pane // view, and the task panel. mxConfigurationController->requestResourceActivation( diff --git a/sd/source/ui/inc/framework/FrameworkHelper.hxx b/sd/source/ui/inc/framework/FrameworkHelper.hxx index 27ed5f6f8bef..dc3d05b59ecd 100644 --- a/sd/source/ui/inc/framework/FrameworkHelper.hxx +++ b/sd/source/ui/inc/framework/FrameworkHelper.hxx @@ -226,9 +226,18 @@ public: /** Request the activation of the specified task panel in the standard task pane. + @param rsTaskPanelURL + The panel that is to be activated. + @param bEnsureTaskPaneIsVisible + When this is then the task pane is activated when not + yet active. + When this flag is then the requested panel + is activated only when the task pane is already active. When it + is not active then this call is silently ignored. */ void RequestTaskPanel ( - const ::rtl::OUString& rsTaskPanelURL); + const ::rtl::OUString& rsTaskPanelURL, + const bool bEnsureTaskPaneIsVisible = true); /** Process a slot call that requests a view shell change. */ diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index e5076f0fa931..859b19246f05 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -445,13 +445,11 @@ bool SlideSorterController::Command ( // indicator so that the user knows where a page insertion // would take place. mpInsertionIndicatorHandler->Start(false); + mpInsertionIndicatorHandler->UpdateIndicatorIcon( + dynamic_cast(SD_MOD()->pTransferClip)); mpInsertionIndicatorHandler->UpdatePosition( pWindow->PixelToLogic(rEvent.GetMousePosPixel()), InsertionIndicatorHandler::MoveMode); - mpInsertionIndicatorHandler->UpdateIndicatorIcon( - dynamic_cast(SD_MOD()->pTransferClip)); - mpInsertionIndicatorHandler->UpdateIndicatorIcon( - dynamic_cast(SD_MOD()->pTransferClip)); pContext.reset(new InsertionIndicatorHandler::ForceShowContext( mpInsertionIndicatorHandler)); } diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index 058cbb343e92..9329df1a3766 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -453,4 +453,40 @@ PageSelector::UpdateLock::~UpdateLock (void) +//===== PageSelector::BroadcastLock ============================================== + +PageSelector::BroadcastLock::BroadcastLock (SlideSorter& rSlideSorter) + : mrSelector(rSlideSorter.GetController().GetPageSelector()), + mbIsMakeSelectionVisiblePending(false) +{ + mrSelector.DisableBroadcasting(); +} + + + + +PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector) + : mrSelector(rSelector) +{ + mrSelector.DisableBroadcasting(); +} + + + + +PageSelector::BroadcastLock::~BroadcastLock (void) +{ + mrSelector.EnableBroadcasting(mbIsMakeSelectionVisiblePending); +} + + + + +void PageSelector::BroadcastLock::RequestMakeSelectionVisible (void) +{ + mbIsMakeSelectionVisiblePending = true; +} + + + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index c3b4f8f1fe2b..ac155377c0df 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -459,28 +459,23 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) bResult = TRUE; break; + case KEY_HOME: + GotoPage(0); + bResult = TRUE; + break; + + case KEY_END: + GotoPage(mrSlideSorter.GetModel().GetPageCount()-1); + bResult = TRUE; + break; + case KEY_DELETE: case KEY_BACKSPACE: { if (mrSlideSorter.GetProperties()->IsUIReadOnly()) break; - int nSelectedPagesCount = 0; - - // Count the selected pages and look if there any objects on any - // of the selected pages so that we can warn the user and - // prevent an accidental deletion. - model::PageEnumeration aSelectedPages ( - model::PageEnumerationProvider::CreateSelectedPagesEnumeration( - mrSlideSorter.GetModel())); - while (aSelectedPages.HasMoreElements()) - { - nSelectedPagesCount++; - aSelectedPages.GetNextElement(); - } - - if (nSelectedPagesCount > 0) - mrController.GetSelectionManager()->DeleteSelectedPages(); + mrController.GetSelectionManager()->DeleteSelectedPages(rCode.GetCode()==KEY_DELETE); mnShiftKeySelectionAnchor = -1; bResult = TRUE; @@ -750,23 +745,31 @@ void SelectionFunction::GotoNextPage (int nOffset) SdPage* pPage = pDescriptor->GetPage(); OSL_ASSERT(pPage!=NULL); sal_Int32 nIndex = (pPage->GetPageNum()-1) / 2; - nIndex += nOffset; - USHORT nPageCount = (USHORT)mrSlideSorter.GetModel().GetPageCount(); - - if (nIndex >= nPageCount) - nIndex = nPageCount - 1; - if (nIndex < 0) - nIndex = 0; - - mrController.GetFocusManager().SetFocusedPage(nIndex); - model::SharedPageDescriptor pNextPageDescriptor ( - mrSlideSorter.GetModel().GetPageDescriptor (nIndex)); - if (pNextPageDescriptor.get() != NULL) - SetCurrentPage(pNextPageDescriptor); - else - { - OSL_ASSERT(pNextPageDescriptor.get() != NULL); - } + GotoPage(nIndex + nOffset); + } + mnShiftKeySelectionAnchor = -1; +} + + + + +void SelectionFunction::GotoPage (int nIndex) +{ + USHORT nPageCount = (USHORT)mrSlideSorter.GetModel().GetPageCount(); + + if (nIndex >= nPageCount) + nIndex = nPageCount - 1; + if (nIndex < 0) + nIndex = 0; + + mrController.GetFocusManager().SetFocusedPage(nIndex); + model::SharedPageDescriptor pNextPageDescriptor ( + mrSlideSorter.GetModel().GetPageDescriptor (nIndex)); + if (pNextPageDescriptor.get() != NULL) + SetCurrentPage(pNextPageDescriptor); + else + { + OSL_ASSERT(pNextPageDescriptor.get() != NULL); } mnShiftKeySelectionAnchor = -1; } @@ -931,8 +934,8 @@ bool SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor) bool bResult (true); - mrController.GetPageSelector().DisableBroadcasting(); - PageSelector::UpdateLock aLock (mrSlideSorter); + PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter); + PageSelector::UpdateLock aUpdateLock (mrSlideSorter); // With the event code determine the type of operation with which to // react to the event. @@ -966,7 +969,8 @@ bool SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor) } } - mrController.GetPageSelector().EnableBroadcasting(rDescriptor.mbMakeSelectionVisible); + if (rDescriptor.mbMakeSelectionVisible) + aBroadcastLock.RequestMakeSelectionVisible(); return bResult; } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 2430332aacac..e1d42b161053 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -114,7 +114,7 @@ SelectionManager::~SelectionManager (void) -void SelectionManager::DeleteSelectedPages (void) +void SelectionManager::DeleteSelectedPages (const bool bSelectFollowingPage) { // Create some locks to prevent updates of the model, view, selection // state while modifying any of them. @@ -132,19 +132,23 @@ void SelectionManager::DeleteSelectedPages (void) model::PageEnumeration aPageEnumeration ( PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); ::std::vector aSelectedPages; - sal_Int32 nLastPageIndex (-1); + sal_Int32 nNewCurrentSlide (-1); while (aPageEnumeration.HasMoreElements()) { SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); aSelectedPages.push_back(pDescriptor->GetPage()); - nLastPageIndex = pDescriptor->GetPageIndex(); + if (bSelectFollowingPage || nNewCurrentSlide<0) + nNewCurrentSlide = pDescriptor->GetPageIndex(); } if (aSelectedPages.empty()) return; // Determine the slide to select (and thereby make the current slide) // after the deletion. - sal_Int32 nNewCurrentSlide (nLastPageIndex - aSelectedPages.size() + 1); + if (bSelectFollowingPage) + nNewCurrentSlide -= aSelectedPages.size() - 1; + else + --nNewCurrentSlide; // The actual deletion of the selected pages is done in one of two // helper functions. They are specialized for normal respectively for @@ -164,7 +168,9 @@ void SelectionManager::DeleteSelectedPages (void) mrController.GetFocusManager().ToggleFocus(); // Set the new current slide. - if (nNewCurrentSlide >= mrSlideSorter.GetModel().GetPageCount()) + if (nNewCurrentSlide < 0) + nNewCurrentSlide = 0; + else if (nNewCurrentSlide >= mrSlideSorter.GetModel().GetPageCount()) nNewCurrentSlide = mrSlideSorter.GetModel().GetPageCount()-1; mrController.GetPageSelector().SelectPage(nNewCurrentSlide); mrController.GetFocusManager().SetFocusedPage(nNewCurrentSlide); diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 7ea11e841a8e..c3f101fd60bb 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -1077,124 +1077,56 @@ bool SlotManager::RenameSlideFromDrawViewShell( USHORT nPageId, const String & r */ void SlotManager::InsertSlide (SfxRequest& rRequest) { - PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); - // The fallback insertion position is after the last slide. - sal_Int32 nInsertionIndex (rSelector.GetPageCount() - 1); - if (rSelector.GetSelectedPageCount() > 0) - { - // Deselect all but the last selected slide. - bool bLastSelectedSlideSeen (false); - for (int nIndex=rSelector.GetPageCount()-1; nIndex>=0; --nIndex) - { - if (rSelector.IsPageSelected(nIndex)) - { - if (bLastSelectedSlideSeen) - rSelector.DeselectPage (nIndex); - else - { - nInsertionIndex = nIndex; - bLastSelectedSlideSeen = true; - } - } - } - } + const sal_Int32 nInsertionIndex (GetInsertionPosition()); + USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount()); - // No selection. Is there an insertion indicator? - else if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsActive()) - { - // Select the page before the insertion indicator. - nInsertionIndex - = mrSlideSorter.GetController().GetInsertionIndicatorHandler()->GetInsertionPageIndex(); - nInsertionIndex --; - rSelector.SelectPage (nInsertionIndex); - } + PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter); - // Is there a stored insertion position? - else if (mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() >= 0) + SdPage* pNewPage = NULL; + if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE) { - nInsertionIndex - = mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() - 1; - rSelector.SelectPage(nInsertionIndex); - } - - // Select the last page when there is at least one page. - else if (rSelector.GetPageCount() > 0) - { - nInsertionIndex = rSelector.GetPageCount() - 1; - rSelector.SelectPage (nInsertionIndex); + SlideSorterViewShell* pShell = dynamic_cast( + mrSlideSorter.GetViewShell()); + if (pShell != NULL) + { + pNewPage = pShell->CreateOrDuplicatePage ( + rRequest, + mrSlideSorter.GetModel().GetPageType(), + nInsertionIndex>=0 + ? mrSlideSorter.GetModel().GetPageDescriptor(nInsertionIndex)->GetPage() + : NULL); + } } - - // Hope for the best that CreateOrDuplicatePage() can cope with an empty - // selection. else { - nInsertionIndex = -1; - } - - USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount()); - - rSelector.DisableBroadcasting(); - // In order for SlideSorterController::GetActualPage() to select the - // selected page as current page we have to turn off the focus - // temporarily. - { - FocusManager::FocusHider aTemporaryFocusHider ( - mrSlideSorter.GetController().GetFocusManager()); - - SdPage* pPreviousPage = NULL; - if (nInsertionIndex >= 0) - pPreviousPage = mrSlideSorter.GetModel() - .GetPageDescriptor(nInsertionIndex)->GetPage(); - - if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE) - { - SlideSorterViewShell* pShell = dynamic_cast( - mrSlideSorter.GetViewShell()); - if (pShell != NULL) - { - pShell->CreateOrDuplicatePage ( - rRequest, - mrSlideSorter.GetModel().GetPageType(), - pPreviousPage); - } - } - else + // Use the API to create a new page. + SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument(); + Reference xMasterPagesSupplier ( + pDocument->getUnoModel(), UNO_QUERY); + if (xMasterPagesSupplier.is()) { - // Use the API to create a new page. - SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument(); - Reference xMasterPagesSupplier ( - pDocument->getUnoModel(), UNO_QUERY); - if (xMasterPagesSupplier.is()) + Reference xMasterPages ( + xMasterPagesSupplier->getMasterPages()); + if (xMasterPages.is()) { - Reference xMasterPages ( - xMasterPagesSupplier->getMasterPages()); - if (xMasterPages.is()) - { - xMasterPages->insertNewByIndex (nInsertionIndex+1); + xMasterPages->insertNewByIndex (nInsertionIndex+1); - // Create shapes for the default layout. - SdPage* pMasterPage = pDocument->GetMasterSdPage( - (USHORT)(nInsertionIndex+1), PK_STANDARD); - pMasterPage->CreateTitleAndLayout (TRUE,TRUE); - } + // Create shapes for the default layout. + pNewPage = pDocument->GetMasterSdPage( + (USHORT)(nInsertionIndex+1), PK_STANDARD); + pNewPage->CreateTitleAndLayout (TRUE,TRUE); } } } + if (pNewPage == NULL) + return; // When a new page has been inserted then select it, make it the // current page, and focus it. - view::SlideSorterView::DrawLock aLock (mrSlideSorter); - if (mrSlideSorter.GetModel().GetPageCount() > nPageCount) - { - nInsertionIndex++; - model::SharedPageDescriptor pDescriptor = mrSlideSorter.GetModel().GetPageDescriptor(nInsertionIndex); - if (pDescriptor.get() != NULL) - { - mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); - mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(pDescriptor); - } - } - rSelector.EnableBroadcasting(); + view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); + PageSelector::UpdateLock aUpdateLock (mrSlideSorter); + mrSlideSorter.GetController().GetPageSelector().DeselectAllPages(); + mrSlideSorter.GetController().GetPageSelector().SelectPage(pNewPage); } @@ -1351,6 +1283,56 @@ void SlotManager::ChangeSlideExclusionState ( +sal_Int32 SlotManager::GetInsertionPosition (void) +{ + PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); + + // The insertion indicator is preferred. After all the user explicitly + // used it to define the insertion position. + if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsActive()) + { + // Select the page before the insertion indicator. + return mrSlideSorter.GetController().GetInsertionIndicatorHandler()->GetInsertionPageIndex() + - 1; + } + + // Is there a stored insertion position? + else if (mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() >= 0) + { + return mrSlideSorter.GetController().GetSelectionManager()->GetInsertionPosition() - 1; + } + + // Use the index of the last selected slide. + else if (rSelector.GetSelectedPageCount() > 0) + { + for (int nIndex=rSelector.GetPageCount()-1; nIndex>=0; --nIndex) + if (rSelector.IsPageSelected(nIndex)) + return nIndex; + + // We should never get here. + OSL_ASSERT(false); + return rSelector.GetPageCount() - 1; + } + + // Select the last page when there is at least one page. + else if (rSelector.GetPageCount() > 0) + { + return rSelector.GetPageCount() - 1; + } + + // Hope for the best that CreateOrDuplicatePage() can cope with an empty + // selection. + else + { + // We should never get here because there has to be at least one page. + OSL_ASSERT(false); + return -1; + } +} + + + + //----------------------------------------------------------------------------- namespace { diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index b301b5a97352..a8009aa8b915 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -114,20 +114,6 @@ public: void PrepareModelChange (void); void HandleModelChange (void); - /** Enable the broadcasting of selection change events. This calls the - SlideSorterController::SelectionHasChanged() method to do the actual - work. When EnableBroadcasting has been called as many times as - DisableBroadcasting() was called before and the selection has been - changed in the mean time, this change will be broadcasted. - */ - void EnableBroadcasting (bool bMakeSelectionVisible = true); - - /** Disable the broadcasting o selectio change events. Subsequent - changes of the selection will set a flag that triggers the sending - of events when EnableBroadcasting() is called. - */ - void DisableBroadcasting (void); - /** Return the descriptor of the most recently selected page. This works only when the page has not been de-selected in the mean time. This method helps the view when it scrolls the selection into the @@ -196,6 +182,18 @@ public: PageSelector& mrSelector; }; + class BroadcastLock + { + public: + BroadcastLock (SlideSorter& rSlideSorter); + BroadcastLock (PageSelector& rPageSelector); + ~BroadcastLock (void); + void RequestMakeSelectionVisible (void); + private: + PageSelector& mrSelector; + bool mbIsMakeSelectionVisiblePending; + }; + private: model::SlideSorterModel& mrModel; SlideSorter& mrSlideSorter; @@ -210,6 +208,20 @@ private: sal_Int32 mnUpdateLockCount; bool mbIsUpdateCurrentPagePending; + /** Enable the broadcasting of selection change events. This calls the + SlideSorterController::SelectionHasChanged() method to do the actual + work. When EnableBroadcasting has been called as many times as + DisableBroadcasting() was called before and the selection has been + changed in the mean time, this change will be broadcasted. + */ + void EnableBroadcasting (bool bMakeSelectionVisible = true); + + /** Disable the broadcasting o selectio change events. Subsequent + changes of the selection will set a flag that triggers the sending + of events when EnableBroadcasting() is called. + */ + void DisableBroadcasting (void); + void CountSelectedPages (void); void UpdateCurrentPage (const bool bUpdateOnlyWhenPending = false); }; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index a6995f88bdcd..3d0b2eb34b23 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -177,6 +177,13 @@ private: */ void GotoNextPage (int nOffset); + /** Make the slide with the given index the new current slide. + @param nIndex + Index of the new current slide. When the new index is outside + the range of valid page numbers it is clipped to that range. + */ + void GotoPage (int nIndex); + void ProcessMouseEvent (sal_uInt32 nEventType, const MouseEvent& rEvent); void ProcessKeyEvent (const KeyEvent& rEvent); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx index 6ba0d0af0715..5b4d3f4b0a9e 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx @@ -68,8 +68,13 @@ public: /** Delete the currently selected slides. When this method returns the selection is empty. + @param bSelectFollowingPage + When then after deleting the selected pages make the + slide after the last selected page the new current page. + When then make the first slide before the selected + pages the new current slide. */ - void DeleteSelectedPages (void); + void DeleteSelectedPages (const bool bSelectFollowingPage = true); /** Move the maked pages to a position directly after the specified page. */ diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx index e84262c8b677..feca487e95c4 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx @@ -112,6 +112,11 @@ private: void AssignTransitionEffect (void); + /** Use one of several ways to determine where to insert a new page. + This can be the current selection or the insertion indicator. + */ + sal_Int32 GetInsertionPosition (void); + DECL_LINK(UserEventCallback, void*); }; diff --git a/sd/source/ui/view/viewshe3.cxx b/sd/source/ui/view/viewshe3.cxx index 7eb225db44bb..7469be4a0269 100644 --- a/sd/source/ui/view/viewshe3.cxx +++ b/sd/source/ui/view/viewshe3.cxx @@ -257,7 +257,8 @@ SdPage* ViewShell::CreateOrDuplicatePage ( && rBase.GetMainViewShell()->GetShellType()!=ViewShell::ST_DRAW) { framework::FrameworkHelper::Instance(GetViewShellBase())->RequestTaskPanel( - framework::FrameworkHelper::msLayoutTaskPanelURL); + framework::FrameworkHelper::msLayoutTaskPanelURL, + false); } // AutoLayouts muessen fertig sein -- cgit v1.2.3 From 59224bb1aa235a3b1ef6757d85de0141b0495649 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 15 Mar 2010 10:48:46 +0100 Subject: renaissance1: #i107215# Fixed initialization of current slide for slide sorter bar. --- .../controller/SlsCurrentSlideManager.cxx | 17 ++++++++++++++++- sd/source/ui/slidesorter/controller/SlsListener.cxx | 4 ++-- .../inc/controller/SlsCurrentSlideManager.hxx | 3 ++- sd/source/ui/slidesorter/model/SlideSorterModel.cxx | 11 ++++++----- .../ui/slidesorter/shell/SlideSorterService.cxx | 2 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 21 ++++++++++++++++++--- 6 files changed, 45 insertions(+), 13 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx index 72a380a02328..1b902da47ee2 100644 --- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx @@ -72,7 +72,22 @@ CurrentSlideManager::~CurrentSlideManager (void) -void CurrentSlideManager::CurrentSlideHasChanged (const sal_Int32 nSlideIndex) +void CurrentSlideManager::NotifyCurrentSlideChange (const SdPage* pPage) +{ + if (pPage != NULL) + NotifyCurrentSlideChange( + mrSlideSorter.GetModel().GetIndex( + Reference( + const_cast(pPage)->getUnoPage(), + UNO_QUERY))); + else + NotifyCurrentSlideChange(-1); +} + + + + +void CurrentSlideManager::NotifyCurrentSlideChange (const sal_Int32 nSlideIndex) { if (mnCurrentSlideIndex != nSlideIndex) { diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 38348a4fdb6e..66afdce47947 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -503,7 +503,7 @@ void SAL_CALL Listener::propertyChange ( static const ::rtl::OUString sEditModePropertyName ( RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode")); - if (rEvent.PropertyName.equals (sCurrentPagePropertyName)) + if (rEvent.PropertyName.equals(sCurrentPagePropertyName)) { Any aCurrentPage = rEvent.NewValue; Reference xPageSet (aCurrentPage, UNO_QUERY); @@ -521,7 +521,7 @@ void SAL_CALL Listener::propertyChange ( // last recently selected page of the PageSelector. This is // used when making the selection visible. mrController.GetPageSelector().SelectPage(nCurrentPage-1); - mrController.GetCurrentSlideManager()->CurrentSlideHasChanged(nCurrentPage-1); + mrController.GetCurrentSlideManager()->NotifyCurrentSlideChange(nCurrentPage-1); } catch (beans::UnknownPropertyException aEvent) { diff --git a/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx index f5e4ddd71ee2..f17742e34fc8 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx @@ -61,7 +61,8 @@ public: /** Call this when the current page of the main view shell has been switched. Use SwitchCurrentSlide() to initiate such a switch. */ - void CurrentSlideHasChanged (const sal_Int32 nSlideIndex); + void NotifyCurrentSlideChange (const sal_Int32 nSlideIndex); + void NotifyCurrentSlideChange (const SdPage* pPage); /** Call this method to switch the current page of the main view shell to the given slide. Use CurrentSlideHasChanged() when the current diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx index ee5c0dfd45e0..2c9b2d1c3671 100644 --- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx +++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx @@ -402,7 +402,7 @@ void SlideSorterModel::SetDocumentSlides ( ::osl::MutexGuard aGuard (maMutex); // Reset the current page so to cause everbody to release references to it. - mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(-1); + mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange(-1); mxSlides = rxSlides; Resync(); @@ -412,21 +412,22 @@ void SlideSorterModel::SetDocumentSlides ( { SdPage* pPage = pViewShell->getCurrentPage(); if (pPage != NULL) - mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged( - GetIndex(Reference(pPage->getUnoPage(), UNO_QUERY))); + mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( + pPage); else { // No current page. This can only be when the slide sorter is // the main view shell. Get current slide form frame view. const FrameView* pFrameView = pViewShell->GetFrameView(); if (pFrameView != NULL) - mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged( + mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( pFrameView->GetSelectedPage()); else { // No frame view. As a last resort use the first slide as // current slide. - mrSlideSorter.GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(0); + mrSlideSorter.GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( + sal_Int32(0)); } } } diff --git a/sd/source/ui/slidesorter/shell/SlideSorterService.cxx b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx index 272a85b3f391..c339f9004d60 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterService.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx @@ -270,7 +270,7 @@ void SAL_CALL SlideSorterService::setCurrentPage(const ReferenceGetController().GetCurrentSlideManager()->CurrentSlideHasChanged( + mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( mpSlideSorter->GetModel().GetIndex(rxSlide)); } diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index f9e93f775784..4e0fc3c66260 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -627,20 +627,32 @@ void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView) } else rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow); - mpSlideSorter->GetController().GetCurrentSlideManager()->CurrentSlideHasChanged( - mpFrameView->GetSelectedPage()); + if (IsMainViewShell()) + mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( + mpFrameView->GetSelectedPage()); mpSlideSorter->GetController().Rearrange(true); // DrawMode for 'main' window if (GetActiveWindow()->GetDrawMode() != pFrameView->GetDrawMode() ) GetActiveWindow()->SetDrawMode( pFrameView->GetDrawMode() ); } + + // When this slide sorter is not displayed in the main window then we do + // not share the same frame view and have to find other ways to acquire + // certain values. + if ( ! IsMainViewShell()) + { + ::boost::shared_ptr pMainViewShell = GetViewShellBase().GetMainViewShell(); + if (pMainViewShell.get() != NULL) + mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( + pMainViewShell->getCurrentPage()); + } } -void SlideSorterViewShell::WriteFrameViewData() +void SlideSorterViewShell::WriteFrameViewData (void) { OSL_ASSERT(mpSlideSorter.get()!=NULL); if (mpFrameView != NULL) @@ -681,6 +693,9 @@ void SlideSorterViewShell::SetZoom (long int ) // the window. } + + + void SlideSorterViewShell::SetZoomRect (const Rectangle& rZoomRect) { OSL_ASSERT(mpSlideSorter.get()!=NULL); -- cgit v1.2.3 From 8c23aba539c0f5764ec543e4cfa6bac2fc20e7ae Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 15 Mar 2010 13:50:38 +0100 Subject: renaissance1: #i107215# Preview generation takes better care of last row and column of pixels. --- sd/source/ui/tools/PreviewRenderer.cxx | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/sd/source/ui/tools/PreviewRenderer.cxx b/sd/source/ui/tools/PreviewRenderer.cxx index 7e1c2a7f9f63..65f904ed373c 100644 --- a/sd/source/ui/tools/PreviewRenderer.cxx +++ b/sd/source/ui/tools/PreviewRenderer.cxx @@ -381,23 +381,26 @@ void PreviewRenderer::SetupOutputSize ( // First set the map mode to some arbitrary scale that is numerically // stable. MapMode aMapMode (mpPreviewDevice->GetMapMode()); - aMapMode.SetMapUnit(MAP_100TH_MM); - double nInitialScale = 1; - aMapMode.SetScaleX (Fraction(nInitialScale)); - aMapMode.SetScaleY (Fraction(nInitialScale)); - aMapMode.SetOrigin (Point(0,0)); + aMapMode.SetMapUnit(MAP_PIXEL); // Adapt it to the desired width. const Size aPageModelSize (rPage.GetSize()); - const Size aOutputSize = mpPreviewDevice->LogicToPixel(rPage.GetSize(), aMapMode); - const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0); - const double nFinalScale (nInitialScale * (rFramePixelSize.Width()-2*nFrameWidth) - / aOutputSize.Width()); - aMapMode.SetScaleX (nFinalScale); - aMapMode.SetScaleY (nFinalScale); - aMapMode.SetOrigin (mpPreviewDevice->PixelToLogic( - Point(nFrameWidth,nFrameWidth),aMapMode)); - + if (aPageModelSize.Width()>0 || aPageModelSize.Height()>0) + { + const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0); + aMapMode.SetScaleX( + Fraction(rFramePixelSize.Width()-2*nFrameWidth-1, aPageModelSize.Width())); + aMapMode.SetScaleY( + Fraction(rFramePixelSize.Height()-2*nFrameWidth-1, aPageModelSize.Height())); + aMapMode.SetOrigin(mpPreviewDevice->PixelToLogic(Point(nFrameWidth,nFrameWidth),aMapMode)); + } + else + { + // We should never get here. + OSL_ASSERT(false); + aMapMode.SetScaleX(1.0); + aMapMode.SetScaleY(1.0); + } mpPreviewDevice->SetMapMode (aMapMode); mpPreviewDevice->SetOutputSizePixel(rFramePixelSize); } -- cgit v1.2.3 From b390fae1706b9c511158a03e4fd61f263be4e511 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 19 Mar 2010 15:06:39 +0100 Subject: renaissance1: #i107215# Reorganized and improved layouting. --- sd/source/core/drawdoc2.cxx | 3 +- sd/source/ui/dlg/PaneDockingWindow.cxx | 70 +- sd/source/ui/inc/PaneDockingWindow.hxx | 18 + sd/source/ui/inc/SlideSorter.hxx | 2 + sd/source/ui/presenter/PresenterPreviewCache.cxx | 2 +- .../ui/slidesorter/cache/SlsGenericPageCache.cxx | 29 +- .../ui/slidesorter/cache/SlsGenericPageCache.hxx | 21 +- sd/source/ui/slidesorter/cache/SlsPageCache.cxx | 17 +- .../controller/SlideSorterController.cxx | 14 +- .../ui/slidesorter/controller/SlsClipboard.cxx | 3 +- .../slidesorter/controller/SlsScrollBarManager.cxx | 156 +- .../controller/SlsSelectionFunction.cxx | 12 +- .../slidesorter/controller/SlsSelectionManager.cxx | 6 +- .../ui/slidesorter/inc/cache/SlsPageCache.hxx | 24 +- .../inc/controller/SlsScrollBarManager.hxx | 26 +- .../ui/slidesorter/inc/view/SlideSorterView.hxx | 16 +- sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 182 +-- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 18 +- .../ui/slidesorter/shell/SlideSorterService.cxx | 9 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 43 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 290 ++-- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 1558 ++++++++++++++------ .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 28 +- 23 files changed, 1521 insertions(+), 1026 deletions(-) diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx index eb279d639ce8..6ccf50453e50 100644 --- a/sd/source/core/drawdoc2.cxx +++ b/sd/source/core/drawdoc2.cxx @@ -1469,8 +1469,7 @@ USHORT SdDrawDocument::CreatePage ( -USHORT SdDrawDocument::DuplicatePage ( - const USHORT nPageNum) +USHORT SdDrawDocument::DuplicatePage (USHORT nPageNum) { PageKind ePageKind = PK_STANDARD; diff --git a/sd/source/ui/dlg/PaneDockingWindow.cxx b/sd/source/ui/dlg/PaneDockingWindow.cxx index b2f17bc0ab2a..0eb33468daf0 100644 --- a/sd/source/ui/dlg/PaneDockingWindow.cxx +++ b/sd/source/ui/dlg/PaneDockingWindow.cxx @@ -34,13 +34,16 @@ #include "PaneDockingWindow.hxx" #include "Window.hxx" #include "ViewShellBase.hxx" +#include "framework/FrameworkHelper.hxx" #include "sdresid.hxx" #include "res_bmp.hrc" #include #include #include +#include +#include #include -#include "framework/FrameworkHelper.hxx" +#include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -55,11 +58,7 @@ PaneDockingWindow::PaneDockingWindow ( const ResId& rResId, const ::rtl::OUString& rsPaneURL, const ::rtl::OUString& rsTitle) - : SfxDockingWindow ( - _pBindings, - pChildWindow, - pParent, - rResId), + : SfxDockingWindow (_pBindings, pChildWindow, pParent, rResId), msPaneURL(rsPaneURL), msTitle(rsTitle), mpTitleToolBox(), @@ -121,7 +120,7 @@ void PaneDockingWindow::Layout (void) Size aWindowSize (GetOutputSizePixel()); Size aToolBoxSize (0,0); - int nTitleBarHeight (GetSettings().GetStyleSettings().GetTitleHeight()); + mnTitleBarHeight = GetSettings().GetStyleSettings().GetTitleHeight(); // Place the title tool box. if (mpTitleToolBox.get() != NULL) @@ -132,20 +131,20 @@ void PaneDockingWindow::Layout (void) mpTitleToolBox->ShowItem (1); aToolBoxSize = mpTitleToolBox->CalcWindowSizePixel(); - if (aToolBoxSize.Height() > nTitleBarHeight) - nTitleBarHeight = aToolBoxSize.Height(); + if (aToolBoxSize.Height() > mnTitleBarHeight) + mnTitleBarHeight = aToolBoxSize.Height(); mpTitleToolBox->SetPosSizePixel ( Point(aWindowSize.Width()-aToolBoxSize.Width(), - (nTitleBarHeight-aToolBoxSize.Height())/2), + (mnTitleBarHeight-aToolBoxSize.Height())/2), aToolBoxSize); } // Place the content window. - if (nTitleBarHeight < aToolBoxSize.Height()) - nTitleBarHeight = aToolBoxSize.Height(); - aWindowSize.Height() -= nTitleBarHeight; + if (mnTitleBarHeight < aToolBoxSize.Height()) + mnTitleBarHeight = aToolBoxSize.Height(); + aWindowSize.Height() -= mnTitleBarHeight; mpContentWindow->SetPosSizePixel( - Point(maBorder.Left(),nTitleBarHeight+maBorder.Top()), + Point(maBorder.Left(),mnTitleBarHeight+maBorder.Top()), Size (aWindowSize.Width()-maBorder.Left()-maBorder.Right(), aWindowSize.Height()-maBorder.Top()-maBorder.Bottom())); } @@ -159,10 +158,6 @@ void PaneDockingWindow::Paint (const Rectangle& rRectangle) Layout(); SfxDockingWindow::Paint (rRectangle); - int nTitleBarHeight (GetSettings().GetStyleSettings().GetTitleHeight()); - Size aToolBoxSize = mpTitleToolBox->CalcWindowSizePixel(); - if (aToolBoxSize.Height() > nTitleBarHeight) - nTitleBarHeight = aToolBoxSize.Height(); Color aOriginalLineColor (GetLineColor()); Color aOriginalFillColor (GetFillColor()); SetFillColor (GetSettings().GetStyleSettings().GetDialogColor()); @@ -180,7 +175,7 @@ void PaneDockingWindow::Paint (const Rectangle& rRectangle) int nInnerLeft = nOuterLeft + maBorder.Left() - 1; int nOuterRight = aWindowSize.Width() - 1; int nInnerRight = nOuterRight - maBorder.Right() + 1; - int nInnerTop = nTitleBarHeight + maBorder.Top() - 1; + int nInnerTop = mnTitleBarHeight + maBorder.Top() - 1; int nOuterBottom = aWindowSize.Height() - 1; int nInnerBottom = nOuterBottom - maBorder.Bottom() + 1; @@ -424,4 +419,41 @@ void PaneDockingWindow::MouseButtonDown (const MouseEvent& rEvent) + +void PaneDockingWindow::SetValidSizeRange (const Range aValidSizeRange) +{ + SplitWindow* pSplitWindow = dynamic_cast(GetParent()); + if (pSplitWindow != NULL) + { + const USHORT nId (pSplitWindow->GetItemId(static_cast< ::Window*>(this))); + const USHORT nSetId (pSplitWindow->GetSet(nId)); + // Because the PaneDockingWindow paints its own decoration, we have + // to compensate the valid size range for that. + sal_Int32 nCompensation (pSplitWindow->IsHorizontal() + ? mnTitleBarHeight + maBorder.Top() + maBorder.Bottom() + : maBorder.Left() + maBorder.Right()); + pSplitWindow->SetItemSizeRange( + nSetId, + Range( + aValidSizeRange.Min() + nCompensation, + aValidSizeRange.Max() + nCompensation)); + } +} + + + + +PaneDockingWindow::Orientation PaneDockingWindow::GetOrientation (void) const +{ + SplitWindow* pSplitWindow = dynamic_cast(GetParent()); + if (pSplitWindow == NULL) + return UnknownOrientation; + else if (pSplitWindow->IsHorizontal()) + return HorizontalOrientation; + else + return VerticalOrientation; +} + + + } // end of namespace ::sd diff --git a/sd/source/ui/inc/PaneDockingWindow.hxx b/sd/source/ui/inc/PaneDockingWindow.hxx index c61f0e8d774c..e4516480124f 100644 --- a/sd/source/ui/inc/PaneDockingWindow.hxx +++ b/sd/source/ui/inc/PaneDockingWindow.hxx @@ -38,6 +38,7 @@ #include class ToolBox; +class SplitWindow; namespace sd { @@ -107,6 +108,19 @@ public: ::boost::shared_ptr GetTitleToolBox (void) const; + /** When docked the given range is passed to the parent SplitWindow. + */ + void SetValidSizeRange (const Range aValidSizeRange); + + enum Orientation { HorizontalOrientation, VerticalOrientation, UnknownOrientation }; + /** When the PaneDockingWindow is docked and managed by a split window + it can derive its orientation from the orientation of the split + window and return either HorizontalOrientation or + VerticalOrientation. + Otherwise UnknownOrientation is returned. + */ + Orientation GetOrientation (void) const; + private: /** The pane which is represented by the docking window. */ @@ -127,6 +141,10 @@ private: */ SvBorder maBorder; + /** The current height of the title bar. + */ + sal_Int32 mnTitleBarHeight; + sal_uInt16 mnChildWindowId; ::boost::scoped_ptr< ::Window> mpContentWindow; diff --git a/sd/source/ui/inc/SlideSorter.hxx b/sd/source/ui/inc/SlideSorter.hxx index 49869d807848..c1515ff0d4d4 100644 --- a/sd/source/ui/inc/SlideSorter.hxx +++ b/sd/source/ui/inc/SlideSorter.hxx @@ -200,6 +200,8 @@ public: */ ::boost::shared_ptr GetProperties (void) const; + /** Return the active theme wich gives access to colors and fonts. + */ ::boost::shared_ptr GetTheme (void) const; protected: diff --git a/sd/source/ui/presenter/PresenterPreviewCache.cxx b/sd/source/ui/presenter/PresenterPreviewCache.cxx index 523097f53247..e8b04611b688 100644 --- a/sd/source/ui/presenter/PresenterPreviewCache.cxx +++ b/sd/source/ui/presenter/PresenterPreviewCache.cxx @@ -213,7 +213,7 @@ Reference SAL_CALL PresenterPreviewCache::getSlidePreview ( if (pPage == NULL) throw RuntimeException(); - const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage)); + const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage,true)); if (aPreview.IsEmpty()) return NULL; else diff --git a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx index ba1eb21e9ca6..e8ae79047545 100644 --- a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx +++ b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx @@ -43,6 +43,7 @@ #include "model/SlsPageDescriptor.hxx" #include "controller/SlideSorterController.hxx" + namespace sd { namespace slidesorter { namespace cache { GenericPageCache::GenericPageCache ( @@ -134,7 +135,9 @@ void GenericPageCache::ChangePreviewSize ( -BitmapEx GenericPageCache::GetPreviewBitmap (CacheKey aKey) +BitmapEx GenericPageCache::GetPreviewBitmap ( + const CacheKey aKey, + const bool bResize) { OSL_ASSERT(aKey != NULL); @@ -147,13 +150,15 @@ BitmapEx GenericPageCache::GetPreviewBitmap (CacheKey aKey) ::boost::shared_ptr pPreview(mpBitmapCache->GetBitmap(pPage)); OSL_ASSERT(pPreview.get() != NULL); aPreview = *pPreview; - Size aBitmapSize (aPreview.GetSizePixel()); - if (aBitmapSize != maPreviewSize) + const Size aBitmapSize (aPreview.GetSizePixel()); + if (bResize && aBitmapSize != maPreviewSize) { // Scale the bitmap to the desired size when that is possible, // i.e. the bitmap is not empty. if (aBitmapSize.Width()>0 && aBitmapSize.Height()>0) - aPreview.Scale (maPreviewSize, BMP_SCALE_FAST); + { + aPreview.Scale(maPreviewSize, BMP_SCALE_FAST); + } } bMayBeUpToDate = true; } @@ -172,8 +177,8 @@ BitmapEx GenericPageCache::GetPreviewBitmap (CacheKey aKey) void GenericPageCache::RequestPreviewBitmap ( - CacheKey aKey, - bool bMayBeUpToDate) + const CacheKey aKey, + const bool bMayBeUpToDate) { OSL_ASSERT(aKey != NULL); @@ -211,7 +216,7 @@ void GenericPageCache::RequestPreviewBitmap ( -void GenericPageCache::InvalidatePreviewBitmap (CacheKey aKey) +void GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey) { if (mpBitmapCache.get() != NULL) mpBitmapCache->InvalidateBitmap(mpCacheContext->GetPage(aKey)); @@ -220,7 +225,7 @@ void GenericPageCache::InvalidatePreviewBitmap (CacheKey aKey) -void GenericPageCache::ReleasePreviewBitmap (CacheKey aKey) +void GenericPageCache::ReleasePreviewBitmap (const CacheKey aKey) { if (mpBitmapCache.get() != NULL) { @@ -254,9 +259,9 @@ void GenericPageCache::ReleasePreviewBitmap (CacheKey aKey) -void GenericPageCache::InvalidateCache (bool bUpdateCache) +void GenericPageCache::InvalidateCache (const bool bUpdateCache) { - if (mpBitmapCache.get() != NULL) + if (mpBitmapCache) { // When the cache is being invalidated then it makes no sense to // continue creating preview bitmaps. However, this may be @@ -276,7 +281,9 @@ void GenericPageCache::InvalidateCache (bool bUpdateCache) -void GenericPageCache::SetPreciousFlag (CacheKey aKey, bool bIsPrecious) +void GenericPageCache::SetPreciousFlag ( + const CacheKey aKey, + const bool bIsPrecious) { ProvideCacheAndProcessor(); diff --git a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx index 7afa01a9b860..5196d688be96 100644 --- a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx +++ b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx @@ -81,11 +81,18 @@ public: receives the correctly sized preview bitmap. @param rRequestData This data is used to determine the preview. + @param bResize + When then when the available bitmap has not the + requested size, it is scaled before it is returned. When + then the bitmap is returned in the wrong size and it is + the task of the caller to scale it. @return Returns a bitmap that is either empty, contains a scaled (up or down) version or is the requested bitmap. */ - BitmapEx GetPreviewBitmap (CacheKey aKey); + BitmapEx GetPreviewBitmap ( + const CacheKey aKey, + const bool bResize); /** When the requested preview bitmap does not yet exist or is not up-to-date then the rendering of one is scheduled. Otherwise this @@ -100,33 +107,33 @@ public: unsure use . */ void RequestPreviewBitmap ( - CacheKey aKey, - bool bMayBeUpToDate = true); + const CacheKey aKey, + const bool bMayBeUpToDate = true); /** Tell the cache to replace the bitmap associated with the given request data with a new one that reflects recent changes in the content of the page object. */ - void InvalidatePreviewBitmap (CacheKey aKey); + void InvalidatePreviewBitmap (const CacheKey aKey); /** Call this method when a view-object-contact object is being deleted and does not need (a) its current bitmap in the cache and (b) a requested a new bitmap. */ - void ReleasePreviewBitmap (CacheKey aKey); + void ReleasePreviewBitmap (const CacheKey aKey); /** Call this method when all preview bitmaps have to be generated anew. This is the case when the size of the page objects on the screen has changed or when the model has changed. */ - void InvalidateCache (bool bUpdateCache); + void InvalidateCache (const bool bUpdateCache); /** With the precious flag you can control whether a bitmap can be removed from the cache or reduced in size to make room for other bitmaps or is so precious that it will not be touched. A typical use is to set the precious flag for the visible pages. */ - void SetPreciousFlag (CacheKey aKey, bool bIsPrecious); + void SetPreciousFlag (const CacheKey aKey, const bool bIsPrecious); /** Return when there is no preview bitmap in the cache. */ diff --git a/sd/source/ui/slidesorter/cache/SlsPageCache.cxx b/sd/source/ui/slidesorter/cache/SlsPageCache.cxx index 0e0b7e2f01c4..c0ec8daaf3ca 100644 --- a/sd/source/ui/slidesorter/cache/SlsPageCache.cxx +++ b/sd/source/ui/slidesorter/cache/SlsPageCache.cxx @@ -78,15 +78,17 @@ void PageCache::ChangeSize ( -BitmapEx PageCache::GetPreviewBitmap (CacheKey aKey) +BitmapEx PageCache::GetPreviewBitmap ( + const CacheKey aKey, + const bool bResize) { - return mpImplementation->GetPreviewBitmap(aKey); + return mpImplementation->GetPreviewBitmap(aKey, bResize); } -void PageCache::RequestPreviewBitmap (CacheKey aKey) +void PageCache::RequestPreviewBitmap (const CacheKey aKey) { return mpImplementation->RequestPreviewBitmap(aKey); } @@ -106,8 +108,7 @@ void PageCache::InvalidatePreviewBitmap ( -void PageCache::ReleasePreviewBitmap ( - CacheKey aKey) +void PageCache::ReleasePreviewBitmap (const CacheKey aKey) { mpImplementation->ReleasePreviewBitmap(aKey); } @@ -115,7 +116,7 @@ void PageCache::ReleasePreviewBitmap ( -void PageCache::InvalidateCache (bool bUpdateCache) +void PageCache::InvalidateCache (const bool bUpdateCache) { mpImplementation->InvalidateCache(bUpdateCache); } @@ -124,8 +125,8 @@ void PageCache::InvalidateCache (bool bUpdateCache) void PageCache::SetPreciousFlag ( - CacheKey aKey, - bool bIsPrecious) + const CacheKey aKey, + const bool bIsPrecious) { mpImplementation->SetPreciousFlag(aKey, bIsPrecious); } diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 859b19246f05..7ff2397d5b84 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -800,17 +800,21 @@ Rectangle SlideSorterController::Rearrange (bool bForce) SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { + if (bForce) + mrView.UpdateOrientation(); + // Place the scroll bars. - aNewContentArea = GetScrollBarManager().PlaceScrollBars(maTotalWindowArea); + aNewContentArea = GetScrollBarManager().PlaceScrollBars( + maTotalWindowArea, + mrView.GetOrientation() != view::Layouter::VERTICAL, + mrView.GetOrientation() != view::Layouter::HORIZONTAL); bool bSizeHasChanged (false); // Only when bForce is not true we have to test for a size change in // order to determine whether the window and the view have to be resized. if ( ! bForce) { - Rectangle aCurrentContentArea ( - pWindow->GetPosPixel(), - pWindow->GetOutputSizePixel()); + Rectangle aCurrentContentArea (pWindow->GetPosPixel(), pWindow->GetOutputSizePixel()); bSizeHasChanged = (aNewContentArea != aCurrentContentArea); } if (bForce || bSizeHasChanged) @@ -860,7 +864,7 @@ void SlideSorterController::SetZoom (long int nZoom) { SlideSorterView::DrawLock aLock (mrSlideSorter); - mrView.GetLayouter().SetZoom(nZoom/100.0); + mrView.GetLayouter()._SetZoom(nZoom/100.0); mrView.Layout(); GetScrollBarManager().UpdateScrollBars (false); mrView.GetPreviewCache()->InvalidateCache(); diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 7f74b600640a..7596e9946be2 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -380,7 +380,8 @@ void Clipboard::CreateSlideTransferable ( model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); if ( ! pDescriptor || pDescriptor->GetPage()==NULL) continue; - Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap()); + Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false) + .GetBitmap()); aRepresentatives.push_back(aPreview); if (aRepresentatives.size() >= 3) break; diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index 1537adec84b5..cb301c21d32d 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -136,12 +136,24 @@ void ScrollBarManager::Disconnect (void) window changes and a second call to the layouter becomes necessary. That call is made anyway after this method returns. */ -Rectangle ScrollBarManager::PlaceScrollBars (const Rectangle& rAvailableArea) +Rectangle ScrollBarManager::PlaceScrollBars ( + const Rectangle& rAvailableArea, + const bool bIsHorizontalScrollBarAllowed, + const bool bIsVerticalScrollBarAllowed) { - Rectangle aRemainingSpace (DetermineScrollBarVisibilities(rAvailableArea)); - PlaceHorizontalScrollBar (rAvailableArea); - PlaceVerticalScrollBar (rAvailableArea); - PlaceFiller (rAvailableArea); + Rectangle aRemainingSpace (DetermineScrollBarVisibilities( + rAvailableArea, + bIsHorizontalScrollBarAllowed, + bIsVerticalScrollBarAllowed)); + + if (mpHorizontalScrollBar!=NULL && mpHorizontalScrollBar->IsVisible()) + PlaceHorizontalScrollBar (rAvailableArea); + + if (mpVerticalScrollBar!=NULL && mpVerticalScrollBar->IsVisible()) + PlaceVerticalScrollBar (rAvailableArea); + + if (mpScrollBarFiller!=NULL && mpScrollBarFiller->IsVisible()) + PlaceFiller (rAvailableArea); return aRemainingSpace; } @@ -151,25 +163,21 @@ Rectangle ScrollBarManager::PlaceScrollBars (const Rectangle& rAvailableArea) void ScrollBarManager::PlaceHorizontalScrollBar (const Rectangle& aAvailableArea) { - if (mpHorizontalScrollBar != NULL - && mpHorizontalScrollBar->IsVisible()) - { - // Save the current relative position. - mnHorizontalPosition = double(mpHorizontalScrollBar->GetThumbPos()) - / double(mpHorizontalScrollBar->GetRange().Len()); - - // Place the scroll bar. - Size aScrollBarSize (mpHorizontalScrollBar->GetSizePixel()); - mpHorizontalScrollBar->SetPosSizePixel ( - Point(aAvailableArea.Left(), - aAvailableArea.Bottom()-aScrollBarSize.Height()+1), - Size (aAvailableArea.GetWidth() - GetVerticalScrollBarWidth(), - aScrollBarSize.Height())); - - // Restore the relative position. - mpHorizontalScrollBar->SetThumbPos( - (long)(0.5 + mnHorizontalPosition * mpHorizontalScrollBar->GetRange().Len())); - } + // Save the current relative position. + mnHorizontalPosition = double(mpHorizontalScrollBar->GetThumbPos()) + / double(mpHorizontalScrollBar->GetRange().Len()); + + // Place the scroll bar. + Size aScrollBarSize (mpHorizontalScrollBar->GetSizePixel()); + mpHorizontalScrollBar->SetPosSizePixel ( + Point(aAvailableArea.Left(), + aAvailableArea.Bottom()-aScrollBarSize.Height()+1), + Size (aAvailableArea.GetWidth() - GetVerticalScrollBarWidth(), + aScrollBarSize.Height())); + + // Restore the relative position. + mpHorizontalScrollBar->SetThumbPos( + (long)(0.5 + mnHorizontalPosition * mpHorizontalScrollBar->GetRange().Len())); } @@ -177,21 +185,17 @@ void ScrollBarManager::PlaceHorizontalScrollBar (const Rectangle& aAvailableArea void ScrollBarManager::PlaceVerticalScrollBar (const Rectangle& aArea) { - if (mpVerticalScrollBar != NULL - && mpVerticalScrollBar->IsVisible()) - { - const double nThumbPosition (mpVerticalScrollBar->GetThumbPos()); + const double nThumbPosition (mpVerticalScrollBar->GetThumbPos()); - // Place the scroll bar. - Size aScrollBarSize (mpVerticalScrollBar->GetSizePixel()); - Point aPosition (aArea.Right()-aScrollBarSize.Width()+1, aArea.Top()); - Size aSize (aScrollBarSize.Width(), aArea.GetHeight() - GetHorizontalScrollBarHeight()); - mpVerticalScrollBar->SetPosSizePixel(aPosition, aSize); + // Place the scroll bar. + Size aScrollBarSize (mpVerticalScrollBar->GetSizePixel()); + Point aPosition (aArea.Right()-aScrollBarSize.Width()+1, aArea.Top()); + Size aSize (aScrollBarSize.Width(), aArea.GetHeight() - GetHorizontalScrollBarHeight()); + mpVerticalScrollBar->SetPosSizePixel(aPosition, aSize); - // Restore the position. - mpVerticalScrollBar->SetThumbPos(nThumbPosition); - mnVerticalPosition = nThumbPosition / double(mpVerticalScrollBar->GetRange().Len()); - } + // Restore the position. + mpVerticalScrollBar->SetThumbPos(nThumbPosition); + mnVerticalPosition = nThumbPosition / double(mpVerticalScrollBar->GetRange().Len()); } @@ -199,23 +203,13 @@ void ScrollBarManager::PlaceVerticalScrollBar (const Rectangle& aArea) void ScrollBarManager::PlaceFiller (const Rectangle& aArea) { - // Place the filler when both scroll bars are visible. - if (mpHorizontalScrollBar != NULL - && mpVerticalScrollBar != NULL - && mpHorizontalScrollBar->IsVisible() - && mpVerticalScrollBar->IsVisible()) - { - mpScrollBarFiller->SetPosSizePixel( - Point( - aArea.Right()-mpVerticalScrollBar->GetSizePixel().Width()+1, - aArea.Bottom()-mpHorizontalScrollBar->GetSizePixel().Height()+1), - Size ( - mpVerticalScrollBar->GetSizePixel().Width(), - mpHorizontalScrollBar->GetSizePixel().Height())); - mpScrollBarFiller->Show(); - } - else - mpScrollBarFiller->Hide(); + mpScrollBarFiller->SetPosSizePixel( + Point( + aArea.Right()-mpVerticalScrollBar->GetSizePixel().Width()+1, + aArea.Bottom()-mpHorizontalScrollBar->GetSizePixel().Height()+1), + Size ( + mpVerticalScrollBar->GetSizePixel().Width(), + mpHorizontalScrollBar->GetSizePixel().Height())); } @@ -224,8 +218,7 @@ void ScrollBarManager::PlaceFiller (const Rectangle& aArea) void ScrollBarManager::AdaptWindowSize (const Rectangle& rArea) { Size aPixelContentSize (mpContentWindow->LogicToPixel( - mrSlideSorter.GetView().GetLayouter().GetPageBox ( - mrSlideSorter.GetModel().GetPageCount()).GetSize())); + mrSlideSorter.GetView().GetLayouter().GetTotalBoundingBox().GetSize())); int nHeightDifference = aPixelContentSize.Height() - rArea.GetHeight(); ::Window* pParentWindow = mpContentWindow->GetParent(); Size aNewWindowSize (pParentWindow->GetSizePixel()); @@ -391,7 +384,10 @@ void ScrollBarManager::SetWindowOrigin ( b) when not showing a scroll bar the area used by the page objects fits into the available area in the scroll bars orientation. */ -Rectangle ScrollBarManager::DetermineScrollBarVisibilities (const Rectangle& rAvailableArea) +Rectangle ScrollBarManager::DetermineScrollBarVisibilities ( + const Rectangle& rAvailableArea, + const bool bIsHorizontalScrollBarAllowed, + const bool bIsVerticalScrollBarAllowed) { // Test which combination of scroll bars is the best. bool bShowHorizontal = false; @@ -402,20 +398,35 @@ Rectangle ScrollBarManager::DetermineScrollBarVisibilities (const Rectangle& rAv // No pages => no scroll bars. break; - if (TestScrollBarVisibilities(bShowHorizontal=false, bShowVertical=false, rAvailableArea)) + if (TestScrollBarVisibilities(false, false, rAvailableArea)) break; - if (TestScrollBarVisibilities(bShowHorizontal=true, bShowVertical=false, rAvailableArea)) + if (bIsHorizontalScrollBarAllowed + && TestScrollBarVisibilities(true, false, rAvailableArea)) + { + bShowHorizontal = true; break; - if (TestScrollBarVisibilities(bShowHorizontal=false, bShowVertical=true, rAvailableArea)) + } + if (bIsVerticalScrollBarAllowed + && TestScrollBarVisibilities(false, true, rAvailableArea)) + { + bShowVertical = true; break; - if (TestScrollBarVisibilities(bShowHorizontal=true, bShowVertical=true, rAvailableArea)) + } + if (bIsHorizontalScrollBarAllowed + && bIsVerticalScrollBarAllowed + && TestScrollBarVisibilities(true, true, rAvailableArea)) + { + bShowHorizontal = true; + bShowVertical = true; break; + } } while (false); // Make the visibility of the scroll bars permanent. mpVerticalScrollBar->Show(bShowVertical); mpHorizontalScrollBar->Show(bShowHorizontal); + mpScrollBarFiller->Show(bShowVertical && bShowHorizontal); // Adapt the remaining space accordingly. Rectangle aRemainingSpace (rAvailableArea); @@ -449,26 +460,15 @@ bool ScrollBarManager::TestScrollBarVisibilities ( // Tell the view to rearrange its page objects and check whether the // page objects can be shown without clipping. - bool bRearrangeSuccess (false); - if (mrSlideSorter.GetView().GetOrientation() == view::SlideSorterView::HORIZONTAL) - { - bRearrangeSuccess = mrSlideSorter.GetView().GetLayouter().RearrangeHorizontal ( - aBrowserSize, - rModel.GetPageDescriptor(0)->GetPage()->GetSize(), - rModel.GetPageCount()); - } - else - { - bRearrangeSuccess = mrSlideSorter.GetView().GetLayouter().RearrangeVertical ( - aBrowserSize, - rModel.GetPageDescriptor(0)->GetPage()->GetSize(), - rModel.GetPageCount()); - } + bool bRearrangeSuccess (mrSlideSorter.GetView().GetLayouter().Rearrange ( + mrSlideSorter.GetView().GetOrientation(), + aBrowserSize, + rModel.GetPageDescriptor(0)->GetPage()->GetSize(), + rModel.GetPageCount())); if (bRearrangeSuccess) { - Size aPageSize = mrSlideSorter.GetView().GetLayouter().GetPageBox ( - rModel.GetPageCount()).GetSize(); + Size aPageSize = mrSlideSorter.GetView().GetLayouter().GetTotalBoundingBox().GetSize(); Size aWindowModelSize = mpContentWindow->PixelToLogic(aBrowserSize); bool bHorizontallyClipped = (aPageSize.Width() > aWindowModelSize.Width()); diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index ac155377c0df..9ddfbf481b7e 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -389,12 +389,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) case KEY_ESCAPE: // When there is an active multiselection or drag-and-drop - // operation then stop that. Otherwise transfer the focus to - // the tool box. - - if ( ! (mpDragAndDropContext || mpMouseMultiSelector)) - rFocusManager.SetFocusToToolBox(); - + // operation then stop that. StopDragAndDrop(); if (mpMouseMultiSelector) { @@ -1125,7 +1120,8 @@ void SelectionFunction::ProcessButtonUpEvent (const EventDescriptor& rDescriptor 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()) + && mnButtonDownPageIndex == rDescriptor.mpHitDescriptor->GetPageIndex() + && rDescriptor.mpHitDescriptor->GetVisualState().GetButtonAlpha()<0.7) { ProcessButtonClick(rDescriptor.mpHitDescriptor, mnButtonDownButtonIndex); } @@ -1146,7 +1142,7 @@ void SelectionFunction::ProcessMouseMotionEvent (const EventDescriptor& rDescrip switch (rDescriptor.mnEventCode) { case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE): - SetCurrentPage(rDescriptor.mpHitDescriptor); + // SetCurrentPage(rDescriptor.mpHitDescriptor); // Fallthrough // A mouse motion without visible substitution starts that. diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index e1d42b161053..0cec638ac82c 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -436,7 +436,7 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) sal_Int32 nNewTop (aVisibleArea.Top()); sal_Int32 nNewLeft (aVisibleArea.Left()); - if (mrSlideSorter.GetView().GetOrientation() != SlideSorterView::HORIZONTAL) + if (mrSlideSorter.GetView().GetOrientation() != Layouter::HORIZONTAL) { // Scroll the visible area to make aSelectionBox visible. if (mrSlideSorter.GetProperties()->IsCenterSelection()) @@ -461,7 +461,7 @@ Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) } - if (mrSlideSorter.GetView().GetOrientation() != SlideSorterView::VERTICAL) + if (mrSlideSorter.GetView().GetOrientation() != Layouter::VERTICAL) { // Scroll the visible area to make aSelectionBox visible. if (mrSlideSorter.GetProperties()->IsCenterSelection()) @@ -547,7 +547,7 @@ bool SelectionManager::DoesSelectionExceedVisibleArea (const Rectangle& rSelecti Rectangle( Point(0,0), pWindow->GetOutputSizePixel()))); - if (mrSlideSorter.GetView().GetOrientation() == SlideSorterView::VERTICAL) + if (mrSlideSorter.GetView().GetOrientation() != Layouter::HORIZONTAL) return rSelectionBox.GetHeight() > aVisibleArea.GetHeight(); else return rSelectionBox.GetWidth() > aVisibleArea.GetWidth(); diff --git a/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx index b4e91acd0dca..d32b1a82aeef 100644 --- a/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx +++ b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx @@ -111,22 +111,30 @@ public: preview, i.e. either a scaled (up or down) version of a previous preview (of the wrong size) or an empty bitmap. In this case a request for the generation of a new preview is created and inserted - into the request queue. When the preview is available the page - shape will be told to paint itself again. When it then calls this - method again if receives the correctly sized preview bitmap. + into the request queue. When the preview is available in the right + size the page shape will be told to paint itself again. When it + then calls this method again if receives the correctly sized preview + bitmap. @param rRequestData This data is used to determine the preview. + @param bResize + When then when the available bitmap has not the + requested size, it is scaled before it is returned. When + then the bitmap is returned in the wrong size and it is + the task of the caller to scale it. @return Returns a bitmap that is either empty, contains a scaled (up or down) version or is the requested bitmap. */ - BitmapEx GetPreviewBitmap (CacheKey aKey); + BitmapEx GetPreviewBitmap ( + const CacheKey aKey, + const bool bResize); /** When the requested preview bitmap does not yet exist or is not up-to-date then the rendering of one is scheduled. Otherwise this method does nothing. */ - void RequestPreviewBitmap (CacheKey aKey); + void RequestPreviewBitmap (const CacheKey aKey); /** Tell the cache that the bitmap associated with the given request data is not up-to-date anymore. @@ -142,7 +150,7 @@ public: and does not need (a) its current bitmap in the cache and (b) a requested new bitmap. */ - void ReleasePreviewBitmap (CacheKey aKey); + void ReleasePreviewBitmap (const CacheKey aKey); /** Call this method when all preview bitmaps have to be generated anew. This is the case when the size of the page objects on the screen has @@ -152,14 +160,14 @@ public: are created. When it is the existing previews are only marked as not being up-to-date anymore. */ - void InvalidateCache (bool bUpdateCache = true); + void InvalidateCache (const bool bUpdateCache = true); /** With the precious flag you can control whether a bitmap can be removed or reduced in size to make room for other bitmaps or is so precious that it will not touched. A typical use is to set the precious flag for exactly the visible pages. */ - void SetPreciousFlag (CacheKey aKey, bool bIsPrecious); + void SetPreciousFlag (const CacheKey aKey, const bool bIsPrecious); void Pause (void); void Resume (void); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx index 4c3a71e578d7..7d23cd17b983 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx @@ -116,20 +116,25 @@ public: bool bScrollToCurrentPosition = true); /** Place the scroll bars inside the given area. When the available - area is not large enough for the content to display the resulting - behaviour depends on the mbUseVerticalScrollBar flag. When it is - set to true then a vertical scroll bar is shown. Otherwise the - height of the returned area is enlarged so that the content fits - into it. + area is not large enough for the content to display the horizontal + and/or vertical scroll bar is enabled. @param rAvailableArea The scroll bars will be placed inside this rectangle. It is expected to be given in pixel relative to its parent. + @param bIsHorizontalScrollBarAllowed + Only when this flag is the horizontal scroll may be + displayed. + @param bIsVerticalScrollBarAllowed + Only when this flag is the horizontal scroll may be + displayed. @return Returns the space that remains after the scroll bars are - placed. When the mbUseVerticalScrollBar flag is false then the - returned rectangle may be larger than the given one. + placed. */ - Rectangle PlaceScrollBars (const Rectangle& rAvailableArea); + Rectangle PlaceScrollBars ( + const Rectangle& rAvailableArea, + const bool bIsHorizontalScrollBarAllowed, + const bool bIsVerticalScrollBarAllowed); /** Update the vertical and horizontal scroll bars so that the visible area has the given top and left values. @@ -231,7 +236,10 @@ private: The area that is enclosed by the scroll bars is returned. It will be filled with the SlideSorterView. */ - Rectangle DetermineScrollBarVisibilities (const Rectangle& rAvailableArea); + Rectangle DetermineScrollBarVisibilities( + const Rectangle& rAvailableArea, + const bool bIsHorizontalScrollBarAllowed, + const bool bIsVerticalScrollBarAllowed); /** Typically called by DetermineScrollBarVisibilities() this method tests a specific configuration of the two scroll bars being visible diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index a9cad51af652..b5bdb91ade29 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -34,6 +34,7 @@ #include "SlideSorter.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsSharedPageDescriptor.hxx" +#include "view/SlsLayouter.hxx" #include "View.hxx" #include @@ -88,9 +89,11 @@ public: virtual ~SlideSorterView (void); void Dispose (void); - enum Orientation { HORIZONTAL, VERTICAL, GRID }; - void SetOrientation (const Orientation eOrientation); - Orientation GetOrientation (void) const; + /** Set the general way of layouting the page objects. Note that this + method does not trigger any repaints or layouts. + */ + bool SetOrientation (const Layouter::Orientation eOrientation); + Layouter::Orientation GetOrientation (void) const; void RequestRepaint (void); void RequestRepaint (const model::SharedPageDescriptor& rDescriptor); @@ -211,6 +214,8 @@ public: const bool bStateValue, const bool bAnimate = true); + void UpdateOrientation (void); + ::boost::shared_ptr GetPageObjectPainter (void); ::boost::shared_ptr GetLayeredDevice (void) const; @@ -244,7 +249,7 @@ private: bool mbModelChangedWhileModifyEnabled; Size maPreviewSize; bool mbPreciousFlagUpdatePending; - Orientation meOrientation; + Layouter::Orientation meOrientation; ::boost::shared_ptr mpProperties; model::SharedPageDescriptor mpPageUnderMouse; bool mbIsMouseOverIndicationAllowed; @@ -258,9 +263,6 @@ private: void DeterminePageObjectVisibilities (void); void UpdatePreciousFlags (void); - - ::drawinglayer::primitive2d::Primitive2DSequence GetPrimitive2DHierarchy ( - const Region& rPaintArea) const; }; diff --git a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx index 12bc67aa5e4b..ee27cd9201c6 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx @@ -77,21 +77,13 @@ class InsertPosition; class Layouter { public: + enum Orientation { HORIZONTAL, VERTICAL, GRID }; + Layouter (const SharedSdWindow& rpWindow); ~Layouter (void); ::boost::shared_ptr GetPageObjectLayouter (void) const; - /** Set the minimal, the maximal, and the desired width of the page - objects. The three parameters have to fullfill the constraint - nMinimalWidth <= nPreferredWidth <= nMaximalWidth or the call is - ignored. - */ - void SetObjectWidth ( - sal_Int32 nMinimalWidth, - sal_Int32 nMaximalWidth, - sal_Int32 nPreferredWidth); - /** Set the horizontal and vertical borders in pixel coordinates between the enclosing window and page objects. The borders may be painted larger then the given values when the space for the insertion marker @@ -133,6 +125,9 @@ public: /** Central method of this class. It takes the input values and calculates the output values. Both given sizes must not be 0 in any dimension or the call is ignored. + @param eOrientation + This defines the generaly layout and specifies whether there may + be more than one row or more than one column. @param rWindowSize The size of the window in pixels that the slide sorter is displayed in. This can differ from the size of mpWindow during @@ -146,11 +141,8 @@ public: The return value indicates whether the Get... methods can be used to obtain valid values (). */ - bool RearrangeHorizontal ( - const Size& rWindowSize, - const Size& rPreviewModelSize, - const sal_uInt32 nPageCount); - bool RearrangeVertical ( + bool Rearrange ( + const Orientation eOrientation, const Size& rWindowSize, const Size& rPreviewModelSize, const sal_uInt32 nPageCount); @@ -158,8 +150,8 @@ public: /** Change the zoom factor. This does not change the general layout (number of columns). */ - void SetZoom (double nZoomFactor); - void SetZoom (Fraction nZoomFactor); + void _SetZoom (double nZoomFactor); + void _SetZoom (Fraction nZoomFactor); /** Return the number of columns. */ @@ -196,7 +188,7 @@ public: /** Return the bounding box in model coordinates of the page that contains the given amount of page objects. */ - Rectangle GetPageBox (const sal_Int32 nObjectCount = -1) const; + Rectangle GetTotalBoundingBox (void) const; /** Return the index of the first fully or partially visible page object. This takes into account only the vertical dimension. @@ -247,143 +239,19 @@ public: const Size& rIndicatorSize, model::SlideSorterModel& rModel) const; - /** Return whether the main orientation of the slides in the slide - sorter is vertical, i.e. all slides are arranged in one column. - */ - bool IsVertical (void) const; + Range GetValidHorizontalSizeRange (void) const; + Range GetValidVerticalSizeRange (void) const; + class Implementation; private: + ::boost::scoped_ptr mpImplementation; SharedSdWindow mpWindow; - sal_Int32 mnRequestedLeftBorder; - sal_Int32 mnRequestedRightBorder; - sal_Int32 mnRequestedTopBorder; - sal_Int32 mnRequestedBottomBorder; - sal_Int32 mnLeftBorder; - sal_Int32 mnRightBorder; - sal_Int32 mnTopBorder; - sal_Int32 mnBottomBorder; - sal_Int32 mnVerticalGap; - sal_Int32 mnHorizontalGap; - sal_Int32 mnMinimalWidth; - sal_Int32 mnPreferredWidth; - sal_Int32 mnMaximalWidth; - sal_Int32 mnMinimalColumnCount; - sal_Int32 mnMaximalColumnCount; - sal_Int32 mnPageCount; - sal_Int32 mnColumnCount; - sal_Int32 mnRowCount; - /// The maximum number of columns. Can only be larger than the current - /// number of columns when there are not enough pages to fill all - /// available columns. - sal_Int32 mnMaxColumnCount; - /// The maximum number of rows. Can only be larger than the current - /// number of rows when there are not enough pages to fill all available - /// rows. - sal_Int32 mnMaxRowCount; - Size maPageObjectSize; - bool mbIsVertical; - - ::boost::shared_ptr mpPageObjectLayouter; - - enum GapMembership { GM_NONE, GM_PREVIOUS, GM_BOTH, GM_NEXT, - GM_PAGE_BORDER}; - - /** Calculate the row that the point with the given vertical coordinate - is over. The horizontal component is ignored. - @param nYPosition - Vertical position in model coordinates. - @param bIncludeBordersAndGaps - When this flag is then the area of borders and gaps are - interpreted as belonging to one of the rows. - @param eGapMembership - Specifies to what row the gap areas belong. Here GM_NONE - corresponds to bIncludeBordersAndGaps being . When - GM_BOTH is given then the upper half is associated to the row - above and the lower half to the row below. Values of - GM_PREVIOUS and GM_NEXT associate the whole gap area with the - row above or below respectively. - */ - sal_Int32 GetRowAtPosition ( - sal_Int32 nYPosition, - bool bIncludeBordersAndGaps, - GapMembership eGapMembership = GM_NONE) const; - - /** Calculate the column that the point with the given horizontal - coordinate is over. The verical component is ignored. - @param nXPosition - Horizontal position in model coordinates. - @param bIncludeBordersAndGaps - When this flag is then the area of borders and gaps are - interpreted as belonging to one of the columns. - @param eGapMembership - Specifies to what column the gap areas belong. Here GM_NONE - corresponds to bIncludeBordersAndGaps being . When - GM_BOTH is given then the left half is associated with the - column at the left and the right half with the column to the - right. Values of GM_PREVIOUS and GM_NEXT associate the whole - gap area with the column to the left or right respectively. - */ - sal_Int32 GetColumnAtPosition ( - sal_Int32 nXPosition, - bool bIncludeBordersAndGaps, - GapMembership eGapMembership = GM_NONE) const; - - /** This method is typically called from GetRowAtPosition() and - GetColumnAtPosition() to handle a position that lies inside the gap - between two adjacent rows or columns. - @param nDistanceIntoGap - Vertical distance from the bottom of the upper row down into the - gap or or horizontal distance from the right edge right into the - gap. - @param eGapMemberhship - This value decides what areas in the gap belong to which (or no) - row or column. - @param nIndex - The row index of the upper row or the column index of the left - column. - @param nGap - Width or height of the gap in model coordiantes between the - page borders. - @return - Returns either the index of the upper row (as given as nRow), the - index of the lower row (nRow+1) or -1 to indicate that the - position belongs to no row. - */ - sal_Int32 ResolvePositionInGap ( - sal_Int32 nDistanceIntoGap, - GapMembership eGapMembership, - sal_Int32 nIndex, - sal_Int32 nGap) const; - - /** Calculate the logical part of the insert position, i.e. the page - after whicht to insert. - */ - void CalculateLogicalInsertPosition ( - const Point& rModelPosition, - InsertPosition& rPosition) const; - - /** Calculate the geometrical part of the insert position, i.e. the - location of where to display the insertion indicator and the - distances about which the leading and trailing pages have to be - moved to make room for the indicator. - */ - void CalculateGeometricPosition ( - InsertPosition& rPosition, - const Size& rIndicatorSize, - const bool bIsVertical, - model::SlideSorterModel& rModel) const; - - /** Return the bounding box of the preview or, when selected, of the page - object. Thus, it returns something like a visual bounding box. - */ - Rectangle GetInnerBoundingBox ( - model::SlideSorterModel& rModel, - const sal_Int32 nIndex) const; }; + /** Collect all values concerning the logical and visual properties of the insertion position that is used for drag-and-drop and copy-and-past. */ @@ -395,6 +263,18 @@ public: bool operator== (const InsertPosition& rInsertPosition) const; bool operator!= (const InsertPosition& rInsertPosition) const; + void SetLogicalPosition ( + const sal_Int32 nRow, + const sal_Int32 nColumn, + const sal_Int32 nIndex, + const bool bIsAtRunStart, + const bool bIsAtRunEnd, + const bool bIsExtraSpaceNeeded); + void SetGeometricalPosition( + const Point aLocation, + const Point aLeadingOffset, + const Point aTrailingOffset); + sal_Int32 GetRow (void) const { return mnRow; } sal_Int32 GetColumn (void) const { return mnColumn; } sal_Int32 GetIndex (void) const { return mnIndex; } @@ -409,14 +289,12 @@ private: sal_Int32 mnRow; sal_Int32 mnColumn; sal_Int32 mnIndex; - Point maLocation; - Point maLeadingOffset; - Point maTrailingOffset; bool mbIsAtRunStart : 1; bool mbIsAtRunEnd : 1; bool mbIsExtraSpaceNeeded : 1; - - friend class Layouter; + Point maLocation; + Point maLeadingOffset; + Point maTrailingOffset; }; diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx index 089d9b70f5fc..d3fb4857ae64 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorter.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -200,26 +200,25 @@ void SlideSorter::Init (void) SetupListeners (); // Initialize the window. - SharedSdWindow pWindow (GetContentWindow()); - if (pWindow != NULL) + SharedSdWindow pContentWindow (GetContentWindow()); + if (pContentWindow) { - ::Window* pParentWindow = pWindow->GetParent(); + ::Window* pParentWindow = pContentWindow->GetParent(); if (pParentWindow != NULL) pParentWindow->SetBackground(Wallpaper()); - pWindow->SetBackground(Wallpaper()); - pWindow->SetViewOrigin (Point(0,0)); + pContentWindow->SetBackground(Wallpaper()); + pContentWindow->SetViewOrigin (Point(0,0)); // We do our own scrolling while dragging a page selection. - pWindow->SetUseDropScroll (false); + pContentWindow->SetUseDropScroll (false); // Change the winbits so that the active window accepts the focus. - pWindow->SetStyle ((pWindow->GetStyle() & ~WB_DIALOGCONTROL) | WB_TABSTOP); - pWindow->Hide(); + pContentWindow->SetStyle ((pContentWindow->GetStyle() & ~WB_DIALOGCONTROL) | WB_TABSTOP); + pContentWindow->Hide(); // Set view pointer of base class. SetupControls(pParentWindow); mbIsValid = true; } - } @@ -697,7 +696,6 @@ long ContentWindow::Notify (NotifyEvent& rEvent) - } // end of anonymous namespace diff --git a/sd/source/ui/slidesorter/shell/SlideSorterService.cxx b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx index c339f9004d60..283be95d915f 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterService.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterService.cxx @@ -38,6 +38,7 @@ #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" +#include "view/SlsLayouter.hxx" #include "DrawController.hxx" #include #include @@ -50,7 +51,7 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; using ::rtl::OUString; -using ::sd::slidesorter::view::SlideSorterView; +using ::sd::slidesorter::view::Layouter; namespace sd { namespace slidesorter { @@ -448,7 +449,7 @@ sal_Bool SAL_CALL SlideSorterService::getIsOrientationVertical (void) if (mpSlideSorter.get() == NULL || ! mpSlideSorter->IsValid()) return true; else - return mpSlideSorter->GetView().GetOrientation() == SlideSorterView::VERTICAL; + return mpSlideSorter->GetView().GetOrientation() != Layouter::HORIZONTAL; } @@ -460,8 +461,8 @@ void SAL_CALL SlideSorterService::setIsOrientationVertical (sal_Bool bValue) ThrowIfDisposed(); if (mpSlideSorter.get() != NULL && mpSlideSorter->IsValid()) mpSlideSorter->GetView().SetOrientation(bValue - ? SlideSorterView::VERTICAL - : SlideSorterView::HORIZONTAL); + ? Layouter::GRID + : Layouter::HORIZONTAL); } diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 4e0fc3c66260..edd3e37dae20 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -112,13 +112,6 @@ TYPEINIT1(SlideSorterViewShell, ViewShell); pViewShell->Initialize(); if (pViewShell->mpSlideSorter.get() == NULL) pViewShell.reset(); - - // The layout of slides depends on whether the slide sorter is - // displayed in the center or the side pane. - if (bIsCenterPane) - pViewShell->mpSlideSorter->GetView().SetOrientation(view::SlideSorterView::GRID); - else - pViewShell->mpSlideSorter->GetView().SetOrientation(view::SlideSorterView::VERTICAL); } catch(Exception&) { @@ -571,7 +564,29 @@ void SlideSorterViewShell::ArrangeGUIElements (void) bool SlideSorterViewShell::HandleScrollCommand (const CommandEvent& rEvent, ::sd::Window* pWindow) { - bool bDone = ViewShell::HandleScrollCommand(rEvent, pWindow); + bool bDone (false); + + if (rEvent.GetCommand() == COMMAND_WHEEL + && mpSlideSorter->GetView().GetOrientation() == view::Layouter::HORIZONTAL) + { + // Make the wheel scroll the horizontal scroll bar. For this we + // change the IsHoriz() flag of the CommandWheelData structure. + CommandWheelData* pData = (CommandWheelData*)rEvent.GetData(); + CommandEvent aEvent ( + rEvent.GetMousePosPixel(), + COMMAND_WHEEL, + FALSE, + new CommandWheelData( + pData->GetDelta(), + pData->GetNotchDelta(), + pData->GetScrollLines(), + pData->GetMode(), + pData->GetModifier(), + TRUE)); + bDone = ViewShell::HandleScrollCommand(aEvent, pWindow); + } + else + bDone = ViewShell::HandleScrollCommand(rEvent, pWindow); if (bDone) { @@ -617,16 +632,12 @@ void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView) view::SlideSorterView& rView (mpSlideSorter->GetView()); USHORT nSlidesPerRow (pFrameView->GetSlidesPerRow()); - if (nSlidesPerRow == 0 || ! IsMainViewShell()) + if (nSlidesPerRow > 0 + && rView.GetOrientation() == view::Layouter::GRID + && IsMainViewShell()) { - // When a value of 0 (automatic) is given or the the slide - // sorter is displayed in a side pane then we ignore the value - // of the frame view and adapt the number of columns - // automatically to the window width. - rView.GetLayouter().SetColumnCount(1,1); - } - else rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow); + } if (IsMainViewShell()) mpSlideSorter->GetController().GetCurrentSlideManager()->NotifyCurrentSlideChange( mpFrameView->GetSelectedPage()); diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 16da8620fb9b..fdfd9ec8f8f0 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -54,6 +54,7 @@ #include "cache/SlsCacheContext.hxx" #include "taskpane/SlideSorterCacheDisplay.hxx" #include "DrawDocShell.hxx" +#include "PaneDockingWindow.hxx" #include "drawdoc.hxx" #include "sdpage.hxx" @@ -122,97 +123,8 @@ private: SlideSorterView& mrView; }; -class AnimatedSphere -{ -public: - AnimatedSphere ( - const Size& rWindowSize, - const double nStartTime) - : mnCenterX(rand() * rWindowSize.Width() / RAND_MAX), - mnCenterY(rand() * rWindowSize.Height() / RAND_MAX), - mnStartRadius(10), - mnEndRadius(rand() * 150 / RAND_MAX), - maColor(GetColor()), - mnLocalTime(-nStartTime), - mnValue(0), - mnStartTime(nStartTime), - mbIsValid(rWindowSize.Width()>10 && rWindowSize.Height()>10), - mnSpeedUp(0.5 + rand() * 1.0 / RAND_MAX) - { - } - void SetTime (const double nTime) - { - mnLocalTime = (nTime - mnStartTime) * mnSpeedUp; - if (mnLocalTime >= 0 && mnLocalTime <= mnSpeedUp) - mnValue = controller::AnimationFunction::SlowInSlowOut_0to0_Sine(mnLocalTime/mnSpeedUp); - else - mnValue = 0; - } - bool IsExpired (void) - { - return mnLocalTime >= mnSpeedUp || ! mbIsValid; - } - - Rectangle GetBoundingBox (void) - { - if (mnLocalTime < 0) - return Rectangle(); - - const double nRadius (mnStartRadius*(1-mnValue) + mnEndRadius*mnValue); - const sal_Int32 nIntRadius (ceil(nRadius)+1); - return Rectangle( - mnCenterX-nIntRadius, - mnCenterY-nIntRadius, - mnCenterX+nIntRadius, - mnCenterY+nIntRadius); - } - - void Paint (OutputDevice& rDevice) - { - if (mnLocalTime < 0 || ! mbIsValid) - return; - - rDevice.SetFillColor(maColor); - rDevice.SetLineColor(); - - const Rectangle aBox (GetBoundingBox()); - const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); - rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); - rDevice.DrawPolygon( - ::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), - 1.0, - 1.0)); - rDevice.SetAntialiasing(nSavedAntialiasingMode); - } - -private: - const sal_Int32 mnCenterX; - const sal_Int32 mnCenterY; - const double mnStartRadius; - const double mnEndRadius; - const Color maColor; - double mnLocalTime; - double mnValue; - const double mnStartTime; - const bool mbIsValid; - const double mnSpeedUp; - - static Color GetColor (void) - { - Color aColor; - do - { - aColor.SetRed(rand() * 255 / RAND_MAX); - aColor.SetGreen(rand() * 255 / RAND_MAX); - aColor.SetBlue(rand() * 255 / RAND_MAX); - } - while (aColor.GetGreen()<=aColor.GetRed() || aColor.GetGreen()<=aColor.GetBlue()); - return aColor; - } -}; class BackgroundPainter : public ILayerPainter, @@ -220,31 +132,15 @@ class BackgroundPainter { public: BackgroundPainter ( - const ::boost::shared_ptr& rpAnimator, const SharedSdWindow& rpWindow, - const Color aBackgroundColor, - const bool bIsAnimated) - : mpAnimator(rpAnimator), - maBackgroundColor(aBackgroundColor), - maSpheres(), - mpInvalidator(), - mpWindow(rpWindow), - mnAnimationId(controller::Animator::NotAnAnimationId) + const Color aBackgroundColor) + : maBackgroundColor(aBackgroundColor), + mpWindow(rpWindow) { - if (bIsAnimated) - { - mnAnimationId = mpAnimator->AddInfiniteAnimation(::boost::ref(*this), 0.01); - - for (sal_Int32 nIndex=0; nIndex<10; ++nIndex) - maSpheres.push_back(::boost::shared_ptr( - new AnimatedSphere(rpWindow->GetSizePixel(), nIndex*0.3))); - } } ~BackgroundPainter (void) { - if (mnAnimationId >= 0) - mpAnimator->RemoveAnimation(mnAnimationId); } virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) @@ -252,66 +148,16 @@ public: rDevice.SetFillColor(maBackgroundColor); rDevice.SetLineColor(); rDevice.DrawRect(rRepaintArea); - - for (SphereVector::const_iterator - iSphere(maSpheres.begin()), - iEnd(maSpheres.end()); - iSphere!=iEnd; - ++iSphere) - { - if (rRepaintArea.IsOver((*iSphere)->GetBoundingBox())) - (*iSphere)->Paint(rDevice); - } } virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator) { - Invalidate(); - mpInvalidator = rpInvalidator; - Invalidate(); - } - - void operator () (const double nTime) - { - Invalidate(); - - for (SphereVector::iterator - iSphere(maSpheres.begin()), - iEnd(maSpheres.end()); - iSphere!=iEnd; - ++iSphere) - { - if ((*iSphere)->IsExpired()) - (*iSphere).reset( - new AnimatedSphere(mpWindow->GetSizePixel(), nTime)); - else - (*iSphere)->SetTime(nTime); - } - - Invalidate(); + (void)rpInvalidator; } private: - const ::boost::shared_ptr mpAnimator; const Color maBackgroundColor; - typedef ::std::vector< ::boost::shared_ptr > SphereVector; - SphereVector maSpheres; - SharedILayerInvalidator mpInvalidator; SharedSdWindow mpWindow; - controller::Animator::AnimationId mnAnimationId; - - void Invalidate (void) - { - if (mpInvalidator) - for (SphereVector::const_iterator - iSphere(maSpheres.begin()), - iEnd(maSpheres.end()); - iSphere!=iEnd; - ++iSphere) - { - mpInvalidator->Invalidate((*iSphere)->GetBoundingBox()); - } - } }; @@ -334,7 +180,7 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) mbModelChangedWhileModifyEnabled(true), maPreviewSize(0,0), mbPreciousFlagUpdatePending(true), - meOrientation(VERTICAL), + meOrientation(Layouter::GRID), mpProperties(rSlideSorter.GetProperties()), mpPageUnderMouse(), mbIsMouseOverIndicationAllowed(true), @@ -342,8 +188,6 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) mpPageObjectPainter(), mpSelectionPainter() { - OSL_TRACE("layered device at %x", mpLayeredDevice.get()); - // Hide the page that contains the page objects. SetPageVisible (FALSE); @@ -352,7 +196,6 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) // the SlideSorterView destructor the layered device is destroyed and // with it the only reference to the wrapper which therefore is also // destroyed. - OSL_TRACE("layered device at %x", mpLayeredDevice.get()); mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 2); } @@ -374,9 +217,6 @@ SlideSorterView::~SlideSorterView (void) void SlideSorterView::Init (void) { HandleModelChange(); - - // mpSelectionPainter.reset(new SelectionPainter(mrSlideSorter)); - // mpLayeredDevice->RegisterPainter(mpSelectionPainter, 1); } @@ -389,7 +229,7 @@ void SlideSorterView::Dispose (void) mpLayeredDevice->Dispose(); mpPreviewCache.reset(); - // hide the page to avoid problems in the view when deleting + // Hide the page to avoid problems in the view when deleting // visualized objects HideSdrPage(); @@ -448,11 +288,6 @@ void SlideSorterView::LocalModelHasChanged(void) // First call our base class. View::ModelHasChanged (); - - // Initialize everything that depends on a page view, now that we have - // one. - // SetApplicationDocumentColor( - // Application::GetSettings().GetStyleSettings().GetWindowColor()); } @@ -514,34 +349,25 @@ void SlideSorterView::HandleDrawModeChange (void) void SlideSorterView::Resize (void) { + UpdateOrientation(); + if ( ! mpLayeredDevice->HasPainter(0)) mpLayeredDevice->RegisterPainter( SharedILayerPainter(new BackgroundPainter( - mrSlideSorter.GetController().GetAnimator(), mrSlideSorter.GetContentWindow(), - mrSlideSorter.GetTheme()->GetColor(Theme::Background), - false)), + mrSlideSorter.GetTheme()->GetColor(Theme::Background))), 0); mpLayeredDevice->Resize(); SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (mrModel.GetPageCount()>0 && pWindow) { - bool bRearrangeSuccess (false); - if (meOrientation == HORIZONTAL) - { - bRearrangeSuccess = mpLayouter->RearrangeHorizontal ( - pWindow->GetSizePixel(), - mrModel.GetPageDescriptor(0)->GetPage()->GetSize(), - mrModel.GetPageCount()); - } - else - { - bRearrangeSuccess = mpLayouter->RearrangeVertical ( + const bool bRearrangeSuccess ( + mpLayouter->Rearrange ( + meOrientation, pWindow->GetSizePixel(), mrModel.GetPageDescriptor(0)->GetPage()->GetSize(), - mrModel.GetPageCount()); - } + mrModel.GetPageCount())); if (bRearrangeSuccess) { @@ -554,6 +380,75 @@ void SlideSorterView::Resize (void) +void SlideSorterView::UpdateOrientation (void) +{ + // The layout of slides depends on whether the slide sorter is + // displayed in the center or the side pane. + if (mrSlideSorter.GetViewShell()->IsMainViewShell()) + SetOrientation(Layouter::GRID); + else + { + // Get access to the docking window. + ::Window* pWindow = mrSlideSorter.GetContentWindow().get(); + PaneDockingWindow* pDockingWindow = NULL; + while (pWindow!=NULL && pDockingWindow==NULL) + { + pDockingWindow = dynamic_cast(pWindow); + pWindow = pWindow->GetParent(); + } + + if (pDockingWindow != NULL) + { + const long nScrollBarSize ( + Application::GetSettings().GetStyleSettings().GetScrollBarSize()); + switch (pDockingWindow->GetOrientation()) + { + case PaneDockingWindow::HorizontalOrientation: + if (SetOrientation(Layouter::HORIZONTAL)) + { + const Range aRange (mpLayouter->GetValidVerticalSizeRange()); + pDockingWindow->SetValidSizeRange(Range( + aRange.Min() + nScrollBarSize, + aRange.Max() + nScrollBarSize)); + } + break; + + case PaneDockingWindow::VerticalOrientation: + if (SetOrientation(Layouter::VERTICAL)) + { + const Range aRange (mpLayouter->GetValidHorizontalSizeRange()); + pDockingWindow->SetValidSizeRange(Range( + aRange.Min() + nScrollBarSize, + aRange.Max() + nScrollBarSize)); + } + break; + + case PaneDockingWindow::UnknownOrientation: + if (SetOrientation(Layouter::GRID)) + { + const sal_Int32 nAdditionalSize (10); + pDockingWindow->SetMinOutputSizePixel(Size( + mpLayouter->GetValidHorizontalSizeRange().Min() + + nScrollBarSize + + nAdditionalSize, + mpLayouter->GetValidVerticalSizeRange().Min() + + nScrollBarSize + + nAdditionalSize)); + } + return; + } + } + else + { + OSL_ASSERT(pDockingWindow!=NULL); + SetOrientation(Layouter::GRID); + } + } +} + + + + void SlideSorterView::Layout () { SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); @@ -561,7 +456,7 @@ void SlideSorterView::Layout () { // Set the model area, i.e. the smallest rectangle that includes all // page objects. - const Rectangle aViewBox (mpLayouter->GetPageBox(mrModel.GetPageCount())); + const Rectangle aViewBox (mpLayouter->GetTotalBoundingBox()); pWindow->SetViewOrigin (aViewBox.TopLeft()); pWindow->SetViewSize (aViewBox.GetSize()); @@ -679,16 +574,21 @@ void SlideSorterView::UpdatePreciousFlags (void) -void SlideSorterView::SetOrientation (const Orientation eOrientation) +bool SlideSorterView::SetOrientation (const Layouter::Orientation eOrientation) { - meOrientation = eOrientation; - RequestRepaint(); + if (meOrientation != eOrientation) + { + meOrientation = eOrientation; + return true; + } + else + return false; } -SlideSorterView::Orientation SlideSorterView::GetOrientation (void) const +Layouter::Orientation SlideSorterView::GetOrientation (void) const { return meOrientation; } @@ -747,7 +647,7 @@ void SlideSorterView::RequestRepaint (const Region& rRepaintRegion) Rectangle SlideSorterView::GetModelArea (void) { - return mpLayouter->GetPageBox(mrModel.GetPageCount()); + return mpLayouter->GetTotalBoundingBox(); } @@ -917,7 +817,7 @@ void SlideSorterView::SetIsMouseOverIndicationAllowed (const bool bIsAllowed) void SlideSorterView::UpdatePageUnderMouse (bool bAnimate) { SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - if (pWindow) + if (pWindow && ! pWindow->IsMouseCaptured()) { const Window::PointerState aPointerState (pWindow->GetPointerState()); UpdatePageUnderMouse ( diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 156ebaac8b7d..cc43787972a8 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -33,69 +33,301 @@ #include "view/SlsLayouter.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" - #include "Window.hxx" +#include #include +namespace { + sal_Int32 RoundToInt (const double nValue) + { + return sal_Int32(::rtl::math::round(nValue)); + } +} + namespace sd { namespace slidesorter { namespace view { -Layouter::Layouter (const SharedSdWindow& rpWindow) - : mpWindow(rpWindow), - mnRequestedLeftBorder(5), - mnRequestedRightBorder(5), - mnRequestedTopBorder(5), - mnRequestedBottomBorder(5), - mnLeftBorder(5), - mnRightBorder(5), - mnTopBorder(5), - mnBottomBorder(5), - mnVerticalGap (10), - mnHorizontalGap(10), - mnMinimalWidth(100), - mnPreferredWidth(200), - mnMaximalWidth(300), - mnMinimalColumnCount(1), - mnMaximalColumnCount(4), - mnPageCount(0), - mnColumnCount(1), - mnRowCount(0), - mnMaxColumnCount(0), - mnMaxRowCount(0), - maPageObjectSize(1,1), - mbIsVertical(true) +class Layouter::Implementation { -} +public: + SharedSdWindow mpWindow; + sal_Int32 mnRequestedLeftBorder; + sal_Int32 mnRequestedRightBorder; + sal_Int32 mnRequestedTopBorder; + sal_Int32 mnRequestedBottomBorder; + sal_Int32 mnLeftBorder; + sal_Int32 mnRightBorder; + sal_Int32 mnTopBorder; + sal_Int32 mnBottomBorder; + sal_Int32 mnVerticalGap; + sal_Int32 mnHorizontalGap; + Size maMinimalSize; + Size maPreferredSize; + Size maMaximalSize; + sal_Int32 mnMinimalColumnCount; + sal_Int32 mnMaximalColumnCount; + sal_Int32 mnPageCount; + sal_Int32 mnColumnCount; + sal_Int32 mnRowCount; + /// The maximum number of columns. Can only be larger than the current + /// number of columns when there are not enough pages to fill all + /// available columns. + sal_Int32 mnMaxColumnCount; + /// The maximum number of rows. Can only be larger than the current + /// number of rows when there are not enough pages to fill all available + /// rows. + sal_Int32 mnMaxRowCount; + Size maPageObjectSize; + + ::boost::shared_ptr mpPageObjectLayouter; + + enum GapMembership { + GM_NONE, + GM_PREVIOUS, + GM_BOTH, + GM_NEXT, + GM_PAGE_BORDER + }; + + static Implementation* Create ( + const Implementation& rImplementation, + const Layouter::Orientation eOrientation); + + virtual Layouter::Orientation GetOrientation (void) const = 0; + + bool Rearrange ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const sal_uInt32 nPageCount); + + /** Calculate the row that the point with the given vertical coordinate + is over. The horizontal component is ignored. + @param nYPosition + Vertical position in model coordinates. + @param bIncludeBordersAndGaps + When this flag is then the area of borders and gaps are + interpreted as belonging to one of the rows. + @param eGapMembership + Specifies to what row the gap areas belong. Here GM_NONE + corresponds to bIncludeBordersAndGaps being . When + GM_BOTH is given then the upper half is associated to the row + above and the lower half to the row below. Values of + GM_PREVIOUS and GM_NEXT associate the whole gap area with the + row above or below respectively. + */ + sal_Int32 GetRowAtPosition ( + sal_Int32 nYPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership = GM_NONE) const; + + /** Calculate the column that the point with the given horizontal + coordinate is over. The verical component is ignored. + @param nXPosition + Horizontal position in model coordinates. + @param bIncludeBordersAndGaps + When this flag is then the area of borders and gaps are + interpreted as belonging to one of the columns. + @param eGapMembership + Specifies to what column the gap areas belong. Here GM_NONE + corresponds to bIncludeBordersAndGaps being . When + GM_BOTH is given then the left half is associated with the + column at the left and the right half with the column to the + right. Values of GM_PREVIOUS and GM_NEXT associate the whole + gap area with the column to the left or right respectively. + */ + sal_Int32 GetColumnAtPosition ( + sal_Int32 nXPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership = GM_NONE) const; + + /** This method is typically called from GetRowAtPosition() and + GetColumnAtPosition() to handle a position that lies inside the gap + between two adjacent rows or columns. + @param nDistanceIntoGap + Vertical distance from the bottom of the upper row down into the + gap or or horizontal distance from the right edge right into the + gap. + @param eGapMemberhship + This value decides what areas in the gap belong to which (or no) + row or column. + @param nIndex + The row index of the upper row or the column index of the left + column. + @param nGap + Width or height of the gap in model coordiantes between the + page borders. + @return + Returns either the index of the upper row (as given as nRow), the + index of the lower row (nRow+1) or -1 to indicate that the + position belongs to no row. + */ + sal_Int32 ResolvePositionInGap ( + sal_Int32 nDistanceIntoGap, + GapMembership eGapMembership, + sal_Int32 nIndex, + sal_Int32 nGap) const; + + /** Calculate the logical part of the insert position, i.e. the page + after whicht to insert. + */ + virtual void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const = 0; + + /** Calculate the geometrical part of the insert position, i.e. the + location of where to display the insertion indicator and the + distances about which the leading and trailing pages have to be + moved to make room for the indicator. + */ + void CalculateGeometricPosition ( + InsertPosition& rPosition, + const Size& rIndicatorSize, + const bool bIsVertical, + model::SlideSorterModel& rModel) const; + + /** Return the bounding box of the preview or, when selected, of the page + object. Thus, it returns something like a visual bounding box. + */ + Rectangle GetInnerBoundingBox ( + model::SlideSorterModel& rModel, + const sal_Int32 nIndex) const; + + Range GetValidHorizontalSizeRange (void) const; + Range GetValidVerticalSizeRange (void) const; + + Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const bool bCalculateWidth, + const bool bCalculateHeight) const; + + Rectangle GetPageObjectBox ( + const sal_Int32 nIndex, + const bool bIncludeBorderAndGap = false) const; + + Rectangle GetPageObjectBox ( + const sal_Int32 nRow, + const sal_Int32 nColumn) const; + + Rectangle AddBorderAndGap ( + const Rectangle& rBoundingBox, + const sal_Int32 nRow, + const sal_Int32 nColumn) const; + + Rectangle GetTotalBoundingBox (void) const; + + virtual ~Implementation (void); +protected: + Implementation (const SharedSdWindow& rpWindow); + Implementation (const Implementation& rImplementation); + + virtual void CalculateRowAndColumnCount (const Size& rWindowSize) = 0; + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) = 0; + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const = 0; + void CalculateVerticalLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; +}; + + +/** The vertical layouter has one column and as many rows as there are + pages. +*/ +class VerticalImplementation : public Layouter::Implementation +{ +public: + VerticalImplementation (const SharedSdWindow& rpWindow); + VerticalImplementation (const Implementation& rImplementation); + virtual Layouter::Orientation GetOrientation (void) const; + void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; +protected: + virtual void CalculateRowAndColumnCount (const Size& rWindowSize); + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const; +}; -Layouter::~Layouter (void) + +/** The horizontal layouter has one row and as many columns as there are + pages. +*/ +class HorizontalImplementation : public Layouter::Implementation +{ +public: + HorizontalImplementation (const SharedSdWindow& rpWindow); + HorizontalImplementation (const Implementation& rImplementation); + + virtual Layouter::Orientation GetOrientation (void) const; + + void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; + +protected: + virtual void CalculateRowAndColumnCount (const Size& rWindowSize); + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const; +}; + + +/** The number of columns of the grid layouter is defined via a control in + the slide sorter tool bar. The number of rows is calculated from the + number of columns and the number of pages. +*/ +class GridImplementation : public Layouter::Implementation +{ +public: + GridImplementation (const SharedSdWindow& rpWindow); + GridImplementation (const Implementation& rImplementation); + + virtual Layouter::Orientation GetOrientation (void) const; + + void CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const; + +protected: + virtual void CalculateRowAndColumnCount (const Size& rWindowSize); + virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize); + virtual Size CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const; +}; + + + + +//===== Layouter ============================================================== + +Layouter::Layouter (const SharedSdWindow& rpWindow) + : mpImplementation(new GridImplementation(rpWindow)), + mpWindow(rpWindow) { } -::boost::shared_ptr Layouter::GetPageObjectLayouter (void) const +Layouter::~Layouter (void) { - return mpPageObjectLayouter; } -void Layouter::SetObjectWidth ( - sal_Int32 nMinimalWidth, - sal_Int32 nMaximalWidth, - sal_Int32 nPreferredWidth) +::boost::shared_ptr Layouter::GetPageObjectLayouter (void) const { - if (nMinimalWidth <= nPreferredWidth && nPreferredWidth <= nMaximalWidth) - { - mnMinimalWidth = nMinimalWidth; - mnPreferredWidth = nMaximalWidth; - mnMaximalWidth = nPreferredWidth; - } + return mpImplementation->mpPageObjectLayouter; } @@ -108,13 +340,13 @@ void Layouter::SetBorders ( sal_Int32 nBottomBorder) { if (nLeftBorder >= 0) - mnRequestedLeftBorder = nLeftBorder; + mpImplementation->mnRequestedLeftBorder = nLeftBorder; if (nRightBorder >= 0) - mnRequestedRightBorder = nRightBorder; + mpImplementation->mnRequestedRightBorder = nRightBorder; if (nTopBorder >= 0) - mnRequestedTopBorder = nTopBorder; + mpImplementation->mnRequestedTopBorder = nTopBorder; if (nBottomBorder >= 0) - mnRequestedBottomBorder = nBottomBorder; + mpImplementation->mnRequestedBottomBorder = nBottomBorder; } @@ -125,9 +357,9 @@ void Layouter::SetGaps ( sal_Int32 nVerticalGap) { if (nHorizontalGap >= 0) - mnHorizontalGap = nHorizontalGap; + mpImplementation->mnHorizontalGap = nHorizontalGap; if (nVerticalGap >= 0) - mnVerticalGap = nVerticalGap; + mpImplementation->mnVerticalGap = nVerticalGap; } @@ -140,193 +372,46 @@ void Layouter::SetColumnCount ( { if (nMinimalColumnCount <= nMaximalColumnCount) { - mnMinimalColumnCount = nMinimalColumnCount; - mnMaximalColumnCount = nMaximalColumnCount; + mpImplementation->mnMinimalColumnCount = nMinimalColumnCount; + mpImplementation->mnMaximalColumnCount = nMaximalColumnCount; } } -bool Layouter::RearrangeHorizontal ( +bool Layouter::Rearrange ( + const Orientation eOrientation, const Size& rWindowSize, const Size& rPageSize, const sal_uInt32 nPageCount) { OSL_ASSERT(mpWindow); - mbIsVertical = false; - mnPageCount = nPageCount; - - if (rWindowSize.Width() > 0 - && rWindowSize.Height() > 0 - && rPageSize.Width() > 0 - && rPageSize.Height() > 0) - { - // Calculate the column count. - mnColumnCount = nPageCount; - mnRowCount = 1; - - // Update the border values. - mnLeftBorder = mnRequestedLeftBorder; - mnTopBorder = mnRequestedTopBorder; - mnRightBorder = mnRequestedRightBorder; - mnBottomBorder = mnRequestedBottomBorder; - if (mnColumnCount > 1) - { - int nMinimumBorderWidth = mnHorizontalGap/2; - if (mnLeftBorder < nMinimumBorderWidth) - mnLeftBorder = nMinimumBorderWidth; - if (mnRightBorder < nMinimumBorderWidth) - mnRightBorder = nMinimumBorderWidth; - } - else - { - int nMinimumBorderHeight = mnVerticalGap/2; - if (mnTopBorder < nMinimumBorderHeight) - mnTopBorder = nMinimumBorderHeight; - if (mnBottomBorder < nMinimumBorderHeight) - mnBottomBorder = nMinimumBorderHeight; - } - - // Calculate the width of each page object. - sal_uInt32 nTargetHeight = 0; - sal_uInt32 nRowCount = 1; - if (mnColumnCount > 0) - nTargetHeight = (rWindowSize.Height() - - mnTopBorder - - mnBottomBorder - - (nRowCount-1) * mnVerticalGap - ) - / nRowCount; - sal_uInt32 nMinimalHeight (mnMinimalWidth * rPageSize.Height() / rPageSize.Width()); - sal_uInt32 nMaximalHeight (mnMaximalWidth * rPageSize.Height() / rPageSize.Width()); - if (nTargetHeight < nMinimalHeight) - nTargetHeight = nMinimalHeight; - if (nTargetHeight > nMaximalHeight) - nTargetHeight = nMaximalHeight; - - // Setup the page object layouter and ask it for the page object size. - mpPageObjectLayouter.reset( - new PageObjectLayouter( - Size(0, nTargetHeight), - rPageSize, - mpWindow, - nPageCount)); - maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); - - mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) - / (maPageObjectSize.Width() + mnHorizontalGap); - mnMaxRowCount = 1; - - return true; - } - else - return false; -} - - - - -bool Layouter::RearrangeVertical ( - const Size& rWindowSize, - const Size& rPreviewModelSize, - const sal_uInt32 nPageCount) -{ - OSL_ASSERT(mpWindow); - - mbIsVertical = true; - mnPageCount = nPageCount; - - if (rWindowSize.Width() > 0 - && rWindowSize.Height() > 0 - && rPreviewModelSize.Width() > 0 - && rPreviewModelSize.Height() > 0) - { - // Calculate the column count. - mnColumnCount = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder) - / (mnPreferredWidth + mnHorizontalGap); - if (mnColumnCount < mnMinimalColumnCount) - mnColumnCount = mnMinimalColumnCount; - if (mnColumnCount > mnMaximalColumnCount) - mnColumnCount = mnMaximalColumnCount; - mnRowCount = (nPageCount + mnColumnCount-1)/mnColumnCount; - - // Update the border values. - mnLeftBorder = mnRequestedLeftBorder; - mnTopBorder = mnRequestedTopBorder; - mnRightBorder = mnRequestedRightBorder; - mnBottomBorder = mnRequestedBottomBorder; - if (mnColumnCount > 1) - { - int nMinimumBorderWidth = mnHorizontalGap/2; - if (mnLeftBorder < nMinimumBorderWidth) - mnLeftBorder = nMinimumBorderWidth; - if (mnRightBorder < nMinimumBorderWidth) - mnRightBorder = nMinimumBorderWidth; - } - else - { - int nMinimumBorderHeight = mnVerticalGap/2; - if (mnTopBorder < nMinimumBorderHeight) - mnTopBorder = nMinimumBorderHeight; - if (mnBottomBorder < nMinimumBorderHeight) - mnBottomBorder = nMinimumBorderHeight; - } + if (eOrientation != mpImplementation->GetOrientation()) + mpImplementation.reset(Implementation::Create(*mpImplementation, eOrientation)); - // Calculate the width of each page object. - sal_Int32 nTargetWidth = 0; - if (mnColumnCount > 0) - nTargetWidth = (rWindowSize.Width() - - mnLeftBorder - - mnRightBorder - - (mnColumnCount-1) * mnHorizontalGap - ) - / mnColumnCount; - if (nTargetWidth < mnMinimalWidth) - nTargetWidth = mnMinimalWidth; - if (nTargetWidth > mnMaximalWidth) - nTargetWidth = mnMaximalWidth; - - // Setup the page object layouter and ask it for the page object size. - mpPageObjectLayouter.reset( - new PageObjectLayouter( - Size(nTargetWidth, 0), - rPreviewModelSize, - mpWindow, - nPageCount)); - maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); - - mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) - / (maPageObjectSize.Width() + mnHorizontalGap); - mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) - / (maPageObjectSize.Height() + mnVerticalGap); - - return true; - } - else - return false; + return mpImplementation->Rearrange(rWindowSize, rPageSize, nPageCount); } -void Layouter::SetZoom (double nZoomFactor) +void Layouter::_SetZoom (double nZoomFactor) { - SetZoom(Fraction(nZoomFactor)); + _SetZoom(Fraction(nZoomFactor)); } -void Layouter::SetZoom (Fraction nZoomFactor) +void Layouter::_SetZoom (Fraction nZoomFactor) { OSL_ASSERT(mpWindow); MapMode aMapMode (mpWindow->GetMapMode()); aMapMode.SetScaleX (nZoomFactor); aMapMode.SetScaleY (nZoomFactor); - // maPageObjectPixelSize = mpWindow->LogicToPixel (maPageObjectModelSize); mpWindow->SetMapMode (aMapMode); } @@ -335,7 +420,7 @@ void Layouter::SetZoom (Fraction nZoomFactor) sal_Int32 Layouter::GetColumnCount (void) const { - return mnColumnCount; + return mpImplementation->mnColumnCount; } @@ -343,7 +428,7 @@ sal_Int32 Layouter::GetColumnCount (void) const sal_Int32 Layouter::GetRowCount (void) const { - return mnRowCount; + return mpImplementation->mnRowCount; } @@ -351,7 +436,7 @@ sal_Int32 Layouter::GetRowCount (void) const sal_Int32 Layouter::GetRow (const sal_Int32 nIndex) const { - return nIndex / mnColumnCount; + return nIndex / mpImplementation->mnColumnCount; } @@ -359,7 +444,7 @@ sal_Int32 Layouter::GetRow (const sal_Int32 nIndex) const sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const { - return nIndex % mnColumnCount; + return nIndex % mpImplementation->mnColumnCount; } @@ -367,9 +452,9 @@ sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const { - const sal_Int32 nIndex (nRow * mnColumnCount + nColumn); + const sal_Int32 nIndex (nRow * mpImplementation->mnColumnCount + nColumn); OSL_ASSERT(nIndex>=0); - return ::std::min(nIndex, mnPageCount-1); + return ::std::min(nIndex, mpImplementation->mnPageCount-1); } @@ -377,7 +462,7 @@ sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) con bool Layouter::IsColumnCountFixed (void) const { - return mnMinimalColumnCount == mnMaximalColumnCount; + return mpImplementation->mnMinimalColumnCount == mpImplementation->mnMaximalColumnCount; } @@ -385,7 +470,7 @@ bool Layouter::IsColumnCountFixed (void) const Size Layouter::GetPageObjectSize (void) const { - return maPageObjectSize; + return mpImplementation->maPageObjectSize; } @@ -395,70 +480,15 @@ Rectangle Layouter::GetPageObjectBox ( const sal_Int32 nIndex, const bool bIncludeBorderAndGap) const { - const sal_Int32 nRow (GetRow(nIndex)); - const sal_Int32 nColumn (GetColumn(nIndex)); - Rectangle aBoundingBox( - Point (mnLeftBorder - + nColumn * maPageObjectSize.Width() - + (nColumn>0 ? nColumn : 0) * mnHorizontalGap, - mnTopBorder - + nRow * maPageObjectSize.Height() - + (nRow>0 ? nRow : 0) * mnVerticalGap), - maPageObjectSize); - if (bIncludeBorderAndGap) - { - if (nColumn == 0) - aBoundingBox.Left() = 0; - else - aBoundingBox.Left() -= mnHorizontalGap/2; - if (nColumn == mnColumnCount-1) - aBoundingBox.Right() += mnRightBorder; - else - aBoundingBox.Right() += mnHorizontalGap/2; - if (nRow == 0) - aBoundingBox.Top() = 0; - else - aBoundingBox.Top() -= mnVerticalGap/2; - if (nRow == mnRowCount-1) - aBoundingBox.Bottom() += mnBottomBorder; - else - aBoundingBox.Bottom() += mnVerticalGap/2; - } - return aBoundingBox; + return mpImplementation->GetPageObjectBox(nIndex, bIncludeBorderAndGap); } -Rectangle Layouter::GetPageBox (const sal_Int32 nObjectCount) const +Rectangle Layouter::GetTotalBoundingBox (void) const { - sal_Int32 nCount (nObjectCount); - if (nCount < 0) - nCount = mnPageCount; - - sal_Int32 nHorizontalSize = 0; - sal_Int32 nVerticalSize = 0; - if (mnColumnCount > 0) - { - sal_Int32 nRowCount = (nCount+mnColumnCount-1) / mnColumnCount; - nHorizontalSize = - mnLeftBorder - + mnRightBorder - + mnColumnCount * maPageObjectSize.Width(); - if (mnColumnCount > 1) - nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap; - nVerticalSize = - mnTopBorder - + mnBottomBorder - + nRowCount * maPageObjectSize.Height(); - if (nRowCount > 1) - nVerticalSize += (nRowCount-1) * mnVerticalGap; - } - - return Rectangle ( - Point(0,0), - Size (nHorizontalSize, nVerticalSize) - ); + return mpImplementation->GetTotalBoundingBox(); } @@ -470,194 +500,31 @@ InsertPosition Layouter::GetInsertPosition ( model::SlideSorterModel& rModel) const { InsertPosition aPosition; - CalculateLogicalInsertPosition(rModelPosition, aPosition); - CalculateGeometricPosition(aPosition, rIndicatorSize, GetColumnCount()==1, rModel); + mpImplementation->CalculateLogicalInsertPosition( + rModelPosition, + aPosition); + mpImplementation->CalculateGeometricPosition( + aPosition, + rIndicatorSize, + GetColumnCount()==1, + rModel); return aPosition; } -void Layouter::CalculateLogicalInsertPosition ( - const Point& rModelPosition, - InsertPosition& rPosition) const -{ - // Determine logical position. - if (mnColumnCount == 1) - { - const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; - const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); - rPosition.mnRow = ::std::min(mnPageCount, nY / nRowHeight); - rPosition.mnColumn = 0; - rPosition.mnIndex = rPosition.mnRow; - rPosition.mbIsAtRunStart = (rPosition.mnRow == 0); - rPosition.mbIsAtRunEnd = (rPosition.mnRow == mnRowCount); - rPosition.mbIsExtraSpaceNeeded = (rPosition.mnRow >= mnMaxRowCount); - } - else - { - rPosition.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); - rPosition.mnColumn = ::std::min(mnColumnCount, nX / nRowWidth); - rPosition.mnIndex = rPosition.mnRow * mnColumnCount + rPosition.mnColumn; - - rPosition.mbIsAtRunStart = (rPosition.mnColumn == 0); - rPosition.mbIsAtRunEnd = (rPosition.mnColumn == mnColumnCount); - - if (rPosition.mnIndex >= mnPageCount) - { - rPosition.mnIndex = mnPageCount; - rPosition.mnRow = mnRowCount-1; - rPosition.mnColumn = mnPageCount%mnColumnCount; - rPosition.mbIsAtRunEnd = true; - } - rPosition.mbIsExtraSpaceNeeded = (rPosition.mnColumn >= mnMaxColumnCount); - } -} - - - - -void Layouter::CalculateGeometricPosition ( - InsertPosition& rPosition, - const Size& rIndicatorSize, - const bool bIsVertical, - model::SlideSorterModel& rModel) const +Range Layouter::GetValidHorizontalSizeRange (void) const { - // 1. Determine right/bottom of the leading page and the left/top of the - // trailing page object and how to distribute the missing space. - sal_Int32 nLeadingLocation (0); - sal_Int32 nTrailingLocation (0); - bool bIsLeadingFixed (false); - bool bIsTrailingFixed (false); - sal_Int32 nSecondaryLocation (0); - - if (rPosition.mbIsAtRunStart) - { - // Place indicator at the top of the column. - const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex)); - const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex)); - if (bIsVertical) - { - nLeadingLocation = aOuterBox.Top(); - nTrailingLocation = aInnerBox.Top(); - nSecondaryLocation = aInnerBox.Center().X(); - } - else - { - nLeadingLocation = aOuterBox.Left(); - nTrailingLocation = aInnerBox.Left(); - nSecondaryLocation = aInnerBox.Center().Y(); - } - bIsLeadingFixed = true; - } - else if (rPosition.mbIsAtRunEnd) - { - // Place indicator at the bottom/right of the column/row. - - const Rectangle aOuterBox (GetPageObjectBox(rPosition.mnIndex-1)); - const Rectangle aInnerBox (GetInnerBoundingBox(rModel, rPosition.mnIndex-1)); - if (bIsVertical) - { - nLeadingLocation = aInnerBox.Bottom(); - nTrailingLocation = aOuterBox.Bottom(); - nSecondaryLocation = aInnerBox.Center().X(); - } - else - { - nLeadingLocation = aInnerBox.Right(); - nTrailingLocation = aOuterBox.Right(); - nSecondaryLocation = aInnerBox.Center().Y(); - } - bIsTrailingFixed = true; - if ( ! rPosition.mbIsExtraSpaceNeeded) - bIsLeadingFixed = true; - } - else - { - // Place indicator between two rows/columns. - const Rectangle aBox1 (GetInnerBoundingBox(rModel, rPosition.mnIndex-1)); - const Rectangle aBox2 (GetInnerBoundingBox(rModel, rPosition.mnIndex)); - if (bIsVertical) - { - nLeadingLocation = aBox1.Bottom(); - nTrailingLocation = aBox2.Top(); - nSecondaryLocation = (aBox1.Center().X() + aBox2.Center().X()) / 2; - } - else - { - nLeadingLocation = aBox1.Right(); - nTrailingLocation = aBox2.Left(); - nSecondaryLocation = (aBox1.Center().Y() + aBox2.Center().Y()) / 2; - } - } - - // 2. Calculate the location of the insert indicator and the offsets of - // leading and trailing pages. - const sal_Int32 nAvailableSpace (nTrailingLocation - nLeadingLocation); - const sal_Int32 nRequiredSpace (bIsVertical ? rIndicatorSize.Height():rIndicatorSize.Width()); - const sal_Int32 nMissingSpace (::std::max(sal_Int32(0), nRequiredSpace - nAvailableSpace)); - sal_Int32 nPrimaryLocation (0); - sal_Int32 nLeadingOffset (0); - sal_Int32 nTrailingOffset (0); - if (bIsLeadingFixed) - { - nPrimaryLocation = nLeadingLocation + nRequiredSpace/2; - if ( ! bIsTrailingFixed) - nTrailingOffset = nMissingSpace; - } - else if (bIsTrailingFixed) - { - nPrimaryLocation = nTrailingLocation - nRequiredSpace/2; - nLeadingOffset = -nMissingSpace; - } - else - { - nPrimaryLocation = (nLeadingLocation + nTrailingLocation) /2; - nLeadingOffset = -nMissingSpace/2; - nTrailingOffset = nMissingSpace + nLeadingOffset; - } - - if (bIsVertical) - { - rPosition.maLocation = Point(nSecondaryLocation, nPrimaryLocation); - rPosition.maLeadingOffset = Point(0, nLeadingOffset); - rPosition.maTrailingOffset = Point(0, nTrailingOffset); - } - else - { - rPosition.maLocation = Point(nPrimaryLocation, nSecondaryLocation); - rPosition.maLeadingOffset = Point(nLeadingOffset, 0); - rPosition.maTrailingOffset = Point(nTrailingOffset, 0); - } + return mpImplementation->GetValidHorizontalSizeRange(); } -Rectangle Layouter::GetInnerBoundingBox ( - model::SlideSorterModel& rModel, - const sal_Int32 nIndex) const +Range Layouter::GetValidVerticalSizeRange (void) const { - model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); - if ( ! pDescriptor) - return Rectangle(); - - const Point aLocation (pDescriptor->GetLocation(true)); - if (pDescriptor->HasState(model::PageDescriptor::ST_Selected)) - return GetPageObjectLayouter()->GetBoundingBox( - aLocation, - PageObjectLayouter::PageObject, - PageObjectLayouter::ModelCoordinateSystem); - else - return GetPageObjectLayouter()->GetBoundingBox( - aLocation, - PageObjectLayouter::Preview, - PageObjectLayouter::ModelCoordinateSystem); + return mpImplementation->GetValidVerticalSizeRange(); } @@ -665,12 +532,17 @@ Rectangle Layouter::GetInnerBoundingBox ( Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const { - sal_Int32 nRow0 = GetRowAtPosition (aVisibleArea.Top(), true, GM_BOTH); - sal_Int32 nRow1 = GetRowAtPosition (aVisibleArea.Bottom(), - true, GM_BOTH); + const sal_Int32 nRow0 (mpImplementation->GetRowAtPosition ( + aVisibleArea.Top(), + true, + Implementation::GM_BOTH)); + const sal_Int32 nRow1 (mpImplementation->GetRowAtPosition ( + aVisibleArea.Bottom(), + true, + Implementation::GM_BOTH)); return Range( - ::std::min(nRow0 * mnColumnCount, mnPageCount-1), - ::std::min((nRow1+1) * mnColumnCount - 1, mnPageCount-1)); + ::std::min(nRow0*mpImplementation->mnColumnCount, mpImplementation->mnPageCount-1), + ::std::min((nRow1+1)*mpImplementation->mnColumnCount-1, mpImplementation->mnPageCount-1)); } @@ -680,15 +552,19 @@ sal_Int32 Layouter::GetIndexAtPoint ( const Point& rPosition, const bool bIncludePageBorders) const { - sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), - bIncludePageBorders, - bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE); - sal_Int32 nColumn = GetColumnAtPosition (rPosition.X(), - bIncludePageBorders, - bIncludePageBorders ? GM_PAGE_BORDER : GM_NONE); + const sal_Int32 nRow ( + mpImplementation->GetRowAtPosition ( + rPosition.Y(), + bIncludePageBorders, + bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE)); + const sal_Int32 nColumn ( + mpImplementation->GetColumnAtPosition ( + rPosition.X(), + bIncludePageBorders, + bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE)); if (nRow >= 0 && nColumn >= 0) - return nRow * mnColumnCount + nColumn; + return nRow * mpImplementation->mnColumnCount + nColumn; else return -1; } @@ -696,20 +572,147 @@ sal_Int32 Layouter::GetIndexAtPoint ( -bool Layouter::IsVertical (void) const +//===== Layouter::Implementation ============================================== + +Layouter::Implementation* Layouter::Implementation::Create ( + const Implementation& rImplementation, + const Layouter::Orientation eOrientation) { - return mbIsVertical; + switch (eOrientation) + { + case HORIZONTAL: return new HorizontalImplementation(rImplementation); + case VERTICAL: return new VerticalImplementation(rImplementation); + case GRID: + default: return new GridImplementation(rImplementation); + } } -sal_Int32 Layouter::GetRowAtPosition ( - sal_Int32 nYPosition, - bool bIncludeBordersAndGaps, - GapMembership eGapMembership) const -{ - sal_Int32 nRow = -1; +Layouter::Implementation::Implementation (const SharedSdWindow& rpWindow) + : mpWindow(rpWindow), + mnRequestedLeftBorder(5), + mnRequestedRightBorder(5), + mnRequestedTopBorder(5), + mnRequestedBottomBorder(5), + mnLeftBorder(5), + mnRightBorder(5), + mnTopBorder(5), + mnBottomBorder(5), + mnVerticalGap (10), + mnHorizontalGap(10), + maMinimalSize(100,75), + maPreferredSize(200,150), + maMaximalSize(300,200), + mnMinimalColumnCount(1), + mnMaximalColumnCount(15), + mnPageCount(0), + mnColumnCount(1), + mnRowCount(0), + mnMaxColumnCount(0), + mnMaxRowCount(0), + maPageObjectSize(1,1) +{ +} + + + + +Layouter::Implementation::Implementation (const Implementation& rImplementation) + : mpWindow(rImplementation.mpWindow), + mnRequestedLeftBorder(rImplementation.mnRequestedLeftBorder), + mnRequestedRightBorder(rImplementation.mnRequestedRightBorder), + mnRequestedTopBorder(rImplementation.mnRequestedTopBorder), + mnRequestedBottomBorder(rImplementation.mnRequestedBottomBorder), + mnLeftBorder(rImplementation.mnLeftBorder), + mnRightBorder(rImplementation.mnRightBorder), + mnTopBorder(rImplementation.mnTopBorder), + mnBottomBorder(rImplementation.mnBottomBorder), + mnVerticalGap(rImplementation.mnVerticalGap), + mnHorizontalGap(rImplementation.mnHorizontalGap), + maMinimalSize(rImplementation.maMinimalSize), + maPreferredSize(rImplementation.maPreferredSize), + maMaximalSize(rImplementation.maMaximalSize), + mnMinimalColumnCount(rImplementation.mnMinimalColumnCount), + mnMaximalColumnCount(rImplementation.mnMaximalColumnCount), + mnPageCount(rImplementation.mnPageCount), + mnColumnCount(rImplementation.mnColumnCount), + mnRowCount(rImplementation.mnRowCount), + mnMaxColumnCount(rImplementation.mnMaxColumnCount), + mnMaxRowCount(rImplementation.mnMaxRowCount), + maPageObjectSize(rImplementation.maPageObjectSize) +{ +} + + + + +Layouter::Implementation::~Implementation (void) +{ +} + + + + +bool Layouter::Implementation::Rearrange ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const sal_uInt32 nPageCount) +{ + mnPageCount = nPageCount; + + if (rWindowSize.Width()<=0 || rWindowSize.Height()<=0) + return false; + if (rPreviewModelSize.Width()<=0 || rPreviewModelSize.Height()<=0) + return false; + + CalculateRowAndColumnCount(rWindowSize); + + // Update the border values. + mnLeftBorder = mnRequestedLeftBorder; + mnTopBorder = mnRequestedTopBorder; + mnRightBorder = mnRequestedRightBorder; + mnBottomBorder = mnRequestedBottomBorder; + if (mnColumnCount > 1) + { + int nMinimumBorderWidth = mnHorizontalGap/2; + if (mnLeftBorder < nMinimumBorderWidth) + mnLeftBorder = nMinimumBorderWidth; + if (mnRightBorder < nMinimumBorderWidth) + mnRightBorder = nMinimumBorderWidth; + } + else + { + int nMinimumBorderHeight = mnVerticalGap/2; + if (mnTopBorder < nMinimumBorderHeight) + mnTopBorder = nMinimumBorderHeight; + if (mnBottomBorder < nMinimumBorderHeight) + mnBottomBorder = nMinimumBorderHeight; + } + + mpPageObjectLayouter.reset( + new PageObjectLayouter( + CalculateTargetSize(rWindowSize, rPreviewModelSize), + rPreviewModelSize, + mpWindow, + mnPageCount)); + maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize(); + + CalculateMaxRowAndColumnCount(rWindowSize); + + return true; +} + + + + +sal_Int32 Layouter::Implementation::GetRowAtPosition ( + sal_Int32 nYPosition, + bool bIncludeBordersAndGaps, + GapMembership eGapMembership) const +{ + sal_Int32 nRow = -1; const sal_Int32 nY = nYPosition - mnTopBorder; if (nY >= 0) @@ -743,7 +746,7 @@ sal_Int32 Layouter::GetRowAtPosition ( -sal_Int32 Layouter::GetColumnAtPosition ( +sal_Int32 Layouter::Implementation::GetColumnAtPosition ( sal_Int32 nXPosition, bool bIncludeBordersAndGaps, GapMembership eGapMembership) const @@ -786,7 +789,7 @@ sal_Int32 Layouter::GetColumnAtPosition ( -sal_Int32 Layouter::ResolvePositionInGap ( +sal_Int32 Layouter::Implementation::ResolvePositionInGap ( sal_Int32 nDistanceIntoGap, GapMembership eGapMembership, sal_Int32 nIndex, @@ -843,18 +846,597 @@ sal_Int32 Layouter::ResolvePositionInGap ( +void Layouter::Implementation::CalculateGeometricPosition ( + InsertPosition& rPosition, + const Size& rIndicatorSize, + const bool bIsVertical, + model::SlideSorterModel& rModel) const +{ + // 1. Determine right/bottom of the leading page and the left/top of the + // trailing page object and how to distribute the missing space. + sal_Int32 nLeadingLocation (0); + sal_Int32 nTrailingLocation (0); + bool bIsLeadingFixed (false); + bool bIsTrailingFixed (false); + sal_Int32 nSecondaryLocation (0); + const sal_Int32 nIndex (rPosition.GetIndex()); + + if (rPosition.IsAtRunStart()) + { + // Place indicator at the top of the column. + const Rectangle aOuterBox (GetPageObjectBox(nIndex)); + const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex)); + if (bIsVertical) + { + nLeadingLocation = aOuterBox.Top(); + nTrailingLocation = aInnerBox.Top(); + nSecondaryLocation = aInnerBox.Center().X(); + } + else + { + nLeadingLocation = aOuterBox.Left(); + nTrailingLocation = aInnerBox.Left(); + nSecondaryLocation = aInnerBox.Center().Y(); + } + bIsLeadingFixed = true; + } + else if (rPosition.IsAtRunEnd()) + { + // Place indicator at the bottom/right of the column/row. + + const Rectangle aOuterBox (GetPageObjectBox(nIndex-1)); + const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex-1)); + if (bIsVertical) + { + nLeadingLocation = aInnerBox.Bottom(); + nTrailingLocation = aOuterBox.Bottom(); + nSecondaryLocation = aInnerBox.Center().X(); + } + else + { + nLeadingLocation = aInnerBox.Right(); + nTrailingLocation = aOuterBox.Right(); + nSecondaryLocation = aInnerBox.Center().Y(); + } + bIsTrailingFixed = true; + if ( ! rPosition.IsExtraSpaceNeeded()) + bIsLeadingFixed = true; + } + else + { + // Place indicator between two rows/columns. + const Rectangle aBox1 (GetInnerBoundingBox(rModel, nIndex-1)); + const Rectangle aBox2 (GetInnerBoundingBox(rModel, nIndex)); + if (bIsVertical) + { + nLeadingLocation = aBox1.Bottom(); + nTrailingLocation = aBox2.Top(); + nSecondaryLocation = (aBox1.Center().X() + aBox2.Center().X()) / 2; + } + else + { + nLeadingLocation = aBox1.Right(); + nTrailingLocation = aBox2.Left(); + nSecondaryLocation = (aBox1.Center().Y() + aBox2.Center().Y()) / 2; + } + } + + // 2. Calculate the location of the insert indicator and the offsets of + // leading and trailing pages. + const sal_Int32 nAvailableSpace (nTrailingLocation - nLeadingLocation); + const sal_Int32 nRequiredSpace (bIsVertical ? rIndicatorSize.Height():rIndicatorSize.Width()); + const sal_Int32 nMissingSpace (::std::max(sal_Int32(0), nRequiredSpace - nAvailableSpace)); + sal_Int32 nPrimaryLocation (0); + sal_Int32 nLeadingOffset (0); + sal_Int32 nTrailingOffset (0); + if (bIsLeadingFixed) + { + nPrimaryLocation = nLeadingLocation + nRequiredSpace/2; + if ( ! bIsTrailingFixed) + nTrailingOffset = nMissingSpace; + } + else if (bIsTrailingFixed) + { + nPrimaryLocation = nTrailingLocation - nRequiredSpace/2; + nLeadingOffset = -nMissingSpace; + } + else + { + nPrimaryLocation = (nLeadingLocation + nTrailingLocation) /2; + nLeadingOffset = -nMissingSpace/2; + nTrailingOffset = nMissingSpace + nLeadingOffset; + } + + if (bIsVertical) + { + rPosition.SetGeometricalPosition( + Point(nSecondaryLocation, nPrimaryLocation), + Point(0, nLeadingOffset), + Point(0, nTrailingOffset)); + } + else + { + rPosition.SetGeometricalPosition( + Point(nPrimaryLocation, nSecondaryLocation), + Point(nLeadingOffset, 0), + Point(nTrailingOffset, 0)); + } +} + + + + +Rectangle Layouter::Implementation::GetInnerBoundingBox ( + model::SlideSorterModel& rModel, + const sal_Int32 nIndex) const +{ + model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); + if ( ! pDescriptor) + return Rectangle(); + + const Point aLocation (pDescriptor->GetLocation(true)); + if (pDescriptor->HasState(model::PageDescriptor::ST_Selected)) + return mpPageObjectLayouter->GetBoundingBox( + aLocation, + PageObjectLayouter::PageObject, + PageObjectLayouter::ModelCoordinateSystem); + else + return mpPageObjectLayouter->GetBoundingBox( + aLocation, + PageObjectLayouter::Preview, + PageObjectLayouter::ModelCoordinateSystem); +} + + + + +Range Layouter::Implementation::GetValidHorizontalSizeRange (void) const +{ + return Range( + mnLeftBorder + maMinimalSize.Width() + mnRightBorder, + mnLeftBorder + maMaximalSize.Width() + mnRightBorder); +} + + + + +Range Layouter::Implementation::GetValidVerticalSizeRange (void) const +{ + return Range( + mnTopBorder + maMinimalSize.Height() + mnBottomBorder, + mnTopBorder + maMaximalSize.Height() + mnBottomBorder); +} + + + + +Size Layouter::Implementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const bool bCalculateWidth, + const bool bCalculateHeight) const +{ + if (mnColumnCount<=0 || mnRowCount<=0) + return maPreferredSize; + if ( ! (bCalculateWidth || bCalculateHeight)) + { + OSL_ASSERT(bCalculateWidth || bCalculateHeight); + return maPreferredSize; + } + + const double nPreviewAspectRatio ( + double(rPreviewModelSize.Width())/double(rPreviewModelSize.Height())); + + // Calculate the width of each page object. + Size aTargetSize (0,0); + if (bCalculateWidth) + aTargetSize.setWidth( + (rWindowSize.Width() - mnLeftBorder - mnRightBorder + - (mnColumnCount-1) * mnHorizontalGap) + / mnColumnCount); + else if (bCalculateHeight) + aTargetSize.setHeight( + (rWindowSize.Height() - mnTopBorder - mnBottomBorder + - (mnRowCount-1) * mnVerticalGap) + / mnRowCount); + + if (bCalculateWidth) + { + if (aTargetSize.Width() < maMinimalSize.Width()) + aTargetSize.setWidth(maMinimalSize.Width()); + else if (aTargetSize.Width() > maMaximalSize.Width()) + aTargetSize.setWidth(maMaximalSize.Width()); + } + else if (bCalculateHeight) + { + if (aTargetSize.Height() < maMinimalSize.Height()) + aTargetSize.setHeight(maMinimalSize.Height()); + else if (aTargetSize.Height() > maMaximalSize.Height()) + aTargetSize.setHeight(maMaximalSize.Height()); + } + + return aTargetSize; +} + + + + +Rectangle Layouter::Implementation::GetPageObjectBox ( + const sal_Int32 nIndex, + const bool bIncludeBorderAndGap) const +{ + const sal_Int32 nRow (nIndex / mnColumnCount); + const sal_Int32 nColumn (nIndex % mnColumnCount); + + const Rectangle aBoundingBox (GetPageObjectBox(nRow,nColumn)); + if (bIncludeBorderAndGap) + return AddBorderAndGap(aBoundingBox, nRow, nColumn); + else + return aBoundingBox; +} + + + + +Rectangle Layouter::Implementation::GetPageObjectBox ( + const sal_Int32 nRow, + const sal_Int32 nColumn) const +{ + return Rectangle( + Point (mnLeftBorder + + nColumn * maPageObjectSize.Width() + + (nColumn>0 ? nColumn : 0) * mnHorizontalGap, + mnTopBorder + + nRow * maPageObjectSize.Height() + + (nRow>0 ? nRow : 0) * mnVerticalGap), + maPageObjectSize); +} + + + + + +Rectangle Layouter::Implementation::AddBorderAndGap ( + const Rectangle& rBoundingBox, + const sal_Int32 nRow, + const sal_Int32 nColumn) const +{ + Rectangle aBoundingBox (rBoundingBox); + + if (nColumn == 0) + aBoundingBox.Left() = 0; + else + aBoundingBox.Left() -= mnHorizontalGap/2; + if (nColumn == mnColumnCount-1) + aBoundingBox.Right() += mnRightBorder; + else + aBoundingBox.Right() += mnHorizontalGap/2; + if (nRow == 0) + aBoundingBox.Top() = 0; + else + aBoundingBox.Top() -= mnVerticalGap/2; + if (nRow == mnRowCount-1) + aBoundingBox.Bottom() += mnBottomBorder; + else + aBoundingBox.Bottom() += mnVerticalGap/2; + return aBoundingBox; +} + + + + +Rectangle Layouter::Implementation::GetTotalBoundingBox (void) const +{ + sal_Int32 nHorizontalSize = 0; + sal_Int32 nVerticalSize = 0; + if (mnColumnCount > 0) + { + sal_Int32 nRowCount = (mnPageCount+mnColumnCount-1) / mnColumnCount; + nHorizontalSize = + mnLeftBorder + + mnRightBorder + + mnColumnCount * maPageObjectSize.Width(); + if (mnColumnCount > 1) + nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap; + nVerticalSize = + mnTopBorder + + mnBottomBorder + + nRowCount * maPageObjectSize.Height(); + if (nRowCount > 1) + nVerticalSize += (nRowCount-1) * mnVerticalGap; + } + + return Rectangle ( + Point(0,0), + Size (nHorizontalSize, nVerticalSize) + ); +} + + + + +void Layouter::Implementation::CalculateVerticalLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const +{ + const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2; + const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap); + const sal_Int32 nRow (::std::min(mnPageCount, nY / nRowHeight)); + rPosition.SetLogicalPosition ( + nRow, + 0, + nRow, + (nRow == 0), + (nRow == mnRowCount), + (nRow >= mnMaxRowCount)); +} + + + + +//===== HorizontalImplementation ================================================ + +HorizontalImplementation::HorizontalImplementation (const SharedSdWindow& rpWindow) + : Implementation(rpWindow) +{ +} + + + + +HorizontalImplementation::HorizontalImplementation (const Implementation& rImplementation) + : Implementation(rImplementation) +{ +} + + + + +Layouter::Orientation HorizontalImplementation::GetOrientation (void) const +{ + return Layouter::HORIZONTAL; +} + + + + +void HorizontalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) +{ + (void)rWindowSize; + + // Row and column count are fixed (for a given page count.) + mnColumnCount = mnPageCount; + mnRowCount = 1; +} + + + + +void HorizontalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) +{ + mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) + / (maPageObjectSize.Width() + mnHorizontalGap); + mnMaxRowCount = 1; +} + + + + +Size HorizontalImplementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const +{ + return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, false, true); +} + + + + +void HorizontalImplementation::CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const +{ + const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; + const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap); + const sal_Int32 nColumn (::std::min(mnPageCount, nX / nColumnWidth)); + rPosition.SetLogicalPosition ( + 0, + nColumn, + nColumn, + (nColumn == 0), + (nColumn == mnColumnCount), + (nColumn >= mnMaxColumnCount)); +} + + + + +//===== VerticalImplementation ================================================ + +VerticalImplementation::VerticalImplementation (const SharedSdWindow& rpWindow) + : Implementation(rpWindow) +{ +} + + + + +VerticalImplementation::VerticalImplementation (const Implementation& rImplementation) + : Implementation(rImplementation) +{ +} + + + + +Layouter::Orientation VerticalImplementation::GetOrientation (void) const +{ + return Layouter::VERTICAL; +} + + + + +void VerticalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) +{ + (void)rWindowSize; + + // Row and column count are fixed (for a given page count.) + mnRowCount = mnPageCount; + mnColumnCount = 1; + +} + + + + +void VerticalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) +{ + mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) + / (maPageObjectSize.Height() + mnVerticalGap); + mnMaxColumnCount = 1; +} + + + + +Size VerticalImplementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const +{ + return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, true, false); +} + + + + +void VerticalImplementation::CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const +{ + return CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition); +} + + + + +//===== GridImplementation ================================================ + +GridImplementation::GridImplementation (const SharedSdWindow& rpWindow) + : Implementation(rpWindow) +{ +} + + + + +GridImplementation::GridImplementation (const Implementation& rImplementation) + : Implementation(rImplementation) +{ +} + + + + +Layouter::Orientation GridImplementation::GetOrientation (void) const +{ + return Layouter::GRID; +} + + + + +void GridImplementation::CalculateRowAndColumnCount (const Size& rWindowSize) +{ + // Calculate the column count. + mnColumnCount + = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder) + / (maPreferredSize.Width() + mnHorizontalGap); + if (mnColumnCount < mnMinimalColumnCount) + mnColumnCount = mnMinimalColumnCount; + if (mnColumnCount > mnMaximalColumnCount) + mnColumnCount = mnMaximalColumnCount; + mnRowCount = (mnPageCount + mnColumnCount-1)/mnColumnCount; +} + + + + +void GridImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize) +{ + mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder) + / (maPageObjectSize.Width() + mnHorizontalGap); + mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder) + / (maPageObjectSize.Height() + mnVerticalGap); +} + + + + + +Size GridImplementation::CalculateTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize) const +{ + return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, true, true); +} + + + + +void GridImplementation::CalculateLogicalInsertPosition ( + const Point& rModelPosition, + InsertPosition& rPosition) const +{ + if (mnColumnCount == 1) + { + CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition); + } + else + { + // Handle the general case of more than one column. + sal_Int32 nRow (::std::min( + mnRowCount-1, + GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH))); + const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2; + const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap); + sal_Int32 nColumn (::std::min(mnColumnCount, nX / nColumnWidth)); + sal_Int32 nIndex (nRow * mnColumnCount + nColumn); + bool bIsAtRunEnd (nColumn == mnColumnCount); + + if (nIndex >= mnPageCount) + { + nIndex = mnPageCount; + nRow = mnRowCount-1; + nColumn = mnPageCount%mnColumnCount; + bIsAtRunEnd = true; + } + + rPosition.SetLogicalPosition ( + nRow, + nColumn, + nIndex, + (nColumn == 0), + bIsAtRunEnd, + (nColumn >= mnMaxColumnCount)); + } +} + + + + //===== InsertPosition ======================================================== InsertPosition::InsertPosition (void) : mnRow(-1), mnColumn(-1), mnIndex(-1), - maLocation(0,0), - maLeadingOffset(0,0), - maTrailingOffset(0,0), mbIsAtRunStart(false), mbIsAtRunEnd(false), - mbIsExtraSpaceNeeded(false) + mbIsExtraSpaceNeeded(false), + maLocation(0,0), + maLeadingOffset(0,0), + maTrailingOffset(0,0) { } @@ -868,12 +1450,12 @@ InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition mnRow = rInsertPosition.mnRow; mnColumn = rInsertPosition.mnColumn; mnIndex = rInsertPosition.mnIndex; - maLocation = rInsertPosition.maLocation; - maLeadingOffset = rInsertPosition.maLeadingOffset; - maTrailingOffset = rInsertPosition.maTrailingOffset; mbIsAtRunStart = rInsertPosition.mbIsAtRunStart; mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd; mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded; + maLocation = rInsertPosition.maLocation; + maLeadingOffset = rInsertPosition.maLeadingOffset; + maTrailingOffset = rInsertPosition.maTrailingOffset; } return *this; } @@ -902,4 +1484,36 @@ bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const + +void InsertPosition::SetLogicalPosition ( + const sal_Int32 nRow, + const sal_Int32 nColumn, + const sal_Int32 nIndex, + const bool bIsAtRunStart, + const bool bIsAtRunEnd, + const bool bIsExtraSpaceNeeded) +{ + mnRow = nRow; + mnColumn = nColumn; + mnIndex = nIndex; + mbIsAtRunStart = bIsAtRunStart; + mbIsAtRunEnd = bIsAtRunEnd; + mbIsExtraSpaceNeeded = bIsExtraSpaceNeeded; +} + + + + +void InsertPosition::SetGeometricalPosition( + const Point aLocation, + const Point aLeadingOffset, + const Point aTrailingOffset) +{ + maLocation = aLocation; + maLeadingOffset = aLeadingOffset; + maTrailingOffset = aTrailingOffset; +} + + + } } } // end of namespace ::sd::slidesorter::namespace diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 19f7bc14b664..ec0b274397b7 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -59,7 +59,6 @@ #include #include #include -#include using namespace ::drawinglayer::primitive2d; using namespace ::basegfx; @@ -209,10 +208,14 @@ void PageObjectPainter::PaintPageObject ( void PageObjectPainter::NotifyResize (void) { - maNormalBackground.SetEmpty(); - maSelectionBackground.SetEmpty(); - maFocusedSelectionBackground.SetEmpty(); - maMouseOverBackground.SetEmpty(); + if ( ! mpPageObjectLayouter + || mpPageObjectLayouter->GetPageObjectSize() != maNewSlideIcon.GetSizePixel()) + { + maNormalBackground.SetEmpty(); + maSelectionBackground.SetEmpty(); + maFocusedSelectionBackground.SetEmpty(); + maMouseOverBackground.SetEmpty(); + } } @@ -270,7 +273,7 @@ void PageObjectPainter::PaintPreview ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const { - Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( + const Rectangle aBox (mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::Preview, PageObjectLayouter::ModelCoordinateSystem)); @@ -278,12 +281,17 @@ void PageObjectPainter::PaintPreview ( if (mpCache != NULL) { const SdrPage* pPage = rpDescriptor->GetPage(); - BitmapEx aBitmap (mpCache->GetPreviewBitmap(pPage)); - if (aBitmap.GetSizePixel() != aBox.GetSize()) - aBitmap.Scale(aBox.GetSize()); mpCache->SetPreciousFlag(pPage, true); - rDevice.DrawBitmapEx(aBox.TopLeft(), aBitmap); + const Bitmap aBitmap (mpCache->GetPreviewBitmap(pPage,false).GetBitmap()); + if (aBitmap.GetSizePixel() != aBox.GetSize()) + { + rDevice.DrawBitmap(aBox.TopLeft(), aBox.GetSize(), aBitmap); + } + else + { + rDevice.DrawBitmap(aBox.TopLeft(), aBitmap); + } } if (rpDescriptor->GetVisualState().GetCurrentVisualState() -- cgit v1.2.3 From f38cf1fdb8e23c4031b198214a29510046c05ecc Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Tue, 23 Mar 2010 12:50:14 +0100 Subject: renaissance1: #i107215# Improved button handling. Added debug design dialog. --- .../controller/SlsSelectionFunction.cxx | 19 +- .../slidesorter/inc/view/SlsPageObjectLayouter.hxx | 17 +- .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 6 +- sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 40 +- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 3 + sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx | 637 +++++++++++++++++++++ sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx | 61 ++ sd/source/ui/slidesorter/shell/makefile.mk | 3 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 4 +- sd/source/ui/slidesorter/view/SlsIcons.hrc | 11 +- sd/source/ui/slidesorter/view/SlsIcons.src | 26 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 19 +- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 27 +- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 71 ++- sd/source/ui/slidesorter/view/SlsTheme.cxx | 264 +++++---- 15 files changed, 1035 insertions(+), 173 deletions(-) create mode 100644 sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx create mode 100644 sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 9ddfbf481b7e..79a64cc37404 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -1325,10 +1325,23 @@ SelectionFunction::EventDescriptor::EventDescriptor ( { mpHitPage = mpHitDescriptor->GetPage(); - mnButtonIndex - = rSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt( + if (mpHitDescriptor->HasState(model::PageDescriptor::ST_Excluded)) + { + if (rSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox( mpHitDescriptor, - maMouseModelPosition); + view::PageObjectLayouter::WideButton, + view::PageObjectLayouter::ModelCoordinateSystem).IsInside(maMouseModelPosition)) + { + mnButtonIndex = view::PageObjectLayouter::ShowHideButtonIndex; + } + } + else + { + mnButtonIndex + = rSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt( + mpHitDescriptor, + maMouseModelPosition); + } } } diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx index 99ceee121b42..09243029e2a4 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx @@ -80,7 +80,9 @@ public: // Indicator whether or not there is a slide transition associated // with this slide. TransitionEffectIndicator, - ButtonArea, + // Wide button placed without border at the bottom of the preview. + WideButton, + // Individual button. Specify nIndex when calling GetBoundingBox(). Button }; /** Two coordinate systems are supported. They differ only in @@ -91,7 +93,16 @@ public: */ enum CoordinateSystem { WindowCoordinateSystem, - ModelCoordinateSystem}; + ModelCoordinateSystem + }; + + enum ButtonIndex { + MinButtonIndex = 0, + StartShowButtonIndex = MinButtonIndex, + ShowHideButtonIndex = 1, + DuplicateButtonIndex = 2, + MaxButtonIndex = DuplicateButtonIndex + }; /** Return the bounding box of the page object or one of its graphical parts. @@ -148,7 +159,7 @@ private: Rectangle maPageNumberFrameBoundingBox; Rectangle maPreviewBoundingBox; Rectangle maTransitionEffectBoundingBox; - Rectangle maButtonAreaBoundingBox; + Rectangle maWideButtonBoundingBox; const Image maTransitionEffectIcon; const ::boost::shared_ptr mpPageNumberFont; diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index c67777418fc2..e02c68e7967a 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -60,7 +60,7 @@ public: OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor); - void NotifyResize (void); + void NotifyResize (const bool bForce = false); /** Called when the theme changes, either because it is replaced with another or because the system colors have changed. So, even when @@ -84,6 +84,7 @@ private: Bitmap maSelectionBackground; Bitmap maFocusedSelectionBackground; Bitmap maMouseOverBackground; + ::rtl::OUString msUnhideString; void PaintBackground ( OutputDevice& rDevice, @@ -100,6 +101,9 @@ private: void PaintButtons ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const; + void PaintWideButton ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; void PrepareBackgrounds (OutputDevice& rDevice); void PaintBorder ( OutputDevice& rDevice, diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index 5b7241aaadc2..ba0a8a56bb3d 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -67,18 +67,18 @@ public: enum FontType { PageNumberFont, - PageCountFont + PageCountFont, + ButtonFont }; static ::boost::shared_ptr GetFont ( const FontType eType, const OutputDevice& rDevice); - static ColorData GetColorForVisualState (const model::VisualState::State eState); - enum ColorType { Background, PageBackground, ButtonBackground, + ButtonText, MouseOverColor, PageNumberBorder, PageNumberColor, @@ -86,6 +86,7 @@ public: PreviewBorder }; ColorData GetColor (const ColorType eType); + void SetColor (const ColorType eType, const ColorData aColorData); enum GradientColorType { NormalPage, @@ -97,11 +98,22 @@ public: Border1, Border2, Fill1, - Fill2 + Fill2, + Base }; ColorData GetGradientColor ( const GradientColorType eType, const GradientColorClass eClass); + sal_Int32 GetGradientOffset ( + const GradientColorType eType, + const GradientColorClass eClass); + void SetGradient ( + const GradientColorType eType, + const ColorData aBaseColor, + const sal_Int32 nFillStartOffset, + const sal_Int32 nFillEndOffset, + const sal_Int32 nBorderStartOffset, + const sal_Int32 nBorderEndOffset); enum IconType { @@ -111,14 +123,29 @@ public: }; BitmapEx GetIcon (const IconType eType); + enum IntegerValueType + { + ButtonCornerRadius, + ButtonMaxAlpha + }; + sal_Int32 GetIntegerValue (const IntegerValueType eType) const; + void SetIntegerValue (const IntegerValueType eType, const sal_Int32 nValue); + private: class GradientDescriptor { public: + ColorData maBaseColor; + ColorData maFillColor1; ColorData maFillColor2; ColorData maBorderColor1; ColorData maBorderColor2; + + sal_Int32 mnFillOffset1; + sal_Int32 mnFillOffset2; + sal_Int32 mnBorderOffset1; + sal_Int32 mnBorderOffset2; }; ColorData maBackgroundColor; ColorData maPageBackgroundColor; @@ -129,6 +156,11 @@ private: BitmapEx maRawShadow; BitmapEx maRawInsertShadow; BitmapEx maHideSlideOverlay; + ::std::vector maColor; + sal_Int32 mnButtonCornerRadius; + sal_Int32 mnButtonMaxAlpha; + + GradientDescriptor& GetGradient (const GradientColorType eType); }; diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx index d3fb4857ae64..13f1a0ce816e 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorter.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -34,6 +34,7 @@ #include "SlideSorterChildWindow.hrc" #include "SlideSorterViewShell.hxx" +#include "SlsDebugDialog.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsProperties.hxx" @@ -219,6 +220,8 @@ void SlideSorter::Init (void) mbIsValid = true; } + + SlideSorterDebugDialog::ShowDebugDialog(*this); } diff --git a/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx new file mode 100644 index 000000000000..09b1cf60d265 --- /dev/null +++ b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx @@ -0,0 +1,637 @@ +/************************************************************************* + * + * 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: SlideSorterService.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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. + * + ************************************************************************/ + +#ifdef DEBUG + +#include "SlsDebugDialog.hxx" +#include "view/SlideSorterView.hxx" +#include "view/SlsTheme.hxx" +#include "view/SlsPageObjectPainter.hxx" + +#include +#include +#include +#include +#include +#include +#include + +namespace css = ::com::sun::star; +using namespace ::sd::slidesorter::view; + +namespace sd { namespace slidesorter { + +//===== TextButton ============================================================ + +class TextButton : public PushButton +{ +public: + typedef ::boost::function Action; + + TextButton ( + ::Window* pParent, + const char* pText, + const Action& rAction) + : PushButton(pParent), + maAction(rAction) + { + SetText(::rtl::OUString::createFromAscii(pText)); + Show(); + } + + virtual void Click (void) + { + if (maAction) + maAction(this); + } + +private: + Action maAction; +}; + + + + +//===== ColorControl ========================================================== + +class ColorControl +{ +public: + typedef ::boost::function ColorGetter; + typedef ::boost::function ColorSetter; + typedef ::boost::function Updater; + ColorControl ( + ::Window* pParent, + const char* pTitle, + const Rectangle& rBoundingBox, + const ColorGetter& rGetter, + const ColorSetter& rSetter, + const Updater& rUpdater) + : maGetter(rGetter), + maSetter(rSetter), + maUpdater(rUpdater), + mpContainer(new ::Window(pParent, WB_BORDER)), + mpTitle(new FixedText(mpContainer)), + mpRedSlider(new Slider(mpContainer)), + mpGreenSlider(new Slider(mpContainer)), + mpBlueSlider(new Slider(mpContainer)), + mpTextValue(new FixedText(mpContainer)), + mpColorValue(new ::Window(mpContainer)) + { + const double nWidth (rBoundingBox.GetWidth()); + const double nLeft (0); + const double nTop (0); + const ColorData aStartColor (rGetter ? rGetter() : 0); + + mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); + mpContainer->Show(); + + mpTitle->SetText(::rtl::OUString::createFromAscii(pTitle)); + mpTitle->SetPosSizePixel(nLeft, nTop, nWidth,20); + mpTitle->Show(); + + mpRedSlider->SetPosSizePixel(nLeft, nTop+30, nWidth, 10); + mpRedSlider->SetRange(Range(0,255)); + mpRedSlider->Show(); + + mpGreenSlider->SetPosSizePixel(nLeft, nTop+40, nWidth, 10); + mpGreenSlider->SetRange(Range(0,255)); + mpGreenSlider->Show(); + + mpBlueSlider->SetPosSizePixel(nLeft, nTop+50, nWidth, 10); + mpBlueSlider->SetRange(Range(0,255)); + mpBlueSlider->Show(); + + SetColor(aStartColor); + + mpRedSlider->SetSlideHdl(LINK(this, ColorControl, UpdateColor)); + mpGreenSlider->SetSlideHdl(LINK(this, ColorControl, UpdateColor)); + mpBlueSlider->SetSlideHdl(LINK(this, ColorControl, UpdateColor)); + + mpTextValue->SetText(::rtl::OUString::createFromAscii("x000000")); + mpTextValue->SetPosSizePixel(nLeft, nTop+70, 150, 20); + mpTextValue->Show(); + + mpColorValue->SetPosSizePixel(nLeft + 150, nTop+70, nWidth - 160, 20); + mpColorValue->SetBackground(Wallpaper(Color(aStartColor))); + mpColorValue->Show(); + + UpdateDisplay(); + } + + void SetColor (const ColorData aColorData) + { + const Color aColor (aColorData); + mpRedSlider->SetThumbPos(aColor.GetRed()); + mpGreenSlider->SetThumbPos(aColor.GetGreen()); + mpBlueSlider->SetThumbPos(aColor.GetBlue()); + UpdateDisplay(); + } + + + ColorData GetColor (void) const + { + return Color( + mpRedSlider->GetThumbPos(), + mpGreenSlider->GetThumbPos(), + mpBlueSlider->GetThumbPos()).GetColor(); + } + + DECL_LINK(UpdateColor, void*); + +private: + ColorGetter maGetter; + ColorSetter maSetter; + Updater maUpdater; + ::Window* mpContainer; + FixedText* mpTitle; + Slider* mpRedSlider; + Slider* mpGreenSlider; + Slider* mpBlueSlider; + FixedText* mpTextValue; + ::Window* mpColorValue; + + Color UpdateDisplay (void) + { + const int nRed (mpRedSlider->GetThumbPos()); + const int nGreen (mpGreenSlider->GetThumbPos()); + const int nBlue (mpBlueSlider->GetThumbPos()); + + Color aColor (nRed, nGreen, nBlue); + mpColorValue->SetBackground(Wallpaper(aColor)); + mpColorValue->Invalidate(); + + const int nMaxLength(10); + char aBuffer[nMaxLength]; + snprintf(aBuffer, nMaxLength, "x%02x%02x%02x", nRed,nGreen,nBlue); + mpTextValue->SetText(::rtl::OUString::createFromAscii(aBuffer)); + + return aColor; + } + +}; + +IMPL_LINK(ColorControl, UpdateColor, void*, EMPTYARG) +{ + const Color aColor (UpdateDisplay()); + if (maSetter) + { + maSetter(aColor.GetColor()); + if (maUpdater) + maUpdater(); + } + + return 0; +} + + + + +//===== GradientControl ======================================================= + +class GradientControl +{ +public: + typedef ::boost::function Updater; + + GradientControl ( + ::Window* pParent, + const char* pTitle, + const Theme::GradientColorType eType, + const Rectangle& rBoundingBox, + SlideSorter& rSlideSorter) + : mpTheme(rSlideSorter.GetTheme()), + mrSlideSorter(rSlideSorter), + meType(eType), + mpContainer(new ::Window(pParent, WB_BORDER)), + mpColorControl(new ColorControl(mpContainer, "Base Color", + Rectangle(0,0, rBoundingBox.GetWidth()-4, 90), + ::boost::bind(&Theme::GetGradientColor, mpTheme, + ::boost::bind(&GradientControl::GetType, this), Theme::Base), + ::boost::bind(&GradientControl::SetBaseColor, this, _1), + ::boost::bind(&GradientControl::Update, this, (void*)0))), + mpFillOffset1Slider(new Slider(mpContainer)), + mpFillOffset1Text(new FixedText(mpContainer)), + mpFillOffset1Color(new ::Window(mpContainer)), + mpFillOffset2Slider(new Slider(mpContainer)), + mpFillOffset2Text(new FixedText(mpContainer)), + mpFillOffset2Color(new ::Window(mpContainer)), + mpBorderOffset1Slider(new Slider(mpContainer)), + mpBorderOffset1Text(new FixedText(mpContainer)), + mpBorderOffset1Color(new ::Window(mpContainer)), + mpBorderOffset2Slider(new Slider(mpContainer)), + mpBorderOffset2Text(new FixedText(mpContainer)), + mpBorderOffset2Color(new ::Window(mpContainer)) + { + const double nWidth (rBoundingBox.GetWidth()); + ::boost::shared_ptr pTheme (mrSlideSorter.GetTheme()); + const ColorData aStartColor (pTheme->GetGradientColor(eType, Theme::Base)); + + mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); + mpContainer->Show(); + + Initialize(mpFillOffset1Slider, mpFillOffset1Text, mpFillOffset1Color, + mpTheme->GetGradientOffset(eType, Theme::Fill1), 100, nWidth); + Initialize(mpFillOffset2Slider, mpFillOffset2Text, mpFillOffset2Color, + mpTheme->GetGradientOffset(eType, Theme::Fill2), 120, nWidth); + Initialize(mpBorderOffset1Slider, mpBorderOffset1Text, mpBorderOffset1Color, + mpTheme->GetGradientOffset(eType, Theme::Border1), 140, nWidth); + Initialize(mpBorderOffset2Slider, mpBorderOffset2Text, mpBorderOffset2Color, + mpTheme->GetGradientOffset(eType, Theme::Border2), 160, nWidth); + + Update(0); + } + + void Initialize ( + Slider* pSlider, + FixedText* pText, + ::Window* pWindow, + const sal_Int32 nOffset, + const sal_Int32 nY, + const sal_Int32 nWidth) + { + pSlider->SetPosSizePixel(10,nY,nWidth/2,15); + pSlider->Show(); + pSlider->SetRange(Range(-100,+100)); + pSlider->SetThumbPos(nOffset); + pSlider->SetSlideHdl(LINK(this, GradientControl, Update)); + + pText->SetPosSizePixel(nWidth/2+10, nY, nWidth/2-60, 15); + pText->Show(); + + pWindow->SetPosSizePixel(nWidth-40, nY, 40, 15); + pWindow->Show(); + } + + void SetBaseColor (const ColorData aColor) + { + mpColorControl->SetColor(aColor); + } + + ::Window* GetContainer (void) + { + return mpContainer; + } + + Theme::GradientColorType GetType (void) const + { + return meType; + } + + void SetType (const Theme::GradientColorType eType) + { + meType = eType; + mpColorControl->SetColor(mpTheme->GetGradientColor(meType, Theme::Base)); + mpFillOffset1Slider->SetThumbPos(mpTheme->GetGradientOffset(meType, Theme::Fill1)); + mpFillOffset2Slider->SetThumbPos(mpTheme->GetGradientOffset(meType, Theme::Fill2)); + mpBorderOffset1Slider->SetThumbPos(mpTheme->GetGradientOffset(meType, Theme::Border1)); + mpBorderOffset2Slider->SetThumbPos(mpTheme->GetGradientOffset(meType, Theme::Border2)); + UpdateDisplay(); + } + +private: + ::boost::shared_ptr mpTheme; + SlideSorter& mrSlideSorter; + Theme::GradientColorType meType; + ::Window* mpContainer; + ColorControl* mpColorControl; + Slider* mpFillOffset1Slider; + FixedText* mpFillOffset1Text; + ::Window* mpFillOffset1Color; + sal_Int32 mnFillOffset1; + Slider* mpFillOffset2Slider; + FixedText* mpFillOffset2Text; + ::Window* mpFillOffset2Color; + sal_Int32 mnFillOffset2; + Slider* mpBorderOffset1Slider; + FixedText* mpBorderOffset1Text; + ::Window* mpBorderOffset1Color; + sal_Int32 mnBorderOffset1; + Slider* mpBorderOffset2Slider; + FixedText* mpBorderOffset2Text; + ::Window* mpBorderOffset2Color; + sal_Int32 mnBorderOffset2; + + DECL_LINK(Update, void*); + + void UpdateDisplay (void) + { + const sal_Int32 nFillOffset1 (mpFillOffset1Slider->GetThumbPos()); + const sal_Int32 nFillOffset2 (mpFillOffset2Slider->GetThumbPos()); + const sal_Int32 nBorderOffset1 (mpBorderOffset1Slider->GetThumbPos()); + const sal_Int32 nBorderOffset2 (mpBorderOffset2Slider->GetThumbPos()); + + mpFillOffset1Text->SetText(::rtl::OUString::valueOf(nFillOffset1)); + mpFillOffset1Color->SetBackground(Wallpaper( + mpTheme->GetGradientColor(meType, Theme::Fill1))); + mpFillOffset1Color->Invalidate(); + + mpFillOffset2Text->SetText(::rtl::OUString::valueOf(nFillOffset2)); + mpFillOffset2Color->SetBackground(Wallpaper( + mpTheme->GetGradientColor(meType, Theme::Fill2))); + mpFillOffset2Color->Invalidate(); + + mpBorderOffset1Text->SetText(::rtl::OUString::valueOf(nBorderOffset1)); + mpBorderOffset1Color->SetBackground(Wallpaper( + mpTheme->GetGradientColor(meType, Theme::Border1))); + mpBorderOffset1Color->Invalidate(); + + mpBorderOffset2Text->SetText(::rtl::OUString::valueOf(nBorderOffset2)); + mpBorderOffset2Color->SetBackground(Wallpaper( + mpTheme->GetGradientColor(meType, Theme::Border2))); + mpBorderOffset2Color->Invalidate(); + + mrSlideSorter.GetView().GetPageObjectPainter()->NotifyResize(true); + mrSlideSorter.GetView().RequestRepaint(); + } +}; + + +IMPL_LINK(GradientControl, Update, void*, EMPTYARG) +{ + UpdateDisplay(); + + + mpTheme->SetGradient(meType, + mpColorControl->GetColor(), + mpFillOffset1Slider->GetThumbPos(), + mpFillOffset2Slider->GetThumbPos(), + mpBorderOffset1Slider->GetThumbPos(), + mpBorderOffset2Slider->GetThumbPos()); + + return 0; +} + + + + +//===== SliderControl ========================================================= + +class SliderControl +{ +public: + typedef ::boost::function ValueGetter; + typedef ::boost::function ValueSetter; + typedef ::boost::function Updater; + SliderControl ( + ::Window* pParent, + const char* pTitle, + const Rectangle& rBoundingBox, + const Range aRange, + const ValueGetter& rGetter, + const ValueSetter& rSetter, + const Updater& rUpdater) + : maGetter(rGetter), + maSetter(rSetter), + maUpdater(rUpdater), + mpContainer(new ::Window(pParent, WB_BORDER)), + mpTitle(new FixedText(mpContainer)), + mpSlider(new Slider(mpContainer)), + mpTextValue(new FixedText(mpContainer)) + { + const double nWidth (rBoundingBox.GetWidth()); + const double nLeft (0); + const double nTop (0); + const sal_Int32 nStartValue (maGetter ? maGetter() : 0); + + mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); + mpContainer->Show(); + + mpTitle->SetText(::rtl::OUString::createFromAscii(pTitle)); + mpTitle->SetPosSizePixel(nLeft, nTop, nWidth,20); + mpTitle->Show(); + + mpSlider->SetPosSizePixel(nLeft, nTop+30, nWidth, 10); + mpSlider->SetRange(aRange); + mpSlider->SetSlideHdl(LINK(this, SliderControl, UpdateValue)); + mpSlider->SetThumbPos(nStartValue); + mpSlider->Show(); + + mpTextValue->SetText(::rtl::OUString::valueOf(nStartValue)); + mpTextValue->SetPosSizePixel(nLeft, nTop+50, 150, 20); + mpTextValue->Show(); + + UpdateValue(0); + } + +private: + ValueGetter maGetter; + ValueSetter maSetter; + Updater maUpdater; + ::Window* mpContainer; + FixedText* mpTitle; + Slider* mpSlider; + FixedText* mpTextValue; + + DECL_LINK(UpdateValue, void*); +}; + +IMPL_LINK(SliderControl, UpdateValue, void*, EMPTYARG) +{ + const sal_Int32 nValue (mpSlider->GetThumbPos()); + + const sal_Int32 nMaxLength (30); + char aBuffer[nMaxLength]; + snprintf(aBuffer, nMaxLength, "%d %f", nValue, nValue/255.0); + mpTextValue->SetText(::rtl::OUString::createFromAscii(aBuffer)); + + if (maSetter) + { + maSetter(nValue); + if (maUpdater) + maUpdater(); + } + + return 0; +} + + + + +//===== ChoiceControl ========================================================= + +class ChoiceControl +{ +public: + typedef ::boost::function ValueGetter; + typedef ::boost::function ValueSetter; + ChoiceControl ( + ::Window* pParent, + const char* pTitle, + const Rectangle& rBoundingBox, + const char** aValues, + const int nValueCount, + GradientControl* pSubControl, + const ValueGetter& rGetter, + const ValueSetter& rSetter) + : maValues(), + maGetter(rGetter), + maSetter(rSetter), + mpContainer(new ::Window(pParent, WB_BORDER)), + mpComboBox(new ComboBox(mpContainer, WB_DROPDOWN)), + mpSubControl(pSubControl) + { + const double nWidth (rBoundingBox.GetWidth()); + const double nLeft (0); + const double nTop (0); + const sal_Int32 nStartValue (maGetter ? maGetter() : 0); + + mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); + mpContainer->Show(); + + mpComboBox->SetPosSizePixel(nLeft, nTop, nWidth-5, 20); + mpComboBox->ToggleDropDown(); + mpComboBox->SetSelectHdl(LINK(this, ChoiceControl, UpdateValue)); + mpComboBox->SetDoubleClickHdl(LINK(this, ChoiceControl, UpdateValue)); + for (int nIndex=0; nIndexInsertEntry(::rtl::OUString::createFromAscii(aValues[nIndex]))); + maValues[nId] = nIndex; + } + mpComboBox->Show(); + + mpSubControl->GetContainer()->SetParent(mpContainer); + mpSubControl->GetContainer()->SetPosSizePixel( + nLeft, nTop+20, nWidth, rBoundingBox.GetHeight()-20); + + UpdateValue(0); + } + +private: + ::std::map maValues; + ValueGetter maGetter; + ValueSetter maSetter; + ::Window* mpContainer; + ComboBox* mpComboBox; + GradientControl* mpSubControl; + + DECL_LINK(UpdateValue, void*); +}; + +IMPL_LINK(ChoiceControl, UpdateValue, void*, EMPTYARG) +{ + USHORT nId (mpComboBox->GetSelectEntryPos()); + const sal_Int32 nIndex (maValues[nId]); + const Theme::GradientColorType nValue ((Theme::GradientColorType)nIndex); + + if (maSetter) + maSetter(nValue); + + return 0; +} + + + + +//===== SlideSorterDebugDialog ================================================ + +void SlideSorterDebugDialog::ShowDebugDialog (SlideSorter& rSlideSorter) +{ + static const char* pText = getenv("SD_SHOW_DEBUG_DIALOG"); + if (pText!=NULL && pText[0]!='0') + { + new SlideSorterDebugDialog(rSlideSorter); + } +} + + + + +SlideSorterDebugDialog::SlideSorterDebugDialog (SlideSorter& rSlideSorter) + : mpTopLevelWindow(new WorkWindow(NULL, WB_STDWORK)) +{ + mpTopLevelWindow->SetSizePixel(Size(300,510)); + + { + Button* pButton = new TextButton( + mpTopLevelWindow, + "Close", + ::boost::bind(&WorkWindow::Close, mpTopLevelWindow)); + pButton->SetPosSizePixel(195,480,100,25); + + } + + ::boost::shared_ptr pTheme(rSlideSorter.GetTheme()); + { + ColorControl* pControl = new ColorControl( + mpTopLevelWindow, + "Unhide Button Background", + Rectangle(10,10,290,110), + ::boost::bind(&view::Theme::GetColor, pTheme, view::Theme::ButtonBackground), + ::boost::bind(&view::Theme::SetColor, pTheme, view::Theme::ButtonBackground, _1), + ::boost::bind(&view::SlideSorterView::RequestRepaint, + ::boost::ref(rSlideSorter.GetView()))); + } + + { + SliderControl* pControl = new SliderControl( + mpTopLevelWindow, + "Max Button Alpha", + Rectangle(10,120,290,200), + Range(0,255), + ::boost::bind(&view::Theme::GetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha), + ::boost::bind(&view::Theme::SetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha, _1), + ::boost::bind(&view::SlideSorterView::RequestRepaint, + ::boost::ref(rSlideSorter.GetView()))); + } + + { + GradientControl* pControl = new GradientControl( + mpTopLevelWindow, + "Selection Page Gradient", + Theme::SelectedPage, + Rectangle(10,210,285,450), + rSlideSorter); + const char* aValues[] = { + "Normal", + "Selected", + "SelectedAndFocused", + "MouseOver" + }; + ChoiceControl* pChoiceControl = new ChoiceControl( + mpTopLevelWindow, + "Gradient", + Rectangle(10,210,290,470), + aValues, + 4, + pControl, + ::boost::bind(&GradientControl::GetType, pControl), + ::boost::bind(&GradientControl::SetType, pControl, _1)); + } + + mpTopLevelWindow->Show(true); +} + + +} } // end of namespace ::sd::slidesorter + +#endif diff --git a/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx b/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx new file mode 100644 index 000000000000..c2f2f8a6b6b2 --- /dev/null +++ b/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * 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: SlideSorterService.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_DEBUG_DIALOG_HXX +#define SD_DEBUG_DIALOG_HXX + +#ifdef DEBUG + +#include + +class WorkWindow; + +namespace sd { namespace slidesorter { + +class SlideSorter; + +class SlideSorterDebugDialog + : public ::boost::noncopyable +{ +public: + static void ShowDebugDialog (SlideSorter& rSlideSorter); + +private: + WorkWindow* mpTopLevelWindow; + + SlideSorterDebugDialog (SlideSorter& rSlideSorter); +}; + + +} } // end of namespace ::sd::slidesorter + +#endif +#endif diff --git a/sd/source/ui/slidesorter/shell/makefile.mk b/sd/source/ui/slidesorter/shell/makefile.mk index 95e159985b01..a36df664664a 100644 --- a/sd/source/ui/slidesorter/shell/makefile.mk +++ b/sd/source/ui/slidesorter/shell/makefile.mk @@ -49,7 +49,8 @@ PRJINC=..$/.. SLOFILES = \ $(SLO)$/SlideSorter.obj \ $(SLO)$/SlideSorterService.obj \ - $(SLO)$/SlideSorterViewShell.obj + $(SLO)$/SlideSorterViewShell.obj \ + $(SLO)$/SlsDebugDialog.obj EXCEPTIONSFILES= diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index e6d17c8a6e02..407e9a81fc06 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -970,7 +970,9 @@ bool SlideSorterView::SetState ( // Fade in or out the buttons. if (eState == PageDescriptor::ST_MouseOver) { - const double nEndAlpha (bStateValue ? 0.2 : 1.0); + const double nEndAlpha (bStateValue + ? mrSlideSorter.GetTheme()->GetIntegerValue(Theme::ButtonMaxAlpha)/255.0 + : 1.0); if (bAnimate) { const double nStartAlpha (pDescriptor->GetVisualState().GetButtonAlpha()); diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hrc b/sd/source/ui/slidesorter/view/SlsIcons.hrc index 240321d77475..22b4b398955c 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.hrc +++ b/sd/source/ui/slidesorter/view/SlsIcons.hrc @@ -35,15 +35,14 @@ #define IMG_ICONS RID_SLIDESORTER_ICONS -#define IMAGE_INSERTION_INDICATOR_NORMAL 1 -#define IMAGE_INSERTION_INDICATOR_MASK 2 -#define IMAGE_INSERTION_INDICATOR_SELECT 3 -#define IMAGE_PRESENTATION 4 -#define IMAGE_SHOW_SLIDE 5 -#define IMAGE_NEW_SLIDE 6 +#define IMAGE_PRESENTATION 1 +#define IMAGE_SHOW_SLIDE 2 +#define IMAGE_NEW_SLIDE 3 #define IMAGE_SHADOW 10 #define IMAGE_INSERT_SHADOW 11 #define IMAGE_HIDE_SLIDE_OVERLAY 12 +#define STRING_UNHIDE 13 + #endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.src b/sd/source/ui/slidesorter/view/SlsIcons.src index d8a5ffadc3ef..4bee98eb0559 100644 --- a/sd/source/ui/slidesorter/view/SlsIcons.src +++ b/sd/source/ui/slidesorter/view/SlsIcons.src @@ -32,34 +32,19 @@ Resource IMG_ICONS { - Image IMAGE_INSERTION_INDICATOR_NORMAL - { - ImageBitmap = Bitmap { File = "moving_50.png" ; }; - }; - - Image IMAGE_INSERTION_INDICATOR_MASK - { - ImageBitmap = Bitmap { File = "moving_50_mask.png" ; }; - }; - - Image IMAGE_INSERTION_INDICATOR_SELECT - { - ImageBitmap = Bitmap { File = "moving_50_select.png" ; }; - }; - Image IMAGE_PRESENTATION { - ImageBitmap = Bitmap { File = "commandimagelist/lc_presentation.png" ; }; + ImageBitmap = Bitmap { File = "slide_sorter_command1.png" ; }; }; Image IMAGE_SHOW_SLIDE { - ImageBitmap = Bitmap { File = "commandimagelist/lc_showslide.png" ; }; + ImageBitmap = Bitmap { File = "slide_sorter_command2.png" ; }; }; Image IMAGE_NEW_SLIDE { - ImageBitmap = Bitmap { File = "commandimagelist/lc_insertpage.png" ; }; + ImageBitmap = Bitmap { File = "slide_sorter_command3.png" ; }; }; Image IMAGE_SHADOW @@ -76,4 +61,9 @@ Resource IMG_ICONS { ImageBitmap = Bitmap { File = "slide_sorter_hide_slide_overlay.png" ; }; }; + + String STRING_UNHIDE + { + Text [ en-US ] = "unhide" ; + }; }; diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index cc43787972a8..612db3a06791 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -195,12 +195,6 @@ public: Range GetValidHorizontalSizeRange (void) const; Range GetValidVerticalSizeRange (void) const; - Size CalculateTargetSize ( - const Size& rWindowSize, - const Size& rPreviewModelSize, - const bool bCalculateWidth, - const bool bCalculateHeight) const; - Rectangle GetPageObjectBox ( const sal_Int32 nIndex, const bool bIncludeBorderAndGap = false) const; @@ -226,6 +220,11 @@ protected: virtual Size CalculateTargetSize ( const Size& rWindowSize, const Size& rPreviewModelSize) const = 0; + Size GetTargetSize ( + const Size& rWindowSize, + const Size& rPreviewModelSize, + const bool bCalculateWidth, + const bool bCalculateHeight) const; void CalculateVerticalLogicalInsertPosition ( const Point& rModelPosition, InsertPosition& rPosition) const; @@ -1010,7 +1009,7 @@ Range Layouter::Implementation::GetValidVerticalSizeRange (void) const -Size Layouter::Implementation::CalculateTargetSize ( +Size Layouter::Implementation::GetTargetSize ( const Size& rWindowSize, const Size& rPreviewModelSize, const bool bCalculateWidth, @@ -1226,7 +1225,7 @@ Size HorizontalImplementation::CalculateTargetSize ( const Size& rWindowSize, const Size& rPreviewModelSize) const { - return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, false, true); + return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, false, true); } @@ -1304,7 +1303,7 @@ Size VerticalImplementation::CalculateTargetSize ( const Size& rWindowSize, const Size& rPreviewModelSize) const { - return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, true, false); + return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, false); } @@ -1378,7 +1377,7 @@ Size GridImplementation::CalculateTargetSize ( const Size& rWindowSize, const Size& rPreviewModelSize) const { - return Implementation::CalculateTargetSize(rWindowSize, rPreviewModelSize, true, true); + return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, true); } diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx index 61722bd25159..2baabd218fe4 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -64,7 +64,7 @@ PageObjectLayouter::PageObjectLayouter ( maPageNumberAreaBoundingBox(), maPreviewBoundingBox(), maTransitionEffectBoundingBox(), - maButtonAreaBoundingBox(), + maWideButtonBoundingBox(), maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)), mpPageNumberFont(Theme::GetFont(Theme::PageNumberFont, *rpWindow)) { @@ -100,11 +100,14 @@ PageObjectLayouter::PageObjectLayouter ( maPreviewBoundingBox.Bottom() - aIconSize.Height()), aIconSize); - maButtonAreaBoundingBox = Rectangle( - 0, - maPageObjectBoundingBox.Bottom() - gaButtonSize.Height() - gnButtonGap, - maPageObjectBoundingBox.Right() - gnButtonGap, - maPageObjectBoundingBox.Bottom() - gnButtonGap); + // The wide "unhide" button is placed at the lower edge of the preview. + // Add 1 pixel at the sides to compensate for the missing border around + // the button. + maWideButtonBoundingBox = Rectangle( + maPreviewBoundingBox.Left() - 1, + maPreviewBoundingBox.Bottom() - gaButtonSize.Height() - 1, + maPreviewBoundingBox.Right() + 1, + maPreviewBoundingBox.Bottom() + 1); } @@ -225,16 +228,16 @@ Rectangle PageObjectLayouter::GetBoundingBox ( aBoundingBox = maTransitionEffectBoundingBox; break; - case ButtonArea: - aBoundingBox = maButtonAreaBoundingBox; + case WideButton: + aBoundingBox = maWideButtonBoundingBox; break; case Button: aBoundingBox = Rectangle( - maPageObjectBoundingBox.BottomRight() + maPreviewBoundingBox.BottomRight() - Point( - (nIndex+1)*(gaButtonSize.Width() + gnButtonGap), - gaButtonSize.Height() + gnButtonGap), + (nIndex+1)*gaButtonSize.Width() + nIndex*gnButtonGap, + gaButtonSize.Height()), gaButtonSize); break; } @@ -315,7 +318,7 @@ sal_Int32 PageObjectLayouter::GetButtonIndexAt ( const model::SharedPageDescriptor& rpPageDescriptor, const Point& rWindowLocation) { - if ( ! GetBoundingBox(rpPageDescriptor, ButtonArea, ModelCoordinateSystem) + if ( ! GetBoundingBox(rpPageDescriptor, Preview, ModelCoordinateSystem) .IsInside(rWindowLocation)) { return -1; diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index ec0b274397b7..4bbe202d654c 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -153,13 +153,15 @@ PageObjectPainter::PageObjectPainter ( maNormalBackground(), maSelectionBackground(), maFocusedSelectionBackground(), - maMouseOverBackground() + maMouseOverBackground(), + msUnhideString() { LocalResource aResource (IMG_ICONS); maStartPresentationIcon = Image(SdResId(IMAGE_PRESENTATION)).GetBitmapEx(); maShowSlideIcon = Image(SdResId(IMAGE_SHOW_SLIDE)).GetBitmapEx(); maNewSlideIcon = Image(SdResId(IMAGE_NEW_SLIDE)).GetBitmapEx(); + msUnhideString = String(SdResId(STRING_UNHIDE)); mpShadowPainter.reset(new FramePainter(mpTheme->GetIcon(Theme::RawShadow))); } @@ -198,7 +200,10 @@ void PageObjectPainter::PaintPageObject ( PaintPreview(rDevice, rpDescriptor); PaintPageNumber(rDevice, rpDescriptor); PaintTransitionEffect(rDevice, rpDescriptor); - PaintButtons(rDevice, rpDescriptor); + if (rpDescriptor->HasState(model::PageDescriptor::ST_Excluded)) + PaintWideButton(rDevice, rpDescriptor); + else + PaintButtons(rDevice, rpDescriptor); rDevice.SetAntialiasing(nSavedAntialiasingMode); } @@ -206,9 +211,10 @@ void PageObjectPainter::PaintPageObject ( -void PageObjectPainter::NotifyResize (void) +void PageObjectPainter::NotifyResize (const bool bForce) { if ( ! mpPageObjectLayouter + || bForce || mpPageObjectLayouter->GetPageObjectSize() != maNewSlideIcon.GetSizePixel()) { maNormalBackground.SetEmpty(); @@ -334,6 +340,7 @@ void PageObjectPainter::PaintPageNumber ( rDevice.SetTextColor(Color(mpTheme->GetColor(Theme::PageNumberColor))); rDevice.DrawText(aBox, sPageNumber, TEXT_DRAW_RIGHT | TEXT_DRAW_VCENTER); +#if 0 if (rpDescriptor->GetVisualState().GetCurrentVisualState() == model::VisualState::VS_Excluded) { @@ -348,6 +355,7 @@ void PageObjectPainter::PaintPageNumber ( rDevice.DrawLine(aFrameBox.TopLeft(), aBox.BottomRight()); } +#endif } @@ -381,17 +389,12 @@ void PageObjectPainter::PaintButtons ( if (rpDescriptor->GetVisualState().GetButtonAlpha() >= 1) return; - const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox( - rpDescriptor, - PageObjectLayouter::Preview, - PageObjectLayouter::ModelCoordinateSystem)); - const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); rDevice.SetLineColor(); - const double nCornerRadius(3); + const double nCornerRadius(mpTheme->GetIntegerValue(Theme::ButtonCornerRadius)); for (int nButtonIndex=0; nButtonIndex<3; ++nButtonIndex) { Color aButtonFillColor (mpTheme->GetColor(Theme::ButtonBackground)); @@ -459,6 +462,56 @@ void PageObjectPainter::PaintButtons ( +void PageObjectPainter::PaintWideButton ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const +{ + if (rpDescriptor->GetVisualState().GetButtonAlpha() >= 1) + return; + + const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); + rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); + + // Determine background color. + Color aButtonFillColor (mpTheme->GetColor(Theme::ButtonBackground)); + switch (rpDescriptor->GetVisualState().GetButtonState(PageObjectLayouter::ShowHideButtonIndex)) + { + case model::VisualState::BS_Normal: + break; + + case model::VisualState::BS_MouseOver: + aButtonFillColor.IncreaseLuminance(50); + break; + + case model::VisualState::BS_Pressed: + aButtonFillColor.DecreaseLuminance(50); + break; + } + rDevice.SetFillColor(aButtonFillColor); + rDevice.SetLineColor(); + + const Rectangle aBox ( + mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::WideButton, + PageObjectLayouter::ModelCoordinateSystem)); + const double nCornerRadius(mpTheme->GetIntegerValue(Theme::ButtonCornerRadius)); + rDevice.DrawTransparent( + ::basegfx::B2DPolyPolygon( + ::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), + nCornerRadius/aBox.GetWidth(), + nCornerRadius/aBox.GetHeight())), + rpDescriptor->GetVisualState().GetButtonAlpha()); + + // Paint text over the button background. + rDevice.SetTextColor(mpTheme->GetColor(Theme::ButtonText)); + rDevice.DrawText(aBox, msUnhideString, TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER); +} + + + + void PageObjectPainter::PrepareBackgrounds (OutputDevice& rDevice) { if (maNormalBackground.IsEmpty()) diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index 14b79afea1ff..826aee152533 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -69,8 +69,6 @@ const static ColorData BackgroundColorData = 0xffffff; const static ColorData gnMouseOverColor = 0x59000000 | StellaBlue; -const static double gnCornerRadius = 4.0; - ColorData ChangeLuminance (const ColorData aColorData, const int nValue) { @@ -93,7 +91,10 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) maSelectedAndFocusedGradient(), maMouseOverGradient(), maRawShadow(), - maRawInsertShadow() + maRawInsertShadow(), + maColor(PreviewBorder+1), + mnButtonCornerRadius(3), + mnButtonMaxAlpha(255 * 20/100) { LocalResource aResource (IMG_ICONS); @@ -101,6 +102,17 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) maRawInsertShadow = Image(SdResId(IMAGE_INSERT_SHADOW)).GetBitmapEx(); maHideSlideOverlay = Image(SdResId(IMAGE_HIDE_SLIDE_OVERLAY)).GetBitmapEx(); + maColor.resize(PreviewBorder+1); + maColor[Background] = maBackgroundColor; + maColor[PageBackground] = AirForceBlue; + maColor[ButtonBackground] = AirForceBlue; + maColor[ButtonText] = AntiqueWhite; + maColor[MouseOverColor] = gnMouseOverColor; + maColor[PageNumberBorder] = Azure; + maColor[PageNumberColor] = 0x0848a8f; + maColor[Selection] = StellaBlue; + maColor[PreviewBorder] = 0x949599; + Update(rpProperties); } @@ -112,23 +124,14 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert maBackgroundColor = rpProperties->GetBackgroundColor().GetColor(); maPageBackgroundColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor; + maColor[Background] = maBackgroundColor; + #ifdef USE_SYSTEM_SELECTION_COLOR const ColorData aSelectionColor (rpProperties->GetSelectionColor().GetColor()); - maSelectedGradient.maFillColor1 = ChangeLuminance(aSelectionColor, +50); - maSelectedGradient.maFillColor2 = ChangeLuminance(aSelectionColor, -10); - maSelectedGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, -10); - maSelectedGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, -30); - - maSelectedAndFocusedGradient.maFillColor1 = ChangeLuminance(aSelectionColor, +30); - maSelectedAndFocusedGradient.maFillColor2 = ChangeLuminance(aSelectionColor, -30); - maSelectedAndFocusedGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, -30); - maSelectedAndFocusedGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, -50); - - maMouseOverGradient.maFillColor1 = ChangeLuminance(aSelectionColor, +90); - maMouseOverGradient.maFillColor2 = ChangeLuminance(aSelectionColor, +30); - maMouseOverGradient.maBorderColor1 = ChangeLuminance(aSelectionColor, +10); - maMouseOverGradient.maBorderColor2 = ChangeLuminance(aSelectionColor, +30); + SetGradient(SelectedPage, aSelectionColor, +50,-10, -10,-30); + SetGradient(SelectedAndFocusedPage, aSelectionColor, +30,-30, -30,-50); + SetGradient(MouseOverPage, aSelectionColor, +90,+30, +10,+30); #else @@ -148,10 +151,7 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert maMouseOverGradient.maBorderColor2 = 0x0e85cd; #endif - maNormalGradient.maFillColor1 = maBackgroundColor; - maNormalGradient.maFillColor2 = maBackgroundColor; - maNormalGradient.maBorderColor1 = maBackgroundColor; - maNormalGradient.maBorderColor2 = maBackgroundColor; + SetGradient(NormalPage, maBackgroundColor, 0,0, 0,0); } @@ -175,8 +175,20 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert pFont.reset(new Font(Application::GetSettings().GetStyleSettings().GetAppFont())); pFont->SetTransparent(TRUE); pFont->SetWeight(WEIGHT_NORMAL); - const Size aSize (pFont->GetSize()); - pFont->SetSize(Size(aSize.Width()*5/3, aSize.Height()*5/3)); + { + const Size aSize (pFont->GetSize()); + pFont->SetSize(Size(aSize.Width()*5/3, aSize.Height()*5/3)); + } + break; + + case ButtonFont: + pFont.reset(new Font(Application::GetSettings().GetStyleSettings().GetAppFont())); + pFont->SetTransparent(TRUE); + pFont->SetWeight(WEIGHT_BOLD); + { + const Size aSize (pFont->GetSize()); + pFont->SetSize(Size(aSize.Width()*4/3, aSize.Height()*4/3)); + } break; } @@ -196,116 +208,89 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert -ColorData Theme::GetColorForVisualState (const model::VisualState::State eState) +ColorData Theme::GetColor (const ColorType eType) { - ColorData nColor; - switch (eState) - { - case model::VisualState::VS_Selected: - nColor = 0x80000000 | StellaBlue; - break; - - case model::VisualState::VS_Focused: - nColor = AndroidGreen; - break; + if (eType>=0 && eTypeGetSelectionColor(); - break; - case model::VisualState::VS_Excluded: - nColor = 0x88000000; - break; - case model::VisualState::VS_None: - default: - nColor = 0x80000000 | AntiqueWhite; - break; - } - return nColor; +void Theme::SetColor ( + const ColorType eType, + const ColorData aData) +{ + if (eType>=0 && eTypemaBorderColor1; - case Border2: return pDescriptor->maBorderColor2; - case Fill1: return pDescriptor->maFillColor1; - case Fill2: return pDescriptor->maFillColor2; - - default: - OSL_ASSERT(false); - break; - } - } - return 0; + rGradient.mnFillOffset1 = nFillStartOffset; + rGradient.mnFillOffset2 = nFillEndOffset; + rGradient.mnBorderOffset1 = nBorderStartOffset; + rGradient.mnBorderOffset2 = nBorderEndOffset; } @@ -329,4 +314,73 @@ BitmapEx Theme::GetIcon (const IconType eType) } } + + + +sal_Int32 Theme::GetIntegerValue (const IntegerValueType eType) const +{ + switch (eType) + { + case ButtonCornerRadius: + return mnButtonCornerRadius; + + case ButtonMaxAlpha: + return mnButtonMaxAlpha; + + default: + return 0; + } +} + + + + +void Theme::SetIntegerValue (const IntegerValueType eType, const sal_Int32 nValue) +{ + switch (eType) + { + case ButtonCornerRadius: + mnButtonCornerRadius = nValue; + break; + + case ButtonMaxAlpha: + mnButtonMaxAlpha = nValue; + break; + + default: + break; + } +} + + + + +Theme::GradientDescriptor& Theme::GetGradient (const GradientColorType eType) +{ + switch(eType) + { + default: + OSL_ASSERT(false); + // fall through + + case NormalPage: + return maNormalGradient; + break; + + case SelectedPage: + return maSelectedGradient; + break; + + case SelectedAndFocusedPage: + return maSelectedAndFocusedGradient; + break; + + case MouseOverPage: + return maMouseOverGradient; + break; + } +} + + + } } } // end of namespace ::sd::slidesorter::view -- cgit v1.2.3 From 1e89c38545f74a2d18564f9df6ec1ff4d5ef9390 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Tue, 23 Mar 2010 13:35:01 +0100 Subject: renaissance1: #i107215# Fixed minor compilation problems. --- sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx | 2 ++ sd/source/ui/slidesorter/view/SlsLayouter.cxx | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index edd3e37dae20..137d2fe1db81 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -104,6 +104,8 @@ TYPEINIT1(SlideSorterViewShell, ViewShell); FrameView* pFrameViewArgument, const bool bIsCenterPane) { + (void)bIsCenterPane; + ::boost::shared_ptr pViewShell; try { diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 612db3a06791..5b6f43e3bf77 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -1015,6 +1015,8 @@ Size Layouter::Implementation::GetTargetSize ( const bool bCalculateWidth, const bool bCalculateHeight) const { + (void)rPreviewModelSize; + if (mnColumnCount<=0 || mnRowCount<=0) return maPreferredSize; if ( ! (bCalculateWidth || bCalculateHeight)) @@ -1023,9 +1025,6 @@ Size Layouter::Implementation::GetTargetSize ( return maPreferredSize; } - const double nPreviewAspectRatio ( - double(rPreviewModelSize.Width())/double(rPreviewModelSize.Height())); - // Calculate the width of each page object. Size aTargetSize (0,0); if (bCalculateWidth) -- cgit v1.2.3 From 1b8c751edf19558950965cec825a150f97ba082b Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 24 Mar 2010 15:49:18 +0100 Subject: renaissance1: #i107215# Improved button handling. --- sd/source/ui/inc/SlideSorter.hxx | 4 + .../controller/SlideSorterController.cxx | 2 +- .../controller/SlsSelectionFunction.cxx | 1 + .../ui/slidesorter/inc/view/SlideSorterView.hxx | 9 +- .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 10 + sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 4 +- sd/source/ui/slidesorter/shell/SlideSorter.cxx | 8 +- sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx | 217 +++++++++++++++------ sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx | 8 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 132 +++++++------ sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 7 +- sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx | 4 + .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 179 ++++++++++++++--- sd/source/ui/slidesorter/view/SlsTheme.cxx | 18 +- 14 files changed, 434 insertions(+), 169 deletions(-) diff --git a/sd/source/ui/inc/SlideSorter.hxx b/sd/source/ui/inc/SlideSorter.hxx index 257695e0fc91..2d92ff8ead9e 100644 --- a/sd/source/ui/inc/SlideSorter.hxx +++ b/sd/source/ui/inc/SlideSorter.hxx @@ -72,6 +72,8 @@ typedef ::boost::shared_ptr SharedSdWindow; namespace sd { namespace slidesorter { +class SlideSorterDebugDialog; + /** Show previews for all the slides in a document and allow the user to insert or delete slides and modify the order of the slides. @@ -252,6 +254,8 @@ private: ::boost::shared_ptr mpProperties; ::boost::shared_ptr mpTheme; + ::boost::scoped_ptr mpDebugDialog; + SlideSorter ( ViewShell& rViewShell, const ::boost::shared_ptr& rpContentWindow, diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index fce7e53ade23..d35849819c05 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -651,7 +651,7 @@ IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent) // Update theme colors. mrSlideSorter.GetProperties()->HandleDataChangeEvent(); mrSlideSorter.GetTheme()->Update(mrSlideSorter.GetProperties()); - mrView.GetPageObjectPainter()->SetTheme(mrSlideSorter.GetTheme()); + mrView.HandleDataChangeEvent(); } break; diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 5055e22e3661..af982413e5a6 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -1122,6 +1122,7 @@ void SelectionFunction::ProcessButtonUpEvent (const EventDescriptor& rDescriptor { ProcessButtonClick(rDescriptor.mpHitDescriptor, mnButtonDownButtonIndex); } + mrSlideSorter.GetView().SetButtonUnderMouse(rDescriptor.mnButtonIndex, true); break; case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 241e1685ac97..2b068642930a 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -32,6 +32,7 @@ #include "model/SlsPageDescriptor.hxx" #include "model/SlsSharedPageDescriptor.hxx" #include "view/SlsLayouter.hxx" +#include "view/SlsILayerPainter.hxx" #include "View.hxx" #include @@ -67,6 +68,7 @@ class Layouter; class PageObjectPainter; class SelectionPainter; + class SlideSorterView : public sd::View, public ::boost::noncopyable @@ -146,6 +148,8 @@ public: utl::ConfigurationBroadcaster* pBroadcaster, sal_uInt32 nHint); + void HandleDataChangeEvent (void); + void Layout (void); /** This tells the view that it has to re-determine the visibility of the page objects before painting them the next time. @@ -203,7 +207,9 @@ public: void SetPageUnderMouse ( const model::SharedPageDescriptor& rpDescriptor, const bool bAnimate = true); - void SetButtonUnderMouse (const sal_Int32 nButtonIndex); + void SetButtonUnderMouse ( + const sal_Int32 nButtonIndex, + const bool bForce = false); bool SetState ( const model::SharedPageDescriptor& rpDescriptor, @@ -254,6 +260,7 @@ private: ::boost::shared_ptr mpPageObjectPainter; ::boost::shared_ptr mpSelectionPainter; Region maRedrawRegion; + SharedILayerPainter mpBackgroundPainter; /** Determine the visibility of all page objects. */ diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx index e02c68e7967a..2fa10d39f318 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx @@ -101,9 +101,19 @@ private: void PaintButtons ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const; + void PaintButtonsType0 ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; + void PaintButtonsType1 ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const; void PaintWideButton ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const; + Rectangle PaintWideButtonBackground ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor, + const model::VisualState::ButtonState eState) const; void PrepareBackgrounds (OutputDevice& rDevice); void PaintBorder ( OutputDevice& rDevice, diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index ba0a8a56bb3d..1991babb0208 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -126,7 +126,8 @@ public: enum IntegerValueType { ButtonCornerRadius, - ButtonMaxAlpha + ButtonMaxAlpha, + ButtonPaintType }; sal_Int32 GetIntegerValue (const IntegerValueType eType) const; void SetIntegerValue (const IntegerValueType eType, const sal_Int32 nValue); @@ -159,6 +160,7 @@ private: ::std::vector maColor; sal_Int32 mnButtonCornerRadius; sal_Int32 mnButtonMaxAlpha; + sal_Int32 mnButtonPaintType; GradientDescriptor& GetGradient (const GradientColorType eType); }; diff --git a/sd/source/ui/slidesorter/shell/SlideSorter.cxx b/sd/source/ui/slidesorter/shell/SlideSorter.cxx index 4e9afe7cb1ab..825dd578aed9 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorter.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorter.cxx @@ -142,7 +142,8 @@ SlideSorter::SlideSorter ( mpScrollBarBox(rpScrollBarBox), mbLayoutPending(true), mpProperties(new controller::Properties()), - mpTheme(new view::Theme(mpProperties)) + mpTheme(new view::Theme(mpProperties)), + mpDebugDialog() { } @@ -167,7 +168,8 @@ SlideSorter::SlideSorter ( mpScrollBarBox(new ScrollBarBox(&rParentWindow)), mbLayoutPending(true), mpProperties(new controller::Properties()), - mpTheme(new view::Theme(mpProperties)) + mpTheme(new view::Theme(mpProperties)), + mpDebugDialog() { } @@ -218,7 +220,7 @@ void SlideSorter::Init (void) mbIsValid = true; } - SlideSorterDebugDialog::ShowDebugDialog(*this); + mpDebugDialog.reset(SlideSorterDebugDialog::CreateDebugDialog(*this)); } diff --git a/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx index 09b1cf60d265..29dade85bec9 100644 --- a/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx +++ b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx @@ -29,8 +29,6 @@ * ************************************************************************/ -#ifdef DEBUG - #include "SlsDebugDialog.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsTheme.hxx" @@ -59,11 +57,15 @@ public: TextButton ( ::Window* pParent, const char* pText, + const Rectangle& rBoundingBox, const Action& rAction) : PushButton(pParent), maAction(rAction) { SetText(::rtl::OUString::createFromAscii(pText)); + SetPosSizePixel( + rBoundingBox.Top(), rBoundingBox.Left(), + rBoundingBox.GetHeight(), rBoundingBox.GetWidth()); Show(); } @@ -224,7 +226,6 @@ public: GradientControl ( ::Window* pParent, - const char* pTitle, const Theme::GradientColorType eType, const Rectangle& rBoundingBox, SlideSorter& rSlideSorter) @@ -460,7 +461,7 @@ IMPL_LINK(SliderControl, UpdateValue, void*, EMPTYARG) const sal_Int32 nMaxLength (30); char aBuffer[nMaxLength]; - snprintf(aBuffer, nMaxLength, "%d %f", nValue, nValue/255.0); + snprintf(aBuffer, nMaxLength, "%ld %f", nValue, nValue/255.0); mpTextValue->SetText(::rtl::OUString::createFromAscii(aBuffer)); if (maSetter) @@ -485,7 +486,6 @@ public: typedef ::boost::function ValueSetter; ChoiceControl ( ::Window* pParent, - const char* pTitle, const Rectangle& rBoundingBox, const char** aValues, const int nValueCount, @@ -552,15 +552,84 @@ IMPL_LINK(ChoiceControl, UpdateValue, void*, EMPTYARG) +//===== BoolControl =========================================================== + +class BoolControl +{ +public: + typedef ::boost::function ValueGetter; + typedef ::boost::function ValueSetter; + typedef ::boost::function Updater; + BoolControl ( + ::Window* pParent, + const char* pTitle, + const Rectangle& rBoundingBox, + const sal_Int32 nOnValue, + const sal_Int32 nOffValue, + const ValueGetter& rGetter, + const ValueSetter& rSetter, + const Updater& rUpdater) + : maGetter(rGetter), + maSetter(rSetter), + maUpdater(rUpdater), + mpContainer(new ::Window(pParent, WB_BORDER)), + mpButton(new CheckBox(mpContainer)), + mnOnValue(nOnValue), + mnOffValue(nOffValue) + { + const double nWidth (rBoundingBox.GetWidth()); + const double nLeft (0); + const double nTop (0); + const sal_Int32 nStartValue (maGetter ? maGetter() : 0); + + mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); + mpContainer->Show(); + + mpButton->SetText(::rtl::OUString::createFromAscii(pTitle)); + mpButton->SetPosSizePixel(nLeft, nTop, nWidth,20); + mpButton->Check(maGetter() == mnOnValue ? TRUE : FALSE); + mpButton->SetToggleHdl(LINK(this, BoolControl, UpdateValue)); + mpButton->Show(); + } + +private: + ValueGetter maGetter; + ValueSetter maSetter; + Updater maUpdater; + ::Window* mpContainer; + CheckBox* mpButton; + const sal_Int32 mnOnValue; + const sal_Int32 mnOffValue; + + DECL_LINK(UpdateValue, void*); +}; + +IMPL_LINK(BoolControl, UpdateValue, void*, EMPTYARG) +{ + const bool bValue (mpButton->IsChecked()); + + if (maSetter) + { + maSetter(bValue ? mnOnValue : mnOffValue); + if (maUpdater) + maUpdater(); + } + + return 0; +} + + + + //===== SlideSorterDebugDialog ================================================ -void SlideSorterDebugDialog::ShowDebugDialog (SlideSorter& rSlideSorter) +SlideSorterDebugDialog* SlideSorterDebugDialog::CreateDebugDialog (SlideSorter& rSlideSorter) { static const char* pText = getenv("SD_SHOW_DEBUG_DIALOG"); if (pText!=NULL && pText[0]!='0') - { - new SlideSorterDebugDialog(rSlideSorter); - } + return new SlideSorterDebugDialog(rSlideSorter); + else + return NULL; } @@ -569,69 +638,89 @@ void SlideSorterDebugDialog::ShowDebugDialog (SlideSorter& rSlideSorter) SlideSorterDebugDialog::SlideSorterDebugDialog (SlideSorter& rSlideSorter) : mpTopLevelWindow(new WorkWindow(NULL, WB_STDWORK)) { + ::boost::shared_ptr pTheme(rSlideSorter.GetTheme()); + mpTopLevelWindow->SetSizePixel(Size(300,510)); - { - Button* pButton = new TextButton( - mpTopLevelWindow, - "Close", - ::boost::bind(&WorkWindow::Close, mpTopLevelWindow)); - pButton->SetPosSizePixel(195,480,100,25); + new TextButton( + mpTopLevelWindow, + "Close", + Rectangle(195,480,100,25), + ::boost::bind(&WorkWindow::Close, mpTopLevelWindow)); + + new ColorControl( + mpTopLevelWindow, + "Unhide Button Background", + Rectangle(10,10,290,110), + ::boost::bind(&view::Theme::GetColor, pTheme, view::Theme::ButtonBackground), + ::boost::bind(&view::Theme::SetColor, pTheme, view::Theme::ButtonBackground, _1), + ::boost::bind(&view::SlideSorterView::RequestRepaint, + ::boost::ref(rSlideSorter.GetView()))); + + new SliderControl( + mpTopLevelWindow, + "Max Button Alpha", + Rectangle(10,120,290,200), + Range(0,255), + ::boost::bind(&view::Theme::GetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha), + ::boost::bind(&view::Theme::SetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha, _1), + ::boost::bind(&view::SlideSorterView::RequestRepaint, + ::boost::ref(rSlideSorter.GetView()))); + + GradientControl* pControl = new GradientControl( + mpTopLevelWindow, + Theme::SelectedPage, + Rectangle(10,210,285,450), + rSlideSorter); + const char* aValues[] = { + "Normal", + "Selected", + "SelectedAndFocused", + "MouseOver" + }; + new ChoiceControl( + mpTopLevelWindow, + Rectangle(10,210,290,470), + aValues, + 4, + pControl, + ::boost::bind(&GradientControl::GetType, pControl), + ::boost::bind(&GradientControl::SetType, pControl, _1)); + + new BoolControl( + mpTopLevelWindow, + "Alternative Button Paint Style", + Rectangle(10,480,290,500), + 1,0, + ::boost::bind(&view::Theme::GetIntegerValue, pTheme, view::Theme::ButtonPaintType), + ::boost::bind(&view::Theme::SetIntegerValue, pTheme, view::Theme::ButtonPaintType, _1), + ::boost::bind(&view::SlideSorterView::RequestRepaint, + ::boost::ref(rSlideSorter.GetView()))); - } + mpTopLevelWindow->Show(true); +} - ::boost::shared_ptr pTheme(rSlideSorter.GetTheme()); - { - ColorControl* pControl = new ColorControl( - mpTopLevelWindow, - "Unhide Button Background", - Rectangle(10,10,290,110), - ::boost::bind(&view::Theme::GetColor, pTheme, view::Theme::ButtonBackground), - ::boost::bind(&view::Theme::SetColor, pTheme, view::Theme::ButtonBackground, _1), - ::boost::bind(&view::SlideSorterView::RequestRepaint, - ::boost::ref(rSlideSorter.GetView()))); - } - { - SliderControl* pControl = new SliderControl( - mpTopLevelWindow, - "Max Button Alpha", - Rectangle(10,120,290,200), - Range(0,255), - ::boost::bind(&view::Theme::GetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha), - ::boost::bind(&view::Theme::SetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha, _1), - ::boost::bind(&view::SlideSorterView::RequestRepaint, - ::boost::ref(rSlideSorter.GetView()))); - } - { - GradientControl* pControl = new GradientControl( - mpTopLevelWindow, - "Selection Page Gradient", - Theme::SelectedPage, - Rectangle(10,210,285,450), - rSlideSorter); - const char* aValues[] = { - "Normal", - "Selected", - "SelectedAndFocused", - "MouseOver" - }; - ChoiceControl* pChoiceControl = new ChoiceControl( - mpTopLevelWindow, - "Gradient", - Rectangle(10,210,290,470), - aValues, - 4, - pControl, - ::boost::bind(&GradientControl::GetType, pControl), - ::boost::bind(&GradientControl::SetType, pControl, _1)); - } - mpTopLevelWindow->Show(true); +SlideSorterDebugDialog::~SlideSorterDebugDialog (void) +{ + DeleteWindow(mpTopLevelWindow); } -} } // end of namespace ::sd::slidesorter -#endif + +void SlideSorterDebugDialog::DeleteWindow (::Window* pWindow) +{ + if (pWindow == NULL) + return; + + while (pWindow->GetChildCount() > 0) + DeleteWindow(pWindow->GetChild(0)); + + delete pWindow; +} + + +} } // end of namespace ::sd::slidesorter diff --git a/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx b/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx index c2f2f8a6b6b2..5964aa158726 100644 --- a/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx +++ b/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx @@ -32,11 +32,10 @@ #ifndef SD_DEBUG_DIALOG_HXX #define SD_DEBUG_DIALOG_HXX -#ifdef DEBUG - #include class WorkWindow; +class Window; namespace sd { namespace slidesorter { @@ -46,16 +45,17 @@ class SlideSorterDebugDialog : public ::boost::noncopyable { public: - static void ShowDebugDialog (SlideSorter& rSlideSorter); + static SlideSorterDebugDialog* CreateDebugDialog (SlideSorter& rSlideSorter); + ~SlideSorterDebugDialog (void); private: WorkWindow* mpTopLevelWindow; SlideSorterDebugDialog (SlideSorter& rSlideSorter); + void DeleteWindow (::Window* pWindow); }; } } // end of namespace ::sd::slidesorter #endif -#endif diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 04f5d61294ad..41d671353be6 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -64,21 +64,16 @@ #include #include #include -#include #include #include #include #include -#include #include -#include #include #include #include #include #include -#include -#include #include #include @@ -97,29 +92,29 @@ using ::sd::slidesorter::controller::AnimationFunction; namespace sd { namespace slidesorter { namespace view { - -/** Wrapper around the SlideSorterView that supports the IPainter interface - and that allows the LayeredDevice to hold the SlideSorterView (held as - scoped_ptr by the SlideSorter) as shared_ptr. -*/ -class Painter : public ILayerPainter -{ -public: - Painter (SlideSorterView& rView) : mrView(rView) {} - virtual ~Painter (void) {} - - virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) - { - mrView.Paint(rDevice,rRepaintArea); - } - virtual void SetLayerInvalidator (const SharedILayerInvalidator&) +namespace { + /** Wrapper around the SlideSorterView that supports the IPainter + interface and that allows the LayeredDevice to hold the + SlideSorterView (held as scoped_ptr by the SlideSorter) as + shared_ptr. + */ + class Painter : public ILayerPainter { - } + public: + Painter (SlideSorterView& rView) : mrView(rView) {} + virtual ~Painter (void) {} -private: - SlideSorterView& mrView; -}; + virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) + { + mrView.Paint(rDevice,rRepaintArea); + } + virtual void SetLayerInvalidator (const SharedILayerInvalidator&) {} + + private: + SlideSorterView& mrView; + }; +} @@ -128,17 +123,8 @@ class BackgroundPainter public ::boost::noncopyable { public: - BackgroundPainter ( - const SharedSdWindow& rpWindow, - const Color aBackgroundColor) - : maBackgroundColor(aBackgroundColor), - mpWindow(rpWindow) - { - } - - ~BackgroundPainter (void) - { - } + BackgroundPainter (const Color aBackgroundColor) : maBackgroundColor(aBackgroundColor) {} + virtual ~BackgroundPainter (void) {} virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) { @@ -147,14 +133,12 @@ public: rDevice.DrawRect(rRepaintArea); } - virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator) - { - (void)rpInvalidator; - } + virtual void SetLayerInvalidator (const SharedILayerInvalidator&) {} + + void SetColor (const Color aColor) { maBackgroundColor = aColor; } private: - const Color maBackgroundColor; - SharedSdWindow mpWindow; + Color maBackgroundColor; }; @@ -183,17 +167,25 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) mbIsMouseOverIndicationAllowed(true), mnButtonUnderMouse(-1), mpPageObjectPainter(), - mpSelectionPainter() + mpSelectionPainter(), + mpBackgroundPainter( + new BackgroundPainter(mrSlideSorter.GetTheme()->GetColor(Theme::Background))) { // Hide the page that contains the page objects. SetPageVisible (FALSE); + + // Register the background painter on level 0 + mpLayeredDevice->RegisterPainter(mpBackgroundPainter, 0); + // Wrap a shared_ptr held wrapper around this view and register it as // painter at the layered device. There is no explicit destruction: in // the SlideSorterView destructor the layered device is destroyed and // with it the only reference to the wrapper which therefore is also // destroyed. - mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 2); + // The painter is placed on level 0, like the background painter, so + // that it is buffered. + mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 0); } @@ -344,17 +336,26 @@ void SlideSorterView::HandleDrawModeChange (void) +void SlideSorterView::HandleDataChangeEvent (void) +{ + GetPageObjectPainter()->SetTheme(mrSlideSorter.GetTheme()); + + // Update the color used by the background painter. + ::boost::shared_ptr pPainter ( + ::boost::dynamic_pointer_cast(mpBackgroundPainter)); + if (pPainter) + pPainter->SetColor(mrSlideSorter.GetTheme()->GetColor(Theme::Background)); + + RequestRepaint(); +} + + + + void SlideSorterView::Resize (void) { UpdateOrientation(); - if ( ! mpLayeredDevice->HasPainter(0)) - mpLayeredDevice->RegisterPainter( - SharedILayerPainter(new BackgroundPainter( - mrSlideSorter.GetContentWindow(), - mrSlideSorter.GetTheme()->GetColor(Theme::Background))), - 0); - mpLayeredDevice->Resize(); SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (mrModel.GetPageCount()>0 && pWindow) @@ -916,9 +917,11 @@ void SlideSorterView::SetPageUnderMouse ( -void SlideSorterView::SetButtonUnderMouse (const sal_Int32 nButtonIndex) +void SlideSorterView::SetButtonUnderMouse ( + const sal_Int32 nButtonIndex, + const bool bForce) { - if (mnButtonUnderMouse != nButtonIndex) + if (mnButtonUnderMouse != nButtonIndex || bForce) { if (mpPageUnderMouse) { @@ -967,9 +970,10 @@ bool SlideSorterView::SetState ( // Fade in or out the buttons. if (eState == PageDescriptor::ST_MouseOver) { - const double nEndAlpha (bStateValue - ? mrSlideSorter.GetTheme()->GetIntegerValue(Theme::ButtonMaxAlpha)/255.0 - : 1.0); + const double nMinAlpha ( + mrSlideSorter.GetTheme()->GetIntegerValue(Theme::ButtonMaxAlpha)/255.0); + const static double nMaxAlpha (1.0); + const double nEndAlpha (bStateValue ? nMinAlpha : nMaxAlpha); if (bAnimate) { const double nStartAlpha (pDescriptor->GetVisualState().GetButtonAlpha()); @@ -983,9 +987,19 @@ bool SlideSorterView::SetState ( const ::boost::function aBlendFunctor ( ::boost::bind( AnimationFunction::Blend, - nStartAlpha, + nStartAlpha, nEndAlpha, ::boost::bind(AnimationFunction::Linear, _1))); + + // Delay the fade in a little bit when the buttons are not + // visible at all so that we do not leave a trail of + // half-visible buttons when the mouse is moved across the + // screen. No delay on fade out or when the buttons are already + // showing. Fade out is faster than fade in. + double nStartOffset (bStateValue ? 500 : 100); + const double nDuration (bStateValue ? 400 : 250); + if (nStartAlpha>nMinAlpha && nStartAlphaGetVisualState().SetButtonAlphaAnimationId( mrSlideSorter.GetController().GetAnimator()->AddAnimation( ::boost::bind( @@ -993,8 +1007,8 @@ bool SlideSorterView::SetState ( pDescriptor, ::boost::ref(*this), ::boost::bind(aBlendFunctor, _1)), - bStateValue ? 500 : 0, - 400, + nStartOffset, + nDuration, ::boost::bind( &VisualState::SetButtonAlphaAnimationId, ::boost::ref(pDescriptor->GetVisualState()), diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx index b625e60865b6..cf69970bca57 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx @@ -295,7 +295,9 @@ void LayeredDevice::Repaint (const Region& rRepaintRegion) void LayeredDevice::RepaintRectangle (const Rectangle& rRepaintRectangle) { - if (mpLayers->size() <= 1) + if (mpLayers->size() == 0) + return; + else if (mpLayers->size() == 1) { // Just copy the main layer into the target device. (*mpLayers)[0]->Repaint(*mpTargetWindow, rRepaintRectangle); @@ -457,6 +459,9 @@ void Layer::Validate (const MapMode& rMapMode) void Layer::ValidateRectangle (const Rectangle& rBox) { + if ( ! mpLayerDevice) + return; + const Region aSavedClipRegion (mpLayerDevice->GetClipRegion()); mpLayerDevice->SetClipRegion(Region(rBox)); diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx index b428ae7e427c..d67e0e99c473 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx @@ -49,6 +49,10 @@ class Window; namespace sd { namespace slidesorter { namespace view { +/** A simple wrapper around an OutputDevice that provides support for + independent layers and buffering. + Each layer may contain any number of painters. +*/ class LayeredDevice : public ::boost::enable_shared_from_this diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 4bbe202d654c..a473cb21a20d 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -200,10 +200,7 @@ void PageObjectPainter::PaintPageObject ( PaintPreview(rDevice, rpDescriptor); PaintPageNumber(rDevice, rpDescriptor); PaintTransitionEffect(rDevice, rpDescriptor); - if (rpDescriptor->HasState(model::PageDescriptor::ST_Excluded)) - PaintWideButton(rDevice, rpDescriptor); - else - PaintButtons(rDevice, rpDescriptor); + PaintButtons(rDevice, rpDescriptor); rDevice.SetAntialiasing(nSavedAntialiasingMode); } @@ -230,7 +227,7 @@ void PageObjectPainter::NotifyResize (const bool bForce) void PageObjectPainter::SetTheme (const ::boost::shared_ptr& rpTheme) { mpTheme = rpTheme; - NotifyResize(); + NotifyResize(true); } @@ -385,6 +382,22 @@ void PageObjectPainter::PaintTransitionEffect ( void PageObjectPainter::PaintButtons ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const +{ + if (rpDescriptor->HasState(model::PageDescriptor::ST_Excluded)) + PaintWideButton(rDevice, rpDescriptor); + else + if (mpTheme->GetIntegerValue(Theme::ButtonPaintType) == 0) + PaintButtonsType0(rDevice, rpDescriptor); + else + PaintButtonsType1(rDevice, rpDescriptor); +} + + + + +void PageObjectPainter::PaintButtonsType0 ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const { if (rpDescriptor->GetVisualState().GetButtonAlpha() >= 1) return; @@ -462,7 +475,7 @@ void PageObjectPainter::PaintButtons ( -void PageObjectPainter::PaintWideButton ( +void PageObjectPainter::PaintButtonsType1 ( OutputDevice& rDevice, const model::SharedPageDescriptor& rpDescriptor) const { @@ -472,41 +485,151 @@ void PageObjectPainter::PaintWideButton ( const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); - // Determine background color. - Color aButtonFillColor (mpTheme->GetColor(Theme::ButtonBackground)); - switch (rpDescriptor->GetVisualState().GetButtonState(PageObjectLayouter::ShowHideButtonIndex)) + rDevice.SetLineColor(); + + // Determine state for the background. + model::VisualState::ButtonState eState (model::VisualState::BS_Normal); + for (int nButtonIndex=0; nButtonIndex<3; ++nButtonIndex) { - case model::VisualState::BS_Normal: + const model::VisualState::ButtonState eButtonState ( + rpDescriptor->GetVisualState().GetButtonState(nButtonIndex)); + if (eButtonState != model::VisualState::BS_Normal) + { + eState = eButtonState; break; + } + } - case model::VisualState::BS_MouseOver: - aButtonFillColor.IncreaseLuminance(50); - break; + // Paint the button background with the state of the button under the mouse. + PaintWideButtonBackground(rDevice, rpDescriptor, eState); - case model::VisualState::BS_Pressed: - aButtonFillColor.DecreaseLuminance(50); - break; + // Paint the icons. + for (int nButtonIndex=0; nButtonIndex<3; ++nButtonIndex) + { + const Rectangle aBox ( + mpPageObjectLayouter->GetBoundingBox( + rpDescriptor, + PageObjectLayouter::Button, + PageObjectLayouter::ModelCoordinateSystem, + nButtonIndex)); + + // Choose icon. + const BitmapEx* pImage = NULL; + switch (nButtonIndex) + { + case 0: + pImage = &maNewSlideIcon; + break; + case 1: + pImage = &maShowSlideIcon; + break; + case 2: + pImage = &maStartPresentationIcon; + break; + } + + // Adjust luminosity of icon to indicate its state. + Bitmap aIcon (pImage->GetBitmap()); + switch (rpDescriptor->GetVisualState().GetButtonState(nButtonIndex)) + { + case model::VisualState::BS_Normal: + break; + + case model::VisualState::BS_MouseOver: + aIcon.Adjust(+30); + break; + + case model::VisualState::BS_Pressed: + aIcon.Adjust(-30); + break; + } + + // Paint icon over the button background. + if (pImage != NULL) + { + AlphaMask aMask (pImage->GetMask()); + AdaptTransparency( + aMask, + rpDescriptor->GetVisualState().GetButtonAlpha()); + rDevice.DrawImage( + Point( + aBox.Left()+(aBox.GetWidth()-pImage->GetSizePixel().Width())/2, + aBox.Top()+(aBox.GetHeight()-pImage->GetSizePixel().Height())/2), + BitmapEx(aIcon, aMask)); + } } - rDevice.SetFillColor(aButtonFillColor); - rDevice.SetLineColor(); + rDevice.SetAntialiasing(nSavedAntialiasingMode); +} + + + + +Rectangle PageObjectPainter::PaintWideButtonBackground ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor, + const model::VisualState::ButtonState eState) const +{ const Rectangle aBox ( mpPageObjectLayouter->GetBoundingBox( rpDescriptor, PageObjectLayouter::WideButton, PageObjectLayouter::ModelCoordinateSystem)); - const double nCornerRadius(mpTheme->GetIntegerValue(Theme::ButtonCornerRadius)); - rDevice.DrawTransparent( - ::basegfx::B2DPolyPolygon( - ::basegfx::tools::createPolygonFromRect( - ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), - nCornerRadius/aBox.GetWidth(), - nCornerRadius/aBox.GetHeight())), - rpDescriptor->GetVisualState().GetButtonAlpha()); + if (rpDescriptor->GetVisualState().GetButtonAlpha() < 1) + { + const USHORT nSavedAntialiasingMode (rDevice.GetAntialiasing()); + rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW); + + // Determine background color. + Color aButtonFillColor (mpTheme->GetColor(Theme::ButtonBackground)); + switch (eState) + { + case model::VisualState::BS_Normal: + break; + + case model::VisualState::BS_MouseOver: + aButtonFillColor.IncreaseLuminance(50); + break; + + case model::VisualState::BS_Pressed: + aButtonFillColor.DecreaseLuminance(50); + break; + } + rDevice.SetFillColor(aButtonFillColor); + rDevice.SetLineColor(); + + const double nCornerRadius(mpTheme->GetIntegerValue(Theme::ButtonCornerRadius)); + rDevice.DrawTransparent( + ::basegfx::B2DPolyPolygon( + ::basegfx::tools::createPolygonFromRect( + ::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()), + nCornerRadius/aBox.GetWidth(), + nCornerRadius/aBox.GetHeight())), + rpDescriptor->GetVisualState().GetButtonAlpha()); + + rDevice.SetAntialiasing(nSavedAntialiasingMode); + } + return aBox; +} + + + + +void PageObjectPainter::PaintWideButton ( + OutputDevice& rDevice, + const model::SharedPageDescriptor& rpDescriptor) const +{ + const Rectangle aButtonBox (PaintWideButtonBackground( + rDevice, + rpDescriptor, + rpDescriptor->GetVisualState().GetButtonState(PageObjectLayouter::ShowHideButtonIndex))); // Paint text over the button background. - rDevice.SetTextColor(mpTheme->GetColor(Theme::ButtonText)); - rDevice.DrawText(aBox, msUnhideString, TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER); + if (rpDescriptor->GetVisualState().GetButtonAlpha() < 1) + { + rDevice.SetTextColor(mpTheme->GetColor(Theme::ButtonText)); + rDevice.DrawText(aButtonBox, msUnhideString, TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER); + } } diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index 826aee152533..173997cea22f 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -94,7 +94,8 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) maRawInsertShadow(), maColor(PreviewBorder+1), mnButtonCornerRadius(3), - mnButtonMaxAlpha(255 * 20/100) + mnButtonMaxAlpha(255 * 20/100), + mnButtonPaintType(0) { LocalResource aResource (IMG_ICONS); @@ -210,7 +211,7 @@ void Theme::Update (const ::boost::shared_ptr& rpPropert ColorData Theme::GetColor (const ColorType eType) { - if (eType>=0 && eType=0 && sal_uInt32(eType)=0 && eType=0 && sal_uInt32(eType) Date: Wed, 24 Mar 2010 16:12:51 +0100 Subject: renaissance1: #i107215# Fixed minor compilation problems. --- sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx | 3 --- 1 file changed, 3 deletions(-) diff --git a/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx index 29dade85bec9..58a5a8776129 100644 --- a/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx +++ b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx @@ -254,7 +254,6 @@ public: { const double nWidth (rBoundingBox.GetWidth()); ::boost::shared_ptr pTheme (mrSlideSorter.GetTheme()); - const ColorData aStartColor (pTheme->GetGradientColor(eType, Theme::Base)); mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); mpContainer->Show(); @@ -502,7 +501,6 @@ public: const double nWidth (rBoundingBox.GetWidth()); const double nLeft (0); const double nTop (0); - const sal_Int32 nStartValue (maGetter ? maGetter() : 0); mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); mpContainer->Show(); @@ -580,7 +578,6 @@ public: const double nWidth (rBoundingBox.GetWidth()); const double nLeft (0); const double nTop (0); - const sal_Int32 nStartValue (maGetter ? maGetter() : 0); mpContainer->SetPosSizePixel(rBoundingBox.TopLeft(), rBoundingBox.GetSize()); mpContainer->Show(); -- cgit v1.2.3 From 93a68953ef974f1a9f0b0aac5ef78a6d3be503c5 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Wed, 24 Mar 2010 18:28:31 +0100 Subject: renaissance1: #i107215# Fixed destruction of DebugDialog. Improved button handling. --- .../controller/SlsSelectionFunction.cxx | 9 +- sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx | 116 +++++++++++++++------ sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx | 3 + .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 17 ++- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 4 - 5 files changed, 111 insertions(+), 38 deletions(-) diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index af982413e5a6..85d10a7407fb 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -1122,7 +1122,14 @@ void SelectionFunction::ProcessButtonUpEvent (const EventDescriptor& rDescriptor { ProcessButtonClick(rDescriptor.mpHitDescriptor, mnButtonDownButtonIndex); } - mrSlideSorter.GetView().SetButtonUnderMouse(rDescriptor.mnButtonIndex, true); + // Update state of button under mouse (typically from pressed to + // mouse over). Note that the button under the mouse can change + // when the exclusions state changes (three buttons vs. wide button.) + mrSlideSorter.GetView().SetButtonUnderMouse( + mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt( + rDescriptor.mpHitDescriptor, + rDescriptor.maMouseModelPosition), + true); break; case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: diff --git a/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx index 58a5a8776129..fa57962659e4 100644 --- a/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx +++ b/sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx @@ -47,9 +47,16 @@ using namespace ::sd::slidesorter::view; namespace sd { namespace slidesorter { +class DebugControl +{ +public: + DebugControl (void) {}; + virtual ~DebugControl (void) {} +}; + //===== TextButton ============================================================ -class TextButton : public PushButton +class TextButton : public PushButton, public DebugControl { public: typedef ::boost::function Action; @@ -84,7 +91,7 @@ private: //===== ColorControl ========================================================== -class ColorControl +class ColorControl : public DebugControl { public: typedef ::boost::function ColorGetter; @@ -149,6 +156,18 @@ public: UpdateDisplay(); } + virtual ~ColorControl (void) + { + delete mpTitle; + delete mpRedSlider; + delete mpGreenSlider; + delete mpBlueSlider; + delete mpTextValue; + delete mpColorValue; + + delete mpContainer; + } + void SetColor (const ColorData aColorData) { const Color aColor (aColorData); @@ -219,7 +238,7 @@ IMPL_LINK(ColorControl, UpdateColor, void*, EMPTYARG) //===== GradientControl ======================================================= -class GradientControl +class GradientControl : public DebugControl { public: typedef ::boost::function Updater; @@ -270,6 +289,25 @@ public: Update(0); } + virtual ~GradientControl (void) + { + delete mpColorControl; + delete mpFillOffset1Slider; + delete mpFillOffset1Text; + delete mpFillOffset1Color; + delete mpFillOffset2Slider; + delete mpFillOffset2Text; + delete mpFillOffset2Color; + delete mpBorderOffset1Slider; + delete mpBorderOffset1Text; + delete mpBorderOffset1Color; + delete mpBorderOffset2Slider; + delete mpBorderOffset2Text; + delete mpBorderOffset2Color; + + delete mpContainer; + } + void Initialize ( Slider* pSlider, FixedText* pText, @@ -395,7 +433,7 @@ IMPL_LINK(GradientControl, Update, void*, EMPTYARG) //===== SliderControl ========================================================= -class SliderControl +class SliderControl : public DebugControl { public: typedef ::boost::function ValueGetter; @@ -442,6 +480,14 @@ public: UpdateValue(0); } + virtual ~SliderControl (void) + { + delete mpTitle; + delete mpSlider; + delete mpTextValue; + delete mpContainer; + } + private: ValueGetter maGetter; ValueSetter maSetter; @@ -478,7 +524,7 @@ IMPL_LINK(SliderControl, UpdateValue, void*, EMPTYARG) //===== ChoiceControl ========================================================= -class ChoiceControl +class ChoiceControl : public DebugControl { public: typedef ::boost::function ValueGetter; @@ -524,6 +570,13 @@ public: UpdateValue(0); } + virtual ~ChoiceControl (void) + { + delete mpComboBox; + delete mpSubControl; + delete mpContainer; + } + private: ::std::map maValues; ValueGetter maGetter; @@ -552,7 +605,7 @@ IMPL_LINK(ChoiceControl, UpdateValue, void*, EMPTYARG) //===== BoolControl =========================================================== -class BoolControl +class BoolControl : public DebugControl { public: typedef ::boost::function ValueGetter; @@ -589,6 +642,12 @@ public: mpButton->Show(); } + virtual ~BoolControl (void) + { + delete mpButton; + delete mpContainer; + } + private: ValueGetter maGetter; ValueSetter maSetter; @@ -633,28 +692,29 @@ SlideSorterDebugDialog* SlideSorterDebugDialog::CreateDebugDialog (SlideSorter& SlideSorterDebugDialog::SlideSorterDebugDialog (SlideSorter& rSlideSorter) - : mpTopLevelWindow(new WorkWindow(NULL, WB_STDWORK)) + : mpTopLevelWindow(new WorkWindow(NULL, WB_STDWORK)), + maControls() { ::boost::shared_ptr pTheme(rSlideSorter.GetTheme()); mpTopLevelWindow->SetSizePixel(Size(300,510)); - new TextButton( + maControls.push_back(new TextButton( mpTopLevelWindow, "Close", Rectangle(195,480,100,25), - ::boost::bind(&WorkWindow::Close, mpTopLevelWindow)); + ::boost::bind(&WorkWindow::Close, mpTopLevelWindow))); - new ColorControl( + maControls.push_back(new ColorControl( mpTopLevelWindow, "Unhide Button Background", Rectangle(10,10,290,110), ::boost::bind(&view::Theme::GetColor, pTheme, view::Theme::ButtonBackground), ::boost::bind(&view::Theme::SetColor, pTheme, view::Theme::ButtonBackground, _1), ::boost::bind(&view::SlideSorterView::RequestRepaint, - ::boost::ref(rSlideSorter.GetView()))); + ::boost::ref(rSlideSorter.GetView())))); - new SliderControl( + maControls.push_back(new SliderControl( mpTopLevelWindow, "Max Button Alpha", Rectangle(10,120,290,200), @@ -662,7 +722,7 @@ SlideSorterDebugDialog::SlideSorterDebugDialog (SlideSorter& rSlideSorter) ::boost::bind(&view::Theme::GetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha), ::boost::bind(&view::Theme::SetIntegerValue, pTheme, view::Theme::ButtonMaxAlpha, _1), ::boost::bind(&view::SlideSorterView::RequestRepaint, - ::boost::ref(rSlideSorter.GetView()))); + ::boost::ref(rSlideSorter.GetView())))); GradientControl* pControl = new GradientControl( mpTopLevelWindow, @@ -675,16 +735,16 @@ SlideSorterDebugDialog::SlideSorterDebugDialog (SlideSorter& rSlideSorter) "SelectedAndFocused", "MouseOver" }; - new ChoiceControl( + maControls.push_back(new ChoiceControl( mpTopLevelWindow, Rectangle(10,210,290,470), aValues, 4, pControl, ::boost::bind(&GradientControl::GetType, pControl), - ::boost::bind(&GradientControl::SetType, pControl, _1)); + ::boost::bind(&GradientControl::SetType, pControl, _1))); - new BoolControl( + maControls.push_back(new BoolControl( mpTopLevelWindow, "Alternative Button Paint Style", Rectangle(10,480,290,500), @@ -692,7 +752,7 @@ SlideSorterDebugDialog::SlideSorterDebugDialog (SlideSorter& rSlideSorter) ::boost::bind(&view::Theme::GetIntegerValue, pTheme, view::Theme::ButtonPaintType), ::boost::bind(&view::Theme::SetIntegerValue, pTheme, view::Theme::ButtonPaintType, _1), ::boost::bind(&view::SlideSorterView::RequestRepaint, - ::boost::ref(rSlideSorter.GetView()))); + ::boost::ref(rSlideSorter.GetView())))); mpTopLevelWindow->Show(true); } @@ -702,22 +762,18 @@ SlideSorterDebugDialog::SlideSorterDebugDialog (SlideSorter& rSlideSorter) SlideSorterDebugDialog::~SlideSorterDebugDialog (void) { - DeleteWindow(mpTopLevelWindow); + for (::std::vector::const_iterator + iControl(maControls.begin()), + iEnd(maControls.end()); + iControl!=iEnd; + ++iControl) + { + delete *iControl; + } + delete mpTopLevelWindow; } -void SlideSorterDebugDialog::DeleteWindow (::Window* pWindow) -{ - if (pWindow == NULL) - return; - - while (pWindow->GetChildCount() > 0) - DeleteWindow(pWindow->GetChild(0)); - - delete pWindow; -} - - } } // end of namespace ::sd::slidesorter diff --git a/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx b/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx index 5964aa158726..669d0236aea3 100644 --- a/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx +++ b/sd/source/ui/slidesorter/shell/SlsDebugDialog.hxx @@ -33,6 +33,7 @@ #define SD_DEBUG_DIALOG_HXX #include +#include class WorkWindow; class Window; @@ -40,6 +41,7 @@ class Window; namespace sd { namespace slidesorter { class SlideSorter; +class DebugControl; class SlideSorterDebugDialog : public ::boost::noncopyable @@ -50,6 +52,7 @@ public: private: WorkWindow* mpTopLevelWindow; + ::std::vector maControls; SlideSorterDebugDialog (SlideSorter& rSlideSorter); void DeleteWindow (::Window* pWindow); diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx index 2baabd218fe4..faab407da0de 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectLayouter.cxx @@ -323,12 +323,23 @@ sal_Int32 PageObjectLayouter::GetButtonIndexAt ( { return -1; } - for (sal_Int32 nIndex=0; nIndex<3; ++nIndex) + if (rpPageDescriptor->HasState(model::PageDescriptor::ST_Excluded)) { - if (GetBoundingBox(rpPageDescriptor, Button, ModelCoordinateSystem, nIndex) + if (GetBoundingBox(rpPageDescriptor, WideButton, ModelCoordinateSystem) .IsInside(rWindowLocation)) { - return nIndex; + return ShowHideButtonIndex; + } + } + else + { + for (sal_Int32 nIndex=0; nIndex<3; ++nIndex) + { + if (GetBoundingBox(rpPageDescriptor, Button, ModelCoordinateSystem, nIndex) + .IsInside(rWindowLocation)) + { + return nIndex; + } } } return -1; diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index a473cb21a20d..164613fdf998 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -49,10 +49,6 @@ #include "Window.hxx" #include "sdpage.hxx" #include "sdresid.hxx" -#include -#include -#include -#include #include #include #include -- cgit v1.2.3 From 8c6409990af3f38230a465801c7aba39e127e338 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Thu, 8 Apr 2010 14:47:08 +0200 Subject: renaissance1: #i107215# Many fixes around drag-and-drop and selection. --- sd/source/core/drawdoc3.cxx | 36 ++- .../controller/SlideSorterController.cxx | 28 +- .../ui/slidesorter/controller/SlsClipboard.cxx | 141 ++++++---- .../controller/SlsDragAndDropContext.cxx | 3 +- .../ui/slidesorter/controller/SlsFocusManager.cxx | 7 +- .../controller/SlsInsertionIndicatorHandler.cxx | 10 +- .../ui/slidesorter/controller/SlsListener.cxx | 22 +- .../ui/slidesorter/controller/SlsPageSelector.cxx | 97 +++---- .../controller/SlsSelectionFunction.cxx | 15 +- .../slidesorter/controller/SlsSelectionManager.cxx | 304 ++------------------- .../controller/SlsSelectionObserver.cxx | 152 +++++++++++ .../ui/slidesorter/controller/SlsSlotManager.cxx | 8 +- .../controller/SlsVisibleAreaManager.cxx | 254 +++++++++++++++++ sd/source/ui/slidesorter/controller/makefile.mk | 4 +- .../inc/controller/SlideSorterController.hxx | 14 +- .../ui/slidesorter/inc/controller/SlsAnimator.hxx | 6 + .../ui/slidesorter/inc/controller/SlsClipboard.hxx | 7 + .../controller/SlsInsertionIndicatorHandler.hxx | 2 +- .../slidesorter/inc/controller/SlsPageSelector.hxx | 34 +-- .../inc/controller/SlsSelectionManager.hxx | 62 +---- .../inc/controller/SlsSelectionObserver.hxx | 78 ++++++ .../inc/controller/SlsVisibleAreaManager.hxx | 81 ++++++ .../ui/slidesorter/inc/model/SlideSorterModel.hxx | 23 ++ .../ui/slidesorter/inc/model/SlsPageDescriptor.hxx | 9 +- .../ui/slidesorter/inc/model/SlsVisualState.hxx | 2 +- .../ui/slidesorter/inc/view/SlsInsertAnimator.hxx | 9 +- sd/source/ui/slidesorter/inc/view/SlsResource.hrc | 50 ++++ sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 23 +- .../ui/slidesorter/model/SlideSorterModel.cxx | 228 ++++++++++++++-- .../ui/slidesorter/model/SlsPageDescriptor.cxx | 17 +- .../ui/slidesorter/shell/SlideSorterViewShell.cxx | 7 +- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 80 +++--- sd/source/ui/slidesorter/view/SlsIcons.hrc | 48 ---- sd/source/ui/slidesorter/view/SlsIcons.hxx | 51 ---- sd/source/ui/slidesorter/view/SlsIcons.src | 69 ----- .../ui/slidesorter/view/SlsInsertAnimator.cxx | 40 ++- .../view/SlsInsertionIndicatorOverlay.cxx | 25 +- sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 88 +++--- sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx | 2 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 76 ++++-- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 21 +- sd/source/ui/slidesorter/view/SlsResource.hxx | 51 ++++ sd/source/ui/slidesorter/view/SlsResource.src | 79 ++++++ sd/source/ui/slidesorter/view/SlsTheme.cxx | 47 +++- sd/source/ui/slidesorter/view/makefile.mk | 2 +- sd/source/ui/unoidl/SdUnoSlideView.cxx | 2 - 46 files changed, 1529 insertions(+), 885 deletions(-) create mode 100644 sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx create mode 100644 sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx create mode 100644 sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx create mode 100644 sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx create mode 100644 sd/source/ui/slidesorter/inc/view/SlsResource.hrc delete mode 100644 sd/source/ui/slidesorter/view/SlsIcons.hrc delete mode 100644 sd/source/ui/slidesorter/view/SlsIcons.hxx delete mode 100644 sd/source/ui/slidesorter/view/SlsIcons.src create mode 100644 sd/source/ui/slidesorter/view/SlsResource.hxx create mode 100644 sd/source/ui/slidesorter/view/SlsResource.src diff --git a/sd/source/core/drawdoc3.cxx b/sd/source/core/drawdoc3.cxx index 103a197d5a1f..025700a790fc 100644 --- a/sd/source/core/drawdoc3.cxx +++ b/sd/source/core/drawdoc3.cxx @@ -57,6 +57,7 @@ #include #include +#include #include "glob.hrc" #include "drawdoc.hxx" @@ -410,6 +411,20 @@ void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc delete pLayout; } +/** Just add one page to the container given to the constructor. +*/ +class InsertBookmarkAsPage_AddBookmarkedPages + : public SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase +{ +public: + InsertBookmarkAsPage_AddBookmarkedPages(::std::vector& rContainer) + : mrContainer(rContainer) {} + ~InsertBookmarkAsPage_AddBookmarkedPages(void) {} + void operator() (SdDrawDocument&, SdPage* pPage) { mrContainer.push_back(pPage); } +private: + ::std::vector& mrContainer; +}; + BOOL SdDrawDocument::InsertBookmarkAsPage( List* pBookmarkList, @@ -668,23 +683,24 @@ BOOL SdDrawDocument::InsertBookmarkAsPage( USHORT nActualInsertPos = nInsertPos; + // Collect the bookmarked pages. + ::std::vector aBookmarkedPages (pBookmarkList->Count(), NULL); for (USHORT nPos = 0; nPos < pBookmarkList->Count(); nPos++) { - /************************************************************** - * Namen der Bookmark-Seiten aus Liste holen - **************************************************************/ String aPgName(*(String*) pBookmarkList->GetObject(nPos)); BOOL bIsMasterPage; USHORT nBMPage = pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage ); if (nBMPage != SDRPAGE_NOTFOUND) { - pBMPage = (SdPage*) pBookmarkDoc->GetPage(nBMPage); - } - else - { - pBMPage = NULL; + aBookmarkedPages[nPos] = dynamic_cast(pBookmarkDoc->GetPage(nBMPage)); } + } + + for (USHORT nPos = 0; nPos < pBookmarkList->Count(); nPos++) + { + pBMPage = aBookmarkedPages[nPos]; + USHORT nBMPage = pBMPage!=NULL ? pBMPage->GetPageNum() : SDRPAGE_NOTFOUND; if (pBMPage && pBMPage->GetPageKind()==PK_STANDARD && !pBMPage->IsMasterPage()) { @@ -696,6 +712,8 @@ BOOL SdDrawDocument::InsertBookmarkAsPage( // #95991# delay renaming *after* pages are copied (might destroy source otherwise) // #67905# don't change name if source and dest model are the same! // #96029# avoid renaming if replacing the same page + String aPgName(*(String*) pBookmarkList->GetObject(nPos)); + BOOL bIsMasterPage; USHORT nPageSameName = GetPageByName(aPgName, bIsMasterPage); if( pBookmarkDoc != this && nPageSameName != SDRPAGE_NOTFOUND && @@ -705,7 +723,7 @@ BOOL SdDrawDocument::InsertBookmarkAsPage( bMustRename = sal_True; } - SdPage* pBookmarkPage = dynamic_cast< SdPage* >( pBookmarkDoc->GetPage(nBMPage) ); + SdPage* pBookmarkPage = pBMPage; if (bReplace ) { ReplacePageInCustomShows( dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ), pBookmarkPage ); diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index d35849819c05..6eae261ec1d2 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -44,6 +44,7 @@ #include "controller/SlsSelectionManager.hxx" #include "controller/SlsSlotManager.hxx" #include "controller/SlsTransferable.hxx" +#include "controller/SlsVisibleAreaManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageDescriptor.hxx" @@ -119,6 +120,7 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) mpSelectionManager(), mpInsertionIndicatorHandler(new InsertionIndicatorHandler(rSlideSorter)), mpAnimator(new Animator(rSlideSorter)), + mpVisibleAreaManager(new VisibleAreaManager(rSlideSorter)), mpListener(), mnModelChangeLockCount(0), mbPreModelChangeDone(false), @@ -205,7 +207,7 @@ SlideSorterController::~SlideSorterController (void) void SlideSorterController::Dispose (void) { - mpInsertionIndicatorHandler->End(); + mpInsertionIndicatorHandler->End(Animator::AM_Immediate); mpSelectionManager.reset(); mpAnimator->Dispose(); } @@ -345,9 +347,6 @@ void SlideSorterController::Paint ( try { - if (GetSelectionManager()->IsMakeSelectionVisiblePending()) - GetSelectionManager()->MakeSelectionVisible(); - mrView.CompleteRedraw(pWindow, Region(rBBox), 0); } catch (const Exception&) @@ -546,7 +545,6 @@ void SlideSorterController::PreModelChange (void) mrSlideSorter.GetViewShell()->Broadcast( ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START)); - mpPageSelector->PrepareModelChange(); GetCurrentSlideManager()->PrepareModelChange(); if (mrSlideSorter.GetContentWindow()) @@ -579,8 +577,6 @@ void SlideSorterController::PostModelChange (void) Rearrange(); } - mpPageSelector->HandleModelChange (); - if (mrSlideSorter.GetViewShell() != NULL) mrSlideSorter.GetViewShell()->Broadcast( ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END)); @@ -825,8 +821,8 @@ Rectangle SlideSorterController::Rearrange (bool bForce) // 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(); + // Keep the current slide in the visible area. + GetVisibleAreaManager().RequestVisible(GetCurrentSlideManager()->GetCurrentSlide()); } return aNewContentArea; @@ -1052,6 +1048,11 @@ void SlideSorterController::SetDocumentSlides (const ReferenceDeselectAllPages(); + mpPageSelector->SelectPage(mpCurrentSlideManager->GetCurrentSlide()); } } @@ -1066,6 +1067,15 @@ void SlideSorterController::SetDocumentSlides (const Reference #include #include +#include #include #include #include @@ -82,6 +85,43 @@ namespace sd { namespace slidesorter { namespace controller { +class Clipboard::UndoContext +{ +public: + UndoContext ( + SdDrawDocument* pDocument, + const ::boost::shared_ptr& rpMainViewShell, + const ::boost::shared_ptr& rpTheme) + : mpDocument(pDocument), + mpMainViewShell(rpMainViewShell) + { + if (mpDocument!=NULL && mpDocument->IsUndoEnabled()) + { + if (mpMainViewShell && mpMainViewShell->GetShellType() == ViewShell::ST_DRAW) + mpDocument->BegUndo(rpTheme->GetString(view::Theme::String_DragAndDropPages)); + else + mpDocument->BegUndo(rpTheme->GetString(view::Theme::String_DragAndDropSlides)); + } + } + + ~UndoContext (void) + { + if (mpDocument!=NULL && mpDocument->IsUndoEnabled()) + mpDocument->EndUndo(); + if (mpMainViewShell && mpMainViewShell->GetViewFrame()!=NULL) + { + SfxBindings& rBindings = mpMainViewShell->GetViewFrame()->GetBindings(); + rBindings.Invalidate(SID_UNDO); + rBindings.Invalidate(SID_REDO); + } + } +private: + SdDrawDocument* mpDocument; + ::boost::shared_ptr mpMainViewShell; +}; + + + Clipboard::Clipboard (SlideSorter& rSlideSorter) : ViewClipboard(rSlideSorter.GetView()), @@ -89,7 +129,8 @@ Clipboard::Clipboard (SlideSorter& rSlideSorter) mrController(mrSlideSorter.GetController()), maPagesToRemove(), maPagesToSelect(), - mbUpdateSelectionPending(false) + mbUpdateSelectionPending(false), + mpUndoContext() { } @@ -144,11 +185,11 @@ void Clipboard::HandleSlotCall (SfxRequest& rRequest) if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE) { view::SlideSorterView::DrawLock aLock (mrSlideSorter); + SelectionObserver::Context aContext (mrSlideSorter); if(xFunc.is()) xFunc->DoPaste(); else DoPaste(); - mrController.GetSelectionManager()->MakeSelectionVisible(); } rRequest.Done(); break; @@ -263,9 +304,9 @@ sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow) sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition) { SdTransferable* pClipTransferable = SD_MOD()->pTransferClip; - bool bMergeMasterPages = !pClipTransferable->HasSourceDoc ( - mrSlideSorter.GetModel().GetDocument()); - USHORT nInsertIndex ((USHORT)(nInsertPosition * 2 + 1)); + model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); + bool bMergeMasterPages = !pClipTransferable->HasSourceDoc (rModel.GetDocument()); + USHORT nInsertIndex (rModel.GetCoreIndex(nInsertPosition)); sal_Int32 nInsertPageCount (0); if (pClipTransferable->HasPageBookmarks()) { @@ -273,7 +314,7 @@ sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition) const ::vos::OGuard aGuard (Application::GetSolarMutex()); nInsertPageCount = (USHORT) rBookmarkList.Count(); - mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage( + rModel.GetDocument()->InsertBookmarkAsPage( const_cast(&rBookmarkList), NULL, FALSE, @@ -296,9 +337,9 @@ sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition) { const ::vos::OGuard aGuard (Application::GetSolarMutex()); - bMergeMasterPages = (pDataDoc != mrSlideSorter.GetModel().GetDocument()); + bMergeMasterPages = (pDataDoc != rModel.GetDocument()); nInsertPageCount = pDataDoc->GetSdPageCount( PK_STANDARD ); - mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage( + rModel.GetDocument()->InsertBookmarkAsPage( NULL, NULL, FALSE, @@ -496,9 +537,11 @@ void Clipboard::DragFinished (sal_Int8 nDropAction) } mrController.GetSelectionManager()->DeleteSelectedPages (); } + mpUndoContext.reset(); + mrSlideSorter.GetController().GetSelectionManager()->GetSelectionObserver()->EndObservation(); - if (nDropAction != DND_ACTION_NONE) - SelectPages(); + // if (nDropAction != DND_ACTION_NONE) + // SelectPages(); } @@ -592,6 +635,7 @@ sal_Int8 Clipboard::ExecuteDrop ( USHORT nLayer) { sal_Int8 nResult = DND_ACTION_NONE; + mpUndoContext.reset(); switch (IsDropAccepted()) { @@ -614,38 +658,34 @@ sal_Int8 Clipboard::ExecuteDrop ( rEvent.mnAction); USHORT nIndex = DetermineInsertPosition(*pDragTransferable); + // Tell the insertion indicator handler to hide before the model + // is modified. Doing it later may result in page objects whose + // animation state is not properly reset because they are then + // in another run then before the model change. + mrController.GetInsertionIndicatorHandler()->End(Animator::AM_Immediate); + if (bContinue) { SlideSorterController::ModelChangeLock aModelChangeLock (mrController); - if (pDragTransferable->GetView() == &mrSlideSorter.GetView() - && rEvent.mnAction == DND_ACTION_MOVE) - { - // We are asked to move pages inside one view. For this we - // call MoveSelectedPages() which is faster than going the - // generic way. - - // Remember to select the moved pages afterwards. - maPagesToRemove.swap(maPagesToSelect); - maPagesToRemove.clear(); - - USHORT nSdrModelIndex; - if (nIndex != SDRPAGE_NOTFOUND) - nSdrModelIndex = nIndex / 2 - 1; - else - nSdrModelIndex = SDRPAGE_NOTFOUND; - mrController.GetSelectionManager()->MoveSelectedPages(nSdrModelIndex); - mbUpdateSelectionPending = true; - nResult = DND_ACTION_NONE; - } - else - { - // Handle a general drop operation. - HandlePageDrop(*pDragTransferable); - nResult = rEvent.mnAction; - } + // Handle a general drop operation. + mpUndoContext.reset(new UndoContext ( + mrSlideSorter.GetModel().GetDocument(), + mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell(), + mrSlideSorter.GetTheme())); + mrSlideSorter.GetController().GetSelectionManager() + ->GetSelectionObserver()->StartObservation(); + + HandlePageDrop(*pDragTransferable); + nResult = rEvent.mnAction; + + // When moving or copying inside one view then leave the + // undo context active a little longer until + // NotifyDragFinished is called and possibly some slides are + // deleted. Otherwise all actions in the target view are + // complete and + // ( pDragTransferable->GetView() != &mrSlideSorter.GetView() ) } - mrController.GetInsertionIndicatorHandler()->End(); // Notify the receiving selection function that drag-and-drop is // finished and the substitution handler can be released. @@ -686,12 +726,11 @@ USHORT Clipboard::DetermineInsertPosition (const SdTransferable& ) sal_Int32 nInsertionIndex ( mrController.GetInsertionIndicatorHandler()->GetInsertionPageIndex()); - // The index returned by the overlay starts with 1 for the first slide. - // This is now converted that to an SdModel index that also starts with 1. + // Convert to insertion index to that of an SdModel. if (nInsertionIndex >= 0) - nInsertPosition = (USHORT)nInsertionIndex * 2 + 1; - - return nInsertPosition; + return mrSlideSorter.GetModel().GetCoreIndex(nInsertionIndex); + else + return 0; } @@ -707,14 +746,12 @@ USHORT Clipboard::InsertSlides ( // Remember the inserted pages so that they can be selected when the // operation is finished. - int nDocumentIndex = nInsertPosition / 2 - 1; - for (USHORT i=1; i<=nInsertedPageCount; i++) - { - model::SharedPageDescriptor pDescriptor ( - mrSlideSorter.GetModel().GetPageDescriptor(nDocumentIndex + i)); - if (pDescriptor.get() != NULL) - maPagesToSelect.push_back (pDescriptor->GetPage()); - } + maPagesToSelect.clear(); + SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument(); + if (pDocument != NULL) + for (sal_Int32 i=0; i<=nInsertedPageCount; i+=2) + maPagesToSelect.push_back( + dynamic_cast(pDocument->GetPage(nInsertPosition+i))); mbUpdateSelectionPending |= (nInsertedPageCount>0); @@ -780,8 +817,8 @@ sal_Int8 Clipboard::ExecuteOrAcceptShapeDrop ( model::SharedPageDescriptor pDescriptor ( mrSlideSorter.GetModel().GetPageDescriptor( mrSlideSorter.GetView().GetPageIndexAtPoint(rPosition))); - if (pDescriptor.get() != NULL && pDescriptor->GetPage()!=NULL) - nPage = (pDescriptor->GetPage()->GetPageNum() - 1) / 2; + if (pDescriptor) + nPage = pDescriptor->GetPageIndex(); } // Now comes the code that is different for the Execute and Accept: diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx index 4c8bd0158461..97d2a5e08881 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -192,7 +192,8 @@ void DragAndDropContext::SetTargetSlideSorter ( if (mpTargetSlideSorter != NULL) { mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll(); - mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End(); + mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End( + Animator::AM_Animated); } mpTargetSlideSorter = pSlideSorter; diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index e923edff47ec..8f3d5d05008a 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -31,8 +31,8 @@ #include "SlideSorter.hxx" #include "PaneDockingWindow.hxx" #include "controller/SlideSorterController.hxx" -#include "controller/SlsSelectionManager.hxx" #include "controller/SlsCurrentSlideManager.hxx" +#include "controller/SlsVisibleAreaManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" @@ -298,11 +298,8 @@ void FocusManager::ShowFocusIndicator ( { // Scroll the focused page object into the visible area and repaint // it, so that the focus indicator becomes visible. - mrSlideSorter.GetController().GetSelectionManager()->MakeRectangleVisible ( - mrSlideSorter.GetView().GetLayouter().GetPageObjectBox( - rpDescriptor->GetPageIndex(), true)); + mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor); } - mrSlideSorter.GetView().RequestRepaint(rpDescriptor); NotifyFocusChangeListeners(); diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index 68f4f1d6b0e3..d7e3f52a9b18 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -88,15 +88,15 @@ void InsertionIndicatorHandler::Start (const bool bIsOverSourceView) -void InsertionIndicatorHandler::End (void) +void InsertionIndicatorHandler::End (const controller::Animator::AnimationMode eMode) { if (mbIsForcedShow || ! mbIsActive || mbIsReadOnly) return; - GetInsertAnimator()->Reset(); + GetInsertAnimator()->Reset(eMode); mbIsActive = false; - maInsertPosition = view::InsertPosition(); + // maInsertPosition = view::InsertPosition(); meMode = UnknownMode; mpInsertionIndicatorOverlay->Hide(); @@ -116,7 +116,7 @@ void InsertionIndicatorHandler::ForceShow (void) void InsertionIndicatorHandler::ForceEnd (void) { mbIsForcedShow = false; - End(); + End(Animator::AM_Immediate); } @@ -219,7 +219,7 @@ void InsertionIndicatorHandler::SetPosition ( } else { - GetInsertAnimator()->Reset(); + GetInsertAnimator()->Reset(Animator::AM_Animated); mpInsertionIndicatorOverlay->Hide(); } } diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 3e303cde4f47..93bdb9aa43ce 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -35,6 +35,8 @@ #include "controller/SlideSorterController.hxx" #include "controller/SlsPageSelector.hxx" #include "controller/SlsCurrentSlideManager.hxx" +#include "controller/SlsSelectionManager.hxx" +#include "controller/SlsSelectionObserver.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "view/SlideSorterView.hxx" @@ -315,13 +317,23 @@ void Listener::Notify ( switch (rSdrHint.GetKind()) { case HINT_PAGEORDERCHG: - if (rBroadcaster.ISA(SdDrawDocument)) + if (&rBroadcaster == mrSlideSorter.GetModel().GetDocument()) { - SdDrawDocument& rDocument (static_cast(rBroadcaster)); - if (rDocument.GetMasterSdPageCount(PK_STANDARD) - == rDocument.GetMasterSdPageCount(PK_NOTES)) + // Notify model and selection observer about the page. + // The return value of the model call acts as filter as + // to which events to pass to the selection observer. + if (mrSlideSorter.GetModel().NotifyPageEvent(rSdrHint.GetPage())) + mrController.GetSelectionManager() + ->GetSelectionObserver()->NotifyPageEvent(rSdrHint.GetPage()); + + if (rBroadcaster.ISA(SdDrawDocument)) { - mrController.HandleModelChange(); + SdDrawDocument& rDocument (static_cast(rBroadcaster)); + if (rDocument.GetMasterSdPageCount(PK_STANDARD) + == rDocument.GetMasterSdPageCount(PK_NOTES)) + { + mrController.HandleModelChange(); + } } } break; diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index 2509c3d02fa8..ec76256b5e97 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -35,6 +35,7 @@ #include "controller/SlsSelectionManager.hxx" #include "controller/SlsAnimator.hxx" #include "controller/SlsCurrentSlideManager.hxx" +#include "controller/SlsVisibleAreaManager.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlideSorterModel.hxx" @@ -54,6 +55,23 @@ using namespace ::com::sun::star::uno; using namespace ::sd::slidesorter::model; using namespace ::sd::slidesorter::view; +namespace +{ +class BoolContext +{ +public: + BoolContext (bool& rValue, bool bContextValue) : mrValue(rValue),mbSavedValue(mrValue) + { mrValue = bContextValue; } + ~BoolContext (void) + { mrValue = mbSavedValue; } +private: + bool& mrValue; + const bool mbSavedValue; +}; + +} // end of anonymous namespace + + namespace sd { namespace slidesorter { namespace controller { @@ -68,7 +86,8 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter) mpSelectionAnchor(), mpCurrentPage(), mnUpdateLockCount(0), - mbIsUpdateCurrentPagePending(false) + mbIsUpdateCurrentPagePending(false), + mbIsMakeVisibleDisabled(false) { CountSelectedPages (); } @@ -79,10 +98,11 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter) void PageSelector::SelectAllPages (void) { PageSelector::UpdateLock aLock (*this); + BoolContext aContext (mbIsMakeVisibleDisabled, true); int nPageCount = mrModel.GetPageCount(); for (int nPageIndex=0; nPageIndexGetCoreSelection()) { + mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(pDescriptor); mrSlideSorter.GetView().RequestRepaint(pDescriptor); bSelectionHasChanged = true; } @@ -164,7 +186,7 @@ void PageSelector::SelectPage (int nPageIndex) void PageSelector::SelectPage (const SdPage* pPage) { - int nPageIndex = (pPage->GetPageNum()-1) / 2; + const sal_Int32 nPageIndex (mrModel.GetIndex(pPage)); SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); if (pDescriptor.get()!=NULL && pDescriptor->GetPage()==pPage) SelectPage(pDescriptor); @@ -179,6 +201,8 @@ void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor) && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, true)) { mnSelectedPageCount ++; + if ( ! mbIsMakeVisibleDisabled) + mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor); mrSlideSorter.GetView().RequestRepaint(rpDescriptor); mpMostRecentlySelectedPage = rpDescriptor; @@ -208,7 +232,7 @@ void PageSelector::DeselectPage (int nPageIndex) void PageSelector::DeselectPage (const SdPage* pPage) { - int nPageIndex = (pPage->GetPageNum()-1) / 2; + const sal_Int32 nPageIndex (mrModel.GetIndex(pPage)); SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex)); if (pDescriptor.get()!=NULL && pDescriptor->GetPage()==pPage) DeselectPage(pDescriptor); @@ -223,6 +247,8 @@ void PageSelector::DeselectPage (const SharedPageDescriptor& rpDescriptor) && mrSlideSorter.GetView().SetState(rpDescriptor, PageDescriptor::ST_Selected, false)) { mnSelectedPageCount --; + if ( ! mbIsMakeVisibleDisabled) + mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor); mrSlideSorter.GetView().RequestRepaint(rpDescriptor); if (mpMostRecentlySelectedPage == rpDescriptor) mpMostRecentlySelectedPage.reset(); @@ -265,38 +291,6 @@ int PageSelector::GetSelectedPageCount (void) const -void PageSelector::PrepareModelChange (void) -{ - DeselectAllPages (); -} - - - - -void PageSelector::HandleModelChange (void) -{ - GetCoreSelection(); -} - - - - -SharedPageDescriptor PageSelector::GetMostRecentlySelectedPage (void) const -{ - return mpMostRecentlySelectedPage; -} - - - - -void PageSelector::SetMostRecentlySelectedPage (const model::SharedPageDescriptor& rpDescriptor) -{ - mpMostRecentlySelectedPage = rpDescriptor; -} - - - - SharedPageDescriptor PageSelector::GetSelectionAnchor (void) const { return mpSelectionAnchor; @@ -320,13 +314,13 @@ void PageSelector::CountSelectedPages (void) -void PageSelector::EnableBroadcasting (bool bMakeSelectionVisible) +void PageSelector::EnableBroadcasting (void) { if (mnBroadcastDisableLevel > 0) mnBroadcastDisableLevel --; if (mnBroadcastDisableLevel==0 && mbSelectionChangeBroadcastPending) { - mrController.GetSelectionManager()->SelectionHasChanged(bMakeSelectionVisible); + mrController.GetSelectionManager()->SelectionHasChanged(); mbSelectionChangeBroadcastPending = false; } } @@ -396,19 +390,15 @@ void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending) if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected)) { // Switching the current slide normally sets also the selection - // to just the new current slide. To prevent that here we store - // and at the end of this scope restore the current selection. + // to just the new current slide. To prevent that, we store + // (and at the end of this scope restore) the current selection. ::boost::shared_ptr pSelection (GetPageSelection()); - SharedPageDescriptor pRecentSelection (GetMostRecentlySelectedPage()); mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); // Restore the selection and prevent a recursive call to // UpdateCurrentPage(). SetPageSelection(pSelection, false); - // Restore the most recently selected page. Important for - // making the right part of the selection visible. - mpMostRecentlySelectedPage = pRecentSelection; return; } } @@ -453,8 +443,7 @@ PageSelector::UpdateLock::~UpdateLock (void) //===== PageSelector::BroadcastLock ============================================== PageSelector::BroadcastLock::BroadcastLock (SlideSorter& rSlideSorter) - : mrSelector(rSlideSorter.GetController().GetPageSelector()), - mbIsMakeSelectionVisiblePending(false) + : mrSelector(rSlideSorter.GetController().GetPageSelector()) { mrSelector.DisableBroadcasting(); } @@ -473,17 +462,7 @@ PageSelector::BroadcastLock::BroadcastLock (PageSelector& rSelector) PageSelector::BroadcastLock::~BroadcastLock (void) { - mrSelector.EnableBroadcasting(mbIsMakeSelectionVisiblePending); + mrSelector.EnableBroadcasting(); } - - - -void PageSelector::BroadcastLock::RequestMakeSelectionVisible (void) -{ - mbIsMakeSelectionVisiblePending = true; -} - - - } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 85d10a7407fb..416f06a82616 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -356,6 +356,7 @@ void SelectionFunction::NotifyDragFinished (void) BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) { + view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); PageSelector::UpdateLock aLock (mrSlideSorter); FocusManager& rFocusManager (mrController.GetFocusManager()); BOOL bResult = FALSE; @@ -559,10 +560,6 @@ void SelectionFunction::MoveFocus ( rSelector.DeselectAllPages(); mrController.GetPageSelector().SelectPage(pFocusedDescriptor); } - - // Mark the currently focused page as last selected so that it is made - // visible on the next paint. - mrController.GetPageSelector().SetMostRecentlySelectedPage(pFocusedDescriptor); } @@ -961,9 +958,6 @@ bool SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor) } } - if (rDescriptor.mbMakeSelectionVisible) - aBroadcastLock.RequestMakeSelectionVisible(); - return bResult; } @@ -1181,7 +1175,7 @@ void SelectionFunction::PostProcessEvent (const EventDescriptor& rDescriptor) // Now turn them off. if ( ! mrController.IsContextMenuOpen()) - mrController.GetInsertionIndicatorHandler()->End(); + mrController.GetInsertionIndicatorHandler()->End(Animator::AM_Animated); mnButtonDownPageIndex = -1; mnButtonDownButtonIndex = -1; @@ -1293,7 +1287,7 @@ void SelectionFunction::StopDragAndDrop (void) mpDragAndDropContext.reset(); UpdateMouseOverIndicationPermission(); } - mrController.GetInsertionIndicatorHandler()->End(); + mrController.GetInsertionIndicatorHandler()->End(Animator::AM_Animated); } @@ -1561,9 +1555,6 @@ void SelectionFunction::MouseMultiSelector::UpdateSelection (void) UpdateSelectionState(pDescriptor, aRange.IsInside(nIndex)); } - - // Rely on auto scrolling to make page objects visible. - mrSlideSorter.GetController().GetSelectionManager()->ResetMakeSelectionVisiblePending(); } } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx index 5ff0e034d816..8e8a97713666 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx @@ -30,15 +30,17 @@ #include "controller/SlsSelectionManager.hxx" #include "SlideSorter.hxx" -#include "SlsSelectionCommand.hxx" +#include "SlsCommand.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsAnimator.hxx" #include "controller/SlsAnimationFunction.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "controller/SlsFocusManager.hxx" +#include "controller/SlsPageSelector.hxx" #include "controller/SlsProperties.hxx" #include "controller/SlsScrollBarManager.hxx" #include "controller/SlsSlotManager.hxx" +#include "controller/SlsSelectionObserver.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageDescriptor.hxx" @@ -67,24 +69,12 @@ using namespace ::sd::slidesorter::controller; namespace sd { namespace slidesorter { namespace controller { -namespace { - class VisibleAreaScroller - { - public: - VisibleAreaScroller ( - SlideSorter& rSlideSorter, - const Point aStart, - const Point aEnd); - void operator() (const double nValue); - private: - SlideSorter& mrSlideSorter; - Point maStart; - const Point maEnd; - const ::boost::function maAccelerationFunction; - }; -} - +class SelectionManager::PageInsertionListener + : public SfxListener +{ +public: +}; SelectionManager::SelectionManager (SlideSorter& rSlideSorter) @@ -94,7 +84,9 @@ SelectionManager::SelectionManager (SlideSorter& rSlideSorter) mbIsMakeSelectionVisiblePending(true), mnInsertionPosition(-1), mnAnimationId(Animator::NotAnAnimationId), - maRequestedTopLeft() + maRequestedTopLeft(), + mpPageInsertionListener(), + mpSelectionObserver(new SelectionObserver(rSlideSorter)) { } @@ -196,7 +188,7 @@ void SelectionManager::DeleteSelectedNormalPages (const ::std::vector& if (xPages->getCount() <= 1) break; - USHORT nPage = ((*aI)->GetPageNum()-1) / 2; + const USHORT nPage (model::FromCoreIndex((*aI)->GetPageNum())); Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW ); xPages->remove(xPage); @@ -232,7 +224,7 @@ void SelectionManager::DeleteSelectedMasterPages (const ::std::vector& if (xPages->getCount() <= 1) break; - USHORT nPage = ((*aI)->GetPageNum()-1) / 2; + const USHORT nPage (model::FromCoreIndex((*aI)->GetPageNum())); Reference< XDrawPage > xPage( xPages->getByIndex( nPage ), UNO_QUERY_THROW ); xPages->remove(xPage); @@ -247,58 +239,6 @@ void SelectionManager::DeleteSelectedMasterPages (const ::std::vector& -bool SelectionManager::MoveSelectedPages (const sal_Int32 nTargetPageIndex) -{ - bool bMoved (false); - PageSelector& rSelector (mrController.GetPageSelector()); - - view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); - SlideSorterController::ModelChangeLock aLock (mrController); - - // Transfer selection of the slide sorter to the document. - mrSlideSorter.GetModel().SynchronizeDocumentSelection (); - - // Detect how many pages lie between document start and insertion - // position. - sal_Int32 nPageCountBeforeTarget (0); - ::boost::shared_ptr pSelection (rSelector.GetPageSelection()); - PageSelector::PageSelection::const_iterator iSelectedPage (pSelection->begin()); - PageSelector::PageSelection::const_iterator iSelectionEnd (pSelection->end()); - for ( ; iSelectedPage!=iSelectionEnd; ++iSelectedPage) - { - if (*iSelectedPage==NULL) - continue; - if (((*iSelectedPage)->GetPageNum()-1)/2 <= nTargetPageIndex) - ++nPageCountBeforeTarget; - else - break; - } - - // Prepare to select the moved pages. - SelectionCommand* pCommand = new SelectionCommand( - rSelector,mrController.GetCurrentSlideManager(),mrSlideSorter.GetModel()); - sal_Int32 nSelectedPageCount (rSelector.GetSelectedPageCount()); - for (sal_Int32 nOffset=0; nOffsetAddSlide(sal::static_int_cast( - nTargetPageIndex + nOffset - nPageCountBeforeTarget + 1)); - - // At the moment we can not move master pages. - if (nTargetPageIndex>=0) - { - if (mrSlideSorter.GetModel().GetEditMode() == EM_PAGE) - bMoved = mrSlideSorter.GetModel().GetDocument()->MovePages( - sal::static_int_cast(nTargetPageIndex)); - } - if (bMoved) - mrController.GetSlotManager()->ExecuteCommandAsynchronously( - ::std::auto_ptr(pCommand)); - - return bMoved; -} - - - - void SelectionManager::SelectionHasChanged (const bool bMakeSelectionVisible) { if (bMakeSelectionVisible) @@ -340,173 +280,6 @@ void SelectionManager::SelectionHasChanged (const bool bMakeSelectionVisible) -bool SelectionManager::IsMakeSelectionVisiblePending (void) const -{ - return mbIsMakeSelectionVisiblePending; -} - - - - -void SelectionManager::ResetMakeSelectionVisiblePending (void) -{ - mbIsMakeSelectionVisiblePending = false; -} - - - - -/** We have to distinguish three cases: 1) the selection is empty, 2) the - selection fits completely into the visible area, 3) it does not. - 1) The visible area is not modified. - 2) When the selection fits completely into the visible area we have to - decide how to align it. It is done by scrolling it there and thus when - we scoll up the (towards the end of the document) the bottom of the - selection is aligned with the bottom of the window. When we scroll - down (towards the beginning of the document) the top of the selection is - aligned with the top of the window. - 3) We have to decide what part of the selection to make visible. Here - we use the eSelectionHint and concentrate on either the first, the last, - or the most recently selected page. We then again apply the algorithm - of a). - -*/ -Size SelectionManager::MakeSelectionVisible (const SelectionHint eSelectionHint) -{ - SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - if (pWindow == NULL) - return Size(0,0); - - mbIsMakeSelectionVisiblePending = false; - - // Determine the descriptors of the first and last selected page and the - // bounding box that encloses their page objects. - model::SharedPageDescriptor pFirst; - model::SharedPageDescriptor pLast; - Rectangle aSelectionBox; - const view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); - model::PageEnumeration aSelectedPages ( - PageEnumerationProvider::CreateSelectedPagesEnumeration(mrSlideSorter.GetModel())); - while (aSelectedPages.HasMoreElements()) - { - model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); - - if (pFirst.get() == NULL) - pFirst = pDescriptor; - pLast = pDescriptor; - - aSelectionBox.Union(rLayouter.GetPageObjectBox(pDescriptor->GetPageIndex(), true)); - } - - if (pFirst != NULL) - { - // Determine scroll direction and the position in model coordinates - // that will be aligned with the top/left or bottom/right window - // border. - if (DoesSelectionExceedVisibleArea(aSelectionBox)) - { - // We can show only a part of the selection. - aSelectionBox = ResolveLargeSelection(pFirst,pLast, eSelectionHint); - } - - return MakeRectangleVisible(aSelectionBox); - } - - return Size(0,0); -} - - - - -Size SelectionManager::MakeRectangleVisible (const Rectangle& rBox) -{ - SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - if (pWindow == NULL) - return Size(0,0); - - Rectangle aVisibleArea (pWindow->PixelToLogic( - Rectangle( - Point(0,0), - pWindow->GetOutputSizePixel()))); - - sal_Int32 nNewTop (aVisibleArea.Top()); - sal_Int32 nNewLeft (aVisibleArea.Left()); - - if (mrSlideSorter.GetView().GetOrientation() != Layouter::HORIZONTAL) - { - // Scroll the visible area to make aSelectionBox visible. - if (mrSlideSorter.GetProperties()->IsCenterSelection()) - { - nNewTop = rBox.Top() - (aVisibleArea.GetHeight() - rBox.GetHeight()) / 2; - } - else - { - if (rBox.Top() < aVisibleArea.Top()) - nNewTop = rBox.Top(); - else if (rBox.Bottom() > aVisibleArea.Bottom()) - nNewTop = rBox.Bottom() - aVisibleArea.GetHeight(); - // otherwise we do not modify the visible area. - } - - // Make some corrections of the new visible area. - Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); - if (nNewTop + aVisibleArea.GetHeight() > aModelArea.Bottom()) - nNewTop = aModelArea.GetHeight() - aVisibleArea.GetHeight(); - if (nNewTop < aModelArea.Top()) - nNewTop = aModelArea.Top(); - - } - - if (mrSlideSorter.GetView().GetOrientation() != Layouter::VERTICAL) - { - // Scroll the visible area to make aSelectionBox visible. - if (mrSlideSorter.GetProperties()->IsCenterSelection()) - { - nNewLeft = rBox.Left() - (aVisibleArea.GetWidth() - rBox.GetWidth()) / 2; - } - else - { - if (rBox.Left() < aVisibleArea.Left()) - nNewLeft = rBox.Left(); - else if (rBox.Right() > aVisibleArea.Right()) - nNewLeft = rBox.Right() - aVisibleArea.GetWidth(); - // otherwise we do not modify the visible area. - } - - // Make some corrections of the new visible area. - Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); - if (nNewLeft + aVisibleArea.GetWidth() > aModelArea.Right()) - nNewLeft = aModelArea.GetWidth() - aVisibleArea.GetWidth(); - if (nNewLeft < aModelArea.Left()) - nNewLeft = aModelArea.Left(); - } - - // Scroll when the visible area is not already at the requested location - // and there is no active animation to scroll to it. - if ((nNewTop != aVisibleArea.Top() || nNewLeft != aVisibleArea.Left()) - && (mnAnimationId==Animator::NotAnAnimationId - || maRequestedTopLeft != Point(nNewLeft,nNewTop))) - { - if (mnAnimationId != Animator::NotAnAnimationId) - mrController.GetAnimator()->RemoveAnimation(mnAnimationId); - - maRequestedTopLeft = Point(nNewLeft, nNewTop); - VisibleAreaScroller aAnimation( - mrSlideSorter, - aVisibleArea.TopLeft(), - maRequestedTopLeft); - if (mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) - mnAnimationId = mrController.GetAnimator()->AddAnimation(aAnimation, 0, 300); - else - aAnimation(1.0); - } - - return Size(aVisibleArea.Left() - nNewLeft, aVisibleArea.Top() - nNewTop); -} - - - - void SelectionManager::AddSelectionChangeListener (const Link& rListener) { if (::std::find ( @@ -531,7 +304,7 @@ void SelectionManager::RemoveSelectionChangeListener(const Link&rListener) } - +/* bool SelectionManager::DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const { @@ -593,7 +366,7 @@ Rectangle SelectionManager::ResolveLargeSelection ( true); } - +*/ sal_Int32 SelectionManager::GetInsertionPosition (void) const @@ -612,7 +385,7 @@ sal_Int32 SelectionManager::GetInsertionPosition (void) const const sal_Int32 nPosition (aSelectedPages.GetNextElement()->GetPage()->GetPageNum()); // Convert *2+1 index to straight index (n-1)/2 after the page // (+1). - nInsertionPosition = (nPosition-1)/2 + 1; + nInsertionPosition = model::FromCoreIndex(nPosition) + 1; } } @@ -639,50 +412,9 @@ void SelectionManager::SetInsertionPosition (const sal_Int32 nInsertionPosition) -//===== VerticalVisibleAreaScroller =========================================== - -namespace { - -const static sal_Int32 gnMaxScrollDistance = 300; - -VisibleAreaScroller::VisibleAreaScroller ( - SlideSorter& rSlideSorter, - const Point aStart, - const Point aEnd) - : mrSlideSorter(rSlideSorter), - maStart(aStart), - maEnd(aEnd), - maAccelerationFunction( - controller::AnimationParametricFunction( - controller::AnimationBezierFunction (0.1,0.6))) +::boost::shared_ptr SelectionManager::GetSelectionObserver (void) const { - // 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(aStart.X()-aEnd.X()) > gnMaxScrollDistance) - if (aStart.X() < aEnd.X()) - maStart.X() = aEnd.X()-gnMaxScrollDistance; - else - maStart.X() = aEnd.X()+gnMaxScrollDistance; - if (abs(aStart.Y()-aEnd.Y()) > gnMaxScrollDistance) - if (aStart.Y() < aEnd.Y()) - maStart.Y() = aEnd.Y()-gnMaxScrollDistance; - else - maStart.Y() = aEnd.Y()+gnMaxScrollDistance; + return mpSelectionObserver; } - - - -void VisibleAreaScroller::operator() (const double nTime) -{ - const double nLocalTime (maAccelerationFunction(nTime)); - mrSlideSorter.GetController().GetScrollBarManager().SetTopLeft( - Point( - sal_Int32(0.5 + maStart.X() * (1.0 - nLocalTime) + maEnd.X() * nLocalTime), - sal_Int32 (0.5 + maStart.Y() * (1.0 - nLocalTime) + maEnd.Y() * nLocalTime))); -} - -} // end of anonymous namespace - } } } // end of namespace ::sd::slidesorter diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx new file mode 100644 index 000000000000..91edc092016f --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 "SlideSorter.hxx" +#include "controller/SlideSorterController.hxx" +#include "controller/SlsSelectionManager.hxx" +#include "controller/SlsSelectionObserver.hxx" +#include "controller/SlsPageSelector.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageDescriptor.hxx" +#include +#include "drawdoc.hxx" + + +namespace sd { namespace slidesorter { namespace controller { + +SelectionObserver::Context::Context (SlideSorter& rSlideSorter) + : mpSelectionObserver( + rSlideSorter.GetController().GetSelectionManager()->GetSelectionObserver()) +{ + if (mpSelectionObserver) + mpSelectionObserver->StartObservation(); +} + + + + +SelectionObserver::Context::~Context(void) +{ + if (mpSelectionObserver) + mpSelectionObserver->EndObservation(); +} + + + + +//===== SelectionObserver ===================================================== + +SelectionObserver::SelectionObserver (SlideSorter& rSlideSorter) + : mrSlideSorter(rSlideSorter), + mpDocument(mrSlideSorter.GetModel().GetDocument()), + mbIsOvservationActive(false), + maInsertedPages(), + maDeletedPages() +{ +} + + + + +SelectionObserver::~SelectionObserver (void) +{ +} + + + + +void SelectionObserver::NotifyPageEvent (const SdrPage* pSdrPage) +{ + if ( ! mbIsOvservationActive) + return; + + const SdPage* pPage = dynamic_cast(pSdrPage); + if (pPage == NULL) + return; + + if (pPage->IsInserted()) + maInsertedPages.push_back(pPage); + else + { + ::std::vector::iterator iPage( + ::std::find(maInsertedPages.begin(), maInsertedPages.end(), pPage)); + if (iPage != maInsertedPages.end()) + maInsertedPages.erase(iPage); + + maDeletedPages.push_back(pPage->GetPageNum()); + } +} + + + +void SelectionObserver::StartObservation (void) +{ + OSL_ASSERT(!mbIsOvservationActive); + maInsertedPages.clear(); + maDeletedPages.clear(); + mbIsOvservationActive = true; +} + + + + +void SelectionObserver::EndObservation (void) +{ + OSL_ASSERT(mbIsOvservationActive); + mbIsOvservationActive = false; + + model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); + PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); + rSelector.DeselectAllPages(); + if ( ! maInsertedPages.empty()) + { + // Select the inserted pages. + for (::std::vector::const_iterator + iPage(maInsertedPages.begin()), + iEnd(maInsertedPages.end()); + iPage!=iEnd; + ++iPage) + { + rSelector.SelectPage(*iPage); + /* + const sal_Int32 nIndex (rModel.GetIndex (*iPage)); + model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); + if (pDescriptor) + pDescriptor->SetState(model::PageDescriptor::ST_Selected, + true); + */ + } + maInsertedPages.clear(); + } + maDeletedPages.clear(); +} + + + +} } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 36c0e2494491..1a2410f1eb64 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -40,6 +40,7 @@ #include "controller/SlsPageSelector.hxx" #include "controller/SlsSelectionFunction.hxx" #include "controller/SlsSelectionManager.hxx" +#include "controller/SlsSelectionObserver.hxx" #include "SlsCommand.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" @@ -184,7 +185,6 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_SELECTALL: mrSlideSorter.GetController().GetPageSelector().SelectAllPages(); - mrSlideSorter.GetController().GetSelectionManager()->ResetMakeSelectionVisiblePending(); rRequest.Done(); break; @@ -399,7 +399,10 @@ void SlotManager::FuSupport (SfxRequest& rRequest) SlideSorterViewShell* pViewShell = dynamic_cast(mrSlideSorter.GetViewShell()); if (pViewShell != NULL) + { + SelectionObserver::Context aContext (mrSlideSorter); pViewShell->ImpSidUndo (FALSE, rRequest); + } break; } @@ -408,7 +411,10 @@ void SlotManager::FuSupport (SfxRequest& rRequest) SlideSorterViewShell* pViewShell = dynamic_cast(mrSlideSorter.GetViewShell()); if (pViewShell != NULL) + { + SelectionObserver::Context aContext (mrSlideSorter); pViewShell->ImpSidRedo (FALSE, rRequest); + } break; } diff --git a/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx b/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx new file mode 100644 index 000000000000..c683c5e0a2c4 --- /dev/null +++ b/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx @@ -0,0 +1,254 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 "controller/SlsVisibleAreaManager.hxx" +#include "controller/SlideSorterController.hxx" +#include "controller/SlsProperties.hxx" +#include "controller/SlsAnimationFunction.hxx" +#include "controller/SlsScrollBarManager.hxx" + + +namespace sd { namespace slidesorter { namespace controller { + +namespace { + class VisibleAreaScroller + { + public: + VisibleAreaScroller ( + SlideSorter& rSlideSorter, + const Point aStart, + const Point aEnd); + void operator() (const double nValue); + private: + SlideSorter& mrSlideSorter; + Point maStart; + const Point maEnd; + const ::boost::function maAccelerationFunction; + }; + +} // end of anonymous namespace + + + +VisibleAreaManager::VisibleAreaManager (SlideSorter& rSlideSorter) + : mrSlideSorter(rSlideSorter), + maVisibleRequests(), + mnScrollAnimationId(Animator::NotAnAnimationId), + maRequestedVisibleTopLeft(), + meRequestedAnimationMode(Animator::AM_Immediate) +{ +} + + + + +VisibleAreaManager::~VisibleAreaManager (void) +{ +} + + + + +void VisibleAreaManager::RequestVisible ( + const model::SharedPageDescriptor& rpDescriptor, + const Animator::AnimationMode eRequestedAnimationMode) +{ + if (rpDescriptor) + { + maVisibleRequests.push_back( + mrSlideSorter.GetView().GetLayouter().GetPageObjectBox( + rpDescriptor->GetPageIndex(), + true)); + if (eRequestedAnimationMode == Animator::AM_Animated) + meRequestedAnimationMode = Animator::AM_Animated; + MakeVisible(); + } +} + + + + +void VisibleAreaManager::MakeVisible (void) +{ + if (maVisibleRequests.empty()) + return; + + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if ( ! pWindow) + return; + const Point aCurrentTopLeft (pWindow->PixelToLogic(Point(0,0))); + + const ::boost::optional aNewVisibleTopLeft (GetRequestedTopLeft()); + maVisibleRequests.clear(); + if ( ! aNewVisibleTopLeft) + return; + + // We now know what the visible area shall be. Scroll accordingly + // unless that is not already the visible area or a running scroll + // animation has it as its target area. + if (mnScrollAnimationId!=Animator::NotAnAnimationId + && maRequestedVisibleTopLeft==aNewVisibleTopLeft) + return; + + // Stop a running animation. + if (mnScrollAnimationId != Animator::NotAnAnimationId) + mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(mnScrollAnimationId); + + maRequestedVisibleTopLeft = aNewVisibleTopLeft.get(); + VisibleAreaScroller aAnimation( + mrSlideSorter, + aCurrentTopLeft, + maRequestedVisibleTopLeft); + if (meRequestedAnimationMode==Animator::AM_Animated + && mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling()) + { + mnScrollAnimationId = mrSlideSorter.GetController().GetAnimator()->AddAnimation( + aAnimation, + 0, + 300); + } + else + { + // Execute the animation at its final value. + aAnimation(1.0); + } + meRequestedAnimationMode = Animator::AM_Immediate; +} + + + + +::boost::optional VisibleAreaManager::GetRequestedTopLeft (void) const +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if ( ! pWindow) + return ::boost::optional(); + + // Get the currently visible area and the model area. + const Rectangle aVisibleArea (pWindow->PixelToLogic( + Rectangle( + Point(0,0), + pWindow->GetOutputSizePixel()))); + const Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); + + sal_Int32 nVisibleTop (aVisibleArea.Top()); + const sal_Int32 nVisibleWidth (aVisibleArea.GetWidth()); + sal_Int32 nVisibleLeft (aVisibleArea.Left()); + const sal_Int32 nVisibleHeight (aVisibleArea.GetHeight()); + + // Find the longest run of boxes whose union fits into the visible area. + Rectangle aBoundingBox; + for (::std::vector::const_iterator + iBox(maVisibleRequests.begin()), + iEnd(maVisibleRequests.end()); + iBox!=iEnd; + ++iBox) + { + if (nVisibleTop+nVisibleHeight <= iBox->Bottom()) + nVisibleTop = iBox->Bottom()-nVisibleHeight; + if (nVisibleTop > iBox->Top()) + nVisibleTop = iBox->Top(); + + if (nVisibleLeft+nVisibleWidth <= iBox->Right()) + nVisibleLeft = iBox->Right()-nVisibleWidth; + if (nVisibleLeft > iBox->Left()) + nVisibleLeft = iBox->Left(); + + // Make sure the visible area does not move outside the model area. + if (nVisibleTop + nVisibleHeight > aModelArea.Bottom()) + nVisibleTop = aModelArea.Bottom() - nVisibleHeight; + if (nVisibleTop < aModelArea.Top()) + nVisibleTop = aModelArea.Top(); + + if (nVisibleLeft + nVisibleWidth > aModelArea.Right()) + nVisibleLeft = aModelArea.Right() - nVisibleWidth; + if (nVisibleLeft < aModelArea.Left()) + nVisibleLeft = aModelArea.Left(); + } + + const Point aRequestedTopLeft (nVisibleLeft, nVisibleTop); + if (aRequestedTopLeft == aVisibleArea.TopLeft()) + return ::boost::optional(); + else + return ::boost::optional(aRequestedTopLeft); +} + + + + + + + +//===== VerticalVisibleAreaScroller =========================================== + +namespace { + +const static sal_Int32 gnMaxScrollDistance = 300; + +VisibleAreaScroller::VisibleAreaScroller ( + SlideSorter& rSlideSorter, + const Point aStart, + const Point aEnd) + : mrSlideSorter(rSlideSorter), + maStart(aStart), + maEnd(aEnd), + maAccelerationFunction( + 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(aStart.X()-aEnd.X()) > gnMaxScrollDistance) + if (aStart.X() < aEnd.X()) + maStart.X() = aEnd.X()-gnMaxScrollDistance; + else + maStart.X() = aEnd.X()+gnMaxScrollDistance; + if (abs(aStart.Y()-aEnd.Y()) > gnMaxScrollDistance) + if (aStart.Y() < aEnd.Y()) + maStart.Y() = aEnd.Y()-gnMaxScrollDistance; + else + maStart.Y() = aEnd.Y()+gnMaxScrollDistance; +} + + + + +void VisibleAreaScroller::operator() (const double nTime) +{ + const double nLocalTime (maAccelerationFunction(nTime)); + mrSlideSorter.GetController().GetScrollBarManager().SetTopLeft( + Point( + sal_Int32(0.5 + maStart.X() * (1.0 - nLocalTime) + maEnd.X() * nLocalTime), + sal_Int32 (0.5 + maStart.Y() * (1.0 - nLocalTime) + maEnd.Y() * nLocalTime))); +} + +} // end of anonymous namespace + +} } } // 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 89646e38ef5d..460ef16ed3f1 100644 --- a/sd/source/ui/slidesorter/controller/makefile.mk +++ b/sd/source/ui/slidesorter/controller/makefile.mk @@ -58,8 +58,10 @@ SLOFILES = \ $(SLO)$/SlsSelectionCommand.obj \ $(SLO)$/SlsSelectionFunction.obj \ $(SLO)$/SlsSelectionManager.obj \ + $(SLO)$/SlsSelectionObserver.obj \ $(SLO)$/SlsSlotManager.obj \ - $(SLO)$/SlsTransferable.obj + $(SLO)$/SlsTransferable.obj \ + $(SLO)$/SlsVisibleAreaManager.obj # --- Tagets ------------------------------------------------------- diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index 71b2073011aa..b72120e9fcb9 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -37,7 +37,6 @@ #include #include #include -#include #include namespace sd { namespace slidesorter { @@ -67,7 +66,9 @@ class PageSelector; class ScrollBarManager; class SelectionFunction; class SelectionManager; +class SelectionObserver; class SlotManager; +class VisibleAreaManager; class SlideSorterController { @@ -249,21 +250,24 @@ public: */ ::boost::shared_ptr GetAnimator (void) const; + VisibleAreaManager& GetVisibleAreaManager (void) const; + void CheckForMasterPageAssignment (void); private: SlideSorter& mrSlideSorter; model::SlideSorterModel& mrModel; view::SlideSorterView& mrView; - ::std::auto_ptr mpPageSelector; - ::std::auto_ptr mpFocusManager; + ::boost::scoped_ptr mpPageSelector; + ::boost::scoped_ptr mpFocusManager; ::boost::shared_ptr mpSlotManager; - ::std::auto_ptr mpClipboard; - ::std::auto_ptr mpScrollBarManager; + ::boost::scoped_ptr mpClipboard; + ::boost::scoped_ptr mpScrollBarManager; mutable ::boost::shared_ptr mpCurrentSlideManager; ::boost::shared_ptr mpSelectionManager; ::boost::shared_ptr mpInsertionIndicatorHandler; ::boost::shared_ptr mpAnimator; + ::boost::scoped_ptr mpVisibleAreaManager; // The listener listens to UNO events and thus is a UNO object. // For proper life time management and at the same time free access to diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx index a82e4b1d1773..2d8418e49631 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx @@ -48,6 +48,12 @@ class Animator : private ::boost::noncopyable { public: + /** In some circumstances we have to avoid animation and jump to the + final animation state immediately. Use this enum instead of a bool + to be more expressive. + */ + enum AnimationMode { AM_Animated, AM_Immediate }; + Animator (SlideSorter& rSlideSorter); ~Animator (void); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx index 0bdbd7cb569f..536684be5dc3 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx @@ -24,6 +24,7 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef SD_SLIDESORTER_CLIPBOARD #define SD_SLIDESORTER_CLIPBOARD @@ -127,6 +128,12 @@ private: */ bool mbUpdateSelectionPending; + /** Used when a drop is executed to combine all undo actions into one. + Typically created in ExecuteDrop() and released in DragFinish(). + */ + class UndoContext; + ::boost::scoped_ptr mpUndoContext; + void CreateSlideTransferable ( ::Window* pWindow, bool bDrag); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx index 73f11e3e0e32..3945225baf8b 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -68,7 +68,7 @@ public: /** Deactivate the insertion marker. */ - void End (void); + void End (const controller::Animator::AnimationMode eMode); class ForceShowContext { diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index 1d5b17eb5bca..c2d221c62bd5 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -81,10 +81,17 @@ public: */ void SetCoreSelection (void); + /** Select the specified descriptor. The selection state of the other + descriptors is not affected. + */ void SelectPage (int nPageIndex); - /** Select the descriptor that is associated with the given page. + /** Select the descriptor that is associated with the given page. The + selection state of the other descriptors is not affected. */ void SelectPage (const SdPage* pPage); + /** Select the specified descriptor. The selection state of the other + descriptors is not affected. + */ void SelectPage (const model::SharedPageDescriptor& rpDescriptor); /** Return whether the specified page is selected. This convenience @@ -108,26 +115,6 @@ public: int GetPageCount (void) const; int GetSelectedPageCount (void) const; - void PrepareModelChange (void); - void HandleModelChange (void); - - /** Return the descriptor of the most recently selected page. This - works only when the page has not been de-selected in the mean time. - This method helps the view when it scrolls the selection into the - visible area. - @return - When the selection is empty or when the most recently selected - page has been deselected already (but other pages are still - selected) then NULL is returned, even when a selection did exist - but has been cleared. - */ - model::SharedPageDescriptor GetMostRecentlySelectedPage (void) const; - - /** Mark the given page as the most recently selected. Use this method - when the selection does not really change but the focus does. - */ - void SetMostRecentlySelectedPage (const model::SharedPageDescriptor& rpDescriptor); - /** Return the anchor for a range selection. This usually is the first selected page after all pages have been deselected. @return @@ -185,10 +172,8 @@ public: BroadcastLock (SlideSorter& rSlideSorter); BroadcastLock (PageSelector& rPageSelector); ~BroadcastLock (void); - void RequestMakeSelectionVisible (void); private: PageSelector& mrSelector; - bool mbIsMakeSelectionVisiblePending; }; private: @@ -204,6 +189,7 @@ private: model::SharedPageDescriptor mpCurrentPage; sal_Int32 mnUpdateLockCount; bool mbIsUpdateCurrentPagePending; + bool mbIsMakeVisibleDisabled; /** Enable the broadcasting of selection change events. This calls the SlideSorterController::SelectionHasChanged() method to do the actual @@ -211,7 +197,7 @@ private: DisableBroadcasting() was called before and the selection has been changed in the mean time, this change will be broadcasted. */ - void EnableBroadcasting (bool bMakeSelectionVisible = true); + void EnableBroadcasting (void); /** Disable the broadcasting o selectio change events. Subsequent changes of the selection will set a flag that triggers the sending diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx index 8810107f28db..74f5b4dece95 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx @@ -45,6 +45,7 @@ class SlideSorter; namespace sd { namespace slidesorter { namespace controller { class SlideSorterController; +class SelectionObserver; /** This class is a part of the controller and handles the selection of slides. @@ -72,56 +73,12 @@ public: */ void DeleteSelectedPages (const bool bSelectFollowingPage = true); - /** Move the maked pages to a position directly after the specified page. - */ - bool MoveSelectedPages (const sal_Int32 nTargetPage); - /** Call this method after the selection has changed (possible several calls to the PageSelector) to invalidate the relevant slots and send appropriate events. */ void SelectionHasChanged (const bool bMakeSelectionVisible = true); - /** Return when the selection has changed but has not yet been - moved to the visible area of the slide sorter view. - */ - bool IsMakeSelectionVisiblePending (void) const; - - /** Reset any request to make the set of selected pages visible. - */ - void ResetMakeSelectionVisiblePending (void); - - enum SelectionHint { SH_FIRST, SH_LAST, SH_RECENT }; - - /** Try to make all currently selected page objects visible, i.e. set - the origin so that the page objects lie inside the visible area. - When the selection is empty then the visible area is not modified. - -

This method, and the ones is calls, look into the Properties - object of the SlideSorter in order to determine whether the current - selection is to be displayed centered.

- @param eSelectionHint - This is an advice on which selected page object to handle with - the highest priority when the whole selection does not fit into - the visible area. - @return - Returns the vertical translation of the visible area. It is 0 - when no update of the visible area was done. - */ - Size MakeSelectionVisible ( - const SelectionHint eSelectionHint = SH_RECENT); - - /** Modify the origin of the visible area so that the given rectangle - comes into view. This is done with the smallest change: no - scrolling takes place when the given rectangle already lies in the - visible area. Otherwise either the top or the bottom of the given - rectangle is aligned with the top or the bottom of the visible area. - @return - Returns the vertical translation of the visible area. It is 0 - when no update of the visible area was done. - */ - Size MakeRectangleVisible (const Rectangle& rBox); - /** Add a listener that is called when the selection of the slide sorter changes. @param rListener @@ -154,6 +111,8 @@ public: */ void SetInsertionPosition (const sal_Int32 nInsertionPosition); + ::boost::shared_ptr GetSelectionObserver (void) const; + private: SlideSorter& mrSlideSorter; SlideSorterController& mrController; @@ -183,6 +142,11 @@ private: Animator::AnimationId mnAnimationId; Point maRequestedTopLeft; + class PageInsertionListener; + ::boost::scoped_ptr mpPageInsertionListener; + + ::boost::shared_ptr mpSelectionObserver; + /** Delete the given list of normal pages. This method is a helper function for DeleteSelectedPages(). @param rSelectedNormalPages @@ -201,7 +165,7 @@ private: bounding box of all currently selected slides, does not fit entirely into the visible area of the slide sorter view. */ - bool DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const; + // bool DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const; /** When not all currently selected slides fit into the visible area of the slide sorter view, and thus DoesSelectionExceedVisibleArea() @@ -217,10 +181,10 @@ private: @return Returns the new visible area. */ - Rectangle ResolveLargeSelection ( - const model::SharedPageDescriptor& rpFirst, - const model::SharedPageDescriptor& rpLast, - const SelectionHint eSelectionHint); + // Rectangle ResolveLargeSelection ( + // const model::SharedPageDescriptor& rpFirst, + // const model::SharedPageDescriptor& rpLast, + // const SelectionHint eSelectionHint); }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx new file mode 100644 index 000000000000..7718b9b7af01 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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_CONTROLLER_SELECTION_OBSERVER_HXX +#define SD_SLIDESORTER_CONTROLLER_SELECTION_OBSERVER_HXX + +#include +#include + +namespace sd { namespace slidesorter { +class SlideSorter; +} } + +class SdDrawDocument; +class SdrPage; + +namespace sd { namespace slidesorter { namespace controller { + +class SelectionObserver +{ +public: + SelectionObserver (SlideSorter& rSlideSorter); + virtual ~SelectionObserver (void); + + void NotifyPageEvent (const SdrPage* pPage); + void StartObservation (void); + void EndObservation (void); + + /** Use this little class instead of calling StartObservation and + EndObservation directly so that EndObservation is not forgotten or + omitted due to an exception or some break or return in the middle of + code. + */ + class Context + { + public: + Context (SlideSorter& rSlideSorter); + ~Context(void); + private: + ::boost::shared_ptr mpSelectionObserver; + }; + +private: + SlideSorter& mrSlideSorter; + SdDrawDocument* mpDocument; + bool mbIsOvservationActive; + + ::std::vector maInsertedPages; + ::std::vector maDeletedPages; +}; + +} } } // end of namespace ::sd::slidesorter::controller + +#endif diff --git a/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx new file mode 100644 index 000000000000..7edf45b22b16 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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_VISIBLE_AREA_MANAGER_HXX +#define SD_SLIDESORTER_VISIBLE_AREA_MANAGER_HXX + +#include "controller/SlsAnimator.hxx" +#include "model/SlsSharedPageDescriptor.hxx" +#include +#include + +namespace sd { namespace slidesorter { namespace controller { + + +/** Manage requests for scrolling page objects into view. +*/ +class VisibleAreaManager + : public ::boost::noncopyable +{ +public: + VisibleAreaManager (SlideSorter& rSlideSorter); + ~VisibleAreaManager (void); + + /** Request to make the specified page object visible. + @param eRequestedAnimationMode + This flag specifies wether to smoothly scroll the page object into + view (AM_Animated) or do this in one step (AM_Immediate). + */ + void RequestVisible ( + const model::SharedPageDescriptor& rpDescriptor, + const Animator::AnimationMode eRequestedAnimationMode = Animator::AM_Immediate); + +private: + SlideSorter& mrSlideSorter; + + /** List of rectangle that someone wants to be moved into the visible + area. + Cleared on every call to ForgetVisibleRequests() and MakeVisible(). + */ + ::std::vector maVisibleRequests; + + /** Animation id for a scroll animation that sets the top + and left of the visible area to maRequestedVisibleTopLeft. + */ + Animator::AnimationId mnScrollAnimationId; + Point maRequestedVisibleTopLeft; + + Animator::AnimationMode meRequestedAnimationMode; + + void MakeVisible (void); + ::boost::optional GetRequestedTopLeft (void) const; +}; + + +} } } // end of namespace ::sd::slidesorter::view + +#endif diff --git a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx index 767ec630f6fc..9dfd861fd5cf 100644 --- a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx @@ -45,6 +45,7 @@ class SdDrawDocument; namespace css = ::com::sun::star; class SdrPage; +class SdPage; namespace sd { namespace slidesorter { class SlideSorter; @@ -58,6 +59,9 @@ namespace sd { namespace slidesorter { namespace model { class DocumentPageContainer; +inline sal_Int32 FromCoreIndex (const USHORT nCoreIndex) { return (nCoreIndex-1)/2; } +inline USHORT ToCoreIndex (const sal_Int32 nIndex) { return nIndex*2+1; } + /** The model of the slide sorter gives access to the slides that are to be displayed in the slide sorter view. Via the SetDocumentSlides() method this set of slides can be modified (but do not call it directly, use @@ -146,6 +150,13 @@ public: */ sal_Int32 GetIndex (const SdrPage* pPage) const; + /** Return an index for accessing an SdrModel that corresponds to the + given SlideSorterModel index. In many cases we just have to apply + the n*2+1 magic. Only when a special model is set, like a custom + slide show, then the returned value is different. + */ + USHORT GetCoreIndex (const sal_Int32 nIndex) const; + /** Call this method after the document has changed its structure. This will get the model in sync with the SdDrawDocument. This method tries not to throw away to much information already gathered. This @@ -207,6 +218,14 @@ public: */ Region RestoreSelection (void); + /** Typically called from controller::Listener this method handles the + insertion and deletion of single pages. + @return + Returns when the given page is relevant for the current + page kind and edit mode. + */ + bool NotifyPageEvent (const SdrPage* pPage); + private: mutable ::osl::Mutex maMutex; SlideSorter& mrSlideSorter; @@ -221,6 +240,10 @@ private: */ void AdaptSize (void); + SdPage* GetPage (const sal_Int32 nCoreIndex) const; + void InsertSlide (SdPage* pPage); + void DeleteSlide (const SdPage* pPage); + void UpdateIndices (const sal_Int32 nFirstIndex); }; } } } // end of namespace ::sd::slidesorter::model diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx index 308bb5a49a15..276f1a7c10a7 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx @@ -96,6 +96,7 @@ public: access the model filters them out. */ sal_Int32 GetPageIndex (void) const; + void SetPageIndex (const sal_Int32 nIndex); bool UpdateMasterPage (void); @@ -136,7 +137,10 @@ private: /** This index is displayed as page number in the view. It may or may not be the actual page index. */ - const sal_Int32 mnIndex; + sal_Int32 mnIndex; + + Rectangle maBoundingBox; + VisualState maVisualState; bool mbIsSelected : 1; bool mbWasSelected : 1; @@ -145,9 +149,6 @@ private: bool mbIsCurrent : 1; bool mbIsMouseOver : 1; - Rectangle maBoundingBox; - - VisualState maVisualState; // Do not use the copy constructor operator. It is not implemented. PageDescriptor (const PageDescriptor& rDescriptor); diff --git a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx index b8df8a6688f8..2a09fc047b80 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx @@ -84,7 +84,7 @@ public: void SetActiveButtonState (const sal_Int32 nIndex, const ButtonState eState); ButtonState GetButtonState (const sal_Int32 nIndex); - const sal_Int32 mnPageId; // For debugging + sal_Int32 mnPageId; // For debugging private: State meCurrentVisualState; diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx index affe0824bd8c..b932134cf9a6 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx @@ -55,7 +55,14 @@ public: */ void SetInsertPosition (const InsertPosition& rInsertPosition); - void Reset (void); + enum ResetMode { RM_Normal, RM_AbortAnimations }; + /** Restore the normal position of all page objects. + @param eMode + This flag controls wether to start an animation that ends in the + normal positions of all slides (AM_Animated) or to restore the + normal positions immediately (AM_Immediate). + */ + void Reset (const controller::Animator::AnimationMode eMode); private: class Implementation; diff --git a/sd/source/ui/slidesorter/inc/view/SlsResource.hrc b/sd/source/ui/slidesorter/inc/view/SlsResource.hrc new file mode 100644 index 000000000000..e23c4e8a9a36 --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsResource.hrc @@ -0,0 +1,50 @@ +/************************************************************************* + * + * 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: CondFormat.hrc,v $ + * $Revision: 1.4 $ + * + * 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_ICONS_HRC +#define SD_SLIDESORTER_ICONS_HRC + +#include "glob.hrc" + +#define IMG_ICONS RID_SLIDESORTER_ICONS + +#define IMAGE_PRESENTATION 1 +#define IMAGE_SHOW_SLIDE 2 +#define IMAGE_NEW_SLIDE 3 + +#define IMAGE_SHADOW 10 +#define IMAGE_INSERT_SHADOW 11 +#define IMAGE_HIDE_SLIDE_OVERLAY 12 + +#define STRING_UNHIDE 13 +#define STRING_DRAG_AND_DROP_PAGES 14 +#define STRING_DRAG_AND_DROP_SLIDES 15 + +#endif diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx index 1991babb0208..eefeda7c14d4 100644 --- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx @@ -117,9 +117,12 @@ public: enum IconType { - RawShadow, - RawInsertShadow, - HideSlideOverlay + Icon_RawShadow, + Icon_RawInsertShadow, + Icon_HideSlideOverlay, + Icon_StartPresentation, + Icon_ShowSlide, + Icon_DuplicateSlide }; BitmapEx GetIcon (const IconType eType); @@ -132,6 +135,14 @@ public: sal_Int32 GetIntegerValue (const IntegerValueType eType) const; void SetIntegerValue (const IntegerValueType eType, const sal_Int32 nValue); + enum StringType + { + String_Unhide, + String_DragAndDropPages, + String_DragAndDropSlides + }; + ::rtl::OUString GetString (const StringType eType) const; + private: class GradientDescriptor { @@ -157,10 +168,16 @@ private: BitmapEx maRawShadow; BitmapEx maRawInsertShadow; BitmapEx maHideSlideOverlay; + BitmapEx maStartPresentationIcon; + BitmapEx maShowSlideIcon; + BitmapEx maDuplicateSlideIcon; ::std::vector maColor; sal_Int32 mnButtonCornerRadius; sal_Int32 mnButtonMaxAlpha; sal_Int32 mnButtonPaintType; + ::rtl::OUString msUnhide; + ::rtl::OUString msDragAndDropPages; + ::rtl::OUString msDragAndDropSlides; GradientDescriptor& GetGradient (const GradientColorType eType); }; diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx index e111d44d3a08..61befe64f80d 100644 --- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx +++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx @@ -65,6 +65,39 @@ namespace { private: Reference mxSlide; }; + + bool CheckModel (const SlideSorterModel& rModel) + { + for (sal_Int32 nIndex=0,nCount=rModel.GetPageCount(); nIndexGetPageIndex(), + pDescriptor->GetVisualState().mnPageId, + FromCoreIndex(pDescriptor->GetPage()->GetPageNum()), + pDescriptor->GetPage()); + if (nIndex != pDescriptor->GetPageIndex()) + { + OSL_ASSERT(nIndex == pDescriptor->GetPageIndex()); + return false; + } + if (nIndex != pDescriptor->GetVisualState().mnPageId) + { + OSL_ASSERT(nIndex == pDescriptor->GetVisualState().mnPageId); + return false; + } + /* + if (nIndex != FromCoreIndex(pDescriptor->GetPage()->GetPageNum())) + { + OSL_ASSERT(nIndex != FromCoreIndex(pDescriptor->GetPage()->GetPageNum())); + return false; + } + */ + } + + return true; + } } @@ -194,15 +227,7 @@ SharedPageDescriptor SlideSorterModel::GetPageDescriptor ( pDescriptor = maPageDescriptors[nPageIndex]; if (pDescriptor == NULL && bCreate && mxSlides.is()) { - SdDrawDocument* pModel = const_cast(this)->GetDocument(); - SdPage* pPage = NULL; - if (pModel != NULL) - { - if (meEditMode == EM_PAGE) - pPage = pModel->GetSdPage ((USHORT)nPageIndex, mePageKind); - else - pPage = pModel->GetMasterSdPage ((USHORT)nPageIndex, mePageKind); - } + SdPage* pPage = GetPage(nPageIndex); pDescriptor.reset(new PageDescriptor ( Reference(mxSlides->getByIndex(nPageIndex),UNO_QUERY), pPage, @@ -314,6 +339,18 @@ sal_Int32 SlideSorterModel::GetIndex (const SdrPage* pPage) const +USHORT SlideSorterModel::GetCoreIndex (const sal_Int32 nIndex) const +{ + SharedPageDescriptor pDescriptor (GetPageDescriptor(nIndex)); + if (pDescriptor) + return pDescriptor->GetPage()->GetPageNum(); + else + return mxSlides->getCount()*2+1; +} + + + + /** For now this method uses a trivial algorithm: throw away all descriptors and create them anew (on demand). The main problem that we are facing when designing a better algorithm is that we can not compare pointers to @@ -324,8 +361,37 @@ sal_Int32 SlideSorterModel::GetIndex (const SdrPage* pPage) const void SlideSorterModel::Resync (void) { ::osl::MutexGuard aGuard (maMutex); - ClearDescriptorList (); - AdaptSize(); + + // Check if document and this model really differ. + bool bIsUpToDate (true); + SdDrawDocument* pDocument = GetDocument(); + if (pDocument!=NULL && maPageDescriptors.size()==pDocument->GetSdPageCount(mePageKind)) + { + for (sal_Int32 nIndex=0,nCount=maPageDescriptors.size(); nIndexGetPage() + != GetPage(nIndex)) + { + OSL_TRACE("page %d differs\n", nIndex); + bIsUpToDate = false; + break; + } + } + } + else + { + bIsUpToDate = false; + OSL_TRACE("models differ"); + } + + if ( ! bIsUpToDate) + { + SynchronizeDocumentSelection(); // Try to make the current selection persistent. + ClearDescriptorList (); + AdaptSize(); + } + CheckModel(*this); } @@ -333,21 +399,26 @@ void SlideSorterModel::Resync (void) void SlideSorterModel::ClearDescriptorList (void) { - ::osl::MutexGuard aGuard (maMutex); + DescriptorContainer aDescriptors; + + { + ::osl::MutexGuard aGuard (maMutex); + aDescriptors.swap(maPageDescriptors); + } - // Clear the cache of page descriptors. - DescriptorContainer::iterator I; - for (I=maPageDescriptors.begin(); I!=maPageDescriptors.end(); I++) + for (DescriptorContainer::iterator iDescriptor=aDescriptors.begin(), iEnd=aDescriptors.end(); + iDescriptor!=iEnd; + ++iDescriptor) { - if (I->get() != NULL) + if (iDescriptor->get() != NULL) { - if ( ! I->unique()) + if ( ! iDescriptor->unique()) { - OSL_TRACE("SlideSorterModel::ClearDescriptorList: trying to delete page descriptor that is still used with count %d", I->use_count()); + OSL_TRACE("SlideSorterModel::ClearDescriptorList: trying to delete page descriptor that is still used with count %d", iDescriptor->use_count()); // No assertion here because that can hang the office when // opening a dialog from here. } - I->reset(); + iDescriptor->reset(); } } } @@ -547,4 +618,123 @@ Region SlideSorterModel::RestoreSelection (void) } + + +bool SlideSorterModel::NotifyPageEvent (const SdrPage* pSdrPage) +{ + ::osl::MutexGuard aGuard (maMutex); + + SdPage* pPage = const_cast(dynamic_cast(pSdrPage)); + OSL_ASSERT(pPage!=NULL); + if (pPage == NULL) + return false; + + // We are only interested in pages that are currently served by this + // model. + if (pPage->GetPageKind() != mePageKind) + return false; + if (pPage->IsMasterPage() != (meEditMode==EM_MASTERPAGE)) + return false; + + if (pPage->IsInserted()) + InsertSlide(pPage); + else + DeleteSlide(pPage); + CheckModel(*this); + + return true; +} + + + + +void SlideSorterModel::InsertSlide (SdPage* pPage) +{ + // Find the index at which to insert the given page. + USHORT nCoreIndex (pPage->GetPageNum()); + sal_Int32 nIndex (FromCoreIndex(nCoreIndex)); + if (pPage != GetPage(nIndex)) + return; + + // Check that the pages in the document before and after the given page + // are present in this model. + if (nIndex>0) + if (GetPage(nIndex-1) != GetPageDescriptor(nIndex-1)->GetPage()) + return; + if (nIndexGetPage()) + return; + + // Insert the given page at index nIndex + maPageDescriptors.insert( + maPageDescriptors.begin()+nIndex, + SharedPageDescriptor( + new PageDescriptor ( + Reference(mxSlides->getByIndex(nIndex),UNO_QUERY), + pPage, + nIndex))); + + // Update page indices. + UpdateIndices(nIndex+1); + OSL_TRACE("page inserted"); +} + + + + +void SlideSorterModel::DeleteSlide (const SdPage* pPage) +{ + const sal_Int32 nIndex (GetIndex(pPage)); + if (maPageDescriptors[nIndex]) + if (maPageDescriptors[nIndex]->GetPage() != pPage) + return; + + maPageDescriptors.erase(maPageDescriptors.begin()+nIndex); + UpdateIndices(nIndex); + OSL_TRACE("page removed"); +} + + + + +void SlideSorterModel::UpdateIndices (const sal_Int32 nFirstIndex) +{ + for (sal_Int32 nDescriptorIndex=0,nCount=maPageDescriptors.size(); + nDescriptorIndexGetPageIndex()!=nDescriptorIndex) + { + OSL_ASSERT(rpDescriptor->GetPageIndex()==nDescriptorIndex); + } + } + else + { + rpDescriptor->SetPageIndex(nDescriptorIndex); + } + } +} + + + + +SdPage* SlideSorterModel::GetPage (const sal_Int32 nSdIndex) const +{ + SdDrawDocument* pModel = const_cast(this)->GetDocument(); + if (pModel != NULL) + { + if (meEditMode == EM_PAGE) + return pModel->GetSdPage ((USHORT)nSdIndex, mePageKind); + else + return pModel->GetMasterSdPage ((USHORT)nSdIndex, mePageKind); + } + else + return NULL; +} + + } } } // end of namespace ::sd::slidesorter::model diff --git a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx index 69874abb7f6b..756c486f1e74 100644 --- a/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx +++ b/sd/source/ui/slidesorter/model/SlsPageDescriptor.cxx @@ -52,19 +52,21 @@ PageDescriptor::PageDescriptor ( mxPage(rxPage), mpMasterPage(NULL), mnIndex(nIndex), + maBoundingBox(), + maVisualState(nIndex), mbIsSelected(false), mbWasSelected(false), mbIsVisible(false), mbIsFocused(false), mbIsCurrent(false), - mbIsMouseOver(false), - maBoundingBox(), - maVisualState(nIndex) + mbIsMouseOver(false) { OSL_ASSERT(mpPage); OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage)); if (mpPage!=NULL && mpPage->TRG_HasMasterPage()) mpMasterPage = &mpPage->TRG_GetMasterPage(); + + GetCoreSelection(); } @@ -101,6 +103,15 @@ sal_Int32 PageDescriptor::GetPageIndex (void) const +void PageDescriptor::SetPageIndex (const sal_Int32 nNewIndex) +{ + mnIndex = nNewIndex; + maVisualState.mnPageId = nNewIndex; +} + + + + bool PageDescriptor::UpdateMasterPage (void) { const SdrPage* pMaster = NULL; diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 11b03fb3ff15..3212e8f74760 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -40,6 +40,7 @@ #include "controller/SlsCurrentSlideManager.hxx" #include "controller/SlsSelectionManager.hxx" #include "controller/SlsSelectionFunction.hxx" +#include "controller/SlsProperties.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" #include "model/SlideSorterModel.hxx" @@ -303,12 +304,16 @@ SlideSorter& SlideSorterViewShell::GetSlideSorter (void) const bool SlideSorterViewShell::RelocateToParentWindow (::Window* pParentWindow) { - OSL_ASSERT(mpSlideSorter.get()!=NULL); + OSL_ASSERT(mpSlideSorter); + if ( ! mpSlideSorter) + return false; + if (pParentWindow == NULL) WriteFrameViewData(); const bool bSuccess (mpSlideSorter->RelocateToWindow(pParentWindow)); if (pParentWindow != NULL) ReadFrameViewData(mpFrameView); + return bSuccess; } diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 41d671353be6..e69090f611b9 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -175,17 +175,21 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) SetPageVisible (FALSE); - // Register the background painter on level 0 - mpLayeredDevice->RegisterPainter(mpBackgroundPainter, 0); + // Register the background painter on level 1 to avoid the creation of a + // background buffer. + mpLayeredDevice->RegisterPainter(mpBackgroundPainter, 1); - // Wrap a shared_ptr held wrapper around this view and register it as + // Wrap a shared_ptr-held-wrapper around this view and register it as // painter at the layered device. There is no explicit destruction: in // the SlideSorterView destructor the layered device is destroyed and // with it the only reference to the wrapper which therefore is also // destroyed. - // The painter is placed on level 0, like the background painter, so - // that it is buffered. - mpLayeredDevice->RegisterPainter(SharedILayerPainter(new Painter(*this)), 0); + SharedILayerPainter pPainter (new Painter(*this)); + + // The painter is placed on level 1 to avoid buffering. This should be + // a little faster during animations because the previews are painted + // directly into the window, not via the buffer. + mpLayeredDevice->RegisterPainter(pPainter, 1); } @@ -370,6 +374,7 @@ void SlideSorterView::Resize (void) if (bRearrangeSuccess) { Layout(); + UpdatePageUnderMouse(false); RequestRepaint(); } } @@ -438,7 +443,9 @@ void SlideSorterView::UpdateOrientation (void) } else { - OSL_ASSERT(pDockingWindow!=NULL); + // We are not placed in a docking window. One possible reason + // is that the slide sorter is temporarily into a cache and was + // reparented to a non-docking window. SetOrientation(Layouter::GRID); } } @@ -472,12 +479,20 @@ void SlideSorterView::Layout () // Iterate over all page objects and place them relative to the // containing page. + sal_Int32 nIndex (0); model::PageEnumeration aPageEnumeration ( model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); while (aPageEnumeration.HasMoreElements()) { model::SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); pDescriptor->SetBoundingBox(mpLayouter->GetPageObjectBox(pDescriptor->GetPageIndex())); + OSL_TRACE("%d %d(%d) : %d %d %d %d", + pDescriptor->GetPageIndex(), pDescriptor->GetVisualState().mnPageId, nIndex, + pDescriptor->GetBoundingBox().Left(), + pDescriptor->GetBoundingBox().Top(), + pDescriptor->GetBoundingBox().GetWidth(), + pDescriptor->GetBoundingBox().GetHeight()); + ++nIndex; } GetPageObjectPainter()->NotifyResize(); @@ -599,11 +614,11 @@ void SlideSorterView::RequestRepaint (void) SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { - pWindow->Invalidate(); mpLayeredDevice->InvalidateAllLayers( Rectangle( pWindow->PixelToLogic(Point(0,0)), pWindow->PixelToLogic(pWindow->GetSizePixel()))); + pWindow->Invalidate(); } } @@ -623,8 +638,8 @@ void SlideSorterView::RequestRepaint (const Rectangle& rRepaintBox) SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { - pWindow->Invalidate(rRepaintBox); mpLayeredDevice->InvalidateAllLayers(rRepaintBox); + pWindow->Invalidate(rRepaintBox); } } @@ -635,8 +650,8 @@ void SlideSorterView::RequestRepaint (const Region& rRepaintRegion) SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { - pWindow->Invalidate(rRepaintRegion); mpLayeredDevice->InvalidateAllLayers(rRepaintRegion); + pWindow->Invalidate(rRepaintRegion); } } @@ -684,6 +699,8 @@ void SlideSorterView::CompleteRedraw ( if (mnLockRedrawSmph == 0) { mrSlideSorter.GetContentWindow()->IncrementLockCount(); + if (mpLayeredDevice->HandleMapModeChange()) + DeterminePageObjectVisibilities(); mpLayeredDevice->Repaint(rPaintArea); mrSlideSorter.GetContentWindow()->DecrementLockCount(); } @@ -756,6 +773,8 @@ void SlideSorterView::ConfigurationChanged ( cache::PageCacheManager::Instance()->InvalidateAllCaches(); ::sd::View::ConfigurationChanged(pBroadcaster, nHint); + RequestRepaint(); + } @@ -819,10 +838,14 @@ void SlideSorterView::UpdatePageUnderMouse (bool bAnimate) if (pWindow && ! pWindow->IsMouseCaptured()) { const Window::PointerState aPointerState (pWindow->GetPointerState()); - UpdatePageUnderMouse ( - aPointerState.maPos, - (aPointerState.mnState & MOUSE_LEFT)!=0, - bAnimate); + const Rectangle aWindowBox (pWindow->GetPosPixel(), pWindow->GetSizePixel()); + if (aWindowBox.IsInside(aPointerState.maPos)) + UpdatePageUnderMouse ( + aPointerState.maPos, + (aPointerState.mnState & MOUSE_LEFT)!=0, + bAnimate); + else + SetPageUnderMouse(SharedPageDescriptor(),false); } } @@ -951,21 +974,15 @@ bool SlideSorterView::SetState ( if ( ! bModified) return false; - switch(eState) - { - case PageDescriptor::ST_Visible: - case PageDescriptor::ST_Selected: - case PageDescriptor::ST_Focused: - case PageDescriptor::ST_MouseOver: - case PageDescriptor::ST_Current: - case PageDescriptor::ST_Excluded: - RequestRepaint(pDescriptor); - break; - - case PageDescriptor::ST_WasSelected: - // Ignore. - break; - } + // When the page object is not visible (i.e. not on the screen then + // nothing has to be painted. + if ( ! pDescriptor->HasState(PageDescriptor::ST_Visible)) + return true; + + // For most states a change of that state leads to visible difference + // and we have to request a repaint. + if (eState != PageDescriptor::ST_WasSelected) + RequestRepaint(pDescriptor); // Fade in or out the buttons. if (eState == PageDescriptor::ST_MouseOver) @@ -1083,11 +1100,6 @@ SlideSorterView::DrawLock::~DrawLock (void) mpWindow->Invalidate(mrView.maRedrawRegion); mpWindow->Update(); } - /* - mrView.CompleteRedraw( - mpWindow.get(), - mrView.maRedrawRegion); - */ } diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hrc b/sd/source/ui/slidesorter/view/SlsIcons.hrc deleted file mode 100644 index 22b4b398955c..000000000000 --- a/sd/source/ui/slidesorter/view/SlsIcons.hrc +++ /dev/null @@ -1,48 +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: CondFormat.hrc,v $ - * $Revision: 1.4 $ - * - * 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_ICONS_HRC -#define SD_SLIDESORTER_ICONS_HRC - -#include "glob.hrc" - -#define IMG_ICONS RID_SLIDESORTER_ICONS - -#define IMAGE_PRESENTATION 1 -#define IMAGE_SHOW_SLIDE 2 -#define IMAGE_NEW_SLIDE 3 - -#define IMAGE_SHADOW 10 -#define IMAGE_INSERT_SHADOW 11 -#define IMAGE_HIDE_SLIDE_OVERLAY 12 - -#define STRING_UNHIDE 13 - -#endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.hxx b/sd/source/ui/slidesorter/view/SlsIcons.hxx deleted file mode 100644 index 63c4de22584a..000000000000 --- a/sd/source/ui/slidesorter/view/SlsIcons.hxx +++ /dev/null @@ -1,51 +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: SlsViewCacheContext.hxx,v $ - * - * $Revision: 1.3 $ - * - * 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_ICONS_HXX -#define SD_SLIDESORTER_ICONS_HXX - -#include "SlsIcons.hrc" -#include "sdresid.hxx" -#include - -namespace sd { namespace slidesorter { namespace view { - -class LocalResource : public Resource -{ -public: - LocalResource (const sal_uInt16 nResourceId) : Resource(SdResId(nResourceId)){} - ~LocalResource (void) { FreeResource(); } -}; - - -} } } // end of namespace ::sd::slidesorter::view - -#endif diff --git a/sd/source/ui/slidesorter/view/SlsIcons.src b/sd/source/ui/slidesorter/view/SlsIcons.src deleted file mode 100644 index 4bee98eb0559..000000000000 --- a/sd/source/ui/slidesorter/view/SlsIcons.src +++ /dev/null @@ -1,69 +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: CondFormat.src,v $ - * $Revision: 1.6 $ - * - * 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 "SlsIcons.hrc" - -Resource IMG_ICONS -{ - Image IMAGE_PRESENTATION - { - ImageBitmap = Bitmap { File = "slide_sorter_command1.png" ; }; - }; - - Image IMAGE_SHOW_SLIDE - { - ImageBitmap = Bitmap { File = "slide_sorter_command2.png" ; }; - }; - - Image IMAGE_NEW_SLIDE - { - ImageBitmap = Bitmap { File = "slide_sorter_command3.png" ; }; - }; - - Image IMAGE_SHADOW - { - ImageBitmap = Bitmap { File = "slide_sorter_shadow.png" ; }; - }; - - Image IMAGE_INSERT_SHADOW - { - ImageBitmap = Bitmap { File = "slide_sorter_insert_shadow.png" ; }; - }; - - Image IMAGE_HIDE_SLIDE_OVERLAY - { - ImageBitmap = Bitmap { File = "slide_sorter_hide_slide_overlay.png" ; }; - }; - - String STRING_UNHIDE - { - Text [ en-US ] = "unhide" ; - }; -}; diff --git a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx index 2ecf8eab6498..aaa8cf5d6d18 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertAnimator.cxx @@ -77,7 +77,7 @@ public: void UpdateOffsets( const InsertPosition& rInsertPosition, const view::Layouter& GetLayouter); - void ResetOffsets (void); + void ResetOffsets (const controller::Animator::AnimationMode eMode); /// Index of the row or column that this run represents. sal_Int32 mnRunIndex; @@ -134,9 +134,9 @@ public: Implementation (SlideSorter& rSlideSorter); virtual ~Implementation (void); - void SetInsertPosition (const InsertPosition& rInsertPosition); - - void Reset (void); + void SetInsertPosition ( + const InsertPosition& rInsertPosition, + const controller::Animator::AnimationMode eAnimationMode); virtual void RemoveRun (PageObjectRun* pRun); @@ -176,15 +176,15 @@ InsertAnimator::InsertAnimator (SlideSorter& rSlideSorter) void InsertAnimator::SetInsertPosition (const InsertPosition& rInsertPosition) { - mpImplementation->SetInsertPosition(rInsertPosition); + mpImplementation->SetInsertPosition(rInsertPosition, controller::Animator::AM_Animated); } -void InsertAnimator::Reset (void) +void InsertAnimator::Reset (const controller::Animator::AnimationMode eMode) { - mpImplementation->Reset(); + mpImplementation->SetInsertPosition(InsertPosition(), eMode); } @@ -206,13 +206,15 @@ InsertAnimator::Implementation::Implementation (SlideSorter& rSlideSorter) InsertAnimator::Implementation::~Implementation (void) { - Reset(); + SetInsertPosition(InsertPosition(), controller::Animator::AM_Immediate); } -void InsertAnimator::Implementation::SetInsertPosition (const InsertPosition& rInsertPosition) +void InsertAnimator::Implementation::SetInsertPosition ( + const InsertPosition& rInsertPosition, + const controller::Animator::AnimationMode eMode) { if (maInsertPosition == rInsertPosition) return; @@ -227,7 +229,7 @@ void InsertAnimator::Implementation::SetInsertPosition (const InsertPosition& rI { if (pOldRun) { - pOldRun->ResetOffsets(); + pOldRun->ResetOffsets(eMode); maRuns.insert(pOldRun); } } @@ -242,14 +244,6 @@ void InsertAnimator::Implementation::SetInsertPosition (const InsertPosition& rI -void InsertAnimator::Implementation::Reset (void) -{ - SetInsertPosition(InsertPosition()); -} - - - - SharedPageObjectRun InsertAnimator::Implementation::GetRun ( view::Layouter& rLayouter, const InsertPosition& rInsertPosition, @@ -425,7 +419,7 @@ void PageObjectRun::UpdateOffsets( -void PageObjectRun::ResetOffsets (void) +void PageObjectRun::ResetOffsets (const controller::Animator::AnimationMode eMode) { mnLocalInsertIndex = -1; const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1); @@ -434,10 +428,14 @@ void PageObjectRun::ResetOffsets (void) { model::SharedPageDescriptor pDescriptor(rModel.GetPageDescriptor(nIndex+mnStartIndex)); if (pDescriptor) - maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset(); + if (eMode == controller::Animator::AM_Animated) + maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset(); + else + pDescriptor->GetVisualState().SetLocationOffset(Point(0,0)); maEndOffset[nIndex] = Point(0,0); } - RestartAnimation(); + if (eMode == controller::Animator::AM_Animated) + RestartAnimation(); } diff --git a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx index 52f9f915c5b2..3dfde5b0d83b 100644 --- a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx +++ b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx @@ -79,7 +79,6 @@ namespace sd { namespace slidesorter { namespace view { 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), @@ -89,7 +88,8 @@ InsertionIndicatorOverlay::InsertionIndicatorOverlay (SlideSorter& rSlideSorter) maLocation(), maIcon(), maIconOffset(), - mpShadowPainter(new FramePainter(mrSlideSorter.GetTheme()->GetIcon(Theme::RawInsertShadow))) + mpShadowPainter( + new FramePainter(mrSlideSorter.GetTheme()->GetIcon(Theme::Icon_RawInsertShadow))) { } @@ -160,16 +160,6 @@ void InsertionIndicatorOverlay::Create ( *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(); @@ -241,16 +231,7 @@ Point InsertionIndicatorOverlay::PaintRepresentatives ( 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); - } + aPreview.Scale(aPreviewSize, BMP_SCALE_INTERPOLATE); rContent.DrawBitmapEx(aPageOffset, aPreview); // Tone down the bitmap. The further back the darker it becomes. diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx index cf69970bca57..f368dff59555 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx @@ -138,8 +138,8 @@ typedef ::boost::shared_ptr SharedLayer; class LayeredDevice::LayerContainer : public ::std::vector { public: - LayerContainer (void) { OSL_TRACE("created layer container at %x", this); } - ~LayerContainer (void) { OSL_TRACE("destroyed layer container at %x", this); } + LayerContainer (void) {} + ~LayerContainer (void) {} }; @@ -153,7 +153,6 @@ LayeredDevice::LayeredDevice (const SharedSdWindow& rpTargetWindow) mpBackBuffer(new VirtualDevice(*mpTargetWindow)), maSavedMapMode(rpTargetWindow->GetMapMode()) { - OSL_TRACE("layered device created at %x", this); mpBackBuffer->SetOutputSizePixel(mpTargetWindow->GetSizePixel()); } @@ -162,7 +161,6 @@ LayeredDevice::LayeredDevice (const SharedSdWindow& rpTargetWindow) LayeredDevice::~LayeredDevice (void) { - OSL_TRACE("layered device destroyed at %x", this); } @@ -279,8 +277,6 @@ bool LayeredDevice::HasPainter (const sal_Int32 nLayer) void LayeredDevice::Repaint (const Region& rRepaintRegion) { - HandleMapModeChange(); - // Validate the contents of all layers (that have their own devices.) ::std::for_each( mpLayers->begin(), @@ -339,11 +335,11 @@ void LayeredDevice::Dispose (void) -void LayeredDevice::HandleMapModeChange (void) +bool LayeredDevice::HandleMapModeChange (void) { const MapMode& rMapMode (mpTargetWindow->GetMapMode()); if (maSavedMapMode == rMapMode) - return; + return false; const Rectangle aLogicWindowBox ( mpTargetWindow->PixelToLogic(Rectangle(Point(0,0), mpTargetWindow->GetSizePixel()))); @@ -352,10 +348,7 @@ void LayeredDevice::HandleMapModeChange (void) || maSavedMapMode.GetMapUnit() != rMapMode.GetMapUnit()) { // When the scale has changed then we have to paint everything. - ::std::for_each( - mpLayers->begin(), - mpLayers->end(), - ::boost::bind(&Layer::InvalidateRectangle, _1, ::boost::cref(aLogicWindowBox))); + InvalidateAllLayers(aLogicWindowBox); } else if (maSavedMapMode.GetOrigin() != rMapMode.GetOrigin()) { @@ -366,18 +359,34 @@ void LayeredDevice::HandleMapModeChange (void) aLogicWindowBox.TopLeft(), mpTargetWindow->PixelToLogic(Point(0,0), maSavedMapMode), aLogicWindowBox.GetSize()); - InvalidateAllLayers(aLogicWindowBox); + OSL_TRACE("scrolling %d %d", aDelta.X(), aDelta.Y()); - /* + // Invalidate the area(s) that have been exposed. const Rectangle aWindowBox (Point(0,0), mpTargetWindow->GetSizePixel()); - if (aDelta.X < 0) - Invalidate( - mpTargetWindow->PixelToLogic( - aWindowBox.TopRight(), - Point(mpTargetWindow->GetSizePixel().Right()X+aDelta.X,0)), - mpTargetWindow->PixelToLogic( - Point(mpTargetWindow->GetSizePixel().X+aDelta.X,0)), - */ + if (aDelta.Y() < 0) + InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle( + aWindowBox.Left(), + aWindowBox.Bottom()+aDelta.Y(), + aWindowBox.Right(), + aWindowBox.Bottom()))); + else if (aDelta.Y() > 0) + InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle( + aWindowBox.Left(), + aWindowBox.Top(), + aWindowBox.Right(), + aWindowBox.Top()+aDelta.Y()))); + if (aDelta.X() < 0) + InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle( + aWindowBox.Right()+aDelta.X(), + aWindowBox.Top(), + aWindowBox.Right(), + aWindowBox.Bottom()))); + else if (aDelta.X() > 0) + InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle( + aWindowBox.Left(), + aWindowBox.Top(), + aWindowBox.Left()+aDelta.X(), + aWindowBox.Bottom()))); } else { @@ -386,6 +395,8 @@ void LayeredDevice::HandleMapModeChange (void) } maSavedMapMode = rMapMode; + + return true; } @@ -412,11 +423,15 @@ Layer::~Layer (void) void Layer::Initialize (const SharedSdWindow& rpTargetWindow) { +#if 0 + (void)rpTargetWindow; +#else if ( ! mpLayerDevice) { mpLayerDevice.reset(new VirtualDevice(*rpTargetWindow)); mpLayerDevice->SetOutputSizePixel(rpTargetWindow->GetSizePixel()); } +#endif } @@ -424,6 +439,13 @@ void Layer::Initialize (const SharedSdWindow& rpTargetWindow) void Layer::InvalidateRectangle (const Rectangle& rInvalidationBox) { + /* + OSL_TRACE("invalidating layer %x %d %d %d %d", this, + rInvalidationBox.Left(), + rInvalidationBox.Top(), + rInvalidationBox.GetWidth(), + rInvalidationBox.GetHeight()); + */ maInvalidationRegion.Union(rInvalidationBox); } @@ -442,16 +464,14 @@ void Layer::Validate (const MapMode& rMapMode) { if (mpLayerDevice && ! maInvalidationRegion.IsEmpty()) { - mpLayerDevice->SetMapMode(rMapMode); + Region aRegion (maInvalidationRegion); + maInvalidationRegion.SetEmpty(); + mpLayerDevice->SetMapMode(rMapMode); ForAllRectangles( - maInvalidationRegion, + aRegion, ::boost::bind(&Layer::ValidateRectangle, this, _1)); } - // else nothing to do now. The painting is done in Repaint() directly - // into the back buffer. - - maInvalidationRegion.SetEmpty(); } @@ -461,9 +481,15 @@ void Layer::ValidateRectangle (const Rectangle& rBox) { if ( ! mpLayerDevice) return; - + /* + OSL_TRACE("validating layer %x %d %d %d %d", this, + rBox.Left(), + rBox.Top(), + rBox.GetWidth(), + rBox.GetHeight()); + */ const Region aSavedClipRegion (mpLayerDevice->GetClipRegion()); - mpLayerDevice->SetClipRegion(Region(rBox)); + mpLayerDevice->IntersectClipRegion(rBox); for (::std::vector::const_iterator iPainter(maPainters.begin()), @@ -508,7 +534,7 @@ void Layer::Resize (const Size& rSize) if (mpLayerDevice) { mpLayerDevice->SetOutputSizePixel(rSize); - maInvalidationRegion.Union(Rectangle(Point(0,0), rSize)); + maInvalidationRegion = Rectangle(Point(0,0), rSize); } } diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx index d67e0e99c473..85941c7b9739 100644 --- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx +++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.hxx @@ -79,6 +79,7 @@ public: bool HasPainter (const sal_Int32 nLayer); + bool HandleMapModeChange (void); void Repaint (const Region& rRepaintRegion); void Resize (void); @@ -93,7 +94,6 @@ private: MapMode maSavedMapMode; void RepaintRectangle (const Rectangle& rRepaintRectangle); - void HandleMapModeChange (void); }; diff --git a/sd/source/ui/slidesorter/view/SlsLayouter.cxx b/sd/source/ui/slidesorter/view/SlsLayouter.cxx index 87d6b4b62d5c..ea660062ae5c 100644 --- a/sd/source/ui/slidesorter/view/SlsLayouter.cxx +++ b/sd/source/ui/slidesorter/view/SlsLayouter.cxx @@ -78,11 +78,17 @@ public: ::boost::shared_ptr mpPageObjectLayouter; + /** Specify how the gap between two page objects is associated with the + page objects. + */ enum GapMembership { - GM_NONE, - GM_PREVIOUS, - GM_BOTH, - GM_NEXT, + GM_NONE, // Gap is not associated with any page object. + GM_PREVIOUS, // The whole gap is associated with the previous page + // object (left or above the gap.) + GM_BOTH, // Half of the gap is associated with previous, half + // with the next page object. + GM_NEXT, // The whole gap is associated with the next page + // object (right or below the gap.) GM_PAGE_BORDER }; @@ -125,12 +131,7 @@ public: When this flag is then the area of borders and gaps are interpreted as belonging to one of the columns. @param eGapMembership - Specifies to what column the gap areas belong. Here GM_NONE - corresponds to bIncludeBordersAndGaps being . When - GM_BOTH is given then the left half is associated with the - column at the left and the right half with the column to the - right. Values of GM_PREVIOUS and GM_NEXT associate the whole - gap area with the column to the left or right respectively. + Specifies to what column the gap areas belong. */ sal_Int32 GetColumnAtPosition ( sal_Int32 nXPosition, @@ -192,7 +193,10 @@ public: Range GetValidHorizontalSizeRange (void) const; Range GetValidVerticalSizeRange (void) const; - Rectangle GetPageObjectBox ( + Range GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const; + sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const; + + Rectangle GetPageObjectBox ( const sal_Int32 nIndex, const bool bIncludeBorderAndGap = false) const; @@ -448,9 +452,7 @@ sal_Int32 Layouter::GetColumn (const sal_Int32 nIndex) const sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const { - const sal_Int32 nIndex (nRow * mpImplementation->mnColumnCount + nColumn); - OSL_ASSERT(nIndex>=0); - return ::std::min(nIndex, mpImplementation->mnPageCount-1); + return mpImplementation->GetIndex(nRow,nColumn); } @@ -528,17 +530,7 @@ Range Layouter::GetValidVerticalSizeRange (void) const Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const { - const sal_Int32 nRow0 (mpImplementation->GetRowAtPosition ( - aVisibleArea.Top(), - true, - Implementation::GM_BOTH)); - const sal_Int32 nRow1 (mpImplementation->GetRowAtPosition ( - aVisibleArea.Bottom(), - true, - Implementation::GM_BOTH)); - return Range( - ::std::min(nRow0*mpImplementation->mnColumnCount, mpImplementation->mnPageCount-1), - ::std::min((nRow1+1)*mpImplementation->mnColumnCount-1, mpImplementation->mnPageCount-1)); + return mpImplementation->GetRangeOfVisiblePageObjects(aVisibleArea); } @@ -559,10 +551,7 @@ sal_Int32 Layouter::GetIndexAtPoint ( bIncludePageBorders, bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE)); - if (nRow >= 0 && nColumn >= 0) - return nRow * mpImplementation->mnColumnCount + nColumn; - else - return -1; + return mpImplementation->GetIndex(nRow,nColumn); } @@ -1006,6 +995,21 @@ Range Layouter::Implementation::GetValidVerticalSizeRange (void) const +Range Layouter::Implementation::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const +{ + const sal_Int32 nRow0 (GetRowAtPosition(aVisibleArea.Top(), true, GM_NEXT)); + const sal_Int32 nCol0 (GetColumnAtPosition(aVisibleArea.Left(),true, GM_NEXT)); + const sal_Int32 nRow1 (GetRowAtPosition(aVisibleArea.Bottom(), true, GM_PREVIOUS)); + const sal_Int32 nCol1 (GetColumnAtPosition(aVisibleArea.Right(), true, GM_PREVIOUS)); + + // When start and end lie in different rows then the range may include + // slides outside (left or right of) the given area. + return Range(GetIndex(nRow0,nCol0), GetIndex(nRow1,nCol1)); +} + + + + Size Layouter::Implementation::GetTargetSize ( const Size& rWindowSize, const Size& rPreviewModelSize, @@ -1056,6 +1060,20 @@ Size Layouter::Implementation::GetTargetSize ( +sal_Int32 Layouter::Implementation::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const +{ + if (nRow >= 0 && nColumn >= 0) + { + const sal_Int32 nIndex (nRow * mnColumnCount + nColumn); + return ::std::min(nIndex, mnPageCount-1); + } + else + return -1; +} + + + + Rectangle Layouter::Implementation::GetPageObjectBox ( const sal_Int32 nIndex, const bool bIncludeBorderAndGap) const diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx index 164613fdf998..b0c1bfc5828b 100644 --- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx +++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx @@ -42,7 +42,6 @@ #include "view/SlsPageObjectLayouter.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsTheme.hxx" -#include "SlsIcons.hxx" #include "SlsFramePainter.hxx" #include "cache/SlsPageCache.hxx" #include "controller/SlsProperties.hxx" @@ -142,24 +141,16 @@ PageObjectPainter::PageObjectPainter ( mpProperties(rSlideSorter.GetProperties()), mpTheme(rSlideSorter.GetTheme()), mpPageNumberFont(Theme::GetFont(Theme::PageNumberFont, *rSlideSorter.GetContentWindow())), - maStartPresentationIcon(), - maShowSlideIcon(), - maNewSlideIcon(), - mpShadowPainter(), + maStartPresentationIcon(mpTheme->GetIcon(Theme::Icon_StartPresentation)), + maShowSlideIcon(mpTheme->GetIcon(Theme::Icon_ShowSlide)), + maNewSlideIcon(mpTheme->GetIcon(Theme::Icon_DuplicateSlide)), + mpShadowPainter(new FramePainter(mpTheme->GetIcon(Theme::Icon_RawShadow))), maNormalBackground(), maSelectionBackground(), maFocusedSelectionBackground(), maMouseOverBackground(), - msUnhideString() + msUnhideString(mpTheme->GetString(Theme::String_Unhide)) { - LocalResource aResource (IMG_ICONS); - - maStartPresentationIcon = Image(SdResId(IMAGE_PRESENTATION)).GetBitmapEx(); - maShowSlideIcon = Image(SdResId(IMAGE_SHOW_SLIDE)).GetBitmapEx(); - maNewSlideIcon = Image(SdResId(IMAGE_NEW_SLIDE)).GetBitmapEx(); - msUnhideString = String(SdResId(STRING_UNHIDE)); - - mpShadowPainter.reset(new FramePainter(mpTheme->GetIcon(Theme::RawShadow))); } @@ -296,7 +287,7 @@ void PageObjectPainter::PaintPreview ( if (rpDescriptor->GetVisualState().GetCurrentVisualState() == model::VisualState::VS_Excluded) { - const BitmapEx aOverlay (mpTheme->GetIcon(Theme::HideSlideOverlay)); + const BitmapEx aOverlay (mpTheme->GetIcon(Theme::Icon_HideSlideOverlay)); const sal_Int32 nIconWidth (aOverlay.GetSizePixel().Width()); const sal_Int32 nIconHeight (aOverlay.GetSizePixel().Height()); if (nIconWidth>0 && nIconHeight>0) diff --git a/sd/source/ui/slidesorter/view/SlsResource.hxx b/sd/source/ui/slidesorter/view/SlsResource.hxx new file mode 100644 index 000000000000..5195e3475c0e --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsResource.hxx @@ -0,0 +1,51 @@ +/************************************************************************* + * + * 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: SlsViewCacheContext.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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_RESOURCE_HXX +#define SD_SLIDESORTER_RESOURCE_HXX + +#include "view/SlsResource.hrc" +#include "sdresid.hxx" +#include + +namespace sd { namespace slidesorter { namespace view { + +class LocalResource : public Resource +{ +public: + LocalResource (const sal_uInt16 nResourceId) : Resource(SdResId(nResourceId)){} + ~LocalResource (void) { FreeResource(); } +}; + + +} } } // end of namespace ::sd::slidesorter::view + +#endif diff --git a/sd/source/ui/slidesorter/view/SlsResource.src b/sd/source/ui/slidesorter/view/SlsResource.src new file mode 100644 index 000000000000..87e6c02356f2 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlsResource.src @@ -0,0 +1,79 @@ +/************************************************************************* + * + * 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: CondFormat.src,v $ + * $Revision: 1.6 $ + * + * 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 "view/SlsResource.hrc" + +Resource IMG_ICONS +{ + Image IMAGE_PRESENTATION + { + ImageBitmap = Bitmap { File = "slide_sorter_command1.png" ; }; + }; + + Image IMAGE_SHOW_SLIDE + { + ImageBitmap = Bitmap { File = "slide_sorter_command2.png" ; }; + }; + + Image IMAGE_NEW_SLIDE + { + ImageBitmap = Bitmap { File = "slide_sorter_command3.png" ; }; + }; + + Image IMAGE_SHADOW + { + ImageBitmap = Bitmap { File = "slide_sorter_shadow.png" ; }; + }; + + Image IMAGE_INSERT_SHADOW + { + ImageBitmap = Bitmap { File = "slide_sorter_insert_shadow.png" ; }; + }; + + Image IMAGE_HIDE_SLIDE_OVERLAY + { + ImageBitmap = Bitmap { File = "slide_sorter_hide_slide_overlay.png" ; }; + }; + + String STRING_UNHIDE + { + Text [ en-US ] = "unhide" ; + }; + + String STRING_DRAG_AND_DROP_PAGES + { + Text [ en-US ] = "Drag and Drop Pages" ; + }; + + String STRING_DRAG_AND_DROP_SLIDES + { + Text [ en-US ] = "Drag and Drop Slides" ; + }; +}; diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx index 173997cea22f..3ffc1bba7230 100644 --- a/sd/source/ui/slidesorter/view/SlsTheme.cxx +++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx @@ -30,7 +30,7 @@ ************************************************************************/ #include "view/SlsTheme.hxx" -#include "SlsIcons.hxx" +#include "SlsResource.hxx" #include "controller/SlsProperties.hxx" #include "sdresid.hxx" #include @@ -92,16 +92,30 @@ Theme::Theme (const ::boost::shared_ptr& rpProperties) maMouseOverGradient(), maRawShadow(), maRawInsertShadow(), + maHideSlideOverlay(), + maStartPresentationIcon(), + maShowSlideIcon(), + maDuplicateSlideIcon(), maColor(PreviewBorder+1), mnButtonCornerRadius(3), mnButtonMaxAlpha(255 * 20/100), - mnButtonPaintType(0) + mnButtonPaintType(0), + msUnhide(), + msDragAndDropPages(), + msDragAndDropSlides() + { LocalResource aResource (IMG_ICONS); maRawShadow = Image(SdResId(IMAGE_SHADOW)).GetBitmapEx(); maRawInsertShadow = Image(SdResId(IMAGE_INSERT_SHADOW)).GetBitmapEx(); maHideSlideOverlay = Image(SdResId(IMAGE_HIDE_SLIDE_OVERLAY)).GetBitmapEx(); + maStartPresentationIcon = Image(SdResId(IMAGE_PRESENTATION)).GetBitmapEx(); + maShowSlideIcon = Image(SdResId(IMAGE_SHOW_SLIDE)).GetBitmapEx(); + maDuplicateSlideIcon = Image(SdResId(IMAGE_NEW_SLIDE)).GetBitmapEx(); + msUnhide = String(SdResId(STRING_UNHIDE)); + msDragAndDropPages = String(SdResId(STRING_DRAG_AND_DROP_PAGES)); + msDragAndDropSlides = String(SdResId(STRING_DRAG_AND_DROP_SLIDES)); maColor.resize(PreviewBorder+1); maColor[Background] = maBackgroundColor; @@ -301,15 +315,24 @@ BitmapEx Theme::GetIcon (const IconType eType) { switch (eType) { - case RawShadow: + case Icon_RawShadow: return maRawShadow; - case RawInsertShadow: + case Icon_RawInsertShadow: return maRawInsertShadow; - case HideSlideOverlay: + case Icon_HideSlideOverlay: return maHideSlideOverlay; + case Icon_StartPresentation: + return maStartPresentationIcon; + + case Icon_ShowSlide: + return maShowSlideIcon; + + case Icon_DuplicateSlide: + return maDuplicateSlideIcon; + default: return BitmapEx(); } @@ -363,6 +386,20 @@ void Theme::SetIntegerValue (const IntegerValueType eType, const sal_Int32 nValu +::rtl::OUString Theme::GetString (const StringType eType) const +{ + switch (eType) + { + case String_Unhide: return msUnhide; + case String_DragAndDropPages: return msDragAndDropPages; + case String_DragAndDropSlides: return msDragAndDropSlides; + default: return ::rtl::OUString(); + } +} + + + + Theme::GradientDescriptor& Theme::GetGradient (const GradientColorType eType) { switch(eType) diff --git a/sd/source/ui/slidesorter/view/makefile.mk b/sd/source/ui/slidesorter/view/makefile.mk index 212817d8410f..cd63b6738801 100644 --- a/sd/source/ui/slidesorter/view/makefile.mk +++ b/sd/source/ui/slidesorter/view/makefile.mk @@ -46,7 +46,7 @@ IMGLST_SRS=$(SRS)$/$(TARGET).srs SRS1NAME=$(TARGET) SRC1FILES = \ - SlsIcons.src + SlsResource.src SLOFILES = \ $(SLO)$/SlideSorterView.obj \ diff --git a/sd/source/ui/unoidl/SdUnoSlideView.cxx b/sd/source/ui/unoidl/SdUnoSlideView.cxx index 34121dc5ac4b..ae3a24178396 100644 --- a/sd/source/ui/unoidl/SdUnoSlideView.cxx +++ b/sd/source/ui/unoidl/SdUnoSlideView.cxx @@ -32,7 +32,6 @@ #include "SlideSorter.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsPageSelector.hxx" -#include "controller/SlsSelectionManager.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" @@ -99,7 +98,6 @@ sal_Bool SAL_CALL SdUnoSlideView::select (const Any& aSelection) } } } - rSlideSorterController.GetSelectionManager()->MakeSelectionVisible(); return bOk; } -- cgit v1.2.3 From 8c9901906bbc6b59baa0b2ef918b7e7fe89538b8 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Fri, 23 Apr 2010 17:06:10 +0200 Subject: renaissance1: #i107215# Reorganized the selection function. Introduced button bar. --- sd/source/ui/presenter/PresenterPreviewCache.cxx | 6 +- sd/source/ui/slidesorter/cache/SlsBitmapCache.cxx | 135 +- sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx | 32 +- .../ui/slidesorter/cache/SlsBitmapCompressor.cxx | 83 +- .../ui/slidesorter/cache/SlsBitmapCompressor.hxx | 27 +- .../ui/slidesorter/cache/SlsBitmapFactory.cxx | 48 +- .../ui/slidesorter/cache/SlsBitmapFactory.hxx | 4 +- .../ui/slidesorter/cache/SlsGenericPageCache.cxx | 70 +- .../ui/slidesorter/cache/SlsGenericPageCache.hxx | 15 +- sd/source/ui/slidesorter/cache/SlsPageCache.cxx | 25 +- .../ui/slidesorter/cache/SlsPageCacheManager.cxx | 10 + .../ui/slidesorter/cache/SlsQueueProcessor.cxx | 9 +- .../controller/SlideSorterController.cxx | 16 +- .../ui/slidesorter/controller/SlsClipboard.cxx | 82 +- .../controller/SlsCurrentSlideManager.cxx | 5 +- .../controller/SlsDragAndDropContext.cxx | 14 - .../controller/SlsDragAndDropContext.hxx | 2 - .../ui/slidesorter/controller/SlsFocusManager.cxx | 14 +- .../controller/SlsInsertionIndicatorHandler.cxx | 30 +- .../ui/slidesorter/controller/SlsListener.cxx | 12 + .../ui/slidesorter/controller/SlsPageSelector.cxx | 28 +- .../ui/slidesorter/controller/SlsProperties.cxx | 16 +- .../slidesorter/controller/SlsScrollBarManager.cxx | 2 + .../controller/SlsSelectionFunction.cxx | 1644 ++++++++++++-------- .../controller/SlsSelectionObserver.cxx | 36 +- .../ui/slidesorter/controller/SlsSlotManager.cxx | 67 +- .../controller/SlsVisibleAreaManager.cxx | 43 +- .../ui/slidesorter/inc/cache/SlsCacheContext.hxx | 4 +- .../ui/slidesorter/inc/cache/SlsPageCache.hxx | 13 +- .../slidesorter/inc/cache/SlsPageCacheManager.hxx | 5 + .../inc/controller/SlideSorterController.hxx | 1 + .../ui/slidesorter/inc/controller/SlsClipboard.hxx | 6 +- .../slidesorter/inc/controller/SlsFocusManager.hxx | 12 +- .../controller/SlsInsertionIndicatorHandler.hxx | 8 +- .../slidesorter/inc/controller/SlsPageSelector.hxx | 3 +- .../slidesorter/inc/controller/SlsProperties.hxx | 3 + .../inc/controller/SlsSelectionFunction.hxx | 86 +- .../inc/controller/SlsSelectionManager.hxx | 25 - .../inc/controller/SlsSelectionObserver.hxx | 7 + .../inc/controller/SlsVisibleAreaManager.hxx | 17 +- .../ui/slidesorter/inc/model/SlsVisualState.hxx | 8 - .../ui/slidesorter/inc/view/SlideSorterView.hxx | 16 +- sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx | 322 ++++ sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx | 8 +- .../slidesorter/inc/view/SlsPageObjectLayouter.hxx | 28 +- .../slidesorter/inc/view/SlsPageObjectPainter.hxx | 43 +- sd/source/ui/slidesorter/inc/view/SlsResource.hrc | 51 +- sd/source/ui/slidesorter/inc/view/SlsTheme.hxx | 82 +- .../ui/slidesorter/model/SlideSorterModel.cxx | 7 - sd/source/ui/slidesorter/model/SlsVisualState.cxx | 20 - sd/source/ui/slidesorter/shell/SlsDebugDialog.cxx | 221 ++- sd/source/ui/slidesorter/view/SlideSorterView.cxx | 184 +-- sd/source/ui/slidesorter/view/SlsButtonBar.cxx | 960 ++++++++++++ .../ui/slidesorter/view/SlsInsertAnimator.cxx | 55 +- sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx | 6 +- sd/source/ui/slidesorter/view/SlsLayouter.cxx | 29 +- .../ui/slidesorter/view/SlsPageObjectLayouter.cxx | 64 +- .../ui/slidesorter/view/SlsPageObjectPainter.cxx | 462 ++---- sd/source/ui/slidesorter/view/SlsResource.src | 131 +- sd/source/ui/slidesorter/view/SlsTheme.cxx | 290 +++- .../ui/slidesorter/view/SlsViewCacheContext.cxx | 3 +- .../ui/slidesorter/view/SlsViewCacheContext.hxx | 3 +- sd/source/ui/slidesorter/view/makefile.mk | 1 + 63 files changed, 3817 insertions(+), 1842 deletions(-) create mode 100644 sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx create mode 100644 sd/source/ui/slidesorter/view/SlsButtonBar.cxx diff --git a/sd/source/ui/presenter/PresenterPreviewCache.cxx b/sd/source/ui/presenter/PresenterPreviewCache.cxx index 59af1fc34c7d..f0d0002c04d0 100644 --- a/sd/source/ui/presenter/PresenterPreviewCache.cxx +++ b/sd/source/ui/presenter/PresenterPreviewCache.cxx @@ -64,7 +64,7 @@ public: // CacheContext virtual void NotifyPreviewCreation ( - CacheKey aKey, const ::boost::shared_ptr& rPreview); + CacheKey aKey, const PreviewType& rPreview); virtual bool IsIdle (void); virtual bool IsVisible (CacheKey aKey); virtual const SdrPage* GetPage (CacheKey aKey); @@ -209,7 +209,7 @@ Reference SAL_CALL PresenterPreviewCache::getSlidePreview ( if (pPage == NULL) throw RuntimeException(); - const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage,true)); + const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage,true).GetBitmap()); if (aPreview.IsEmpty()) return NULL; else @@ -368,7 +368,7 @@ void PresenterPreviewCache::PresenterCacheContext::RemovePreviewCreationNotifyLi void PresenterPreviewCache::PresenterCacheContext::NotifyPreviewCreation ( CacheKey aKey, - const ::boost::shared_ptr& rPreview) + const PreviewType& rPreview) { (void)rPreview; diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapCache.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapCache.cxx index 47818b73d193..315496355658 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapCache.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapCache.cxx @@ -33,7 +33,6 @@ #include "SlsBitmapCompressor.hxx" #include "SlsCacheConfiguration.hxx" -#include "taskpane/SlideSorterCacheDisplay.hxx" #include "sdpage.hxx" #include "drawdoc.hxx" @@ -55,8 +54,7 @@ namespace sd { namespace slidesorter { namespace cache { class BitmapCache::CacheEntry { public: - CacheEntry(const ::boost::shared_ptr& rpBitmap, - sal_Int32 nLastAccessTime, bool bIsPrecious); + CacheEntry(const PreviewType& rBitmap, sal_Int32 nLastAccessTime, bool bIsPrecious); CacheEntry(sal_Int32 nLastAccessTime, bool bIsPrecious); ~CacheEntry (void) {}; inline void Recycle (const CacheEntry& rEntry); @@ -68,18 +66,26 @@ public: void SetUpToDate (bool bIsUpToDate) { mbIsUpToDate = bIsUpToDate; } sal_Int32 GetAccessTime (void) const { return mnLastAccessTime; } void SetAccessTime (sal_Int32 nAccessTime) { mnLastAccessTime = nAccessTime; } - ::boost::shared_ptr GetPreview (void) const { return mpPreview; } - inline void SetPreview (const ::boost::shared_ptr& rpPreview); + + PreviewType GetPreview (void) const { return maPreview; } + inline void SetPreview (const PreviewType& rPreview); bool HasPreview (void) const; + + PreviewType GetMarkedPreview (void) const { return maMarkedPreview; } + inline void SetMarkedPreview (const PreviewType& rMarkePreview); + bool HasMarkedPreview (void) const; + bool HasReplacement (void) const { return (mpReplacement.get() != NULL); } inline bool HasLosslessReplacement (void) const; - void Clear (void) { mpPreview.reset(); mpReplacement.reset(); mpCompressor.reset(); } + void Clear (void) { maPreview.GetBitmap().SetEmpty(); maMarkedPreview.GetBitmap().SetEmpty(); + mpReplacement.reset(); mpCompressor.reset(); } void Invalidate (void) { mpReplacement.reset(); mpCompressor.reset(); mbIsUpToDate = false; } bool IsPrecious (void) const { return mbIsPrecious; } void SetPrecious (bool bIsPrecious) { mbIsPrecious = bIsPrecious; } private: - ::boost::shared_ptr mpPreview; + PreviewType maPreview; + PreviewType maMarkedPreview; ::boost::shared_ptr mpReplacement; ::boost::shared_ptr mpCompressor; Size maBitmapSize; @@ -229,7 +235,7 @@ bool BitmapCache::BitmapIsUpToDate (const CacheKey& rKey) -::boost::shared_ptr BitmapCache::GetBitmap (const CacheKey& rKey) +PreviewType BitmapCache::GetBitmap (const CacheKey& rKey) { ::osl::MutexGuard aGuard (maMutex); @@ -238,10 +244,9 @@ bool BitmapCache::BitmapIsUpToDate (const CacheKey& rKey) { // Create an empty bitmap for the given key that acts as placeholder // until we are given the real one. Mark it as not being up to date. - SetBitmap (rKey, ::boost::shared_ptr(new BitmapEx()), false); + SetBitmap(rKey, PreviewType(), false); iEntry = mpBitmapContainer->find(rKey); iEntry->second.SetUpToDate(false); - SSCD_SET_UPTODATE(iEntry->first,false); } else { @@ -261,6 +266,23 @@ bool BitmapCache::BitmapIsUpToDate (const CacheKey& rKey) +PreviewType BitmapCache::GetMarkedBitmap (const CacheKey& rKey) +{ + ::osl::MutexGuard aGuard (maMutex); + + CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey)); + if (iEntry != mpBitmapContainer->end()) + { + iEntry->second.SetAccessTime(mnCurrentAccessTime++); + return iEntry->second.GetMarkedPreview(); + } + else + return PreviewType(); +} + + + + void BitmapCache::ReleaseBitmap (const CacheKey& rKey) { ::osl::MutexGuard aGuard (maMutex); @@ -276,7 +298,7 @@ void BitmapCache::ReleaseBitmap (const CacheKey& rKey) -void BitmapCache::InvalidateBitmap (const CacheKey& rKey) +bool BitmapCache::InvalidateBitmap (const CacheKey& rKey) { ::osl::MutexGuard aGuard (maMutex); @@ -284,7 +306,6 @@ void BitmapCache::InvalidateBitmap (const CacheKey& rKey) if (iEntry != mpBitmapContainer->end()) { iEntry->second.SetUpToDate(false); - SSCD_SET_UPTODATE(iEntry->first,false); // When there is a preview then we release the replacement. The // preview itself is kept until a new one is created. @@ -292,10 +313,12 @@ void BitmapCache::InvalidateBitmap (const CacheKey& rKey) { UpdateCacheSize(iEntry->second, REMOVE); iEntry->second.Invalidate(); - SSCD_SET_UPTODATE(iEntry->first,false); UpdateCacheSize(iEntry->second, ADD); } + return true; } + else + return false; } @@ -309,7 +332,6 @@ void BitmapCache::InvalidateCache (void) for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry) { iEntry->second.Invalidate(); - SSCD_SET_UPTODATE(iEntry->first,false); } ReCalculateTotalCacheSize(); } @@ -319,7 +341,7 @@ void BitmapCache::InvalidateCache (void) void BitmapCache::SetBitmap ( const CacheKey& rKey, - const ::boost::shared_ptr& rpPreview, + const PreviewType& rPreview, bool bIsPrecious) { ::osl::MutexGuard aGuard (maMutex); @@ -328,16 +350,15 @@ void BitmapCache::SetBitmap ( if (iEntry != mpBitmapContainer->end()) { UpdateCacheSize(iEntry->second, REMOVE); - iEntry->second.SetPreview(rpPreview); + iEntry->second.SetPreview(rPreview); iEntry->second.SetUpToDate(true); - SSCD_SET_UPTODATE(iEntry->first,true); iEntry->second.SetAccessTime(mnCurrentAccessTime++); } else { iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type ( rKey, - CacheEntry (rpPreview, mnCurrentAccessTime++, bIsPrecious)) + CacheEntry(rPreview, mnCurrentAccessTime++, bIsPrecious)) ).first; } @@ -348,6 +369,25 @@ void BitmapCache::SetBitmap ( +void BitmapCache::SetMarkedBitmap ( + const CacheKey& rKey, + const PreviewType& rPreview) +{ + ::osl::MutexGuard aGuard (maMutex); + + CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey)); + if (iEntry != mpBitmapContainer->end()) + { + UpdateCacheSize(iEntry->second, REMOVE); + iEntry->second.SetMarkedPreview(rPreview); + iEntry->second.SetAccessTime(mnCurrentAccessTime++); + UpdateCacheSize(iEntry->second, ADD); + } +} + + + + bool BitmapCache::IsPrecious (const CacheKey& rKey) { ::osl::MutexGuard aGuard (maMutex); @@ -380,9 +420,7 @@ void BitmapCache::SetPrecious (const CacheKey& rKey, bool bIsPrecious) { iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type ( rKey, - CacheEntry ( - ::boost::shared_ptr(), - mnCurrentAccessTime++, bIsPrecious)) + CacheEntry(PreviewType(), mnCurrentAccessTime++, bIsPrecious)) ).first; UpdateCacheSize(iEntry->second, ADD); } @@ -540,7 +578,8 @@ void BitmapCache::UpdateCacheSize (const CacheEntry& rEntry, CacheOperation eOpe BitmapCache::CacheEntry::CacheEntry( sal_Int32 nLastAccessTime, bool bIsPrecious) - : mpPreview(), + : maPreview(), + maMarkedPreview(), mbIsUpToDate(true), mnLastAccessTime(nLastAccessTime), mbIsPrecious(bIsPrecious) @@ -551,10 +590,11 @@ BitmapCache::CacheEntry::CacheEntry( BitmapCache::CacheEntry::CacheEntry( - const ::boost::shared_ptr& rpPreview, + const PreviewType& rPreview, sal_Int32 nLastAccessTime, bool bIsPrecious) - : mpPreview(rpPreview), + : maPreview(rPreview), + maMarkedPreview(), mbIsUpToDate(true), mnLastAccessTime(nLastAccessTime), mbIsPrecious(bIsPrecious) @@ -569,7 +609,8 @@ inline void BitmapCache::CacheEntry::Recycle (const CacheEntry& rEntry) if ((rEntry.HasPreview() || rEntry.HasLosslessReplacement()) && ! (HasPreview() || HasLosslessReplacement())) { - mpPreview = rEntry.mpPreview; + maPreview = rEntry.maPreview; + maMarkedPreview = rEntry.maMarkedPreview; mpReplacement = rEntry.mpReplacement; mpCompressor = rEntry.mpCompressor; mnLastAccessTime = rEntry.mnLastAccessTime; @@ -583,8 +624,8 @@ inline void BitmapCache::CacheEntry::Recycle (const CacheEntry& rEntry) inline sal_Int32 BitmapCache::CacheEntry::GetMemorySize (void) const { sal_Int32 nSize (0); - if (mpPreview.get() != NULL) - nSize += mpPreview->GetSizeBytes(); + nSize += maPreview.GetBitmap().GetSizeBytes(); + nSize += maMarkedPreview.GetBitmap().GetSizeBytes(); if (mpReplacement.get() != NULL) nSize += mpReplacement->GetMemorySize(); return nSize; @@ -595,14 +636,14 @@ inline sal_Int32 BitmapCache::CacheEntry::GetMemorySize (void) const void BitmapCache::CacheEntry::Compress (const ::boost::shared_ptr& rpCompressor) { - if (mpPreview.get() != NULL) + if ( ! maPreview.IsEmpty()) { if (mpReplacement.get() == NULL) { - mpReplacement = rpCompressor->Compress(mpPreview); + mpReplacement = rpCompressor->Compress(maPreview); #ifdef VERBOSE - sal_uInt32 nOldSize (mpPreview->GetSizeBytes()); + sal_uInt32 nOldSize (maPreview.GetSizeBytes()); sal_uInt32 nNewSize (mpReplacement.get()!=NULL ? mpReplacement->GetMemorySize() : 0); if (nOldSize == 0) nOldSize = 1; @@ -617,7 +658,8 @@ void BitmapCache::CacheEntry::Compress (const ::boost::shared_ptrDecompress(*mpReplacement); + maPreview = mpCompressor->Decompress(*mpReplacement); + maMarkedPreview.GetBitmap().SetEmpty(); if ( ! mpCompressor->IsLossless()) mbIsUpToDate = false; } @@ -636,9 +679,10 @@ inline void BitmapCache::CacheEntry::Decompress (void) -inline void BitmapCache::CacheEntry::SetPreview (const ::boost::shared_ptr& rpPreview) +inline void BitmapCache::CacheEntry::SetPreview (const PreviewType& rPreview) { - mpPreview = rpPreview; + maPreview = rPreview; + maMarkedPreview.GetBitmap().SetEmpty(); mpReplacement.reset(); mpCompressor.reset(); } @@ -648,10 +692,23 @@ inline void BitmapCache::CacheEntry::SetPreview (const ::boost::shared_ptrGetSizePixel().Width()>0 && mpPreview->GetSizePixel().Height()>0; - else - return false; + return ! maPreview.IsEmpty(); +} + + + + +inline void BitmapCache::CacheEntry::SetMarkedPreview (const PreviewType& rMarkedPreview) +{ + maMarkedPreview = rMarkedPreview; +} + + + + +bool BitmapCache::CacheEntry::HasMarkedPreview (void) const +{ + return ! maMarkedPreview.IsEmpty(); } diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx b/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx index 2c8fbc24b626..d35db6b542da 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapCache.hxx @@ -30,10 +30,11 @@ class SdrPage; +#include "cache/SlsPreviewType.hxx" #include #include -#include #include +#include #include namespace sd { namespace slidesorter { namespace cache { @@ -48,6 +49,10 @@ class BitmapCompressor; compaction algorithms to determine which previews may be compressed or even discarded and which have to remain in their original form. The precious flag is usually set for the visible previews. + + Additionally to the actual preview there is an optional marked preview. + This is used for slides excluded from the slide show which have a preview + that shows a mark (some sort of bitmap overlay) to that effect. */ class BitmapCache { @@ -106,16 +111,25 @@ public: /** Return the preview bitmap for the given contact object. */ - ::boost::shared_ptr GetBitmap (const CacheKey& rKey); + PreviewType GetBitmap (const CacheKey& rKey); + + /** Return the marked preview bitmap for the given contact object. + */ + PreviewType GetMarkedBitmap (const CacheKey& rKey); /** Release the reference to the preview bitmap that is associated with the given key. */ void ReleaseBitmap (const CacheKey& rKey); - /** Mark the specified preview bitmap as not being up-to-date anymore. + /** Mark the specified preview bitmap as not being up-to-date + anymore. + @return + When the key references a page in the cache then + return . When the key is not known then + is returned. */ - void InvalidateBitmap (const CacheKey& rKey); + bool InvalidateBitmap (const CacheKey& rKey); /** Mark all preview bitmaps as not being up-to-date anymore. */ @@ -125,9 +139,15 @@ public: */ void SetBitmap ( const CacheKey& rKey, - const ::boost::shared_ptr& rpPreview, + const PreviewType& rPreview, bool bIsPrecious); + /** Add or replace a marked bitmap for the given key. + */ + void SetMarkedBitmap ( + const CacheKey& rKey, + const PreviewType& rPreview); + /** Return whether the specified preview bitmap has been marked as precious. */ @@ -175,7 +195,7 @@ public: private: mutable ::osl::Mutex maMutex; - ::std::auto_ptr mpBitmapContainer; + ::boost::scoped_ptr mpBitmapContainer; /** Total size of bytes that are occupied by bitmaps in the cache for whom the slides are currently not inside the visible area. diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.cxx index 86fc72885414..7a9b5d80882a 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.cxx @@ -47,37 +47,24 @@ class NoBitmapCompression::DummyReplacement : public BitmapReplacement { public: - ::boost::shared_ptr mpPreview; + PreviewType maPreview; Size maOriginalSize; - DummyReplacement (const ::boost::shared_ptr& rpPreview) : mpPreview(rpPreview) - { - } - - virtual ~DummyReplacement(); - - virtual sal_Int32 GetMemorySize (void) const; + DummyReplacement (const PreviewType& rPreview) : maPreview(rPreview) { } + virtual ~DummyReplacement(void) {} + virtual sal_Int32 GetMemorySize (void) const { return maPreview.GetBitmap().GetSizeBytes(); } }; -NoBitmapCompression::DummyReplacement::~DummyReplacement() -{ -} -sal_Int32 NoBitmapCompression::DummyReplacement::GetMemorySize (void) const -{ - return mpPreview->GetSizeBytes(); -} -::boost::shared_ptr NoBitmapCompression::Compress ( - const ::boost::shared_ptr& rpBitmap) const +::boost::shared_ptr NoBitmapCompression::Compress (const PreviewType& rBitmap) const { - return ::boost::shared_ptr(new DummyReplacement(rpBitmap)); + return ::boost::shared_ptr(new DummyReplacement(rBitmap)); } -::boost::shared_ptr NoBitmapCompression::Decompress ( - const BitmapReplacement& rBitmapData) const +PreviewType NoBitmapCompression::Decompress (const BitmapReplacement& rBitmapData) const { - return dynamic_cast(rBitmapData).mpPreview; + return dynamic_cast(rBitmapData).maPreview; } @@ -93,8 +80,7 @@ bool NoBitmapCompression::IsLossless (void) const //===== CompressionByDeletion ================================================= -::boost::shared_ptr CompressionByDeletion::Compress ( - const ::boost::shared_ptr& ) const +::boost::shared_ptr CompressionByDeletion::Compress (const PreviewType& ) const { return ::boost::shared_ptr(); } @@ -102,12 +88,11 @@ bool NoBitmapCompression::IsLossless (void) const -::boost::shared_ptr CompressionByDeletion::Decompress ( - const BitmapReplacement& ) const +PreviewType CompressionByDeletion::Decompress (const BitmapReplacement& ) const { // Return a NULL pointer. This will eventually lead to a request for // the creation of a new one. - return ::boost::shared_ptr(); + return PreviewType(); } @@ -128,11 +113,10 @@ bool CompressionByDeletion::IsLossless (void) const class ResolutionReduction::ResolutionReducedReplacement : public BitmapReplacement { public: - ::boost::shared_ptr mpPreview; + PreviewType maPreview; Size maOriginalSize; virtual ~ResolutionReducedReplacement(); - virtual sal_Int32 GetMemorySize (void) const; }; @@ -142,23 +126,20 @@ ResolutionReduction::ResolutionReducedReplacement::~ResolutionReducedReplacement sal_Int32 ResolutionReduction::ResolutionReducedReplacement::GetMemorySize (void) const { - if (mpPreview.get() != NULL) - return mpPreview->GetSizeBytes(); - else - return 0; + return maPreview.GetBitmap().GetSizeBytes(); } ::boost::shared_ptr ResolutionReduction::Compress ( - const ::boost::shared_ptr& rpBitmap) const + const PreviewType& rBitmap) const { ResolutionReducedReplacement* pResult = new ResolutionReducedReplacement(); - pResult->mpPreview.reset(new BitmapEx(*rpBitmap)); - Size aSize (rpBitmap->GetSizePixel()); + pResult->maPreview = rBitmap; + Size aSize (rBitmap.GetBitmap().GetSizePixel()); pResult->maOriginalSize = aSize; if (aSize.Width()>0 && aSize.Width()mpPreview->Scale(Size(mnWidth,nHeight)); + pResult->maPreview.GetBitmap().Scale(Size(mnWidth,nHeight)); } return ::boost::shared_ptr(pResult); @@ -167,22 +148,21 @@ sal_Int32 ResolutionReduction::ResolutionReducedReplacement::GetMemorySize (void -::boost::shared_ptr ResolutionReduction::Decompress ( - const BitmapReplacement& rBitmapData) const +PreviewType ResolutionReduction::Decompress (const BitmapReplacement& rBitmapData) const { - ::boost::shared_ptr pResult; + PreviewType aResult; const ResolutionReducedReplacement* pData ( dynamic_cast(&rBitmapData)); - if (pData->mpPreview.get() != NULL) + if ( ! pData->maPreview.GetBitmap().IsEmpty()) { - pResult.reset(new BitmapEx(*pData->mpPreview)); + aResult = pData->maPreview; if (pData->maOriginalSize.Width() > mnWidth) - pResult->Scale(pData->maOriginalSize); + aResult.GetBitmap().Scale(pData->maOriginalSize); } - return pResult; + return aResult; } @@ -223,15 +203,14 @@ public: -::boost::shared_ptr PngCompression::Compress ( - const ::boost::shared_ptr& rpBitmap) const +::boost::shared_ptr PngCompression::Compress (const PreviewType& rBitmap) const { - ::vcl::PNGWriter aWriter (*rpBitmap); + ::vcl::PNGWriter aWriter (rBitmap.GetBitmap()); SvMemoryStream aStream (32768, 32768); aWriter.Write(aStream); PngReplacement* pResult = new PngReplacement(); - pResult->maImageSize = rpBitmap->GetSizePixel(); + pResult->maImageSize = rBitmap.GetBitmap().GetSizePixel(); pResult->mnDataSize = aStream.Tell(); pResult->mpData = new char[pResult->mnDataSize]; memcpy(pResult->mpData, aStream.GetData(), pResult->mnDataSize); @@ -242,21 +221,19 @@ public: -::boost::shared_ptr PngCompression::Decompress ( +PreviewType PngCompression::Decompress ( const BitmapReplacement& rBitmapData) const { - BitmapEx* pResult = NULL; + PreviewType aResult; const PngReplacement* pData (dynamic_cast(&rBitmapData)); if (pData != NULL) { SvMemoryStream aStream (pData->mpData, pData->mnDataSize, STREAM_READ); ::vcl::PNGReader aReader (aStream); - pResult = new BitmapEx(aReader.Read()); + aResult = PreviewType::Create(aReader.Read().GetBitmap()); } -// sal_Int32 nRatio ((100L * (ULONG)pResult->GetSizeBytes()) / (ULONG)pData->mnDataSize); - - return ::boost::shared_ptr(pResult); + return aResult; } diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.hxx b/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.hxx index cd564ddddcfd..94af70dce2b2 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.hxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapCompressor.hxx @@ -28,11 +28,11 @@ #ifndef SD_SLIDESORTER_BITMAP_COMPRESSOR_HXX #define SD_SLIDESORTER_BITMAP_COMPRESSOR_HXX +#include "cache/SlsPreviewType.hxx" #include #include #include -class BitmapEx; namespace sd { namespace slidesorter { namespace cache { @@ -48,8 +48,7 @@ public: /** Compress the given bitmap into a replacement format that is specific to the compressor class. */ - virtual ::boost::shared_ptr Compress ( - const ::boost::shared_ptr& rpBitmap) const = 0; + virtual ::boost::shared_ptr Compress (const PreviewType& rBitmap) const = 0; /** Decompress the given replacement data into a preview bitmap. Depending on the compression technique the returned bitmap may @@ -58,7 +57,7 @@ public: task of the caller to create a new preview bitmap if the returned one is not as desired. */ - virtual ::boost::shared_ptr Decompress (const BitmapReplacement& rBitmapData)const=0; + virtual PreviewType Decompress (const BitmapReplacement& rBitmapData)const=0; /** Return whether the compression and decompression is lossless. This value is used by the caller of Decompress() to decide whether to use @@ -91,9 +90,8 @@ class NoBitmapCompression { class DummyReplacement; public: - virtual ::boost::shared_ptr Compress ( - const ::boost::shared_ptr& rpBitmap) const; - virtual ::boost::shared_ptr Decompress (const BitmapReplacement& rBitmapData) const; + virtual ::boost::shared_ptr Compress (const PreviewType& rpBitmap) const; + virtual PreviewType Decompress (const BitmapReplacement& rBitmapData) const; virtual bool IsLossless (void) const; }; @@ -109,9 +107,8 @@ class CompressionByDeletion : public BitmapCompressor { public: - virtual ::boost::shared_ptr Compress ( - const ::boost::shared_ptr& rpBitmap) const; - virtual ::boost::shared_ptr Decompress (const BitmapReplacement& rBitmapData) const; + virtual ::boost::shared_ptr Compress (const PreviewType& rBitmap) const; + virtual PreviewType Decompress (const BitmapReplacement& rBitmapData) const; virtual bool IsLossless (void) const; }; @@ -129,11 +126,10 @@ class ResolutionReduction class ResolutionReducedReplacement; static const sal_Int32 mnWidth = 100; public: - virtual ::boost::shared_ptr Compress ( - const ::boost::shared_ptr& rpBitmap) const; + virtual ::boost::shared_ptr Compress (const PreviewType& rpBitmap) const; /** Scale the replacement bitmap up to the original size. */ - virtual ::boost::shared_ptr Decompress (const BitmapReplacement& rBitmapData) const; + virtual PreviewType Decompress (const BitmapReplacement& rBitmapData) const; virtual bool IsLossless (void) const; }; @@ -148,9 +144,8 @@ class PngCompression { class PngReplacement; public: - virtual ::boost::shared_ptr Compress ( - const ::boost::shared_ptr& rpBitmap) const; - virtual ::boost::shared_ptr Decompress (const BitmapReplacement& rBitmapData) const; + virtual ::boost::shared_ptr Compress (const PreviewType& rBitmap) const; + virtual PreviewType Decompress (const BitmapReplacement& rBitmapData) const; virtual bool IsLossless (void) const; }; diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx index c403dfb407da..d7ffe735d204 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx @@ -43,6 +43,8 @@ #include const static sal_Int32 gnSuperSampleFactor (2); +const static bool gbAllowSuperSampling (false); + namespace sd { namespace slidesorter { namespace view { class SlideSorterView; @@ -66,59 +68,25 @@ BitmapFactory::~BitmapFactory (void) -::boost::shared_ptr BitmapFactory::CreateBitmap ( +PreviewType BitmapFactory::CreateBitmap ( const SdPage& rPage, const Size& rPixelSize, const bool bDoSuperSampling) { - (void)bDoSuperSampling; Size aSize (rPixelSize); - bool bDo (false);//bDoSuperSampling); - if (bDo) + if (bDoSuperSampling && gbAllowSuperSampling) { aSize.Width() *= gnSuperSampleFactor; aSize.Height() *= gnSuperSampleFactor; } - const Image aPreview (maRenderer.RenderPage (&rPage, aSize, String())); - - ::boost::shared_ptr pPreview (new BitmapEx(aPreview.GetBitmapEx())); - if (bDo) + Bitmap aPreview (maRenderer.RenderPage (&rPage, aSize, String()).GetBitmapEx().GetBitmap()); + if (bDoSuperSampling && gbAllowSuperSampling) { -#if 1 - const sal_Int32 nSuperSampleCount (gnSuperSampleFactor * gnSuperSampleFactor); - BitmapReadAccess* pRA = pPreview->GetBitmap().AcquireReadAccess(); - Bitmap aBitmap (rPixelSize, pPreview->GetBitCount()); - BitmapWriteAccess* pWA = aBitmap.AcquireWriteAccess(); - const sal_Int32 nWidth (pRA->Width()); - const sal_Int32 nHeight (pRA->Height()); - for (sal_Int32 nY=0; nYGetColor(nY+nV, nX+nU)); - nRed += aColor.GetRed(); - nGreen += aColor.GetGreen(); - nBlue += aColor.GetBlue(); - } - pWA->SetPixel(nY/gnSuperSampleFactor, nX/gnSuperSampleFactor, - BitmapColor( - nRed/nSuperSampleCount, - nGreen/nSuperSampleCount, - nBlue/nSuperSampleCount)); - } - pPreview.reset(new BitmapEx(aBitmap)); -#else - pPreview->Scale(rPixelSize, BMP_SCALE_INTERPOLATE); -#endif + aPreview.Scale(rPixelSize, BMP_SCALE_INTERPOLATE); } - return pPreview; + return PreviewType::Create(aPreview); } diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx index 74ed687a312d..3a24cf51f0ae 100644 --- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx +++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.hxx @@ -29,9 +29,9 @@ #define SD_SLIDESORTER_PREVIEW_BITMAP_FACTORY_HXX #include "PreviewRenderer.hxx" +#include "cache/SlsPreviewType.hxx" #include -class BitmapEx; class SdPage; class Size; @@ -50,7 +50,7 @@ public: BitmapFactory (void); ~BitmapFactory (void); - ::boost::shared_ptr CreateBitmap ( + PreviewType CreateBitmap ( const SdPage& rPage, const Size& rPixelSize, const bool bDoSuperSampling); diff --git a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx index c2c3985a414a..01e15b5dd8b1 100644 --- a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx +++ b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.cxx @@ -131,32 +131,32 @@ void GenericPageCache::ChangePreviewSize ( -BitmapEx GenericPageCache::GetPreviewBitmap ( +PreviewType GenericPageCache::GetPreviewBitmap ( const CacheKey aKey, const bool bResize) { OSL_ASSERT(aKey != NULL); - BitmapEx aPreview; + PreviewType aPreview; bool bMayBeUpToDate = true; ProvideCacheAndProcessor(); const SdrPage* pPage = mpCacheContext->GetPage(aKey); if (mpBitmapCache->HasBitmap(pPage)) { - ::boost::shared_ptr pPreview(mpBitmapCache->GetBitmap(pPage)); - OSL_ASSERT(pPreview.get() != NULL); - aPreview = *pPreview; - const Size aBitmapSize (aPreview.GetSizePixel()); - if (bResize && aBitmapSize != maPreviewSize) + aPreview = mpBitmapCache->GetBitmap(pPage); + const Size aBitmapSize (aPreview.GetBitmap().GetSizePixel()); + if (aBitmapSize != maPreviewSize) { // Scale the bitmap to the desired size when that is possible, // i.e. the bitmap is not empty. - if (aBitmapSize.Width()>0 && aBitmapSize.Height()>0) + if (bResize && aBitmapSize.Width()>0 && aBitmapSize.Height()>0) { - aPreview.Scale(maPreviewSize, BMP_SCALE_FAST); + aPreview.GetBitmap().Scale(maPreviewSize, BMP_SCALE_FAST); } + bMayBeUpToDate = false; } - bMayBeUpToDate = true; + else + bMayBeUpToDate = true; } else bMayBeUpToDate = false; @@ -172,6 +172,46 @@ BitmapEx GenericPageCache::GetPreviewBitmap ( +PreviewType GenericPageCache::GetMarkedPreviewBitmap ( + const CacheKey aKey, + const bool bResize) +{ + OSL_ASSERT(aKey != NULL); + + ProvideCacheAndProcessor(); + const SdrPage* pPage = mpCacheContext->GetPage(aKey); + PreviewType aMarkedPreview (mpBitmapCache->GetMarkedBitmap(pPage)); + const Size aBitmapSize (aMarkedPreview.GetBitmap().GetSizePixel()); + if (bResize && aBitmapSize != maPreviewSize) + { + // Scale the bitmap to the desired size when that is possible, + // i.e. the bitmap is not empty. + if (aBitmapSize.Width()>0 && aBitmapSize.Height()>0) + { + aMarkedPreview.GetBitmap().Scale(maPreviewSize, BMP_SCALE_FAST); + } + } + + return aMarkedPreview; +} + + + + +void GenericPageCache::SetMarkedPreviewBitmap ( + const CacheKey aKey, + const PreviewType& rMarkedBitmap) +{ + OSL_ASSERT(aKey != NULL); + + ProvideCacheAndProcessor(); + const SdrPage* pPage = mpCacheContext->GetPage(aKey); + mpBitmapCache->SetMarkedBitmap(pPage, rMarkedBitmap); +} + + + + void GenericPageCache::RequestPreviewBitmap ( const CacheKey aKey, const bool bMayBeUpToDate) @@ -188,8 +228,8 @@ void GenericPageCache::RequestPreviewBitmap ( bIsUpToDate = mpBitmapCache->BitmapIsUpToDate (pPage); if (bIsUpToDate) { - ::boost::shared_ptr pPreview (mpBitmapCache->GetBitmap(pPage)); - if (pPreview.get()==NULL || pPreview->GetSizePixel()!=maPreviewSize) + const PreviewType aPreview (mpBitmapCache->GetBitmap(pPage)); + if (aPreview.IsEmpty() || aPreview.GetBitmap().GetSizePixel()!=maPreviewSize) bIsUpToDate = false; } @@ -212,10 +252,12 @@ void GenericPageCache::RequestPreviewBitmap ( -void GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey) +bool GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey) { if (mpBitmapCache.get() != NULL) - mpBitmapCache->InvalidateBitmap(mpCacheContext->GetPage(aKey)); + return mpBitmapCache->InvalidateBitmap(mpCacheContext->GetPage(aKey)); + else + return false; } diff --git a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx index 1d1ee0f1f06e..540bf6d227af 100644 --- a/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx +++ b/sd/source/ui/slidesorter/cache/SlsGenericPageCache.hxx @@ -30,8 +30,7 @@ #include "SlideSorter.hxx" #include "SlsRequestQueue.hxx" -#include "SlsQueueProcessor.hxx" -#include +#include "cache/SlsPreviewType.hxx" #include namespace sd { namespace slidesorter { namespace cache { @@ -87,9 +86,15 @@ public: Returns a bitmap that is either empty, contains a scaled (up or down) version or is the requested bitmap. */ - BitmapEx GetPreviewBitmap ( + PreviewType GetPreviewBitmap ( const CacheKey aKey, const bool bResize); + PreviewType GetMarkedPreviewBitmap ( + const CacheKey aKey, + const bool bResize); + void SetMarkedPreviewBitmap ( + const CacheKey aKey, + const PreviewType& rMarkedBitmap); /** When the requested preview bitmap does not yet exist or is not up-to-date then the rendering of one is scheduled. Otherwise this @@ -110,8 +115,10 @@ public: /** Tell the cache to replace the bitmap associated with the given request data with a new one that reflects recent changes in the content of the page object. + @return + When the key is kown then return . */ - void InvalidatePreviewBitmap (const CacheKey aKey); + bool InvalidatePreviewBitmap (const CacheKey aKey); /** Call this method when a view-object-contact object is being deleted and does not need (a) its current bitmap in the cache and (b) a diff --git a/sd/source/ui/slidesorter/cache/SlsPageCache.cxx b/sd/source/ui/slidesorter/cache/SlsPageCache.cxx index 4ca6464df98a..d59ad2c32259 100644 --- a/sd/source/ui/slidesorter/cache/SlsPageCache.cxx +++ b/sd/source/ui/slidesorter/cache/SlsPageCache.cxx @@ -75,7 +75,7 @@ void PageCache::ChangeSize ( -BitmapEx PageCache::GetPreviewBitmap ( +PreviewType PageCache::GetPreviewBitmap ( const CacheKey aKey, const bool bResize) { @@ -85,6 +85,26 @@ BitmapEx PageCache::GetPreviewBitmap ( +PreviewType PageCache::GetMarkedPreviewBitmap ( + const CacheKey aKey, + const bool bResize) +{ + return mpImplementation->GetMarkedPreviewBitmap(aKey, bResize); +} + + + + +void PageCache::SetMarkedPreviewBitmap ( + const CacheKey aKey, + const PreviewType& rMarkedBitmap) +{ + mpImplementation->SetMarkedPreviewBitmap(aKey, rMarkedBitmap); +} + + + + void PageCache::RequestPreviewBitmap (const CacheKey aKey) { return mpImplementation->RequestPreviewBitmap(aKey); @@ -97,8 +117,7 @@ void PageCache::InvalidatePreviewBitmap ( const CacheKey aKey, const bool bRequestPreview) { - mpImplementation->InvalidatePreviewBitmap(aKey); - if (bRequestPreview) + if (mpImplementation->InvalidatePreviewBitmap(aKey) && bRequestPreview) RequestPreviewBitmap(aKey); } diff --git a/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx b/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx index 01d7d45a32b0..820288de331d 100644 --- a/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx +++ b/sd/source/ui/slidesorter/cache/SlsPageCacheManager.cxx @@ -397,6 +397,16 @@ void PageCacheManager::InvalidateAllCaches (void) +void PageCacheManager::ReleasePreviewBitmap (const SdrPage* pPage) +{ + PageCacheContainer::iterator iCache; + for (iCache=mpPageCaches->begin(); iCache!=mpPageCaches->end(); ++iCache) + iCache->second->ReleaseBitmap(pPage); +} + + + + ::boost::shared_ptr PageCacheManager::GetRecentlyUsedCache ( DocumentKey pDocument, const Size& rPreviewSize) diff --git a/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx b/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx index 4ee928edbfcd..e4598927d75c 100644 --- a/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx +++ b/sd/source/ui/slidesorter/cache/SlsQueueProcessor.cxx @@ -213,15 +213,12 @@ void QueueProcessor::ProcessOneRequest ( const SdPage* pSdPage = dynamic_cast(mpCacheContext->GetPage(aKey)); if (pSdPage != NULL) { - const ::boost::shared_ptr pPreview ( + const PreviewType aPreview ( maBitmapFactory.CreateBitmap(*pSdPage, maPreviewSize, mbDoSuperSampling)); - mpCache->SetBitmap ( - pSdPage, - pPreview, - ePriorityClass!=NOT_VISIBLE); + mpCache->SetBitmap (pSdPage, aPreview, ePriorityClass!=NOT_VISIBLE); // Initiate a repaint of the new preview. - mpCacheContext->NotifyPreviewCreation(aKey, pPreview); + mpCacheContext->NotifyPreviewCreation(aKey, aPreview); } } } diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 6eae261ec1d2..0f758012c6ac 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -96,7 +96,6 @@ #include #include - using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::sd::slidesorter::model; @@ -123,6 +122,7 @@ SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter) mpVisibleAreaManager(new VisibleAreaManager(rSlideSorter)), mpListener(), mnModelChangeLockCount(0), + mbIsForcedRearrangePending(false), mbPreModelChangeDone(false), mbPostModelChangePending(false), maSelectionBeforeSwitch(), @@ -528,7 +528,9 @@ void SlideSorterController::UnlockModelChange (void) { mnModelChangeLockCount -= 1; if (mnModelChangeLockCount==0 && mbPostModelChangePending) + { PostModelChange(); + } } @@ -574,7 +576,7 @@ void SlideSorterController::PostModelChange (void) // The visibility of the scroll bars may have to be changed. Then // the size of the view has to change, too. Let Rearrange() handle // that. - Rearrange(); + Rearrange(mbIsForcedRearrangePending); } if (mrSlideSorter.GetViewShell() != NULL) @@ -790,6 +792,14 @@ Rectangle SlideSorterController::Rearrange (bool bForce) if (aNewContentArea.IsEmpty()) return aNewContentArea; + if (mnModelChangeLockCount>0) + { + mbIsForcedRearrangePending |= bForce; + return aNewContentArea; + } + else + mbIsForcedRearrangePending = false; + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { @@ -822,7 +832,7 @@ Rectangle SlideSorterController::Rearrange (bool bForce) GetScrollBarManager().UpdateScrollBars(false, !bForce); // Keep the current slide in the visible area. - GetVisibleAreaManager().RequestVisible(GetCurrentSlideManager()->GetCurrentSlide()); + GetVisibleAreaManager().RequestCurrentSlideVisible(); } return aNewContentArea; diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx index 32a0a6dafbb6..6131c8629204 100644 --- a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx +++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx @@ -418,8 +418,8 @@ void Clipboard::CreateSlideTransferable ( model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); if ( ! pDescriptor || pDescriptor->GetPage()==NULL) continue; - Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false) - .GetBitmap()); + Bitmap aPreview ( + pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false).GetBitmap()); aRepresentatives.push_back(aPreview); if (aRepresentatives.size() >= 3) break; @@ -429,11 +429,6 @@ void Clipboard::CreateSlideTransferable ( { mrSlideSorter.GetView().BrkAction(); SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument(); - ::boost::shared_ptr pDragAndDropContext; - ::rtl::Reference pSelectionFunction ( - mrSlideSorter.GetController().GetCurrentSelectionFunction()); - if (pSelectionFunction.is()) - pDragAndDropContext = pSelectionFunction->GetDragAndDropContext(); SdTransferable* pTransferable = new Transferable ( pDocument, NULL, @@ -538,10 +533,7 @@ void Clipboard::DragFinished (sal_Int8 nDropAction) mrController.GetSelectionManager()->DeleteSelectedPages (); } mpUndoContext.reset(); - mrSlideSorter.GetController().GetSelectionManager()->GetSelectionObserver()->EndObservation(); - - // if (nDropAction != DND_ACTION_NONE) - // SelectPages(); + mpSelectionObserverContext.reset(); } @@ -570,7 +562,7 @@ sal_Int8 Clipboard::AcceptDrop ( USHORT nPage, USHORT nLayer) { - sal_Int8 nResult = DND_ACTION_NONE; + sal_Int8 nAction (DND_ACTION_NONE); const Clipboard::DropType eDropType (IsDropAccepted()); @@ -579,7 +571,7 @@ sal_Int8 Clipboard::AcceptDrop ( case DT_PAGE: { // Accept a drop. - nResult = rEvent.mnAction; + nAction = rEvent.mnAction; // Use the copy action when the drop action is the default, i.e. not // explicitly set to move or link, and when the source and @@ -592,7 +584,11 @@ sal_Int8 Clipboard::AcceptDrop ( && (mrSlideSorter.GetModel().GetDocument()->GetDocSh() != pDragTransferable->GetPageDocShell())) { - nResult = DND_ACTION_COPY; + nAction = DND_ACTION_COPY; + } + else if (mrController.GetInsertionIndicatorHandler()->IsInsertionTrivial(nAction)) + { + nAction = DND_ACTION_NONE; } // Show the insertion marker and the substitution for a drop. @@ -600,7 +596,7 @@ sal_Int8 Clipboard::AcceptDrop ( SelectionFunction* pSelectionFunction = dynamic_cast( mrSlideSorter.GetViewShell()->GetCurrentFunction().get()); if (pSelectionFunction != NULL) - pSelectionFunction->MouseDragged(rEvent, nResult); + pSelectionFunction->MouseDragged(rEvent, nAction); // Scroll the window when the mouse reaches the window border. // mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel); @@ -608,7 +604,7 @@ sal_Int8 Clipboard::AcceptDrop ( break; case DT_SHAPE: - nResult = ExecuteOrAcceptShapeDrop( + nAction = ExecuteOrAcceptShapeDrop( DC_ACCEPT, rEvent.maPosPixel, &rEvent, @@ -617,11 +613,13 @@ sal_Int8 Clipboard::AcceptDrop ( nPage, nLayer); break; + default: + nAction = DND_ACTION_NONE; break; } - return nResult; + return nAction; } @@ -644,25 +642,30 @@ sal_Int8 Clipboard::ExecuteDrop ( const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; const Point aEventModelPosition ( pTargetWindow->PixelToLogic (rEvent.maPosPixel)); - long int nXOffset = labs (pDragTransferable->GetStartPos().X() - - aEventModelPosition.X()); - long int nYOffset = labs (pDragTransferable->GetStartPos().Y() - - aEventModelPosition.Y()); - const bool bContinue = + const sal_Int32 nXOffset (labs (pDragTransferable->GetStartPos().X() + - aEventModelPosition.X())); + const sal_Int32 nYOffset (labs (pDragTransferable->GetStartPos().Y() + - aEventModelPosition.Y())); + bool bContinue = ( pDragTransferable->GetView() != &mrSlideSorter.GetView() ) || ( nXOffset >= 2 && nYOffset >= 2 ); + ::boost::shared_ptr pInsertionIndicatorHandler( + mrController.GetInsertionIndicatorHandler()); // Get insertion position and then turn off the insertion indicator. - mrController.GetInsertionIndicatorHandler()->UpdatePosition( - aEventModelPosition, - rEvent.mnAction); + pInsertionIndicatorHandler->UpdatePosition(aEventModelPosition, rEvent.mnAction); USHORT nIndex = DetermineInsertPosition(*pDragTransferable); + // Do not process the insertion when it is trivial, + // i.e. would insert pages at their original place. + if (pInsertionIndicatorHandler->IsInsertionTrivial(rEvent.mnAction)) + bContinue = false; + // Tell the insertion indicator handler to hide before the model // is modified. Doing it later may result in page objects whose // animation state is not properly reset because they are then // in another run then before the model change. - mrController.GetInsertionIndicatorHandler()->End(Animator::AM_Immediate); + pInsertionIndicatorHandler->End(Animator::AM_Immediate); if (bContinue) { @@ -673,18 +676,15 @@ sal_Int8 Clipboard::ExecuteDrop ( mrSlideSorter.GetModel().GetDocument(), mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell(), mrSlideSorter.GetTheme())); - mrSlideSorter.GetController().GetSelectionManager() - ->GetSelectionObserver()->StartObservation(); + mpSelectionObserverContext.reset(new SelectionObserver::Context(mrSlideSorter)); HandlePageDrop(*pDragTransferable); nResult = rEvent.mnAction; - // When moving or copying inside one view then leave the - // undo context active a little longer until - // NotifyDragFinished is called and possibly some slides are - // deleted. Otherwise all actions in the target view are - // complete and - // ( pDragTransferable->GetView() != &mrSlideSorter.GetView() ) + // We leave the undo context alive for when moving or + // copying inside one view then the actions in + // NotifyDragFinished should be covered as well as + // well as the ones above. } // Notify the receiving selection function that drag-and-drop is @@ -716,6 +716,18 @@ sal_Int8 Clipboard::ExecuteDrop ( +void Clipboard::Abort (void) +{ + if (mpSelectionObserverContext) + { + mpSelectionObserverContext->Abort(); + mpSelectionObserverContext.reset(); + } +} + + + + USHORT Clipboard::DetermineInsertPosition (const SdTransferable& ) { USHORT nInsertPosition = SDRPAGE_NOTFOUND; @@ -723,7 +735,7 @@ USHORT Clipboard::DetermineInsertPosition (const SdTransferable& ) // Tell the model to move the dragged pages behind the one with the // index nInsertionIndex which first has to be transformed into an index // understandable by the document. - sal_Int32 nInsertionIndex ( + const sal_Int32 nInsertionIndex ( mrController.GetInsertionIndicatorHandler()->GetInsertionPageIndex()); // Convert to insertion index to that of an SdModel. diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx index 56beb4a90623..5a7ead7d2391 100644 --- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx @@ -92,8 +92,11 @@ void CurrentSlideManager::NotifyCurrentSlideChange (const sal_Int32 nSlideIndex) // Update the selection. mrSlideSorter.GetController().GetPageSelector().DeselectAllPages(); - if (mpCurrentSlide.get() != NULL) + if (mpCurrentSlide) + { mrSlideSorter.GetController().GetPageSelector().SelectPage(mpCurrentSlide); + mrSlideSorter.GetController().GetFocusManager().SetFocusedPage(mpCurrentSlide); + } } } diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx index 97d2a5e08881..9b3b52486f96 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx @@ -169,20 +169,6 @@ void DragAndDropContext::UpdatePosition ( -void DragAndDropContext::Show (void) -{ -} - - - - -void DragAndDropContext::Hide (void) -{ -} - - - - void DragAndDropContext::SetTargetSlideSorter ( SlideSorter* pSlideSorter, const Point aMousePosition, diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx index 3f0a4e3547d7..ead764ec84be 100644 --- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx +++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.hxx @@ -71,8 +71,6 @@ public: const InsertionIndicatorHandler::Mode eMode, const bool bAllowAutoScroll = true); - void Show (void); - void Hide (void); void SetTargetSlideSorter ( SlideSorter* pSlideSorter = NULL, const Point aMousePosition = Point(0,0), diff --git a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx index 8f3d5d05008a..8d84a57e5691 100644 --- a/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx @@ -229,7 +229,7 @@ sal_Int32 FocusManager::GetFocusedPageIndex (void) const - +/* void FocusManager::FocusPage (sal_Int32 nPageIndex) { if (nPageIndex != mnPageIndex) @@ -242,7 +242,7 @@ void FocusManager::FocusPage (sal_Int32 nPageIndex) if (HasFocus() && !IsFocusShowing()) ShowFocus(); } - +*/ @@ -267,6 +267,14 @@ void FocusManager::SetFocusedPage (sal_Int32 nPageIndex) +void FocusManager::SetFocusedPageToCurrentPage (void) +{ + SetFocusedPage(mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide()); +} + + + + bool FocusManager::IsFocusShowing (void) const { return HasFocus() && mbPageIsFocused; @@ -298,7 +306,7 @@ void FocusManager::ShowFocusIndicator ( { // Scroll the focused page object into the visible area and repaint // it, so that the focus indicator becomes visible. - mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor); + mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true); } mrSlideSorter.GetView().RequestRepaint(rpDescriptor); diff --git a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx index d7e3f52a9b18..a0b70aa1ed23 100644 --- a/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx +++ b/sd/source/ui/slidesorter/controller/SlsInsertionIndicatorHandler.cxx @@ -149,6 +149,10 @@ void InsertionIndicatorHandler::UpdatePosition ( const Point& rMouseModelPosition, const Mode eMode) { + OSL_TRACE("InsertionIndicatorHandler::UpdatePosition %d,%d, %d", + rMouseModelPosition.X(), + rMouseModelPosition.Y(), + eMode); if ( ! mbIsActive) return; @@ -201,6 +205,19 @@ void InsertionIndicatorHandler::SetPosition ( maIconSize, mrSlideSorter.GetModel())); + static sal_Int32 TargetIndex (1); + if (aInsertPosition.GetIndex() == TargetIndex) + { + const view::InsertPosition aPosition (rLayouter.GetInsertPosition( + rPoint, + maIconSize, + mrSlideSorter.GetModel())); + const view::InsertPosition aPosition2 (rLayouter.GetInsertPosition( + rPoint, + maIconSize, + mrSlideSorter.GetModel())); + } + if (maInsertPosition != aInsertPosition || meMode != eMode // || ! mpInsertionIndicatorOverlay->IsVisible() @@ -209,9 +226,10 @@ void InsertionIndicatorHandler::SetPosition ( maInsertPosition = aInsertPosition; meMode = eMode; mbIsInsertionTrivial = IsInsertionTrivial(maInsertPosition.GetIndex(), eMode); - if (maInsertPosition.GetIndex()>=0 && ! mbIsInsertionTrivial) { + OSL_TRACE("A insertion at %d is %strivial", + maInsertPosition.GetIndex(), mbIsInsertionTrivial?"":"not "); mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation()); GetInsertAnimator()->SetInsertPosition(maInsertPosition); @@ -219,6 +237,8 @@ void InsertionIndicatorHandler::SetPosition ( } else { + OSL_TRACE("B insertion at %d is %strivial", + maInsertPosition.GetIndex(), mbIsInsertionTrivial?"":"not "); GetInsertAnimator()->Reset(Animator::AM_Animated); mpInsertionIndicatorOverlay->Hide(); } @@ -289,6 +309,14 @@ bool InsertionIndicatorHandler::IsInsertionTrivial ( +bool InsertionIndicatorHandler::IsInsertionTrivial (const sal_Int8 nDndAction) +{ + return IsInsertionTrivial(GetInsertionPageIndex(), GetModeFromDndAction(nDndAction)); +} + + + + //===== InsertionIndicatorHandler::ForceShowContext =========================== InsertionIndicatorHandler::ForceShowContext::ForceShowContext ( diff --git a/sd/source/ui/slidesorter/controller/SlsListener.cxx b/sd/source/ui/slidesorter/controller/SlsListener.cxx index 93bdb9aa43ce..f4f73fd2b7cb 100644 --- a/sd/source/ui/slidesorter/controller/SlsListener.cxx +++ b/sd/source/ui/slidesorter/controller/SlsListener.cxx @@ -323,8 +323,20 @@ void Listener::Notify ( // The return value of the model call acts as filter as // to which events to pass to the selection observer. if (mrSlideSorter.GetModel().NotifyPageEvent(rSdrHint.GetPage())) + { + // The page of the hint belongs (or belonged) + // to the model. + + // Tell the cache manager that the preview + // bitmaps for a deleted page can be removed + // from all caches. + const SdrPage* pPage = rSdrHint.GetPage(); + if (pPage!=NULL && ! pPage->IsInserted()) + cache::PageCacheManager::Instance()->ReleasePreviewBitmap(pPage); + mrController.GetSelectionManager() ->GetSelectionObserver()->NotifyPageEvent(rSdrHint.GetPage()); + } if (rBroadcaster.ISA(SdDrawDocument)) { diff --git a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx index ec76256b5e97..d7a11cf89f7f 100644 --- a/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx +++ b/sd/source/ui/slidesorter/controller/SlsPageSelector.cxx @@ -202,7 +202,7 @@ void PageSelector::SelectPage (const SharedPageDescriptor& rpDescriptor) { mnSelectedPageCount ++; if ( ! mbIsMakeVisibleDisabled) - mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor); + mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true); mrSlideSorter.GetView().RequestRepaint(rpDescriptor); mpMostRecentlySelectedPage = rpDescriptor; @@ -412,18 +412,18 @@ void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending) //===== PageSelector::UpdateLock ============================================== PageSelector::UpdateLock::UpdateLock (SlideSorter& rSlideSorter) - : mrSelector(rSlideSorter.GetController().GetPageSelector()) + : mpSelector(&rSlideSorter.GetController().GetPageSelector()) { - ++mrSelector.mnUpdateLockCount; + ++mpSelector->mnUpdateLockCount; } PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector) - : mrSelector(rSelector) + : mpSelector(&rSelector) { - ++mrSelector.mnUpdateLockCount; + ++mpSelector->mnUpdateLockCount; } @@ -431,10 +431,20 @@ PageSelector::UpdateLock::UpdateLock (PageSelector& rSelector) PageSelector::UpdateLock::~UpdateLock (void) { - --mrSelector.mnUpdateLockCount; - OSL_ASSERT(mrSelector.mnUpdateLockCount >= 0); - if (mrSelector.mnUpdateLockCount == 0) - mrSelector.UpdateCurrentPage(true); + Release(); +} + +void PageSelector::UpdateLock::Release (void) +{ + if (mpSelector != NULL) + { + --mpSelector->mnUpdateLockCount; + OSL_ASSERT(mpSelector->mnUpdateLockCount >= 0); + if (mpSelector->mnUpdateLockCount == 0) + mpSelector->UpdateCurrentPage(true); + + mpSelector = NULL; + } } diff --git a/sd/source/ui/slidesorter/controller/SlsProperties.cxx b/sd/source/ui/slidesorter/controller/SlsProperties.cxx index d983e2ba679f..532047cfaefe 100644 --- a/sd/source/ui/slidesorter/controller/SlsProperties.cxx +++ b/sd/source/ui/slidesorter/controller/SlsProperties.cxx @@ -37,14 +37,16 @@ Properties::Properties (void) mbIsShowSelection(true), mbIsShowFocus(true), mbIsCenterSelection(false), - mbIsSmoothSelectionScrolling(true),//false), + mbIsSmoothSelectionScrolling(true), mbIsSuspendPreviewUpdatesDuringFullScreenPresentation(true), maBackgroundColor(Application::GetSettings().GetStyleSettings().GetWindowColor()), maTextColor(Application::GetSettings().GetStyleSettings().GetActiveTextColor()), maSelectionColor(Application::GetSettings().GetStyleSettings().GetHighlightColor()), maHighlightColor(Application::GetSettings().GetStyleSettings().GetMenuHighlightColor()), mbIsUIReadOnly(false), - mbIsOnlyPreviewTriggersMouseOver(true) + mbIsOnlyPreviewTriggersMouseOver(true), + mbIsHighContrastModeActive( + Application::GetSettings().GetStyleSettings().GetHighContrastMode()) { } @@ -64,6 +66,8 @@ void Properties::HandleDataChangeEvent (void) maTextColor = Application::GetSettings().GetStyleSettings().GetActiveTextColor(); maSelectionColor = Application::GetSettings().GetStyleSettings().GetHighlightColor(); maHighlightColor = Application::GetSettings().GetStyleSettings().GetMenuHighlightColor(); + mbIsHighContrastModeActive + = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); } @@ -258,4 +262,12 @@ void Properties::SetOnlyPreviewTriggersMouseOver (const bool bFlag) } + + +bool Properties::IsHighContrastModeActive (void) const +{ + return mbIsHighContrastModeActive; +} + + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index f6dd4d93862f..3ae1b85c214d 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -31,6 +31,7 @@ #include "SlideSorter.hxx" #include "controller/SlideSorterController.hxx" +#include "controller/SlsVisibleAreaManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "view/SlideSorterView.hxx" @@ -324,6 +325,7 @@ IMPL_LINK(ScrollBarManager, VerticalScrollBarHandler, ScrollBar*, pScrollBar) / double(pScrollBar->GetRange().Len()); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); mrSlideSorter.GetContentWindow()->SetVisibleXY (-1, nRelativePosition); + mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking(); } return TRUE; } diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx index 416f06a82616..e527d5914871 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx @@ -50,6 +50,7 @@ #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsPageObjectLayouter.hxx" +#include "view/SlsButton.hxx" #include "framework/FrameworkHelper.hxx" #include "showview.hxx" #include "ViewShellBase.hxx" @@ -72,6 +73,7 @@ #include #include #include +#include namespace { static const sal_uInt32 SINGLE_CLICK (0x00000001); @@ -88,11 +90,10 @@ static const sal_uInt32 MOUSE_DRAG (0x00000800); static const sal_uInt32 OVER_SELECTED_PAGE (0x00010000); static const sal_uInt32 OVER_UNSELECTED_PAGE (0x00020000); 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 DRAG_ACTIVE (0x01000000); -static const sal_uInt32 MULTI_SELECTOR (0x02000000); +static const sal_uInt32 OVER_BUTTON_AREA (0x00080000); +static const sal_uInt32 OVER_BUTTON (0x00100000); +static const sal_uInt32 SHIFT_MODIFIER (0x00200000); +static const sal_uInt32 CONTROL_MODIFIER (0x00400000); static const sal_uInt32 KEY_EVENT (0x10000000); @@ -102,40 +103,177 @@ static const sal_uInt32 NOT_OVER_PAGE (0x00000000); // Masks static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIFIER); +static const sal_uInt32 BUTTON_MASK (LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON); } // end of anonymous namespace -#define ONLY_PREVIEW_TRIGGERS_MOUSE_OVER + + +// 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 namespace sd { namespace slidesorter { namespace controller { +//===== SelectionFunction::EventDescriptor ==================================== -class SelectionFunction::MouseMultiSelector +class SelectionFunction::EventDescriptor { public: - /** Start a rectangle selection at the given position. + Point maMousePosition; + Point maMouseModelPosition; + model::SharedPageDescriptor mpHitDescriptor; + SdrPage* mpHitPage; + sal_uInt32 mnEventCode; + bool mbIsOverButton; + InsertionIndicatorHandler::Mode meDragMode; + bool mbMakeSelectionVisible; + bool mbIsLeaving; + + EventDescriptor ( + sal_uInt32 nEventType, + const MouseEvent& rEvent, + SlideSorter& rSlideSorter); + EventDescriptor ( + sal_uInt32 nEventType, + const AcceptDropEvent& rEvent, + const sal_Int8 nDragAction, + SlideSorter& rSlideSorter); + EventDescriptor ( + const KeyEvent& rEvent, + SlideSorter& rSlideSorter); + + void SetDragMode (const InsertionIndicatorHandler::Mode eMode); + +private: + /** Compute a numerical code that describes a mouse event and that can + be used for fast look up of the appropriate reaction. + */ + sal_uInt32 EncodeMouseEvent (const MouseEvent& rEvent) const; + + /** Compute a numerical code that describes a key event and that can + be used for fast look up of the appropriate reaction. + */ + sal_uInt32 EncodeKeyEvent (const KeyEvent& rEvent) const; + + /** Compute a numerical code that describes the current state like + whether the selection rectangle is visible or whether the page under + the mouse or the one that has the focus is selected. */ - MouseMultiSelector ( + sal_uInt32 EncodeState (void) const; +}; + + + + +//===== SelectionFunction::ModeHandler ======================================== + +class SelectionFunction::ModeHandler +{ +public: + ModeHandler ( SlideSorter& rSlideSorter, - const Point& rMouseModelPosition); - virtual ~MouseMultiSelector (void); + SelectionFunction& rSelectionFunction, + const bool bIsMouseOverIndicatorAllowed); + virtual ~ModeHandler (void); - void RestoreInitialSelection (void); + virtual Mode GetMode (void) const = 0; + virtual void Abort (void) = 0; + void ProcessEvent (EventDescriptor& rDescriptor); - /** Update the rectangle selection so that the given position becomes - the new second point of the selection rectangle. + /** Set the selection to exactly the specified page and also set it as + the current page. */ - void UpdatePosition ( + void SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor); + + /// Deselect all pages. + void DeselectAllPages (void); + void SelectOnePage (const model::SharedPageDescriptor& rpDescriptor); + + /** When the view on which this selection function is working is the + main view then the view is switched to the regular editing view. + */ + void SwitchView (const model::SharedPageDescriptor& rpDescriptor); + + void StartDrag ( const Point& rMousePosition, - const bool bAllowAutoScroll = true); + const InsertionIndicatorHandler::Mode eMode); + + bool IsMouseOverIndicatorAllowed (void) const; + +protected: + SlideSorter& mrSlideSorter; + SelectionFunction& mrSelectionFunction; + + virtual bool ProcessButtonDownEvent (EventDescriptor& rDescriptor); + virtual bool ProcessButtonUpEvent (EventDescriptor& rDescriptor); + virtual bool ProcessMotionEvent (EventDescriptor& rDescriptor); + virtual bool ProcessDragEvent (EventDescriptor& rDescriptor); + virtual bool HandleUnprocessedEvent (EventDescriptor& rDescriptor); + + void ReprocessEvent (EventDescriptor& rDescriptor); + +private: + const bool mbIsMouseOverIndicatorAllowed; +}; + + +class NormalModeHandler : public SelectionFunction::ModeHandler +{ +public: + NormalModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction); + virtual ~NormalModeHandler (void); + + virtual SelectionFunction::Mode GetMode (void) const; + virtual void Abort (void); + +protected: + virtual bool ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor); + +private: + Point maButtonDownLocation; + + /** Select all pages between and including the selection anchor and the + specified page. + */ + void RangeSelect (const model::SharedPageDescriptor& rpDescriptor); +}; + + +class MultiSelectionModeHandler : public SelectionFunction::ModeHandler +{ +public: + /** Start a rectangle selection at the given position. + */ + MultiSelectionModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction, + const Point& rMouseModelPosition, + const sal_uInt32 nEventCode); + virtual ~MultiSelectionModeHandler (void); + + virtual SelectionFunction::Mode GetMode (void) const; + virtual void Abort (void); + enum SelectionMode { SM_Normal, SM_Add, SM_Toggle }; void SetSelectionMode (const SelectionMode eSelectionMode); void SetSelectionModeFromModifier (const sal_uInt32 nEventCode); +protected: + virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool HandleUnprocessedEvent (SelectionFunction::EventDescriptor& rDescriptor); + private: - SlideSorter& mrSlideSorter; SelectionMode meSelectionMode; Point maSecondCorner; Pointer maSavedPointer; @@ -145,39 +283,64 @@ private: virtual void UpdateModelPosition (const Point& rMouseModelPosition); virtual void UpdateSelection (void); + /** Update the rectangle selection so that the given position becomes + the new second point of the selection rectangle. + */ + void UpdatePosition ( + const Point& rMousePosition, + const bool bAllowAutoScroll); + void UpdateSelectionState ( const model::SharedPageDescriptor& rpDescriptor, const bool bIsInSelection) const; }; +class DragAndDropModeHandler : public SelectionFunction::ModeHandler +{ +public: + DragAndDropModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction, + const Point& rMousePosition, + ::Window* pWindow); + virtual ~DragAndDropModeHandler (void); + + virtual SelectionFunction::Mode GetMode (void) const; + virtual void Abort (void); + +protected: + virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor); + +private: + ::boost::scoped_ptr mpDragAndDropContext; +}; -class SelectionFunction::EventDescriptor +class ButtonModeHandler : public SelectionFunction::ModeHandler { public: - Point maMousePosition; - Point maMouseModelPosition; - model::SharedPageDescriptor mpHitDescriptor; - SdrPage* mpHitPage; - sal_uInt32 mnEventCode; - sal_Int32 mnButtonIndex; - InsertionIndicatorHandler::Mode meDragMode; - bool mbMakeSelectionVisible; + ButtonModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction); + virtual ~ButtonModeHandler (void); + virtual void Abort (void); - EventDescriptor ( - sal_uInt32 nEventType, - const Point& rMousePosition, - SlideSorter& rSlideSorter); - EventDescriptor ( - const KeyEvent& rEvent, - SlideSorter& rSlideSorter); - EventDescriptor (const EventDescriptor& rDescriptor); + virtual SelectionFunction::Mode GetMode (void) const; + virtual void ProcessEvent (SelectionFunction::EventDescriptor& rDescriptor); - void SetDragMode (const InsertionIndicatorHandler::Mode eMode); +protected: + virtual bool ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor); + virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor); }; + + +//===== SelectionFunction ===================================================== + TYPEINIT1(SelectionFunction, FuPoor); @@ -195,12 +358,8 @@ SelectionFunction::SelectionFunction ( mbDragSelection(false), maInsertionMarkerBox(), mbProcessingMouseButtonDown(false), - mpDragAndDropContext(), - mpMouseMultiSelector(), - mnButtonDownPageIndex(-1), - mnButtonDownButtonIndex(-1), - mbIsDeselectionPending(false), - mnShiftKeySelectionAnchor(-1) + mnShiftKeySelectionAnchor(-1), + mpModeHandler(new NormalModeHandler(rSlideSorter, *this)) { } @@ -209,6 +368,7 @@ SelectionFunction::SelectionFunction ( SelectionFunction::~SelectionFunction (void) { + mpModeHandler.reset(); } @@ -244,33 +404,7 @@ BOOL SelectionFunction::MouseButtonDown (const MouseEvent& rEvent) BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent) { - Point aMousePosition (rEvent.GetPosPixel()); - - mrSlideSorter.GetView().UpdatePageUnderMouse( - aMousePosition, - (rEvent.GetButtons() & MOUSE_LEFT)!=0, - true); - - // Detect the mouse leaving the window. When not button is pressed then - // we can call IsLeaveWindow at the event. Otherwise we have to make an - // explicit test. - if (rEvent.IsLeaveWindow() - || ! Rectangle(Point(0,0),mpWindow->GetOutputSizePixel()).IsInside(aMousePosition)) - { - StopDragAndDrop(); - mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); - } - else - { - // Call ProcessMouseEvent() only when one of the buttons is - // pressed. This prevents calling the method on every motion. - if (rEvent.GetButtons() != 0 - && mbProcessingMouseButtonDown) - { - ProcessMouseEvent(MOUSE_MOTION, rEvent); - } - } - + ProcessMouseEvent(MOUSE_MOTION, rEvent); return TRUE; } @@ -284,7 +418,7 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent) ProcessMouseEvent(BUTTON_UP, rEvent); mbProcessingMouseButtonDown = false; - mpWindow->ReleaseMouse(); +// mpWindow->ReleaseMouse(); return TRUE; } @@ -292,63 +426,9 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent) -void SelectionFunction::MouseDragged ( - const AcceptDropEvent& rEvent, - const sal_Int8 nDragAction) -{ - const InsertionIndicatorHandler::Mode eMode ( - InsertionIndicatorHandler::GetModeFromDndAction(nDragAction));//rEvent.mnAction)); - if (rEvent.mbLeaving) - { - StopDragAndDrop(); - } - else if ( ! mpDragAndDropContext) - { - // Connect the substitution handler to this selection function. - mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter)); - const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; - mrController.GetInsertionIndicatorHandler()->Start( - pDragTransferable != NULL - && pDragTransferable->GetView()==&mrSlideSorter.GetView()); - mpDragAndDropContext->UpdatePosition(rEvent.maPosPixel, eMode); - UpdateMouseOverIndicationPermission(); - } - - // 1. Compute some frequently used values relating to the event. - ::std::auto_ptr pEventDescriptor ( - new EventDescriptor(MOUSE_DRAG, rEvent.maPosPixel, mrSlideSorter)); - - // 2. Detect whether we are dragging pages or dragging a selection rectangle. - if (mpDragAndDropContext) - pEventDescriptor->mnEventCode |= DRAG_ACTIVE; - if (mpMouseMultiSelector) - pEventDescriptor->mnEventCode |= MULTI_SELECTOR; - - // 3. Set the drag mode. - pEventDescriptor->SetDragMode(eMode); - - // 4. Process the event. - if ( ! ProcessEvent(*pEventDescriptor)) - { - OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); - } - PostProcessEvent(*pEventDescriptor); -} - - - - void SelectionFunction::NotifyDragFinished (void) { - StopDragAndDrop(); -} - - - - -::boost::shared_ptr SelectionFunction::GetDragAndDropContext (void) const -{ - return mpDragAndDropContext; + SwitchToNormalMode(); } @@ -370,8 +450,8 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor()); if (pDescriptor.get() != NULL) { - SetCurrentPage(pDescriptor); - SwitchView(pDescriptor); + mpModeHandler->SetCurrentPage(pDescriptor); + mpModeHandler->SwitchView(pDescriptor); } bResult = TRUE; } @@ -388,13 +468,8 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) case KEY_ESCAPE: // When there is an active multiselection or drag-and-drop // operation then stop that. - StopDragAndDrop(); - if (mpMouseMultiSelector) - { - mrSlideSorter.GetView().RequestRepaint( - mrSlideSorter.GetModel().RestoreSelection()); - StopMouseMultiSelection(); - } + mpModeHandler->Abort(); + SwitchToNormalMode(); bResult = TRUE; break; @@ -478,8 +553,7 @@ BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) case KEY_F10: if (rCode.IsShift()) { - DeselectAllPages(); - mrController.GetPageSelector().SelectPage( + mpModeHandler->SelectOnePage( mrSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); } break; @@ -557,8 +631,7 @@ void SelectionFunction::MoveFocus ( else { // Without shift just select the focused page. - rSelector.DeselectAllPages(); - mrController.GetPageSelector().SelectPage(pFocusedDescriptor); + mpModeHandler->SelectOnePage(pFocusedDescriptor); } } @@ -624,41 +697,6 @@ void SelectionFunction::DoPaste (void) -void SelectionFunction::StartDrag ( - const Point& rMousePosition, - const InsertionIndicatorHandler::Mode eMode) -{ - // Do not start a drag-and-drop operation when one is already active. - // (when dragging pages from one document into another, pressing a - // modifier key can trigger a MouseMotion event in the originating - // window (focus still in there). Together with the mouse button pressed - // (drag-and-drop is active) this triggers the start of drag-and-drop.) - if (SD_MOD()->pTransferDrag != NULL) - return; - - if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) - { - if (mrSlideSorter.GetViewShell() != NULL) - { - SlideSorterViewShell* pSlideSorterViewShell - = dynamic_cast(mrSlideSorter.GetViewShell()); - pSlideSorterViewShell->StartDrag (rMousePosition, mpWindow); - } - - if ( ! mpDragAndDropContext) - { - mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter)); - mrController.GetInsertionIndicatorHandler()->Start(true); - UpdateMouseOverIndicationPermission(); - } - mpDragAndDropContext->UpdatePosition(rMousePosition, eMode); - mpWindow->ReleaseMouse(); - } -} - - - - bool SelectionFunction::cancel (void) { mrController.GetFocusManager().ToggleFocus(); @@ -668,63 +706,6 @@ bool SelectionFunction::cancel (void) -void SelectionFunction::UpdateMouseOverIndicationPermission (void) -{ - - // In some modes (dragging, moving) the mouse over indicator is only - // annoying. Turn it off in these cases. - mrSlideSorter.GetView().SetIsMouseOverIndicationAllowed( - ! mpDragAndDropContext - && ! mpMouseMultiSelector); -} - - - - -void SelectionFunction::DeselectAllPages (void) -{ - mbIsDeselectionPending = false; - mrController.GetPageSelector().DeselectAllPages(); - mnShiftKeySelectionAnchor = -1; -} - - - - -void SelectionFunction::RangeSelect (const model::SharedPageDescriptor& rpDescriptor) -{ - PageSelector::UpdateLock aLock (mrSlideSorter); - PageSelector& rSelector (mrController.GetPageSelector()); - - model::SharedPageDescriptor pAnchor (rSelector.GetSelectionAnchor()); - DeselectAllPages(); - - if (pAnchor.get() != NULL) - { - // Select all pages between the anchor and the given one, including - // the two. - USHORT nAnchorIndex ((pAnchor->GetPage()->GetPageNum()-1) / 2); - USHORT nOtherIndex ((rpDescriptor->GetPage()->GetPageNum()-1) / 2); - - // Iterate over all pages in the range. Start with the anchor - // page. This way the PageSelector will recognize it again as - // anchor (the first selected page after a DeselectAllPages() - // becomes the anchor.) - USHORT nStep = (nAnchorIndex < nOtherIndex) ? +1 : -1; - USHORT nIndex = nAnchorIndex; - while (true) - { - rSelector.SelectPage(nIndex); - if (nIndex == nOtherIndex) - break; - nIndex = nIndex + nStep; - } - } -} - - - - void SelectionFunction::GotoNextPage (int nOffset) { model::SharedPageDescriptor pDescriptor @@ -755,7 +736,7 @@ void SelectionFunction::GotoPage (int nIndex) model::SharedPageDescriptor pNextPageDescriptor ( mrSlideSorter.GetModel().GetPageDescriptor (nIndex)); if (pNextPageDescriptor.get() != NULL) - SetCurrentPage(pNextPageDescriptor); + mpModeHandler->SetCurrentPage(pNextPageDescriptor); else { OSL_ASSERT(pNextPageDescriptor.get() != NULL); @@ -771,49 +752,263 @@ void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEve // #95491# remember button state for creation of own MouseEvents SetMouseButtonCode (rEvent.GetButtons()); - // 1. Compute some frequently used values relating to the event. - ::std::auto_ptr pEventDescriptor ( - new EventDescriptor(nEventType, rEvent.GetPosPixel(), mrSlideSorter)); + EventDescriptor aEventDescriptor (nEventType, rEvent, mrSlideSorter); + ProcessEvent(aEventDescriptor); +} - // 2. Compute a numerical code that describes the event and that is used - // for fast look-up of the associated reaction. - pEventDescriptor->mnEventCode - = EncodeMouseEvent(*pEventDescriptor, rEvent) | EncodeState(*pEventDescriptor); - // 3. Process the event. - if ( ! ProcessEvent(*pEventDescriptor)) - { - OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); - } - PostProcessEvent(*pEventDescriptor); + + +void SelectionFunction::MouseDragged ( + const AcceptDropEvent& rEvent, + const sal_Int8 nDragAction) +{ + EventDescriptor aEventDescriptor (MOUSE_DRAG, rEvent, nDragAction, mrSlideSorter); + ProcessEvent(aEventDescriptor); } -sal_uInt32 SelectionFunction::EncodeMouseEvent ( - const EventDescriptor& rDescriptor, - const MouseEvent& rEvent) const + +void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent) { - // Initialize with the type of mouse event. - sal_uInt32 nEventCode (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION)); + EventDescriptor aEventDescriptor (rEvent, mrSlideSorter); + ProcessEvent(aEventDescriptor); +} - // Detect the affected button. - switch (rEvent.GetButtons()) - { - case MOUSE_LEFT: nEventCode |= LEFT_BUTTON; break; - case MOUSE_RIGHT: nEventCode |= RIGHT_BUTTON; break; - case MOUSE_MIDDLE: nEventCode |= MIDDLE_BUTTON; break; - } - // Detect the number of clicks. - switch (rEvent.GetClicks()) - { - case 1: nEventCode |= SINGLE_CLICK; break; - case 2: nEventCode |= DOUBLE_CLICK; break; - } - // Detect pressed modifier keys. + +void SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor) +{ + PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter); + PageSelector::UpdateLock aUpdateLock (mrSlideSorter); + + // The call to ProcessEvent may switch to another mode handler. + // To avoid the destruction of the called handler before the call + // completes we aquire a temporary reference here. + ::boost::shared_ptr pModeHandler (mpModeHandler); + pModeHandler->ProcessEvent(rDescriptor); + + if (rDescriptor.mnEventCode & BUTTON_UP) + { +// mpWindow->ReleaseMouse(); + + // Hide insertion indicator. + if ( ! mrController.IsContextMenuOpen()) + mrController.GetInsertionIndicatorHandler()->End(Animator::AM_Animated); + } +} + + + + +bool Match ( + const sal_uInt32 nEventCode, + const sal_uInt32 nPositivePattern) +{ + return (nEventCode & nPositivePattern)==nPositivePattern; +} + + + + +void SelectionFunction::SwitchToNormalMode (void) +{ + if (mpModeHandler->GetMode() != NormalMode) + SwitchMode(::boost::shared_ptr( + new NormalModeHandler(mrSlideSorter, *this))); +} + + + + +void SelectionFunction::SwitchToDragAndDropMode (const Point aMousePosition) +{ + if (mpModeHandler->GetMode() != DragAndDropMode) + { + SwitchMode(::boost::shared_ptr( + new DragAndDropModeHandler(mrSlideSorter, *this, aMousePosition, mpWindow))); + } +} + + + + +void SelectionFunction::SwitchToMultiSelectionMode ( + const Point aMousePosition, + const sal_uInt32 nEventCode) +{ + if (mpModeHandler->GetMode() != MultiSelectionMode) + SwitchMode(::boost::shared_ptr( + new MultiSelectionModeHandler(mrSlideSorter, *this, aMousePosition, nEventCode))); +} + + + + +void SelectionFunction::SwitchToButtonMode (void) +{ + if (mpModeHandler->GetMode() != ButtonMode) + SwitchMode(::boost::shared_ptr( + new ButtonModeHandler(mrSlideSorter, *this))); +} + + + + +void SelectionFunction::SwitchMode (const ::boost::shared_ptr& rpHandler) +{ + // Not all modes allow mouse over indicator. + if (mpModeHandler->IsMouseOverIndicatorAllowed() != rpHandler->IsMouseOverIndicatorAllowed()) + { + if ( ! rpHandler->IsMouseOverIndicatorAllowed()) + { + mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); + mrSlideSorter.GetView().GetButtonBar().ResetPage(); + } + else + mrSlideSorter.GetView().UpdatePageUnderMouse(false); + } + + mpModeHandler = rpHandler; +} + + + + +void SelectionFunction::ResetShiftKeySelectionAnchor (void) +{ + mnShiftKeySelectionAnchor = -1; +} + + + + +//===== EventDescriptor ======================================================= + +SelectionFunction::EventDescriptor::EventDescriptor ( + const sal_uInt32 nEventType, + const MouseEvent& rEvent, + SlideSorter& rSlideSorter) + : maMousePosition(rEvent.GetPosPixel()), + maMouseModelPosition(), + mpHitDescriptor(), + mpHitPage(), + mnEventCode(nEventType), + mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()), + meDragMode(InsertionIndicatorHandler::MoveMode), + mbMakeSelectionVisible(true), + mbIsLeaving(false) +{ + maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition); + mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition); + if (mpHitDescriptor) + { + mpHitPage = mpHitDescriptor->GetPage(); + } + + mnEventCode |= EncodeMouseEvent(rEvent); + mnEventCode |= EncodeState(); + + mbIsLeaving = rEvent.IsLeaveWindow() + || ! Rectangle(Point(0,0), + rSlideSorter.GetContentWindow()->GetOutputSizePixel()).IsInside(maMousePosition); +} + + + + +SelectionFunction::EventDescriptor::EventDescriptor ( + const sal_uInt32 nEventType, + const AcceptDropEvent& rEvent, + const sal_Int8 nDragAction, + SlideSorter& rSlideSorter) + : maMousePosition(rEvent.maPosPixel), + maMouseModelPosition(), + mpHitDescriptor(), + mpHitPage(), + mnEventCode(nEventType), + mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()), + meDragMode(InsertionIndicatorHandler::GetModeFromDndAction(nDragAction)), + mbMakeSelectionVisible(true), + mbIsLeaving(false) +{ + maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition); + mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition); + if (mpHitDescriptor) + { + mpHitPage = mpHitDescriptor->GetPage(); + } + + mnEventCode |= EncodeState(); + + mbIsLeaving = rEvent.mbLeaving + || ! Rectangle(Point(0,0), + rSlideSorter.GetContentWindow()->GetOutputSizePixel()).IsInside(maMousePosition); +} + + + + +SelectionFunction::EventDescriptor::EventDescriptor ( + const KeyEvent& rEvent, + SlideSorter& rSlideSorter) + : maMousePosition(), + maMouseModelPosition(), + mpHitDescriptor(), + mpHitPage(), + mnEventCode(KEY_EVENT), + mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()), + meDragMode(InsertionIndicatorHandler::MoveMode), + mbMakeSelectionVisible(true), + mbIsLeaving(false) +{ + model::SharedPageDescriptor pHitDescriptor ( + rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); + if (pHitDescriptor.get() != NULL) + { + mpHitPage = pHitDescriptor->GetPage(); + mpHitDescriptor = pHitDescriptor; + } + + mnEventCode |= EncodeKeyEvent(rEvent) | EncodeState(); +} + + + + +void SelectionFunction::EventDescriptor::SetDragMode (const InsertionIndicatorHandler::Mode eMode) +{ + meDragMode = eMode; +} + + + + +sal_uInt32 SelectionFunction::EventDescriptor::EncodeMouseEvent ( + const MouseEvent& rEvent) const +{ + // Initialize with the type of mouse event. + sal_uInt32 nEventCode (mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION)); + + // Detect the affected button. + switch (rEvent.GetButtons()) + { + case MOUSE_LEFT: nEventCode |= LEFT_BUTTON; break; + case MOUSE_RIGHT: nEventCode |= RIGHT_BUTTON; break; + case MOUSE_MIDDLE: nEventCode |= MIDDLE_BUTTON; break; + } + + // Detect the number of clicks. + switch (rEvent.GetClicks()) + { + case 1: nEventCode |= SINGLE_CLICK; break; + case 2: nEventCode |= DOUBLE_CLICK; break; + } + + // Detect pressed modifier keys. if (rEvent.IsShift()) nEventCode |= SHIFT_MODIFIER; if (rEvent.IsMod1()) @@ -821,7 +1016,7 @@ sal_uInt32 SelectionFunction::EncodeMouseEvent ( // Detect whether the mouse is over one of the active elements inside a // page object. - if (rDescriptor.mnButtonIndex >= 0) + if (mbIsOverButton) nEventCode |= OVER_BUTTON; return nEventCode; @@ -829,17 +1024,11 @@ sal_uInt32 SelectionFunction::EncodeMouseEvent ( -sal_uInt32 SelectionFunction::EncodeKeyEvent ( - const EventDescriptor& rDescriptor, - const KeyEvent& rEvent) const -{ - (void)rDescriptor; - - // Initialize as key event. - sal_uInt32 nEventCode (KEY_EVENT); - // Add the actual key code in the lower 16 bit. - nEventCode |= rEvent.GetKeyCode().GetCode(); +sal_uInt32 SelectionFunction::EventDescriptor::EncodeKeyEvent (const KeyEvent& rEvent) const +{ + // The key code in the lower 16 bit. + sal_uInt32 nEventCode (rEvent.GetKeyCode().GetCode()); // Detect pressed modifier keys. if (rEvent.GetKeyCode().IsShift()) @@ -853,177 +1042,274 @@ sal_uInt32 SelectionFunction::EncodeKeyEvent ( -sal_uInt32 SelectionFunction::EncodeState ( - const EventDescriptor& rDescriptor) const +sal_uInt32 SelectionFunction::EventDescriptor::EncodeState (void) const { sal_uInt32 nEventCode (0); // Detect whether the event has happened over a page object. - if (rDescriptor.mpHitPage != NULL && rDescriptor.mpHitDescriptor) + if (mpHitPage!=NULL && mpHitDescriptor) { - if (rDescriptor.mpHitDescriptor->HasState(model::PageDescriptor::ST_Selected)) + if (mpHitDescriptor->HasState(model::PageDescriptor::ST_Selected)) nEventCode |= OVER_SELECTED_PAGE; else nEventCode |= OVER_UNSELECTED_PAGE; // Detect whether the mouse is over one of the active elements // inside a page object. - if (rDescriptor.mnButtonIndex >= 0) + if (mbIsOverButton) nEventCode |= OVER_BUTTON; } - // Detect whether we are dragging pages or dragging a selection rectangle. - if (mpDragAndDropContext) - nEventCode |= DRAG_ACTIVE; - if (mpMouseMultiSelector) - nEventCode |= MULTI_SELECTOR; - return nEventCode; } -void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent) -{ - // 1. Compute some frequently used values relating to the event. - ::std::auto_ptr pEventDescriptor ( - new EventDescriptor(rEvent, mrSlideSorter)); - - // 2. Encode the event. - pEventDescriptor->mnEventCode - = EncodeKeyEvent(*pEventDescriptor, rEvent) | EncodeState(*pEventDescriptor); +//===== SelectionFunction::ModeHandler ======================================== - // 3. Process the event. - if ( ! ProcessEvent(*pEventDescriptor)) - OSL_TRACE ("can not handle event code %x", pEventDescriptor->mnEventCode); - PostProcessEvent(*pEventDescriptor); +SelectionFunction::ModeHandler::ModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction, + const bool bIsMouseOverIndicatorAllowed) + : mrSlideSorter(rSlideSorter), + mrSelectionFunction(rSelectionFunction), + mbIsMouseOverIndicatorAllowed(bIsMouseOverIndicatorAllowed) +{ } -bool Match ( - const sal_uInt32 nEventCode, - const sal_uInt32 nPositivePattern) +SelectionFunction::ModeHandler::~ModeHandler (void) { - return (nEventCode & nPositivePattern)==nPositivePattern; } -bool SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor) +void SelectionFunction::ModeHandler::ReprocessEvent (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 + mrSelectionFunction.ProcessEvent(rDescriptor); +} - bool bResult (true); - PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter); - PageSelector::UpdateLock aUpdateLock (mrSlideSorter); - // With the event code determine the type of operation with which to - // react to the event. - switch (rDescriptor.mnEventCode & (DRAG_ACTIVE | MULTI_SELECTOR)) +void SelectionFunction::ModeHandler::ProcessEvent ( + SelectionFunction::EventDescriptor& rDescriptor) +{ + bool bIsProcessed (false); + switch (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION | MOUSE_DRAG)) { - case DRAG_ACTIVE: - ProcessEventWhileDragActive(rDescriptor); + case BUTTON_DOWN: + bIsProcessed = ProcessButtonDownEvent(rDescriptor); break; - case MULTI_SELECTOR: - ProcessEventWhileMultiSelectorActive(rDescriptor); + case BUTTON_UP: + bIsProcessed = ProcessButtonUpEvent(rDescriptor); + mrSelectionFunction.SwitchToNormalMode(); break; - default: - OSL_ASSERT(!mpMouseMultiSelector); - OSL_ASSERT(!mpDragAndDropContext); - switch (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION)) - { - case BUTTON_DOWN: - ProcessButtonDownEvent(rDescriptor); - break; - - case BUTTON_UP: - ProcessButtonUpEvent(rDescriptor); - break; + case MOUSE_MOTION: + bIsProcessed = ProcessMotionEvent(rDescriptor); + break; - case MOUSE_MOTION: - ProcessMouseMotionEvent(rDescriptor); - break; - } + case MOUSE_DRAG: + bIsProcessed = ProcessDragEvent(rDescriptor); + break; } - return bResult; + if ( ! bIsProcessed) + HandleUnprocessedEvent(rDescriptor); } -void SelectionFunction::ProcessEventWhileDragActive (EventDescriptor& rDescriptor) +bool SelectionFunction::ModeHandler::ProcessButtonDownEvent (EventDescriptor&) { - OSL_ASSERT(mpDragAndDropContext); - // The substitution is visible. Handle events accordingly. - if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) - { - // mpDragAndDropContext->UpdatePosition( - // rDescriptor.maMousePosition, - // rDescriptor.meDragMode); - } - else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG)) - { - mpDragAndDropContext->UpdatePosition( + return false; +} + + + + +bool SelectionFunction::ModeHandler::ProcessButtonUpEvent (EventDescriptor&) +{ + return false; +} + + + + +bool SelectionFunction::ModeHandler::ProcessMotionEvent (EventDescriptor& rDescriptor) +{ + if (mbIsMouseOverIndicatorAllowed) + mrSlideSorter.GetView().UpdatePageUnderMouse( rDescriptor.maMousePosition, - rDescriptor.meDragMode); - } - else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON)) + (rDescriptor.mnEventCode & LEFT_BUTTON) != 0, + true); + + // Detect the mouse leaving the window. When not button is pressed then + // we can call IsLeaveWindow at the event. Otherwise we have to make an + // explicit test. + if (rDescriptor.mbIsLeaving) { - // The following Process() call may lead to the desctruction - // of rDescriptor.mpHitDescriptor so release our reference to it. - rDescriptor.mpHitDescriptor.reset(); - StopDragAndDrop(); + mrSelectionFunction.SwitchToNormalMode(); + mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); + + return true; } + else + return false; } -void SelectionFunction::ProcessEventWhileMultiSelectorActive (EventDescriptor& rDescriptor) +bool SelectionFunction::ModeHandler::ProcessDragEvent (EventDescriptor&) { - OSL_ASSERT(mpMouseMultiSelector); - // The selection rectangle is visible. Handle events accordingly. - if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) + return false; +} + + + + +bool SelectionFunction::ModeHandler::HandleUnprocessedEvent (EventDescriptor&) +{ + return false; +} + + + + +void SelectionFunction::ModeHandler::SetCurrentPage ( + const model::SharedPageDescriptor& rpDescriptor) +{ + SelectOnePage(rpDescriptor); + + mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor); +} + + + + +void SelectionFunction::ModeHandler::DeselectAllPages (void) +{ + mrSlideSorter.GetController().GetPageSelector().DeselectAllPages(); + mrSelectionFunction.ResetShiftKeySelectionAnchor(); +} + + + + +void SelectionFunction::ModeHandler::SelectOnePage ( + const model::SharedPageDescriptor& rpDescriptor) +{ + DeselectAllPages(); + mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor); +} + + + + +void SelectionFunction::ModeHandler::SwitchView (const model::SharedPageDescriptor& rpDescriptor) +{ + // Switch to the draw view. This is done only when the current + // view is the main view. + ViewShell* pViewShell = mrSlideSorter.GetViewShell(); + if (pViewShell!=NULL && pViewShell->IsMainViewShell()) { - if (mpMouseMultiSelector) + if (rpDescriptor.get()!=NULL && rpDescriptor->GetPage()!=NULL) { - mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); - mpMouseMultiSelector->UpdatePosition(rDescriptor.maMousePosition); + mrSlideSorter.GetModel().GetDocument()->SetSelected(rpDescriptor->GetPage(), TRUE); + pViewShell->GetFrameView()->SetSelectedPage( + (rpDescriptor->GetPage()->GetPageNum()-1)/2); } - rDescriptor.mbMakeSelectionVisible = false; - } - else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK)) - { - StopMouseMultiSelection(); + if (mrSlideSorter.GetViewShellBase() != NULL) + framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())->RequestView( + framework::FrameworkHelper::msImpressViewURL, + framework::FrameworkHelper::msCenterPaneURL); } - // Anything else stops the rectangle selection and the event is - // processed again. - else +} + + + + +void SelectionFunction::ModeHandler::StartDrag ( + const Point& rMousePosition, + const InsertionIndicatorHandler::Mode eMode) +{ + // Do not start a drag-and-drop operation when one is already active. + // (when dragging pages from one document into another, pressing a + // modifier key can trigger a MouseMotion event in the originating + // window (focus still in there). Together with the mouse button pressed + // (drag-and-drop is active) this triggers the start of drag-and-drop.) + if (SD_MOD()->pTransferDrag != NULL) + return; + + if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly()) { - StopMouseMultiSelection(); - rDescriptor.mnEventCode &= ~MULTI_SELECTOR; - ProcessEvent(rDescriptor); + mrSelectionFunction.SwitchToDragAndDropMode(rMousePosition); } } -void SelectionFunction::ProcessButtonDownEvent (EventDescriptor& rDescriptor) +bool SelectionFunction::ModeHandler::IsMouseOverIndicatorAllowed (void) const { + return mbIsMouseOverIndicatorAllowed; +} + + + + +//===== NormalModeHandler ===================================================== + +NormalModeHandler::NormalModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction) + : ModeHandler(rSlideSorter, rSelectionFunction, true) +{ +} + + + + +NormalModeHandler::~NormalModeHandler (void) +{ +} + + + + +SelectionFunction::Mode NormalModeHandler::GetMode (void) const +{ + return SelectionFunction::NormalMode; +} + + + + +void NormalModeHandler::Abort (void) +{ +} + + + + +bool NormalModeHandler::ProcessButtonDownEvent ( + SelectionFunction::EventDescriptor& rDescriptor) +{ + // Remember the location where the left button is pressed. With + // that we can filter away motion events that are caused by key + // presses. We also can tune the minimal motion distance that + // triggers a drag-and-drop operation. + if ((rDescriptor.mnEventCode & BUTTON_DOWN) != 0) + maButtonDownLocation = rDescriptor.maMousePosition; + switch (rDescriptor.mnEventCode) { case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE: @@ -1049,16 +1335,11 @@ void SelectionFunction::ProcessButtonDownEvent (EventDescriptor& rDescriptor) 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); + if (mrSlideSorter.GetView().GetButtonBar().IsMouseOverButton()) + { + mrSelectionFunction.SwitchToButtonMode(); + ReprocessEvent(rDescriptor); + } break; // Right button for context menu. @@ -1068,7 +1349,6 @@ void SelectionFunction::ProcessButtonDownEvent (EventDescriptor& rDescriptor) // 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; @@ -1086,14 +1366,20 @@ void SelectionFunction::ProcessButtonDownEvent (EventDescriptor& rDescriptor) mrSlideSorter.GetModel().SaveCurrentSelection(); DeselectAllPages(); break; + + default: + return false; } + return true; } -void SelectionFunction::ProcessButtonUpEvent (const EventDescriptor& rDescriptor) +bool NormalModeHandler::ProcessButtonUpEvent ( + SelectionFunction::EventDescriptor& rDescriptor) { + bool bIsProcessed (true); switch (rDescriptor.mnEventCode) { case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE: @@ -1102,42 +1388,39 @@ void SelectionFunction::ProcessButtonUpEvent (const EventDescriptor& rDescriptor // Multi selection with the control modifier. case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER: - mrController.GetPageSelector().DeselectPage(rDescriptor.mpHitDescriptor); + mrSlideSorter.GetController().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() - && rDescriptor.mpHitDescriptor->GetVisualState().GetButtonAlpha()<0.7) - { - ProcessButtonClick(rDescriptor.mpHitDescriptor, mnButtonDownButtonIndex); - } - // Update state of button under mouse (typically from pressed to - // mouse over). Note that the button under the mouse can change - // when the exclusions state changes (three buttons vs. wide button.) - mrSlideSorter.GetView().SetButtonUnderMouse( - mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt( - rDescriptor.mpHitDescriptor, - rDescriptor.maMouseModelPosition), - true); + mrSlideSorter.GetController().GetPageSelector().SelectPage( + rDescriptor.mpHitDescriptor); + mrSlideSorter.GetView().UpdatePageUnderMouse( + rDescriptor.mpHitDescriptor, + rDescriptor.maMousePosition, + false); break; - case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE: - if (mbIsDeselectionPending) - DeselectAllPages(); + break; + + default: + bIsProcessed = false; break; } + mrSelectionFunction.SwitchToNormalMode(); + return bIsProcessed; } -void SelectionFunction::ProcessMouseMotionEvent (const EventDescriptor& rDescriptor) +bool NormalModeHandler::ProcessMotionEvent ( + SelectionFunction::EventDescriptor& rDescriptor) { + if (ModeHandler::ProcessMotionEvent(rDescriptor)) + return true; + + bool bIsProcessed (true); switch (rDescriptor.mnEventCode) { case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE): @@ -1146,200 +1429,74 @@ void SelectionFunction::ProcessMouseMotionEvent (const EventDescriptor& rDescrip // 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 MouseMultiSelector(mrSlideSorter, rDescriptor.maMouseModelPosition)); - mpMouseMultiSelector->SetSelectionModeFromModifier(rDescriptor.mnEventCode); - UpdateMouseOverIndicationPermission(); - break; - } -} - - - - -void SelectionFunction::PostProcessEvent (const EventDescriptor& rDescriptor) -{ - if (rDescriptor.mnEventCode & BUTTON_UP) - { - mpWindow->ReleaseMouse(); - - // Now turn them off. - if ( ! mrController.IsContextMenuOpen()) - mrController.GetInsertionIndicatorHandler()->End(Animator::AM_Animated); - - mnButtonDownPageIndex = -1; - mnButtonDownButtonIndex = -1; - } -} - - - - -void SelectionFunction::SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor) -{ - PageSelector& rSelector (mrController.GetPageSelector()); - rSelector.DeselectAllPages (); - rSelector.SelectPage(rpDescriptor); - - mrController.GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor); - mrController.GetFocusManager().SetFocusedPage(rpDescriptor); - - mnShiftKeySelectionAnchor = -1; -} - - - - -void SelectionFunction::SwitchView (const model::SharedPageDescriptor& rpDescriptor) -{ - // Switch to the draw view. This is done only when the current - // view is the main view. - ViewShell* pViewShell = mrSlideSorter.GetViewShell(); - if (pViewShell!=NULL && pViewShell->IsMainViewShell()) - { - if (rpDescriptor.get()!=NULL && rpDescriptor->GetPage()!=NULL) - { - mrSlideSorter.GetModel().GetDocument()->SetSelected(rpDescriptor->GetPage(), TRUE); - mpViewShell->GetFrameView()->SetSelectedPage( - (rpDescriptor->GetPage()->GetPageNum()-1)/2); - } - if (mrSlideSorter.GetViewShellBase() != NULL) - framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())->RequestView( - framework::FrameworkHelper::msImpressViewURL, - framework::FrameworkHelper::msCenterPaneURL); - } -} - - - - -void SelectionFunction::ProcessButtonClick ( - const model::SharedPageDescriptor& rpDescriptor, - const sal_Int32 nButtonIndex) -{ - OSL_ASSERT(rpDescriptor); - - PageSelector::UpdateLock aLock (mrSlideSorter); - PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); - switch (nButtonIndex) - { - case 2: - // Start slide show at current slide. - mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide( - rpDescriptor); - if (mrSlideSorter.GetViewShell() != NULL) - mrSlideSorter.GetViewShell()->GetDispatcher()->Execute( - SID_PRESENTATION, - SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); - break; + { + const sal_Int32 nDistance ( + ::std::max ( + abs(maButtonDownLocation.X() - rDescriptor.maMousePosition.X()), + abs(maButtonDownLocation.Y() - rDescriptor.maMousePosition.Y()))); + if (nDistance > 3) + StartDrag( + rDescriptor.maMousePosition, + (rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0 + ? InsertionIndicatorHandler::CopyMode + : InsertionIndicatorHandler::MoveMode); + } + break; - case 1: - if ( ! rpDescriptor) - return; - // Toggle exclusion state. - mrSlideSorter.GetController().GetSlotManager()->ChangeSlideExclusionState( - (rpDescriptor->HasState(model::PageDescriptor::ST_Selected) - ? model::SharedPageDescriptor() - : rpDescriptor), - ! rpDescriptor->HasState(model::PageDescriptor::ST_Excluded)); + // A mouse motion not over a page starts a rectangle selection. + case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE): + mrSelectionFunction.SwitchToMultiSelectionMode( + rDescriptor.maMouseModelPosition, + rDescriptor.mnEventCode); break; - case 0: - if ( ! rpDescriptor) - return; - // When the page under the button is not selected then set the - // selection to just this page. - if ( ! rpDescriptor->HasState(model::PageDescriptor::ST_Selected)) - { - rSelector.DeselectAllPages(); - rSelector.SelectPage(rpDescriptor); - } - // Duplicate the selected pages. Insert the new pages right - // after the current selection and select them - if (mrSlideSorter.GetViewShell() != NULL) - mrSlideSorter.GetViewShell()->GetDispatcher()->Execute( - SID_DUPLICATE_PAGE, - SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); + default: + bIsProcessed = false; break; } + return bIsProcessed; } -void SelectionFunction::StopDragAndDrop (void) +bool NormalModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor) { - if (mpDragAndDropContext) - { - // Disconnect the substitution handler from this selection function. - mpDragAndDropContext->Hide(); - mpDragAndDropContext->SetTargetSlideSorter(); - mpDragAndDropContext.reset(); - UpdateMouseOverIndicationPermission(); - } - mrController.GetInsertionIndicatorHandler()->End(Animator::AM_Animated); + mrSelectionFunction.SwitchToDragAndDropMode(rDescriptor.maMousePosition); + ReprocessEvent(rDescriptor); + return true; } -void SelectionFunction::StopMouseMultiSelection (void) +void NormalModeHandler::RangeSelect (const model::SharedPageDescriptor& rpDescriptor) { - if (mpMouseMultiSelector) - { - mpMouseMultiSelector.reset(); - UpdateMouseOverIndicationPermission(); - } -} - - - + PageSelector::UpdateLock aLock (mrSlideSorter); + PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); -//===== EventDescriptor ======================================================= + model::SharedPageDescriptor pAnchor (rSelector.GetSelectionAnchor()); + DeselectAllPages(); -SelectionFunction::EventDescriptor::EventDescriptor ( - sal_uInt32 nEventType, - const Point& rMousePosition, - SlideSorter& rSlideSorter) - : maMousePosition(rMousePosition), - maMouseModelPosition(), - mpHitDescriptor(), - mpHitPage(), - mnEventCode(nEventType), - mnButtonIndex(-1) -{ - maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition); - mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition); - if (mpHitDescriptor) + if (pAnchor.get() != NULL) { - mpHitPage = mpHitDescriptor->GetPage(); + // Select all pages between the anchor and the given one, including + // the two. + USHORT nAnchorIndex ((pAnchor->GetPage()->GetPageNum()-1) / 2); + USHORT nOtherIndex ((rpDescriptor->GetPage()->GetPageNum()-1) / 2); - if (mpHitDescriptor->HasState(model::PageDescriptor::ST_Excluded)) - { - if (rSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox( - mpHitDescriptor, - view::PageObjectLayouter::WideButton, - view::PageObjectLayouter::ModelCoordinateSystem).IsInside(maMouseModelPosition)) - { - mnButtonIndex = view::PageObjectLayouter::ShowHideButtonIndex; - } - } - else + // Iterate over all pages in the range. Start with the anchor + // page. This way the PageSelector will recognize it again as + // anchor (the first selected page after a DeselectAllPages() + // becomes the anchor.) + USHORT nStep = (nAnchorIndex < nOtherIndex) ? +1 : -1; + USHORT nIndex = nAnchorIndex; + while (true) { - mnButtonIndex - = rSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetButtonIndexAt( - mpHitDescriptor, - maMouseModelPosition); + rSelector.SelectPage(nIndex); + if (nIndex == nOtherIndex) + break; + nIndex = nIndex + nStep; } } } @@ -1347,83 +1504,101 @@ SelectionFunction::EventDescriptor::EventDescriptor ( +//===== MultiSelectionModeHandler ============================================= -SelectionFunction::EventDescriptor::EventDescriptor ( - const KeyEvent&, - SlideSorter& rSlideSorter) - : maMousePosition(), - maMouseModelPosition(), - mpHitDescriptor(), - mpHitPage(), - mnEventCode(0), - mnButtonIndex(-1), - meDragMode(InsertionIndicatorHandler::MoveMode), - mbMakeSelectionVisible(true) +MultiSelectionModeHandler::MultiSelectionModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction, + const Point& rMouseModelPosition, + const sal_uInt32 nEventCode) + : ModeHandler(rSlideSorter, rSelectionFunction, false), + meSelectionMode(SM_Normal), + maSecondCorner(rMouseModelPosition), + maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()), + mnAnchorIndex(-1), + mnSecondIndex(-1) { - model::SharedPageDescriptor pHitDescriptor ( - rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); - if (pHitDescriptor.get() != NULL) - { - mpHitPage = pHitDescriptor->GetPage(); - mpHitDescriptor = pHitDescriptor; - } + const Pointer aSelectionPointer (POINTER_TEXT); + mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer); + SetSelectionModeFromModifier(nEventCode); } -SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDescriptor) - : maMousePosition(rDescriptor.maMousePosition), - maMouseModelPosition(rDescriptor.maMouseModelPosition), - mpHitDescriptor(rDescriptor.mpHitDescriptor), - mpHitPage(rDescriptor.mpHitPage), - mnEventCode(rDescriptor.mnEventCode), - mnButtonIndex(rDescriptor.mnButtonIndex), - meDragMode(InsertionIndicatorHandler::MoveMode), - mbMakeSelectionVisible(true) +MultiSelectionModeHandler::~MultiSelectionModeHandler (void) { + mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer); } -void SelectionFunction::EventDescriptor::SetDragMode (const InsertionIndicatorHandler::Mode eMode) +SelectionFunction::Mode MultiSelectionModeHandler::GetMode (void) const { - meDragMode = eMode; + return SelectionFunction::MultiSelectionMode; } -//===== SelectionFunction::MouseMultiSelector ====================================== +void MultiSelectionModeHandler::Abort (void) +{ + mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection()); +} + -SelectionFunction::MouseMultiSelector::MouseMultiSelector ( - SlideSorter& rSlideSorter, - const Point& rMouseModelPosition) - : mrSlideSorter(rSlideSorter), - meSelectionMode(SM_Normal), - maSecondCorner(rMouseModelPosition), - maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()), - mnAnchorIndex(-1), - mnSecondIndex(-1) + + +bool MultiSelectionModeHandler::ProcessButtonUpEvent ( + SelectionFunction::EventDescriptor& rDescriptor) { - const Pointer aSelectionPointer (POINTER_TEXT); - mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer); + if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK)) + { + mrSelectionFunction.SwitchToNormalMode(); + return true; + } + else + return false; } -SelectionFunction::MouseMultiSelector::~MouseMultiSelector (void) +bool MultiSelectionModeHandler::ProcessMotionEvent ( + SelectionFunction::EventDescriptor& rDescriptor) { - mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer); + // The selection rectangle is visible. Handle events accordingly. + if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) + { + SetSelectionModeFromModifier(rDescriptor.mnEventCode); + UpdatePosition(rDescriptor.maMousePosition, true); + rDescriptor.mbMakeSelectionVisible = false; + return true; + } + else + return false; +} + + + +bool MultiSelectionModeHandler::HandleUnprocessedEvent ( + SelectionFunction::EventDescriptor& rDescriptor) +{ + if ( ! ModeHandler::HandleUnprocessedEvent(rDescriptor)) + { + // If the event has not been processed then stop multi selection. + mrSelectionFunction.SwitchToNormalMode(); + ReprocessEvent(rDescriptor); + } + return true; } -void SelectionFunction::MouseMultiSelector::UpdatePosition ( +void MultiSelectionModeHandler::UpdatePosition ( const Point& rMousePosition, const bool bAllowAutoScroll) { @@ -1436,7 +1611,7 @@ void SelectionFunction::MouseMultiSelector::UpdatePosition ( if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll( rMousePosition, ::boost::bind( - &SelectionFunction::MouseMultiSelector::UpdatePosition, + &MultiSelectionModeHandler::UpdatePosition, this, rMousePosition, false)))) @@ -1448,7 +1623,7 @@ void SelectionFunction::MouseMultiSelector::UpdatePosition ( -void SelectionFunction::MouseMultiSelector::SetSelectionModeFromModifier ( +void MultiSelectionModeHandler::SetSelectionModeFromModifier ( const sal_uInt32 nEventCode) { switch (nEventCode & MODIFIER_MASK) @@ -1470,7 +1645,7 @@ void SelectionFunction::MouseMultiSelector::SetSelectionModeFromModifier ( -void SelectionFunction::MouseMultiSelector::SetSelectionMode (const SelectionMode eSelectionMode) +void MultiSelectionModeHandler::SetSelectionMode (const SelectionMode eSelectionMode) { if (meSelectionMode != eSelectionMode) { @@ -1482,7 +1657,7 @@ void SelectionFunction::MouseMultiSelector::SetSelectionMode (const SelectionMod -void SelectionFunction::MouseMultiSelector::UpdateSelectionState ( +void MultiSelectionModeHandler::UpdateSelectionState ( const model::SharedPageDescriptor& rpDescriptor, const bool bIsInSelection) const { @@ -1520,7 +1695,7 @@ void SelectionFunction::MouseMultiSelector::UpdateSelectionState ( -void SelectionFunction::MouseMultiSelector::UpdateModelPosition (const Point& rMouseModelPosition) +void MultiSelectionModeHandler::UpdateModelPosition (const Point& rMouseModelPosition) { maSecondCorner = rMouseModelPosition; UpdateSelection(); @@ -1529,7 +1704,7 @@ void SelectionFunction::MouseMultiSelector::UpdateModelPosition (const Point& rM -void SelectionFunction::MouseMultiSelector::UpdateSelection (void) +void MultiSelectionModeHandler::UpdateSelection (void) { view::SlideSorterView::DrawLock aLock (mrSlideSorter); @@ -1539,6 +1714,7 @@ void SelectionFunction::MouseMultiSelector::UpdateSelection (void) const sal_Int32 nIndexUnderMouse ( mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint ( maSecondCorner, + false, false)); if (nIndexUnderMouse>=0 && nIndexUnderMousepTransferDrag; + if (pDragTransferable==NULL && mrSlideSorter.GetViewShell() != NULL) + { + SlideSorterViewShell* pSlideSorterViewShell + = dynamic_cast(mrSlideSorter.GetViewShell()); + if (pSlideSorterViewShell != NULL) + pSlideSorterViewShell->StartDrag(rMousePosition, pWindow); + pDragTransferable = SD_MOD()->pTransferDrag; + } + + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(true); + mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter)); + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->Start( + pDragTransferable != NULL + && pDragTransferable->GetView()==&mrSlideSorter.GetView()); +} + + + + +DragAndDropModeHandler::~DragAndDropModeHandler (void) +{ + if (mpDragAndDropContext) + { + // Disconnect the substitution handler from this selection function. + mpDragAndDropContext->SetTargetSlideSorter(); + mpDragAndDropContext.reset(); + } + mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(Animator::AM_Animated); +} + + + + +SelectionFunction::Mode DragAndDropModeHandler::GetMode (void) const +{ + return SelectionFunction::DragAndDropMode; +} + + + + +void DragAndDropModeHandler::Abort (void) +{ + mrSlideSorter.GetController().GetClipboard().Abort(); + if (mpDragAndDropContext) + mpDragAndDropContext->Dispose(); + // mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection()); +} + + + + +bool DragAndDropModeHandler::ProcessButtonUpEvent ( + SelectionFunction::EventDescriptor& rDescriptor) +{ + 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(); + mrSelectionFunction.SwitchToNormalMode(); + return true; + } + else + return false; +} + + + + +bool DragAndDropModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor) +{ + OSL_ASSERT(mpDragAndDropContext); + + if (rDescriptor.mbIsLeaving) + { + mrSelectionFunction.SwitchToNormalMode(); + } + else if (mpDragAndDropContext) + { + mpDragAndDropContext->UpdatePosition( + rDescriptor.maMousePosition, + rDescriptor.meDragMode); + } + + return true; +} + + + + +//===== ButtonModeHandler ===================================================== + +ButtonModeHandler::ButtonModeHandler ( + SlideSorter& rSlideSorter, + SelectionFunction& rSelectionFunction) + : ModeHandler(rSlideSorter, rSelectionFunction, true) +{ +} + + + + +ButtonModeHandler::~ButtonModeHandler (void) +{ +} + + + + +SelectionFunction::Mode ButtonModeHandler::GetMode (void) const +{ + return SelectionFunction::ButtonMode; +} + + + + +void ButtonModeHandler::Abort (void) +{ +} + + + + +void ButtonModeHandler::ProcessEvent (SelectionFunction::EventDescriptor& rDescriptor) +{ +} + + + + +bool ButtonModeHandler::ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor) +{ + switch (rDescriptor.mnEventCode) + { + 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. + mrSlideSorter.GetView().GetButtonBar().ProcessButtonDownEvent( + rDescriptor.mpHitDescriptor, + rDescriptor.maMouseModelPosition); + return true; + + default: + return false; + } +} + + + + +bool ButtonModeHandler::ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor) +{ + switch (rDescriptor.mnEventCode & BUTTON_MASK) + { + case LEFT_BUTTON: + mrSlideSorter.GetView().GetButtonBar().ProcessButtonUpEvent( + rDescriptor.mpHitDescriptor, + rDescriptor.maMouseModelPosition); + mrSelectionFunction.SwitchToNormalMode(); + return true; + break; + } + + return false; +} + + + + +bool ButtonModeHandler::ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor) +{ + switch (rDescriptor.mnEventCode & (MOUSE_MOTION | BUTTON_MASK)) + { + case MOUSE_MOTION | LEFT_BUTTON: + mrSlideSorter.GetView().GetButtonBar().ProcessMouseMotionEvent( + rDescriptor.mpHitDescriptor, + rDescriptor.maMouseModelPosition, + true); + return true; + break; + + case MOUSE_MOTION: + mrSlideSorter.GetView().GetButtonBar().ProcessMouseMotionEvent( + rDescriptor.mpHitDescriptor, + rDescriptor.maMouseModelPosition, + false); + return true; + break; + } + + return false; +} + + + + } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx index 91edc092016f..660990d4c4b6 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx @@ -32,6 +32,7 @@ #include "controller/SlsSelectionManager.hxx" #include "controller/SlsSelectionObserver.hxx" #include "controller/SlsPageSelector.hxx" +#include "controller/SlsFocusManager.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include @@ -60,6 +61,18 @@ SelectionObserver::Context::~Context(void) +void SelectionObserver::Context::Abort(void) +{ + if (mpSelectionObserver) + { + mpSelectionObserver->AbortObservation(); + mpSelectionObserver.reset(); + } +} + + + + //===== SelectionObserver ===================================================== SelectionObserver::SelectionObserver (SlideSorter& rSlideSorter) @@ -116,6 +129,17 @@ void SelectionObserver::StartObservation (void) +void SelectionObserver::AbortObservation (void) +{ + OSL_ASSERT(mbIsOvservationActive); + mbIsOvservationActive = false; + maInsertedPages.clear(); + maDeletedPages.clear(); +} + + + + void SelectionObserver::EndObservation (void) { OSL_ASSERT(mbIsOvservationActive); @@ -123,6 +147,7 @@ void SelectionObserver::EndObservation (void) model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector()); + PageSelector::UpdateLock aUpdateLock (mrSlideSorter); rSelector.DeselectAllPages(); if ( ! maInsertedPages.empty()) { @@ -134,17 +159,14 @@ void SelectionObserver::EndObservation (void) ++iPage) { rSelector.SelectPage(*iPage); - /* - const sal_Int32 nIndex (rModel.GetIndex (*iPage)); - model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); - if (pDescriptor) - pDescriptor->SetState(model::PageDescriptor::ST_Selected, - true); - */ } maInsertedPages.clear(); } maDeletedPages.clear(); + + aUpdateLock.Release(); + mrSlideSorter.GetController().GetFocusManager().SetFocusedPageToCurrentPage(); + } diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 1a2410f1eb64..d6d8c71d9193 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -168,15 +168,16 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) if (pPagesPerRow != NULL) { sal_Int32 nColumnCount = pPagesPerRow->GetValue(); - // Force the given number of columns by setting the - // minimal and maximal number of columns to the same - // value. + // Force the given number of columns by setting + // the minimal and maximal number of columns to + // the same value. mrSlideSorter.GetView().GetLayouter().SetColumnCount ( nColumnCount, nColumnCount); // Force a repaint and re-layout. pShell->ArrangeGUIElements (); // Rearrange the UI-elements controlled by the - // controller and force a rearrangement of the view. + // controller and force a rearrangement of the + // view. mrSlideSorter.GetController().Rearrange(true); } } @@ -190,11 +191,11 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_SLIDE_TRANSITIONS_PANEL: { - // Make the slide transition panel visible (expand it) in the - // tool pane. + // Make the slide transition panel visible (expand it) + // in the tool pane. if (mrSlideSorter.GetViewShellBase() != NULL) - framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase()) - ->RequestTaskPanel(sd::framework::FrameworkHelper::msSlideTransitionTaskPanelURL); + framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase()) + ->RequestTaskPanel(sd::framework::FrameworkHelper::msSlideTransitionTaskPanelURL); rRequest.Ignore (); break; } @@ -215,7 +216,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) &mrSlideSorter.GetView(), pDocument, rRequest); - break; + break; case SID_EXPAND_PAGE: FuExpandPage::Create ( @@ -249,14 +250,14 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_DELETE_PAGE: case SID_DELETE_MASTER_PAGE: case SID_DELETE: // we need SID_CUT to handle the delete key - // (DEL -> accelerator -> SID_CUT). - if (mrSlideSorter.GetModel().GetPageCount() > 1) - { - mrSlideSorter.GetController().GetSelectionManager()->DeleteSelectedPages(); - } + // (DEL -> accelerator -> SID_CUT). + if (mrSlideSorter.GetModel().GetPageCount() > 1) + { + mrSlideSorter.GetController().GetSelectionManager()->DeleteSelectedPages(); + } - rRequest.Done(); - break; + rRequest.Done(); + break; case SID_RENAMEPAGE: case SID_RENAME_MASTER_PAGE: @@ -400,6 +401,9 @@ void SlotManager::FuSupport (SfxRequest& rRequest) = dynamic_cast(mrSlideSorter.GetViewShell()); if (pViewShell != NULL) { + view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); + SlideSorterController::ModelChangeLock aModelLock (mrSlideSorter.GetController()); + PageSelector::UpdateLock aUpdateLock (mrSlideSorter); SelectionObserver::Context aContext (mrSlideSorter); pViewShell->ImpSidUndo (FALSE, rRequest); } @@ -412,6 +416,9 @@ void SlotManager::FuSupport (SfxRequest& rRequest) = dynamic_cast(mrSlideSorter.GetViewShell()); if (pViewShell != NULL) { + view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); + SlideSorterController::ModelChangeLock aModelLock (mrSlideSorter.GetController()); + PageSelector::UpdateLock aUpdateLock (mrSlideSorter); SelectionObserver::Context aContext (mrSlideSorter); pViewShell->ImpSidRedo (FALSE, rRequest); } @@ -870,18 +877,22 @@ void SlotManager::GetStatusBarState (SfxItemSet& rSet) model::PageEnumeration aSelectedPages ( model::PageEnumerationProvider::CreateSelectedPagesEnumeration( mrSlideSorter.GetModel())); - pPage = aSelectedPages.GetNextElement()->GetPage(); - nFirstPage = pPage->GetPageNum()/2; - pFirstPage = pPage; - - aPageStr += sal_Unicode(' '); - aPageStr += String::CreateFromInt32( nFirstPage + 1 ); - aPageStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " / " )); - aPageStr += String::CreateFromInt32( - mrSlideSorter.GetModel().GetPageCount()); - - aLayoutStr = pFirstPage->GetLayoutName(); - aLayoutStr.Erase( aLayoutStr.SearchAscii( SD_LT_SEPARATOR ) ); + model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); + if (pDescriptor) + { + pPage = pDescriptor->GetPage(); + nFirstPage = pPage->GetPageNum()/2; + pFirstPage = pPage; + + aPageStr += sal_Unicode(' '); + aPageStr += String::CreateFromInt32( nFirstPage + 1 ); + aPageStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " / " )); + aPageStr += String::CreateFromInt32( + mrSlideSorter.GetModel().GetPageCount()); + + aLayoutStr = pFirstPage->GetLayoutName(); + aLayoutStr.Erase( aLayoutStr.SearchAscii( SD_LT_SEPARATOR ) ); + } } rSet.Put( SfxStringItem( SID_STATUS_PAGE, aPageStr ) ); diff --git a/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx b/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx index c683c5e0a2c4..f9c4c1ad4f0a 100644 --- a/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsVisibleAreaManager.cxx @@ -32,6 +32,7 @@ #include "controller/SlsProperties.hxx" #include "controller/SlsAnimationFunction.hxx" #include "controller/SlsScrollBarManager.hxx" +#include "controller/SlsCurrentSlideManager.hxx" namespace sd { namespace slidesorter { namespace controller { @@ -61,7 +62,8 @@ VisibleAreaManager::VisibleAreaManager (SlideSorter& rSlideSorter) maVisibleRequests(), mnScrollAnimationId(Animator::NotAnAnimationId), maRequestedVisibleTopLeft(), - meRequestedAnimationMode(Animator::AM_Immediate) + meRequestedAnimationMode(Animator::AM_Immediate), + mbIsCurrentSlideTrackingActive(true) { } @@ -75,25 +77,56 @@ VisibleAreaManager::~VisibleAreaManager (void) +void VisibleAreaManager::ActivateCurrentSlideTracking (void) +{ + mbIsCurrentSlideTrackingActive = true; +} + + + + +void VisibleAreaManager::DeactivateCurrentSlideTracking (void) +{ + mbIsCurrentSlideTrackingActive = false; +} + + + + void VisibleAreaManager::RequestVisible ( const model::SharedPageDescriptor& rpDescriptor, - const Animator::AnimationMode eRequestedAnimationMode) + const bool bForce) { if (rpDescriptor) { + const sal_Int32 nIndex (rpDescriptor->GetPageIndex()); + if (nIndex > 20) + { + OSL_TRACE("%d", nIndex); + } maVisibleRequests.push_back( mrSlideSorter.GetView().GetLayouter().GetPageObjectBox( rpDescriptor->GetPageIndex(), true)); - if (eRequestedAnimationMode == Animator::AM_Animated) - meRequestedAnimationMode = Animator::AM_Animated; - MakeVisible(); + if (bForce && ! mbIsCurrentSlideTrackingActive) + ActivateCurrentSlideTracking(); + MakeVisible(); } } +void VisibleAreaManager::RequestCurrentSlideVisible (void) +{ + if (mbIsCurrentSlideTrackingActive) + RequestVisible( + mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide()); +} + + + + void VisibleAreaManager::MakeVisible (void) { if (maVisibleRequests.empty()) diff --git a/sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx b/sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx index c828e95d1d02..c7f88b87a62a 100644 --- a/sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx +++ b/sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx @@ -33,12 +33,12 @@ #include #include -class BitmapEx; class SdrPage; namespace sd { namespace slidesorter { namespace cache { typedef const SdrPage* CacheKey; +class PreviewType; /** This interface allows the individualisation of different instances of the PreviewCache. @@ -55,7 +55,7 @@ public: */ virtual void NotifyPreviewCreation ( CacheKey aKey, - const ::boost::shared_ptr& rPreview) = 0; + const PreviewType& rPreview) = 0; /** Called to determine whether the system is idle and a preview can be created without annoying the user. diff --git a/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx index 82bdd8566b0d..42ede1483c7c 100644 --- a/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx +++ b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx @@ -29,11 +29,9 @@ #define SD_SLIDESORTER_PAGE_CACHE_HXX #include "cache/SlsCacheContext.hxx" +#include "cache/SlsPreviewType.hxx" #include -#include -#include #include -#include namespace sd { namespace slidesorter { namespace view { class PageObjectViewObjectContact; @@ -123,10 +121,17 @@ public: Returns a bitmap that is either empty, contains a scaled (up or down) version or is the requested bitmap. */ - BitmapEx GetPreviewBitmap ( + PreviewType GetPreviewBitmap ( const CacheKey aKey, const bool bResize); + PreviewType GetMarkedPreviewBitmap ( + const CacheKey aKey, + const bool bResize); + void SetMarkedPreviewBitmap ( + const CacheKey aKey, + const PreviewType& rBitmap); + /** When the requested preview bitmap does not yet exist or is not up-to-date then the rendering of one is scheduled. Otherwise this method does nothing. diff --git a/sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx b/sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx index 50202a7eed3d..8e1d827a286f 100644 --- a/sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx +++ b/sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx @@ -113,6 +113,11 @@ public: */ void InvalidateAllCaches (void); + /** Call this method when a page has been deleted and its preview + is not needed anymore. + */ + void ReleasePreviewBitmap (const SdrPage* pPage); + private: /** Singleton instance of the cache manager. Note that this is a weak pointer. The (implementation class of) ViewShellBase holds a diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx index b72120e9fcb9..04f19d0f7ed0 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx @@ -275,6 +275,7 @@ private: ::rtl::Reference mpListener; int mnModelChangeLockCount; + bool mbIsForcedRearrangePending; bool mbPreModelChangeDone; bool mbPostModelChangePending; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx index 536684be5dc3..9a3f8f7fdff5 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx @@ -29,7 +29,7 @@ #define SD_SLIDESORTER_CLIPBOARD #include "ViewClipboard.hxx" - +#include "controller/SlsSelectionObserver.hxx" #include #include #include @@ -97,6 +97,8 @@ public: USHORT nPage = SDRPAGE_NOTFOUND, USHORT nLayer = SDRPAGE_NOTFOUND); + void Abort (void); + protected: virtual USHORT DetermineInsertPosition ( const SdTransferable& rTransferable); @@ -134,6 +136,8 @@ private: class UndoContext; ::boost::scoped_ptr mpUndoContext; + ::boost::scoped_ptr mpSelectionObserverContext; + void CreateSlideTransferable ( ::Window* pWindow, bool bDrag); diff --git a/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx index 2612f7939610..1d5aaee7a130 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx @@ -120,16 +120,6 @@ public: */ sal_Int32 GetFocusedPageIndex (void) const; - /** DEPRECATED. (Use equivalent SetFocusedPage(sal_Int32) instead. - - Set the focus to the page with the given index. This does not make - the focus visible. - @param nPageIndex - Index of a page as it is accepted by the slide sorter model. - The index is not checked for validity. - */ - void FocusPage (sal_Int32 nPageIndex); - /** Set the focused page to the one described by the given page descriptor. The visibility of the focus indicator is not modified. @param rDescriptor @@ -145,6 +135,8 @@ public: */ void SetFocusedPage (sal_Int32 nPageIndex); + void SetFocusedPageToCurrentPage (void); + /** Return when the focus inidcator is currently shown. A prerequisite is that the window managed by this focus manager has the input focus as indicated by a return value of diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx index 3945225baf8b..fa721058cccd 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx @@ -60,7 +60,7 @@ public: ~InsertionIndicatorHandler (void); enum Mode { CopyMode, MoveMode, UnknownMode }; - static Mode GetModeFromDndAction (const sal_Int8 nMode); + static Mode GetModeFromDndAction (const sal_Int8 nDndAction); /** Activate the insertion marker at the given coordinates. */ @@ -102,7 +102,6 @@ public: */ sal_Int32 GetInsertionPageIndex (void) const; - /** Determine whether moving the current selection to the current position of the insertion marker would alter the document. This would be the case when the selection is not consecutive or would be @@ -111,6 +110,11 @@ public: bool IsInsertionTrivial ( const sal_Int32 nInsertionIndex, const Mode eMode) const; + /** This method is like the other variant. It operates implicitly + on the current insertion index as would be returned by + GetInsertionPageIndex(). + */ + bool IsInsertionTrivial (const sal_Int8 nDndAction); private: SlideSorter& mrSlideSorter; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx index c2d221c62bd5..bc39a5108cf2 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx @@ -162,8 +162,9 @@ public: UpdateLock (SlideSorter& rSlideSorter); UpdateLock (PageSelector& rPageSelector); ~UpdateLock (void); + void Release (void); private: - PageSelector& mrSelector; + PageSelector* mpSelector; }; class BroadcastLock diff --git a/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx index e72f47644a76..06d239c81da3 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx @@ -120,6 +120,8 @@ public: bool IsOnlyPreviewTriggersMouseOver (void) const; void SetOnlyPreviewTriggersMouseOver (const bool bFlag); + bool IsHighContrastModeActive (void) const; + private: bool mbIsHighlightCurrentSlide; bool mbIsShowSelection; @@ -133,6 +135,7 @@ private: Color maHighlightColor; bool mbIsUIReadOnly; bool mbIsOnlyPreviewTriggersMouseOver; + bool mbIsHighContrastModeActive; }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx index 9dfdf57bacd6..358d58b6d761 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx @@ -104,7 +104,22 @@ public: */ void UpdateMouseOverIndicationPermission (void); - ::boost::shared_ptr GetDragAndDropContext (void) const; + class EventDescriptor; + class ModeHandler; + friend class ModeHandler; + enum Mode + { + NormalMode, + MultiSelectionMode, + DragAndDropMode, + ButtonMode + }; + void SwitchToNormalMode (void); + void SwitchToDragAndDropMode(const Point aMousePosition); + void SwitchToMultiSelectionMode (const Point aMousePosition, const sal_uInt32 nEventCode); + void SwitchToButtonMode (void); + + void ResetShiftKeySelectionAnchor (void); protected: SlideSorter& mrSlideSorter; @@ -117,7 +132,6 @@ protected: virtual ~SelectionFunction(); private: - class EventDescriptor; /// The rectangle of the mouse drag selection. Rectangle maDragSelectionRectangle; @@ -134,16 +148,6 @@ private: */ bool mbProcessingMouseButtonDown; - ::boost::shared_ptr mpDragAndDropContext; - - class MouseMultiSelector; - ::boost::scoped_ptr mpMouseMultiSelector; - - /** Remember where the left mouse button was pressed. - */ - sal_Int32 mnButtonDownPageIndex; - sal_Int32 mnButtonDownButtonIndex; - bool mbIsDeselectionPending; /** Remember the slide where the shift key was pressed and started a @@ -151,19 +155,10 @@ private: */ sal_Int32 mnShiftKeySelectionAnchor; - void StartDrag ( - const Point& rMousePosition, - const InsertionIndicatorHandler::Mode eMode); - - /** Set the selection to exactly the specified page and also set it as - the current page. + /** The selection function can be in one of several mutually + exclusive modes. */ - void SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor); - - /** When the view on which this selection function is working is the - main view then the view is switched to the regular editing view. - */ - void SwitchView (const model::SharedPageDescriptor& rpDescriptor); + ::boost::shared_ptr mpModeHandler; /** Make the slide nOffset slides away of the current one the new current slide. When the new index is outside the range of valid @@ -187,45 +182,7 @@ private: // What follows are a couple of helper methods that are used by // ProcessMouseEvent(). - /// Deselect all pages. - void DeselectAllPages (void); - - /** Select all pages between and including the selection anchor and the - specified page. - */ - void RangeSelect (const model::SharedPageDescriptor& rpDescriptor); - - /** Compute a numerical code that describes a mouse event and that can - be used for fast look up of the appropriate reaction. - */ - sal_uInt32 EncodeMouseEvent ( - const EventDescriptor& rDescriptor, - const MouseEvent& rEvent) const; - - /** Compute a numerical code that describes a key event and that can - be used for fast look up of the appropriate reaction. - */ - sal_uInt32 EncodeKeyEvent ( - const EventDescriptor& rDescriptor, - const KeyEvent& rEvent) const; - - /** Compute a numerical code that describes the current state like - whether the selection rectangle is visible or whether the page under - the mouse or the one that has the focus is selected. - */ - sal_uInt32 EncodeState (const EventDescriptor& rDescriptor) const; - - 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, - const sal_Int32 nButtonIndex); + void ProcessEvent (EventDescriptor& rEvent); void MoveFocus ( const FocusManager::FocusMoveDirection eDirection, @@ -233,7 +190,8 @@ private: const bool bIsControlDown); void StopDragAndDrop (void); - void StopMouseMultiSelection (void); + + void SwitchMode (const ::boost::shared_ptr& rpHandler); }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx index 74f5b4dece95..a9617a88c2e6 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx @@ -160,31 +160,6 @@ private: A list of master pages. Supplying normal pages is an error. */ void DeleteSelectedMasterPages (const ::std::vector& rSelectedMasterPages); - - /** Return when the given rectangle, that typically is the - bounding box of all currently selected slides, does not fit entirely - into the visible area of the slide sorter view. - */ - // bool DoesSelectionExceedVisibleArea (const Rectangle& rSelectionBox) const; - - /** When not all currently selected slides fit into the visible area of - the slide sorter view, and thus DoesSelectionExceedVisibleArea() - would return , then it is the task of this method to - determine which part of the selection to move into the visible area. - @param rpFirst - The first selected slide. Must not be an empty pointer. - @param rpLast - The last selected slide. Must not be an empty pointer. - @param eSelectionHint - This hint tells the method on which slide to concentrate, - i.e. which slide has to be inside the returned visible area. - @return - Returns the new visible area. - */ - // Rectangle ResolveLargeSelection ( - // const model::SharedPageDescriptor& rpFirst, - // const model::SharedPageDescriptor& rpLast, - // const SelectionHint eSelectionHint); }; } } } // end of namespace ::sd::slidesorter::controller diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx index 7718b9b7af01..0fb45b403af1 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx @@ -30,6 +30,7 @@ #include #include +#include namespace sd { namespace slidesorter { class SlideSorter; @@ -40,6 +41,10 @@ class SdrPage; namespace sd { namespace slidesorter { namespace controller { +/** Observe insertions and deletions of pages between calls to + StartObservation() and EndObservation(). When the later is called + the selection is set to just the newly inserted pages. +*/ class SelectionObserver { public: @@ -48,6 +53,7 @@ public: void NotifyPageEvent (const SdrPage* pPage); void StartObservation (void); + void AbortObservation (void); void EndObservation (void); /** Use this little class instead of calling StartObservation and @@ -60,6 +66,7 @@ public: public: Context (SlideSorter& rSlideSorter); ~Context(void); + void Abort (void); private: ::boost::shared_ptr mpSelectionObserver; }; diff --git a/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx index 7edf45b22b16..33fda41975cf 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx @@ -45,14 +45,21 @@ public: VisibleAreaManager (SlideSorter& rSlideSorter); ~VisibleAreaManager (void); + void ActivateCurrentSlideTracking (void); + void DeactivateCurrentSlideTracking (void); + + /** Request the current slide to be moved into the visible area. + This request is only obeyed when the current slide tracking is + active. + @see ActivateCurrentSlideTracking() and DeactivateCurrentSlideTracking() + */ + void RequestCurrentSlideVisible (void); + /** Request to make the specified page object visible. - @param eRequestedAnimationMode - This flag specifies wether to smoothly scroll the page object into - view (AM_Animated) or do this in one step (AM_Immediate). */ void RequestVisible ( const model::SharedPageDescriptor& rpDescriptor, - const Animator::AnimationMode eRequestedAnimationMode = Animator::AM_Immediate); + const bool bForce = false); private: SlideSorter& mrSlideSorter; @@ -68,8 +75,8 @@ private: */ Animator::AnimationId mnScrollAnimationId; Point maRequestedVisibleTopLeft; - Animator::AnimationMode meRequestedAnimationMode; + bool mbIsCurrentSlideTrackingActive; void MakeVisible (void); ::boost::optional GetRequestedTopLeft (void) const; diff --git a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx index 2a09fc047b80..3830dfbca206 100644 --- a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx @@ -79,11 +79,6 @@ public: sal_Int32 GetButtonAlphaAnimationId (void) const; void SetButtonAlphaAnimationId (const sal_Int32 nAnimationId); - enum ButtonState { BS_Normal, BS_MouseOver, BS_Pressed }; - - void SetActiveButtonState (const sal_Int32 nIndex, const ButtonState eState); - ButtonState GetButtonState (const sal_Int32 nIndex); - sal_Int32 mnPageId; // For debugging private: @@ -99,9 +94,6 @@ private: double mnButtonAlpha; sal_Int32 mnButtonAlphaAnimationId; - - sal_Int32 mnActiveButtonIndex; - ButtonState meActiveButtonState; }; } } } // end of namespace ::sd::slidesorter::model diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx index 2b068642930a..4afc5a74ccf0 100644 --- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx +++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx @@ -63,6 +63,7 @@ class SlideSorterModel; namespace sd { namespace slidesorter { namespace view { +class ButtonBar; class LayeredDevice; class Layouter; class PageObjectPainter; @@ -198,18 +199,19 @@ public: /** The page under the mouse is not highlighted in some contexts. Call this method on context changes. */ - void SetIsMouseOverIndicationAllowed (const bool bIsAllowed); void UpdatePageUnderMouse (bool bAnimate); void UpdatePageUnderMouse ( const Point& rMousePosition, const bool bIsMouseButtonDown, const bool bAnimate = true); + void UpdatePageUnderMouse ( + const model::SharedPageDescriptor& rpDescriptor, + const Point& rMousePosition, + const bool bIsMouseButtonDown, + const bool bAnimate = true); void SetPageUnderMouse ( const model::SharedPageDescriptor& rpDescriptor, const bool bAnimate = true); - void SetButtonUnderMouse ( - const sal_Int32 nButtonIndex, - const bool bForce = false); bool SetState ( const model::SharedPageDescriptor& rpDescriptor, @@ -237,6 +239,8 @@ public: SharedSdWindow mpWindow; }; + ButtonBar& GetButtonBar (void) const; + protected: virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); @@ -255,18 +259,20 @@ private: Layouter::Orientation meOrientation; ::boost::shared_ptr mpProperties; model::SharedPageDescriptor mpPageUnderMouse; - bool mbIsMouseOverIndicationAllowed; + ::rtl::OUString msHelpText; sal_Int32 mnButtonUnderMouse; ::boost::shared_ptr mpPageObjectPainter; ::boost::shared_ptr mpSelectionPainter; Region maRedrawRegion; SharedILayerPainter mpBackgroundPainter; + ::boost::scoped_ptr mpButtonBar; /** Determine the visibility of all page objects. */ void DeterminePageObjectVisibilities (void); void UpdatePreciousFlags (void); + void Rearrange (void); }; diff --git a/sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx b/sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx new file mode 100644 index 000000000000..61b81614b2ae --- /dev/null +++ b/sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx @@ -0,0 +1,322 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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_VIEW_BUTTON_BAR_HXX +#define SD_SLIDESORTER_VIEW_BUTTON_BAR_HXX + +#include "model/SlsSharedPageDescriptor.hxx" +#include +#include +#include + + +namespace sd { namespace slidesorter { +class SlideSorter; +} } + + +namespace sd { namespace slidesorter { namespace view { + +class Theme; + +class Button; +typedef ::boost::shared_ptr