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),
1134  mbIsSelected(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),
1391  mbIsListenerRegistered(false)
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  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxNormal.X2 - aTextBBoxNormal.X1));
1455  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOver.X2 - aTextBBoxMouseOver.X1));
1456  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxSelected.X2 - aTextBBoxSelected.X1));
1457  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxDisabled.X2 - aTextBBoxDisabled.X1));
1458  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOverSelected.X2 - aTextBBoxMouseOverSelected.X1));
1459 
1460  sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1461  Reference<rendering::XBitmap> xBitmap;
1462  if (mpMode->mpIcon)
1463  xBitmap = mpMode->mpIcon->GetNormalBitmap();
1464  if (xBitmap.is())
1465  {
1466  const sal_Int32 nGap (5);
1467  geometry::IntegerSize2D aSize (xBitmap->getSize());
1468  return awt::Size(
1469  ::std::max(aSize.Width, *std::max_element(widths.begin(), widths.end())),
1470  aSize.Height + nGap + nTextHeight);
1471  }
1472  else
1473  {
1474  return awt::Size(*std::max_element(widths.begin(), widths.end()), nTextHeight);
1475  }
1476 }
1477 
1478 void Button::PaintIcon (
1479  const Reference<rendering::XCanvas>& rxCanvas,
1480  const sal_Int32 nTextHeight,
1481  const rendering::ViewState& rViewState)
1482 {
1483  if (!mpMode)
1484  return;
1485 
1486  Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetBitmap(GetMode()));
1487  if (!xBitmap.is())
1488  return;
1489 
1492  const sal_Int32 nX (maLocation.X
1493  + (maSize.Width-xBitmap->getSize().Width) / 2);
1494  const sal_Int32 nY (maLocation.Y
1495  + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
1496  const rendering::RenderState aRenderState(
1497  geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
1498  nullptr,
1499  Sequence<double>(4),
1500  rendering::CompositeOperation::OVER);
1501  rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
1502  }
1503  else {
1504  const sal_Int32 nX (maLocation.X
1505  + (maSize.Width+xBitmap->getSize().Width) / 2);
1506  const sal_Int32 nY (maLocation.Y
1507  + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
1508  const rendering::RenderState aRenderState(
1509  geometry::AffineMatrix2D(-1,0,nX, 0,1,nY),
1510  nullptr,
1511  Sequence<double>(4),
1512  rendering::CompositeOperation::OVER);
1513  rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
1514  }
1515 }
1516 
1517 PresenterBitmapDescriptor::Mode Button::GetMode() const
1518 {
1519  if ( ! IsEnabled())
1521  else if (mbIsPressed)
1523  else if (mbIsOver)
1525  else
1527 }
1528 
1529 //----- lang::XEventListener --------------------------------------------------
1530 
1531 void SAL_CALL Button::disposing (const css::lang::EventObject& rEvent)
1532 {
1533  mbIsListenerRegistered = false;
1534  Element::disposing(rEvent);
1535 }
1536 
1537 } // end of anonymous namespace
1538 
1539 //===== PresenterToolBar::Label ===============================================
1540 
1541 namespace {
1542 
1543 Label::Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1544  : Element(rpToolBar)
1545 {
1546 }
1547 
1548 awt::Size Label::CreateBoundingSize (
1549  const Reference<rendering::XCanvas>& rxCanvas)
1550 {
1551  if (!mpMode)
1552  return awt::Size(0,0);
1553 
1554  geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1555  return awt::Size(
1556  sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1),
1557  sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1558 }
1559 
1560 void Label::SetText (const OUString& rsText)
1561 {
1562  OSL_ASSERT(mpToolBar);
1563  if (!mpMode)
1564  return;
1565 
1566  const bool bRequestLayout (mpMode->maText.GetText().getLength() != rsText.getLength());
1567 
1568  mpMode->maText.SetText(rsText);
1569  // Just use the character count for determining whether a layout is
1570  // necessary. This is an optimization to avoid layouts every time a new
1571  // time value is set on some labels.
1572  if (bRequestLayout)
1573  mpToolBar->RequestLayout();
1574  else
1575  Invalidate(false);
1576 }
1577 
1578 void Label::Paint (
1579  const Reference<rendering::XCanvas>& rxCanvas,
1580  const rendering::ViewState& rViewState)
1581 {
1582  OSL_ASSERT(rxCanvas.is());
1583  if (!mpMode)
1584  return;
1585 
1586  mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox());
1587 }
1588 
1589 bool Label::SetState (const bool, const bool)
1590 {
1591  // For labels there is no mouse over effect.
1592  return Element::SetState(false, false);
1593 }
1594 
1595 } // end of anonymous namespace
1596 
1597 //===== Text ==================================================================
1598 
1599 namespace {
1600 
1601 Text::Text()
1602 {
1603 }
1604 
1605 Text::Text (
1606  const OUString& rsText,
1608  : msText(rsText),
1609  mpFont(rpFont)
1610 {
1611 }
1612 
1613 void Text::SetText (const OUString& rsText)
1614 {
1615  msText = rsText;
1616 }
1617 
1618 const OUString& Text::GetText() const
1619 {
1620  return msText;
1621 }
1622 
1623 const PresenterTheme::SharedFontDescriptor& Text::GetFont() const
1624 {
1625  return mpFont;
1626 }
1627 
1628 void Text::Paint (
1629  const Reference<rendering::XCanvas>& rxCanvas,
1630  const rendering::ViewState& rViewState,
1631  const awt::Rectangle& rBoundingBox)
1632 {
1633  OSL_ASSERT(rxCanvas.is());
1634 
1635  if (msText.isEmpty())
1636  return;
1637  if (!mpFont)
1638  return;
1639 
1640  if ( ! mpFont->mxFont.is())
1641  mpFont->PrepareFont(rxCanvas);
1642  if ( ! mpFont->mxFont.is())
1643  return;
1644 
1645  rendering::StringContext aContext (msText, 0, msText.getLength());
1646 
1647  Reference<rendering::XTextLayout> xLayout (
1648  mpFont->mxFont->createTextLayout(
1649  aContext,
1650  rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1651  0));
1652  geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
1653  const double nTextWidth = aBox.X2 - aBox.X1;
1654  const double nY = rBoundingBox.Y + rBoundingBox.Height - aBox.Y2;
1655  const double nX = rBoundingBox.X + (rBoundingBox.Width - nTextWidth)/2;
1656 
1657  rendering::RenderState aRenderState(
1658  geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
1659  nullptr,
1660  Sequence<double>(4),
1661  rendering::CompositeOperation::SOURCE);
1662  PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
1663  rxCanvas->drawTextLayout(
1664  xLayout,
1665  rViewState,
1666  aRenderState);
1667 }
1668 
1669 geometry::RealRectangle2D Text::GetBoundingBox (const Reference<rendering::XCanvas>& rxCanvas)
1670 {
1671  if (mpFont && !msText.isEmpty())
1672  {
1673  if ( ! mpFont->mxFont.is())
1674  mpFont->PrepareFont(rxCanvas);
1675  if (mpFont->mxFont.is())
1676  {
1677  rendering::StringContext aContext (msText, 0, msText.getLength());
1678  Reference<rendering::XTextLayout> xLayout (
1679  mpFont->mxFont->createTextLayout(
1680  aContext,
1681  rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1682  0));
1683  return xLayout->queryTextBounds();
1684  }
1685  }
1686  return geometry::RealRectangle2D(0,0,0,0);
1687 }
1688 
1689 //===== TimeFormatter =========================================================
1690 
1691 OUString TimeFormatter::FormatTime (const oslDateTime& rTime)
1692 {
1693  OUStringBuffer sText;
1694 
1695  const sal_Int32 nHours (sal::static_int_cast<sal_Int32>(rTime.Hours));
1696  const sal_Int32 nMinutes (sal::static_int_cast<sal_Int32>(rTime.Minutes));
1697  const sal_Int32 nSeconds(sal::static_int_cast<sal_Int32>(rTime.Seconds));
1698  // Hours
1699  sText.append(nHours);
1700 
1701  sText.append(":");
1702 
1703  // Minutes
1704  const OUString sMinutes (OUString::number(nMinutes));
1705  if (sMinutes.getLength() == 1)
1706  sText.append("0");
1707  sText.append(sMinutes);
1708 
1709  // Seconds
1710  sText.append(":");
1711  const OUString sSeconds (OUString::number(nSeconds));
1712  if (sSeconds.getLength() == 1)
1713  sText.append("0");
1714  sText.append(sSeconds);
1715  return sText.makeStringAndClear();
1716 }
1717 
1718 //===== TimeLabel =============================================================
1719 
1720 TimeLabel::TimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1721  : Label(rpToolBar)
1722 {
1723 }
1724 
1725 void SAL_CALL TimeLabel::disposing()
1726 {
1727  PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->RemoveListener(mpListener);
1728  mpListener.reset();
1729 }
1730 
1731 void TimeLabel::ConnectToTimer()
1732 {
1733  mpListener = std::make_shared<Listener>(this);
1734  PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->AddListener(mpListener);
1735 }
1736 
1737 //===== CurrentTimeLabel ======================================================
1738 
1739 ::rtl::Reference<Element> CurrentTimeLabel::Create (
1740  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1741 {
1742  ::rtl::Reference<TimeLabel> pElement(new CurrentTimeLabel(rpToolBar));
1743  pElement->ConnectToTimer();
1744  return pElement;
1745 }
1746 
1747 CurrentTimeLabel::~CurrentTimeLabel()
1748 {
1749 }
1750 
1751 CurrentTimeLabel::CurrentTimeLabel (
1752  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1753  : TimeLabel(rpToolBar)
1754 {
1755 }
1756 
1757 void CurrentTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
1758 {
1759  SetText(TimeFormatter::FormatTime(rCurrentTime));
1760  Invalidate(false);
1761 }
1762 
1763 void CurrentTimeLabel::SetModes (
1764  const SharedElementMode& rpNormalMode,
1765  const SharedElementMode& rpMouseOverMode,
1766  const SharedElementMode& rpSelectedMode,
1767  const SharedElementMode& rpDisabledMode,
1768  const SharedElementMode& rpMouseOverSelectedMode)
1769 {
1770  TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode);
1771  SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1772 }
1773 
1774 //===== PresentationTimeLabel =================================================
1775 
1776 ::rtl::Reference<Element> PresentationTimeLabel::Create (
1777  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1778 {
1779  ::rtl::Reference<TimeLabel> pElement(new PresentationTimeLabel(rpToolBar));
1780  pElement->ConnectToTimer();
1781  return pElement;
1782 }
1783 
1784 PresentationTimeLabel::~PresentationTimeLabel()
1785 {
1786  mpToolBar->GetPresenterController()->SetPresentationTime(nullptr);
1787 }
1788 
1789 PresentationTimeLabel::PresentationTimeLabel (
1790  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1791  : TimeLabel(rpToolBar),
1793 {
1794  restart();
1795  setPauseStatus(false);
1796  TimeValue pauseTime(0,0);
1797  setPauseTimeValue(pauseTime);
1798  mpToolBar->GetPresenterController()->SetPresentationTime(this);
1799 }
1800 
1801 void PresentationTimeLabel::restart()
1802 {
1803  TimeValue pauseTime(0, 0);
1804  setPauseTimeValue(pauseTime);
1805  maStartTimeValue.Seconds = 0;
1806  maStartTimeValue.Nanosec = 0;
1807 }
1808 
1809 bool PresentationTimeLabel::isPaused()
1810 {
1811  return paused;
1812 }
1813 
1814 void PresentationTimeLabel::setPauseStatus(const bool pauseStatus)
1815 {
1816  paused = pauseStatus;
1817 }
1818 
1819 const TimeValue& PresentationTimeLabel::getPauseTimeValue() const
1820 {
1821  return pauseTimeValue;
1822 }
1823 
1824 void PresentationTimeLabel::setPauseTimeValue(const TimeValue pauseTime)
1825 {
1826  //store the time at which the presentation was paused
1827  pauseTimeValue = pauseTime;
1828 }
1829 
1830 void PresentationTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
1831 {
1832  TimeValue aCurrentTimeValue;
1833  if (!osl_getTimeValueFromDateTime(&rCurrentTime, &aCurrentTimeValue))
1834  return;
1835 
1836  if (maStartTimeValue.Seconds==0 && maStartTimeValue.Nanosec==0)
1837  {
1838  // This method is called for the first time. Initialize the
1839  // start time. The start time is rounded to nearest second to
1840  // keep the time updates synchronized with the current time label.
1841  maStartTimeValue = aCurrentTimeValue;
1842  if (maStartTimeValue.Nanosec >= 500000000)
1843  maStartTimeValue.Seconds += 1;
1844  maStartTimeValue.Nanosec = 0;
1845  }
1846 
1847  //The start time value is incremented by the amount of time
1848  //the presentation was paused for in order to continue the
1849  //timer from the same position
1850  if(!isPaused())
1851  {
1852  TimeValue pauseTime = getPauseTimeValue();
1853  if(pauseTime.Seconds != 0 || pauseTime.Nanosec != 0)
1854  {
1855  TimeValue incrementValue(0, 0);
1856  incrementValue.Seconds = aCurrentTimeValue.Seconds - pauseTime.Seconds;
1857  if(pauseTime.Nanosec > aCurrentTimeValue.Nanosec)
1858  {
1859  incrementValue.Nanosec = 1000000000 + aCurrentTimeValue.Nanosec - pauseTime.Nanosec;
1860  }
1861  else
1862  {
1863  incrementValue.Nanosec = aCurrentTimeValue.Nanosec - pauseTime.Nanosec;
1864  }
1865 
1866  maStartTimeValue.Seconds += incrementValue.Seconds;
1867  maStartTimeValue.Nanosec += incrementValue.Nanosec;
1868  if(maStartTimeValue.Nanosec >= 1000000000)
1869  {
1870  maStartTimeValue.Seconds += 1;
1871  maStartTimeValue.Nanosec -= 1000000000;
1872  }
1873 
1874  TimeValue pauseTime_(0, 0);
1875  setPauseTimeValue(pauseTime_);
1876  }
1877  }
1878  else
1879  {
1880  TimeValue pauseTime = getPauseTimeValue();
1881  if(pauseTime.Seconds == 0 && pauseTime.Nanosec == 0)
1882  {
1883  setPauseTimeValue(aCurrentTimeValue);
1884  }
1885  }
1886 
1887  TimeValue aElapsedTimeValue;
1888  aElapsedTimeValue.Seconds = aCurrentTimeValue.Seconds - maStartTimeValue.Seconds;
1889  aElapsedTimeValue.Nanosec = aCurrentTimeValue.Nanosec - maStartTimeValue.Nanosec;
1890 
1891  oslDateTime aElapsedDateTime;
1892  if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue, &aElapsedDateTime) && !isPaused())
1893  {
1894  SetText(TimeFormatter::FormatTime(aElapsedDateTime));
1895  Invalidate(false);
1896  }
1897 }
1898 
1899 void PresentationTimeLabel::SetModes (
1900  const SharedElementMode& rpNormalMode,
1901  const SharedElementMode& rpMouseOverMode,
1902  const SharedElementMode& rpSelectedMode,
1903  const SharedElementMode& rpDisabledMode,
1904  const SharedElementMode& rpMouseOverSelectedMode)
1905 {
1906  TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode);
1907 
1908  oslDateTime aStartDateTime;
1909  if (osl_getDateTimeFromTimeValue(&maStartTimeValue, &aStartDateTime))
1910  {
1911  SetText(TimeFormatter::FormatTime(aStartDateTime));
1912  }
1913 }
1914 
1915 //===== VerticalSeparator =====================================================
1916 
1917 VerticalSeparator::VerticalSeparator (
1918  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1919  : Element(rpToolBar)
1920 {
1921 }
1922 
1923 void VerticalSeparator::Paint (
1924  const Reference<rendering::XCanvas>& rxCanvas,
1925  const rendering::ViewState& rViewState)
1926 {
1927  OSL_ASSERT(rxCanvas.is());
1928 
1929  awt::Rectangle aBBox (GetBoundingBox());
1930 
1931  rendering::RenderState aRenderState(
1932  geometry::AffineMatrix2D(1,0,aBBox.X, 0,1,aBBox.Y),
1933  nullptr,
1934  Sequence<double>(4),
1935  rendering::CompositeOperation::OVER);
1936  if (mpMode)
1937  {
1938  PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
1939  if (pFont)
1940  PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
1941  }
1942 
1943  Reference<rendering::XBitmap> xBitmap(mpToolBar->GetPresenterController()->GetPresenterHelper()->loadBitmap("bitmaps/Separator.png", rxCanvas));
1944  if (!xBitmap.is())
1945  return;
1946 
1947  rxCanvas->drawBitmap(
1948  xBitmap,
1949  rViewState,
1950  aRenderState);
1951 }
1952 
1953 awt::Size VerticalSeparator::CreateBoundingSize (
1954  const Reference<rendering::XCanvas>&)
1955 {
1956  return awt::Size(1,20);
1957 }
1958 
1959 bool VerticalSeparator::IsFilling() const
1960 {
1961  return true;
1962 }
1963 
1964 //===== HorizontalSeparator ===================================================
1965 
1966 HorizontalSeparator::HorizontalSeparator (
1967  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1968  : Element(rpToolBar)
1969 {
1970 }
1971 
1972 void HorizontalSeparator::Paint (
1973  const Reference<rendering::XCanvas>& rxCanvas,
1974  const rendering::ViewState& rViewState)
1975 {
1976  OSL_ASSERT(rxCanvas.is());
1977 
1978  awt::Rectangle aBBox (GetBoundingBox());
1979 
1980  rendering::RenderState aRenderState(
1981  geometry::AffineMatrix2D(1,0,0, 0,1,0),
1982  nullptr,
1983  Sequence<double>(4),
1984  rendering::CompositeOperation::OVER);
1985  if (mpMode)
1986  {
1987  PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
1988  if (pFont)
1989  PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
1990  }
1991 
1992  rxCanvas->fillPolyPolygon(
1993  PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()),
1994  rViewState,
1995  aRenderState);
1996 }
1997 
1998 awt::Size HorizontalSeparator::CreateBoundingSize (
1999  const Reference<rendering::XCanvas>&)
2000 {
2001  return awt::Size(20,1);
2002 }
2003 
2004 bool HorizontalSeparator::IsFilling() const
2005 {
2006  return true;
2007 }
2008 
2009 } // end of anonymous namespace
2010 
2011 } // end of namespace ::sdext::presenter
2012 
2013 /* 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)
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