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/svapp.hxx>
21 #include <vcl/settings.hxx>
22 #include "PresenterToolBar.hxx"
24 #include "PresenterBitmapContainer.hxx"
25 #include "PresenterCanvasHelper.hxx"
26 #include "PresenterGeometryHelper.hxx"
27 #include "PresenterPaintManager.hxx"
28 #include "PresenterPaneBase.hxx"
29 #include "PresenterPaneFactory.hxx"
30 #include "PresenterTimer.hxx"
31 #include "PresenterWindowManager.hxx"
33 #include <cppuhelper/compbase.hxx>
34 #include <com/sun/star/awt/FontDescriptor.hpp>
35 #include <com/sun/star/awt/PosSize.hpp>
36 #include <com/sun/star/awt/XWindowPeer.hpp>
37 #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
38 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
39 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
40 #include <com/sun/star/drawing/framework/XPane.hpp>
41 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
42 #include <com/sun/star/lang/XServiceName.hpp>
43 #include <com/sun/star/rendering/CompositeOperation.hpp>
44 #include <com/sun/star/rendering/RenderState.hpp>
45 #include <com/sun/star/rendering/TextDirection.hpp>
46 #include <com/sun/star/rendering/ViewState.hpp>
47 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
48 #include <com/sun/star/text/XTextRange.hpp>
49 #include <com/sun/star/util/Color.hpp>
50 #include <com/sun/star/util/XURLTransformer.hpp>
51 #include <rtl/ustrbuf.hxx>
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::drawing::framework
;
57 namespace sdext
{ namespace presenter
{
59 static const sal_Int32
gnGapSize (20);
68 const OUString
& rsText
,
69 const PresenterTheme::SharedFontDescriptor
& rpFont
);
71 void SetText (const OUString
& rsText
);
72 const OUString
& GetText() const;
73 const PresenterTheme::SharedFontDescriptor
& GetFont() const;
76 const Reference
<rendering::XCanvas
>& rxCanvas
,
77 const rendering::ViewState
& rViewState
,
78 const awt::Rectangle
& rBoundingBox
);
80 geometry::RealRectangle2D
GetBoundingBox (
81 const Reference
<rendering::XCanvas
>& rxCanvas
);
85 PresenterTheme::SharedFontDescriptor mpFont
;
92 ElementMode(const ElementMode
&) = delete;
93 ElementMode
& operator=(const ElementMode
&) = delete;
95 SharedBitmapDescriptor mpIcon
;
99 void ReadElementMode (
100 const Reference
<beans::XPropertySet
>& rxProperties
,
101 const OUString
& rsModeName
,
102 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
103 ::sdext::presenter::PresenterToolBar::Context
const & rContext
);
105 typedef std::shared_ptr
<ElementMode
> SharedElementMode
;
107 } // end of anonymous namespace
109 class PresenterToolBar::Context
113 Context(const Context
&) = delete;
114 Context
& operator=(const Context
&) = delete;
115 Reference
<drawing::XPresenterHelper
> mxPresenterHelper
;
116 css::uno::Reference
<css::rendering::XCanvas
> mxCanvas
;
119 //===== PresenterToolBar::Element =============================================
122 typedef cppu::WeakComponentImplHelper
<
123 css::document::XEventListener
,
124 css::frame::XStatusListener
125 > ElementInterfaceBase
;
128 : private ::cppu::BaseMutex
,
129 public ElementInterfaceBase
132 explicit Element (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
133 Element(const Element
&) = delete;
134 Element
& operator=(const Element
&) = delete;
136 virtual void SAL_CALL
disposing() override
;
138 virtual void SetModes (
139 const SharedElementMode
& rpNormalMode
,
140 const SharedElementMode
& rpMouseOverMode
,
141 const SharedElementMode
& rpSelectedMode
,
142 const SharedElementMode
& rpDisabledMode
);
143 void CurrentSlideHasChanged();
144 void SetLocation (const awt::Point
& rLocation
);
145 void SetSize (const geometry::RealSize2D
& rSize
);
147 const Reference
<rendering::XCanvas
>& rxCanvas
,
148 const rendering::ViewState
& rViewState
) = 0;
149 awt::Size
const & GetBoundingSize (
150 const Reference
<rendering::XCanvas
>& rxCanvas
);
151 awt::Rectangle
GetBoundingBox() const;
152 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
);
153 void Invalidate (const bool bSynchronous
);
154 bool IsOutside (const awt::Rectangle
& rBox
);
155 virtual bool IsFilling() const;
158 // lang::XEventListener
160 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
162 // document::XEventListener
164 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
166 // frame::XStatusListener
168 virtual void SAL_CALL
statusChanged (const css::frame::FeatureStateEvent
& rEvent
) override
;
171 ::rtl::Reference
<PresenterToolBar
> mpToolBar
;
172 awt::Point maLocation
;
174 SharedElementMode mpNormal
;
175 SharedElementMode mpMouseOver
;
176 SharedElementMode mpSelected
;
177 SharedElementMode mpDisabled
;
178 SharedElementMode mpMode
;
183 virtual awt::Size
CreateBoundingSize (
184 const Reference
<rendering::XCanvas
>& rxCanvas
) = 0;
186 bool IsEnabled() const { return mbIsEnabled
;}
191 } // end of anonymous namespace
193 class PresenterToolBar::ElementContainerPart
194 : public ::std::vector
<rtl::Reference
<Element
> >
198 //===== Button ================================================================
202 class Button
: public Element
205 static ::rtl::Reference
<Element
> Create (
206 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
208 virtual void SAL_CALL
disposing() override
;
211 const Reference
<rendering::XCanvas
>& rxCanvas
,
212 const rendering::ViewState
& rViewState
) override
;
214 // lang::XEventListener
216 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
219 virtual awt::Size
CreateBoundingSize (
220 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
223 bool mbIsListenerRegistered
;
225 Button (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
228 const Reference
<rendering::XCanvas
>& rxCanvas
,
229 const sal_Int32 nTextHeight
,
230 const rendering::ViewState
& rViewState
);
231 PresenterBitmapDescriptor::Mode
GetMode() const;
234 //===== Label =================================================================
236 class Label
: public Element
239 explicit Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
241 void SetText (const OUString
& rsText
);
243 const Reference
<rendering::XCanvas
>& rxCanvas
,
244 const rendering::ViewState
& rViewState
) override
;
245 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
) override
;
248 virtual awt::Size
CreateBoundingSize (
249 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
252 // Some specialized controls.
257 static OUString
FormatTime (const oslDateTime
& rTime
);
260 class TimeLabel
: public Label
263 void ConnectToTimer();
264 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) = 0;
266 explicit TimeLabel(const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
267 using Element::disposing
;
268 virtual void SAL_CALL
disposing() override
;
270 class Listener
: public PresenterClockTimer::Listener
273 explicit Listener (const ::rtl::Reference
<TimeLabel
>& rxLabel
)
274 : mxLabel(rxLabel
) {}
275 virtual ~Listener() {}
276 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
277 { if (mxLabel
.is()) mxLabel
->TimeHasChanged(rCurrentTime
); }
279 ::rtl::Reference
<TimeLabel
> mxLabel
;
281 std::shared_ptr
<PresenterClockTimer::Listener
> mpListener
;
284 class CurrentTimeLabel
: public TimeLabel
287 static ::rtl::Reference
<Element
> Create (
288 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
289 virtual void SetModes (
290 const SharedElementMode
& rpNormalMode
,
291 const SharedElementMode
& rpMouseOverMode
,
292 const SharedElementMode
& rpSelectedMode
,
293 const SharedElementMode
& rpDisabledMode
) override
;
295 CurrentTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
296 virtual ~CurrentTimeLabel() override
;
297 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
300 class PresentationTimeLabel
: public TimeLabel
, public IPresentationTime
303 static ::rtl::Reference
<Element
> Create (
304 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
305 virtual void SetModes (
306 const SharedElementMode
& rpNormalMode
,
307 const SharedElementMode
& rpMouseOverMode
,
308 const SharedElementMode
& rpSelectedMode
,
309 const SharedElementMode
& rpDisabledMode
) override
;
310 virtual void restart() override
;
312 TimeValue maStartTimeValue
;
313 PresentationTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
314 virtual ~PresentationTimeLabel() override
;
315 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
318 class VerticalSeparator
: public Element
321 explicit VerticalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
323 const Reference
<rendering::XCanvas
>& rxCanvas
,
324 const rendering::ViewState
& rViewState
) override
;
325 virtual bool IsFilling() const override
;
328 virtual awt::Size
CreateBoundingSize (
329 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
332 class HorizontalSeparator
: public Element
335 explicit HorizontalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
337 const Reference
<rendering::XCanvas
>& rxCanvas
,
338 const rendering::ViewState
& rViewState
) override
;
339 virtual bool IsFilling() const override
;
342 virtual awt::Size
CreateBoundingSize (
343 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
345 } // end of anonymous namespace
347 //===== PresenterToolBar ======================================================
349 PresenterToolBar::PresenterToolBar (
350 const Reference
<XComponentContext
>& rxContext
,
351 const css::uno::Reference
<css::awt::XWindow
>& rxWindow
,
352 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
353 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
354 const Anchor eAnchor
)
355 : PresenterToolBarInterfaceBase(m_aMutex
),
356 mxComponentContext(rxContext
),
357 maElementContainer(),
358 mpCurrentContainerPart(),
361 mxSlideShowController(),
363 mpPresenterController(rpPresenterController
),
364 mbIsLayoutPending(false),
370 void PresenterToolBar::Initialize (
371 const OUString
& rsConfigurationPath
)
375 CreateControls(rsConfigurationPath
);
379 mxWindow
->addWindowListener(this);
380 mxWindow
->addPaintListener(this);
381 mxWindow
->addMouseListener(this);
382 mxWindow
->addMouseMotionListener(this);
384 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
386 xPeer
->setBackground(util::Color(0xff000000));
388 mxWindow
->setVisible(true);
391 mxSlideShowController
= mpPresenterController
->GetSlideShowController();
393 mbIsLayoutPending
= true;
395 catch (RuntimeException
&)
397 mpCurrentContainerPart
.reset();
398 maElementContainer
.clear();
403 PresenterToolBar::~PresenterToolBar()
407 void SAL_CALL
PresenterToolBar::disposing()
411 mxWindow
->removeWindowListener(this);
412 mxWindow
->removePaintListener(this);
413 mxWindow
->removeMouseListener(this);
414 mxWindow
->removeMouseMotionListener(this);
418 // Dispose tool bar elements.
419 ElementContainer::iterator
iPart (maElementContainer
.begin());
420 ElementContainer::const_iterator
iEnd (maElementContainer
.end());
421 for ( ; iPart
!=iEnd
; ++iPart
)
423 OSL_ASSERT(iPart
->get()!=nullptr);
424 ElementContainerPart::iterator
iElement ((*iPart
)->begin());
425 ElementContainerPart::const_iterator
iPartEnd ((*iPart
)->end());
426 for ( ; iElement
!=iPartEnd
; ++iElement
)
428 if (iElement
->get() != nullptr)
430 ::rtl::Reference
<Element
> pElement (*iElement
);
431 Reference
<lang::XComponent
> xComponent (
432 static_cast<XWeak
*>(pElement
.get()), UNO_QUERY
);
434 xComponent
->dispose();
439 mpCurrentContainerPart
.reset();
440 maElementContainer
.clear();
443 void PresenterToolBar::InvalidateArea (
444 const awt::Rectangle
& rRepaintBox
,
445 const bool bSynchronous
)
447 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
450 xManager
->Invalidate(
456 void PresenterToolBar::RequestLayout()
458 mbIsLayoutPending
= true;
460 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
464 xManager
->Invalidate(mxWindow
);
467 geometry::RealSize2D
const & PresenterToolBar::GetMinimalSize()
469 if (mbIsLayoutPending
)
471 return maMinimalSize
;
474 const ::rtl::Reference
<PresenterController
>& PresenterToolBar::GetPresenterController() const
476 return mpPresenterController
;
479 const Reference
<XComponentContext
>& PresenterToolBar::GetComponentContext() const
481 return mxComponentContext
;
484 //----- lang::XEventListener -------------------------------------------------
486 void SAL_CALL
PresenterToolBar::disposing (const lang::EventObject
& rEventObject
)
488 if (rEventObject
.Source
== mxWindow
)
492 //----- XWindowListener -------------------------------------------------------
494 void SAL_CALL
PresenterToolBar::windowResized (const awt::WindowEvent
&)
496 mbIsLayoutPending
= true;
499 void SAL_CALL
PresenterToolBar::windowMoved (const awt::WindowEvent
&) {}
501 void SAL_CALL
PresenterToolBar::windowShown (const lang::EventObject
&)
503 mbIsLayoutPending
= true;
506 void SAL_CALL
PresenterToolBar::windowHidden (const lang::EventObject
&) {}
508 //----- XPaintListener --------------------------------------------------------
509 void SAL_CALL
PresenterToolBar::windowPaint (const css::awt::PaintEvent
& rEvent
)
511 if ( ! mxCanvas
.is())
514 if ( ! mbIsPresenterViewActive
)
517 const rendering::ViewState
aViewState (
518 geometry::AffineMatrix2D(1,0,0, 0,1,0),
519 PresenterGeometryHelper::CreatePolygon(rEvent
.UpdateRect
, mxCanvas
->getDevice()));
521 if (mbIsLayoutPending
)
524 Paint(rEvent
.UpdateRect
, aViewState
);
526 // Make the back buffer visible.
527 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
528 if (xSpriteCanvas
.is())
529 xSpriteCanvas
->updateScreen(false);
532 //----- XMouseListener --------------------------------------------------------
533 void SAL_CALL
PresenterToolBar::mousePressed (const css::awt::MouseEvent
& rEvent
)
536 CheckMouseOver(rEvent
, true, true);
539 void SAL_CALL
PresenterToolBar::mouseReleased (const css::awt::MouseEvent
& rEvent
)
542 CheckMouseOver(rEvent
, true);
545 void SAL_CALL
PresenterToolBar::mouseEntered (const css::awt::MouseEvent
& rEvent
)
548 CheckMouseOver(rEvent
, true);
551 void SAL_CALL
PresenterToolBar::mouseExited (const css::awt::MouseEvent
& rEvent
)
554 CheckMouseOver(rEvent
, false);
557 //----- XMouseMotionListener --------------------------------------------------
559 void SAL_CALL
PresenterToolBar::mouseMoved (const css::awt::MouseEvent
& rEvent
)
562 CheckMouseOver(rEvent
, true);
565 void SAL_CALL
PresenterToolBar::mouseDragged (const css::awt::MouseEvent
&)
570 //----- XDrawView -------------------------------------------------------------
572 void SAL_CALL
PresenterToolBar::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
574 if (rxSlide
!= mxCurrentSlide
)
576 mxCurrentSlide
= rxSlide
;
581 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBar::getCurrentPage()
583 return mxCurrentSlide
;
587 void PresenterToolBar::CreateControls (
588 const OUString
& rsConfigurationPath
)
590 if ( ! mxWindow
.is())
593 // Expand the macro in the bitmap file names.
594 PresenterConfigurationAccess
aConfiguration (
596 "/org.openoffice.Office.PresenterScreen/",
597 PresenterConfigurationAccess::READ_ONLY
);
599 mpCurrentContainerPart
.reset(new ElementContainerPart
);
600 maElementContainer
.clear();
601 maElementContainer
.push_back(mpCurrentContainerPart
);
603 Reference
<container::XHierarchicalNameAccess
> xToolBarNode (
604 aConfiguration
.GetConfigurationNode(rsConfigurationPath
),
606 if (xToolBarNode
.is())
608 Reference
<container::XNameAccess
> xEntries (
609 PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode
, "Entries"),
612 aContext
.mxPresenterHelper
= mpPresenterController
->GetPresenterHelper();
613 aContext
.mxCanvas
= mxCanvas
;
615 && aContext
.mxPresenterHelper
.is()
616 && aContext
.mxCanvas
.is())
618 PresenterConfigurationAccess::ForAll(
620 [this, &aContext
] (OUString
const&, uno::Reference
<beans::XPropertySet
> const& xProps
)
622 return this->ProcessEntry(xProps
, aContext
);
628 void PresenterToolBar::ProcessEntry (
629 const Reference
<beans::XPropertySet
>& rxProperties
,
630 Context
const & rContext
)
632 if ( ! rxProperties
.is())
635 // Type has to be present.
637 if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties
, "Type") >>= sType
))
641 PresenterConfigurationAccess::GetProperty(rxProperties
, "Name") >>= sName
;
643 // Read mode specific values.
644 SharedElementMode
pNormalMode (new ElementMode());
645 SharedElementMode
pMouseOverMode (new ElementMode());
646 SharedElementMode
pSelectedMode (new ElementMode());
647 SharedElementMode
pDisabledMode (new ElementMode());
648 pNormalMode
->ReadElementMode(rxProperties
, "Normal", pNormalMode
, rContext
);
649 pMouseOverMode
->ReadElementMode(rxProperties
, "MouseOver", pNormalMode
, rContext
);
650 pSelectedMode
->ReadElementMode(rxProperties
, "Selected", pNormalMode
, rContext
);
651 pDisabledMode
->ReadElementMode(rxProperties
, "Disabled", pNormalMode
, rContext
);
653 // Create new element.
654 ::rtl::Reference
<Element
> pElement
;
655 if ( sType
== "Button" )
656 pElement
= Button::Create(this);
657 else if ( sType
== "CurrentTimeLabel" )
658 pElement
= CurrentTimeLabel::Create(this);
659 else if ( sType
== "PresentationTimeLabel" )
660 pElement
= PresentationTimeLabel::Create(this);
661 else if ( sType
== "VerticalSeparator" )
662 pElement
.set(new VerticalSeparator(this));
663 else if ( sType
== "HorizontalSeparator" )
664 pElement
.set(new HorizontalSeparator(this));
665 else if ( sType
== "Label" )
666 pElement
.set(new Label(this));
667 else if ( sType
== "ChangeOrientation" )
669 mpCurrentContainerPart
.reset(new ElementContainerPart
);
670 maElementContainer
.push_back(mpCurrentContainerPart
);
675 pElement
->SetModes( pNormalMode
, pMouseOverMode
, pSelectedMode
, pDisabledMode
);
676 pElement
->UpdateState();
677 if (mpCurrentContainerPart
.get() != nullptr)
678 mpCurrentContainerPart
->push_back(pElement
);
682 void PresenterToolBar::Layout (
683 const Reference
<rendering::XCanvas
>& rxCanvas
)
685 if (maElementContainer
.empty())
688 mbIsLayoutPending
= false;
690 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
691 ElementContainer::iterator iPart
;
692 ElementContainer::iterator
iEnd (maElementContainer
.end());
693 ElementContainer::iterator
iBegin (maElementContainer
.begin());
694 ::std::vector
<geometry::RealSize2D
> aPartSizes (maElementContainer
.size());
695 geometry::RealSize2D
aTotalSize (0,0);
696 bool bIsHorizontal (true);
698 double nTotalHorizontalGap (0);
699 sal_Int32
nGapCount (0);
700 for (iPart
=maElementContainer
.begin(),nIndex
=0; iPart
!=iEnd
; ++iPart
,++nIndex
)
702 geometry::RealSize2D
aSize (CalculatePartSize(rxCanvas
, *iPart
, bIsHorizontal
));
704 // Remember the size of each part for later.
705 aPartSizes
[nIndex
] = aSize
;
707 // Add gaps between elements.
708 if ((*iPart
)->size()>1 && bIsHorizontal
)
710 nTotalHorizontalGap
+= ((*iPart
)->size() - 1) * gnGapSize
;
711 nGapCount
+= (*iPart
)->size()-1;
714 // Orientation changes for each part.
715 bIsHorizontal
= !bIsHorizontal
;
716 // Width is accumulated.
717 aTotalSize
.Width
+= aSize
.Width
;
718 // Height is the maximum height of all parts.
719 aTotalSize
.Height
= ::std::max(aTotalSize
.Height
, aSize
.Height
);
721 // Add gaps between parts.
722 if (maElementContainer
.size() > 1)
724 nTotalHorizontalGap
+= (maElementContainer
.size() - 1) * gnGapSize
;
725 nGapCount
+= maElementContainer
.size()-1;
728 // Calculate the minimal size so that the window size of the tool bar
729 // can be adapted accordingly.
730 maMinimalSize
= aTotalSize
;
731 maMinimalSize
.Width
+= nTotalHorizontalGap
;
733 // Calculate the gaps between elements.
734 double nGapWidth (0);
737 if (aTotalSize
.Width
+ nTotalHorizontalGap
> aWindowBox
.Width
)
738 nTotalHorizontalGap
= aWindowBox
.Width
- aTotalSize
.Width
;
739 nGapWidth
= nTotalHorizontalGap
/ nGapCount
;
742 // Determine the location of the left edge.
746 case Left
: nX
= 0; break;
747 case Center
: nX
= (aWindowBox
.Width
- aTotalSize
.Width
- nTotalHorizontalGap
) / 2; break;
751 double nY ((aWindowBox
.Height
- aTotalSize
.Height
) / 2);
752 bIsHorizontal
= true;
754 /* push front or back ? ... */
755 /// check whether RTL interface or not
756 if(!AllSettings::GetLayoutRTL()){
757 for (iPart
=maElementContainer
.begin(), nIndex
=0; iPart
!=iEnd
; ++iPart
,++nIndex
)
759 geometry::RealRectangle2D
aBoundingBox(
761 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
763 // Add space for gaps between elements.
764 if ((*iPart
)->size() > 1)
766 aBoundingBox
.X2
+= ((*iPart
)->size()-1) * nGapWidth
;
768 LayoutPart(rxCanvas
, *iPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
769 bIsHorizontal
= !bIsHorizontal
;
770 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
774 for (iPart
=maElementContainer
.end()-1, nIndex
=2; iPart
!=iBegin
-1; --iPart
, --nIndex
)
776 geometry::RealRectangle2D
aBoundingBox(
778 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
780 // Add space for gaps between elements.
781 if ((*iPart
)->size() > 1)
783 aBoundingBox
.X2
+= ((*iPart
)->size()-1) * nGapWidth
;
785 LayoutPart(rxCanvas
, *iPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
786 bIsHorizontal
= !bIsHorizontal
;
787 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
791 // The whole window has to be repainted.
792 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
795 xManager
->Invalidate(mxWindow
);
798 geometry::RealSize2D
PresenterToolBar::CalculatePartSize (
799 const Reference
<rendering::XCanvas
>& rxCanvas
,
800 const SharedElementContainerPart
& rpPart
,
801 const bool bIsHorizontal
)
803 geometry::RealSize2D
aTotalSize (0,0);
807 // Calculate the summed width of all elements.
808 ElementContainerPart::const_iterator iElement
;
809 for (iElement
=rpPart
->begin(); iElement
!=rpPart
->end(); ++iElement
)
811 if (iElement
->get() == nullptr)
814 const awt::Size
aBSize ((*iElement
)->GetBoundingSize(rxCanvas
));
817 aTotalSize
.Width
+= aBSize
.Width
;
818 if (aBSize
.Height
> aTotalSize
.Height
)
819 aTotalSize
.Height
= aBSize
.Height
;
823 aTotalSize
.Height
+= aBSize
.Height
;
824 if (aBSize
.Width
> aTotalSize
.Width
)
825 aTotalSize
.Width
= aBSize
.Width
;
832 void PresenterToolBar::LayoutPart (
833 const Reference
<rendering::XCanvas
>& rxCanvas
,
834 const SharedElementContainerPart
& rpPart
,
835 const geometry::RealRectangle2D
& rBoundingBox
,
836 const geometry::RealSize2D
& rPartSize
,
837 const bool bIsHorizontal
)
840 if (rpPart
->size() > 1)
843 nGap
= (rBoundingBox
.X2
- rBoundingBox
.X1
- rPartSize
.Width
) / (rpPart
->size()-1);
845 nGap
= (rBoundingBox
.Y2
- rBoundingBox
.Y1
- rPartSize
.Height
) / (rpPart
->size()-1);
848 // Place the elements.
849 double nX (rBoundingBox
.X1
);
850 double nY (rBoundingBox
.Y1
);
852 ElementContainerPart::const_iterator iElement
;
853 ElementContainerPart::const_iterator
iEnd (rpPart
->end());
854 ElementContainerPart::const_iterator
iBegin (rpPart
->begin());
856 /// check whether RTL interface or not
857 if(!AllSettings::GetLayoutRTL()){
858 for (iElement
=rpPart
->begin(); iElement
!=iEnd
; ++iElement
)
860 if (iElement
->get() == nullptr)
863 const awt::Size
aElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
866 if ((*iElement
)->IsFilling())
868 nY
= rBoundingBox
.Y1
;
869 (*iElement
)->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
872 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
873 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
874 nX
+= aElementSize
.Width
+ nGap
;
878 if ((*iElement
)->IsFilling())
880 nX
= rBoundingBox
.X1
;
881 (*iElement
)->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aElementSize
.Height
));
884 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aElementSize
.Width
) / 2;
885 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
886 nY
+= aElementSize
.Height
+ nGap
;
891 for (iElement
=rpPart
->end()-1; iElement
!=iBegin
-1; --iElement
)
893 if (iElement
->get() == nullptr)
896 const awt::Size
aElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
899 if ((*iElement
)->IsFilling())
901 nY
= rBoundingBox
.Y1
;
902 (*iElement
)->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
905 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
906 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
907 nX
+= aElementSize
.Width
+ nGap
;
911 // reverse presentation time with current time
912 if (iElement
==iBegin
){
915 else if (iElement
==iBegin
+2){
918 const awt::Size
aNewElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
919 if ((*iElement
)->IsFilling())
921 nX
= rBoundingBox
.X1
;
922 (*iElement
)->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aNewElementSize
.Height
));
925 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aNewElementSize
.Width
) / 2;
926 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
927 nY
+= aNewElementSize
.Height
+ nGap
;
929 // return the index as it was before the reversing
930 if (iElement
==iBegin
)
932 else if (iElement
==iBegin
+2)
940 void PresenterToolBar::Paint (
941 const awt::Rectangle
& rUpdateBox
,
942 const rendering::ViewState
& rViewState
)
944 OSL_ASSERT(mxCanvas
.is());
946 ElementContainer::iterator iPart
;
947 ElementContainer::const_iterator
iEnd (maElementContainer
.end());
948 for (iPart
=maElementContainer
.begin(); iPart
!=iEnd
; ++iPart
)
950 ElementContainerPart::iterator iElement
;
951 ElementContainerPart::const_iterator
iPartEnd ((*iPart
)->end());
952 for (iElement
=(*iPart
)->begin(); iElement
!=iPartEnd
; ++iElement
)
954 if (iElement
->get() != nullptr)
956 if ( ! (*iElement
)->IsOutside(rUpdateBox
))
957 (*iElement
)->Paint(mxCanvas
, rViewState
);
963 void PresenterToolBar::UpdateSlideNumber()
965 if( mxSlideShowController
.is() )
967 ElementContainer::iterator iPart
;
968 ElementContainer::const_iterator
iEnd (maElementContainer
.end());
969 for (iPart
=maElementContainer
.begin(); iPart
!=iEnd
; ++iPart
)
971 ElementContainerPart::iterator iElement
;
972 ElementContainerPart::const_iterator
iPartEnd ((*iPart
)->end());
973 for (iElement
=(*iPart
)->begin(); iElement
!=iPartEnd
; ++iElement
)
975 if (iElement
->get() != nullptr)
976 (*iElement
)->CurrentSlideHasChanged();
982 void PresenterToolBar::CheckMouseOver (
983 const css::awt::MouseEvent
& rEvent
,
984 const bool bOverWindow
,
985 const bool bMouseDown
)
987 css::awt::MouseEvent rTemp
=rEvent
;
988 if(AllSettings::GetLayoutRTL()){
989 awt::Rectangle aWindowBox
= mxWindow
->getPosSize();
990 rTemp
.X
=aWindowBox
.Width
-rTemp
.X
;
992 ElementContainer::iterator iPart
;
993 ElementContainer::const_iterator
iEnd (maElementContainer
.end());
994 for (iPart
=maElementContainer
.begin(); iPart
!=iEnd
; ++iPart
)
996 ElementContainerPart::iterator iElement
;
997 ElementContainerPart::const_iterator
iPartEnd ((*iPart
)->end());
998 for (iElement
=(*iPart
)->begin(); iElement
!=iPartEnd
; ++iElement
)
1000 if (iElement
->get() == nullptr)
1003 awt::Rectangle
aBox ((*iElement
)->GetBoundingBox());
1004 const bool bIsOver
= bOverWindow
1005 && aBox
.X
<= rTemp
.X
1006 && aBox
.Width
+aBox
.X
-1 >= rTemp
.X
1007 && aBox
.Y
<= rTemp
.Y
1008 && aBox
.Height
+aBox
.Y
-1 >= rTemp
.Y
;
1009 (*iElement
)->SetState(
1011 bIsOver
&& rTemp
.Buttons
!=0 && bMouseDown
&& rTemp
.ClickCount
>0);
1016 void PresenterToolBar::ThrowIfDisposed() const
1018 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1020 throw lang::DisposedException (
1021 "PresenterToolBar has already been disposed",
1022 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1026 //===== PresenterToolBarView ==================================================
1028 PresenterToolBarView::PresenterToolBarView (
1029 const Reference
<XComponentContext
>& rxContext
,
1030 const Reference
<XResourceId
>& rxViewId
,
1031 const Reference
<frame::XController
>& rxController
,
1032 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
1033 : PresenterToolBarViewInterfaceBase(m_aMutex
),
1038 mpPresenterController(rpPresenterController
),
1039 mxSlideShowController(rpPresenterController
->GetSlideShowController()),
1044 Reference
<XControllerManager
> xCM (rxController
, UNO_QUERY_THROW
);
1045 Reference
<XConfigurationController
> xCC(xCM
->getConfigurationController(),UNO_QUERY_THROW
);
1046 mxPane
.set(xCC
->getResource(rxViewId
->getAnchor()), UNO_QUERY_THROW
);
1048 mxWindow
= mxPane
->getWindow();
1049 mxCanvas
= mxPane
->getCanvas();
1051 mpToolBar
= new PresenterToolBar(
1055 rpPresenterController
,
1056 PresenterToolBar::Center
);
1057 mpToolBar
->Initialize("PresenterScreenSettings/ToolBars/ToolBar");
1061 mxWindow
->addPaintListener(this);
1063 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
1065 xPeer
->setBackground(util::Color(0xff000000));
1067 mxWindow
->setVisible(true);
1070 catch (RuntimeException
&)
1077 PresenterToolBarView::~PresenterToolBarView()
1081 void SAL_CALL
PresenterToolBarView::disposing()
1083 Reference
<lang::XComponent
> xComponent (static_cast<XWeak
*>(mpToolBar
.get()), UNO_QUERY
);
1084 mpToolBar
= nullptr;
1085 if (xComponent
.is())
1086 xComponent
->dispose();
1090 mxWindow
->removePaintListener(this);
1096 mpPresenterController
= nullptr;
1097 mxSlideShowController
= nullptr;
1101 const ::rtl::Reference
<PresenterToolBar
>& PresenterToolBarView::GetPresenterToolBar() const
1106 //----- XPaintListener --------------------------------------------------------
1108 void SAL_CALL
PresenterToolBarView::windowPaint (const css::awt::PaintEvent
& rEvent
)
1110 awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
1111 mpPresenterController
->GetCanvasHelper()->Paint(
1112 mpPresenterController
->GetViewBackground(mxViewId
->getResourceURL()),
1115 awt::Rectangle(0,0,aWindowBox
.Width
, aWindowBox
.Height
),
1119 //----- lang::XEventListener -------------------------------------------------
1121 void SAL_CALL
PresenterToolBarView::disposing (const lang::EventObject
& rEventObject
)
1123 if (rEventObject
.Source
== mxWindow
)
1127 //----- XResourceId -----------------------------------------------------------
1129 Reference
<XResourceId
> SAL_CALL
PresenterToolBarView::getResourceId()
1134 sal_Bool SAL_CALL
PresenterToolBarView::isAnchorOnly()
1139 //----- XDrawView -------------------------------------------------------------
1141 void SAL_CALL
PresenterToolBarView::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
1143 Reference
<drawing::XDrawView
> xToolBar (static_cast<XWeak
*>(mpToolBar
.get()), UNO_QUERY
);
1145 xToolBar
->setCurrentPage(rxSlide
);
1148 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBarView::getCurrentPage()
1153 //===== PresenterToolBar::Element =============================================
1158 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1159 : ElementInterfaceBase(m_aMutex
),
1160 mpToolBar(rpToolBar
),
1170 mbIsSelected(false),
1173 if (mpToolBar
.get() != nullptr)
1175 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1176 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1180 void Element::SetModes (
1181 const SharedElementMode
& rpNormalMode
,
1182 const SharedElementMode
& rpMouseOverMode
,
1183 const SharedElementMode
& rpSelectedMode
,
1184 const SharedElementMode
& rpDisabledMode
)
1186 mpNormal
= rpNormalMode
;
1187 mpMouseOver
= rpMouseOverMode
;
1188 mpSelected
= rpSelectedMode
;
1189 mpDisabled
= rpDisabledMode
;
1190 mpMode
= rpNormalMode
;
1193 void Element::disposing()
1197 awt::Size
const & Element::GetBoundingSize (
1198 const Reference
<rendering::XCanvas
>& rxCanvas
)
1200 maSize
= CreateBoundingSize(rxCanvas
);
1204 awt::Rectangle
Element::GetBoundingBox() const
1206 return awt::Rectangle(maLocation
.X
,maLocation
.Y
, maSize
.Width
, maSize
.Height
);
1209 void Element::CurrentSlideHasChanged()
1214 void Element::SetLocation (const awt::Point
& rLocation
)
1216 maLocation
= rLocation
;
1219 void Element::SetSize (const geometry::RealSize2D
& rSize
)
1221 maSize
= awt::Size(sal_Int32(0.5+rSize
.Width
), sal_Int32(0.5+rSize
.Height
));
1224 bool Element::SetState (
1226 const bool bIsPressed
)
1228 bool bModified (mbIsOver
!= bIsOver
|| mbIsPressed
!= bIsPressed
);
1229 bool bClicked (mbIsPressed
&& bIsOver
&& ! bIsPressed
);
1232 mbIsPressed
= bIsPressed
;
1234 // When the element is disabled then ignore mouse over or selection.
1235 // When the element is selected then ignore mouse over.
1237 mpMode
= mpDisabled
;
1238 else if (mbIsSelected
)
1239 mpMode
= mpSelected
;
1241 mpMode
= mpMouseOver
;
1245 if (bClicked
&& mbIsEnabled
)
1247 if (mpMode
.get() != nullptr)
1251 if (mpMode
->msAction
.isEmpty())
1254 if (mpToolBar
.get() == nullptr)
1257 if (mpToolBar
->GetPresenterController().get() == nullptr)
1260 mpToolBar
->GetPresenterController()->DispatchUnoCommand(mpMode
->msAction
);
1261 mpToolBar
->RequestLayout();
1275 void Element::Invalidate (const bool bSynchronous
)
1277 OSL_ASSERT(mpToolBar
.is());
1278 mpToolBar
->InvalidateArea(GetBoundingBox(), bSynchronous
);
1281 bool Element::IsOutside (const awt::Rectangle
& rBox
)
1283 if (rBox
.X
>= maLocation
.X
+maSize
.Width
)
1285 else if (rBox
.Y
>= maLocation
.Y
+maSize
.Height
)
1287 else if (maLocation
.X
>= rBox
.X
+rBox
.Width
)
1289 else if (maLocation
.Y
>= rBox
.Y
+rBox
.Height
)
1296 bool Element::IsFilling() const
1301 void Element::UpdateState()
1303 OSL_ASSERT(mpToolBar
.get() != nullptr);
1304 OSL_ASSERT(mpToolBar
->GetPresenterController().get() != nullptr);
1306 if (mpMode
.get() == nullptr)
1309 util::URL
aURL (mpToolBar
->GetPresenterController()->CreateURLFromString(mpMode
->msAction
));
1310 Reference
<frame::XDispatch
> xDispatch (mpToolBar
->GetPresenterController()->GetDispatch(aURL
));
1313 xDispatch
->addStatusListener(this, aURL
);
1314 xDispatch
->removeStatusListener(this, aURL
);
1318 //----- lang::XEventListener --------------------------------------------------
1320 void SAL_CALL
Element::disposing (const css::lang::EventObject
&) {}
1322 //----- document::XEventListener ----------------------------------------------
1324 void SAL_CALL
Element::notifyEvent (const css::document::EventObject
&)
1329 //----- frame::XStatusListener ------------------------------------------------
1331 void SAL_CALL
Element::statusChanged (const css::frame::FeatureStateEvent
& rEvent
)
1333 bool bIsSelected (mbIsSelected
);
1334 bool bIsEnabled (rEvent
.IsEnabled
);
1335 rEvent
.State
>>= bIsSelected
;
1337 if (bIsSelected
!= mbIsSelected
|| bIsEnabled
!= mbIsEnabled
)
1339 mbIsEnabled
= bIsEnabled
;
1340 mbIsSelected
= bIsSelected
;
1341 SetState(mbIsOver
, mbIsPressed
);
1342 mpToolBar
->RequestLayout();
1346 } // end of anonymous namespace
1348 //===== ElementMode ===========================================================
1352 ElementMode::ElementMode()
1359 void ElementMode::ReadElementMode (
1360 const Reference
<beans::XPropertySet
>& rxElementProperties
,
1361 const OUString
& rsModeName
,
1362 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
1363 ::sdext::presenter::PresenterToolBar::Context
const & rContext
)
1367 Reference
<container::XHierarchicalNameAccess
> xNode (
1368 PresenterConfigurationAccess::GetProperty(rxElementProperties
, rsModeName
),
1370 Reference
<beans::XPropertySet
> xProperties (
1371 PresenterConfigurationAccess::GetNodeProperties(xNode
, OUString()));
1372 if ( ! xProperties
.is() && rpDefaultMode
.get()!=nullptr)
1374 // The mode is not specified. Use the given, possibly empty,
1375 // default mode instead.
1376 mpIcon
= rpDefaultMode
->mpIcon
;
1377 msAction
= rpDefaultMode
->msAction
;
1378 maText
= rpDefaultMode
->maText
;
1382 if ( ! (PresenterConfigurationAccess::GetProperty(xProperties
, "Action") >>= msAction
))
1383 if (rpDefaultMode
.get()!=nullptr)
1384 msAction
= rpDefaultMode
->msAction
;
1386 // Read text and font
1387 OUString
sText (rpDefaultMode
.get()!=nullptr ? rpDefaultMode
->maText
.GetText() : OUString());
1388 PresenterConfigurationAccess::GetProperty(xProperties
, "Text") >>= sText
;
1389 Reference
<container::XHierarchicalNameAccess
> xFontNode (
1390 PresenterConfigurationAccess::GetProperty(xProperties
, "Font"), UNO_QUERY
);
1391 PresenterTheme::SharedFontDescriptor
pFont (PresenterTheme::ReadFont(
1393 rpDefaultMode
.get()!=nullptr
1394 ? rpDefaultMode
->maText
.GetFont()
1395 : PresenterTheme::SharedFontDescriptor()));
1396 maText
= Text(sText
,pFont
);
1398 // Read bitmaps to display as icons.
1399 Reference
<container::XHierarchicalNameAccess
> xIconNode (
1400 PresenterConfigurationAccess::GetProperty(xProperties
, "Icon"), UNO_QUERY
);
1401 mpIcon
= PresenterBitmapContainer::LoadBitmap(
1404 rContext
.mxPresenterHelper
,
1406 rpDefaultMode
.get()!=nullptr ? rpDefaultMode
->mpIcon
: SharedBitmapDescriptor());
1414 } // end of anonymous namespace
1416 //===== Button ================================================================
1420 ::rtl::Reference
<Element
> Button::Create (
1421 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1423 ::rtl::Reference
<Button
> pElement (new Button(rpToolBar
));
1424 pElement
->Initialize();
1425 return ::rtl::Reference
<Element
>(pElement
.get());
1429 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1430 : Element(rpToolBar
),
1431 mbIsListenerRegistered(false)
1433 OSL_ASSERT(mpToolBar
.get() != nullptr);
1434 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1435 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1438 void Button::Initialize()
1440 mpToolBar
->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
1441 mbIsListenerRegistered
= true;
1444 void Button::disposing()
1446 OSL_ASSERT(mpToolBar
.get() != nullptr);
1447 if (mpToolBar
.get() != nullptr
1448 && mbIsListenerRegistered
)
1450 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1451 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1453 mbIsListenerRegistered
= false;
1454 mpToolBar
->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
1456 Element::disposing();
1459 void Button::Paint (
1460 const Reference
<rendering::XCanvas
>& rxCanvas
,
1461 const rendering::ViewState
& rViewState
)
1463 OSL_ASSERT(rxCanvas
.is());
1465 if (mpMode
.get() == nullptr)
1468 if (mpMode
->mpIcon
.get() == nullptr)
1471 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1472 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1474 PaintIcon(rxCanvas
, nTextHeight
, rViewState
);
1475 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1478 awt::Size
Button::CreateBoundingSize (
1479 const Reference
<rendering::XCanvas
>& rxCanvas
)
1481 if (mpMode
.get() == nullptr)
1484 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1485 const sal_Int32
nGap (5);
1486 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1487 sal_Int32
nTextWidth (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.X2
- aTextBBox
.X1
));
1488 Reference
<rendering::XBitmap
> xBitmap
;
1489 if (mpMode
->mpIcon
.get() != nullptr)
1490 xBitmap
= mpMode
->mpIcon
->GetNormalBitmap();
1493 geometry::IntegerSize2D
aSize (xBitmap
->getSize());
1495 ::std::max(aSize
.Width
, sal_Int32(0.5 + aTextBBox
.X2
- aTextBBox
.X1
)),
1496 aSize
.Height
+ nGap
+ nTextHeight
);
1499 return awt::Size(nTextWidth
,nTextHeight
);
1502 void Button::PaintIcon (
1503 const Reference
<rendering::XCanvas
>& rxCanvas
,
1504 const sal_Int32 nTextHeight
,
1505 const rendering::ViewState
& rViewState
)
1507 if (mpMode
.get() == nullptr)
1510 Reference
<rendering::XBitmap
> xBitmap (mpMode
->mpIcon
->GetBitmap(GetMode()));
1513 /// check whether RTL interface or not
1514 if(!AllSettings::GetLayoutRTL()){
1515 const sal_Int32
nX (maLocation
.X
1516 + (maSize
.Width
-xBitmap
->getSize().Width
) / 2);
1517 const sal_Int32
nY (maLocation
.Y
1518 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1519 const rendering::RenderState
aRenderState(
1520 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1522 Sequence
<double>(4),
1523 rendering::CompositeOperation::OVER
);
1524 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1527 const sal_Int32
nX (maLocation
.X
1528 + (maSize
.Width
+xBitmap
->getSize().Width
) / 2);
1529 const sal_Int32
nY (maLocation
.Y
1530 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1531 const rendering::RenderState
aRenderState(
1532 geometry::AffineMatrix2D(-1,0,nX
, 0,1,nY
),
1534 Sequence
<double>(4),
1535 rendering::CompositeOperation::OVER
);
1536 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1541 PresenterBitmapDescriptor::Mode
Button::GetMode() const
1544 return PresenterBitmapDescriptor::Disabled
;
1545 else if (mbIsPressed
)
1546 return PresenterBitmapDescriptor::ButtonDown
;
1548 return PresenterBitmapDescriptor::MouseOver
;
1550 return PresenterBitmapDescriptor::Normal
;
1553 //----- lang::XEventListener --------------------------------------------------
1555 void SAL_CALL
Button::disposing (const css::lang::EventObject
& rEvent
)
1557 mbIsListenerRegistered
= false;
1558 Element::disposing(rEvent
);
1561 } // end of anonymous namespace
1563 //===== PresenterToolBar::Label ===============================================
1567 Label::Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1568 : Element(rpToolBar
)
1572 awt::Size
Label::CreateBoundingSize (
1573 const Reference
<rendering::XCanvas
>& rxCanvas
)
1575 if (mpMode
.get() == nullptr)
1576 return awt::Size(0,0);
1578 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1580 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.X2
- aTextBBox
.X1
),
1581 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1584 void Label::SetText (const OUString
& rsText
)
1586 OSL_ASSERT(mpToolBar
.get() != nullptr);
1587 if (mpMode
.get() == nullptr)
1590 const bool bRequestLayout (mpMode
->maText
.GetText().getLength() != rsText
.getLength());
1592 mpMode
->maText
.SetText(rsText
);
1593 // Just use the character count for determining whether a layout is
1594 // necessary. This is an optimization to avoid layouts every time a new
1595 // time value is set on some labels.
1597 mpToolBar
->RequestLayout();
1603 const Reference
<rendering::XCanvas
>& rxCanvas
,
1604 const rendering::ViewState
& rViewState
)
1606 OSL_ASSERT(rxCanvas
.is());
1607 if (mpMode
.get() == nullptr)
1610 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1613 bool Label::SetState (const bool, const bool)
1615 // For labels there is no mouse over effect.
1616 return Element::SetState(false, false);
1619 } // end of anonymous namespace
1621 //===== Text ==================================================================
1632 const OUString
& rsText
,
1633 const PresenterTheme::SharedFontDescriptor
& rpFont
)
1639 void Text::SetText (const OUString
& rsText
)
1644 const OUString
& Text::GetText() const
1649 const PresenterTheme::SharedFontDescriptor
& Text::GetFont() const
1655 const Reference
<rendering::XCanvas
>& rxCanvas
,
1656 const rendering::ViewState
& rViewState
,
1657 const awt::Rectangle
& rBoundingBox
)
1659 OSL_ASSERT(rxCanvas
.is());
1661 if (msText
.isEmpty())
1663 if (mpFont
.get() == nullptr)
1666 if ( ! mpFont
->mxFont
.is())
1667 mpFont
->PrepareFont(rxCanvas
);
1668 if ( ! mpFont
->mxFont
.is())
1671 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1673 Reference
<rendering::XTextLayout
> xLayout (
1674 mpFont
->mxFont
->createTextLayout(
1676 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1678 geometry::RealRectangle2D
aBox (xLayout
->queryTextBounds());
1679 const double nTextWidth
= aBox
.X2
- aBox
.X1
;
1680 const double nY
= rBoundingBox
.Y
+ rBoundingBox
.Height
- aBox
.Y2
;
1681 const double nX
= rBoundingBox
.X
+ (rBoundingBox
.Width
- nTextWidth
)/2;
1683 rendering::RenderState
aRenderState(
1684 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1686 Sequence
<double>(4),
1687 rendering::CompositeOperation::SOURCE
);
1688 PresenterCanvasHelper::SetDeviceColor(aRenderState
, mpFont
->mnColor
);
1689 rxCanvas
->drawTextLayout(
1695 geometry::RealRectangle2D
Text::GetBoundingBox (const Reference
<rendering::XCanvas
>& rxCanvas
)
1697 if (mpFont
.get() != nullptr && !msText
.isEmpty())
1699 if ( ! mpFont
->mxFont
.is())
1700 mpFont
->PrepareFont(rxCanvas
);
1701 if (mpFont
->mxFont
.is())
1703 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1704 Reference
<rendering::XTextLayout
> xLayout (
1705 mpFont
->mxFont
->createTextLayout(
1707 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1709 return xLayout
->queryTextBounds();
1712 return geometry::RealRectangle2D(0,0,0,0);
1715 //===== TimeFormatter =========================================================
1717 OUString
TimeFormatter::FormatTime (const oslDateTime
& rTime
)
1719 OUStringBuffer sText
;
1721 const sal_Int32
nHours (sal::static_int_cast
<sal_Int32
>(rTime
.Hours
));
1722 const sal_Int32
nMinutes (sal::static_int_cast
<sal_Int32
>(rTime
.Minutes
));
1723 const sal_Int32
nSeconds(sal::static_int_cast
<sal_Int32
>(rTime
.Seconds
));
1725 sText
.append(OUString::number(nHours
));
1730 const OUString
sMinutes (OUString::number(nMinutes
));
1731 if (sMinutes
.getLength() == 1)
1733 sText
.append(sMinutes
);
1737 const OUString
sSeconds (OUString::number(nSeconds
));
1738 if (sSeconds
.getLength() == 1)
1740 sText
.append(sSeconds
);
1741 return sText
.makeStringAndClear();
1744 //===== TimeLabel =============================================================
1746 TimeLabel::TimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1752 void SAL_CALL
TimeLabel::disposing()
1754 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->RemoveListener(mpListener
);
1758 void TimeLabel::ConnectToTimer()
1760 mpListener
.reset(new Listener(this));
1761 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->AddListener(mpListener
);
1764 //===== CurrentTimeLabel ======================================================
1766 ::rtl::Reference
<Element
> CurrentTimeLabel::Create (
1767 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1769 ::rtl::Reference
<TimeLabel
> pElement(new CurrentTimeLabel(rpToolBar
));
1770 pElement
->ConnectToTimer();
1771 return ::rtl::Reference
<Element
>(pElement
.get());
1774 CurrentTimeLabel::~CurrentTimeLabel()
1778 CurrentTimeLabel::CurrentTimeLabel (
1779 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1780 : TimeLabel(rpToolBar
)
1784 void CurrentTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1786 SetText(TimeFormatter::FormatTime(rCurrentTime
));
1790 void CurrentTimeLabel::SetModes (
1791 const SharedElementMode
& rpNormalMode
,
1792 const SharedElementMode
& rpMouseOverMode
,
1793 const SharedElementMode
& rpSelectedMode
,
1794 const SharedElementMode
& rpDisabledMode
)
1796 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
);
1797 SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1800 //===== PresentationTimeLabel =================================================
1802 ::rtl::Reference
<Element
> PresentationTimeLabel::Create (
1803 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1805 ::rtl::Reference
<TimeLabel
> pElement(new PresentationTimeLabel(rpToolBar
));
1806 pElement
->ConnectToTimer();
1807 return ::rtl::Reference
<Element
>(pElement
.get());
1810 PresentationTimeLabel::~PresentationTimeLabel()
1812 mpToolBar
->GetPresenterController()->SetPresentationTime(nullptr);
1815 PresentationTimeLabel::PresentationTimeLabel (
1816 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1817 : TimeLabel(rpToolBar
),
1821 mpToolBar
->GetPresenterController()->SetPresentationTime(this);
1824 void PresentationTimeLabel::restart()
1826 maStartTimeValue
.Seconds
= 0;
1827 maStartTimeValue
.Nanosec
= 0;
1830 void PresentationTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1832 TimeValue aCurrentTimeValue
;
1833 if (osl_getTimeValueFromDateTime(&rCurrentTime
, &aCurrentTimeValue
))
1835 if (maStartTimeValue
.Seconds
==0 && maStartTimeValue
.Nanosec
==0)
1837 // This method is called for the first time. Initialize the
1838 // start time. The start time is rounded to nearest second to
1839 // keep the time updates synchronized with the current time label.
1840 maStartTimeValue
= aCurrentTimeValue
;
1841 if (maStartTimeValue
.Nanosec
>= 500000000)
1842 maStartTimeValue
.Seconds
+= 1;
1843 maStartTimeValue
.Nanosec
= 0;
1846 TimeValue aElapsedTimeValue
;
1847 aElapsedTimeValue
.Seconds
= aCurrentTimeValue
.Seconds
- maStartTimeValue
.Seconds
;
1848 aElapsedTimeValue
.Nanosec
= aCurrentTimeValue
.Nanosec
- maStartTimeValue
.Nanosec
;
1850 oslDateTime aElapsedDateTime
;
1851 if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue
, &aElapsedDateTime
))
1853 SetText(TimeFormatter::FormatTime(aElapsedDateTime
));
1859 void PresentationTimeLabel::SetModes (
1860 const SharedElementMode
& rpNormalMode
,
1861 const SharedElementMode
& rpMouseOverMode
,
1862 const SharedElementMode
& rpSelectedMode
,
1863 const SharedElementMode
& rpDisabledMode
)
1865 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
);
1867 oslDateTime aStartDateTime
;
1868 if (osl_getDateTimeFromTimeValue(&maStartTimeValue
, &aStartDateTime
))
1870 SetText(TimeFormatter::FormatTime(aStartDateTime
));
1874 //===== VerticalSeparator =====================================================
1876 VerticalSeparator::VerticalSeparator (
1877 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1878 : Element(rpToolBar
)
1882 void VerticalSeparator::Paint (
1883 const Reference
<rendering::XCanvas
>& rxCanvas
,
1884 const rendering::ViewState
& rViewState
)
1886 OSL_ASSERT(rxCanvas
.is());
1888 awt::Rectangle
aBBox (GetBoundingBox());
1890 rendering::RenderState
aRenderState(
1891 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1893 Sequence
<double>(4),
1894 rendering::CompositeOperation::OVER
);
1895 if (mpMode
.get() != nullptr)
1897 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1898 if (pFont
.get() != nullptr)
1899 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1902 rxCanvas
->fillPolyPolygon(
1903 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
1908 awt::Size
VerticalSeparator::CreateBoundingSize (
1909 const Reference
<rendering::XCanvas
>&)
1911 return awt::Size(1,20);
1914 bool VerticalSeparator::IsFilling() const
1919 //===== HorizontalSeparator ===================================================
1921 HorizontalSeparator::HorizontalSeparator (
1922 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1923 : Element(rpToolBar
)
1927 void HorizontalSeparator::Paint (
1928 const Reference
<rendering::XCanvas
>& rxCanvas
,
1929 const rendering::ViewState
& rViewState
)
1931 OSL_ASSERT(rxCanvas
.is());
1933 awt::Rectangle
aBBox (GetBoundingBox());
1935 rendering::RenderState
aRenderState(
1936 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1938 Sequence
<double>(4),
1939 rendering::CompositeOperation::OVER
);
1940 if (mpMode
.get() != nullptr)
1942 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1943 if (pFont
.get() != nullptr)
1944 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1947 rxCanvas
->fillPolyPolygon(
1948 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
1953 awt::Size
HorizontalSeparator::CreateBoundingSize (
1954 const Reference
<rendering::XCanvas
>&)
1956 return awt::Size(20,1);
1959 bool HorizontalSeparator::IsFilling() const
1964 } // end of anonymous namespace
1966 } } // end of namespace ::sdext::presenter
1968 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */