diff options
author | Andre Fischer <af@openoffice.org> | 2010-06-21 15:59:22 +0200 |
---|---|---|
committer | Andre Fischer <af@openoffice.org> | 2010-06-21 15:59:22 +0200 |
commit | 4a33a0f64fa420d39d079c3ab31a0c4579dc83b7 (patch) | |
tree | 271ffab3112767b6c69b512f122379f083430721 | |
parent | 75154ca8f08ef1e188498c077ca195b134ce2675 (diff) |
renaissance1: #i107215# Slide sorter triggers page change after short delay.
5 files changed, 86 insertions, 26 deletions
diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx index 7c2f3f8c48ce..8253db66ee61 100644 --- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx +++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx @@ -633,6 +633,11 @@ IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent) mrView.RequestRepaint(); break; + case VCLEVENT_WINDOW_HIDE: + if (pActiveWindow && pWindow == pActiveWindow->GetParent()) + mrView.SetPageUnderMouse(SharedPageDescriptor()); + break; + case VCLEVENT_WINDOW_GETFOCUS: if (pActiveWindow) if (pWindow == pActiveWindow.get()) diff --git a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx index 19a3c160ba46..ed6dea7e13d3 100644 --- a/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsCurrentSlideManager.cxx @@ -54,8 +54,11 @@ namespace sd { namespace slidesorter { namespace controller { CurrentSlideManager::CurrentSlideManager (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mnCurrentSlideIndex(-1), - mpCurrentSlide() + mpCurrentSlide(), + maSwitchPageDelayTimer() { + maSwitchPageDelayTimer.SetTimeout(100); + maSwitchPageDelayTimer.SetTimeoutHdl(LINK(this,CurrentSlideManager,SwitchPageCallback)); } @@ -163,21 +166,23 @@ void CurrentSlideManager::SwitchCurrentSlide ( ViewShell* pViewShell = mrSlideSorter.GetViewShell(); if (pViewShell != NULL && pViewShell->IsMainViewShell()) { + // The slide sorter is the main view. FrameView* pFrameView = pViewShell->GetFrameView(); if (pFrameView != NULL) pFrameView->SetSelectedPage(sal::static_int_cast<USHORT>(mnCurrentSlideIndex)); mrSlideSorter.GetController().GetPageSelector().SetCoreSelection(); } - else - { - // Set current page. At the moment we have to do this in two - // different ways. The UNO way is the preferable one but, alas, - // it does not work always correctly (after some kinds of model - // changes). Therefore, we call DrawViewShell::SwitchPage(), - // too. - SetCurrentSlideAtViewShellBase(rpDescriptor); - } - SetCurrentSlideAtXController(rpDescriptor); + + // We do not tell the XController/ViewShellBase about the new + // slide right away. This is done asynchronously after a short + // delay to allow for more slide switches in the slide sorter. + // This goes under the assumption that slide switching inside + // the slide sorter is fast (no expensive redraw of the new page + // (unless the preview of the new slide is not yet preset)) and + // that slide switching in the edit view is slow (all shapes of + // the new slide have to be repainted.) + maSwitchPageDelayTimer.Start(); + if (bUpdateSelection) { mrSlideSorter.GetController().GetPageSelector().DeselectAllPages(); @@ -280,6 +285,27 @@ void CurrentSlideManager::HandleModelChange (void) +IMPL_LINK(CurrentSlideManager, SwitchPageCallback, void*, EMPTYARG) +{ + if (mpCurrentSlide) + { + // Set current page. At the moment we have to do this in two + // different ways. The UNO way is the preferable one but, alas, + // it does not work always correctly (after some kinds of model + // changes). Therefore, we call DrawViewShell::SwitchPage(), + // too. + ViewShell* pViewShell = mrSlideSorter.GetViewShell(); + if (pViewShell==NULL || ! pViewShell->IsMainViewShell()) + SetCurrentSlideAtViewShellBase(mpCurrentSlide); + SetCurrentSlideAtXController(mpCurrentSlide); + } + + return 1; +} + + + + SdPage* GetCurrentSdPage (SlideSorter& rSlideSorter) { SharedPageDescriptor pDescriptor ( diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx index 85643bdd95ef..50cc574801e4 100644 --- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx @@ -96,17 +96,15 @@ void ScrollBarManager::LateInitialization (void) void ScrollBarManager::Connect (void) { if (mpVerticalScrollBar != NULL) + { mpVerticalScrollBar->SetScrollHdl ( - LINK( - this, - ScrollBarManager, - VerticalScrollBarHandler)); + LINK(this, ScrollBarManager, VerticalScrollBarHandler)); + } if (mpHorizontalScrollBar != NULL) - mpHorizontalScrollBar->SetScrollHdl ( - LINK( - this, - ScrollBarManager, - HorizontalScrollBarHandler)); + { + mpHorizontalScrollBar->SetScrollHdl( + LINK(this, ScrollBarManager, HorizontalScrollBarHandler)); + } } @@ -115,9 +113,13 @@ void ScrollBarManager::Connect (void) void ScrollBarManager::Disconnect (void) { if (mpVerticalScrollBar != NULL) + { mpVerticalScrollBar->SetScrollHdl (Link()); + } if (mpHorizontalScrollBar != NULL) + { mpHorizontalScrollBar->SetScrollHdl (Link()); + } } @@ -324,7 +326,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.GetContentWindow()->SetVisibleXY(-1, nRelativePosition); mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking(); } return TRUE; @@ -343,7 +345,7 @@ IMPL_LINK(ScrollBarManager, HorizontalScrollBarHandler, ScrollBar*, pScrollBar) double nRelativePosition = double(pScrollBar->GetThumbPos()) / double(pScrollBar->GetRange().Len()); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); - mrSlideSorter.GetContentWindow()->SetVisibleXY (nRelativePosition, -1); + mrSlideSorter.GetContentWindow()->SetVisibleXY(nRelativePosition, -1); mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking(); } return TRUE; @@ -502,7 +504,7 @@ void ScrollBarManager::SetTopLeft (const Point aNewTopLeft) mnHorizontalPosition = aNewTopLeft.X() / double(mpHorizontalScrollBar->GetRange().Len()); } - mrSlideSorter.GetContentWindow()->SetVisibleXY (mnHorizontalPosition, mnVerticalPosition); + mrSlideSorter.GetContentWindow()->SetVisibleXY(mnHorizontalPosition, mnVerticalPosition); mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); } diff --git a/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx index 258570509c52..c479fe833869 100644 --- a/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx +++ b/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx @@ -29,6 +29,8 @@ #define SD_SLIDESORTER_CURRENT_SLIDE_MANAGER_HXX #include "model/SlsSharedPageDescriptor.hxx" +#include <vcl/timer.hxx> +#include <tools/link.hxx> #include <com/sun/star/drawing/XDrawPage.hpp> class SdPage; @@ -43,6 +45,10 @@ namespace sd { namespace slidesorter { namespace controller { /** Manage the current slide. This includes setting the according flags at the PageDescriptor objects and setting the current slide at the main view shell. + + Switching pages is triggered only after a little delay. This allows + fast travelling through a larger set of slides without having to wait + for the edit view to update its content after every slide change. */ class CurrentSlideManager { @@ -93,6 +99,10 @@ private: SlideSorter& mrSlideSorter; sal_Int32 mnCurrentSlideIndex; model::SharedPageDescriptor mpCurrentSlide; + /** Timer to control the delay after which to ask + XController/ViewShellBase to switch to another slide. + */ + Timer maSwitchPageDelayTimer; bool IsCurrentSlideIsValid (void); void SetCurrentSlideAtViewShellBase (const model::SharedPageDescriptor& rpSlide); @@ -107,6 +117,8 @@ private: method connects to the new current slide. */ void AcquireCurrentSlide (const sal_Int32 nSlideIndex); + + DECL_LINK(SwitchPageCallback,void*); }; diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx index 1b33625daefe..1e3b35a685cc 100644 --- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -65,6 +65,7 @@ #include <svx/xlndsit.hxx> #include <svx/xlnclit.hxx> #include <vcl/svapp.hxx> +#include <vcl/scrbar.hxx> #include <tools/poly.hxx> #include <vcl/lineinfo.hxx> #include <algorithm> @@ -909,19 +910,33 @@ void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint void SlideSorterView::UpdatePageUnderMouse (bool bAnimate) { + ::boost::shared_ptr<ScrollBar> pVScrollBar (mrSlideSorter.GetVerticalScrollBar()); + ::boost::shared_ptr<ScrollBar> pHScrollBar (mrSlideSorter.GetHorizontalScrollBar()); + if ((pVScrollBar && pVScrollBar->IsVisible() && pVScrollBar->IsTracking()) + || (pHScrollBar && pHScrollBar->IsVisible() && pHScrollBar->IsTracking())) + { + // One of the scroll bars is tracking mouse movement. Do not + // highlight the slide under the mouse in this case. + SetPageUnderMouse(SharedPageDescriptor(),false); + return; + } + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); - if (pWindow && ! pWindow->IsMouseCaptured()) + if (pWindow && pWindow->IsVisible() && ! pWindow->IsMouseCaptured()) { const Window::PointerState aPointerState (pWindow->GetPointerState()); 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); + return; + } } + + SetPageUnderMouse(SharedPageDescriptor(),false); } |