/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include "PresenterScrollBar.hxx" #include "PresenterBitmapContainer.hxx" #include "PresenterCanvasHelper.hxx" #include "PresenterGeometryHelper.hxx" #include "PresenterPaintManager.hxx" #include "PresenterTimer.hxx" #include "PresenterUIPainter.hxx" #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; const static double gnScrollBarGap (10); namespace sdext { namespace presenter { //===== PresenterScrollBar::MousePressRepeater ================================ class PresenterScrollBar::MousePressRepeater : public ::boost::enable_shared_from_this { public: MousePressRepeater (const ::rtl::Reference& rpScrollBar); void Dispose (void); void Start (const PresenterScrollBar::Area& reArea); void Stop (void); void SetMouseArea (const PresenterScrollBar::Area& reArea); private: void Callback (const TimeValue& rCurrentTime); void Execute (void); sal_Int32 mnMousePressRepeaterTaskId; ::rtl::Reference mpScrollBar; PresenterScrollBar::Area meMouseArea; }; //===== PresenterScrollBar ==================================================== boost::weak_ptr PresenterScrollBar::mpSharedBitmaps; PresenterScrollBar::PresenterScrollBar ( const Reference& rxComponentContext, const Reference& rxParentWindow, const ::boost::shared_ptr& rpPaintManager, const ::boost::function& rThumbMotionListener) : PresenterScrollBarInterfaceBase(m_aMutex), mxComponentContext(rxComponentContext), mxParentWindow(rxParentWindow), mxWindow(), mxCanvas(), mxPresenterHelper(), mpPaintManager(rpPaintManager), mnThumbPosition(0), mnTotalSize(0), mnThumbSize(0), mnLineHeight(10), maDragAnchor(-1,-1), maThumbMotionListener(rThumbMotionListener), meButtonDownArea(None), meMouseMoveArea(None), mbIsNotificationActive(false), mpBitmaps(), mpPrevButtonDescriptor(), mpNextButtonDescriptor(), mpPagerStartDescriptor(), mpPagerCenterDescriptor(), mpPagerEndDescriptor(), mpThumbStartDescriptor(), mpThumbCenterDescriptor(), mpThumbEndDescriptor(), mpMousePressRepeater(new MousePressRepeater(this)), mpBackgroundBitmap(), mpCanvasHelper(new PresenterCanvasHelper()) { try { Reference xFactory (rxComponentContext->getServiceManager()); if ( ! xFactory.is()) throw RuntimeException(); mxPresenterHelper = Reference( xFactory->createInstanceWithContext( OUString("com.sun.star.comp.Draw.PresenterHelper"), rxComponentContext), UNO_QUERY_THROW); if (mxPresenterHelper.is()) mxWindow = mxPresenterHelper->createWindow(rxParentWindow, sal_False, sal_False, sal_False, sal_False); // Make the background transparent. The slide show paints its own background. Reference xPeer (mxWindow, UNO_QUERY_THROW); if (xPeer.is()) { xPeer->setBackground(0xff000000); } mxWindow->setVisible(sal_True); mxWindow->addWindowListener(this); mxWindow->addPaintListener(this); mxWindow->addMouseListener(this); mxWindow->addMouseMotionListener(this); } catch (RuntimeException&) { } } PresenterScrollBar::~PresenterScrollBar (void) { } void SAL_CALL PresenterScrollBar::disposing (void) { mpMousePressRepeater->Dispose(); if (mxWindow.is()) { mxWindow->removeWindowListener(this); mxWindow->removePaintListener(this); mxWindow->removeMouseListener(this); mxWindow->removeMouseMotionListener(this); Reference xComponent (mxWindow, UNO_QUERY); mxWindow = NULL; if (xComponent.is()) xComponent->dispose(); } mpBitmaps.reset(); } void PresenterScrollBar::SetVisible (const bool bIsVisible) { if (mxWindow.is()) mxWindow->setVisible(bIsVisible); } void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox) { if (mxWindow.is()) { mxWindow->setPosSize( sal_Int32(floor(rBox.X1)), sal_Int32(ceil(rBox.Y1)), sal_Int32(ceil(rBox.X2-rBox.X1)), sal_Int32(floor(rBox.Y2-rBox.Y1)), awt::PosSize::POSSIZE); UpdateBorders(); } } void PresenterScrollBar::SetThumbPosition ( double nPosition, const bool bAsynchronousUpdate) { SetThumbPosition(nPosition, bAsynchronousUpdate, true, true); } void PresenterScrollBar::SetThumbPosition ( double nPosition, const bool bAsynchronousUpdate, const bool bValidate, const bool bNotify) { if (bValidate) nPosition = ValidateThumbPosition(nPosition); if (nPosition != mnThumbPosition && ! mbIsNotificationActive) { mnThumbPosition = nPosition; UpdateBorders(); Repaint(GetRectangle(Total), bAsynchronousUpdate); if (bNotify) NotifyThumbPositionChange(); } } void PresenterScrollBar::SetTotalSize (const double nTotalSize) { if (mnTotalSize != nTotalSize) { mnTotalSize = nTotalSize + 1; UpdateBorders(); Repaint(GetRectangle(Total), false); } } void PresenterScrollBar::SetThumbSize (const double nThumbSize) { OSL_ASSERT(nThumbSize>=0); if (mnThumbSize != nThumbSize) { mnThumbSize = nThumbSize; UpdateBorders(); Repaint(GetRectangle(Total), false); } } void PresenterScrollBar::SetLineHeight (const double nLineHeight) { mnLineHeight = nLineHeight; } void PresenterScrollBar::SetCanvas (const Reference& rxCanvas) { if (mxCanvas != rxCanvas) { mxCanvas = rxCanvas; if (mxCanvas.is()) { if (mpBitmaps.get()==NULL) { if (mpSharedBitmaps.expired()) { try { mpBitmaps.reset(new PresenterBitmapContainer( OUString("PresenterScreenSettings/ScrollBar/Bitmaps"), ::boost::shared_ptr(), mxComponentContext, mxCanvas)); mpSharedBitmaps = mpBitmaps; } catch(Exception&) { OSL_ASSERT(false); } } else mpBitmaps = ::boost::shared_ptr(mpSharedBitmaps); UpdateBitmaps(); UpdateBorders(); } Repaint(GetRectangle(Total), false); } } } void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap) { mpBackgroundBitmap = rpBackgroundBitmap; } void PresenterScrollBar::CheckValues (void) { mnThumbPosition = ValidateThumbPosition(mnThumbPosition); } double PresenterScrollBar::ValidateThumbPosition (double nPosition) { if (nPosition + mnThumbSize > mnTotalSize) nPosition = mnTotalSize - mnThumbSize; if (nPosition < 0) nPosition = 0; return nPosition; } void PresenterScrollBar::Paint ( const awt::Rectangle& rUpdateBox, const bool bNoClip) { if ( ! mxCanvas.is() || ! mxWindow.is()) { OSL_ASSERT(mxCanvas.is()); OSL_ASSERT(mxWindow.is()); return; } if ( ! bNoClip) { if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize())) return; } PaintBackground(rUpdateBox); PaintComposite(rUpdateBox, PagerUp, mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor()); PaintComposite(rUpdateBox, PagerDown, SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor); PaintComposite(rUpdateBox, Thumb, mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor); PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor); PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor); Reference xSpriteCanvas (mxCanvas, UNO_QUERY); if (xSpriteCanvas.is()) xSpriteCanvas->updateScreen(sal_False); } //----- XWindowListener ------------------------------------------------------- void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent& rEvent) throw (css::uno::RuntimeException, std::exception) { (void)rEvent; } void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent& rEvent) throw (css::uno::RuntimeException, std::exception) { (void)rEvent; } void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject& rEvent) throw (css::uno::RuntimeException, std::exception) { (void)rEvent; } void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject& rEvent) throw (css::uno::RuntimeException, std::exception) { (void)rEvent; } //----- XPaintListener -------------------------------------------------------- void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent) throw (css::uno::RuntimeException, std::exception) { if (mxWindow.is()) { awt::Rectangle aRepaintBox (rEvent.UpdateRect); const awt::Rectangle aWindowBox (mxWindow->getPosSize()); aRepaintBox.X += aWindowBox.X; aRepaintBox.Y += aWindowBox.Y; Paint(aRepaintBox); Reference xSpriteCanvas (mxCanvas, UNO_QUERY); if (xSpriteCanvas.is()) xSpriteCanvas->updateScreen(sal_False); } } //----- XMouseListener -------------------------------------------------------- void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent) throw(css::uno::RuntimeException, std::exception) { maDragAnchor.X = rEvent.X; maDragAnchor.Y = rEvent.Y; meButtonDownArea = GetArea(rEvent.X, rEvent.Y); mpMousePressRepeater->Start(meButtonDownArea); } void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent& rEvent) throw(css::uno::RuntimeException, std::exception) { (void)rEvent; mpMousePressRepeater->Stop(); if (mxPresenterHelper.is()) mxPresenterHelper->releaseMouse(mxWindow); } void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent& rEvent) throw(css::uno::RuntimeException, std::exception) { (void)rEvent; } void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent& rEvent) throw(css::uno::RuntimeException, std::exception) { (void)rEvent; if (meMouseMoveArea != None) { const Area eOldMouseMoveArea (meMouseMoveArea); meMouseMoveArea = None; Repaint(GetRectangle(eOldMouseMoveArea), true); } meButtonDownArea = None; meMouseMoveArea = None; mpMousePressRepeater->Stop(); } //----- XMouseMotionListener -------------------------------------------------- void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent) throw (css::uno::RuntimeException, std::exception) { const Area eArea (GetArea(rEvent.X, rEvent.Y)); if (eArea != meMouseMoveArea) { const Area eOldMouseMoveArea (meMouseMoveArea); meMouseMoveArea = eArea; if (eOldMouseMoveArea != None) Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None); if (meMouseMoveArea != None) Repaint(GetRectangle(meMouseMoveArea), true); } mpMousePressRepeater->SetMouseArea(eArea); } void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent) throw (css::uno::RuntimeException, std::exception) { if (meButtonDownArea != Thumb) return; mpMousePressRepeater->Stop(); if (mxPresenterHelper.is()) mxPresenterHelper->captureMouse(mxWindow); const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y)); UpdateDragAnchor(nDragDistance); if (nDragDistance != 0) { SetThumbPosition(mnThumbPosition + nDragDistance, false, true, true); } } //----- lang::XEventListener -------------------------------------------------- void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent) throw (css::uno::RuntimeException, std::exception) { if (rEvent.Source == mxWindow) mxWindow = NULL; } geometry::RealRectangle2D PresenterScrollBar::GetRectangle (const Area eArea) const { OSL_ASSERT(eArea>=0 && eArea<__AreaCount__); return maBox[eArea]; } void PresenterScrollBar::Repaint ( const geometry::RealRectangle2D aBox, const bool bAsynchronousUpdate) { if (mpPaintManager.get() != NULL) mpPaintManager->Invalidate( mxWindow, PresenterGeometryHelper::ConvertRectangle(aBox), bAsynchronousUpdate); } void PresenterScrollBar::PaintBackground( const css::awt::Rectangle& rUpdateBox) { if (mpBackgroundBitmap.get() == NULL) return; const awt::Rectangle aWindowBox (mxWindow->getPosSize()); mpCanvasHelper->Paint( mpBackgroundBitmap, mxCanvas, rUpdateBox, aWindowBox, awt::Rectangle()); } void PresenterScrollBar::PaintBitmap( const css::awt::Rectangle& rUpdateBox, const Area eArea, const SharedBitmapDescriptor& rpBitmaps) { const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea)); const awt::Rectangle aWindowBox (mxWindow->getPosSize()); geometry::RealRectangle2D aBox (aLocalBox); aBox.X1 += aWindowBox.X; aBox.Y1 += aWindowBox.Y; aBox.X2 += aWindowBox.X; aBox.Y2 += aWindowBox.Y; Reference xBitmap (GetBitmap(eArea,rpBitmaps)); if (xBitmap.is()) { Reference xClipPolygon ( PresenterGeometryHelper::CreatePolygon( PresenterGeometryHelper::Intersection(rUpdateBox, PresenterGeometryHelper::ConvertRectangle(aBox)), mxCanvas->getDevice())); const rendering::ViewState aViewState ( geometry::AffineMatrix2D(1,0,0, 0,1,0), xClipPolygon); const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); rendering::RenderState aRenderState ( geometry::AffineMatrix2D( 1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2, 0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2), NULL, Sequence(4), rendering::CompositeOperation::SOURCE); mxCanvas->drawBitmap( xBitmap, aViewState, aRenderState); } } void PresenterScrollBar::NotifyThumbPositionChange (void) { if ( ! mbIsNotificationActive) { mbIsNotificationActive = true; try { maThumbMotionListener(mnThumbPosition); } catch (Exception&) { } mbIsNotificationActive = false; } } PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const { const geometry::RealPoint2D aPoint(nX, nY); if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint)) { if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint)) return Thumb; else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint)) return PagerUp; else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint)) return PagerDown; } else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint)) return PrevButton; else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint)) return NextButton; return None; } void PresenterScrollBar::UpdateWidthOrHeight ( sal_Int32& rSize, const SharedBitmapDescriptor& rpDescriptor) { if (rpDescriptor.get() != NULL) { Reference xBitmap (rpDescriptor->GetNormalBitmap()); if (xBitmap.is()) { const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); const sal_Int32 nBitmapSize = (sal_Int32)GetMinor(aBitmapSize.Width, aBitmapSize.Height); if (nBitmapSize > rSize) rSize = nBitmapSize; } } } css::uno::Reference PresenterScrollBar::GetBitmap ( const Area eArea, const SharedBitmapDescriptor& rpBitmaps) const { if (rpBitmaps.get() == NULL) return NULL; else return rpBitmaps->GetBitmap(GetBitmapMode(eArea)); } PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode ( const Area eArea) const { if (IsDisabled(eArea)) return PresenterBitmapContainer::BitmapDescriptor::Disabled; else if (eArea == meMouseMoveArea) return PresenterBitmapContainer::BitmapDescriptor::MouseOver; else return PresenterBitmapContainer::BitmapDescriptor::Normal; } bool PresenterScrollBar::IsDisabled (const Area eArea) const { OSL_ASSERT(eArea>=0 && eArea<__AreaCount__); return ! maEnabledState[eArea]; } //===== PresenterVerticalScrollBar ============================================ PresenterVerticalScrollBar::PresenterVerticalScrollBar ( const Reference& rxComponentContext, const Reference& rxParentWindow, const ::boost::shared_ptr& rpPaintManager, const ::boost::function& rThumbMotionListener) : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener), mnScrollBarWidth(0) { } PresenterVerticalScrollBar::~PresenterVerticalScrollBar (void) { } double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const { (void)nX; const double nDistance (nY - maDragAnchor.Y); if (nDistance == 0) return 0; else { const awt::Rectangle aWindowBox (mxWindow->getPosSize()); const double nBarWidth (aWindowBox.Width); const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); const double nDragDistance (mnTotalSize / nPagerHeight * nDistance); if (nDragDistance + mnThumbPosition < 0) return -mnThumbPosition; else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize) return mnTotalSize-mnThumbSize-mnThumbPosition; else return nDragDistance; } } void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance) { const awt::Rectangle aWindowBox (mxWindow->getPosSize()); const double nBarWidth (aWindowBox.Width); const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); maDragAnchor.Y += nDragDistance * nPagerHeight / mnTotalSize; } sal_Int32 PresenterVerticalScrollBar::GetSize (void) const { return mnScrollBarWidth; } geometry::RealPoint2D PresenterVerticalScrollBar::GetPoint ( const double nMajor, const double nMinor) const { return geometry::RealPoint2D(nMinor, nMajor); } double PresenterVerticalScrollBar::GetMinor (const double nX, const double nY) const { (void)nY; return nX; } void PresenterVerticalScrollBar::UpdateBorders (void) { const awt::Rectangle aWindowBox (mxWindow->getPosSize()); double nBottom = aWindowBox.Height; if (mpNextButtonDescriptor.get() != NULL) { Reference xBitmap (mpNextButtonDescriptor->GetNormalBitmap()); if (xBitmap.is()) { geometry::IntegerSize2D aSize (xBitmap->getSize()); maBox[NextButton] = geometry::RealRectangle2D( 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); nBottom -= aSize.Height + gnScrollBarGap; } } if (mpPrevButtonDescriptor.get() != NULL) { Reference xBitmap (mpPrevButtonDescriptor->GetNormalBitmap()); if (xBitmap.is()) { geometry::IntegerSize2D aSize (xBitmap->getSize()); maBox[PrevButton] = geometry::RealRectangle2D( 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); nBottom -= aSize.Height + gnScrollBarGap; } } const double nPagerHeight (nBottom); maBox[Pager] = geometry::RealRectangle2D( 0,0, aWindowBox.Width, nBottom); if (mnTotalSize < 1) { maBox[Thumb] = maBox[Pager]; // Set up the enabled/disabled states. maEnabledState[PrevButton] = false; maEnabledState[PagerUp] = false; maEnabledState[NextButton] = false; maEnabledState[PagerDown] = false; maEnabledState[Thumb] = false; } else { const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize); const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize); maBox[Thumb] = geometry::RealRectangle2D( 0, nThumbPosition / mnTotalSize * nPagerHeight, aWindowBox.Width, (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight); // Set up the enabled/disabled states. maEnabledState[PrevButton] = nThumbPosition>0; maEnabledState[PagerUp] = nThumbPosition>0; maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize; maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize; maEnabledState[Thumb] = nThumbSize < mnTotalSize; } maBox[PagerUp] = geometry::RealRectangle2D( maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1); maBox[PagerDown] = geometry::RealRectangle2D( maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2); maBox[Total] = PresenterGeometryHelper::Union( PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]), maBox[Pager]); } void PresenterVerticalScrollBar::UpdateBitmaps (void) { if (mpBitmaps.get() != NULL) { mpPrevButtonDescriptor = mpBitmaps->GetBitmap("Up"); mpNextButtonDescriptor = mpBitmaps->GetBitmap("Down"); mpPagerStartDescriptor = mpBitmaps->GetBitmap("PagerTop"); mpPagerCenterDescriptor = mpBitmaps->GetBitmap("PagerVertical"); mpPagerEndDescriptor = mpBitmaps->GetBitmap("PagerBottom"); mpThumbStartDescriptor = mpBitmaps->GetBitmap("ThumbTop"); mpThumbCenterDescriptor = mpBitmaps->GetBitmap("ThumbVertical"); mpThumbEndDescriptor = mpBitmaps->GetBitmap("ThumbBottom"); mnScrollBarWidth = 0; UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor); UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor); UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor); UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor); UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor); UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor); UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor); UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor); if (mnScrollBarWidth == 0) mnScrollBarWidth = 20; } } void PresenterVerticalScrollBar::PaintComposite( const css::awt::Rectangle& rUpdateBox, const Area eArea, const SharedBitmapDescriptor& rpStartBitmaps, const SharedBitmapDescriptor& rpCenterBitmaps, const SharedBitmapDescriptor& rpEndBitmaps) { const awt::Rectangle aWindowBox (mxWindow->getPosSize()); geometry::RealRectangle2D aBox (GetRectangle(eArea)); aBox.X1 += aWindowBox.X; aBox.Y1 += aWindowBox.Y; aBox.X2 += aWindowBox.X; aBox.Y2 += aWindowBox.Y; // Get bitmaps and sizes. PresenterUIPainter::PaintVerticalBitmapComposite( mxCanvas, rUpdateBox, (eArea == Thumb ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox) : PresenterGeometryHelper::ConvertRectangle(aBox)), GetBitmap(eArea, rpStartBitmaps), GetBitmap(eArea, rpCenterBitmaps), GetBitmap(eArea, rpEndBitmaps)); } //===== PresenterScrollBar::MousePressRepeater ================================ PresenterScrollBar::MousePressRepeater::MousePressRepeater ( const ::rtl::Reference& rpScrollBar) : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId), mpScrollBar(rpScrollBar), meMouseArea(PresenterScrollBar::None) { } void PresenterScrollBar::MousePressRepeater::Dispose (void) { Stop(); mpScrollBar = NULL; } void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea) { meMouseArea = reArea; if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId) { // Execute key press operation at least this one time. Execute(); // Schedule repeated executions. mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask ( ::boost::bind(&PresenterScrollBar::MousePressRepeater::Callback, shared_from_this(), _1), 500000000, 250000000); } else { // There is already an active repeating task. } } void PresenterScrollBar::MousePressRepeater::Stop (void) { if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) { const sal_Int32 nTaskId (mnMousePressRepeaterTaskId); mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId; PresenterTimer::CancelTask(nTaskId); } } void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea) { if (meMouseArea != reArea) { if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) { Stop(); } } } void PresenterScrollBar::MousePressRepeater::Callback (const TimeValue& rCurrentTime) { (void)rCurrentTime; if (mpScrollBar.get() == NULL) { Stop(); return; } Execute(); } void PresenterScrollBar::MousePressRepeater::Execute (void) { const double nThumbPosition (mpScrollBar->GetThumbPosition()); switch (meMouseArea) { case PrevButton: mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true); break; case NextButton: mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true); break; case PagerUp: mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true); break; case PagerDown: mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true); break; default: break; } } } } // end of namespace ::sdext::presenter /* vim:set shiftwidth=4 softtabstop=4 expandtab: */