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  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  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  {
427  Reference<lang::XComponent> xComponent (
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  // Done to introduce gap between the end of the toolbar and the last button
722  aTotalSize.Width += gnGapSize/2;
723 
724  // Calculate the minimal size so that the window size of the tool bar
725  // can be adapted accordingly.
726  maMinimalSize = aTotalSize;
727  maMinimalSize.Width += nTotalHorizontalGap;
728 
729  // Calculate the gaps between elements.
730  double nGapWidth (0);
731  if (nGapCount > 0)
732  {
733  if (aTotalSize.Width + nTotalHorizontalGap > aWindowBox.Width)
734  nTotalHorizontalGap = aWindowBox.Width - aTotalSize.Width;
735  nGapWidth = nTotalHorizontalGap / nGapCount;
736  }
737 
738  // Determine the location of the left edge.
739  double nX (0);
740  switch (meAnchor)
741  {
742  case Left : nX = 0; break;
743  case Center: nX = (aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap) / 2; break;
744  }
745 
746  // Place the parts.
747  double nY ((aWindowBox.Height - aTotalSize.Height) / 2);
748  bIsHorizontal = true;
749 
750  /* push front or back ? ... */
753  nIndex = 0;
754  for (const auto& rxPart : maElementContainer)
755  {
756  geometry::RealRectangle2D aBoundingBox(
757  nX, nY,
758  nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height);
759 
760  // Add space for gaps between elements.
761  if (rxPart->size() > 1 && bIsHorizontal)
762  aBoundingBox.X2 += (rxPart->size() - 1) * nGapWidth;
763 
764  LayoutPart(rxCanvas, rxPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal);
765  bIsHorizontal = !bIsHorizontal;
766  nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth;
767  ++nIndex;
768  }
769  }
770  else {
771  ElementContainer::iterator iPart;
772  ElementContainer::iterator iBegin (maElementContainer.begin());
773  for (iPart=maElementContainer.end()-1, nIndex=2; iPart!=iBegin-1; --iPart, --nIndex)
774  {
775  geometry::RealRectangle2D aBoundingBox(
776  nX, nY,
777  nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height);
778 
779  // Add space for gaps between elements.
780  if ((*iPart)->size() > 1)
781  if (bIsHorizontal)
782  aBoundingBox.X2 += ((*iPart)->size()-1) * nGapWidth;
783 
784  LayoutPart(rxCanvas, *iPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal);
785  bIsHorizontal = !bIsHorizontal;
786  nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth;
787  }
788  }
789 
790  // The whole window has to be repainted.
791  std::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager());
792  if (!xManager)
793  return;
794  xManager->Invalidate(mxWindow);
795 }
796 
797 geometry::RealSize2D PresenterToolBar::CalculatePartSize (
798  const Reference<rendering::XCanvas>& rxCanvas,
799  const SharedElementContainerPart& rpPart,
800  const bool bIsHorizontal)
801 {
802  geometry::RealSize2D aTotalSize (0,0);
803 
804  if (mxWindow.is())
805  {
806  // Calculate the summed width of all elements.
807  for (const auto& rxElement : *rpPart)
808  {
809  if (!rxElement)
810  continue;
811 
812  const awt::Size aBSize (rxElement->GetBoundingSize(rxCanvas));
813  if (bIsHorizontal)
814  {
815  aTotalSize.Width += aBSize.Width;
816  if (aBSize.Height > aTotalSize.Height)
817  aTotalSize.Height = aBSize.Height;
818  }
819  else
820  {
821  aTotalSize.Height += aBSize.Height;
822  if (aBSize.Width > aTotalSize.Width)
823  aTotalSize.Width = aBSize.Width;
824  }
825  }
826  }
827  return aTotalSize;
828 }
829 
830 void PresenterToolBar::LayoutPart (
831  const Reference<rendering::XCanvas>& rxCanvas,
832  const SharedElementContainerPart& rpPart,
833  const geometry::RealRectangle2D& rBoundingBox,
834  const geometry::RealSize2D& rPartSize,
835  const bool bIsHorizontal)
836 {
837  double nGap (0);
838  if (rpPart->size() > 1)
839  {
840  if (bIsHorizontal)
841  nGap = (rBoundingBox.X2 - rBoundingBox.X1 - rPartSize.Width) / (rpPart->size()-1);
842  else
843  nGap = (rBoundingBox.Y2 - rBoundingBox.Y1 - rPartSize.Height) / (rpPart->size()-1);
844  }
845 
846  // Place the elements.
847  double nX (rBoundingBox.X1);
848  double nY (rBoundingBox.Y1);
849 
852  for (auto& rxElement : *rpPart)
853  {
854  if (!rxElement)
855  continue;
856 
857  const awt::Size aElementSize (rxElement->GetBoundingSize(rxCanvas));
858  if (bIsHorizontal)
859  {
860  if (rxElement->IsFilling())
861  {
862  nY = rBoundingBox.Y1;
863  rxElement->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1));
864  }
865  else
866  nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2;
867  rxElement->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
868  nX += aElementSize.Width + nGap;
869  }
870  else
871  {
872  if (rxElement->IsFilling())
873  {
874  nX = rBoundingBox.X1;
875  rxElement->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aElementSize.Height));
876  }
877  else
878  nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aElementSize.Width) / 2;
879  rxElement->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
880  nY += aElementSize.Height + nGap;
881  }
882  }
883  }
884  else {
885  ElementContainerPart::const_iterator iElement;
886  ElementContainerPart::const_iterator iBegin (rpPart->begin());
887 
888  for (iElement=rpPart->end()-1; iElement!=iBegin-1; --iElement)
889  {
890  if (iElement->get() == nullptr)
891  continue;
892 
893  const awt::Size aElementSize ((*iElement)->GetBoundingSize(rxCanvas));
894  if (bIsHorizontal)
895  {
896  if ((*iElement)->IsFilling())
897  {
898  nY = rBoundingBox.Y1;
899  (*iElement)->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1));
900  }
901  else
902  nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2;
903  (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
904  nX += aElementSize.Width + nGap;
905  }
906  else
907  {
908  // reverse presentation time with current time
909  if (iElement==iBegin){
910  iElement=iBegin+2;
911  }
912  else if (iElement==iBegin+2){
913  iElement=iBegin;
914  }
915  const awt::Size aNewElementSize ((*iElement)->GetBoundingSize(rxCanvas));
916  if ((*iElement)->IsFilling())
917  {
918  nX = rBoundingBox.X1;
919  (*iElement)->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aNewElementSize.Height));
920  }
921  else
922  nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aNewElementSize.Width) / 2;
923  (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
924  nY += aNewElementSize.Height + nGap;
925 
926  // return the index as it was before the reversing
927  if (iElement==iBegin)
928  iElement=iBegin+2;
929  else if (iElement==iBegin+2)
930  iElement=iBegin;
931  }
932  }
933  }
934 }
935 
936 void PresenterToolBar::Paint (
937  const awt::Rectangle& rUpdateBox,
938  const rendering::ViewState& rViewState)
939 {
940  OSL_ASSERT(mxCanvas.is());
941 
942  for (const auto& rxPart : maElementContainer)
943  {
944  for (auto& rxElement : *rxPart)
945  {
946  if (rxElement)
947  {
948  if ( ! rxElement->IsOutside(rUpdateBox))
949  rxElement->Paint(mxCanvas, rViewState);
950  }
951  }
952  }
953 }
954 
955 void PresenterToolBar::UpdateSlideNumber()
956 {
957  if( mxSlideShowController.is() )
958  {
959  for (const auto& rxPart : maElementContainer)
960  {
961  for (auto& rxElement : *rxPart)
962  {
963  if (rxElement)
964  rxElement->CurrentSlideHasChanged();
965  }
966  }
967  }
968 }
969 
970 void PresenterToolBar::CheckMouseOver (
971  const css::awt::MouseEvent& rEvent,
972  const bool bOverWindow,
973  const bool bMouseDown)
974 {
975  css::awt::MouseEvent rTemp =rEvent;
977  awt::Rectangle aWindowBox = mxWindow->getPosSize();
978  rTemp.X=aWindowBox.Width-rTemp.X;
979  }
980  for (const auto& rxPart : maElementContainer)
981  {
982  for (auto& rxElement : *rxPart)
983  {
984  if (!rxElement)
985  continue;
986 
987  awt::Rectangle aBox (rxElement->GetBoundingBox());
988  const bool bIsOver = bOverWindow
989  && aBox.X <= rTemp.X
990  && aBox.Width+aBox.X-1 >= rTemp.X
991  && aBox.Y <= rTemp.Y
992  && aBox.Height+aBox.Y-1 >= rTemp.Y;
993  rxElement->SetState(
994  bIsOver,
995  bIsOver && rTemp.Buttons!=0 && bMouseDown && rTemp.ClickCount>0);
996  }
997  }
998 }
999 
1000 void PresenterToolBar::ThrowIfDisposed() const
1001 {
1002  if (rBHelper.bDisposed || rBHelper.bInDispose)
1003  {
1004  throw lang::DisposedException (
1005  "PresenterToolBar has already been disposed",
1006  const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1007  }
1008 }
1009 
1010 //===== PresenterToolBarView ==================================================
1011 
1012 PresenterToolBarView::PresenterToolBarView (
1013  const Reference<XComponentContext>& rxContext,
1014  const Reference<XResourceId>& rxViewId,
1015  const Reference<frame::XController>& rxController,
1016  const ::rtl::Reference<PresenterController>& rpPresenterController)
1018  mxPane(),
1019  mxViewId(rxViewId),
1020  mxWindow(),
1021  mxCanvas(),
1022  mpPresenterController(rpPresenterController),
1023  mpToolBar()
1024 {
1025  try
1026  {
1027  Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
1028  Reference<XConfigurationController> xCC(xCM->getConfigurationController(),UNO_SET_THROW);
1029  mxPane.set(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
1030 
1031  mxWindow = mxPane->getWindow();
1032  mxCanvas = mxPane->getCanvas();
1033 
1035  rxContext,
1036  mxWindow,
1037  mxCanvas,
1038  rpPresenterController,
1040  mpToolBar->Initialize("PresenterScreenSettings/ToolBars/ToolBar");
1041 
1042  if (mxWindow.is())
1043  {
1044  mxWindow->addPaintListener(this);
1045 
1046  Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
1047  if (xPeer.is())
1048  xPeer->setBackground(util::Color(0xff000000));
1049 
1050  mxWindow->setVisible(true);
1051  }
1052  }
1053  catch (RuntimeException&)
1054  {
1055  mxViewId = nullptr;
1056  throw;
1057  }
1058 }
1059 
1061 {
1062 }
1063 
1065 {
1066  Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
1067  mpToolBar = nullptr;
1068  if (xComponent.is())
1069  xComponent->dispose();
1070 
1071  if (mxWindow.is())
1072  {
1073  mxWindow->removePaintListener(this);
1074  mxWindow = nullptr;
1075  }
1076  mxCanvas = nullptr;
1077  mxViewId = nullptr;
1078  mxPane = nullptr;
1079  mpPresenterController = nullptr;
1080 }
1081 
1082 const ::rtl::Reference<PresenterToolBar>& PresenterToolBarView::GetPresenterToolBar() const
1083 {
1084  return mpToolBar;
1085 }
1086 
1087 //----- XPaintListener --------------------------------------------------------
1088 
1089 void SAL_CALL PresenterToolBarView::windowPaint (const css::awt::PaintEvent& rEvent)
1090 {
1091  awt::Rectangle aWindowBox (mxWindow->getPosSize());
1092  mpPresenterController->GetCanvasHelper()->Paint(
1093  mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
1094  mxCanvas,
1095  rEvent.UpdateRect,
1096  awt::Rectangle(0,0,aWindowBox.Width, aWindowBox.Height),
1097  awt::Rectangle());
1098 }
1099 
1100 //----- lang::XEventListener -------------------------------------------------
1101 
1102 void SAL_CALL PresenterToolBarView::disposing (const lang::EventObject& rEventObject)
1103 {
1104  if (rEventObject.Source == mxWindow)
1105  mxWindow = nullptr;
1106 }
1107 
1108 //----- XResourceId -----------------------------------------------------------
1109 
1110 Reference<XResourceId> SAL_CALL PresenterToolBarView::getResourceId()
1111 {
1112  return mxViewId;
1113 }
1114 
1116 {
1117  return false;
1118 }
1119 
1120 //----- XDrawView -------------------------------------------------------------
1121 
1123 {
1124  Reference<drawing::XDrawView> xToolBar (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
1125  if (xToolBar.is())
1126  xToolBar->setCurrentPage(rxSlide);
1127 }
1128 
1130 {
1131  return nullptr;
1132 }
1133 
1134 //===== PresenterToolBar::Element =============================================
1135 
1136 namespace {
1137 
1138 Element::Element (
1139  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1140  : ElementInterfaceBase(m_aMutex),
1141  mpToolBar(rpToolBar),
1142  maLocation(),
1143  maSize(),
1144  mpNormal(),
1145  mpMouseOver(),
1146  mpSelected(),
1147  mpDisabled(),
1149  mpMode(),
1150  mbIsOver(false),
1151  mbIsPressed(false),
1152  mbIsSelected(false),
1153  mbIsEnabled(true)
1154 {
1155  if (mpToolBar)
1156  {
1157  OSL_ASSERT(mpToolBar->GetPresenterController().is());
1158  OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1159  }
1160 }
1161 
1162 void Element::SetModes (
1163  const SharedElementMode& rpNormalMode,
1164  const SharedElementMode& rpMouseOverMode,
1165  const SharedElementMode& rpSelectedMode,
1166  const SharedElementMode& rpDisabledMode,
1167  const SharedElementMode& rpMouseOverSelectedMode)
1168 {
1169  mpNormal = rpNormalMode;
1170  mpMouseOver = rpMouseOverMode;
1171  mpSelected = rpSelectedMode;
1172  mpDisabled = rpDisabledMode;
1173  mpMouseOverSelected = rpMouseOverSelectedMode;
1174  mpMode = rpNormalMode;
1175 }
1176 
1177 void Element::disposing()
1178 {
1179 }
1180 
1181 awt::Size const & Element::GetBoundingSize (
1182  const Reference<rendering::XCanvas>& rxCanvas)
1183 {
1184  maSize = CreateBoundingSize(rxCanvas);
1185  return maSize;
1186 }
1187 
1188 awt::Rectangle Element::GetBoundingBox() const
1189 {
1190  return awt::Rectangle(maLocation.X,maLocation.Y, maSize.Width, maSize.Height);
1191 }
1192 
1193 void Element::CurrentSlideHasChanged()
1194 {
1195  UpdateState();
1196 }
1197 
1198 void Element::SetLocation (const awt::Point& rLocation)
1199 {
1200  maLocation = rLocation;
1201 }
1202 
1203 void Element::SetSize (const geometry::RealSize2D& rSize)
1204 {
1205  maSize = awt::Size(sal_Int32(0.5+rSize.Width), sal_Int32(0.5+rSize.Height));
1206 }
1207 
1208 bool Element::SetState (
1209  const bool bIsOver,
1210  const bool bIsPressed)
1211 {
1212  bool bModified (mbIsOver != bIsOver || mbIsPressed != bIsPressed);
1213  bool bClicked (mbIsPressed && bIsOver && ! bIsPressed);
1214 
1215  mbIsOver = bIsOver;
1216  mbIsPressed = bIsPressed;
1217 
1218  // When the element is disabled then ignore mouse over or selection.
1219  // When the element is selected then ignore mouse over.
1220  if ( ! mbIsEnabled)
1221  mpMode = mpDisabled;
1222  else if (mbIsSelected && mbIsOver)
1224  else if (mbIsSelected)
1225  mpMode = mpSelected;
1226  else if (mbIsOver)
1227  mpMode = mpMouseOver;
1228  else
1229  mpMode = mpNormal;
1230 
1231  if (bClicked && mbIsEnabled)
1232  {
1233  if (mpMode)
1234  {
1235  do
1236  {
1237  if (mpMode->msAction.isEmpty())
1238  break;
1239 
1240  if (!mpToolBar)
1241  break;
1242 
1243  if (!mpToolBar->GetPresenterController())
1244  break;
1245 
1246  mpToolBar->GetPresenterController()->DispatchUnoCommand(mpMode->msAction);
1247  mpToolBar->RequestLayout();
1248  }
1249  while (false);
1250  }
1251 
1252  }
1253  else if (bModified)
1254  {
1255  Invalidate(true);
1256  }
1257 
1258  return bModified;
1259 }
1260 
1261 void Element::Invalidate (const bool bSynchronous)
1262 {
1263  OSL_ASSERT(mpToolBar.is());
1264  mpToolBar->InvalidateArea(GetBoundingBox(), bSynchronous);
1265 }
1266 
1267 bool Element::IsOutside (const awt::Rectangle& rBox)
1268 {
1269  if (rBox.X >= maLocation.X+maSize.Width)
1270  return true;
1271  else if (rBox.Y >= maLocation.Y+maSize.Height)
1272  return true;
1273  else if (maLocation.X >= rBox.X+rBox.Width)
1274  return true;
1275  else if (maLocation.Y >= rBox.Y+rBox.Height)
1276  return true;
1277  else
1278  return false;
1279 }
1280 
1281 
1282 bool Element::IsFilling() const
1283 {
1284  return false;
1285 }
1286 
1287 void Element::UpdateState()
1288 {
1289  OSL_ASSERT(mpToolBar);
1290  OSL_ASSERT(mpToolBar->GetPresenterController());
1291 
1292  if (!mpMode)
1293  return;
1294 
1295  util::URL aURL (mpToolBar->GetPresenterController()->CreateURLFromString(mpMode->msAction));
1296  Reference<frame::XDispatch> xDispatch (mpToolBar->GetPresenterController()->GetDispatch(aURL));
1297  if (xDispatch.is())
1298  {
1299  xDispatch->addStatusListener(this, aURL);
1300  xDispatch->removeStatusListener(this, aURL);
1301  }
1302 }
1303 
1304 //----- lang::XEventListener --------------------------------------------------
1305 
1306 void SAL_CALL Element::disposing (const css::lang::EventObject&) {}
1307 
1308 //----- document::XEventListener ----------------------------------------------
1309 
1310 void SAL_CALL Element::notifyEvent (const css::document::EventObject&)
1311 {
1312  UpdateState();
1313 }
1314 
1315 //----- frame::XStatusListener ------------------------------------------------
1316 
1317 void SAL_CALL Element::statusChanged (const css::frame::FeatureStateEvent& rEvent)
1318 {
1319  bool bIsSelected (mbIsSelected);
1320  bool bIsEnabled (rEvent.IsEnabled);
1321  rEvent.State >>= bIsSelected;
1322 
1323  if (bIsSelected != mbIsSelected || bIsEnabled != mbIsEnabled)
1324  {
1326  mbIsSelected = bIsSelected;
1327  SetState(mbIsOver, mbIsPressed);
1328  mpToolBar->RequestLayout();
1329  }
1330 }
1331 
1332 } // end of anonymous namespace
1333 
1334 //===== ElementMode ===========================================================
1335 
1336 namespace {
1337 
1338 ElementMode::ElementMode()
1339  : mpIcon(),
1340  msAction(),
1341  maText()
1342 {
1343 }
1344 
1345 void ElementMode::ReadElementMode (
1346  const Reference<beans::XPropertySet>& rxElementProperties,
1347  const OUString& rsModeName,
1348  std::shared_ptr<ElementMode> const & rpDefaultMode,
1350 {
1351  try
1352  {
1353  Reference<container::XHierarchicalNameAccess> xNode (
1354  PresenterConfigurationAccess::GetProperty(rxElementProperties, rsModeName),
1355  UNO_QUERY);
1356  Reference<beans::XPropertySet> xProperties (
1358  if (!xProperties.is() && rpDefaultMode != nullptr)
1359  {
1360  // The mode is not specified. Use the given, possibly empty,
1361  // default mode instead.
1362  mpIcon = rpDefaultMode->mpIcon;
1363  msAction = rpDefaultMode->msAction;
1364  maText = rpDefaultMode->maText;
1365  }
1366 
1367  // Read action.
1368  if ( ! (PresenterConfigurationAccess::GetProperty(xProperties, "Action") >>= msAction))
1369  if (rpDefaultMode != nullptr)
1370  msAction = rpDefaultMode->msAction;
1371 
1372  // Read text and font
1373  OUString sText(rpDefaultMode != nullptr ? rpDefaultMode->maText.GetText() : OUString());
1374  PresenterConfigurationAccess::GetProperty(xProperties, "Text") >>= sText;
1375  Reference<container::XHierarchicalNameAccess> xFontNode (
1376  PresenterConfigurationAccess::GetProperty(xProperties, "Font"), UNO_QUERY);
1378  xFontNode, rpDefaultMode != nullptr ? rpDefaultMode->maText.GetFont()
1380  maText = Text(sText,pFont);
1381 
1382  // Read bitmaps to display as icons.
1383  Reference<container::XHierarchicalNameAccess> xIconNode (
1384  PresenterConfigurationAccess::GetProperty(xProperties, "Icon"), UNO_QUERY);
1386  xIconNode, "", rContext.mxPresenterHelper, rContext.mxCanvas,
1387  rpDefaultMode != nullptr ? rpDefaultMode->mpIcon : SharedBitmapDescriptor());
1388  }
1389  catch(Exception&)
1390  {
1391  OSL_ASSERT(false);
1392  }
1393 }
1394 
1395 } // end of anonymous namespace
1396 
1397 //===== Button ================================================================
1398 
1399 namespace {
1400 
1401 ::rtl::Reference<Element> Button::Create (
1402  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1403 {
1404  ::rtl::Reference<Button> pElement (new Button(rpToolBar));
1405  pElement->Initialize();
1406  return pElement;
1407 }
1408 
1410  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1411  : Element(rpToolBar),
1412  mbIsListenerRegistered(false)
1413 {
1414  OSL_ASSERT(mpToolBar);
1415  OSL_ASSERT(mpToolBar->GetPresenterController().is());
1416  OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1417 }
1418 
1419 void Button::Initialize()
1420 {
1421  mpToolBar->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
1422  mbIsListenerRegistered = true;
1423 }
1424 
1425 void Button::disposing()
1426 {
1427  OSL_ASSERT(mpToolBar);
1429  {
1430  OSL_ASSERT(mpToolBar->GetPresenterController().is());
1431  OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1432 
1433  mbIsListenerRegistered = false;
1434  mpToolBar->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
1435  }
1436  Element::disposing();
1437 }
1438 
1439 void Button::Paint (
1440  const Reference<rendering::XCanvas>& rxCanvas,
1441  const rendering::ViewState& rViewState)
1442 {
1443  OSL_ASSERT(rxCanvas.is());
1444 
1445  if (!mpMode)
1446  return;
1447 
1448  if (!mpMode->mpIcon)
1449  return;
1450 
1451  geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1452  sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1453 
1454  PaintIcon(rxCanvas, nTextHeight, rViewState);
1455  mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox());
1456 }
1457 
1458 awt::Size Button::CreateBoundingSize (
1459  const Reference<rendering::XCanvas>& rxCanvas)
1460 {
1461  if (!mpMode)
1462  return awt::Size();
1463 
1464  geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1465 
1466  // tdf#128964 This ensures that if the text of a button changes due to a change in
1467  // the state of the button the other buttons of the toolbar do not move. The button is
1468  // allotted the maximum size so that it doesn't resize during a change of state.
1469  geometry::RealRectangle2D aTextBBoxNormal (mpNormal->maText.GetBoundingBox(rxCanvas));
1470  geometry::RealRectangle2D aTextBBoxMouseOver (mpMouseOver->maText.GetBoundingBox(rxCanvas));
1471  geometry::RealRectangle2D aTextBBoxSelected (mpSelected->maText.GetBoundingBox(rxCanvas));
1472  geometry::RealRectangle2D aTextBBoxDisabled (mpDisabled->maText.GetBoundingBox(rxCanvas));
1473  geometry::RealRectangle2D aTextBBoxMouseOverSelected (mpMouseOverSelected->maText.GetBoundingBox(rxCanvas));
1474  std::vector<sal_Int32> widths;
1475  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxNormal.X2 - aTextBBoxNormal.X1));
1476  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOver.X2 - aTextBBoxMouseOver.X1));
1477  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxSelected.X2 - aTextBBoxSelected.X1));
1478  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxDisabled.X2 - aTextBBoxDisabled.X1));
1479  widths.push_back(sal::static_int_cast<sal_Int32>(0.5 + aTextBBoxMouseOverSelected.X2 - aTextBBoxMouseOverSelected.X1));
1480 
1481  sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1482  Reference<rendering::XBitmap> xBitmap;
1483  if (mpMode->mpIcon)
1484  xBitmap = mpMode->mpIcon->GetNormalBitmap();
1485  if (xBitmap.is())
1486  {
1487  const sal_Int32 nGap (5);
1488  geometry::IntegerSize2D aSize (xBitmap->getSize());
1489  return awt::Size(
1490  ::std::max(aSize.Width, *std::max_element(widths.begin(), widths.end())),
1491  aSize.Height + nGap + nTextHeight);
1492  }
1493  else
1494  {
1495  return awt::Size(*std::max_element(widths.begin(), widths.end()), nTextHeight);
1496  }
1497 }
1498 
1499 void Button::PaintIcon (
1500  const Reference<rendering::XCanvas>& rxCanvas,
1501  const sal_Int32 nTextHeight,
1502  const rendering::ViewState& rViewState)
1503 {
1504  if (!mpMode)
1505  return;
1506 
1507  Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetBitmap(GetMode()));
1508  if (!xBitmap.is())
1509  return;
1510 
1513  const sal_Int32 nX (maLocation.X
1514  + (maSize.Width-xBitmap->getSize().Width) / 2);
1515  const sal_Int32 nY (maLocation.Y
1516  + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
1517  const rendering::RenderState aRenderState(
1518  geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
1519  nullptr,
1520  Sequence<double>(4),
1521  rendering::CompositeOperation::OVER);
1522  rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
1523  }
1524  else {
1525  const sal_Int32 nX (maLocation.X
1526  + (maSize.Width+xBitmap->getSize().Width) / 2);
1527  const sal_Int32 nY (maLocation.Y
1528  + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
1529  const rendering::RenderState aRenderState(
1530  geometry::AffineMatrix2D(-1,0,nX, 0,1,nY),
1531  nullptr,
1532  Sequence<double>(4),
1533  rendering::CompositeOperation::OVER);
1534  rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
1535  }
1536 }
1537 
1538 PresenterBitmapDescriptor::Mode Button::GetMode() const
1539 {
1540  if ( ! IsEnabled())
1542  else if (mbIsPressed)
1544  else if (mbIsOver)
1546  else
1548 }
1549 
1550 //----- lang::XEventListener --------------------------------------------------
1551 
1552 void SAL_CALL Button::disposing (const css::lang::EventObject& rEvent)
1553 {
1554  mbIsListenerRegistered = false;
1555  Element::disposing(rEvent);
1556 }
1557 
1558 } // end of anonymous namespace
1559 
1560 //===== PresenterToolBar::Label ===============================================
1561 
1562 namespace {
1563 
1564 Label::Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1565  : Element(rpToolBar)
1566 {
1567 }
1568 
1569 awt::Size Label::CreateBoundingSize (
1570  const Reference<rendering::XCanvas>& rxCanvas)
1571 {
1572  if (!mpMode)
1573  return awt::Size(0,0);
1574 
1575  geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1576  return awt::Size(
1577  sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1),
1578  sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1579 }
1580 
1581 void Label::SetText (const OUString& rsText)
1582 {
1583  OSL_ASSERT(mpToolBar);
1584  if (!mpMode)
1585  return;
1586 
1587  const bool bRequestLayout (mpMode->maText.GetText().getLength() != rsText.getLength());
1588 
1589  mpMode->maText.SetText(rsText);
1590  // Just use the character count for determining whether a layout is
1591  // necessary. This is an optimization to avoid layouts every time a new
1592  // time value is set on some labels.
1593  if (bRequestLayout)
1594  mpToolBar->RequestLayout();
1595  else
1596  Invalidate(false);
1597 }
1598 
1599 void Label::Paint (
1600  const Reference<rendering::XCanvas>& rxCanvas,
1601  const rendering::ViewState& rViewState)
1602 {
1603  OSL_ASSERT(rxCanvas.is());
1604  if (!mpMode)
1605  return;
1606 
1607  mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox());
1608 }
1609 
1610 bool Label::SetState (const bool, const bool)
1611 {
1612  // For labels there is no mouse over effect.
1613  return Element::SetState(false, false);
1614 }
1615 
1616 } // end of anonymous namespace
1617 
1618 //===== Text ==================================================================
1619 
1620 namespace {
1621 
1622 Text::Text()
1623  : msText(),
1624  mpFont()
1625 {
1626 }
1627 
1628 Text::Text (
1629  const OUString& rsText,
1631  : msText(rsText),
1632  mpFont(rpFont)
1633 {
1634 }
1635 
1636 void Text::SetText (const OUString& rsText)
1637 {
1638  msText = rsText;
1639 }
1640 
1641 const OUString& Text::GetText() const
1642 {
1643  return msText;
1644 }
1645 
1646 const PresenterTheme::SharedFontDescriptor& Text::GetFont() const
1647 {
1648  return mpFont;
1649 }
1650 
1651 void Text::Paint (
1652  const Reference<rendering::XCanvas>& rxCanvas,
1653  const rendering::ViewState& rViewState,
1654  const awt::Rectangle& rBoundingBox)
1655 {
1656  OSL_ASSERT(rxCanvas.is());
1657 
1658  if (msText.isEmpty())
1659  return;
1660  if (!mpFont)
1661  return;
1662 
1663  if ( ! mpFont->mxFont.is())
1664  mpFont->PrepareFont(rxCanvas);
1665  if ( ! mpFont->mxFont.is())
1666  return;
1667 
1668  rendering::StringContext aContext (msText, 0, msText.getLength());
1669 
1670  Reference<rendering::XTextLayout> xLayout (
1671  mpFont->mxFont->createTextLayout(
1672  aContext,
1673  rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1674  0));
1675  geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
1676  const double nTextWidth = aBox.X2 - aBox.X1;
1677  const double nY = rBoundingBox.Y + rBoundingBox.Height - aBox.Y2;
1678  const double nX = rBoundingBox.X + (rBoundingBox.Width - nTextWidth)/2;
1679 
1680  rendering::RenderState aRenderState(
1681  geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
1682  nullptr,
1683  Sequence<double>(4),
1684  rendering::CompositeOperation::SOURCE);
1685  PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
1686  rxCanvas->drawTextLayout(
1687  xLayout,
1688  rViewState,
1689  aRenderState);
1690 }
1691 
1692 geometry::RealRectangle2D Text::GetBoundingBox (const Reference<rendering::XCanvas>& rxCanvas)
1693 {
1694  if (mpFont && !msText.isEmpty())
1695  {
1696  if ( ! mpFont->mxFont.is())
1697  mpFont->PrepareFont(rxCanvas);
1698  if (mpFont->mxFont.is())
1699  {
1700  rendering::StringContext aContext (msText, 0, msText.getLength());
1701  Reference<rendering::XTextLayout> xLayout (
1702  mpFont->mxFont->createTextLayout(
1703  aContext,
1704  rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1705  0));
1706  return xLayout->queryTextBounds();
1707  }
1708  }
1709  return geometry::RealRectangle2D(0,0,0,0);
1710 }
1711 
1712 //===== TimeFormatter =========================================================
1713 
1714 OUString TimeFormatter::FormatTime (const oslDateTime& rTime)
1715 {
1716  OUStringBuffer sText;
1717 
1718  const sal_Int32 nHours (sal::static_int_cast<sal_Int32>(rTime.Hours));
1719  const sal_Int32 nMinutes (sal::static_int_cast<sal_Int32>(rTime.Minutes));
1720  const sal_Int32 nSeconds(sal::static_int_cast<sal_Int32>(rTime.Seconds));
1721  // Hours
1722  sText.append(OUString::number(nHours));
1723 
1724  sText.append(":");
1725 
1726  // Minutes
1727  const OUString sMinutes (OUString::number(nMinutes));
1728  if (sMinutes.getLength() == 1)
1729  sText.append("0");
1730  sText.append(sMinutes);
1731 
1732  // Seconds
1733  sText.append(":");
1734  const OUString sSeconds (OUString::number(nSeconds));
1735  if (sSeconds.getLength() == 1)
1736  sText.append("0");
1737  sText.append(sSeconds);
1738  return sText.makeStringAndClear();
1739 }
1740 
1741 //===== TimeLabel =============================================================
1742 
1743 TimeLabel::TimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1744  : Label(rpToolBar),
1745  mpListener()
1746 {
1747 }
1748 
1749 void SAL_CALL TimeLabel::disposing()
1750 {
1751  PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->RemoveListener(mpListener);
1752  mpListener.reset();
1753 }
1754 
1755 void TimeLabel::ConnectToTimer()
1756 {
1757  mpListener = std::make_shared<Listener>(this);
1758  PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->AddListener(mpListener);
1759 }
1760 
1761 //===== CurrentTimeLabel ======================================================
1762 
1763 ::rtl::Reference<Element> CurrentTimeLabel::Create (
1764  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1765 {
1766  ::rtl::Reference<TimeLabel> pElement(new CurrentTimeLabel(rpToolBar));
1767  pElement->ConnectToTimer();
1768  return pElement;
1769 }
1770 
1771 CurrentTimeLabel::~CurrentTimeLabel()
1772 {
1773 }
1774 
1775 CurrentTimeLabel::CurrentTimeLabel (
1776  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1777  : TimeLabel(rpToolBar)
1778 {
1779 }
1780 
1781 void CurrentTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
1782 {
1783  SetText(TimeFormatter::FormatTime(rCurrentTime));
1784  Invalidate(false);
1785 }
1786 
1787 void CurrentTimeLabel::SetModes (
1788  const SharedElementMode& rpNormalMode,
1789  const SharedElementMode& rpMouseOverMode,
1790  const SharedElementMode& rpSelectedMode,
1791  const SharedElementMode& rpDisabledMode,
1792  const SharedElementMode& rpMouseOverSelectedMode)
1793 {
1794  TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode);
1795  SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1796 }
1797 
1798 //===== PresentationTimeLabel =================================================
1799 
1800 ::rtl::Reference<Element> PresentationTimeLabel::Create (
1801  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1802 {
1803  ::rtl::Reference<TimeLabel> pElement(new PresentationTimeLabel(rpToolBar));
1804  pElement->ConnectToTimer();
1805  return pElement;
1806 }
1807 
1808 PresentationTimeLabel::~PresentationTimeLabel()
1809 {
1810  mpToolBar->GetPresenterController()->SetPresentationTime(nullptr);
1811 }
1812 
1813 PresentationTimeLabel::PresentationTimeLabel (
1814  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1815  : TimeLabel(rpToolBar),
1817 {
1818  restart();
1819  setPauseStatus(false);
1820  TimeValue pauseTime(0,0);
1821  setPauseTimeValue(pauseTime);
1822  mpToolBar->GetPresenterController()->SetPresentationTime(this);
1823 }
1824 
1825 void PresentationTimeLabel::restart()
1826 {
1827  TimeValue pauseTime(0, 0);
1828  setPauseTimeValue(pauseTime);
1829  maStartTimeValue.Seconds = 0;
1830  maStartTimeValue.Nanosec = 0;
1831 }
1832 
1833 bool PresentationTimeLabel::isPaused()
1834 {
1835  return paused;
1836 }
1837 
1838 void PresentationTimeLabel::setPauseStatus(const bool pauseStatus)
1839 {
1840  paused = pauseStatus;
1841 }
1842 
1843 TimeValue PresentationTimeLabel::getPauseTimeValue() const
1844 {
1845  return pauseTimeValue;
1846 }
1847 
1848 void PresentationTimeLabel::setPauseTimeValue(const TimeValue pauseTime)
1849 {
1850  //store the time at which the presentation was paused
1851  pauseTimeValue = pauseTime;
1852 }
1853 
1854 void PresentationTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
1855 {
1856  TimeValue aCurrentTimeValue;
1857  if (!osl_getTimeValueFromDateTime(&rCurrentTime, &aCurrentTimeValue))
1858  return;
1859 
1860  if (maStartTimeValue.Seconds==0 && maStartTimeValue.Nanosec==0)
1861  {
1862  // This method is called for the first time. Initialize the
1863  // start time. The start time is rounded to nearest second to
1864  // keep the time updates synchronized with the current time label.
1865  maStartTimeValue = aCurrentTimeValue;
1866  if (maStartTimeValue.Nanosec >= 500000000)
1867  maStartTimeValue.Seconds += 1;
1868  maStartTimeValue.Nanosec = 0;
1869  }
1870 
1871  //The start time value is incremented by the amount of time
1872  //the presentation was paused for in order to continue the
1873  //timer from the same position
1874  if(!isPaused())
1875  {
1876  TimeValue pauseTime = getPauseTimeValue();
1877  if(pauseTime.Seconds != 0 || pauseTime.Nanosec != 0)
1878  {
1879  TimeValue incrementValue(0, 0);
1880  incrementValue.Seconds = aCurrentTimeValue.Seconds - pauseTime.Seconds;
1881  if(pauseTime.Nanosec > aCurrentTimeValue.Nanosec)
1882  {
1883  incrementValue.Nanosec = 1000000000 + aCurrentTimeValue.Nanosec - pauseTime.Nanosec;
1884  }
1885  else
1886  {
1887  incrementValue.Nanosec = aCurrentTimeValue.Nanosec - pauseTime.Nanosec;
1888  }
1889 
1890  maStartTimeValue.Seconds += incrementValue.Seconds;
1891  maStartTimeValue.Nanosec += incrementValue.Nanosec;
1892  if(maStartTimeValue.Nanosec >= 1000000000)
1893  {
1894  maStartTimeValue.Seconds += 1;
1895  maStartTimeValue.Nanosec -= 1000000000;
1896  }
1897 
1898  TimeValue pauseTime_(0, 0);
1899  setPauseTimeValue(pauseTime_);
1900  }
1901  }
1902  else
1903  {
1904  TimeValue pauseTime = getPauseTimeValue();
1905  if(pauseTime.Seconds == 0 && pauseTime.Nanosec == 0)
1906  {
1907  setPauseTimeValue(aCurrentTimeValue);
1908  }
1909  }
1910 
1911  TimeValue aElapsedTimeValue;
1912  aElapsedTimeValue.Seconds = aCurrentTimeValue.Seconds - maStartTimeValue.Seconds;
1913  aElapsedTimeValue.Nanosec = aCurrentTimeValue.Nanosec - maStartTimeValue.Nanosec;
1914 
1915  oslDateTime aElapsedDateTime;
1916  if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue, &aElapsedDateTime) && !isPaused())
1917  {
1918  SetText(TimeFormatter::FormatTime(aElapsedDateTime));
1919  Invalidate(false);
1920  }
1921 }
1922 
1923 void PresentationTimeLabel::SetModes (
1924  const SharedElementMode& rpNormalMode,
1925  const SharedElementMode& rpMouseOverMode,
1926  const SharedElementMode& rpSelectedMode,
1927  const SharedElementMode& rpDisabledMode,
1928  const SharedElementMode& rpMouseOverSelectedMode)
1929 {
1930  TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode, rpMouseOverSelectedMode);
1931 
1932  oslDateTime aStartDateTime;
1933  if (osl_getDateTimeFromTimeValue(&maStartTimeValue, &aStartDateTime))
1934  {
1935  SetText(TimeFormatter::FormatTime(aStartDateTime));
1936  }
1937 }
1938 
1939 //===== VerticalSeparator =====================================================
1940 
1941 VerticalSeparator::VerticalSeparator (
1942  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1943  : Element(rpToolBar)
1944 {
1945 }
1946 
1947 void VerticalSeparator::Paint (
1948  const Reference<rendering::XCanvas>& rxCanvas,
1949  const rendering::ViewState& rViewState)
1950 {
1951  OSL_ASSERT(rxCanvas.is());
1952 
1953  awt::Rectangle aBBox (GetBoundingBox());
1954 
1955  rendering::RenderState aRenderState(
1956  geometry::AffineMatrix2D(1,0,aBBox.X, 0,1,aBBox.Y),
1957  nullptr,
1958  Sequence<double>(4),
1959  rendering::CompositeOperation::OVER);
1960  if (mpMode)
1961  {
1962  PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
1963  if (pFont)
1964  PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
1965  }
1966 
1967  Reference<rendering::XBitmap> xBitmap(mpToolBar->GetPresenterController()->GetPresenterHelper()->loadBitmap("bitmaps/Separator.png", rxCanvas));
1968  if (!xBitmap.is())
1969  return;
1970 
1971  rxCanvas->drawBitmap(
1972  xBitmap,
1973  rViewState,
1974  aRenderState);
1975 }
1976 
1977 awt::Size VerticalSeparator::CreateBoundingSize (
1978  const Reference<rendering::XCanvas>&)
1979 {
1980  return awt::Size(1,20);
1981 }
1982 
1983 bool VerticalSeparator::IsFilling() const
1984 {
1985  return true;
1986 }
1987 
1988 //===== HorizontalSeparator ===================================================
1989 
1990 HorizontalSeparator::HorizontalSeparator (
1991  const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1992  : Element(rpToolBar)
1993 {
1994 }
1995 
1996 void HorizontalSeparator::Paint (
1997  const Reference<rendering::XCanvas>& rxCanvas,
1998  const rendering::ViewState& rViewState)
1999 {
2000  OSL_ASSERT(rxCanvas.is());
2001 
2002  awt::Rectangle aBBox (GetBoundingBox());
2003 
2004  rendering::RenderState aRenderState(
2005  geometry::AffineMatrix2D(1,0,0, 0,1,0),
2006  nullptr,
2007  Sequence<double>(4),
2008  rendering::CompositeOperation::OVER);
2009  if (mpMode)
2010  {
2011  PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
2012  if (pFont)
2013  PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
2014  }
2015 
2016  rxCanvas->fillPolyPolygon(
2017  PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()),
2018  rViewState,
2019  aRenderState);
2020 }
2021 
2022 awt::Size HorizontalSeparator::CreateBoundingSize (
2023  const Reference<rendering::XCanvas>&)
2024 {
2025  return awt::Size(20,1);
2026 }
2027 
2028 bool HorizontalSeparator::IsFilling() const
2029 {
2030  return true;
2031 }
2032 
2033 } // end of anonymous namespace
2034 
2035 } // end of namespace ::sdext::presenter
2036 
2037 /* 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::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