LibreOffice Module sdext (master)  1
PresenterToolBar.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 <vcl/settings.hxx>
21 #include "PresenterToolBar.hxx"
22 
27 #include "PresenterTimer.hxx"
29 
30 #include <cppuhelper/compbase.hxx>
31 #include <com/sun/star/awt/XWindowPeer.hpp>
32 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
33 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
34 #include <com/sun/star/drawing/framework/XPane.hpp>
35 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
36 #include <com/sun/star/rendering/CompositeOperation.hpp>
37 #include <com/sun/star/rendering/RenderState.hpp>
38 #include <com/sun/star/rendering/TextDirection.hpp>
39 #include <com/sun/star/rendering/ViewState.hpp>
40 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
41 #include <com/sun/star/util/Color.hpp>
42 #include <rtl/ustrbuf.hxx>
43 
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::drawing::framework;
47 
48 namespace sdext::presenter {
49 
50 const sal_Int32 gnGapSize (20);
51 
52 namespace {
53 
54  class Text
55  {
56  public:
57  Text();
58  Text (
59  const OUString& rsText,
61 
62  void SetText (const OUString& rsText);
63  const OUString& GetText() const;
65 
66  void Paint (
67  const Reference<rendering::XCanvas>& rxCanvas,
68  const rendering::ViewState& rViewState,
69  const awt::Rectangle& rBoundingBox);
70 
71  geometry::RealRectangle2D GetBoundingBox (
72  const Reference<rendering::XCanvas>& rxCanvas);
73 
74  private:
75  OUString msText;
77  };
78 
79  class ElementMode
80  {
81  public:
82  ElementMode();
83  ElementMode(const ElementMode&) = delete;
84  ElementMode& operator=(const ElementMode&) = delete;
85 
87  OUString msAction;
89 
90  void ReadElementMode (
91  const Reference<beans::XPropertySet>& rxProperties,
92  const OUString& rsModeName,
93  std::shared_ptr<ElementMode> const & rpDefaultMode,
95  };
96  typedef std::shared_ptr<ElementMode> SharedElementMode;
97 
98 } // end of anonymous namespace
99 
101 {
102 public:
103  Context() = default;
104  Context(const Context&) = delete;
105  Context& operator=(const Context&) = delete;
106  Reference<drawing::XPresenterHelper> mxPresenterHelper;
107  css::uno::Reference<css::rendering::XCanvas> mxCanvas;
108 };
109 
110 //===== PresenterToolBar::Element =============================================
111 
112 namespace {
113  typedef cppu::WeakComponentImplHelper<
114  css::document::XEventListener,
115  css::frame::XStatusListener
116  > ElementInterfaceBase;
117 
118  class Element
119  : private ::cppu::BaseMutex,
120  public ElementInterfaceBase
121  {
122  public:
123  explicit Element (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
124  Element(const Element&) = delete;
125  Element& operator=(const Element&) = delete;
126 
127  virtual void SAL_CALL disposing() override;
128 
129  virtual void SetModes (
130  const SharedElementMode& rpNormalMode,
131  const SharedElementMode& rpMouseOverMode,
132  const SharedElementMode& rpSelectedMode,
133  const SharedElementMode& rpDisabledMode,
134  const SharedElementMode& rpMouseOverSelectedMode);
135  void CurrentSlideHasChanged();
136  void SetLocation (const awt::Point& rLocation);
137  void SetSize (const geometry::RealSize2D& rSize);
138  virtual void Paint (
139  const Reference<rendering::XCanvas>& rxCanvas,
140  const rendering::ViewState& rViewState) = 0;
141  awt::Size const & GetBoundingSize (
142  const Reference<rendering::XCanvas>& rxCanvas);
143  awt::Rectangle GetBoundingBox() const;
144  virtual bool SetState (const bool bIsOver, const bool bIsPressed);
145  void Invalidate (const bool bSynchronous);
146  bool IsOutside (const awt::Rectangle& rBox);
147  virtual bool IsFilling() const;
148  void UpdateState();
149 
150  // lang::XEventListener
151 
152  virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override;
153 
154  // document::XEventListener
155 
156  virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent) override;
157 
158  // frame::XStatusListener
159 
160  virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent) override;
161 
162  protected:
164  awt::Point maLocation;
165  awt::Size maSize;
166  SharedElementMode mpNormal;
167  SharedElementMode mpMouseOver;
168  SharedElementMode mpSelected;
169  SharedElementMode mpDisabled;
170  SharedElementMode mpMouseOverSelected;
171  SharedElementMode mpMode;
172  bool mbIsOver;
175 
176  virtual awt::Size CreateBoundingSize (
177  const Reference<rendering::XCanvas>& rxCanvas) = 0;
178 
179  bool IsEnabled() const { return mbIsEnabled;}
180  private:
182  };
183 
184 } // end of anonymous namespace
185 
187  : public ::std::vector<rtl::Reference<Element> >
188 {
189 };
190 
191 //===== Button ================================================================
192 
193 namespace {
194 
195  class Button : public Element
196  {
197  public:
198  static ::rtl::Reference<Element> Create (
199  const ::rtl::Reference<PresenterToolBar>& rpToolBar);
200 
201  virtual void SAL_CALL disposing() override;
202 
203  virtual void Paint (
204  const Reference<rendering::XCanvas>& rxCanvas,
205  const rendering::ViewState& rViewState) override;
206 
207  // lang::XEventListener
208 
209  virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override;
210 
211  protected:
212  virtual awt::Size CreateBoundingSize (
213  const Reference<rendering::XCanvas>& rxCanvas) override;
214 
215  private:
217 
218  Button (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
219  void Initialize();
220  void PaintIcon (
221  const Reference<rendering::XCanvas>& rxCanvas,
222  const sal_Int32 nTextHeight,
223  const rendering::ViewState& rViewState);
224  PresenterBitmapDescriptor::Mode GetMode() const;
225  };
226 
227 //===== Label =================================================================
228 
229  class Label : public Element
230  {
231  public:
232  explicit Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
233 
234  void SetText (const OUString& rsText);
235  virtual void Paint (
236  const Reference<rendering::XCanvas>& rxCanvas,
237  const rendering::ViewState& rViewState) override;
238  virtual bool SetState (const bool bIsOver, const bool bIsPressed) override;
239 
240  protected:
241  virtual awt::Size CreateBoundingSize (
242  const Reference<rendering::XCanvas>& rxCanvas) override;
243  };
244 
245 // Some specialized controls.
246 
247  class TimeFormatter
248  {
249  public:
250  static OUString FormatTime (const oslDateTime& rTime);
251  };
252 
253  class TimeLabel : public Label
254  {
255  public:
256  void ConnectToTimer();
257  virtual void TimeHasChanged (const oslDateTime& rCurrentTime) = 0;
258  protected:
259  explicit TimeLabel(const ::rtl::Reference<PresenterToolBar>& rpToolBar);
260  using Element::disposing;
261  virtual void SAL_CALL disposing() override;
262  private:
263  class Listener : public PresenterClockTimer::Listener
264  {
265  public:
266  explicit Listener (const ::rtl::Reference<TimeLabel>& rxLabel)
267  : mxLabel(rxLabel) {}
268  virtual ~Listener() {}
269  virtual void TimeHasChanged (const oslDateTime& rCurrentTime) override
270  { if (mxLabel.is()) mxLabel->TimeHasChanged(rCurrentTime); }
271  private:
273  };
274  std::shared_ptr<PresenterClockTimer::Listener> mpListener;
275  };
276 
277  class CurrentTimeLabel : public TimeLabel
278  {
279  public:
280  static ::rtl::Reference<Element> Create (
281  const ::rtl::Reference<PresenterToolBar>& rpToolBar);
282  virtual void SetModes (
283  const SharedElementMode& rpNormalMode,
284  const SharedElementMode& rpMouseOverMode,
285  const SharedElementMode& rpSelectedMode,
286  const SharedElementMode& rpDisabledMode,
287  const SharedElementMode& rpMouseOverSelectedMode) override;
288  private:
289  CurrentTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
290  virtual ~CurrentTimeLabel() override;
291  virtual void TimeHasChanged (const oslDateTime& rCurrentTime) override;
292  };
293 
294  class PresentationTimeLabel : public TimeLabel, public IPresentationTime
295  {
296  public:
297  static ::rtl::Reference<Element> Create (
298  const ::rtl::Reference<PresenterToolBar>& rpToolBar);
299  virtual void SetModes (
300  const SharedElementMode& rpNormalMode,
301  const SharedElementMode& rpMouseOverMode,
302  const SharedElementMode& rpSelectedMode,
303  const SharedElementMode& rpDisabledMode,
304  const SharedElementMode& rpMouseOverSelectedMode) override;
305  virtual void restart() override;
306  virtual bool isPaused() override;
307  virtual void setPauseStatus(const bool pauseStatus) override;
308  const TimeValue& getPauseTimeValue() const;
309  void setPauseTimeValue(const TimeValue pauseTime);
310  private:
311  TimeValue maStartTimeValue;
312  TimeValue pauseTimeValue;
313  PresentationTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
314  bool paused;
315  virtual ~PresentationTimeLabel() override;
316  virtual void TimeHasChanged (const oslDateTime& rCurrentTime) override;
317  };
318 
319  class VerticalSeparator : public Element
320  {
321  public:
322  explicit VerticalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
323  virtual void Paint (
324  const Reference<rendering::XCanvas>& rxCanvas,
325  const rendering::ViewState& rViewState) override;
326  virtual bool IsFilling() const override;
327 
328  protected:
329  virtual awt::Size CreateBoundingSize (
330  const Reference<rendering::XCanvas>& rxCanvas) override;
331  };
332 
333  class HorizontalSeparator : public Element
334  {
335  public:
336  explicit HorizontalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
337  virtual void Paint (
338  const Reference<rendering::XCanvas>& rxCanvas,
339  const rendering::ViewState& rViewState) override;
340  virtual bool IsFilling() const override;
341 
342  protected:
343  virtual awt::Size CreateBoundingSize (
344  const Reference<rendering::XCanvas>& rxCanvas) override;
345  };
346 } // end of anonymous namespace
347 
348 //===== PresenterToolBar ======================================================
349 
351  const Reference<XComponentContext>& rxContext,
352  const css::uno::Reference<css::awt::XWindow>& rxWindow,
353  const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
354  const ::rtl::Reference<PresenterController>& rpPresenterController,
355  const Anchor eAnchor)
357  mxComponentContext(rxContext),
358  mxWindow(rxWindow),
359  mxCanvas(rxCanvas),
360  mpPresenterController(rpPresenterController),
361  mbIsLayoutPending(false),
362  meAnchor(eAnchor)
363 {
364 }
365 
366 void PresenterToolBar::Initialize (
367  const OUString& rsConfigurationPath)
368 {
369  try
370  {
371  CreateControls(rsConfigurationPath);
372 
373  if (mxWindow.is())
374  {
375  mxWindow->addWindowListener(this);
376  mxWindow->addPaintListener(this);
377  mxWindow->addMouseListener(this);
378  mxWindow->addMouseMotionListener(this);
379 
380  Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
381  if (xPeer.is())
382  xPeer->setBackground(util::Color(0xff000000));
383 
384  mxWindow->setVisible(true);
385  }
386 
387  mxSlideShowController = mpPresenterController->GetSlideShowController();
388  UpdateSlideNumber();
389  mbIsLayoutPending = true;
390  }
391  catch (RuntimeException&)
392  {
393  mpCurrentContainerPart.reset();
394  maElementContainer.clear();
395  throw;
396  }
397 }
398 
399 PresenterToolBar::~PresenterToolBar()
400 {
401 }
402 
403 void SAL_CALL PresenterToolBar::disposing()
404 {
405  if (mxWindow.is())
406  {
407  mxWindow->removeWindowListener(this);
408  mxWindow->removePaintListener(this);
409  mxWindow->removeMouseListener(this);
410  mxWindow->removeMouseMotionListener(this);
411  mxWindow = nullptr;
412  }
413 
414  // Dispose tool bar elements.
415  for (const auto& rxPart : maElementContainer)
416  {
417  OSL_ASSERT(rxPart != nullptr);
418  for (const rtl::Reference<Element>& pElement : *rxPart)
419  {
420  if (pElement)
421  {
422  Reference<lang::XComponent> xComponent = pElement;
423  if (xComponent.is())
424  xComponent->dispose();
425  }
426  }
427  }
428 
429  mpCurrentContainerPart.reset();
430  maElementContainer.clear();
431 }
432 
433 void PresenterToolBar::InvalidateArea (
434  const awt::Rectangle& rRepaintBox,
435  const bool bSynchronous)
436 {
437  std::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager());
438  if (!xManager)
439  return;
440  xManager->Invalidate(
441  mxWindow,
442  rRepaintBox,
443  bSynchronous);
444 }
445 
446 void PresenterToolBar::RequestLayout()
447 {
448  mbIsLayoutPending = true;
449 
450  std::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager());
451  if (!xManager)
452  return;
453 
454  xManager->Invalidate(mxWindow);
455 }
456 
457 geometry::RealSize2D const & PresenterToolBar::GetMinimalSize()
458 {
459  if (mbIsLayoutPending)
460  Layout(mxCanvas);
461  return maMinimalSize;
462 }
463 
464 const ::rtl::Reference<PresenterController>& PresenterToolBar::GetPresenterController() const
465 {
466  return mpPresenterController;
467 }
468 
469 const Reference<XComponentContext>& PresenterToolBar::GetComponentContext() const
470 {
471  return mxComponentContext;
472 }
473 
474 //----- lang::XEventListener -------------------------------------------------
475 
476 void SAL_CALL PresenterToolBar::disposing (const lang::EventObject& rEventObject)
477 {
478  if (rEventObject.Source == mxWindow)
479  mxWindow = nullptr;
480 }
481 
482 //----- XWindowListener -------------------------------------------------------
483 
484 void SAL_CALL PresenterToolBar::windowResized (const awt::WindowEvent&)
485 {
486  mbIsLayoutPending = true;
487 }
488 
489 void SAL_CALL PresenterToolBar::windowMoved (const awt::WindowEvent&) {}
490 
491 void SAL_CALL PresenterToolBar::windowShown (const lang::EventObject&)
492 {
493  mbIsLayoutPending = true;
494 }
495 
496 void SAL_CALL PresenterToolBar::windowHidden (const lang::EventObject&) {}
497 
498 //----- XPaintListener --------------------------------------------------------
499 void SAL_CALL PresenterToolBar::windowPaint (const css::awt::PaintEvent& rEvent)
500 {
501  if ( ! mxCanvas.is())
502  return;
503 
504  if ( ! mbIsPresenterViewActive)
505  return;
506 
507  const rendering::ViewState aViewState (
508  geometry::AffineMatrix2D(1,0,0, 0,1,0),
509  PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice()));
510 
511  if (mbIsLayoutPending)
512  Layout(mxCanvas);
513 
514  Paint(rEvent.UpdateRect, aViewState);
515 
516  // Make the back buffer visible.
517  Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
518  if (xSpriteCanvas.is())
519  xSpriteCanvas->updateScreen(false);
520 }
521 
522 //----- XMouseListener --------------------------------------------------------
523 void SAL_CALL PresenterToolBar::mousePressed (const css::awt::MouseEvent& rEvent)
524 {
525  ThrowIfDisposed();
526  CheckMouseOver(rEvent, true, true);
527 }
528 
529 void SAL_CALL PresenterToolBar::mouseReleased (const css::awt::MouseEvent& rEvent)
530 {
531  ThrowIfDisposed();
532  CheckMouseOver(rEvent, true);
533 }
534 
535 void SAL_CALL PresenterToolBar::mouseEntered (const css::awt::MouseEvent& rEvent)
536 {
537  ThrowIfDisposed();
538  CheckMouseOver(rEvent, true);
539 }
540 
541 void SAL_CALL PresenterToolBar::mouseExited (const css::awt::MouseEvent& rEvent)
542 {
543  ThrowIfDisposed();
544  CheckMouseOver(rEvent, false);
545  }
546 
547 //----- XMouseMotionListener --------------------------------------------------
548 
549 void SAL_CALL PresenterToolBar::mouseMoved (const css::awt::MouseEvent& rEvent)
550 {
551  ThrowIfDisposed();
552  CheckMouseOver(rEvent, true);
553  }
554 
555 void SAL_CALL PresenterToolBar::mouseDragged (const css::awt::MouseEvent&)
556 {
557  ThrowIfDisposed();
558 }
559 
560 //----- XDrawView -------------------------------------------------------------
561 
562 void SAL_CALL PresenterToolBar::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
563 {
564  if (rxSlide != mxCurrentSlide)
565  {
566  mxCurrentSlide = rxSlide;
567  UpdateSlideNumber();
568  }
569 }
570 
571 Reference<drawing::XDrawPage> SAL_CALL PresenterToolBar::getCurrentPage()
572 {
573  return mxCurrentSlide;
574 }
575 
576 
577 void PresenterToolBar::CreateControls (
578  const OUString& rsConfigurationPath)
579 {
580  if ( ! mxWindow.is())
581  return;
582 
583  // Expand the macro in the bitmap file names.
584  PresenterConfigurationAccess aConfiguration (
586  "/org.openoffice.Office.PresenterScreen/",
587  PresenterConfigurationAccess::READ_ONLY);
588 
589  mpCurrentContainerPart = std::make_shared<ElementContainerPart>();
590  maElementContainer.clear();
591  maElementContainer.push_back(mpCurrentContainerPart);
592 
593  Reference<container::XHierarchicalNameAccess> xToolBarNode (
594  aConfiguration.GetConfigurationNode(rsConfigurationPath),
595  UNO_QUERY);
596  if (!xToolBarNode.is())
597  return;
598 
600  PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode, "Entries"),
601  UNO_QUERY);
602  Context aContext;
603  aContext.mxPresenterHelper = mpPresenterController->GetPresenterHelper();
604  aContext.mxCanvas = mxCanvas;
605  if (xEntries.is()
606  && aContext.mxPresenterHelper.is()
607  && aContext.mxCanvas.is())
608  {
609  PresenterConfigurationAccess::ForAll(
610  xEntries,
611  [this, &aContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
612  {
613  return this->ProcessEntry(xProps, aContext);
614  });
615  }
616 }
617 
618 void PresenterToolBar::ProcessEntry (
619  const Reference<beans::XPropertySet>& rxProperties,
620  Context const & rContext)
621 {
622  if ( ! rxProperties.is())
623  return;
624 
625  // Type has to be present.
626  OUString sType;
627  if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties, "Type") >>= sType))
628  return;
629 
630  // Read mode specific values.
631  SharedElementMode pNormalMode = std::make_shared<ElementMode>();
632  SharedElementMode pMouseOverMode = std::make_shared<ElementMode>();
633  SharedElementMode pSelectedMode = std::make_shared<ElementMode>();
634  SharedElementMode pDisabledMode = std::make_shared<ElementMode>();
635  SharedElementMode pMouseOverSelectedMode = std::make_shared<ElementMode>();
636  pNormalMode->ReadElementMode(rxProperties, "Normal", pNormalMode, rContext);
637  pMouseOverMode->ReadElementMode(rxProperties, "MouseOver", pNormalMode, rContext);
638  pSelectedMode->ReadElementMode(rxProperties, "Selected", pNormalMode, rContext);
639  pDisabledMode->ReadElementMode(rxProperties, "Disabled", pNormalMode, rContext);
640  pMouseOverSelectedMode->ReadElementMode(rxProperties, "MouseOverSelected", pSelectedMode, rContext);
641 
642  // Create new element.
643  ::rtl::Reference<Element> pElement;
644  if ( sType == "Button" )
645  pElement = Button::Create(this);
646  else if ( sType == "CurrentTimeLabel" )
647  pElement = CurrentTimeLabel::Create(this);
648  else if ( sType == "PresentationTimeLabel" )
649  pElement = PresentationTimeLabel::Create(this);
650  else if ( sType == "VerticalSeparator" )
651  pElement.set(new VerticalSeparator(this));
652  else if ( sType == "HorizontalSeparator" )
653  pElement.set(new HorizontalSeparator(this));
654  else if ( sType == "Label" )
655  pElement.set(new Label(this));
656  else if ( sType == "ChangeOrientation" )
657  {
658  mpCurrentContainerPart = std::make_shared<ElementContainerPart>();
659  maElementContainer.push_back(mpCurrentContainerPart);
660  return;
661  }
662  if (pElement.is())
663  {
664  pElement->SetModes( pNormalMode, pMouseOverMode, pSelectedMode, pDisabledMode, pMouseOverSelectedMode);
665  pElement->UpdateState();
666  if (mpCurrentContainerPart)
667  mpCurrentContainerPart->push_back(pElement);
668  }
669 }
670 
671 void PresenterToolBar::Layout (
672  const Reference<rendering::XCanvas>& rxCanvas)
673 {
674  if (maElementContainer.empty())
675  return;
676 
677  mbIsLayoutPending = false;
678 
679  const awt::Rectangle aWindowBox (mxWindow->getPosSize());
680  ::std::vector<geometry::RealSize2D> aPartSizes (maElementContainer.size());
681  geometry::RealSize2D aTotalSize (0,0);
682  bool bIsHorizontal (true);
683  sal_Int32 nIndex (0);
684  double nTotalHorizontalGap (0);
685  sal_Int32 nGapCount (0);
686  for (const auto& rxPart : maElementContainer)
687  {
688  geometry::RealSize2D aSize (CalculatePartSize(rxCanvas, rxPart, bIsHorizontal));
689 
690  // Remember the size of each part for later.
691  aPartSizes[nIndex] = aSize;
692 
693  // Add gaps between elements.
694  if (rxPart->size()>1 && bIsHorizontal)
695  {
696  nTotalHorizontalGap += (rxPart->size() - 1) * gnGapSize;
697  nGapCount += rxPart->size() - 1;
698  }
699 
700  // Orientation changes for each part.
701  bIsHorizontal = !bIsHorizontal;
702  // Width is accumulated.
703  aTotalSize.Width += aSize.Width;
704  // Height is the maximum height of all parts.
705  aTotalSize.Height = ::std::max(aTotalSize.Height, aSize.Height);
706  ++nIndex;
707  }
708  // Add gaps between parts.
709  if (maElementContainer.size() > 1)
710  {
711  nTotalHorizontalGap += (maElementContainer.size() - 1) * gnGapSize;
712  nGapCount += maElementContainer.size()-1;
713  }
714 
715  // Done to introduce gap between the end of the toolbar and the last button
716  aTotalSize.Width += gnGapSize/2;
717 
718  // Calculate the minimal size so that the window size of the tool bar
719  // can be adapted accordingly.
720  maMinimalSize = aTotalSize;
721  maMinimalSize.Width += nTotalHorizontalGap;
722 
723  // Calculate the gaps between elements.
724  double nGapWidth (0);
725  if (nGapCount > 0)
726  {
727  if (aTotalSize.Width + nTotalHorizontalGap > aWindowBox.Width)
728  nTotalHorizontalGap = aWindowBox.Width - aTotalSize.Width;
729  nGapWidth = nTotalHorizontalGap / nGapCount;
730  }
731 
732  // Determine the location of the left edge.
733  double nX (0);
734  switch (meAnchor)
735  {
736  case Left : nX = 0; break;
737  case Center: nX = (aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap) / 2; break;
738  }
739 
740  // Place the parts.
741  double nY ((aWindowBox.Height - aTotalSize.Height) / 2);
742  bIsHorizontal = true;
743 
744  /* push front or back ? ... */
747  nIndex = 0;
748  for (const auto& rxPart : maElementContainer)
749  {
750  geometry::RealRectangle2D aBoundingBox(
751  nX, nY,
752  nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height);
753 
754  // Add space for gaps between elements.
755  if (rxPart->size() > 1 && bIsHorizontal)
756  aBoundingBox.X2 += (rxPart->size() - 1) * nGapWidth;
757 
758  LayoutPart(rxCanvas, rxPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal);
759  bIsHorizontal = !bIsHorizontal;
760  nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth;
761  ++nIndex;
762  }
763  }
764  else {
765  ElementContainer::iterator iPart;
766  ElementContainer::iterator iBegin (maElementContainer.begin());
767  for (iPart=maElementContainer.end()-1, nIndex=2; iPart!=iBegin-1; --iPart, --nIndex)
768  {
769  geometry::RealRectangle2D aBoundingBox(
770  nX, nY,
771  nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height);
772 
773  // Add space for gaps between elements.
774  if ((*iPart)->size() > 1)
775  if (bIsHorizontal)
776  aBoundingBox.X2 += ((*iPart)->size()-1) * nGapWidth;
777 
778  LayoutPart(rxCanvas, *iPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal);
779  bIsHorizontal = !bIsHorizontal;
780  nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth;
781  }
782  }
783 
784  // The whole window has to be repainted.
785  std::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager());
786  if (!xManager)
787  return;
788  xManager->Invalidate(mxWindow);
789 }
790 
791 geometry::RealSize2D PresenterToolBar::CalculatePartSize (
792  const Reference<rendering::XCanvas>& rxCanvas,
793  const SharedElementContainerPart& rpPart,
794  const bool bIsHorizontal)
795 {
796  geometry::RealSize2D aTotalSize (0,0);
797 
798  if (mxWindow.is())
799  {
800  // Calculate the summed width of all elements.
801  for (const auto& rxElement : *rpPart)
802  {
803  if (!rxElement)
804  continue;
805 
806  const awt::Size aBSize (rxElement->GetBoundingSize(rxCanvas));
807  if (bIsHorizontal)
808  {
809  aTotalSize.Width += aBSize.Width;
810  if (aBSize.Height > aTotalSize.Height)
811  aTotalSize.Height = aBSize.Height;
812  }
813  else
814  {
815  aTotalSize.Height += aBSize.Height;
816  if (aBSize.Width > aTotalSize.Width)
817  aTotalSize.Width = aBSize.Width;
818  }
819  }
820  }
821  return aTotalSize;
822 }
823 
824 void PresenterToolBar::LayoutPart (
825  const Reference<rendering::XCanvas>& rxCanvas,
826  const SharedElementContainerPart& rpPart,
827  const geometry::RealRectangle2D& rBoundingBox,
828  const geometry::RealSize2D& rPartSize,
829  const bool bIsHorizontal)
830 {
831  double nGap (0);
832  if (rpPart->size() > 1)
833  {
834  if (bIsHorizontal)
835  nGap = (rBoundingBox.X2 - rBoundingBox.X1 - rPartSize.Width) / (rpPart->size()-1);
836  else
837  nGap = (rBoundingBox.Y2 - rBoundingBox.Y1 - rPartSize.Height) / (rpPart->size()-1);
838  }
839 
840  // Place the elements.
841  double nX (rBoundingBox.X1);
842  double nY (rBoundingBox.Y1);
843 
846  for (auto& rxElement : *rpPart)
847  {
848  if (!rxElement)
849  continue;
850 
851  const awt::Size aElementSize (rxElement->GetBoundingSize(rxCanvas));
852  if (bIsHorizontal)
853  {
854  if (rxElement->IsFilling())
855  {
856  nY = rBoundingBox.Y1;
857  rxElement->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1));
858  }
859  else
860  nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2;
861  rxElement->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
862  nX += aElementSize.Width + nGap;
863  }
864  else
865  {
866  if (rxElement->IsFilling())
867  {
868  nX = rBoundingBox.X1;
869  rxElement->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aElementSize.Height));
870  }
871  else
872  nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aElementSize.Width) / 2;
873  rxElement->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
874  nY += aElementSize.Height + nGap;
875  }
876  }
877  }
878  else {
879  ElementContainerPart::const_iterator iElement;
880  ElementContainerPart::const_iterator iBegin (rpPart->begin());
881 
882  for (iElement=rpPart->end()-1; iElement!=iBegin-1; --iElement)
883  {
884  if (iElement->get() == nullptr)
885  continue;
886 
887  const awt::Size aElementSize ((*iElement)->GetBoundingSize(rxCanvas));
888  if (bIsHorizontal)
889  {
890  if ((*iElement)->IsFilling())
891  {
892  nY = rBoundingBox.Y1;
893  (*iElement)->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1));
894  }
895  else
896  nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2;
897  (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
898  nX += aElementSize.Width + nGap;
899  }
900  else
901  {
902  // reverse presentation time with current time
903  if (iElement==iBegin){
904  iElement=iBegin+2;
905  }
906  else if (iElement==iBegin+2){
907  iElement=iBegin;
908  }
909  const awt::Size aNewElementSize ((*iElement)->GetBoundingSize(rxCanvas));
910  if ((*iElement)->IsFilling())
911  {
912  nX = rBoundingBox.X1;
913  (*iElement)->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aNewElementSize.Height));
914  }
915  else
916  nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aNewElementSize.Width) / 2;
917  (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
918  nY += aNewElementSize.Height + nGap;
919 
920  // return the index as it was before the reversing
921  if (iElement==iBegin)
922  iElement=iBegin+2;
923  else if (iElement==iBegin+2)
924  iElement=iBegin;
925  }
926  }
927  }
928 }
929 
930 void PresenterToolBar::Paint (
931  const awt::Rectangle& rUpdateBox,
932  const rendering::ViewState& rViewState)
933 {
934  OSL_ASSERT(mxCanvas.is());
935 
936  for (const auto& rxPart : maElementContainer)
937  {
938  for (auto& rxElement : *rxPart)
939  {
940  if (rxElement)
941  {
942  if ( ! rxElement->IsOutside(rUpdateBox))
943  rxElement->Paint(mxCanvas, rViewState);
944  }
945  }
946  }
947 }
948 
949 void PresenterToolBar::UpdateSlideNumber()
950 {
951  if( mxSlideShowController.is() )
952  {
953  for (const auto& rxPart : maElementContainer)
954  {
955  for (auto& rxElement : *rxPart)
956  {
957  if (rxElement)
958  rxElement->CurrentSlideHasChanged();
959  }
960  }
961  }
962 }
963 
964 void PresenterToolBar::CheckMouseOver (
965  const css::awt::MouseEvent& rEvent,
966  const bool bOverWindow,
967  const bool bMouseDown)
968 {
969  css::awt::MouseEvent rTemp =rEvent;
971  awt::Rectangle aWindowBox = mxWindow->getPosSize();
972  rTemp.X=aWindowBox.Width-rTemp.X;
973  }
974  for (const auto& rxPart : maElementContainer)
975  {
976  for (auto& rxElement : *rxPart)
977  {
978  if (!rxElement)
979  continue;
980 
981  awt::Rectangle aBox (rxElement->GetBoundingBox());
982  const bool bIsOver = bOverWindow
983  && aBox.X <= rTemp.X
984  && aBox.Width+aBox.X-1 >= rTemp.X
985  && aBox.Y <= rTemp.Y
986  && aBox.Height+aBox.Y-1 >= rTemp.Y;
987  rxElement->SetState(
988  bIsOver,
989  bIsOver && rTemp.Buttons!=0 && bMouseDown && rTemp.ClickCount>0);
990  }
991  }
992 }
993 
994 void PresenterToolBar::ThrowIfDisposed() const
995 {
996  if (rBHelper.bDisposed || rBHelper.bInDispose)
997  {
998  throw lang::DisposedException (
999  "PresenterToolBar has already been disposed",
1000  const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1001  }
1002 }
1003 
1004 //===== PresenterToolBarView ==================================================
1005 
1006 PresenterToolBarView::PresenterToolBarView (
1007  const Reference<XComponentContext>& rxContext,
1008  const Reference<XResourceId>& rxViewId,
1009  const Reference<frame::XController>& rxController,
1010  const ::rtl::Reference<PresenterController>& rpPresenterController)
1012  mxViewId(rxViewId),
1013  mpPresenterController(rpPresenterController)
1014 {
1015  try
1016  {
1017  Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
1018  Reference<XConfigurationController> xCC(xCM->getConfigurationController(),UNO_SET_THROW);
1019  mxPane.set(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
1020 
1021  mxWindow = mxPane->getWindow();
1022  mxCanvas = mxPane->getCanvas();
1023 
1025  rxContext,
1026  mxWindow,
1027  mxCanvas,
1028  rpPresenterController,
1030  mpToolBar->Initialize("PresenterScreenSettings/ToolBars/ToolBar");
1031 
1032  if (mxWindow.is())
1033  {
1034  mxWindow->addPaintListener(this);
1035 
1036  Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
1037  if (xPeer.is())
1038  xPeer->setBackground(util::Color(0xff000000));
1039 
1040  mxWindow->setVisible(true);
1041  }
1042  }
1043  catch (RuntimeException&)
1044  {
1045  mxViewId = nullptr;
1046  throw;
1047  }
1048 }
1049 
1051 {
1052 }
1053 
1055 {
1057  mpToolBar = nullptr;
1058  if (xComponent.is())
1059  xComponent->dispose();
1060 
1061  if (mxWindow.is())
1062  {
1063  mxWindow->removePaintListener(this);
1064  mxWindow = nullptr;
1065  }
1066  mxCanvas = nullptr;
1067  mxViewId = nullptr;
1068  mxPane = nullptr;
1069  mpPresenterController = nullptr;
1070 }
1071 
1072 const ::rtl::Reference<PresenterToolBar>& PresenterToolBarView::GetPresenterToolBar() const
1073 {
1074  return mpToolBar;
1075 }
1076 
1077 //----- XPaintListener --------------------------------------------------------
1078 
1079 void SAL_CALL PresenterToolBarView::windowPaint (const css::awt::PaintEvent& rEvent)
1080 {
1081  awt::Rectangle aWindowBox (mxWindow->getPosSize());
1082  mpPresenterController->GetCanvasHelper()->Paint(
1083  mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
1084  mxCanvas,
1085  rEvent.UpdateRect,
1086  awt::Rectangle(0,0,aWindowBox.Width, aWindowBox.Height),
1087  awt::Rectangle());
1088 }
1089 
1090 //----- lang::XEventListener -------------------------------------------------
1091 
1092 void SAL_CALL PresenterToolBarView::disposing (const lang::EventObject& rEventObject)
1093 {
1094  if (rEventObject.Source == mxWindow)
1095  mxWindow = nullptr;
1096 }
1097 
1098 //----- XResourceId -----------------------------------------------------------
1099 
1100 Reference<XResourceId> SAL_CALL PresenterToolBarView::getResourceId()
1101 {
1102  return mxViewId;
1103 }
1104 
1106 {
1107  return false;
1108 }
1109 
1110 //----- XDrawView -------------------------------------------------------------
1111 
1113 {
1114  Reference<drawing::XDrawView> xToolBar = mpToolBar;
1115  if (xToolBar.is())
1116  xToolBar->setCurrentPage(rxSlide);
1117 }
1118 
1120 {
1121  return nullptr;
1122 }
1123 
1124 //===== PresenterToolBar::Element =============================================
1125 
1126 namespace {
1127 
1128 Element::Element (
1129  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1130  : ElementInterfaceBase(m_aMutex),
1131  mpToolBar(rpToolBar),
1132  mbIsOver(false),
1133  mbIsPressed(false),
1135  mbIsEnabled(true)
1136 {
1137  if (mpToolBar)
1138  {
1139  OSL_ASSERT(mpToolBar->GetPresenterController().is());
1140  OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1141  }
1142 }
1143 
1144 void Element::SetModes (
1145  const SharedElementMode& rpNormalMode,
1146  const SharedElementMode& rpMouseOverMode,
1147  const SharedElementMode& rpSelectedMode,
1148  const SharedElementMode& rpDisabledMode,
1149  const SharedElementMode& rpMouseOverSelectedMode)
1150 {
1151  mpNormal = rpNormalMode;
1152  mpMouseOver = rpMouseOverMode;
1153  mpSelected = rpSelectedMode;
1154  mpDisabled = rpDisabledMode;
1155  mpMouseOverSelected = rpMouseOverSelectedMode;
1156  mpMode = rpNormalMode;
1157 }
1158 
1159 void Element::disposing()
1160 {
1161 }
1162 
1163 awt::Size const & Element::GetBoundingSize (
1164  const Reference<rendering::XCanvas>& rxCanvas)
1165 {
1166  maSize = CreateBoundingSize(rxCanvas);
1167  return maSize;
1168 }
1169 
1170 awt::Rectangle Element::GetBoundingBox() const
1171 {
1172  return awt::Rectangle(maLocation.X,maLocation.Y, maSize.Width, maSize.Height);
1173 }
1174 
1175 void Element::CurrentSlideHasChanged()
1176 {
1177  UpdateState();
1178 }
1179 
1180 void Element::SetLocation (const awt::Point& rLocation)
1181 {
1182  maLocation = rLocation;
1183 }
1184 
1185 void Element::SetSize (const geometry::RealSize2D& rSize)
1186 {
1187  maSize = awt::Size(sal_Int32(0.5+rSize.Width), sal_Int32(0.5+rSize.Height));
1188 }
1189 
1190 bool Element::SetState (
1191  const bool bIsOver,
1192  const bool bIsPressed)
1193 {
1194  bool bModified (mbIsOver != bIsOver || mbIsPressed != bIsPressed);
1195  bool bClicked (mbIsPressed && bIsOver && ! bIsPressed);
1196 
1197  mbIsOver = bIsOver;
1198  mbIsPressed = bIsPressed;
1199 
1200  // When the element is disabled then ignore mouse over or selection.
1201  // When the element is selected then ignore mouse over.
1202  if ( ! mbIsEnabled)
1203  mpMode = mpDisabled;
1204  else if (mbIsSelected && mbIsOver)
1206  else if (mbIsSelected)
1207  mpMode = mpSelected;
1208  else if (mbIsOver)
1209  mpMode = mpMouseOver;
1210  else
1211  mpMode = mpNormal;
1212 
1213  if (bClicked && mbIsEnabled)
1214  {
1215  if (mpMode)
1216  {
1217  do
1218  {
1219  if (mpMode->msAction.isEmpty())
1220  break;
1221 
1222  if (!mpToolBar)
1223  break;
1224 
1225  if (!mpToolBar->GetPresenterController())
1226  break;
1227 
1228  mpToolBar->GetPresenterController()->DispatchUnoCommand(mpMode->msAction);
1229  mpToolBar->RequestLayout();
1230  }
1231  while (false);
1232  }
1233 
1234  }
1235  else if (bModified)
1236  {
1237  Invalidate(true);
1238  }
1239 
1240  return bModified;
1241 }
1242 
1243 void Element::Invalidate (const bool bSynchronous)
1244 {
1245  OSL_ASSERT(mpToolBar.is());
1246  mpToolBar->InvalidateArea(GetBoundingBox(), bSynchronous);
1247 }
1248 
1249 bool Element::IsOutside (const awt::Rectangle& rBox)
1250 {
1251  if (rBox.X >= maLocation.X+maSize.Width)
1252  return true;
1253  else if (rBox.Y >= maLocation.Y+maSize.Height)
1254  return true;
1255  else if (maLocation.X >= rBox.X+rBox.Width)
1256  return true;
1257  else if (maLocation.Y >= rBox.Y+rBox.Height)
1258  return true;
1259  else
1260  return false;
1261 }
1262 
1263 
1264 bool Element::IsFilling() const
1265 {
1266  return false;
1267 }
1268 
1269 void Element::UpdateState()
1270 {
1271  OSL_ASSERT(mpToolBar);
1272  OSL_ASSERT(mpToolBar->GetPresenterController());
1273 
1274  if (!mpMode)
1275  return;
1276 
1277  util::URL aURL (mpToolBar->GetPresenterController()->CreateURLFromString(mpMode->msAction));
1278  Reference<frame::XDispatch> xDispatch (mpToolBar->GetPresenterController()->GetDispatch(aURL));
1279  if (xDispatch.is())
1280  {
1281  xDispatch->addStatusListener(this, aURL);
1282  xDispatch->removeStatusListener(this, aURL);
1283  }
1284 }
1285 
1286 //----- lang::XEventListener --------------------------------------------------
1287 
1288 void SAL_CALL Element::disposing (const css::lang::EventObject&) {}
1289 
1290 //----- document::XEventListener ----------------------------------------------
1291 
1292 void SAL_CALL Element::notifyEvent (const css::document::EventObject&)
1293 {
1294  UpdateState();
1295 }
1296 
1297 //----- frame::XStatusListener ------------------------------------------------
1298 
1299 void SAL_CALL Element::statusChanged (const css::frame::FeatureStateEvent& rEvent)
1300 {
1301  bool bIsSelected (mbIsSelected);
1302  bool bIsEnabled (rEvent.IsEnabled);
1303  rEvent.State >>= bIsSelected;
1304 
1305  if (bIsSelected != mbIsSelected || bIsEnabled != mbIsEnabled)
1306  {
1308  mbIsSelected = bIsSelected;
1309  SetState(mbIsOver, mbIsPressed);
1310  mpToolBar->RequestLayout();
1311  }
1312 }
1313 
1314 } // end of anonymous namespace
1315 
1316 //===== ElementMode ===========================================================
1317 
1318 namespace {
1319 
1320 ElementMode::ElementMode()
1321 {
1322 }
1323 
1324 void ElementMode::ReadElementMode (
1325  const Reference<beans::XPropertySet>& rxElementProperties,
1326  const OUString& rsModeName,
1327  std::shared_ptr<ElementMode> const & rpDefaultMode,
1329 {
1330  try
1331  {
1332  Reference<container::XHierarchicalNameAccess> xNode (
1333  PresenterConfigurationAccess::GetProperty(rxElementProperties, rsModeName),
1334  UNO_QUERY);
1335  Reference<beans::XPropertySet> xProperties (
1337  if (!xProperties.is() && rpDefaultMode != nullptr)
1338  {
1339  // The mode is not specified. Use the given, possibly empty,
1340  // default mode instead.
1341  mpIcon = rpDefaultMode->mpIcon;
1342  msAction = rpDefaultMode->msAction;
1343  maText = rpDefaultMode->maText;
1344  }
1345 
1346  // Read action.
1347  if ( ! (PresenterConfigurationAccess::GetProperty(xProperties, "Action") >>= msAction))
1348  if (rpDefaultMode != nullptr)
1349  msAction = rpDefaultMode->msAction;
1350 
1351  // Read text and font
1352  OUString sText(rpDefaultMode != nullptr ? rpDefaultMode->maText.GetText() : OUString());
1353  PresenterConfigurationAccess::GetProperty(xProperties, "Text") >>= sText;
1354  Reference<container::XHierarchicalNameAccess> xFontNode (
1355  PresenterConfigurationAccess::GetProperty(xProperties, "Font"), UNO_QUERY);
1357  xFontNode, rpDefaultMode != nullptr ? rpDefaultMode->maText.GetFont()
1359  maText = Text(sText,pFont);
1360 
1361  // Read bitmaps to display as icons.
1362  Reference<container::XHierarchicalNameAccess> xIconNode (
1363  PresenterConfigurationAccess::GetProperty(xProperties, "Icon"), UNO_QUERY);
1365  xIconNode, "", rContext.mxPresenterHelper, rContext.mxCanvas,
1366  rpDefaultMode != nullptr ? rpDefaultMode->mpIcon : SharedBitmapDescriptor());
1367  }
1368  catch(Exception&)
1369  {
1370  OSL_ASSERT(false);
1371  }
1372 }
1373 
1374 } // end of anonymous namespace
1375 
1376 //===== Button ================================================================
1377 
1378 namespace {
1379 
1380 ::rtl::Reference<Element> Button::Create (
1381  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1382 {
1383  ::rtl::Reference<Button> pElement (new Button(rpToolBar));
1384  pElement->Initialize();
1385  return pElement;
1386 }
1387 
1389  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1390  : Element(rpToolBar),
1392 {
1393  OSL_ASSERT(mpToolBar);
1394  OSL_ASSERT(mpToolBar->GetPresenterController().is());
1395  OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1396 }
1397 
1398 void Button::Initialize()
1399 {
1400  mpToolBar->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
1401  mbIsListenerRegistered = true;
1402 }
1403 
1404 void Button::disposing()
1405 {
1406  OSL_ASSERT(mpToolBar);
1408  {
1409  OSL_ASSERT(mpToolBar->GetPresenterController().is());
1410  OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1411 
1412  mbIsListenerRegistered = false;
1413  mpToolBar->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
1414  }
1415  Element::disposing();
1416 }
1417 
1418 void Button::Paint (
1419  const Reference<rendering::XCanvas>& rxCanvas,
1420  const rendering::ViewState& rViewState)
1421 {
1422  OSL_ASSERT(rxCanvas.is());
1423 
1424  if (!mpMode)
1425  return;
1426 
1427  if (!mpMode->mpIcon)
1428  return;
1429 
1430  geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1431  sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1432 
1433  PaintIcon(rxCanvas, nTextHeight, rViewState);
1434  mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox());
1435 }
1436 
1437 awt::Size Button::CreateBoundingSize (
1438  const Reference<rendering::XCanvas>& rxCanvas)
1439 {
1440  if (!mpMode)
1441  return awt::Size();
1442 
1443  geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1444 
1445  // tdf#128964 This ensures that if the text of a button changes due to a change in
1446  // the state of the button the other buttons of the toolbar do not move. The button is
1447  // allotted the maximum size so that it doesn't resize during a change of state.
1448  geometry::RealRectangle2D aTextBBoxNormal (mpNormal->maText.GetBoundingBox(rxCanvas));
1449  geometry::RealRectangle2D aTextBBoxMouseOver (mpMouseOver->maText.GetBoundingBox(rxCanvas));
1450  geometry::RealRectangle2D aTextBBoxSelected (mpSelected->maText.GetBoundingBox(rxCanvas));
1451  geometry::RealRectangle2D aTextBBoxDisabled (mpDisabled->maText.GetBoundingBox(rxCanvas));
1452  geometry::RealRectangle2D aTextBBoxMouseOverSelected (mpMouseOverSelected->maText.GetBoundingBox(rxCanvas));
1453  std::vector<sal_Int32> widths
1454  {
1455  sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxNormal.X2 - aTextBBoxNormal.X1),
1456  sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOver.X2 - aTextBBoxMouseOver.X1),
1457  sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxSelected.X2 - aTextBBoxSelected.X1),
1458  sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxDisabled.X2 - aTextBBoxDisabled.X1),
1459  sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOverSelected.X2 - aTextBBoxMouseOverSelected.X1)
1460  };
1461 
1462  sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1463  Reference<rendering::XBitmap> xBitmap;
1464  if (mpMode->mpIcon)
1465  xBitmap = mpMode->mpIcon->GetNormalBitmap();
1466  if (xBitmap.is())
1467  {
1468  const sal_Int32 nGap (5);
1469  geometry::IntegerSize2D aSize (xBitmap->getSize());
1470  return awt::Size(
1471  ::std::max(aSize.Width, *std::max_element(widths.begin(), widths.end())),
1472  aSize.Height + nGap + nTextHeight);
1473  }
1474  else
1475  {
1476  return awt::Size(*std::max_element(widths.begin(), widths.end()), nTextHeight);
1477  }
1478 }
1479 
1480 void Button::PaintIcon (
1481  const Reference<rendering::XCanvas>& rxCanvas,
1482  const sal_Int32 nTextHeight,
1483  const rendering::ViewState& rViewState)
1484 {
1485  if (!mpMode)
1486  return;
1487 
1488  Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetBitmap(GetMode()));
1489  if (!xBitmap.is())
1490  return;
1491 
1494  const sal_Int32 nX (maLocation.X
1495  + (maSize.Width-xBitmap->getSize().Width) / 2);
1496  const sal_Int32 nY (maLocation.Y
1497  + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
1498  const rendering::RenderState aRenderState(
1499  geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
1500  nullptr,
1501  Sequence<double>(4),
1502  rendering::CompositeOperation::OVER);
1503  rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
1504  }
1505  else {
1506  const sal_Int32 nX (maLocation.X
1507  + (maSize.Width+xBitmap->getSize().Width) / 2);
1508  const sal_Int32 nY (maLocation.Y
1509  + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
1510  const rendering::RenderState aRenderState(
1511  geometry::AffineMatrix2D(-1,0,nX, 0,1,nY),
1512  nullptr,
1513  Sequence<double>(4),
1514  rendering::CompositeOperation::OVER);
1515  rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
1516  }
1517 }
1518 
1519 PresenterBitmapDescriptor::Mode Button::GetMode() const
1520 {
1521  if ( ! IsEnabled())
1523  else if (mbIsPressed)
1525  else if (mbIsOver)
1527  else
1529 }
1530 
1531 //----- lang::XEventListener --------------------------------------------------
1532 
1533 void SAL_CALL Button::disposing (const css::lang::EventObject& rEvent)
1534 {
1535  mbIsListenerRegistered = false;
1536  Element::disposing(rEvent);
1537 }
1538 
1539 } // end of anonymous namespace
1540 
1541 //===== PresenterToolBar::Label ===============================================
1542 
1543 namespace {
1544 
1545 Label::Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1546  : Element(rpToolBar)
1547 {
1548 }
1549 
1550 awt::Size Label::CreateBoundingSize (
1551  const Reference<rendering::XCanvas>& rxCanvas)
1552 {
1553  if (!mpMode)
1554  return awt::Size(0,0);
1555 
1556  geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1557  return awt::Size(
1558  sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1),
1559  sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1560 }
1561 
1562 void Label::SetText (const OUString& rsText)
1563 {
1564  OSL_ASSERT(mpToolBar);
1565  if (!mpMode)
1566  return;
1567 
1568  const bool bRequestLayout (mpMode->maText.GetText().getLength() != rsText.getLength());
1569 
1570  mpMode->maText.SetText(rsText);
1571  // Just use the character count for determining whether a layout is
1572  // necessary. This is an optimization to avoid layouts every time a new
1573  // time value is set on some labels.
1574  if (bRequestLayout)
1575  mpToolBar->RequestLayout();
1576  else
1577  Invalidate(false);
1578 }
1579 
1580 void Label::Paint (
1581  const Reference<rendering::XCanvas>& rxCanvas,
1582  const rendering::ViewState& rViewState)
1583 {
1584  OSL_ASSERT(rxCanvas.is());
1585  if (!mpMode)
1586  return;
1587 
1588  mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox());
1589 }
1590 
1591 bool Label::SetState (const bool, const bool)
1592 {
1593  // For labels there is no mouse over effect.
1594  return Element::SetState(false, false);
1595 }
1596 
1597 } // end of anonymous namespace
1598 
1599 //===== Text ==================================================================
1600 
1601 namespace {
1602 
1603 Text::Text()
1604 {
1605 }
1606 
1607 Text::Text (
1608  const OUString& rsText,
1610  : msText(rsText),
1611  mpFont(rpFont)
1612 {
1613 }
1614 
1615 void Text::SetText (const OUString& rsText)
1616 {
1617  msText = rsText;
1618 }
1619 
1620 const OUString& Text::GetText() const
1621 {
1622  return msText;
1623 }
1624 
1625 const PresenterTheme::SharedFontDescriptor& Text::GetFont() const
1626 {
1627  return mpFont;
1628 }
1629 
1630 void Text::Paint (
1631  const Reference<rendering::XCanvas>& rxCanvas,
1632  const rendering::ViewState& rViewState,
1633  const awt::Rectangle& rBoundingBox)
1634 {
1635  OSL_ASSERT(rxCanvas.is());
1636 
1637  if (msText.isEmpty())
1638  return;
1639  if (!mpFont)
1640  return;
1641 
1642  if ( ! mpFont->mxFont.is())
1643  mpFont->PrepareFont(rxCanvas);
1644  if ( ! mpFont->mxFont.is())
1645  return;
1646 
1647  rendering::StringContext aContext (msText, 0, msText.getLength());
1648 
1649  Reference<rendering::XTextLayout> xLayout (
1650  mpFont->mxFont->createTextLayout(
1651  aContext,
1652  rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1653  0));
1654  geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
1655  const double nTextWidth = aBox.X2 - aBox.X1;
1656  const double nY = rBoundingBox.Y + rBoundingBox.Height - aBox.Y2;
1657  const double nX = rBoundingBox.X + (rBoundingBox.Width - nTextWidth)/2;
1658 
1659  rendering::RenderState aRenderState(
1660  geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
1661  nullptr,
1662  Sequence<double>(4),
1663  rendering::CompositeOperation::SOURCE);
1664  PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
1665  rxCanvas->drawTextLayout(
1666  xLayout,
1667  rViewState,
1668  aRenderState);
1669 }
1670 
1671 geometry::RealRectangle2D Text::GetBoundingBox (const Reference<rendering::XCanvas>& rxCanvas)
1672 {
1673  if (mpFont && !msText.isEmpty())
1674  {
1675  if ( ! mpFont->mxFont.is())
1676  mpFont->PrepareFont(rxCanvas);
1677  if (mpFont->mxFont.is())
1678  {
1679  rendering::StringContext aContext (msText, 0, msText.getLength());
1680  Reference<rendering::XTextLayout> xLayout (
1681  mpFont->mxFont->createTextLayout(
1682  aContext,
1683  rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1684  0));
1685  return xLayout->queryTextBounds();
1686  }
1687  }
1688  return geometry::RealRectangle2D(0,0,0,0);
1689 }
1690 
1691 //===== TimeFormatter =========================================================
1692 
1693 OUString TimeFormatter::FormatTime (const oslDateTime& rTime)
1694 {
1695  OUStringBuffer sText;
1696 
1697  const sal_Int32 nHours (sal::static_int_cast<sal_Int32>(rTime.Hours));
1698  const sal_Int32 nMinutes (sal::static_int_cast<sal_Int32>(rTime.Minutes));
1699  const sal_Int32 nSeconds(sal::static_int_cast<sal_Int32>(rTime.Seconds));
1700  // Hours
1701  sText.append(nHours);
1702 
1703  sText.append(":");
1704 
1705  // Minutes
1706  const OUString sMinutes (OUString::number(nMinutes));
1707  if (sMinutes.getLength() == 1)
1708  sText.append("0");
1709  sText.append(sMinutes);
1710 
1711  // Seconds
1712  sText.append(":");
1713  const OUString sSeconds (OUString::number(nSeconds));
1714  if (sSeconds.getLength() == 1)
1715  sText.append("0");
1716  sText.append(sSeconds);
1717  return sText.makeStringAndClear();
1718 }
1719 
1720 //===== TimeLabel =============================================================
1721 
1722 TimeLabel::TimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1723  : Label(rpToolBar)
1724 {
1725 }
1726 
1727 void SAL_CALL TimeLabel::disposing()
1728 {
1729  PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->RemoveListener(mpListener);
1730  mpListener.reset();
1731 }
1732 
1733 void TimeLabel::ConnectToTimer()
1734 {
1735  mpListener = std::make_shared<Listener>(this);
1736  PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->AddListener(mpListener);
1737 }
1738 
1739 //===== CurrentTimeLabel ======================================================
1740 
1741 ::rtl::Reference<Element> CurrentTimeLabel::Create (
1742  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1743 {
1744  ::rtl::Reference<TimeLabel> pElement(new CurrentTimeLabel(rpToolBar));
1745  pElement->ConnectToTimer();
1746  return pElement;
1747 }
1748 
1749 CurrentTimeLabel::~CurrentTimeLabel()
1750 {
1751 }
1752 
1753 CurrentTimeLabel::CurrentTimeLabel (
1754  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1755  : TimeLabel(rpToolBar)
1756 {
1757 }
1758 
1759 void CurrentTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
1760 {
1761  SetText(TimeFormatter::FormatTime(rCurrentTime));
1762  Invalidate(false);
1763 }
1764 
1765 void CurrentTimeLabel::SetModes (
1766  const SharedElementMode& rpNormalMode,
1767  const SharedElementMode& rpMouseOverMode,
1768  const SharedElementMode& rpSelectedMode,
1769  const SharedElementMode& rpDisabledMode,
1770  const SharedElementMode& rpMouseOverSelectedMode)
1771 {
1772  TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode);
1773  SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1774 }
1775 
1776 //===== PresentationTimeLabel =================================================
1777 
1778 ::rtl::Reference<Element> PresentationTimeLabel::Create (
1779  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1780 {
1781  ::rtl::Reference<TimeLabel> pElement(new PresentationTimeLabel(rpToolBar));
1782  pElement->ConnectToTimer();
1783  return pElement;
1784 }
1785 
1786 PresentationTimeLabel::~PresentationTimeLabel()
1787 {
1788  mpToolBar->GetPresenterController()->SetPresentationTime(nullptr);
1789 }
1790 
1791 PresentationTimeLabel::PresentationTimeLabel (
1792  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1793  : TimeLabel(rpToolBar),
1795 {
1796  restart();
1797  setPauseStatus(false);
1798  TimeValue pauseTime(0,0);
1799  setPauseTimeValue(pauseTime);
1800  mpToolBar->GetPresenterController()->SetPresentationTime(this);
1801 }
1802 
1803 void PresentationTimeLabel::restart()
1804 {
1805  TimeValue pauseTime(0, 0);
1806  setPauseTimeValue(pauseTime);
1807  maStartTimeValue.Seconds = 0;
1808  maStartTimeValue.Nanosec = 0;
1809 }
1810 
1811 bool PresentationTimeLabel::isPaused()
1812 {
1813  return paused;
1814 }
1815 
1816 void PresentationTimeLabel::setPauseStatus(const bool pauseStatus)
1817 {
1818  paused = pauseStatus;
1819 }
1820 
1821 const TimeValue& PresentationTimeLabel::getPauseTimeValue() const
1822 {
1823  return pauseTimeValue;
1824 }
1825 
1826 void PresentationTimeLabel::setPauseTimeValue(const TimeValue pauseTime)
1827 {
1828  //store the time at which the presentation was paused
1829  pauseTimeValue = pauseTime;
1830 }
1831 
1832 void PresentationTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
1833 {
1834  TimeValue aCurrentTimeValue;
1835  if (!osl_getTimeValueFromDateTime(&rCurrentTime, &aCurrentTimeValue))
1836  return;
1837 
1838  if (maStartTimeValue.Seconds==0 && maStartTimeValue.Nanosec==0)
1839  {
1840  // This method is called for the first time. Initialize the
1841  // start time. The start time is rounded to nearest second to
1842  // keep the time updates synchronized with the current time label.
1843  maStartTimeValue = aCurrentTimeValue;
1844  if (maStartTimeValue.Nanosec >= 500000000)
1845  maStartTimeValue.Seconds += 1;
1846  maStartTimeValue.Nanosec = 0;
1847  }
1848 
1849  //The start time value is incremented by the amount of time
1850  //the presentation was paused for in order to continue the
1851  //timer from the same position
1852  if(!isPaused())
1853  {
1854  TimeValue pauseTime = getPauseTimeValue();
1855  if(pauseTime.Seconds != 0 || pauseTime.Nanosec != 0)
1856  {
1857  TimeValue incrementValue(0, 0);
1858  incrementValue.Seconds = aCurrentTimeValue.Seconds - pauseTime.Seconds;
1859  if(pauseTime.Nanosec > aCurrentTimeValue.Nanosec)
1860  {
1861  incrementValue.Nanosec = 1000000000 + aCurrentTimeValue.Nanosec - pauseTime.Nanosec;
1862  }
1863  else
1864  {
1865  incrementValue.Nanosec = aCurrentTimeValue.Nanosec - pauseTime.Nanosec;
1866  }
1867 
1868  maStartTimeValue.Seconds += incrementValue.Seconds;
1869  maStartTimeValue.Nanosec += incrementValue.Nanosec;
1870  if(maStartTimeValue.Nanosec >= 1000000000)
1871  {
1872  maStartTimeValue.Seconds += 1;
1873  maStartTimeValue.Nanosec -= 1000000000;
1874  }
1875 
1876  TimeValue pauseTime_(0, 0);
1877  setPauseTimeValue(pauseTime_);
1878  }
1879  }
1880  else
1881  {
1882  TimeValue pauseTime = getPauseTimeValue();
1883  if(pauseTime.Seconds == 0 && pauseTime.Nanosec == 0)
1884  {
1885  setPauseTimeValue(aCurrentTimeValue);
1886  }
1887  }
1888 
1889  TimeValue aElapsedTimeValue;
1890  aElapsedTimeValue.Seconds = aCurrentTimeValue.Seconds - maStartTimeValue.Seconds;
1891  aElapsedTimeValue.Nanosec = aCurrentTimeValue.Nanosec - maStartTimeValue.Nanosec;
1892 
1893  oslDateTime aElapsedDateTime;
1894  if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue, &aElapsedDateTime) && !isPaused())
1895  {
1896  SetText(TimeFormatter::FormatTime(aElapsedDateTime));
1897  Invalidate(false);
1898  }
1899 }
1900 
1901 void PresentationTimeLabel::SetModes (
1902  const SharedElementMode& rpNormalMode,
1903  const SharedElementMode& rpMouseOverMode,
1904  const SharedElementMode& rpSelectedMode,
1905  const SharedElementMode& rpDisabledMode,
1906  const SharedElementMode& rpMouseOverSelectedMode)
1907 {
1908  TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode);
1909 
1910  oslDateTime aStartDateTime;
1911  if (osl_getDateTimeFromTimeValue(&maStartTimeValue, &aStartDateTime))
1912  {
1913  SetText(TimeFormatter::FormatTime(aStartDateTime));
1914  }
1915 }
1916 
1917 //===== VerticalSeparator =====================================================
1918 
1919 VerticalSeparator::VerticalSeparator (
1920  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1921  : Element(rpToolBar)
1922 {
1923 }
1924 
1925 void VerticalSeparator::Paint (
1926  const Reference<rendering::XCanvas>& rxCanvas,
1927  const rendering::ViewState& rViewState)
1928 {
1929  OSL_ASSERT(rxCanvas.is());
1930 
1931  awt::Rectangle aBBox (GetBoundingBox());
1932 
1933  rendering::RenderState aRenderState(
1934  geometry::AffineMatrix2D(1,0,aBBox.X, 0,1,aBBox.Y),
1935  nullptr,
1936  Sequence<double>(4),
1937  rendering::CompositeOperation::OVER);
1938  if (mpMode)
1939  {
1940  PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
1941  if (pFont)
1942  PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
1943  }
1944 
1945  Reference<rendering::XBitmap> xBitmap(mpToolBar->GetPresenterController()->GetPresenterHelper()->loadBitmap("bitmaps/Separator.png", rxCanvas));
1946  if (!xBitmap.is())
1947  return;
1948 
1949  rxCanvas->drawBitmap(
1950  xBitmap,
1951  rViewState,
1952  aRenderState);
1953 }
1954 
1955 awt::Size VerticalSeparator::CreateBoundingSize (
1956  const Reference<rendering::XCanvas>&)
1957 {
1958  return awt::Size(1,20);
1959 }
1960 
1961 bool VerticalSeparator::IsFilling() const
1962 {
1963  return true;
1964 }
1965 
1966 //===== HorizontalSeparator ===================================================
1967 
1968 HorizontalSeparator::HorizontalSeparator (
1969  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1970  : Element(rpToolBar)
1971 {
1972 }
1973 
1974 void HorizontalSeparator::Paint (
1975  const Reference<rendering::XCanvas>& rxCanvas,
1976  const rendering::ViewState& rViewState)
1977 {
1978  OSL_ASSERT(rxCanvas.is());
1979 
1980  awt::Rectangle aBBox (GetBoundingBox());
1981 
1982  rendering::RenderState aRenderState(
1983  geometry::AffineMatrix2D(1,0,0, 0,1,0),
1984  nullptr,
1985  Sequence<double>(4),
1986  rendering::CompositeOperation::OVER);
1987  if (mpMode)
1988  {
1989  PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
1990  if (pFont)
1991  PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
1992  }
1993 
1994  rxCanvas->fillPolyPolygon(
1995  PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()),
1996  rViewState,
1997  aRenderState);
1998 }
1999 
2000 awt::Size HorizontalSeparator::CreateBoundingSize (
2001  const Reference<rendering::XCanvas>&)
2002 {
2003  return awt::Size(20,1);
2004 }
2005 
2006 bool HorizontalSeparator::IsFilling() const
2007 {
2008  return true;
2009 }
2010 
2011 } // end of anonymous namespace
2012 
2013 } // end of namespace ::sdext::presenter
2014 
2015 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< rendering::XCanvas > mxCanvas
::rtl::Reference< PresenterController > mpPresenterController
URL aURL
std::shared_ptr< FontDescriptor > SharedFontDescriptor
sal_Int32 nIndex
static css::uno::Any GetProperty(const css::uno::Reference< css::beans::XPropertySet > &rxProperties, const OUString &rsKey)
This method wraps a call to getPropertyValue() and returns an empty Any instead of throwing an except...
bool mbIsPressed
Button(WindowType nType)
virtual void SetText(const OUString &rStr) override
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
std::shared_ptr< ElementContainerPart > SharedElementContainerPart
SharedElementMode mpMouseOverSelected
SharedElementMode mpMouseOver
SharedElementMode mpDisabled
awt::Point maLocation
awt::Size maSize
::rtl::Reference< PresenterToolBar > mpToolBar
SharedElementMode mpSelected
static css::uno::Reference< css::beans::XPropertySet > GetNodeProperties(const css::uno::Reference< css::container::XHierarchicalNameAccess > &rxNode, const OUString &rsPathToNode)
Center
SharedBitmapDescriptor mpIcon
TimeValue pauseTimeValue
css::uno::Reference< css::awt::XWindow > mxWindow
SharedElementMode mpMode
std::shared_ptr< PresenterBitmapContainer::BitmapDescriptor > SharedBitmapDescriptor
This class gives access to the configuration.
css::uno::Reference< css::rendering::XCanvas > mxCanvas
static::rtl::Reference< PresenterClockTimer > Instance(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
Reference< drawing::XPresenterHelper > mxPresenterHelper
std::mutex m_aMutex
OUString msText
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
OptionalString sType
bool mbIsEnabled
static SharedFontDescriptor ReadFont(const css::uno::Reference< css::container::XHierarchicalNameAccess > &rxNode, const SharedFontDescriptor &rDefaultFount)
const sal_Int32 gnGapSize(20)
bool paused
virtual sal_Bool SAL_CALL isAnchorOnly() override
virtual void SAL_CALL setCurrentPage(const css::uno::Reference< css::drawing::XDrawPage > &rxSlide) override
css::uno::Any GetConfigurationNode(const OUString &rsPathToNode)
Return a configuration node below the root of the called object.
unsigned char sal_Bool
static bool GetLayoutRTL()
PresenterTheme::SharedFontDescriptor mpFont
css::uno::Reference< css::awt::XWindow > mxWindow
const ::rtl::Reference< PresenterToolBar > & GetPresenterToolBar() const
css::uno::Reference< css::drawing::framework::XResourceId > mxViewId
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
std::shared_ptr< PresenterClockTimer::Listener > mpListener
::rtl::Reference< PresenterToolBar > mpToolBar
SharedElementMode mpNormal
static css::uno::Reference< css::rendering::XPolyPolygon2D > CreatePolygon(const css::awt::Rectangle &rBox, const css::uno::Reference< css::rendering::XGraphicDevice > &rxDevice)
virtual void SAL_CALL disposing() override
::rtl::Reference< TimeLabel > mxLabel
bool mbIsListenerRegistered
css::uno::Reference< css::rendering::XCanvas > mxCanvas
Context & operator=(const Context &)=delete
Reference< XDispatch > xDispatch
rtl::Reference< PresenterController > mpPresenterController
css::uno::Reference< css::rendering::XCanvas > mxCanvas
Text maText
OUString msAction
css::uno::Reference< css::drawing::framework::XPane > mxPane
static std::shared_ptr< BitmapDescriptor > LoadBitmap(const css::uno::Reference< css::container::XHierarchicalNameAccess > &rxNode, const OUString &rsPathToBitmapNode, const css::uno::Reference< css::drawing::XPresenterHelper > &rxPresenterHelper, const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const std::shared_ptr< BitmapDescriptor > &rpDefaultBitmap)
cppu::WeakComponentImplHelper< css::awt::XWindowListener, css::awt::XPaintListener, css::awt::XMouseListener, css::awt::XMouseMotionListener, css::drawing::XDrawView > PresenterToolBarInterfaceBase
bool bIsEnabled
PresenterToolBar(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::awt::XWindow > &rxWindow, const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const ::rtl::Reference< PresenterController > &rpPresenterController, const Anchor eAnchor)
static void SetDeviceColor(css::rendering::RenderState &rRenderState, const css::util::Color aColor)
virtual css::uno::Reference< css::drawing::framework::XResourceId > SAL_CALL getResourceId() override
TimeValue maStartTimeValue
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
virtual void SAL_CALL windowPaint(const css::awt::PaintEvent &rEvent) override
cppu::WeakComponentImplHelper< css::awt::XPaintListener, css::drawing::framework::XView, css::drawing::XDrawView > PresenterToolBarViewInterfaceBase
bool mbIsSelected
Layout
UpdateState
Left
virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL getCurrentPage() override
bool mbIsOver
bool m_bDetectedRangeSegmentation false