1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/settings.hxx>
21 #include "PresenterToolBar.hxx"
23 #include "PresenterBitmapContainer.hxx"
24 #include "PresenterCanvasHelper.hxx"
25 #include "PresenterGeometryHelper.hxx"
26 #include "PresenterPaintManager.hxx"
27 #include "PresenterTimer.hxx"
28 #include "PresenterWindowManager.hxx"
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>
44 using namespace ::com::sun::star
;
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::drawing::framework
;
48 namespace sdext
{ namespace presenter
{
50 static const sal_Int32
gnGapSize (20);
59 const OUString
& rsText
,
60 const PresenterTheme::SharedFontDescriptor
& rpFont
);
62 void SetText (const OUString
& rsText
);
63 const OUString
& GetText() const;
64 const PresenterTheme::SharedFontDescriptor
& GetFont() const;
67 const Reference
<rendering::XCanvas
>& rxCanvas
,
68 const rendering::ViewState
& rViewState
,
69 const awt::Rectangle
& rBoundingBox
);
71 geometry::RealRectangle2D
GetBoundingBox (
72 const Reference
<rendering::XCanvas
>& rxCanvas
);
76 PresenterTheme::SharedFontDescriptor mpFont
;
83 ElementMode(const ElementMode
&) = delete;
84 ElementMode
& operator=(const ElementMode
&) = delete;
86 SharedBitmapDescriptor mpIcon
;
90 void ReadElementMode (
91 const Reference
<beans::XPropertySet
>& rxProperties
,
92 const OUString
& rsModeName
,
93 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
94 ::sdext::presenter::PresenterToolBar::Context
const & rContext
);
96 typedef std::shared_ptr
<ElementMode
> SharedElementMode
;
98 } // end of anonymous namespace
100 class PresenterToolBar::Context
104 Context(const Context
&) = delete;
105 Context
& operator=(const Context
&) = delete;
106 Reference
<drawing::XPresenterHelper
> mxPresenterHelper
;
107 css::uno::Reference
<css::rendering::XCanvas
> mxCanvas
;
110 //===== PresenterToolBar::Element =============================================
113 typedef cppu::WeakComponentImplHelper
<
114 css::document::XEventListener
,
115 css::frame::XStatusListener
116 > ElementInterfaceBase
;
119 : private ::cppu::BaseMutex
,
120 public ElementInterfaceBase
123 explicit Element (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
124 Element(const Element
&) = delete;
125 Element
& operator=(const Element
&) = delete;
127 virtual void SAL_CALL
disposing() override
;
129 virtual void SetModes (
130 const SharedElementMode
& rpNormalMode
,
131 const SharedElementMode
& rpMouseOverMode
,
132 const SharedElementMode
& rpSelectedMode
,
133 const SharedElementMode
& rpDisabledMode
);
134 void CurrentSlideHasChanged();
135 void SetLocation (const awt::Point
& rLocation
);
136 void SetSize (const geometry::RealSize2D
& rSize
);
138 const Reference
<rendering::XCanvas
>& rxCanvas
,
139 const rendering::ViewState
& rViewState
) = 0;
140 awt::Size
const & GetBoundingSize (
141 const Reference
<rendering::XCanvas
>& rxCanvas
);
142 awt::Rectangle
GetBoundingBox() const;
143 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
);
144 void Invalidate (const bool bSynchronous
);
145 bool IsOutside (const awt::Rectangle
& rBox
);
146 virtual bool IsFilling() const;
149 // lang::XEventListener
151 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
153 // document::XEventListener
155 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
157 // frame::XStatusListener
159 virtual void SAL_CALL
statusChanged (const css::frame::FeatureStateEvent
& rEvent
) override
;
162 ::rtl::Reference
<PresenterToolBar
> mpToolBar
;
163 awt::Point maLocation
;
165 SharedElementMode mpNormal
;
166 SharedElementMode mpMouseOver
;
167 SharedElementMode mpSelected
;
168 SharedElementMode mpDisabled
;
169 SharedElementMode mpMode
;
174 virtual awt::Size
CreateBoundingSize (
175 const Reference
<rendering::XCanvas
>& rxCanvas
) = 0;
177 bool IsEnabled() const { return mbIsEnabled
;}
182 } // end of anonymous namespace
184 class PresenterToolBar::ElementContainerPart
185 : public ::std::vector
<rtl::Reference
<Element
> >
189 //===== Button ================================================================
193 class Button
: public Element
196 static ::rtl::Reference
<Element
> Create (
197 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
199 virtual void SAL_CALL
disposing() override
;
202 const Reference
<rendering::XCanvas
>& rxCanvas
,
203 const rendering::ViewState
& rViewState
) override
;
205 // lang::XEventListener
207 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
210 virtual awt::Size
CreateBoundingSize (
211 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
214 bool mbIsListenerRegistered
;
216 Button (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
219 const Reference
<rendering::XCanvas
>& rxCanvas
,
220 const sal_Int32 nTextHeight
,
221 const rendering::ViewState
& rViewState
);
222 PresenterBitmapDescriptor::Mode
GetMode() const;
225 //===== Label =================================================================
227 class Label
: public Element
230 explicit Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
232 void SetText (const OUString
& rsText
);
234 const Reference
<rendering::XCanvas
>& rxCanvas
,
235 const rendering::ViewState
& rViewState
) override
;
236 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
) override
;
239 virtual awt::Size
CreateBoundingSize (
240 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
243 // Some specialized controls.
248 static OUString
FormatTime (const oslDateTime
& rTime
);
251 class TimeLabel
: public Label
254 void ConnectToTimer();
255 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) = 0;
257 explicit TimeLabel(const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
258 using Element::disposing
;
259 virtual void SAL_CALL
disposing() override
;
261 class Listener
: public PresenterClockTimer::Listener
264 explicit Listener (const ::rtl::Reference
<TimeLabel
>& rxLabel
)
265 : mxLabel(rxLabel
) {}
266 virtual ~Listener() {}
267 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
268 { if (mxLabel
.is()) mxLabel
->TimeHasChanged(rCurrentTime
); }
270 ::rtl::Reference
<TimeLabel
> mxLabel
;
272 std::shared_ptr
<PresenterClockTimer::Listener
> mpListener
;
275 class CurrentTimeLabel
: public TimeLabel
278 static ::rtl::Reference
<Element
> Create (
279 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
280 virtual void SetModes (
281 const SharedElementMode
& rpNormalMode
,
282 const SharedElementMode
& rpMouseOverMode
,
283 const SharedElementMode
& rpSelectedMode
,
284 const SharedElementMode
& rpDisabledMode
) override
;
286 CurrentTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
287 virtual ~CurrentTimeLabel() override
;
288 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
291 class PresentationTimeLabel
: public TimeLabel
, public IPresentationTime
294 static ::rtl::Reference
<Element
> Create (
295 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
296 virtual void SetModes (
297 const SharedElementMode
& rpNormalMode
,
298 const SharedElementMode
& rpMouseOverMode
,
299 const SharedElementMode
& rpSelectedMode
,
300 const SharedElementMode
& rpDisabledMode
) override
;
301 virtual void restart() override
;
303 TimeValue maStartTimeValue
;
304 PresentationTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
305 virtual ~PresentationTimeLabel() override
;
306 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
309 class VerticalSeparator
: public Element
312 explicit VerticalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
314 const Reference
<rendering::XCanvas
>& rxCanvas
,
315 const rendering::ViewState
& rViewState
) override
;
316 virtual bool IsFilling() const override
;
319 virtual awt::Size
CreateBoundingSize (
320 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
323 class HorizontalSeparator
: public Element
326 explicit HorizontalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
328 const Reference
<rendering::XCanvas
>& rxCanvas
,
329 const rendering::ViewState
& rViewState
) override
;
330 virtual bool IsFilling() const override
;
333 virtual awt::Size
CreateBoundingSize (
334 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
336 } // end of anonymous namespace
338 //===== PresenterToolBar ======================================================
340 PresenterToolBar::PresenterToolBar (
341 const Reference
<XComponentContext
>& rxContext
,
342 const css::uno::Reference
<css::awt::XWindow
>& rxWindow
,
343 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
344 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
345 const Anchor eAnchor
)
346 : PresenterToolBarInterfaceBase(m_aMutex
),
347 mxComponentContext(rxContext
),
348 maElementContainer(),
349 mpCurrentContainerPart(),
352 mxSlideShowController(),
354 mpPresenterController(rpPresenterController
),
355 mbIsLayoutPending(false),
361 void PresenterToolBar::Initialize (
362 const OUString
& rsConfigurationPath
)
366 CreateControls(rsConfigurationPath
);
370 mxWindow
->addWindowListener(this);
371 mxWindow
->addPaintListener(this);
372 mxWindow
->addMouseListener(this);
373 mxWindow
->addMouseMotionListener(this);
375 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
377 xPeer
->setBackground(util::Color(0xff000000));
379 mxWindow
->setVisible(true);
382 mxSlideShowController
= mpPresenterController
->GetSlideShowController();
384 mbIsLayoutPending
= true;
386 catch (RuntimeException
&)
388 mpCurrentContainerPart
.reset();
389 maElementContainer
.clear();
394 PresenterToolBar::~PresenterToolBar()
398 void SAL_CALL
PresenterToolBar::disposing()
402 mxWindow
->removeWindowListener(this);
403 mxWindow
->removePaintListener(this);
404 mxWindow
->removeMouseListener(this);
405 mxWindow
->removeMouseMotionListener(this);
409 // Dispose tool bar elements.
410 for (const auto& rxPart
: maElementContainer
)
412 OSL_ASSERT(rxPart
!= nullptr);
413 for (rtl::Reference
<Element
>& pElement
: *rxPart
)
415 if (pElement
.get() != nullptr)
417 Reference
<lang::XComponent
> xComponent (
418 static_cast<XWeak
*>(pElement
.get()), UNO_QUERY
);
420 xComponent
->dispose();
425 mpCurrentContainerPart
.reset();
426 maElementContainer
.clear();
429 void PresenterToolBar::InvalidateArea (
430 const awt::Rectangle
& rRepaintBox
,
431 const bool bSynchronous
)
433 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
436 xManager
->Invalidate(
442 void PresenterToolBar::RequestLayout()
444 mbIsLayoutPending
= true;
446 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
450 xManager
->Invalidate(mxWindow
);
453 geometry::RealSize2D
const & PresenterToolBar::GetMinimalSize()
455 if (mbIsLayoutPending
)
457 return maMinimalSize
;
460 const ::rtl::Reference
<PresenterController
>& PresenterToolBar::GetPresenterController() const
462 return mpPresenterController
;
465 const Reference
<XComponentContext
>& PresenterToolBar::GetComponentContext() const
467 return mxComponentContext
;
470 //----- lang::XEventListener -------------------------------------------------
472 void SAL_CALL
PresenterToolBar::disposing (const lang::EventObject
& rEventObject
)
474 if (rEventObject
.Source
== mxWindow
)
478 //----- XWindowListener -------------------------------------------------------
480 void SAL_CALL
PresenterToolBar::windowResized (const awt::WindowEvent
&)
482 mbIsLayoutPending
= true;
485 void SAL_CALL
PresenterToolBar::windowMoved (const awt::WindowEvent
&) {}
487 void SAL_CALL
PresenterToolBar::windowShown (const lang::EventObject
&)
489 mbIsLayoutPending
= true;
492 void SAL_CALL
PresenterToolBar::windowHidden (const lang::EventObject
&) {}
494 //----- XPaintListener --------------------------------------------------------
495 void SAL_CALL
PresenterToolBar::windowPaint (const css::awt::PaintEvent
& rEvent
)
497 if ( ! mxCanvas
.is())
500 if ( ! mbIsPresenterViewActive
)
503 const rendering::ViewState
aViewState (
504 geometry::AffineMatrix2D(1,0,0, 0,1,0),
505 PresenterGeometryHelper::CreatePolygon(rEvent
.UpdateRect
, mxCanvas
->getDevice()));
507 if (mbIsLayoutPending
)
510 Paint(rEvent
.UpdateRect
, aViewState
);
512 // Make the back buffer visible.
513 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
514 if (xSpriteCanvas
.is())
515 xSpriteCanvas
->updateScreen(false);
518 //----- XMouseListener --------------------------------------------------------
519 void SAL_CALL
PresenterToolBar::mousePressed (const css::awt::MouseEvent
& rEvent
)
522 CheckMouseOver(rEvent
, true, true);
525 void SAL_CALL
PresenterToolBar::mouseReleased (const css::awt::MouseEvent
& rEvent
)
528 CheckMouseOver(rEvent
, true);
531 void SAL_CALL
PresenterToolBar::mouseEntered (const css::awt::MouseEvent
& rEvent
)
534 CheckMouseOver(rEvent
, true);
537 void SAL_CALL
PresenterToolBar::mouseExited (const css::awt::MouseEvent
& rEvent
)
540 CheckMouseOver(rEvent
, false);
543 //----- XMouseMotionListener --------------------------------------------------
545 void SAL_CALL
PresenterToolBar::mouseMoved (const css::awt::MouseEvent
& rEvent
)
548 CheckMouseOver(rEvent
, true);
551 void SAL_CALL
PresenterToolBar::mouseDragged (const css::awt::MouseEvent
&)
556 //----- XDrawView -------------------------------------------------------------
558 void SAL_CALL
PresenterToolBar::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
560 if (rxSlide
!= mxCurrentSlide
)
562 mxCurrentSlide
= rxSlide
;
567 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBar::getCurrentPage()
569 return mxCurrentSlide
;
573 void PresenterToolBar::CreateControls (
574 const OUString
& rsConfigurationPath
)
576 if ( ! mxWindow
.is())
579 // Expand the macro in the bitmap file names.
580 PresenterConfigurationAccess
aConfiguration (
582 "/org.openoffice.Office.PresenterScreen/",
583 PresenterConfigurationAccess::READ_ONLY
);
585 mpCurrentContainerPart
.reset(new ElementContainerPart
);
586 maElementContainer
.clear();
587 maElementContainer
.push_back(mpCurrentContainerPart
);
589 Reference
<container::XHierarchicalNameAccess
> xToolBarNode (
590 aConfiguration
.GetConfigurationNode(rsConfigurationPath
),
592 if (!xToolBarNode
.is())
595 Reference
<container::XNameAccess
> xEntries (
596 PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode
, "Entries"),
599 aContext
.mxPresenterHelper
= mpPresenterController
->GetPresenterHelper();
600 aContext
.mxCanvas
= mxCanvas
;
602 && aContext
.mxPresenterHelper
.is()
603 && aContext
.mxCanvas
.is())
605 PresenterConfigurationAccess::ForAll(
607 [this, &aContext
] (OUString
const&, uno::Reference
<beans::XPropertySet
> const& xProps
)
609 return this->ProcessEntry(xProps
, aContext
);
614 void PresenterToolBar::ProcessEntry (
615 const Reference
<beans::XPropertySet
>& rxProperties
,
616 Context
const & rContext
)
618 if ( ! rxProperties
.is())
621 // Type has to be present.
623 if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties
, "Type") >>= sType
))
626 // Read mode specific values.
627 SharedElementMode
pNormalMode (new ElementMode());
628 SharedElementMode
pMouseOverMode (new ElementMode());
629 SharedElementMode
pSelectedMode (new ElementMode());
630 SharedElementMode
pDisabledMode (new ElementMode());
631 pNormalMode
->ReadElementMode(rxProperties
, "Normal", pNormalMode
, rContext
);
632 pMouseOverMode
->ReadElementMode(rxProperties
, "MouseOver", pNormalMode
, rContext
);
633 pSelectedMode
->ReadElementMode(rxProperties
, "Selected", pNormalMode
, rContext
);
634 pDisabledMode
->ReadElementMode(rxProperties
, "Disabled", pNormalMode
, rContext
);
636 // Create new element.
637 ::rtl::Reference
<Element
> pElement
;
638 if ( sType
== "Button" )
639 pElement
= Button::Create(this);
640 else if ( sType
== "CurrentTimeLabel" )
641 pElement
= CurrentTimeLabel::Create(this);
642 else if ( sType
== "PresentationTimeLabel" )
643 pElement
= PresentationTimeLabel::Create(this);
644 else if ( sType
== "VerticalSeparator" )
645 pElement
.set(new VerticalSeparator(this));
646 else if ( sType
== "HorizontalSeparator" )
647 pElement
.set(new HorizontalSeparator(this));
648 else if ( sType
== "Label" )
649 pElement
.set(new Label(this));
650 else if ( sType
== "ChangeOrientation" )
652 mpCurrentContainerPart
.reset(new ElementContainerPart
);
653 maElementContainer
.push_back(mpCurrentContainerPart
);
658 pElement
->SetModes( pNormalMode
, pMouseOverMode
, pSelectedMode
, pDisabledMode
);
659 pElement
->UpdateState();
660 if (mpCurrentContainerPart
.get() != nullptr)
661 mpCurrentContainerPart
->push_back(pElement
);
665 void PresenterToolBar::Layout (
666 const Reference
<rendering::XCanvas
>& rxCanvas
)
668 if (maElementContainer
.empty())
671 mbIsLayoutPending
= false;
673 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
674 ::std::vector
<geometry::RealSize2D
> aPartSizes (maElementContainer
.size());
675 geometry::RealSize2D
aTotalSize (0,0);
676 bool bIsHorizontal (true);
677 sal_Int32
nIndex (0);
678 double nTotalHorizontalGap (0);
679 sal_Int32
nGapCount (0);
680 for (const auto& rxPart
: maElementContainer
)
682 geometry::RealSize2D
aSize (CalculatePartSize(rxCanvas
, rxPart
, bIsHorizontal
));
684 // Remember the size of each part for later.
685 aPartSizes
[nIndex
] = aSize
;
687 // Add gaps between elements.
688 if (rxPart
->size()>1 && bIsHorizontal
)
690 nTotalHorizontalGap
+= (rxPart
->size() - 1) * gnGapSize
;
691 nGapCount
+= rxPart
->size() - 1;
694 // Orientation changes for each part.
695 bIsHorizontal
= !bIsHorizontal
;
696 // Width is accumulated.
697 aTotalSize
.Width
+= aSize
.Width
;
698 // Height is the maximum height of all parts.
699 aTotalSize
.Height
= ::std::max(aTotalSize
.Height
, aSize
.Height
);
702 // Add gaps between parts.
703 if (maElementContainer
.size() > 1)
705 nTotalHorizontalGap
+= (maElementContainer
.size() - 1) * gnGapSize
;
706 nGapCount
+= maElementContainer
.size()-1;
709 // Calculate the minimal size so that the window size of the tool bar
710 // can be adapted accordingly.
711 maMinimalSize
= aTotalSize
;
712 maMinimalSize
.Width
+= nTotalHorizontalGap
;
714 // Calculate the gaps between elements.
715 double nGapWidth (0);
718 if (aTotalSize
.Width
+ nTotalHorizontalGap
> aWindowBox
.Width
)
719 nTotalHorizontalGap
= aWindowBox
.Width
- aTotalSize
.Width
;
720 nGapWidth
= nTotalHorizontalGap
/ nGapCount
;
723 // Determine the location of the left edge.
727 case Left
: nX
= 0; break;
728 case Center
: nX
= (aWindowBox
.Width
- aTotalSize
.Width
- nTotalHorizontalGap
) / 2; break;
732 double nY ((aWindowBox
.Height
- aTotalSize
.Height
) / 2);
733 bIsHorizontal
= true;
735 /* push front or back ? ... */
736 /// check whether RTL interface or not
737 if(!AllSettings::GetLayoutRTL()){
739 for (const auto& rxPart
: maElementContainer
)
741 geometry::RealRectangle2D
aBoundingBox(
743 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
745 // Add space for gaps between elements.
746 if (rxPart
->size() > 1 && bIsHorizontal
)
747 aBoundingBox
.X2
+= (rxPart
->size() - 1) * nGapWidth
;
749 LayoutPart(rxCanvas
, rxPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
750 bIsHorizontal
= !bIsHorizontal
;
751 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
756 ElementContainer::iterator iPart
;
757 ElementContainer::iterator
iBegin (maElementContainer
.begin());
758 for (iPart
=maElementContainer
.end()-1, nIndex
=2; iPart
!=iBegin
-1; --iPart
, --nIndex
)
760 geometry::RealRectangle2D
aBoundingBox(
762 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
764 // Add space for gaps between elements.
765 if ((*iPart
)->size() > 1)
767 aBoundingBox
.X2
+= ((*iPart
)->size()-1) * nGapWidth
;
769 LayoutPart(rxCanvas
, *iPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
770 bIsHorizontal
= !bIsHorizontal
;
771 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
775 // The whole window has to be repainted.
776 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
779 xManager
->Invalidate(mxWindow
);
782 geometry::RealSize2D
PresenterToolBar::CalculatePartSize (
783 const Reference
<rendering::XCanvas
>& rxCanvas
,
784 const SharedElementContainerPart
& rpPart
,
785 const bool bIsHorizontal
)
787 geometry::RealSize2D
aTotalSize (0,0);
791 // Calculate the summed width of all elements.
792 for (const auto& rxElement
: *rpPart
)
794 if (rxElement
.get() == nullptr)
797 const awt::Size
aBSize (rxElement
->GetBoundingSize(rxCanvas
));
800 aTotalSize
.Width
+= aBSize
.Width
;
801 if (aBSize
.Height
> aTotalSize
.Height
)
802 aTotalSize
.Height
= aBSize
.Height
;
806 aTotalSize
.Height
+= aBSize
.Height
;
807 if (aBSize
.Width
> aTotalSize
.Width
)
808 aTotalSize
.Width
= aBSize
.Width
;
815 void PresenterToolBar::LayoutPart (
816 const Reference
<rendering::XCanvas
>& rxCanvas
,
817 const SharedElementContainerPart
& rpPart
,
818 const geometry::RealRectangle2D
& rBoundingBox
,
819 const geometry::RealSize2D
& rPartSize
,
820 const bool bIsHorizontal
)
823 if (rpPart
->size() > 1)
826 nGap
= (rBoundingBox
.X2
- rBoundingBox
.X1
- rPartSize
.Width
) / (rpPart
->size()-1);
828 nGap
= (rBoundingBox
.Y2
- rBoundingBox
.Y1
- rPartSize
.Height
) / (rpPart
->size()-1);
831 // Place the elements.
832 double nX (rBoundingBox
.X1
);
833 double nY (rBoundingBox
.Y1
);
835 /// check whether RTL interface or not
836 if(!AllSettings::GetLayoutRTL()){
837 for (auto& rxElement
: *rpPart
)
839 if (rxElement
.get() == nullptr)
842 const awt::Size
aElementSize (rxElement
->GetBoundingSize(rxCanvas
));
845 if (rxElement
->IsFilling())
847 nY
= rBoundingBox
.Y1
;
848 rxElement
->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
851 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
852 rxElement
->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
853 nX
+= aElementSize
.Width
+ nGap
;
857 if (rxElement
->IsFilling())
859 nX
= rBoundingBox
.X1
;
860 rxElement
->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aElementSize
.Height
));
863 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aElementSize
.Width
) / 2;
864 rxElement
->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
865 nY
+= aElementSize
.Height
+ nGap
;
870 ElementContainerPart::const_iterator iElement
;
871 ElementContainerPart::const_iterator
iEnd (rpPart
->end());
872 ElementContainerPart::const_iterator
iBegin (rpPart
->begin());
874 for (iElement
=rpPart
->end()-1; iElement
!=iBegin
-1; --iElement
)
876 if (iElement
->get() == nullptr)
879 const awt::Size
aElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
882 if ((*iElement
)->IsFilling())
884 nY
= rBoundingBox
.Y1
;
885 (*iElement
)->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
888 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
889 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
890 nX
+= aElementSize
.Width
+ nGap
;
894 // reverse presentation time with current time
895 if (iElement
==iBegin
){
898 else if (iElement
==iBegin
+2){
901 const awt::Size
aNewElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
902 if ((*iElement
)->IsFilling())
904 nX
= rBoundingBox
.X1
;
905 (*iElement
)->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aNewElementSize
.Height
));
908 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aNewElementSize
.Width
) / 2;
909 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
910 nY
+= aNewElementSize
.Height
+ nGap
;
912 // return the index as it was before the reversing
913 if (iElement
==iBegin
)
915 else if (iElement
==iBegin
+2)
922 void PresenterToolBar::Paint (
923 const awt::Rectangle
& rUpdateBox
,
924 const rendering::ViewState
& rViewState
)
926 OSL_ASSERT(mxCanvas
.is());
928 for (const auto& rxPart
: maElementContainer
)
930 for (auto& rxElement
: *rxPart
)
932 if (rxElement
.get() != nullptr)
934 if ( ! rxElement
->IsOutside(rUpdateBox
))
935 rxElement
->Paint(mxCanvas
, rViewState
);
941 void PresenterToolBar::UpdateSlideNumber()
943 if( mxSlideShowController
.is() )
945 for (const auto& rxPart
: maElementContainer
)
947 for (auto& rxElement
: *rxPart
)
949 if (rxElement
.get() != nullptr)
950 rxElement
->CurrentSlideHasChanged();
956 void PresenterToolBar::CheckMouseOver (
957 const css::awt::MouseEvent
& rEvent
,
958 const bool bOverWindow
,
959 const bool bMouseDown
)
961 css::awt::MouseEvent rTemp
=rEvent
;
962 if(AllSettings::GetLayoutRTL()){
963 awt::Rectangle aWindowBox
= mxWindow
->getPosSize();
964 rTemp
.X
=aWindowBox
.Width
-rTemp
.X
;
966 for (const auto& rxPart
: maElementContainer
)
968 for (auto& rxElement
: *rxPart
)
970 if (rxElement
.get() == nullptr)
973 awt::Rectangle
aBox (rxElement
->GetBoundingBox());
974 const bool bIsOver
= bOverWindow
976 && aBox
.Width
+aBox
.X
-1 >= rTemp
.X
978 && aBox
.Height
+aBox
.Y
-1 >= rTemp
.Y
;
981 bIsOver
&& rTemp
.Buttons
!=0 && bMouseDown
&& rTemp
.ClickCount
>0);
986 void PresenterToolBar::ThrowIfDisposed() const
988 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
990 throw lang::DisposedException (
991 "PresenterToolBar has already been disposed",
992 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
996 //===== PresenterToolBarView ==================================================
998 PresenterToolBarView::PresenterToolBarView (
999 const Reference
<XComponentContext
>& rxContext
,
1000 const Reference
<XResourceId
>& rxViewId
,
1001 const Reference
<frame::XController
>& rxController
,
1002 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
1003 : PresenterToolBarViewInterfaceBase(m_aMutex
),
1008 mpPresenterController(rpPresenterController
),
1013 Reference
<XControllerManager
> xCM (rxController
, UNO_QUERY_THROW
);
1014 Reference
<XConfigurationController
> xCC(xCM
->getConfigurationController(),UNO_SET_THROW
);
1015 mxPane
.set(xCC
->getResource(rxViewId
->getAnchor()), UNO_QUERY_THROW
);
1017 mxWindow
= mxPane
->getWindow();
1018 mxCanvas
= mxPane
->getCanvas();
1020 mpToolBar
= new PresenterToolBar(
1024 rpPresenterController
,
1025 PresenterToolBar::Center
);
1026 mpToolBar
->Initialize("PresenterScreenSettings/ToolBars/ToolBar");
1030 mxWindow
->addPaintListener(this);
1032 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
1034 xPeer
->setBackground(util::Color(0xff000000));
1036 mxWindow
->setVisible(true);
1039 catch (RuntimeException
&)
1046 PresenterToolBarView::~PresenterToolBarView()
1050 void SAL_CALL
PresenterToolBarView::disposing()
1052 Reference
<lang::XComponent
> xComponent (static_cast<XWeak
*>(mpToolBar
.get()), UNO_QUERY
);
1053 mpToolBar
= nullptr;
1054 if (xComponent
.is())
1055 xComponent
->dispose();
1059 mxWindow
->removePaintListener(this);
1065 mpPresenterController
= nullptr;
1068 const ::rtl::Reference
<PresenterToolBar
>& PresenterToolBarView::GetPresenterToolBar() const
1073 //----- XPaintListener --------------------------------------------------------
1075 void SAL_CALL
PresenterToolBarView::windowPaint (const css::awt::PaintEvent
& rEvent
)
1077 awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
1078 mpPresenterController
->GetCanvasHelper()->Paint(
1079 mpPresenterController
->GetViewBackground(mxViewId
->getResourceURL()),
1082 awt::Rectangle(0,0,aWindowBox
.Width
, aWindowBox
.Height
),
1086 //----- lang::XEventListener -------------------------------------------------
1088 void SAL_CALL
PresenterToolBarView::disposing (const lang::EventObject
& rEventObject
)
1090 if (rEventObject
.Source
== mxWindow
)
1094 //----- XResourceId -----------------------------------------------------------
1096 Reference
<XResourceId
> SAL_CALL
PresenterToolBarView::getResourceId()
1101 sal_Bool SAL_CALL
PresenterToolBarView::isAnchorOnly()
1106 //----- XDrawView -------------------------------------------------------------
1108 void SAL_CALL
PresenterToolBarView::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
1110 Reference
<drawing::XDrawView
> xToolBar (static_cast<XWeak
*>(mpToolBar
.get()), UNO_QUERY
);
1112 xToolBar
->setCurrentPage(rxSlide
);
1115 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBarView::getCurrentPage()
1120 //===== PresenterToolBar::Element =============================================
1125 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1126 : ElementInterfaceBase(m_aMutex
),
1127 mpToolBar(rpToolBar
),
1137 mbIsSelected(false),
1140 if (mpToolBar
.get() != nullptr)
1142 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1143 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1147 void Element::SetModes (
1148 const SharedElementMode
& rpNormalMode
,
1149 const SharedElementMode
& rpMouseOverMode
,
1150 const SharedElementMode
& rpSelectedMode
,
1151 const SharedElementMode
& rpDisabledMode
)
1153 mpNormal
= rpNormalMode
;
1154 mpMouseOver
= rpMouseOverMode
;
1155 mpSelected
= rpSelectedMode
;
1156 mpDisabled
= rpDisabledMode
;
1157 mpMode
= rpNormalMode
;
1160 void Element::disposing()
1164 awt::Size
const & Element::GetBoundingSize (
1165 const Reference
<rendering::XCanvas
>& rxCanvas
)
1167 maSize
= CreateBoundingSize(rxCanvas
);
1171 awt::Rectangle
Element::GetBoundingBox() const
1173 return awt::Rectangle(maLocation
.X
,maLocation
.Y
, maSize
.Width
, maSize
.Height
);
1176 void Element::CurrentSlideHasChanged()
1181 void Element::SetLocation (const awt::Point
& rLocation
)
1183 maLocation
= rLocation
;
1186 void Element::SetSize (const geometry::RealSize2D
& rSize
)
1188 maSize
= awt::Size(sal_Int32(0.5+rSize
.Width
), sal_Int32(0.5+rSize
.Height
));
1191 bool Element::SetState (
1193 const bool bIsPressed
)
1195 bool bModified (mbIsOver
!= bIsOver
|| mbIsPressed
!= bIsPressed
);
1196 bool bClicked (mbIsPressed
&& bIsOver
&& ! bIsPressed
);
1199 mbIsPressed
= bIsPressed
;
1201 // When the element is disabled then ignore mouse over or selection.
1202 // When the element is selected then ignore mouse over.
1204 mpMode
= mpDisabled
;
1205 else if (mbIsSelected
)
1206 mpMode
= mpSelected
;
1208 mpMode
= mpMouseOver
;
1212 if (bClicked
&& mbIsEnabled
)
1214 if (mpMode
.get() != nullptr)
1218 if (mpMode
->msAction
.isEmpty())
1221 if (mpToolBar
.get() == nullptr)
1224 if (mpToolBar
->GetPresenterController().get() == nullptr)
1227 mpToolBar
->GetPresenterController()->DispatchUnoCommand(mpMode
->msAction
);
1228 mpToolBar
->RequestLayout();
1242 void Element::Invalidate (const bool bSynchronous
)
1244 OSL_ASSERT(mpToolBar
.is());
1245 mpToolBar
->InvalidateArea(GetBoundingBox(), bSynchronous
);
1248 bool Element::IsOutside (const awt::Rectangle
& rBox
)
1250 if (rBox
.X
>= maLocation
.X
+maSize
.Width
)
1252 else if (rBox
.Y
>= maLocation
.Y
+maSize
.Height
)
1254 else if (maLocation
.X
>= rBox
.X
+rBox
.Width
)
1256 else if (maLocation
.Y
>= rBox
.Y
+rBox
.Height
)
1263 bool Element::IsFilling() const
1268 void Element::UpdateState()
1270 OSL_ASSERT(mpToolBar
.get() != nullptr);
1271 OSL_ASSERT(mpToolBar
->GetPresenterController().get() != nullptr);
1273 if (mpMode
.get() == nullptr)
1276 util::URL
aURL (mpToolBar
->GetPresenterController()->CreateURLFromString(mpMode
->msAction
));
1277 Reference
<frame::XDispatch
> xDispatch (mpToolBar
->GetPresenterController()->GetDispatch(aURL
));
1280 xDispatch
->addStatusListener(this, aURL
);
1281 xDispatch
->removeStatusListener(this, aURL
);
1285 //----- lang::XEventListener --------------------------------------------------
1287 void SAL_CALL
Element::disposing (const css::lang::EventObject
&) {}
1289 //----- document::XEventListener ----------------------------------------------
1291 void SAL_CALL
Element::notifyEvent (const css::document::EventObject
&)
1296 //----- frame::XStatusListener ------------------------------------------------
1298 void SAL_CALL
Element::statusChanged (const css::frame::FeatureStateEvent
& rEvent
)
1300 bool bIsSelected (mbIsSelected
);
1301 bool bIsEnabled (rEvent
.IsEnabled
);
1302 rEvent
.State
>>= bIsSelected
;
1304 if (bIsSelected
!= mbIsSelected
|| bIsEnabled
!= mbIsEnabled
)
1306 mbIsEnabled
= bIsEnabled
;
1307 mbIsSelected
= bIsSelected
;
1308 SetState(mbIsOver
, mbIsPressed
);
1309 mpToolBar
->RequestLayout();
1313 } // end of anonymous namespace
1315 //===== ElementMode ===========================================================
1319 ElementMode::ElementMode()
1326 void ElementMode::ReadElementMode (
1327 const Reference
<beans::XPropertySet
>& rxElementProperties
,
1328 const OUString
& rsModeName
,
1329 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
1330 ::sdext::presenter::PresenterToolBar::Context
const & rContext
)
1334 Reference
<container::XHierarchicalNameAccess
> xNode (
1335 PresenterConfigurationAccess::GetProperty(rxElementProperties
, rsModeName
),
1337 Reference
<beans::XPropertySet
> xProperties (
1338 PresenterConfigurationAccess::GetNodeProperties(xNode
, OUString()));
1339 if (!xProperties
.is() && rpDefaultMode
!= nullptr)
1341 // The mode is not specified. Use the given, possibly empty,
1342 // default mode instead.
1343 mpIcon
= rpDefaultMode
->mpIcon
;
1344 msAction
= rpDefaultMode
->msAction
;
1345 maText
= rpDefaultMode
->maText
;
1349 if ( ! (PresenterConfigurationAccess::GetProperty(xProperties
, "Action") >>= msAction
))
1350 if (rpDefaultMode
!= nullptr)
1351 msAction
= rpDefaultMode
->msAction
;
1353 // Read text and font
1354 OUString
sText(rpDefaultMode
!= nullptr ? rpDefaultMode
->maText
.GetText() : OUString());
1355 PresenterConfigurationAccess::GetProperty(xProperties
, "Text") >>= sText
;
1356 Reference
<container::XHierarchicalNameAccess
> xFontNode (
1357 PresenterConfigurationAccess::GetProperty(xProperties
, "Font"), UNO_QUERY
);
1358 PresenterTheme::SharedFontDescriptor
pFont(PresenterTheme::ReadFont(
1359 xFontNode
, rpDefaultMode
!= nullptr ? rpDefaultMode
->maText
.GetFont()
1360 : PresenterTheme::SharedFontDescriptor()));
1361 maText
= Text(sText
,pFont
);
1363 // Read bitmaps to display as icons.
1364 Reference
<container::XHierarchicalNameAccess
> xIconNode (
1365 PresenterConfigurationAccess::GetProperty(xProperties
, "Icon"), UNO_QUERY
);
1366 mpIcon
= PresenterBitmapContainer::LoadBitmap(
1367 xIconNode
, "", rContext
.mxPresenterHelper
, rContext
.mxCanvas
,
1368 rpDefaultMode
!= nullptr ? rpDefaultMode
->mpIcon
: SharedBitmapDescriptor());
1376 } // end of anonymous namespace
1378 //===== Button ================================================================
1382 ::rtl::Reference
<Element
> Button::Create (
1383 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1385 ::rtl::Reference
<Button
> pElement (new Button(rpToolBar
));
1386 pElement
->Initialize();
1387 return ::rtl::Reference
<Element
>(pElement
.get());
1391 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1392 : Element(rpToolBar
),
1393 mbIsListenerRegistered(false)
1395 OSL_ASSERT(mpToolBar
.get() != nullptr);
1396 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1397 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1400 void Button::Initialize()
1402 mpToolBar
->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
1403 mbIsListenerRegistered
= true;
1406 void Button::disposing()
1408 OSL_ASSERT(mpToolBar
.get() != nullptr);
1409 if (mpToolBar
.get() != nullptr
1410 && mbIsListenerRegistered
)
1412 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1413 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1415 mbIsListenerRegistered
= false;
1416 mpToolBar
->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
1418 Element::disposing();
1421 void Button::Paint (
1422 const Reference
<rendering::XCanvas
>& rxCanvas
,
1423 const rendering::ViewState
& rViewState
)
1425 OSL_ASSERT(rxCanvas
.is());
1427 if (mpMode
.get() == nullptr)
1430 if (mpMode
->mpIcon
.get() == nullptr)
1433 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1434 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1436 PaintIcon(rxCanvas
, nTextHeight
, rViewState
);
1437 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1440 awt::Size
Button::CreateBoundingSize (
1441 const Reference
<rendering::XCanvas
>& rxCanvas
)
1443 if (mpMode
.get() == nullptr)
1446 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1447 const sal_Int32
nGap (5);
1448 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1449 sal_Int32
nTextWidth (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.X2
- aTextBBox
.X1
));
1450 Reference
<rendering::XBitmap
> xBitmap
;
1451 if (mpMode
->mpIcon
.get() != nullptr)
1452 xBitmap
= mpMode
->mpIcon
->GetNormalBitmap();
1455 geometry::IntegerSize2D
aSize (xBitmap
->getSize());
1457 ::std::max(aSize
.Width
, sal_Int32(0.5 + aTextBBox
.X2
- aTextBBox
.X1
)),
1458 aSize
.Height
+ nGap
+ nTextHeight
);
1461 return awt::Size(nTextWidth
,nTextHeight
);
1464 void Button::PaintIcon (
1465 const Reference
<rendering::XCanvas
>& rxCanvas
,
1466 const sal_Int32 nTextHeight
,
1467 const rendering::ViewState
& rViewState
)
1469 if (mpMode
.get() == nullptr)
1472 Reference
<rendering::XBitmap
> xBitmap (mpMode
->mpIcon
->GetBitmap(GetMode()));
1476 /// check whether RTL interface or not
1477 if(!AllSettings::GetLayoutRTL()){
1478 const sal_Int32
nX (maLocation
.X
1479 + (maSize
.Width
-xBitmap
->getSize().Width
) / 2);
1480 const sal_Int32
nY (maLocation
.Y
1481 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1482 const rendering::RenderState
aRenderState(
1483 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1485 Sequence
<double>(4),
1486 rendering::CompositeOperation::OVER
);
1487 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1490 const sal_Int32
nX (maLocation
.X
1491 + (maSize
.Width
+xBitmap
->getSize().Width
) / 2);
1492 const sal_Int32
nY (maLocation
.Y
1493 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1494 const rendering::RenderState
aRenderState(
1495 geometry::AffineMatrix2D(-1,0,nX
, 0,1,nY
),
1497 Sequence
<double>(4),
1498 rendering::CompositeOperation::OVER
);
1499 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1503 PresenterBitmapDescriptor::Mode
Button::GetMode() const
1506 return PresenterBitmapDescriptor::Disabled
;
1507 else if (mbIsPressed
)
1508 return PresenterBitmapDescriptor::ButtonDown
;
1510 return PresenterBitmapDescriptor::MouseOver
;
1512 return PresenterBitmapDescriptor::Normal
;
1515 //----- lang::XEventListener --------------------------------------------------
1517 void SAL_CALL
Button::disposing (const css::lang::EventObject
& rEvent
)
1519 mbIsListenerRegistered
= false;
1520 Element::disposing(rEvent
);
1523 } // end of anonymous namespace
1525 //===== PresenterToolBar::Label ===============================================
1529 Label::Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1530 : Element(rpToolBar
)
1534 awt::Size
Label::CreateBoundingSize (
1535 const Reference
<rendering::XCanvas
>& rxCanvas
)
1537 if (mpMode
.get() == nullptr)
1538 return awt::Size(0,0);
1540 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1542 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.X2
- aTextBBox
.X1
),
1543 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1546 void Label::SetText (const OUString
& rsText
)
1548 OSL_ASSERT(mpToolBar
.get() != nullptr);
1549 if (mpMode
.get() == nullptr)
1552 const bool bRequestLayout (mpMode
->maText
.GetText().getLength() != rsText
.getLength());
1554 mpMode
->maText
.SetText(rsText
);
1555 // Just use the character count for determining whether a layout is
1556 // necessary. This is an optimization to avoid layouts every time a new
1557 // time value is set on some labels.
1559 mpToolBar
->RequestLayout();
1565 const Reference
<rendering::XCanvas
>& rxCanvas
,
1566 const rendering::ViewState
& rViewState
)
1568 OSL_ASSERT(rxCanvas
.is());
1569 if (mpMode
.get() == nullptr)
1572 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1575 bool Label::SetState (const bool, const bool)
1577 // For labels there is no mouse over effect.
1578 return Element::SetState(false, false);
1581 } // end of anonymous namespace
1583 //===== Text ==================================================================
1594 const OUString
& rsText
,
1595 const PresenterTheme::SharedFontDescriptor
& rpFont
)
1601 void Text::SetText (const OUString
& rsText
)
1606 const OUString
& Text::GetText() const
1611 const PresenterTheme::SharedFontDescriptor
& Text::GetFont() const
1617 const Reference
<rendering::XCanvas
>& rxCanvas
,
1618 const rendering::ViewState
& rViewState
,
1619 const awt::Rectangle
& rBoundingBox
)
1621 OSL_ASSERT(rxCanvas
.is());
1623 if (msText
.isEmpty())
1625 if (mpFont
.get() == nullptr)
1628 if ( ! mpFont
->mxFont
.is())
1629 mpFont
->PrepareFont(rxCanvas
);
1630 if ( ! mpFont
->mxFont
.is())
1633 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1635 Reference
<rendering::XTextLayout
> xLayout (
1636 mpFont
->mxFont
->createTextLayout(
1638 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1640 geometry::RealRectangle2D
aBox (xLayout
->queryTextBounds());
1641 const double nTextWidth
= aBox
.X2
- aBox
.X1
;
1642 const double nY
= rBoundingBox
.Y
+ rBoundingBox
.Height
- aBox
.Y2
;
1643 const double nX
= rBoundingBox
.X
+ (rBoundingBox
.Width
- nTextWidth
)/2;
1645 rendering::RenderState
aRenderState(
1646 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1648 Sequence
<double>(4),
1649 rendering::CompositeOperation::SOURCE
);
1650 PresenterCanvasHelper::SetDeviceColor(aRenderState
, mpFont
->mnColor
);
1651 rxCanvas
->drawTextLayout(
1657 geometry::RealRectangle2D
Text::GetBoundingBox (const Reference
<rendering::XCanvas
>& rxCanvas
)
1659 if (mpFont
.get() != nullptr && !msText
.isEmpty())
1661 if ( ! mpFont
->mxFont
.is())
1662 mpFont
->PrepareFont(rxCanvas
);
1663 if (mpFont
->mxFont
.is())
1665 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1666 Reference
<rendering::XTextLayout
> xLayout (
1667 mpFont
->mxFont
->createTextLayout(
1669 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1671 return xLayout
->queryTextBounds();
1674 return geometry::RealRectangle2D(0,0,0,0);
1677 //===== TimeFormatter =========================================================
1679 OUString
TimeFormatter::FormatTime (const oslDateTime
& rTime
)
1681 OUStringBuffer sText
;
1683 const sal_Int32
nHours (sal::static_int_cast
<sal_Int32
>(rTime
.Hours
));
1684 const sal_Int32
nMinutes (sal::static_int_cast
<sal_Int32
>(rTime
.Minutes
));
1685 const sal_Int32
nSeconds(sal::static_int_cast
<sal_Int32
>(rTime
.Seconds
));
1687 sText
.append(OUString::number(nHours
));
1692 const OUString
sMinutes (OUString::number(nMinutes
));
1693 if (sMinutes
.getLength() == 1)
1695 sText
.append(sMinutes
);
1699 const OUString
sSeconds (OUString::number(nSeconds
));
1700 if (sSeconds
.getLength() == 1)
1702 sText
.append(sSeconds
);
1703 return sText
.makeStringAndClear();
1706 //===== TimeLabel =============================================================
1708 TimeLabel::TimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1714 void SAL_CALL
TimeLabel::disposing()
1716 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->RemoveListener(mpListener
);
1720 void TimeLabel::ConnectToTimer()
1722 mpListener
.reset(new Listener(this));
1723 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->AddListener(mpListener
);
1726 //===== CurrentTimeLabel ======================================================
1728 ::rtl::Reference
<Element
> CurrentTimeLabel::Create (
1729 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1731 ::rtl::Reference
<TimeLabel
> pElement(new CurrentTimeLabel(rpToolBar
));
1732 pElement
->ConnectToTimer();
1733 return ::rtl::Reference
<Element
>(pElement
.get());
1736 CurrentTimeLabel::~CurrentTimeLabel()
1740 CurrentTimeLabel::CurrentTimeLabel (
1741 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1742 : TimeLabel(rpToolBar
)
1746 void CurrentTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1748 SetText(TimeFormatter::FormatTime(rCurrentTime
));
1752 void CurrentTimeLabel::SetModes (
1753 const SharedElementMode
& rpNormalMode
,
1754 const SharedElementMode
& rpMouseOverMode
,
1755 const SharedElementMode
& rpSelectedMode
,
1756 const SharedElementMode
& rpDisabledMode
)
1758 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
);
1759 SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1762 //===== PresentationTimeLabel =================================================
1764 ::rtl::Reference
<Element
> PresentationTimeLabel::Create (
1765 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1767 ::rtl::Reference
<TimeLabel
> pElement(new PresentationTimeLabel(rpToolBar
));
1768 pElement
->ConnectToTimer();
1769 return ::rtl::Reference
<Element
>(pElement
.get());
1772 PresentationTimeLabel::~PresentationTimeLabel()
1774 mpToolBar
->GetPresenterController()->SetPresentationTime(nullptr);
1777 PresentationTimeLabel::PresentationTimeLabel (
1778 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1779 : TimeLabel(rpToolBar
),
1783 mpToolBar
->GetPresenterController()->SetPresentationTime(this);
1786 void PresentationTimeLabel::restart()
1788 maStartTimeValue
.Seconds
= 0;
1789 maStartTimeValue
.Nanosec
= 0;
1792 void PresentationTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1794 TimeValue aCurrentTimeValue
;
1795 if (!osl_getTimeValueFromDateTime(&rCurrentTime
, &aCurrentTimeValue
))
1798 if (maStartTimeValue
.Seconds
==0 && maStartTimeValue
.Nanosec
==0)
1800 // This method is called for the first time. Initialize the
1801 // start time. The start time is rounded to nearest second to
1802 // keep the time updates synchronized with the current time label.
1803 maStartTimeValue
= aCurrentTimeValue
;
1804 if (maStartTimeValue
.Nanosec
>= 500000000)
1805 maStartTimeValue
.Seconds
+= 1;
1806 maStartTimeValue
.Nanosec
= 0;
1809 TimeValue aElapsedTimeValue
;
1810 aElapsedTimeValue
.Seconds
= aCurrentTimeValue
.Seconds
- maStartTimeValue
.Seconds
;
1811 aElapsedTimeValue
.Nanosec
= aCurrentTimeValue
.Nanosec
- maStartTimeValue
.Nanosec
;
1813 oslDateTime aElapsedDateTime
;
1814 if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue
, &aElapsedDateTime
))
1816 SetText(TimeFormatter::FormatTime(aElapsedDateTime
));
1821 void PresentationTimeLabel::SetModes (
1822 const SharedElementMode
& rpNormalMode
,
1823 const SharedElementMode
& rpMouseOverMode
,
1824 const SharedElementMode
& rpSelectedMode
,
1825 const SharedElementMode
& rpDisabledMode
)
1827 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
);
1829 oslDateTime aStartDateTime
;
1830 if (osl_getDateTimeFromTimeValue(&maStartTimeValue
, &aStartDateTime
))
1832 SetText(TimeFormatter::FormatTime(aStartDateTime
));
1836 //===== VerticalSeparator =====================================================
1838 VerticalSeparator::VerticalSeparator (
1839 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1840 : Element(rpToolBar
)
1844 void VerticalSeparator::Paint (
1845 const Reference
<rendering::XCanvas
>& rxCanvas
,
1846 const rendering::ViewState
& rViewState
)
1848 OSL_ASSERT(rxCanvas
.is());
1850 awt::Rectangle
aBBox (GetBoundingBox());
1852 rendering::RenderState
aRenderState(
1853 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1855 Sequence
<double>(4),
1856 rendering::CompositeOperation::OVER
);
1857 if (mpMode
.get() != nullptr)
1859 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1860 if (pFont
.get() != nullptr)
1861 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1864 rxCanvas
->fillPolyPolygon(
1865 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
1870 awt::Size
VerticalSeparator::CreateBoundingSize (
1871 const Reference
<rendering::XCanvas
>&)
1873 return awt::Size(1,20);
1876 bool VerticalSeparator::IsFilling() const
1881 //===== HorizontalSeparator ===================================================
1883 HorizontalSeparator::HorizontalSeparator (
1884 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1885 : Element(rpToolBar
)
1889 void HorizontalSeparator::Paint (
1890 const Reference
<rendering::XCanvas
>& rxCanvas
,
1891 const rendering::ViewState
& rViewState
)
1893 OSL_ASSERT(rxCanvas
.is());
1895 awt::Rectangle
aBBox (GetBoundingBox());
1897 rendering::RenderState
aRenderState(
1898 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1900 Sequence
<double>(4),
1901 rendering::CompositeOperation::OVER
);
1902 if (mpMode
.get() != nullptr)
1904 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1905 if (pFont
.get() != nullptr)
1906 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1909 rxCanvas
->fillPolyPolygon(
1910 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
1915 awt::Size
HorizontalSeparator::CreateBoundingSize (
1916 const Reference
<rendering::XCanvas
>&)
1918 return awt::Size(20,1);
1921 bool HorizontalSeparator::IsFilling() const
1926 } // end of anonymous namespace
1928 } } // end of namespace ::sdext::presenter
1930 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */