LibreOffice Module sdext (master)  1
PresenterScrollBar.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "PresenterScrollBar.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>
31 
32 #include <algorithm>
33 #include <memory>
34 #include <math.h>
35 
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::uno;
38 
39 const static double gnScrollBarGap (10);
40 
41 namespace sdext::presenter {
42 
43 //===== PresenterScrollBar::MousePressRepeater ================================
44 
46  : public std::enable_shared_from_this<MousePressRepeater>
47 {
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);
54 
55 private:
56  void Callback ();
57  void Execute();
58 
62 };
63 
64 //===== PresenterScrollBar ====================================================
65 
66 std::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps;
67 
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)
74  mxComponentContext(rxComponentContext),
75  mxWindow(),
76  mxCanvas(),
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(std::make_shared<MousePressRepeater>(this)),
98  mpBackgroundBitmap(),
99  mpCanvasHelper(new PresenterCanvasHelper())
100 {
101  try
102  {
103  Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager());
104  if ( ! xFactory.is())
105  throw RuntimeException();
106 
107  mxPresenterHelper.set(
108  xFactory->createInstanceWithContext(
109  "com.sun.star.comp.Draw.PresenterHelper",
110  rxComponentContext),
111  UNO_QUERY_THROW);
112 
113  if (mxPresenterHelper.is())
114  mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
115  false,
116  false,
117  false,
118  false);
119 
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);
123 
124  mxWindow->setVisible(true);
125  mxWindow->addWindowListener(this);
126  mxWindow->addPaintListener(this);
127  mxWindow->addMouseListener(this);
128  mxWindow->addMouseMotionListener(this);
129  }
130  catch (RuntimeException&)
131  {
132  }
133 }
134 
136 {
137 }
138 
140 {
141  mpMousePressRepeater->Dispose();
142 
143  if (mxWindow.is())
144  {
145  mxWindow->removeWindowListener(this);
146  mxWindow->removePaintListener(this);
147  mxWindow->removeMouseListener(this);
148  mxWindow->removeMouseMotionListener(this);
149 
151  mxWindow = nullptr;
152  if (xComponent.is())
153  xComponent->dispose();
154  }
155 
156  mpBitmaps.reset();
157 }
158 
159 void PresenterScrollBar::SetVisible (const bool bIsVisible)
160 {
161  if (mxWindow.is())
162  mxWindow->setVisible(bIsVisible);
163 }
164 
165 void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox)
166 {
167  if (mxWindow.is())
168  {
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();
176  }
177 }
178 
180  double nPosition,
181  const bool bAsynchronousUpdate)
182 {
183  nPosition = ValidateThumbPosition(nPosition);
184 
185  if (nPosition == mnThumbPosition || mbIsNotificationActive)
186  return;
187 
188  mnThumbPosition = nPosition;
189 
190  UpdateBorders();
191  Repaint(GetRectangle(Total), bAsynchronousUpdate);
192 
193  mbIsNotificationActive = true;
194  try
195  {
197  }
198  catch (Exception&)
199  {
200  }
201  mbIsNotificationActive = false;
202 }
203 
204 
205 void PresenterScrollBar::SetTotalSize (const double nTotalSize)
206 {
207  if (mnTotalSize != nTotalSize)
208  {
209  mnTotalSize = nTotalSize + 1;
210  UpdateBorders();
211  Repaint(GetRectangle(Total), false);
212  }
213 }
214 
215 void PresenterScrollBar::SetThumbSize (const double nThumbSize)
216 {
217  OSL_ASSERT(nThumbSize>=0);
218  if (mnThumbSize != nThumbSize)
219  {
220  mnThumbSize = nThumbSize;
221  UpdateBorders();
222  Repaint(GetRectangle(Total), false);
223  }
224 }
225 
226 
227 void PresenterScrollBar::SetLineHeight (const double nLineHeight)
228 {
229  mnLineHeight = nLineHeight;
230 }
231 
232 
233 void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas)
234 {
235  if (mxCanvas == rxCanvas)
236  return;
237 
238  mxCanvas = rxCanvas;
239  if (!mxCanvas.is())
240  return;
241 
242  if (mpBitmaps == nullptr)
243  {
244  if (mpSharedBitmaps.expired())
245  {
246  try
247  {
248  mpBitmaps = std::make_shared<PresenterBitmapContainer>(
249  "PresenterScreenSettings/ScrollBar/Bitmaps",
250  std::shared_ptr<PresenterBitmapContainer>(),
252  mxCanvas);
254  }
255  catch(Exception&)
256  {
257  OSL_ASSERT(false);
258  }
259  }
260  else
261  mpBitmaps = std::shared_ptr<PresenterBitmapContainer>(mpSharedBitmaps);
262  UpdateBitmaps();
263  UpdateBorders();
264  }
265 
266  Repaint(GetRectangle(Total), false);
267 }
268 
270 {
271  mpBackgroundBitmap = rpBackgroundBitmap;
272 }
273 
275 {
277 }
278 
280 {
281  if (nPosition + mnThumbSize > mnTotalSize)
282  nPosition = mnTotalSize - mnThumbSize;
283  if (nPosition < 0)
284  nPosition = 0;
285  return nPosition;
286 }
287 
289  const awt::Rectangle& rUpdateBox)
290 {
291  if ( ! mxCanvas.is() || ! mxWindow.is())
292  {
293  OSL_ASSERT(mxCanvas.is());
294  OSL_ASSERT(mxWindow.is());
295  return;
296  }
297 
298  if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize()))
299  return;
300 
301  PaintBackground(rUpdateBox);
302  PaintComposite(rUpdateBox, PagerUp,
304  PaintComposite(rUpdateBox, PagerDown,
306  PaintComposite(rUpdateBox, Thumb,
310 
311  Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
312  if (xSpriteCanvas.is())
313  xSpriteCanvas->updateScreen(false);
314 }
315 
316 //----- XWindowListener -------------------------------------------------------
317 
318 void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent&) {}
319 
320 void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent&) {}
321 
322 void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject&) {}
323 
324 void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject&) {}
325 
326 //----- XPaintListener --------------------------------------------------------
327 
328 void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent)
329 {
330  if (mxWindow.is())
331  {
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);
337 
338  Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
339  if (xSpriteCanvas.is())
340  xSpriteCanvas->updateScreen(false);
341  }
342 }
343 
344 //----- XMouseListener --------------------------------------------------------
345 
346 void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent)
347 {
348  maDragAnchor.X = rEvent.X;
349  maDragAnchor.Y = rEvent.Y;
350  meButtonDownArea = GetArea(rEvent.X, rEvent.Y);
351 
353 }
354 
355 void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent&)
356 {
357  mpMousePressRepeater->Stop();
358 
359  if (mxPresenterHelper.is())
360  mxPresenterHelper->releaseMouse(mxWindow);
361 }
362 
363 void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent&) {}
364 
365 void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent&)
366 {
367  if (meMouseMoveArea != None)
368  {
369  const Area eOldMouseMoveArea (meMouseMoveArea);
371  Repaint(GetRectangle(eOldMouseMoveArea), true);
372  }
375 
376  mpMousePressRepeater->Stop();
377 }
378 
379 //----- XMouseMotionListener --------------------------------------------------
380 
381 void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent)
382 {
383  const Area eArea (GetArea(rEvent.X, rEvent.Y));
384  if (eArea != meMouseMoveArea)
385  {
386  const Area eOldMouseMoveArea (meMouseMoveArea);
387  meMouseMoveArea = eArea;
388  if (eOldMouseMoveArea != None)
389  Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None);
390  if (meMouseMoveArea != None)
392  }
393  mpMousePressRepeater->SetMouseArea(eArea);
394 }
395 
396 void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent)
397 {
398  if (meButtonDownArea != Thumb)
399  return;
400 
401  mpMousePressRepeater->Stop();
402 
403  if (mxPresenterHelper.is())
404  mxPresenterHelper->captureMouse(mxWindow);
405 
406  const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y));
407  UpdateDragAnchor(nDragDistance);
408  if (nDragDistance != 0)
409  {
410  SetThumbPosition(mnThumbPosition + nDragDistance, false);
411  }
412 }
413 
414 //----- lang::XEventListener --------------------------------------------------
415 
416 void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent)
417 {
418  if (rEvent.Source == mxWindow)
419  mxWindow = nullptr;
420 }
421 
422 
423 geometry::RealRectangle2D const & PresenterScrollBar::GetRectangle (const Area eArea) const
424 {
425  OSL_ASSERT(eArea>=0 && eArea<AreaCount);
426 
427  return maBox[eArea];
428 }
429 
431  const geometry::RealRectangle2D& rBox,
432  const bool bAsynchronousUpdate)
433 {
434  if (mpPaintManager != nullptr)
435  mpPaintManager->Invalidate(
436  mxWindow,
438  bAsynchronousUpdate);
439 }
440 
442  const css::awt::Rectangle& rUpdateBox)
443 {
444  if (mpBackgroundBitmap.get() == nullptr)
445  return;
446 
447  const awt::Rectangle aWindowBox (mxWindow->getPosSize());
448  mpCanvasHelper->Paint(
450  mxCanvas,
451  rUpdateBox,
452  aWindowBox,
453  awt::Rectangle());
454 }
455 
457  const css::awt::Rectangle& rUpdateBox,
458  const Area eArea,
459  const SharedBitmapDescriptor& rpBitmaps)
460 {
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;
468 
469  Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps));
470 
471  if (!xBitmap.is())
472  return;
473 
474  Reference<rendering::XPolyPolygon2D> xClipPolygon (
478  mxCanvas->getDevice()));
479 
480  const rendering::ViewState aViewState (
481  geometry::AffineMatrix2D(1,0,0, 0,1,0),
482  xClipPolygon);
483 
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);
492 
493  mxCanvas->drawBitmap(
494  xBitmap,
495  aViewState,
496  aRenderState);
497 }
498 
499 PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const
500 {
501  const geometry::RealPoint2D aPoint(nX, nY);
502 
504  {
506  return Thumb;
508  return PagerUp;
510  return PagerDown;
511  }
513  return PrevButton;
515  return NextButton;
516 
517  return None;
518 }
519 
521  sal_Int32& rSize,
522  const SharedBitmapDescriptor& rpDescriptor)
523 {
524  if (rpDescriptor.get() != nullptr)
525  {
526  Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap());
527  if (xBitmap.is())
528  {
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;
533  }
534  }
535 }
536 
537 css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap (
538  const Area eArea,
539  const SharedBitmapDescriptor& rpBitmaps) const
540 {
541  if (rpBitmaps.get() == nullptr)
542  return nullptr;
543  else
544  return rpBitmaps->GetBitmap(GetBitmapMode(eArea));
545 }
546 
548  const Area eArea) const
549 {
550  if (IsDisabled(eArea))
552  else if (eArea == meMouseMoveArea)
554  else
556 }
557 
558 bool PresenterScrollBar::IsDisabled (const Area eArea) const
559 {
560  OSL_ASSERT(eArea>=0 && eArea<AreaCount);
561 
562  return ! maEnabledState[eArea];
563 }
564 
565 //===== PresenterVerticalScrollBar ============================================
566 
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)
574 {
575 }
576 
578 {
579 }
580 
581 double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32, const sal_Int32 nY) const
582 {
583  const double nDistance (nY - maDragAnchor.Y);
584  if (nDistance == 0)
585  return 0;
586  else
587  {
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)
596  else
597  return nDragDistance;
598  }
599 }
600 
601 void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance)
602 {
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;
607 }
608 
610 {
611  return mnScrollBarWidth;
612 }
613 
614 double PresenterVerticalScrollBar::GetMinor (const double nX, const double) const
615 {
616  return nX;
617 }
618 
620 {
621  const awt::Rectangle aWindowBox (mxWindow->getPosSize());
622  double nBottom = aWindowBox.Height;
623 
624  if (mpNextButtonDescriptor.get() != nullptr)
625  {
626  Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap());
627  if (xBitmap.is())
628  {
629  geometry::IntegerSize2D aSize (xBitmap->getSize());
630  maBox[NextButton] = geometry::RealRectangle2D(
631  0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
632  nBottom -= aSize.Height + gnScrollBarGap;
633  }
634  }
635  if (mpPrevButtonDescriptor.get() != nullptr)
636  {
637  Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap());
638  if (xBitmap.is())
639  {
640  geometry::IntegerSize2D aSize (xBitmap->getSize());
641  maBox[PrevButton] = geometry::RealRectangle2D(
642  0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
643  nBottom -= aSize.Height + gnScrollBarGap;
644  }
645  }
646  const double nPagerHeight (nBottom);
647  maBox[Pager] = geometry::RealRectangle2D(
648  0,0, aWindowBox.Width, nBottom);
649  if (mnTotalSize < 1)
650  {
651  maBox[Thumb] = maBox[Pager];
652 
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;
659  }
660  else
661  {
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);
668 
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;
675  }
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);
682  maBox[Pager]);
683 }
684 
686 {
687  if (mpBitmaps == nullptr)
688  return;
689 
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");
698 
699  mnScrollBarWidth = 0;
708  if (mnScrollBarWidth == 0)
709  mnScrollBarWidth = 20;
710 }
711 
713  const css::awt::Rectangle& rUpdateBox,
714  const Area eArea,
715  const SharedBitmapDescriptor& rpStartBitmaps,
716  const SharedBitmapDescriptor& rpCenterBitmaps,
717  const SharedBitmapDescriptor& rpEndBitmaps)
718 {
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;
725 
726  // Get bitmaps and sizes.
727 
729  mxCanvas,
730  rUpdateBox,
731  (eArea == Thumb
734  GetBitmap(eArea, rpStartBitmaps),
735  GetBitmap(eArea, rpCenterBitmaps),
736  GetBitmap(eArea, rpEndBitmaps));
737 }
738 
739 //===== PresenterScrollBar::MousePressRepeater ================================
740 
742  const ::rtl::Reference<PresenterScrollBar>& rpScrollBar)
743  : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId),
744  mpScrollBar(rpScrollBar),
745  meMouseArea(PresenterScrollBar::None)
746 {
747 }
748 
750 {
751  Stop();
752  mpScrollBar = nullptr;
753 }
754 
756 {
757  meMouseArea = reArea;
758 
759  if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId)
760  {
761  // Execute key press operation at least this one time.
762  Execute();
763 
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);
771  }
772  else
773  {
774  // There is already an active repeating task.
775  }
776 }
777 
779 {
780  if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
781  {
782  const sal_Int32 nTaskId (mnMousePressRepeaterTaskId);
783  mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId;
785  }
786 }
787 
789 {
790  if (meMouseArea != reArea)
791  {
792  if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
793  {
794  Stop();
795  }
796  }
797 }
798 
800 {
801  if (mpScrollBar.get() == nullptr)
802  {
803  Stop();
804  return;
805  }
806 
807  Execute();
808 }
809 
811 {
812  const double nThumbPosition (mpScrollBar->GetThumbPosition());
813  switch (meMouseArea)
814  {
815  case PrevButton:
816  mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true);
817  break;
818 
819  case NextButton:
820  mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true);
821  break;
822 
823  case PagerUp:
824  mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true);
825  break;
826 
827  case PagerDown:
828  mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true);
829  break;
830 
831  default:
832  break;
833  }
834 }
835 
836 } // end of namespace ::sdext::presenter
837 
838 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< PresenterBitmapContainer > mpBitmaps
Reference< rendering::XCanvas > mxCanvas
virtual void UpdateDragAnchor(const double nDragDistance) override
static sal_Int32 ScheduleRepeatedTask(const css::uno::Reference< css::uno::XComponentContext > &xContext, const Task &rTask, const sal_Int64 nFirst, const sal_Int64 nInterval)
Schedule a task to be executed repeatedly.
virtual void SAL_CALL mouseMoved(const css::awt::MouseEvent &rEvent) override
void PaintBackground(const css::awt::Rectangle &rRepaintBox)
std::unique_ptr< PresenterCanvasHelper > mpCanvasHelper
void CheckValues()
Call this after changing total size or thumb position or size to move the thumb to a valid position...
osl::Mutex m_aMutex
virtual void SAL_CALL windowHidden(const css::lang::EventObject &rEvent) override
css::uno::Reference< css::rendering::XCanvas > mxCanvas
static bool AreRectanglesDisjoint(const css::awt::Rectangle &rBox1, const css::awt::Rectangle &rBox2)
::std::function< void(double)> maThumbMotionListener
virtual void SAL_CALL mouseDragged(const css::awt::MouseEvent &rEvent) override
virtual double GetDragDistance(const sal_Int32 nX, const sal_Int32 nY) const =0
Area GetArea(const double nX, const double nY) const
Base class of horizontal and vertical scroll bars.
static std::weak_ptr< PresenterBitmapContainer > mpSharedBitmaps
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
void PaintBitmap(const css::awt::Rectangle &rRepaintBox, const Area eArea, const SharedBitmapDescriptor &rpBitmaps)
None
void SetLineHeight(const double nLineHeight)
static css::geometry::RealRectangle2D Union(const css::geometry::RealRectangle2D &rBox1, const css::geometry::RealRectangle2D &rBox2)
PresenterBitmapContainer::BitmapDescriptor::Mode GetBitmapMode(const Area eArea) const
PresenterScrollBar(const PresenterScrollBar &)=delete
std::shared_ptr< PresenterBitmapContainer::BitmapDescriptor > SharedBitmapDescriptor
Reference< drawing::XPresenterHelper > mxPresenterHelper
static const double gnScrollBarGap(10)
std::shared_ptr< PresenterBitmapContainer > mpBitmaps
Collection of functions to ease the life of a canvas user.
void SetPosSize(const css::geometry::RealRectangle2D &rBox)
Set the bounding box of the scroll bar.
css::uno::Reference< css::rendering::XBitmap > GetBitmap(const Area eArea, const SharedBitmapDescriptor &rpBitmaps) const
css::geometry::RealRectangle2D const & GetRectangle(const Area eArea) const
css::uno::Reference< css::lang::XComponent > xComponent
void Start(const PresenterScrollBar::Area &reArea)
static void CancelTask(const sal_Int32 nTaskId)
void Paint(const css::awt::Rectangle &rUpdateBox)
On some occasions it is necessary to trigger the painting of a scrollbar from the outside...
MousePressRepeater(const ::rtl::Reference< PresenterScrollBar > &rpScrollBar)
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
void SetBackground(const SharedBitmapDescriptor &rpBackgroundBitmap)
void SetCanvas(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas)
Set the canvas that is used for painting the scroll bar.
css::geometry::RealRectangle2D maBox[AreaCount]
static void PaintVerticalBitmapComposite(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const css::awt::Rectangle &rRepaintBox, const css::awt::Rectangle &rBoundingBox, const css::uno::Reference< css::rendering::XBitmap > &rxTopBitmap, const css::uno::Reference< css::rendering::XBitmap > &rxRepeatableCenterBitmap, const css::uno::Reference< css::rendering::XBitmap > &rxBottomBitmap)
SharedBitmapDescriptor mpThumbCenterDescriptor
std::shared_ptr< PresenterPaintManager > mpPaintManager
virtual void PaintComposite(const css::awt::Rectangle &rRepaintBox, const Area eArea, const SharedBitmapDescriptor &rpStartBitmaps, const SharedBitmapDescriptor &rpCenterBitmaps, const SharedBitmapDescriptor &rpEndBitmaps)=0
void UpdateWidthOrHeight(sal_Int32 &rSize, const SharedBitmapDescriptor &rpDescriptor)
void SetTotalSize(const double nTotalSize)
Set the upper border of the slider range.
static css::awt::Rectangle ConvertRectangleWithConstantSize(const css::geometry::RealRectangle2D &rBox)
Convert the given rectangle to integer coordinates so that width and height remain constant when only...
css::geometry::RealPoint2D maDragAnchor
virtual void SAL_CALL windowResized(const css::awt::WindowEvent &rEvent) override
void SetVisible(const bool bIsVisible)
virtual void SAL_CALL windowPaint(const css::awt::PaintEvent &rEvent) override
bool IsDisabled(const Area eArea) const
void SetThumbPosition(double nPosition, const bool bAsynchronousRepaint)
Set the position of the movable thumb.
SharedBitmapDescriptor mpPagerCenterDescriptor
double ValidateThumbPosition(double nPosition)
virtual void SAL_CALL mouseReleased(const css::awt::MouseEvent &rEvent) override
void SetThumbSize(const double nThumbSize)
Set the size of the movable thumb.
static css::awt::Rectangle ConvertRectangle(const css::geometry::RealRectangle2D &rBox)
Return the bounding box with integer coordinates of the given rectangle.
static css::uno::Reference< css::rendering::XPolyPolygon2D > CreatePolygon(const css::awt::Rectangle &rBox, const css::uno::Reference< css::rendering::XGraphicDevice > &rxDevice)
css::uno::Reference< css::drawing::XPresenterHelper > mxPresenterHelper
virtual void UpdateDragAnchor(const double nDragDistance)=0
virtual double GetMinor(const double nX, const double nY) const override
virtual void SAL_CALL mouseEntered(const css::awt::MouseEvent &rEvent) override
virtual double GetMinor(const double nX, const double nY) const =0
static css::awt::Rectangle Intersection(const css::awt::Rectangle &rBox1, const css::awt::Rectangle &rBox2)
virtual void SAL_CALL mousePressed(const css::awt::MouseEvent &rEvent) override
void Repaint(const css::geometry::RealRectangle2D &rBox, const bool bAsynchronous)
void SetMouseArea(const PresenterScrollBar::Area &reArea)
std::shared_ptr< MousePressRepeater > mpMousePressRepeater
virtual double GetDragDistance(const sal_Int32 nX, const sal_Int32 nY) const override
virtual void SAL_CALL mouseExited(const css::awt::MouseEvent &rEvent) override
virtual void PaintComposite(const css::awt::Rectangle &rRepaintBox, const Area eArea, const SharedBitmapDescriptor &rpStartBitmaps, const SharedBitmapDescriptor &rpCenterBitmaps, const SharedBitmapDescriptor &rpEndBitmaps) override
virtual void SAL_CALL disposing() override
virtual sal_Int32 GetSize() const override
virtual void SAL_CALL windowShown(const css::lang::EventObject &rEvent) override
static const sal_Int32 NotAValidTaskId
Reference< XSingleServiceFactory > xFactory
aCursorMoveIdle Stop()
static bool IsInside(const css::geometry::RealRectangle2D &rBox, const css::geometry::RealPoint2D &rPoint)
The timer allows tasks to be scheduled for execution at a specified time in the future.
css::uno::Reference< css::awt::XWindow > mxWindow
::cppu::WeakComponentImplHelper< css::awt::XWindowListener, css::awt::XPaintListener, css::awt::XMouseListener, css::awt::XMouseMotionListener > PresenterScrollBarInterfaceBase
virtual void SAL_CALL windowMoved(const css::awt::WindowEvent &rEvent) override
PresenterVerticalScrollBar(const css::uno::Reference< css::uno::XComponentContext > &rxComponentContext, const css::uno::Reference< css::awt::XWindow > &rxParentWindow, const std::shared_ptr< PresenterPaintManager > &rpPaintManager, const ::std::function< void(double)> &rThumbMotionListener)