blob: c7a35904dc6f57939a5f73d343474895b854da81 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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 "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::createFromAscii("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::createFromAscii("PresenterScreenSettings/ScrollBar/Bitmaps"),
::boost::shared_ptr<PresenterBitmapContainer>(),
mxComponentContext,
mxCanvas));
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