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