renaissance1: #i107215# Slide sorter triggers page change after short delay.

This commit is contained in:
Andre Fischer
2010-06-21 15:59:22 +02:00
parent 75154ca8f0
commit 4a33a0f64f
5 changed files with 86 additions and 26 deletions

View File

@@ -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())

View File

@@ -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 (

View File

@@ -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();
}

View File

@@ -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*);
};

View File

@@ -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);
}