/* -*- 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 <PresenterHelper.hxx>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/rendering/CompositeOperation.hpp>
#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
#include <algorithm>
#include <memory>
#include <utility>
#include <math.h>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
const double gnScrollBarGap (
10 );
namespace sdext::presenter {
//===== PresenterScrollBar::MousePressRepeater ================================
class PresenterScrollBar::MousePressRepeater
:
public std::enable_shared_from_this<MousePressRepeater>
{
public :
explicit MousePressRepeater (::rtl::Reference<PresenterScrollBar> xScrollBar);
void Dispose();
void Start (
const PresenterScrollBar::Area& reArea);
void Stop();
void SetMouseArea (
const PresenterScrollBar::Area& reArea);
private :
void Callback ();
void Execute();
sal_Int32 mnMousePressRepeaterTaskId;
::rtl::Reference<PresenterScrollBar> mpScrollBar;
PresenterScrollBar::Area meMouseArea;
};
//===== PresenterScrollBar ====================================================
std::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps;
PresenterScrollBar::PresenterScrollBar (
const Reference<XComponentContext>& rxComponentContext,
const Reference<awt::XWindow>& rxParentWindow,
std::shared_ptr<PresenterPaintManager> xPaintManager,
::std::function<
void (
double )> aThumbMotionListener)
: PresenterScrollBarInterfaceBase(m_aMutex),
mxComponentContext(rxComponentContext),
mpPaintManager(std::move(xPaintManager)),
mnThumbPosition(
0 ),
mnTotalSize(
0 ),
mnThumbSize(
0 ),
mnLineHeight(
10 ),
maDragAnchor(-
1 ,-
1 ),
maThumbMotionListener(std::move(aThumbMotionListener)),
meButtonDownArea(None),
meMouseMoveArea(None),
mbIsNotificationActive(
false ),
mpMousePressRepeater(std::make_shared<MousePressRepeater>(
this )),
mpCanvasHelper(
new PresenterCanvasHelper())
{
try
{
mxWindow = sd::presenter::PresenterHelper::createWindow(rxParentWindow,
false );
// Make the background transparent. The slide show paints its own background.
Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
xPeer->setBackground(
0 xff000000);
mxWindow->setVisible(
true );
mxWindow->addWindowListener(
this );
mxWindow->addPaintListener(
this );
mxWindow->addMouseListener(
this );
mxWindow->addMouseMotionListener(
this );
}
catch (RuntimeException&)
{
}
}
PresenterScrollBar::~PresenterScrollBar()
{
}
void SAL_CALL PresenterScrollBar::disposing()
{
mpMousePressRepeater->Dispose();
if (mxWindow.is())
{
mxWindow->removeWindowListener(
this );
mxWindow->removePaintListener(
this );
mxWindow->removeMouseListener(
this );
mxWindow->removeMouseMotionListener(
this );
Reference<lang::XComponent> xComponent = mxWindow;
mxWindow = nullptr;
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)
{
nPosition = ValidateThumbPosition(nPosition);
if (nPosition == mnThumbPosition || mbIsNotificationActive)
return ;
mnThumbPosition = nPosition;
UpdateBorders();
Repaint(GetRectangle(Total), bAsynchronousUpdate);
mbIsNotificationActive =
true ;
try
{
maThumbMotionListener(mnThumbPosition);
}
catch (Exception&)
{
}
mbIsNotificationActive =
false ;
}
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<css::rendering::XCanvas>& rxCa
nvas)
{
if (mxCanvas == rxCanvas)
return ;
mxCanvas = rxCanvas;
if (!mxCanvas.is())
return ;
if (mpBitmaps == nullptr)
{
mpBitmaps = mpSharedBitmaps.lock();
if (!mpBitmaps)
{
try
{
mpBitmaps = std::make_shared<PresenterBitmapContainer>(
"PresenterScreenSettings/ScrollBar/Bitmaps" ,
std::shared_ptr<PresenterBitmapContainer>(),
mxComponentContext,
mxCanvas);
mpSharedBitmaps = mpBitmaps;
}
catch (Exception&)
{
OSL_ASSERT(false );
}
}
UpdateBitmaps();
UpdateBorders();
}
Repaint(GetRectangle(Total), false );
}
void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap)
{
mpBackgroundBitmap = rpBackgroundBitmap;
}
void PresenterScrollBar::CheckValues()
{
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)
{
if ( ! mxCanvas.is() || ! mxWindow.is())
{
OSL_ASSERT(mxCanvas.is());
OSL_ASSERT(mxWindow.is());
return ;
}
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(false );
}
//----- XWindowListener -------------------------------------------------------
void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent&) {}
void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent&) {}
void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject&) {}
void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject&) {}
//----- XPaintListener --------------------------------------------------------
void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent)
{
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(false );
}
}
//----- XMouseListener --------------------------------------------------------
void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent)
{
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&)
{
mpMousePressRepeater->Stop();
sd::presenter::PresenterHelper::releaseMouse(mxWindow);
}
void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent&) {}
void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent&)
{
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)
{
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)
{
if (meButtonDownArea != Thumb)
return ;
mpMousePressRepeater->Stop();
sd::presenter::PresenterHelper::captureMouse(mxWindow);
const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y));
UpdateDragAnchor(nDragDistance);
if (nDragDistance != 0 )
{
SetThumbPosition(mnThumbPosition + nDragDistance, false );
}
}
//----- lang::XEventListener --------------------------------------------------
void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent)
{
if (rEvent.Source == mxWindow)
mxWindow = nullptr;
}
geometry::RealRectangle2D const & PresenterScrollBar::GetRectangle (const Area eArea) const
{
OSL_ASSERT(eArea>=0 && eArea<AreaCount);
return maBox[eArea];
}
void PresenterScrollBar::Repaint (
const geometry::RealRectangle2D& rBox,
const bool bAsynchronousUpdate)
{
if (mpPaintManager != nullptr)
mpPaintManager->Invalidate(
mxWindow,
PresenterGeometryHelper::ConvertRectangle(rBox),
bAsynchronousUpdate);
}
void PresenterScrollBar::PaintBackground(
const css::awt::Rectangle& rUpdateBox)
{
if (!mpBackgroundBitmap)
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())
return ;
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 ),
nullptr,
Sequence<double >(4 ),
rendering::CompositeOperation::SOURCE);
mxCanvas->drawBitmap(
xBitmap,
aViewState,
aRenderState);
}
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)
{
Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap());
if (xBitmap.is())
{
const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
const sal_Int32 nBitmapSize = static_cast <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)
return nullptr;
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 std::shared_ptr<PresenterPaintManager>& rpPaintManager,
const ::std::function<void (double )>& rThumbMotionListener)
: PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener),
mnScrollBarWidth(0 )
{
}
PresenterVerticalScrollBar::~PresenterVerticalScrollBar()
{
}
double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32, const sal_Int32 nY) const
{
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() const
{
return mnScrollBarWidth;
}
double PresenterVerticalScrollBar::GetMinor (const double nX, const double ) const
{
return nX;
}
void PresenterVerticalScrollBar::UpdateBorders()
{
const awt::Rectangle aWindowBox (mxWindow->getPosSize());
double nBottom = aWindowBox.Height;
if (mpNextButtonDescriptor)
{
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)
{
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::clamp(mnThumbPosition, 0 .0 , 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()
{
if (mpBitmaps == nullptr)
return ;
mpPrevButtonDescriptor = mpBitmaps->GetBitmap(u"Up" _ustr);
mpNextButtonDescriptor = mpBitmaps->GetBitmap(u"Down" _ustr);
mpPagerStartDescriptor = mpBitmaps->GetBitmap(u"PagerTop" _ustr);
mpPagerCenterDescriptor = mpBitmaps->GetBitmap(u"PagerVertical" _ustr);
mpPagerEndDescriptor = mpBitmaps->GetBitmap(u"PagerBottom" _ustr);
mpThumbStartDescriptor = mpBitmaps->GetBitmap(u"ThumbTop" _ustr);
mpThumbCenterDescriptor = mpBitmaps->GetBitmap(u"ThumbVertical" _ustr);
mpThumbEndDescriptor = mpBitmaps->GetBitmap(u"ThumbBottom" _ustr);
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 (
::rtl::Reference<PresenterScrollBar> xScrollBar)
: mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId),
mpScrollBar(std::move(xScrollBar)),
meMouseArea(PresenterScrollBar::None)
{
}
void PresenterScrollBar::MousePressRepeater::Dispose()
{
Stop();
mpScrollBar = nullptr;
}
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.
auto xSelf(shared_from_this());
mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask (
mpScrollBar->GetComponentContext(),
[xSelf=std::move(xSelf)] (TimeValue const &) { return xSelf->Callback(); },
500000000 ,
250000000 );
}
else
{
// There is already an active repeating task.
}
}
void PresenterScrollBar::MousePressRepeater::Stop()
{
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 ()
{
if (!mpScrollBar)
{
Stop();
return ;
}
Execute();
}
void PresenterScrollBar::MousePressRepeater::Execute()
{
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: */
Messung V0.5 in Prozent C=98 H=100 G=98
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet am 2026-06-04)
¤
*© Formatika GbR, Deutschland