diff options
Diffstat (limited to 'sdext/source/presenter/PresenterScrollBar.cxx')
-rw-r--r-- | sdext/source/presenter/PresenterScrollBar.cxx | 1348 |
1 files changed, 1348 insertions, 0 deletions
diff --git a/sdext/source/presenter/PresenterScrollBar.cxx b/sdext/source/presenter/PresenterScrollBar.cxx new file mode 100644 index 000000000000..7b78acaed7aa --- /dev/null +++ b/sdext/source/presenter/PresenterScrollBar.cxx @@ -0,0 +1,1348 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sdext.hxx" + +#include "PresenterScrollBar.hxx" +#include "PresenterBitmapContainer.hxx" +#include "PresenterCanvasHelper.hxx" +#include "PresenterComponent.hxx" +#include "PresenterGeometryHelper.hxx" +#include "PresenterPaintManager.hxx" +#include "PresenterTimer.hxx" +#include "PresenterUIPainter.hxx" +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/XWindowPeer.hpp> +#include <com/sun/star/awt/XToolkit.hpp> +#include <com/sun/star/rendering/CompositeOperation.hpp> +#include <com/sun/star/rendering/TexturingMode.hpp> +#include <com/sun/star/rendering/XPolyPolygon2D.hpp> +#include <boost/bind.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/weak_ptr.hpp> +#include <math.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using ::rtl::OUString; + +#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) + +const static double gnScrollBarGap (10); + +namespace sdext { namespace presenter { + +//===== PresenterScrollBar::MousePressRepeater ================================ + +class PresenterScrollBar::MousePressRepeater + : public ::boost::enable_shared_from_this<MousePressRepeater> +{ +public: + MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& 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<PresenterScrollBar> mpScrollBar; + PresenterScrollBar::Area meMouseArea; +}; + + + + +//===== PresenterScrollBar ==================================================== + +boost::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps; + +PresenterScrollBar::PresenterScrollBar ( + const Reference<XComponentContext>& rxComponentContext, + const Reference<awt::XWindow>& rxParentWindow, + const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, + const ::boost::function<void(double)>& 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<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager()); + if ( ! xFactory.is()) + throw RuntimeException(); + + mxPresenterHelper = Reference<drawing::XPresenterHelper>( + xFactory->createInstanceWithContext( + OUString(RTL_CONSTASCII_USTRINGPARAM("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<awt::XWindowPeer> 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<lang::XComponent> 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(); + } +} + + + + +double PresenterScrollBar::GetThumbPosition (void) const +{ + return mnThumbPosition; +} + + + + +void PresenterScrollBar::SetTotalSize (const double nTotalSize) +{ + if (mnTotalSize != nTotalSize) + { + mnTotalSize = nTotalSize + 1; + UpdateBorders(); + Repaint(GetRectangle(Total), false); + } +} + + + + +double PresenterScrollBar::GetTotalSize (void) const +{ + return mnTotalSize; +} + + + + +void PresenterScrollBar::SetThumbSize (const double nThumbSize) +{ + OSL_ASSERT(nThumbSize>=0); + if (mnThumbSize != nThumbSize) + { + mnThumbSize = nThumbSize; + UpdateBorders(); + Repaint(GetRectangle(Total), false); + } +} + + + + +double PresenterScrollBar::GetThumbSize (void) const +{ + return mnThumbSize; +} + + + + +void PresenterScrollBar::SetLineHeight (const double nLineHeight) +{ + mnLineHeight = nLineHeight; +} + + + + +double PresenterScrollBar::GetLineHeight (void) const +{ + return mnLineHeight; +} + + + + +void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas) +{ + if (mxCanvas != rxCanvas) + { + mxCanvas = rxCanvas; + if (mxCanvas.is()) + { + if (mpBitmaps.get()==NULL) + { + if (mpSharedBitmaps.expired()) + { + try + { + mpBitmaps.reset(new PresenterBitmapContainer( + OUString(RTL_CONSTASCII_USTRINGPARAM("PresenterScreenSettings/ScrollBar/Bitmaps")), + ::boost::shared_ptr<PresenterBitmapContainer>(), + mxComponentContext, + mxCanvas, + PresenterComponent::GetBasePath(mxComponentContext))); + mpSharedBitmaps = mpBitmaps; + } + catch(Exception&) + { + OSL_ASSERT(false); + } + } + else + mpBitmaps = ::boost::shared_ptr<PresenterBitmapContainer>(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<rendering::XSpriteCanvas> 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) +{ + (void)rEvent; +} + + + + + +void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +//----- XPaintListener -------------------------------------------------------- + +void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent) + throw (css::uno::RuntimeException) +{ + 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<rendering::XSpriteCanvas> 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) +{ + 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) +{ + (void)rEvent; + + mpMousePressRepeater->Stop(); + + if (mxPresenterHelper.is()) + mxPresenterHelper->releaseMouse(mxWindow); +} + + + + +void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent& rEvent) + throw(css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent& rEvent) + throw(css::uno::RuntimeException) +{ + (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) +{ + 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) +{ + 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) +{ + 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<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps)); + + if (xBitmap.is()) + { + Reference<rendering::XPolyPolygon2D> 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<double>(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<rendering::XBitmap> 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<css::rendering::XBitmap> 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<XComponentContext>& rxComponentContext, + const Reference<awt::XWindow>& rxParentWindow, + const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, + const ::boost::function<void(double)>& 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::GetMajor (const double nX, const double nY) const +{ + (void)nX; + return nY; +} + + + + +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<rendering::XBitmap> 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<rendering::XBitmap> 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(A2S("Up")); + mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Down")); + mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerTop")); + mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerVertical")); + mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerBottom")); + mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbTop")); + mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbVertical")); + mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("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)); +} + + + + +//===== PresenterHorizontalScrollBar ============================================ + +PresenterHorizontalScrollBar::PresenterHorizontalScrollBar ( + const Reference<XComponentContext>& rxComponentContext, + const Reference<awt::XWindow>& rxParentWindow, + const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, + const ::boost::function<void(double)>& rThumbMotionListener) + : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener), + mnScrollBarHeight(0) +{ +} + + + + +PresenterHorizontalScrollBar::~PresenterHorizontalScrollBar (void) +{ +} + + + + +double PresenterHorizontalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const +{ + (void)nY; + const double nDistance (nX - maDragAnchor.X); + if (nDistance == 0) + return 0; + else + { + const awt::Rectangle aWindowBox (mxWindow->getPosSize()); + const double nBarHeight (aWindowBox.Height); + const double nPagerWidth (aWindowBox.Width - 2*nBarHeight); + const double nDragDistance (mnTotalSize / nPagerWidth * nDistance); + if (nDragDistance + mnThumbPosition < 0) + return -mnThumbPosition; + else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize) + return mnTotalSize-mnThumbSize-mnThumbPosition; + else + return nDragDistance; + } +} + + + + +void PresenterHorizontalScrollBar::UpdateDragAnchor (const double nDragDistance) +{ + const awt::Rectangle aWindowBox (mxWindow->getPosSize()); + const double nBarHeight (aWindowBox.Height); + const double nPagerWidth (aWindowBox.Width - 2*nBarHeight); + maDragAnchor.X += nDragDistance * nPagerWidth / mnTotalSize; +} + + + + +sal_Int32 PresenterHorizontalScrollBar::GetSize (void) const +{ + return mnScrollBarHeight; +} + + + + + +geometry::RealPoint2D PresenterHorizontalScrollBar::GetPoint ( + const double nMajor, const double nMinor) const +{ + return geometry::RealPoint2D(nMajor, nMinor); +} + + + + +double PresenterHorizontalScrollBar::GetMajor (const double nX, const double nY) const +{ + (void)nY; + return nX; +} + + + + +double PresenterHorizontalScrollBar::GetMinor (const double nX, const double nY) const +{ + (void)nX; + return nY; +} + + + + +void PresenterHorizontalScrollBar::UpdateBorders (void) +{ + const awt::Rectangle aWindowBox (mxWindow->getPosSize()); + double nRight = aWindowBox.Width; + const double nGap (2); + + if (mpNextButtonDescriptor.get() != NULL) + { + Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap()); + if (xBitmap.is()) + { + geometry::IntegerSize2D aSize (xBitmap->getSize()); + maBox[NextButton] = geometry::RealRectangle2D( + nRight - aSize.Width,0, nRight, aWindowBox.Height); + nRight -= aSize.Width + nGap; + } + } + if (mpPrevButtonDescriptor.get() != NULL) + { + Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap()); + if (xBitmap.is()) + { + geometry::IntegerSize2D aSize (xBitmap->getSize()); + maBox[PrevButton] = geometry::RealRectangle2D( + nRight - aSize.Width,0, nRight, aWindowBox.Height); + nRight -= aSize.Width + nGap; + } + } + + const double nPagerWidth (nRight); + maBox[Pager] = geometry::RealRectangle2D( + 0,0, nRight, aWindowBox.Height); + if (mnTotalSize == 0) + { + 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( + (nThumbPosition) / mnTotalSize * nPagerWidth, 0, + (nThumbPosition+nThumbSize) / mnTotalSize * nPagerWidth, aWindowBox.Height); + + // 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[Thumb].X1-1, maBox[Pager].Y2); + maBox[PagerDown] = geometry::RealRectangle2D( + maBox[Thumb].X2+1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Pager].Y2); + maBox[Total] = PresenterGeometryHelper::Union( + PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]), + maBox[Pager]); +} + + + + +void PresenterHorizontalScrollBar::UpdateBitmaps (void) +{ + if (mpBitmaps.get() != NULL) + { + mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Left")); + mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Right")); + mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerLeft")); + mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerHorizontal")); + mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerRight")); + mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbLeft")); + mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbHorizontal")); + mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbRight")); + + mnScrollBarHeight = 0; + UpdateWidthOrHeight(mnScrollBarHeight, mpPrevButtonDescriptor); + UpdateWidthOrHeight(mnScrollBarHeight, mpNextButtonDescriptor); + UpdateWidthOrHeight(mnScrollBarHeight, mpPagerStartDescriptor); + UpdateWidthOrHeight(mnScrollBarHeight, mpPagerCenterDescriptor); + UpdateWidthOrHeight(mnScrollBarHeight, mpPagerEndDescriptor); + UpdateWidthOrHeight(mnScrollBarHeight, mpThumbStartDescriptor); + UpdateWidthOrHeight(mnScrollBarHeight, mpThumbCenterDescriptor); + UpdateWidthOrHeight(mnScrollBarHeight, mpThumbEndDescriptor); + if (mnScrollBarHeight == 0) + mnScrollBarHeight = 20; + } +} + + + +void PresenterHorizontalScrollBar::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; + + PresenterUIPainter::PaintHorizontalBitmapComposite( + mxCanvas, + rUpdateBox, + PresenterGeometryHelper::ConvertRectangle(aBox), + GetBitmap(eArea, rpStartBitmaps), + GetBitmap(eArea, rpCenterBitmaps), + GetBitmap(eArea, rpEndBitmaps)); +} + + + + +//===== PresenterScrollBar::MousePressRepeater ================================ + +PresenterScrollBar::MousePressRepeater::MousePressRepeater ( + const ::rtl::Reference<PresenterScrollBar>& 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: */ |