vcl: allow for overriding the default PDF rendering resolution
[LibreOffice.git] / sdext / source / presenter / PresenterScrollBar.cxx
blobba171aa6152ce7a84b0a1904839b3e9e21489b8c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "PresenterScrollBar.hxx"
21 #include "PresenterBitmapContainer.hxx"
22 #include "PresenterCanvasHelper.hxx"
23 #include "PresenterGeometryHelper.hxx"
24 #include "PresenterPaintManager.hxx"
25 #include "PresenterTimer.hxx"
26 #include "PresenterUIPainter.hxx"
27 #include <com/sun/star/awt/PosSize.hpp>
28 #include <com/sun/star/awt/XWindowPeer.hpp>
29 #include <com/sun/star/rendering/CompositeOperation.hpp>
30 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
32 #include <algorithm>
33 #include <memory>
34 #include <math.h>
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::uno;
39 const static double gnScrollBarGap (10);
41 namespace sdext { namespace presenter {
43 //===== PresenterScrollBar::MousePressRepeater ================================
45 class PresenterScrollBar::MousePressRepeater
46 : public std::enable_shared_from_this<MousePressRepeater>
48 public:
49 explicit MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& rpScrollBar);
50 void Dispose();
51 void Start (const PresenterScrollBar::Area& reArea);
52 void Stop();
53 void SetMouseArea (const PresenterScrollBar::Area& reArea);
55 private:
56 void Callback ();
57 void Execute();
59 sal_Int32 mnMousePressRepeaterTaskId;
60 ::rtl::Reference<PresenterScrollBar> mpScrollBar;
61 PresenterScrollBar::Area meMouseArea;
64 //===== PresenterScrollBar ====================================================
66 std::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps;
68 PresenterScrollBar::PresenterScrollBar (
69 const Reference<XComponentContext>& rxComponentContext,
70 const Reference<awt::XWindow>& rxParentWindow,
71 const std::shared_ptr<PresenterPaintManager>& rpPaintManager,
72 const ::std::function<void (double)>& rThumbMotionListener)
73 : PresenterScrollBarInterfaceBase(m_aMutex),
74 mxComponentContext(rxComponentContext),
75 mxWindow(),
76 mxCanvas(),
77 mxPresenterHelper(),
78 mpPaintManager(rpPaintManager),
79 mnThumbPosition(0),
80 mnTotalSize(0),
81 mnThumbSize(0),
82 mnLineHeight(10),
83 maDragAnchor(-1,-1),
84 maThumbMotionListener(rThumbMotionListener),
85 meButtonDownArea(None),
86 meMouseMoveArea(None),
87 mbIsNotificationActive(false),
88 mpBitmaps(),
89 mpPrevButtonDescriptor(),
90 mpNextButtonDescriptor(),
91 mpPagerStartDescriptor(),
92 mpPagerCenterDescriptor(),
93 mpPagerEndDescriptor(),
94 mpThumbStartDescriptor(),
95 mpThumbCenterDescriptor(),
96 mpThumbEndDescriptor(),
97 mpMousePressRepeater(new MousePressRepeater(this)),
98 mpBackgroundBitmap(),
99 mpCanvasHelper(new PresenterCanvasHelper())
103 Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager());
104 if ( ! xFactory.is())
105 throw RuntimeException();
107 mxPresenterHelper.set(
108 xFactory->createInstanceWithContext(
109 "com.sun.star.comp.Draw.PresenterHelper",
110 rxComponentContext),
111 UNO_QUERY_THROW);
113 if (mxPresenterHelper.is())
114 mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
115 false,
116 false,
117 false,
118 false);
120 // Make the background transparent. The slide show paints its own background.
121 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
122 xPeer->setBackground(0xff000000);
124 mxWindow->setVisible(true);
125 mxWindow->addWindowListener(this);
126 mxWindow->addPaintListener(this);
127 mxWindow->addMouseListener(this);
128 mxWindow->addMouseMotionListener(this);
130 catch (RuntimeException&)
135 PresenterScrollBar::~PresenterScrollBar()
139 void SAL_CALL PresenterScrollBar::disposing()
141 mpMousePressRepeater->Dispose();
143 if (mxWindow.is())
145 mxWindow->removeWindowListener(this);
146 mxWindow->removePaintListener(this);
147 mxWindow->removeMouseListener(this);
148 mxWindow->removeMouseMotionListener(this);
150 Reference<lang::XComponent> xComponent = mxWindow;
151 mxWindow = nullptr;
152 if (xComponent.is())
153 xComponent->dispose();
156 mpBitmaps.reset();
159 void PresenterScrollBar::SetVisible (const bool bIsVisible)
161 if (mxWindow.is())
162 mxWindow->setVisible(bIsVisible);
165 void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox)
167 if (mxWindow.is())
169 mxWindow->setPosSize(
170 sal_Int32(floor(rBox.X1)),
171 sal_Int32(ceil(rBox.Y1)),
172 sal_Int32(ceil(rBox.X2-rBox.X1)),
173 sal_Int32(floor(rBox.Y2-rBox.Y1)),
174 awt::PosSize::POSSIZE);
175 UpdateBorders();
179 void PresenterScrollBar::SetThumbPosition (
180 double nPosition,
181 const bool bAsynchronousUpdate)
183 nPosition = ValidateThumbPosition(nPosition);
185 if (nPosition == mnThumbPosition || mbIsNotificationActive)
186 return;
188 mnThumbPosition = nPosition;
190 UpdateBorders();
191 Repaint(GetRectangle(Total), bAsynchronousUpdate);
193 mbIsNotificationActive = true;
196 maThumbMotionListener(mnThumbPosition);
198 catch (Exception&)
201 mbIsNotificationActive = false;
205 void PresenterScrollBar::SetTotalSize (const double nTotalSize)
207 if (mnTotalSize != nTotalSize)
209 mnTotalSize = nTotalSize + 1;
210 UpdateBorders();
211 Repaint(GetRectangle(Total), false);
215 void PresenterScrollBar::SetThumbSize (const double nThumbSize)
217 OSL_ASSERT(nThumbSize>=0);
218 if (mnThumbSize != nThumbSize)
220 mnThumbSize = nThumbSize;
221 UpdateBorders();
222 Repaint(GetRectangle(Total), false);
227 void PresenterScrollBar::SetLineHeight (const double nLineHeight)
229 mnLineHeight = nLineHeight;
233 void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas)
235 if (mxCanvas == rxCanvas)
236 return;
238 mxCanvas = rxCanvas;
239 if (!mxCanvas.is())
240 return;
242 if (mpBitmaps == nullptr)
244 if (mpSharedBitmaps.expired())
248 mpBitmaps.reset(new PresenterBitmapContainer(
249 "PresenterScreenSettings/ScrollBar/Bitmaps",
250 std::shared_ptr<PresenterBitmapContainer>(),
251 mxComponentContext,
252 mxCanvas));
253 mpSharedBitmaps = mpBitmaps;
255 catch(Exception&)
257 OSL_ASSERT(false);
260 else
261 mpBitmaps = std::shared_ptr<PresenterBitmapContainer>(mpSharedBitmaps);
262 UpdateBitmaps();
263 UpdateBorders();
266 Repaint(GetRectangle(Total), false);
269 void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap)
271 mpBackgroundBitmap = rpBackgroundBitmap;
274 void PresenterScrollBar::CheckValues()
276 mnThumbPosition = ValidateThumbPosition(mnThumbPosition);
279 double PresenterScrollBar::ValidateThumbPosition (double nPosition)
281 if (nPosition + mnThumbSize > mnTotalSize)
282 nPosition = mnTotalSize - mnThumbSize;
283 if (nPosition < 0)
284 nPosition = 0;
285 return nPosition;
288 void PresenterScrollBar::Paint (
289 const awt::Rectangle& rUpdateBox)
291 if ( ! mxCanvas.is() || ! mxWindow.is())
293 OSL_ASSERT(mxCanvas.is());
294 OSL_ASSERT(mxWindow.is());
295 return;
298 if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize()))
299 return;
301 PaintBackground(rUpdateBox);
302 PaintComposite(rUpdateBox, PagerUp,
303 mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor());
304 PaintComposite(rUpdateBox, PagerDown,
305 SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor);
306 PaintComposite(rUpdateBox, Thumb,
307 mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor);
308 PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor);
309 PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor);
311 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
312 if (xSpriteCanvas.is())
313 xSpriteCanvas->updateScreen(false);
316 //----- XWindowListener -------------------------------------------------------
318 void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent&) {}
320 void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent&) {}
322 void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject&) {}
324 void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject&) {}
326 //----- XPaintListener --------------------------------------------------------
328 void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent)
330 if (mxWindow.is())
332 awt::Rectangle aRepaintBox (rEvent.UpdateRect);
333 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
334 aRepaintBox.X += aWindowBox.X;
335 aRepaintBox.Y += aWindowBox.Y;
336 Paint(aRepaintBox);
338 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
339 if (xSpriteCanvas.is())
340 xSpriteCanvas->updateScreen(false);
344 //----- XMouseListener --------------------------------------------------------
346 void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent)
348 maDragAnchor.X = rEvent.X;
349 maDragAnchor.Y = rEvent.Y;
350 meButtonDownArea = GetArea(rEvent.X, rEvent.Y);
352 mpMousePressRepeater->Start(meButtonDownArea);
355 void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent&)
357 mpMousePressRepeater->Stop();
359 if (mxPresenterHelper.is())
360 mxPresenterHelper->releaseMouse(mxWindow);
363 void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent&) {}
365 void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent&)
367 if (meMouseMoveArea != None)
369 const Area eOldMouseMoveArea (meMouseMoveArea);
370 meMouseMoveArea = None;
371 Repaint(GetRectangle(eOldMouseMoveArea), true);
373 meButtonDownArea = None;
374 meMouseMoveArea = None;
376 mpMousePressRepeater->Stop();
379 //----- XMouseMotionListener --------------------------------------------------
381 void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent)
383 const Area eArea (GetArea(rEvent.X, rEvent.Y));
384 if (eArea != meMouseMoveArea)
386 const Area eOldMouseMoveArea (meMouseMoveArea);
387 meMouseMoveArea = eArea;
388 if (eOldMouseMoveArea != None)
389 Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None);
390 if (meMouseMoveArea != None)
391 Repaint(GetRectangle(meMouseMoveArea), true);
393 mpMousePressRepeater->SetMouseArea(eArea);
396 void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent)
398 if (meButtonDownArea != Thumb)
399 return;
401 mpMousePressRepeater->Stop();
403 if (mxPresenterHelper.is())
404 mxPresenterHelper->captureMouse(mxWindow);
406 const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y));
407 UpdateDragAnchor(nDragDistance);
408 if (nDragDistance != 0)
410 SetThumbPosition(mnThumbPosition + nDragDistance, false);
414 //----- lang::XEventListener --------------------------------------------------
416 void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent)
418 if (rEvent.Source == mxWindow)
419 mxWindow = nullptr;
423 geometry::RealRectangle2D const & PresenterScrollBar::GetRectangle (const Area eArea) const
425 OSL_ASSERT(eArea>=0 && eArea<AreaCount);
427 return maBox[eArea];
430 void PresenterScrollBar::Repaint (
431 const geometry::RealRectangle2D& rBox,
432 const bool bAsynchronousUpdate)
434 if (mpPaintManager != nullptr)
435 mpPaintManager->Invalidate(
436 mxWindow,
437 PresenterGeometryHelper::ConvertRectangle(rBox),
438 bAsynchronousUpdate);
441 void PresenterScrollBar::PaintBackground(
442 const css::awt::Rectangle& rUpdateBox)
444 if (mpBackgroundBitmap.get() == nullptr)
445 return;
447 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
448 mpCanvasHelper->Paint(
449 mpBackgroundBitmap,
450 mxCanvas,
451 rUpdateBox,
452 aWindowBox,
453 awt::Rectangle());
456 void PresenterScrollBar::PaintBitmap(
457 const css::awt::Rectangle& rUpdateBox,
458 const Area eArea,
459 const SharedBitmapDescriptor& rpBitmaps)
461 const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea));
462 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
463 geometry::RealRectangle2D aBox (aLocalBox);
464 aBox.X1 += aWindowBox.X;
465 aBox.Y1 += aWindowBox.Y;
466 aBox.X2 += aWindowBox.X;
467 aBox.Y2 += aWindowBox.Y;
469 Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps));
471 if (!xBitmap.is())
472 return;
474 Reference<rendering::XPolyPolygon2D> xClipPolygon (
475 PresenterGeometryHelper::CreatePolygon(
476 PresenterGeometryHelper::Intersection(rUpdateBox,
477 PresenterGeometryHelper::ConvertRectangle(aBox)),
478 mxCanvas->getDevice()));
480 const rendering::ViewState aViewState (
481 geometry::AffineMatrix2D(1,0,0, 0,1,0),
482 xClipPolygon);
484 const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
485 rendering::RenderState aRenderState (
486 geometry::AffineMatrix2D(
487 1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2,
488 0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2),
489 nullptr,
490 Sequence<double>(4),
491 rendering::CompositeOperation::SOURCE);
493 mxCanvas->drawBitmap(
494 xBitmap,
495 aViewState,
496 aRenderState);
499 PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const
501 const geometry::RealPoint2D aPoint(nX, nY);
503 if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint))
505 if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint))
506 return Thumb;
507 else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint))
508 return PagerUp;
509 else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint))
510 return PagerDown;
512 else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint))
513 return PrevButton;
514 else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint))
515 return NextButton;
517 return None;
520 void PresenterScrollBar::UpdateWidthOrHeight (
521 sal_Int32& rSize,
522 const SharedBitmapDescriptor& rpDescriptor)
524 if (rpDescriptor.get() != nullptr)
526 Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap());
527 if (xBitmap.is())
529 const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
530 const sal_Int32 nBitmapSize = static_cast<sal_Int32>(GetMinor(aBitmapSize.Width, aBitmapSize.Height));
531 if (nBitmapSize > rSize)
532 rSize = nBitmapSize;
537 css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap (
538 const Area eArea,
539 const SharedBitmapDescriptor& rpBitmaps) const
541 if (rpBitmaps.get() == nullptr)
542 return nullptr;
543 else
544 return rpBitmaps->GetBitmap(GetBitmapMode(eArea));
547 PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode (
548 const Area eArea) const
550 if (IsDisabled(eArea))
551 return PresenterBitmapContainer::BitmapDescriptor::Disabled;
552 else if (eArea == meMouseMoveArea)
553 return PresenterBitmapContainer::BitmapDescriptor::MouseOver;
554 else
555 return PresenterBitmapContainer::BitmapDescriptor::Normal;
558 bool PresenterScrollBar::IsDisabled (const Area eArea) const
560 OSL_ASSERT(eArea>=0 && eArea<AreaCount);
562 return ! maEnabledState[eArea];
565 //===== PresenterVerticalScrollBar ============================================
567 PresenterVerticalScrollBar::PresenterVerticalScrollBar (
568 const Reference<XComponentContext>& rxComponentContext,
569 const Reference<awt::XWindow>& rxParentWindow,
570 const std::shared_ptr<PresenterPaintManager>& rpPaintManager,
571 const ::std::function<void (double)>& rThumbMotionListener)
572 : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener),
573 mnScrollBarWidth(0)
577 PresenterVerticalScrollBar::~PresenterVerticalScrollBar()
581 double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32, const sal_Int32 nY) const
583 const double nDistance (nY - maDragAnchor.Y);
584 if (nDistance == 0)
585 return 0;
586 else
588 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
589 const double nBarWidth (aWindowBox.Width);
590 const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
591 const double nDragDistance (mnTotalSize / nPagerHeight * nDistance);
592 if (nDragDistance + mnThumbPosition < 0)
593 return -mnThumbPosition;
594 else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize)
595 return mnTotalSize-mnThumbSize-mnThumbPosition;
596 else
597 return nDragDistance;
601 void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance)
603 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
604 const double nBarWidth (aWindowBox.Width);
605 const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
606 maDragAnchor.Y += nDragDistance * nPagerHeight / mnTotalSize;
609 sal_Int32 PresenterVerticalScrollBar::GetSize() const
611 return mnScrollBarWidth;
614 double PresenterVerticalScrollBar::GetMinor (const double nX, const double) const
616 return nX;
619 void PresenterVerticalScrollBar::UpdateBorders()
621 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
622 double nBottom = aWindowBox.Height;
624 if (mpNextButtonDescriptor.get() != nullptr)
626 Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap());
627 if (xBitmap.is())
629 geometry::IntegerSize2D aSize (xBitmap->getSize());
630 maBox[NextButton] = geometry::RealRectangle2D(
631 0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
632 nBottom -= aSize.Height + gnScrollBarGap;
635 if (mpPrevButtonDescriptor.get() != nullptr)
637 Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap());
638 if (xBitmap.is())
640 geometry::IntegerSize2D aSize (xBitmap->getSize());
641 maBox[PrevButton] = geometry::RealRectangle2D(
642 0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
643 nBottom -= aSize.Height + gnScrollBarGap;
646 const double nPagerHeight (nBottom);
647 maBox[Pager] = geometry::RealRectangle2D(
648 0,0, aWindowBox.Width, nBottom);
649 if (mnTotalSize < 1)
651 maBox[Thumb] = maBox[Pager];
653 // Set up the enabled/disabled states.
654 maEnabledState[PrevButton] = false;
655 maEnabledState[PagerUp] = false;
656 maEnabledState[NextButton] = false;
657 maEnabledState[PagerDown] = false;
658 maEnabledState[Thumb] = false;
660 else
662 const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize);
663 const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize);
664 maBox[Thumb] = geometry::RealRectangle2D(
665 0, nThumbPosition / mnTotalSize * nPagerHeight,
666 aWindowBox.Width,
667 (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight);
669 // Set up the enabled/disabled states.
670 maEnabledState[PrevButton] = nThumbPosition>0;
671 maEnabledState[PagerUp] = nThumbPosition>0;
672 maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize;
673 maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize;
674 maEnabledState[Thumb] = nThumbSize < mnTotalSize;
676 maBox[PagerUp] = geometry::RealRectangle2D(
677 maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1);
678 maBox[PagerDown] = geometry::RealRectangle2D(
679 maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2);
680 maBox[Total] = PresenterGeometryHelper::Union(
681 PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]),
682 maBox[Pager]);
685 void PresenterVerticalScrollBar::UpdateBitmaps()
687 if (mpBitmaps == nullptr)
688 return;
690 mpPrevButtonDescriptor = mpBitmaps->GetBitmap("Up");
691 mpNextButtonDescriptor = mpBitmaps->GetBitmap("Down");
692 mpPagerStartDescriptor = mpBitmaps->GetBitmap("PagerTop");
693 mpPagerCenterDescriptor = mpBitmaps->GetBitmap("PagerVertical");
694 mpPagerEndDescriptor = mpBitmaps->GetBitmap("PagerBottom");
695 mpThumbStartDescriptor = mpBitmaps->GetBitmap("ThumbTop");
696 mpThumbCenterDescriptor = mpBitmaps->GetBitmap("ThumbVertical");
697 mpThumbEndDescriptor = mpBitmaps->GetBitmap("ThumbBottom");
699 mnScrollBarWidth = 0;
700 UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor);
701 UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor);
702 UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor);
703 UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor);
704 UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor);
705 UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor);
706 UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor);
707 UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor);
708 if (mnScrollBarWidth == 0)
709 mnScrollBarWidth = 20;
712 void PresenterVerticalScrollBar::PaintComposite(
713 const css::awt::Rectangle& rUpdateBox,
714 const Area eArea,
715 const SharedBitmapDescriptor& rpStartBitmaps,
716 const SharedBitmapDescriptor& rpCenterBitmaps,
717 const SharedBitmapDescriptor& rpEndBitmaps)
719 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
720 geometry::RealRectangle2D aBox (GetRectangle(eArea));
721 aBox.X1 += aWindowBox.X;
722 aBox.Y1 += aWindowBox.Y;
723 aBox.X2 += aWindowBox.X;
724 aBox.Y2 += aWindowBox.Y;
726 // Get bitmaps and sizes.
728 PresenterUIPainter::PaintVerticalBitmapComposite(
729 mxCanvas,
730 rUpdateBox,
731 (eArea == Thumb
732 ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox)
733 : PresenterGeometryHelper::ConvertRectangle(aBox)),
734 GetBitmap(eArea, rpStartBitmaps),
735 GetBitmap(eArea, rpCenterBitmaps),
736 GetBitmap(eArea, rpEndBitmaps));
739 //===== PresenterScrollBar::MousePressRepeater ================================
741 PresenterScrollBar::MousePressRepeater::MousePressRepeater (
742 const ::rtl::Reference<PresenterScrollBar>& rpScrollBar)
743 : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId),
744 mpScrollBar(rpScrollBar),
745 meMouseArea(PresenterScrollBar::None)
749 void PresenterScrollBar::MousePressRepeater::Dispose()
751 Stop();
752 mpScrollBar = nullptr;
755 void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea)
757 meMouseArea = reArea;
759 if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId)
761 // Execute key press operation at least this one time.
762 Execute();
764 // Schedule repeated executions.
765 auto pThis(shared_from_this());
766 mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask (
767 mpScrollBar->GetComponentContext(),
768 [pThis] (TimeValue const&) { return pThis->Callback(); },
769 500000000,
770 250000000);
772 else
774 // There is already an active repeating task.
778 void PresenterScrollBar::MousePressRepeater::Stop()
780 if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
782 const sal_Int32 nTaskId (mnMousePressRepeaterTaskId);
783 mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId;
784 PresenterTimer::CancelTask(nTaskId);
788 void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea)
790 if (meMouseArea != reArea)
792 if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
794 Stop();
799 void PresenterScrollBar::MousePressRepeater::Callback ()
801 if (mpScrollBar.get() == nullptr)
803 Stop();
804 return;
807 Execute();
810 void PresenterScrollBar::MousePressRepeater::Execute()
812 const double nThumbPosition (mpScrollBar->GetThumbPosition());
813 switch (meMouseArea)
815 case PrevButton:
816 mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true);
817 break;
819 case NextButton:
820 mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true);
821 break;
823 case PagerUp:
824 mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true);
825 break;
827 case PagerDown:
828 mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true);
829 break;
831 default:
832 break;
836 } } // end of namespace ::sdext::presenter
838 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */