1c142477cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3c142477cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4c142477cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5c142477cSAndrew Rist  * distributed with this work for additional information
6c142477cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7c142477cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8c142477cSAndrew Rist  * "License"); you may not use this file except in compliance
9c142477cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10c142477cSAndrew Rist  *
11c142477cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12c142477cSAndrew Rist  *
13c142477cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14c142477cSAndrew Rist  * software distributed under the License is distributed on an
15c142477cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16c142477cSAndrew Rist  * KIND, either express or implied.  See the License for the
17c142477cSAndrew Rist  * specific language governing permissions and limitations
18c142477cSAndrew Rist  * under the License.
19c142477cSAndrew Rist  *
20c142477cSAndrew Rist  *************************************************************/
21c142477cSAndrew Rist 
22c142477cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sdext.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "PresenterClock.hxx"
28cdf0e10cSrcweir #include "PresenterConfigurationAccess.hxx"
29cdf0e10cSrcweir #include "PresenterGeometryHelper.hxx"
30cdf0e10cSrcweir #include <com/sun/star/awt/InvalidateStyle.hpp>
31cdf0e10cSrcweir #include <com/sun/star/awt/MouseButton.hpp>
32cdf0e10cSrcweir #include <com/sun/star/awt/Point.hpp>
33cdf0e10cSrcweir #include <com/sun/star/awt/XWindowPeer.hpp>
34cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
35cdf0e10cSrcweir #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
36cdf0e10cSrcweir #include <com/sun/star/drawing/framework/XControllerManager.hpp>
37cdf0e10cSrcweir #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
38cdf0e10cSrcweir #include <com/sun/star/rendering/CompositeOperation.hpp>
39cdf0e10cSrcweir #include <com/sun/star/rendering/PathCapType.hpp>
40cdf0e10cSrcweir #include <com/sun/star/rendering/TextDirection.hpp>
41cdf0e10cSrcweir #include <com/sun/star/rendering/XCanvasFont.hpp>
42cdf0e10cSrcweir #include <com/sun/star/rendering/XSpriteCanvas.hpp>
43cdf0e10cSrcweir #include <com/sun/star/util/Color.hpp>
44cdf0e10cSrcweir #include <osl/mutex.hxx>
45cdf0e10cSrcweir #include <osl/time.h>
46cdf0e10cSrcweir #include <rtl/ref.hxx>
47cdf0e10cSrcweir #include <vos/timer.hxx>
48cdf0e10cSrcweir #include <boost/bind.hpp>
49cdf0e10cSrcweir #include <cmath>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir using namespace ::com::sun::star;
52cdf0e10cSrcweir using namespace ::com::sun::star::uno;
53cdf0e10cSrcweir using namespace ::com::sun::star::drawing::framework;
54cdf0e10cSrcweir using ::rtl::OUString;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir namespace sdext { namespace presenter {
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 
59cdf0e10cSrcweir /** Wrapper around a library timer.
60cdf0e10cSrcweir */
61cdf0e10cSrcweir class PresenterClock::Timer : public vos::OTimer
62cdf0e10cSrcweir {
63cdf0e10cSrcweir public:
64cdf0e10cSrcweir     explicit Timer (const ::rtl::Reference<PresenterClock>& rpClock);
65cdf0e10cSrcweir     virtual ~Timer (void);
66cdf0e10cSrcweir 
67cdf0e10cSrcweir     void Stop (void);
68cdf0e10cSrcweir 
69cdf0e10cSrcweir protected:
70cdf0e10cSrcweir     virtual void SAL_CALL onShot (void);
71cdf0e10cSrcweir 
72cdf0e10cSrcweir private:
73cdf0e10cSrcweir     ::rtl::Reference<PresenterClock> mpClock;
74cdf0e10cSrcweir };
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 
79cdf0e10cSrcweir namespace {
80cdf0e10cSrcweir     bool GetDateTime (oslDateTime& rDateTime);
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     class BitmapDescriptor
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir     public:
85cdf0e10cSrcweir         Reference<rendering::XBitmap> mxBitmap;
86cdf0e10cSrcweir         awt::Point maOffset;
87cdf0e10cSrcweir         Reference<rendering::XBitmap> mxScaledBitmap;
88cdf0e10cSrcweir         geometry::RealPoint2D maScaledOffset;
89cdf0e10cSrcweir     };
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 
95cdf0e10cSrcweir class PresenterClock::Painter
96cdf0e10cSrcweir {
97cdf0e10cSrcweir public:
98cdf0e10cSrcweir     virtual void Paint (
99cdf0e10cSrcweir         const Reference<rendering::XCanvas>& rxCanvas,
100cdf0e10cSrcweir         const rendering::ViewState& rViewState,
101cdf0e10cSrcweir         const rendering::RenderState& rRenderState,
102cdf0e10cSrcweir         const util::Color& rBackgroundColor,
103cdf0e10cSrcweir         const sal_Int32 nHour,
104cdf0e10cSrcweir         const sal_Int32 nMinute,
105cdf0e10cSrcweir         const sal_Int32 nSecond,
106cdf0e10cSrcweir         const bool bShowSeconds) = 0;
107cdf0e10cSrcweir     virtual void Resize (const awt::Size& rSize) = 0;
108cdf0e10cSrcweir };
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 
113cdf0e10cSrcweir namespace {
114cdf0e10cSrcweir     class AnalogDefaultPainter : public PresenterClock::Painter
115cdf0e10cSrcweir     {
116cdf0e10cSrcweir     public:
117cdf0e10cSrcweir         AnalogDefaultPainter (void);
~AnalogDefaultPainter(void)118cdf0e10cSrcweir         virtual ~AnalogDefaultPainter (void) {}
119cdf0e10cSrcweir         virtual void Paint (
120cdf0e10cSrcweir             const Reference<rendering::XCanvas>& rxCanvas,
121cdf0e10cSrcweir             const rendering::ViewState& rViewState,
122cdf0e10cSrcweir             const rendering::RenderState& rRenderState,
123cdf0e10cSrcweir             const util::Color& rBackgroundColor,
124cdf0e10cSrcweir             const sal_Int32 nHour,
125cdf0e10cSrcweir             const sal_Int32 nMinute,
126cdf0e10cSrcweir             const sal_Int32 nSecond,
127cdf0e10cSrcweir             const bool bShowSeconds);
128cdf0e10cSrcweir         virtual void Resize (const awt::Size& rSize);
129cdf0e10cSrcweir     private:
130cdf0e10cSrcweir         geometry::RealPoint2D maCenter;
131cdf0e10cSrcweir         double mnOuterRadius;
132cdf0e10cSrcweir         awt::Size maSize;
133cdf0e10cSrcweir         Reference<rendering::XBitmap> mxBitmap;
134cdf0e10cSrcweir 
135cdf0e10cSrcweir         /** Relative length (with respect to radius) from center to the tip of
136cdf0e10cSrcweir             the hand.
137cdf0e10cSrcweir         */
138cdf0e10cSrcweir         static const double mnRelativeHourHandLength;
139cdf0e10cSrcweir         /** Relative length (with respect to radius) from center to the
140cdf0e10cSrcweir             oposing end of the tip of the hand.
141cdf0e10cSrcweir         */
142cdf0e10cSrcweir         static const double mnRelativeHourHandLength2;
143cdf0e10cSrcweir         static const double mnRelativeHourHandWidth;
144cdf0e10cSrcweir         static const double mnRelativeMinuteHandLength;
145cdf0e10cSrcweir         static const double mnRelativeMinuteHandLength2;
146cdf0e10cSrcweir         static const double mnRelativeMinuteHandWidth;
147cdf0e10cSrcweir         static const double mnRelativeSecondHandLength;
148cdf0e10cSrcweir         static const double mnRelativeSecondHandLength2;
149cdf0e10cSrcweir         static const double mnRelativeSecondHandWidth;
150cdf0e10cSrcweir 
151cdf0e10cSrcweir         void PaintAngledLine (
152cdf0e10cSrcweir             const double nAngle,
153cdf0e10cSrcweir             const double nInnerRadius,
154cdf0e10cSrcweir             const double nOuterRadius,
155cdf0e10cSrcweir             const double nStrokeWidth,
156cdf0e10cSrcweir             const Reference<rendering::XCanvas>& rxCanvas,
157cdf0e10cSrcweir             const rendering::ViewState& rViewState,
158cdf0e10cSrcweir             const rendering::RenderState& rRenderState);
159cdf0e10cSrcweir     };
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     class AnalogBitmapPainter : public PresenterClock::Painter
163cdf0e10cSrcweir     {
164cdf0e10cSrcweir     public:
165cdf0e10cSrcweir         AnalogBitmapPainter(
166cdf0e10cSrcweir             const Reference<XComponentContext>& rxContext,
167cdf0e10cSrcweir             const OUString& rsThemeName);
~AnalogBitmapPainter(void)168cdf0e10cSrcweir         virtual ~AnalogBitmapPainter (void) {}
169cdf0e10cSrcweir         virtual void Paint (
170cdf0e10cSrcweir             const Reference<rendering::XCanvas>& rxCanvas,
171cdf0e10cSrcweir             const rendering::ViewState& rViewState,
172cdf0e10cSrcweir             const rendering::RenderState& rRenderState,
173cdf0e10cSrcweir             const util::Color& rBackgroundColor,
174cdf0e10cSrcweir             const sal_Int32 nHour,
175cdf0e10cSrcweir             const sal_Int32 nMinute,
176cdf0e10cSrcweir             const sal_Int32 nSecond,
177cdf0e10cSrcweir             const bool bShowSeconds);
178cdf0e10cSrcweir         virtual void Resize (const awt::Size& rSize);
179cdf0e10cSrcweir     private:
180cdf0e10cSrcweir         css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
181cdf0e10cSrcweir         const OUString msThemeName;
182cdf0e10cSrcweir         bool mbThemeLoaded;
183cdf0e10cSrcweir         bool mbThemeLoadingFailed;
184cdf0e10cSrcweir         geometry::RealPoint2D maCenter;
185cdf0e10cSrcweir         double mnOuterRadius;
186cdf0e10cSrcweir         BitmapDescriptor maFace;
187cdf0e10cSrcweir         BitmapDescriptor maMinuteHand;
188cdf0e10cSrcweir         BitmapDescriptor maHourHand;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         void PrepareBitmaps (const Reference<rendering::XCanvas>& rxCanvas);
191cdf0e10cSrcweir         Reference<container::XNameAccess> GetTheme (
192cdf0e10cSrcweir             PresenterConfigurationAccess& rConfiguration);
193cdf0e10cSrcweir         bool ThemeNameComparator (
194cdf0e10cSrcweir             const ::rtl::OUString& rsKey,
195cdf0e10cSrcweir             const Reference<container::XNameAccess>& rxCandidate,
196cdf0e10cSrcweir             const ::rtl::OUString& rsCurrentThemeName);
197cdf0e10cSrcweir         void LoadBitmaps (
198cdf0e10cSrcweir             PresenterConfigurationAccess& rConfiguration,
199cdf0e10cSrcweir             const Reference<container::XNameAccess>& rxNameAccess,
200cdf0e10cSrcweir             const Reference<rendering::XCanvas>& rxCanvas);
201cdf0e10cSrcweir         void LoadBitmap (
202cdf0e10cSrcweir             const OUString& rsKey,
203cdf0e10cSrcweir             const ::std::vector<Any>& rValues,
204cdf0e10cSrcweir             const Reference<container::XNameAccess>& rxBitmapLoader);
205cdf0e10cSrcweir         void ScaleBitmaps (void);
206cdf0e10cSrcweir     };
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     class DigitalDefaultPainter : public PresenterClock::Painter
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir     public:
212cdf0e10cSrcweir         DigitalDefaultPainter (
213cdf0e10cSrcweir             const ::rtl::Reference<PresenterController>& rpPresenterController,
214cdf0e10cSrcweir             const Reference<XResourceId>& rxViewId);
215cdf0e10cSrcweir         virtual ~DigitalDefaultPainter (void);
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         virtual void Paint (
218cdf0e10cSrcweir             const Reference<rendering::XCanvas>& rxCanvas,
219cdf0e10cSrcweir             const rendering::ViewState& rViewState,
220cdf0e10cSrcweir             const rendering::RenderState& rRenderState,
221cdf0e10cSrcweir             const util::Color& rBackgroundColor,
222cdf0e10cSrcweir             const sal_Int32 nHour,
223cdf0e10cSrcweir             const sal_Int32 nMinute,
224cdf0e10cSrcweir             const sal_Int32 nSecond,
225cdf0e10cSrcweir             const bool bShowSeconds);
226cdf0e10cSrcweir         virtual void Resize (const awt::Size& rSize);
227cdf0e10cSrcweir 
228cdf0e10cSrcweir     private:
229cdf0e10cSrcweir         ::rtl::Reference<PresenterController> mpPresenterController;
230cdf0e10cSrcweir         bool mbIs24HourFormat;
231cdf0e10cSrcweir         bool mbIsAdaptFontSize;
232cdf0e10cSrcweir         Reference<rendering::XCanvasFont> mxFont;
233cdf0e10cSrcweir         awt::Size maWindowSize;
234cdf0e10cSrcweir         OUString msViewURL;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir         void CreateFont (
237cdf0e10cSrcweir             const Reference<rendering::XCanvas>& rxCanvas,
238cdf0e10cSrcweir             const bool bIsShowSeconds);
239cdf0e10cSrcweir     };
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 
242cdf0e10cSrcweir } // end of anonymous namespace
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 
247cdf0e10cSrcweir //===== PresenterClock =================================================================
248cdf0e10cSrcweir 
Create(const Reference<XComponentContext> & rxContext,const Reference<XResourceId> & rxViewId,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)249cdf0e10cSrcweir ::rtl::Reference<PresenterClock> PresenterClock::Create (
250cdf0e10cSrcweir     const Reference<XComponentContext>& rxContext,
251cdf0e10cSrcweir     const Reference<XResourceId>& rxViewId,
252cdf0e10cSrcweir     const Reference<frame::XController>& rxController,
253cdf0e10cSrcweir     const ::rtl::Reference<PresenterController>& rpPresenterController)
254cdf0e10cSrcweir {
255cdf0e10cSrcweir     ::rtl::Reference<PresenterClock> pClock (new PresenterClock(
256cdf0e10cSrcweir         rxContext,
257cdf0e10cSrcweir         rxViewId,
258cdf0e10cSrcweir         rxController,
259cdf0e10cSrcweir         rpPresenterController));
260cdf0e10cSrcweir     pClock->LateInit();
261cdf0e10cSrcweir     return pClock;
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 
PresenterClock(const Reference<XComponentContext> & rxContext,const Reference<XResourceId> & rxViewId,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)267cdf0e10cSrcweir PresenterClock::PresenterClock (
268cdf0e10cSrcweir     const Reference<XComponentContext>& rxContext,
269cdf0e10cSrcweir     const Reference<XResourceId>& rxViewId,
270cdf0e10cSrcweir     const Reference<frame::XController>& rxController,
271cdf0e10cSrcweir     const ::rtl::Reference<PresenterController>& rpPresenterController)
272cdf0e10cSrcweir     : PresenterClockInterfaceBase(m_aMutex),
273cdf0e10cSrcweir       mxComponentContext(rxContext),
274cdf0e10cSrcweir       mxViewId(rxViewId),
275cdf0e10cSrcweir       mxWindow(),
276cdf0e10cSrcweir       mxCanvas(),
277cdf0e10cSrcweir       mxPane(),
278cdf0e10cSrcweir       mpPresenterController(rpPresenterController),
279cdf0e10cSrcweir       mbIsResizePending(true),
280cdf0e10cSrcweir       maViewState(),
281cdf0e10cSrcweir       maRenderState(),
282cdf0e10cSrcweir       mpTimer(),
283cdf0e10cSrcweir       mpClockPainter(),
284cdf0e10cSrcweir       mpClockPainter2(),
285cdf0e10cSrcweir       mnMode(1),
286cdf0e10cSrcweir       mnHour(-1),
287cdf0e10cSrcweir       mnMinute(-1),
288cdf0e10cSrcweir       mnSecond(-1),
289cdf0e10cSrcweir       mbIsShowSeconds(true)
290cdf0e10cSrcweir {
291cdf0e10cSrcweir     SetMode(mnMode);
292cdf0e10cSrcweir 
293cdf0e10cSrcweir     maViewState.AffineTransform = geometry::AffineMatrix2D(1,0,0, 0,1,0);
294cdf0e10cSrcweir     maRenderState.AffineTransform = geometry::AffineMatrix2D(1,0,0, 0,1,0);
295cdf0e10cSrcweir     maRenderState.DeviceColor = Sequence<double>(4);
296cdf0e10cSrcweir     PresenterCanvasHelper::SetDeviceColor(maRenderState, util::Color(0x00000000));
297cdf0e10cSrcweir 
298cdf0e10cSrcweir     try
299cdf0e10cSrcweir     {
300cdf0e10cSrcweir 
301cdf0e10cSrcweir         Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
302cdf0e10cSrcweir         Reference<XConfigurationController> xCC (xCM->getConfigurationController(), UNO_QUERY_THROW);
303cdf0e10cSrcweir         mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
304cdf0e10cSrcweir 
305cdf0e10cSrcweir         mxWindow = mxPane->getWindow();
306cdf0e10cSrcweir         if (mxWindow.is())
307cdf0e10cSrcweir         {
308cdf0e10cSrcweir             mxWindow->addPaintListener(this);
309cdf0e10cSrcweir             mxWindow->addWindowListener(this);
310cdf0e10cSrcweir             mxWindow->addMouseListener(this);
311cdf0e10cSrcweir             Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
312cdf0e10cSrcweir             if (xPeer.is())
313cdf0e10cSrcweir                 xPeer->setBackground(util::Color(0xff000000));
314cdf0e10cSrcweir             mxWindow->setVisible(sal_True);
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir         Resize();
318cdf0e10cSrcweir     }
319cdf0e10cSrcweir     catch (RuntimeException&)
320cdf0e10cSrcweir     {
321cdf0e10cSrcweir         disposing();
322cdf0e10cSrcweir         throw;
323cdf0e10cSrcweir     }
324cdf0e10cSrcweir }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 
~PresenterClock(void)329cdf0e10cSrcweir PresenterClock::~PresenterClock (void)
330cdf0e10cSrcweir {
331cdf0e10cSrcweir }
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 
LateInit(void)336cdf0e10cSrcweir void PresenterClock::LateInit (void)
337cdf0e10cSrcweir {
338cdf0e10cSrcweir     mpTimer = new Timer(this);
339cdf0e10cSrcweir }
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 
disposing(void)344cdf0e10cSrcweir void SAL_CALL PresenterClock::disposing (void)
345cdf0e10cSrcweir {
346cdf0e10cSrcweir     //    osl::MutexGuard aGuard (m_aMutex);
347cdf0e10cSrcweir     if (mpTimer != NULL)
348cdf0e10cSrcweir     {
349cdf0e10cSrcweir         mpTimer->Stop();
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir     if (mxWindow.is())
352cdf0e10cSrcweir     {
353cdf0e10cSrcweir         mxWindow->removePaintListener(this);
354cdf0e10cSrcweir         mxWindow->removeWindowListener(this);
355cdf0e10cSrcweir         mxWindow->removeMouseListener(this);
356cdf0e10cSrcweir         mxWindow = NULL;
357cdf0e10cSrcweir     }
358cdf0e10cSrcweir     mxCanvas = NULL;
359cdf0e10cSrcweir     mxViewId = NULL;
360cdf0e10cSrcweir }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 
UpdateTime(void)365cdf0e10cSrcweir void PresenterClock::UpdateTime (void)
366cdf0e10cSrcweir {
367cdf0e10cSrcweir     // Get current time and check whether it is different from last time.
368cdf0e10cSrcweir     oslDateTime aDateTime;
369cdf0e10cSrcweir     if ( ! GetDateTime(aDateTime))
370cdf0e10cSrcweir         return;
371cdf0e10cSrcweir     if (aDateTime.Hours != mnHour
372cdf0e10cSrcweir         || aDateTime.Minutes != mnMinute
373cdf0e10cSrcweir         || aDateTime.Seconds != mnSecond)
374cdf0e10cSrcweir     {
375cdf0e10cSrcweir         mnHour = aDateTime.Hours % 24;
376cdf0e10cSrcweir         mnMinute = aDateTime.Minutes % 60;
377cdf0e10cSrcweir         mnSecond = aDateTime.Seconds % 60;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir         Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
380cdf0e10cSrcweir         if (xPeer.is())
381cdf0e10cSrcweir             xPeer->invalidate(awt::InvalidateStyle::NOERASE |
382cdf0e10cSrcweir             awt::InvalidateStyle::UPDATE);
383cdf0e10cSrcweir     }
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 
388cdf0e10cSrcweir 
389cdf0e10cSrcweir //-----  lang::XEventListener -------------------------------------------------
390cdf0e10cSrcweir 
disposing(const lang::EventObject & rEventObject)391cdf0e10cSrcweir void SAL_CALL PresenterClock::disposing (const lang::EventObject& rEventObject)
392cdf0e10cSrcweir     throw (RuntimeException)
393cdf0e10cSrcweir {
394cdf0e10cSrcweir     //    ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
395cdf0e10cSrcweir     //    osl::MutexGuard aGuard (m_aMutex);
396cdf0e10cSrcweir 
397cdf0e10cSrcweir     if (rEventObject.Source == mxWindow)
398cdf0e10cSrcweir     {
399cdf0e10cSrcweir         mxWindow = NULL;
400cdf0e10cSrcweir         if (mpTimer != NULL)
401cdf0e10cSrcweir             mpTimer->Stop();
402cdf0e10cSrcweir     }
403cdf0e10cSrcweir }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 
408cdf0e10cSrcweir //----- XPaintListener --------------------------------------------------------
409cdf0e10cSrcweir 
windowPaint(const awt::PaintEvent & rEvent)410cdf0e10cSrcweir void SAL_CALL PresenterClock::windowPaint (const awt::PaintEvent& rEvent)
411cdf0e10cSrcweir     throw (RuntimeException)
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     (void)rEvent;
414cdf0e10cSrcweir     ThrowIfDisposed();
415cdf0e10cSrcweir     ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
416cdf0e10cSrcweir     Paint(rEvent.UpdateRect);
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 
422cdf0e10cSrcweir //----- XWindowListener -------------------------------------------------------
423cdf0e10cSrcweir 
windowResized(const awt::WindowEvent & rEvent)424cdf0e10cSrcweir void SAL_CALL PresenterClock::windowResized (const awt::WindowEvent& rEvent)
425cdf0e10cSrcweir     throw (RuntimeException)
426cdf0e10cSrcweir {
427cdf0e10cSrcweir     (void)rEvent;
428cdf0e10cSrcweir     mbIsResizePending = true;
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 
windowMoved(const awt::WindowEvent & rEvent)434cdf0e10cSrcweir void SAL_CALL PresenterClock::windowMoved (const awt::WindowEvent& rEvent)
435cdf0e10cSrcweir     throw (RuntimeException)
436cdf0e10cSrcweir {
437cdf0e10cSrcweir     (void)rEvent;
438cdf0e10cSrcweir     mbIsResizePending = true;
439cdf0e10cSrcweir }
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 
windowShown(const lang::EventObject & rEvent)444cdf0e10cSrcweir void SAL_CALL PresenterClock::windowShown (const lang::EventObject& rEvent)
445cdf0e10cSrcweir     throw (RuntimeException)
446cdf0e10cSrcweir {
447cdf0e10cSrcweir     (void)rEvent;
448cdf0e10cSrcweir     mbIsResizePending = true;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 
windowHidden(const lang::EventObject & rEvent)454cdf0e10cSrcweir void SAL_CALL PresenterClock::windowHidden (const lang::EventObject& rEvent)
455cdf0e10cSrcweir     throw (RuntimeException)
456cdf0e10cSrcweir {
457cdf0e10cSrcweir     (void)rEvent;
458cdf0e10cSrcweir }
459cdf0e10cSrcweir 
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 
462cdf0e10cSrcweir 
463cdf0e10cSrcweir //----- XMouseListener --------------------------------------------------------
464cdf0e10cSrcweir 
mousePressed(const css::awt::MouseEvent & rEvent)465cdf0e10cSrcweir void SAL_CALL PresenterClock::mousePressed (const css::awt::MouseEvent& rEvent)
466cdf0e10cSrcweir     throw (css::uno::RuntimeException)
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     (void)rEvent;
469cdf0e10cSrcweir     if (rEvent.Buttons == awt::MouseButton::LEFT)
470cdf0e10cSrcweir     {
471cdf0e10cSrcweir         SetMode(mnMode+1);
472cdf0e10cSrcweir     }
473cdf0e10cSrcweir }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 
mouseReleased(const css::awt::MouseEvent & rEvent)478cdf0e10cSrcweir void SAL_CALL PresenterClock::mouseReleased (const css::awt::MouseEvent& rEvent)
479cdf0e10cSrcweir     throw (css::uno::RuntimeException)
480cdf0e10cSrcweir {
481cdf0e10cSrcweir     (void)rEvent;
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 
mouseEntered(const css::awt::MouseEvent & rEvent)487cdf0e10cSrcweir void SAL_CALL PresenterClock::mouseEntered (const css::awt::MouseEvent& rEvent)
488cdf0e10cSrcweir     throw (css::uno::RuntimeException)
489cdf0e10cSrcweir {
490cdf0e10cSrcweir     (void)rEvent;
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 
495cdf0e10cSrcweir 
mouseExited(const css::awt::MouseEvent & rEvent)496cdf0e10cSrcweir void SAL_CALL PresenterClock::mouseExited (const css::awt::MouseEvent& rEvent)
497cdf0e10cSrcweir     throw (css::uno::RuntimeException)
498cdf0e10cSrcweir {
499cdf0e10cSrcweir     (void)rEvent;
500cdf0e10cSrcweir }
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 
503cdf0e10cSrcweir 
504cdf0e10cSrcweir 
505cdf0e10cSrcweir //----- XResourceId -----------------------------------------------------------
506cdf0e10cSrcweir 
getResourceId(void)507cdf0e10cSrcweir Reference<XResourceId> SAL_CALL PresenterClock::getResourceId (void)
508cdf0e10cSrcweir     throw (RuntimeException)
509cdf0e10cSrcweir {
510cdf0e10cSrcweir     return mxViewId;
511cdf0e10cSrcweir }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 
515cdf0e10cSrcweir 
isAnchorOnly(void)516cdf0e10cSrcweir sal_Bool SAL_CALL PresenterClock::isAnchorOnly (void)
517cdf0e10cSrcweir     throw (RuntimeException)
518cdf0e10cSrcweir {
519cdf0e10cSrcweir     return false;
520cdf0e10cSrcweir }
521cdf0e10cSrcweir 
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 
524cdf0e10cSrcweir 
525cdf0e10cSrcweir //-----------------------------------------------------------------------------
526cdf0e10cSrcweir 
Resize(void)527cdf0e10cSrcweir void PresenterClock::Resize (void)
528cdf0e10cSrcweir {
529cdf0e10cSrcweir     if (mxPane.is())
530cdf0e10cSrcweir         mxCanvas = Reference<rendering::XCanvas>(mxPane->getCanvas(), UNO_QUERY);
531cdf0e10cSrcweir     if (mxWindow.is() && mxCanvas.is())
532cdf0e10cSrcweir     {
533cdf0e10cSrcweir         const awt::Rectangle aWindowBox (mxWindow->getPosSize());
534cdf0e10cSrcweir         const awt::Size aWindowSize(aWindowBox.Width,aWindowBox.Height);
535cdf0e10cSrcweir         if (mpClockPainter.get() != NULL)
536cdf0e10cSrcweir             mpClockPainter->Resize(aWindowSize);
537cdf0e10cSrcweir         if (mpClockPainter2.get() != NULL)
538cdf0e10cSrcweir             mpClockPainter2->Resize(aWindowSize);
539cdf0e10cSrcweir         mbIsResizePending = false;
540cdf0e10cSrcweir     }
541cdf0e10cSrcweir }
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 
Paint(const awt::Rectangle & rUpdateBox)546cdf0e10cSrcweir void PresenterClock::Paint (const awt::Rectangle& rUpdateBox)
547cdf0e10cSrcweir {
548cdf0e10cSrcweir     if ( ! mxCanvas.is() && mxPane.is())
549cdf0e10cSrcweir         mxCanvas = Reference<rendering::XCanvas>(mxPane->getCanvas(), UNO_QUERY);
550cdf0e10cSrcweir     if ( ! mxWindow.is()
551cdf0e10cSrcweir         || ! mxCanvas.is()
552cdf0e10cSrcweir         || ! mxCanvas->getDevice().is())
553cdf0e10cSrcweir     {
554cdf0e10cSrcweir         return;
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     try
558cdf0e10cSrcweir     {
559cdf0e10cSrcweir         if (mbIsResizePending)
560cdf0e10cSrcweir             Resize();
561cdf0e10cSrcweir 
562cdf0e10cSrcweir         Reference<rendering::XPolyPolygon2D> xUpdatePolygon (
563cdf0e10cSrcweir             PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));
564cdf0e10cSrcweir 
565cdf0e10cSrcweir         Clear(xUpdatePolygon);
566cdf0e10cSrcweir 
567cdf0e10cSrcweir         if (mpClockPainter.get() != NULL)
568cdf0e10cSrcweir             mpClockPainter->Paint(mxCanvas,
569cdf0e10cSrcweir                 maViewState,
570cdf0e10cSrcweir                 maRenderState,
571cdf0e10cSrcweir                 mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()),
572cdf0e10cSrcweir                 mnHour,
573cdf0e10cSrcweir                 mnMinute,
574cdf0e10cSrcweir                 mnSecond,
575cdf0e10cSrcweir                 mbIsShowSeconds);
576cdf0e10cSrcweir 
577cdf0e10cSrcweir         if (mpClockPainter2.get() != NULL)
578cdf0e10cSrcweir             mpClockPainter2->Paint(
579cdf0e10cSrcweir                 mxCanvas,
580cdf0e10cSrcweir                 maViewState,
581cdf0e10cSrcweir                 maRenderState,
582cdf0e10cSrcweir                 mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()),
583cdf0e10cSrcweir                 mnHour,
584cdf0e10cSrcweir                 mnMinute,
585cdf0e10cSrcweir                 mnSecond,
586cdf0e10cSrcweir                 mbIsShowSeconds);
587cdf0e10cSrcweir     }
588cdf0e10cSrcweir     catch (RuntimeException& e)
589cdf0e10cSrcweir     {
590cdf0e10cSrcweir         (void)e;
591cdf0e10cSrcweir     }
592cdf0e10cSrcweir 
593cdf0e10cSrcweir     // Make the back buffer visible.
594cdf0e10cSrcweir     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
595cdf0e10cSrcweir     if (xSpriteCanvas.is())
596cdf0e10cSrcweir         xSpriteCanvas->updateScreen(sal_False);
597cdf0e10cSrcweir }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir 
600cdf0e10cSrcweir 
601cdf0e10cSrcweir 
Clear(const Reference<rendering::XPolyPolygon2D> & rxUpdatePolygon)602cdf0e10cSrcweir void PresenterClock::Clear (const Reference<rendering::XPolyPolygon2D>& rxUpdatePolygon)
603cdf0e10cSrcweir {
604cdf0e10cSrcweir     rendering::RenderState aRenderState = maRenderState;
605cdf0e10cSrcweir     const sal_Int32 nColor (
606cdf0e10cSrcweir         mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()));
607cdf0e10cSrcweir     aRenderState.DeviceColor[0] = ((nColor&0x00ff0000) >> 16) / 255.0;
608cdf0e10cSrcweir     aRenderState.DeviceColor[1] = ((nColor&0x0000ff00) >>  8) / 255.0;
609cdf0e10cSrcweir     aRenderState.DeviceColor[2] = ((nColor&0x000000ff) >>  0) / 255.0;
610cdf0e10cSrcweir 
611cdf0e10cSrcweir     if (rxUpdatePolygon.is())
612cdf0e10cSrcweir         mxCanvas->fillPolyPolygon(
613cdf0e10cSrcweir             rxUpdatePolygon,
614cdf0e10cSrcweir             maViewState,
615cdf0e10cSrcweir             aRenderState);
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 
620cdf0e10cSrcweir 
SetMode(const sal_Int32 nMode)621cdf0e10cSrcweir void PresenterClock::SetMode (const sal_Int32 nMode)
622cdf0e10cSrcweir {
623cdf0e10cSrcweir     mnMode = nMode % 3;
624cdf0e10cSrcweir 
625cdf0e10cSrcweir     switch (mnMode)
626cdf0e10cSrcweir     {
627cdf0e10cSrcweir         case 0:
628cdf0e10cSrcweir             mpClockPainter.reset(
629cdf0e10cSrcweir                 new AnalogBitmapPainter(
630cdf0e10cSrcweir                     mxComponentContext,
631cdf0e10cSrcweir                     OUString::createFromAscii("ClockTheme")));
632cdf0e10cSrcweir             mpClockPainter2.reset();
633cdf0e10cSrcweir             break;
634cdf0e10cSrcweir 
635cdf0e10cSrcweir         case 1:
636cdf0e10cSrcweir             mpClockPainter.reset();
637cdf0e10cSrcweir             mpClockPainter2.reset(new AnalogDefaultPainter());
638cdf0e10cSrcweir             break;
639cdf0e10cSrcweir 
640cdf0e10cSrcweir         case 2:
641cdf0e10cSrcweir             mpClockPainter.reset();
642cdf0e10cSrcweir             mpClockPainter2.reset(new DigitalDefaultPainter(mpPresenterController, mxViewId));
643cdf0e10cSrcweir             break;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir         case 3:
646cdf0e10cSrcweir             mpClockPainter.reset(
647cdf0e10cSrcweir                 new AnalogBitmapPainter(
648cdf0e10cSrcweir                     mxComponentContext,
649cdf0e10cSrcweir                     OUString::createFromAscii("ClockTheme")));
650cdf0e10cSrcweir             mpClockPainter2.reset(new AnalogDefaultPainter());
651cdf0e10cSrcweir             break;
652cdf0e10cSrcweir     }
653cdf0e10cSrcweir     Resize();
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 
658cdf0e10cSrcweir 
ThrowIfDisposed(void)659cdf0e10cSrcweir void PresenterClock::ThrowIfDisposed (void)
660cdf0e10cSrcweir     throw (::com::sun::star::lang::DisposedException)
661cdf0e10cSrcweir {
662cdf0e10cSrcweir 	if (rBHelper.bDisposed || rBHelper.bInDispose)
663cdf0e10cSrcweir 	{
664cdf0e10cSrcweir         throw lang::DisposedException (
665cdf0e10cSrcweir             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
666cdf0e10cSrcweir                 "PresenterClock object has already been disposed")),
667cdf0e10cSrcweir             static_cast<uno::XWeak*>(this));
668cdf0e10cSrcweir     }
669cdf0e10cSrcweir }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir 
672cdf0e10cSrcweir 
673cdf0e10cSrcweir 
674cdf0e10cSrcweir //===== Timer =================================================================
675cdf0e10cSrcweir 
Timer(const::rtl::Reference<PresenterClock> & rpClock)676cdf0e10cSrcweir PresenterClock::Timer::Timer (const ::rtl::Reference<PresenterClock>& rpClock)
677cdf0e10cSrcweir     : OTimer(vos::TTimeValue(10), vos::TTimeValue(100/*ms*/)),
678cdf0e10cSrcweir       mpClock(rpClock)
679cdf0e10cSrcweir {
680cdf0e10cSrcweir     acquire();
681cdf0e10cSrcweir     start();
682cdf0e10cSrcweir }
683cdf0e10cSrcweir 
684cdf0e10cSrcweir 
685cdf0e10cSrcweir 
686cdf0e10cSrcweir 
~Timer(void)687cdf0e10cSrcweir PresenterClock::Timer::~Timer (void)
688cdf0e10cSrcweir {
689cdf0e10cSrcweir     if (mpClock.is())
690cdf0e10cSrcweir         Stop();
691cdf0e10cSrcweir }
692cdf0e10cSrcweir 
693cdf0e10cSrcweir 
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 
Stop(void)696cdf0e10cSrcweir void PresenterClock::Timer::Stop (void)
697cdf0e10cSrcweir {
698cdf0e10cSrcweir     mpClock = NULL;
699cdf0e10cSrcweir     stop();
700cdf0e10cSrcweir     release();
701cdf0e10cSrcweir }
702cdf0e10cSrcweir 
703cdf0e10cSrcweir 
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 
onShot(void)706cdf0e10cSrcweir void SAL_CALL PresenterClock::Timer::onShot (void)
707cdf0e10cSrcweir {
708cdf0e10cSrcweir     if (mpClock.get() != NULL)
709cdf0e10cSrcweir         mpClock->UpdateTime();
710cdf0e10cSrcweir }
711cdf0e10cSrcweir 
712cdf0e10cSrcweir 
713cdf0e10cSrcweir 
714cdf0e10cSrcweir namespace {
715cdf0e10cSrcweir 
716cdf0e10cSrcweir //=============================================================================
717cdf0e10cSrcweir 
GetDateTime(oslDateTime & rDateTime)718cdf0e10cSrcweir bool GetDateTime (oslDateTime& rDateTime)
719cdf0e10cSrcweir {
720cdf0e10cSrcweir     TimeValue aSystemTime;
721cdf0e10cSrcweir     TimeValue aLocalTime;
722cdf0e10cSrcweir     if (osl_getSystemTime(&aSystemTime))
723cdf0e10cSrcweir         if (osl_getLocalTimeFromSystemTime(&aSystemTime, &aLocalTime))
724cdf0e10cSrcweir             if (osl_getDateTimeFromTimeValue(&aLocalTime, &rDateTime))
725cdf0e10cSrcweir                 return true;
726cdf0e10cSrcweir     return false;
727cdf0e10cSrcweir }
728cdf0e10cSrcweir 
729cdf0e10cSrcweir 
730cdf0e10cSrcweir 
731cdf0e10cSrcweir 
732cdf0e10cSrcweir //===== AnalogDefaultPainter ==================================================
733cdf0e10cSrcweir 
734cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeHourHandLength = 0.65;
735cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeHourHandLength2 (-0.1);
736cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeHourHandWidth (0.055);
737cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeMinuteHandLength (-0.2);
738cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeMinuteHandLength2 (0.85);
739cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeMinuteHandWidth (0.025);
740cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeSecondHandLength (-0.25);
741cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeSecondHandLength2 (0.95);
742cdf0e10cSrcweir const double AnalogDefaultPainter::mnRelativeSecondHandWidth (0.015);
743cdf0e10cSrcweir 
AnalogDefaultPainter(void)744cdf0e10cSrcweir AnalogDefaultPainter::AnalogDefaultPainter (void)
745cdf0e10cSrcweir     : maCenter(0,0),
746cdf0e10cSrcweir       mnOuterRadius(0),
747cdf0e10cSrcweir       maSize(0,0),
748cdf0e10cSrcweir       mxBitmap()
749cdf0e10cSrcweir {
750cdf0e10cSrcweir }
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 
Paint(const Reference<rendering::XCanvas> & rxCanvas,const rendering::ViewState & rViewState,const rendering::RenderState & rRenderState,const util::Color & rBackgroundColor,const sal_Int32 nHour,const sal_Int32 nMinute,const sal_Int32 nSecond,const bool bShowSeconds)755cdf0e10cSrcweir void AnalogDefaultPainter::Paint (
756cdf0e10cSrcweir     const Reference<rendering::XCanvas>& rxCanvas,
757cdf0e10cSrcweir     const rendering::ViewState& rViewState,
758cdf0e10cSrcweir     const rendering::RenderState& rRenderState,
759cdf0e10cSrcweir     const util::Color& rBackgroundColor,
760cdf0e10cSrcweir     const sal_Int32 nHour,
761cdf0e10cSrcweir     const sal_Int32 nMinute,
762cdf0e10cSrcweir     const sal_Int32 nSecond,
763cdf0e10cSrcweir     const bool bShowSeconds)
764cdf0e10cSrcweir {
765cdf0e10cSrcweir     double nInnerRadius (0);
766cdf0e10cSrcweir     double nStrokeWidth (0.1);
767cdf0e10cSrcweir     const double nClockSize (2*mnOuterRadius);
768cdf0e10cSrcweir 
769cdf0e10cSrcweir     // Some antialiasing is created by painting into a bitmap twice the
770cdf0e10cSrcweir     // screen size and then scaling it down.
771cdf0e10cSrcweir     const sal_Int32 nSuperSampleFactor (2);
772cdf0e10cSrcweir     if ( ! mxBitmap.is())
773cdf0e10cSrcweir     {
774cdf0e10cSrcweir         mxBitmap = (rxCanvas->getDevice()->createCompatibleBitmap(
775cdf0e10cSrcweir             geometry::IntegerSize2D(
776cdf0e10cSrcweir                 maSize.Width*nSuperSampleFactor,
777cdf0e10cSrcweir                 maSize.Height*nSuperSampleFactor)));
778cdf0e10cSrcweir     }
779cdf0e10cSrcweir     Reference<rendering::XCanvas> xBitmapCanvas (mxBitmap, UNO_QUERY);
780cdf0e10cSrcweir     rendering::RenderState aRenderState(rRenderState);
781cdf0e10cSrcweir     aRenderState.AffineTransform.m00 = nSuperSampleFactor;
782cdf0e10cSrcweir     aRenderState.AffineTransform.m11 = nSuperSampleFactor;
783cdf0e10cSrcweir 
784cdf0e10cSrcweir     // Clear the background.
785cdf0e10cSrcweir     aRenderState.DeviceColor[0] = ((rBackgroundColor&0x00ff0000) >> 16) / 255.0;
786cdf0e10cSrcweir     aRenderState.DeviceColor[1] = ((rBackgroundColor&0x0000ff00) >>  8) / 255.0;
787cdf0e10cSrcweir     aRenderState.DeviceColor[2] = ((rBackgroundColor&0x000000ff) >>  0) / 255.0;
788cdf0e10cSrcweir     Reference<rendering::XPolyPolygon2D> xPolygon (
789cdf0e10cSrcweir         PresenterGeometryHelper::CreatePolygon(
790cdf0e10cSrcweir             awt::Rectangle(0,0,maSize.Width,maSize.Height),
791cdf0e10cSrcweir             xBitmapCanvas->getDevice()));
792cdf0e10cSrcweir     if (xPolygon.is())
793cdf0e10cSrcweir         xBitmapCanvas->fillPolyPolygon(xPolygon, rViewState, aRenderState);
794cdf0e10cSrcweir 
795cdf0e10cSrcweir     // Clock face and clock hands are painted in black.
796cdf0e10cSrcweir     aRenderState.DeviceColor[0] = 0;
797cdf0e10cSrcweir     aRenderState.DeviceColor[1] = 0;
798cdf0e10cSrcweir     aRenderState.DeviceColor[2] = 0;
799cdf0e10cSrcweir 
800cdf0e10cSrcweir     // Paint the clock face.
801cdf0e10cSrcweir     for (sal_Int32 nHourMark=0; nHourMark<12; ++nHourMark)
802cdf0e10cSrcweir     {
803cdf0e10cSrcweir         if (nHourMark%3 == 0)
804cdf0e10cSrcweir         {
805cdf0e10cSrcweir             nInnerRadius = 0.7 * mnOuterRadius;
806cdf0e10cSrcweir             nStrokeWidth = 0.05 * nClockSize;
807cdf0e10cSrcweir         }
808cdf0e10cSrcweir         else
809cdf0e10cSrcweir         {
810cdf0e10cSrcweir             nInnerRadius = 0.8 * mnOuterRadius;
811cdf0e10cSrcweir             nStrokeWidth = 0.03 * nClockSize;
812cdf0e10cSrcweir         }
813cdf0e10cSrcweir 
814cdf0e10cSrcweir         const double nAngle (nHourMark * 2 * M_PI / 12);
815cdf0e10cSrcweir         PaintAngledLine(nAngle, nInnerRadius, mnOuterRadius, nStrokeWidth,
816cdf0e10cSrcweir             xBitmapCanvas, rViewState, aRenderState);
817cdf0e10cSrcweir     }
818cdf0e10cSrcweir 
819cdf0e10cSrcweir     // Paint the hour hand.
820cdf0e10cSrcweir     const double nHoursAngle (((nHour%12)+nMinute/60.0) * 2 * M_PI / 12);
821cdf0e10cSrcweir     PaintAngledLine(nHoursAngle,
822cdf0e10cSrcweir         mnRelativeHourHandLength2*mnOuterRadius,
823cdf0e10cSrcweir         mnRelativeHourHandLength*mnOuterRadius,
824cdf0e10cSrcweir         mnRelativeHourHandWidth*nClockSize,
825cdf0e10cSrcweir         xBitmapCanvas, rViewState, aRenderState);
826cdf0e10cSrcweir 
827cdf0e10cSrcweir     // Paint the minute hand.
828cdf0e10cSrcweir     const double nMinutesAngle ((nMinute+nSecond/60.0) * 2 * M_PI / 60);
829cdf0e10cSrcweir     PaintAngledLine(nMinutesAngle,
830cdf0e10cSrcweir         mnRelativeMinuteHandLength2*mnOuterRadius,
831cdf0e10cSrcweir         mnRelativeMinuteHandLength*mnOuterRadius,
832cdf0e10cSrcweir         mnRelativeMinuteHandWidth*nClockSize,
833cdf0e10cSrcweir         xBitmapCanvas, rViewState, aRenderState);
834cdf0e10cSrcweir 
835cdf0e10cSrcweir     // Optionally paint the second hand.
836cdf0e10cSrcweir     if (bShowSeconds)
837cdf0e10cSrcweir     {
838cdf0e10cSrcweir         const double nSecondsAngle (nSecond * 2 * M_PI / 60);
839cdf0e10cSrcweir         PaintAngledLine(nSecondsAngle,
840cdf0e10cSrcweir             mnRelativeSecondHandLength2*mnOuterRadius,
841cdf0e10cSrcweir             mnRelativeSecondHandLength*mnOuterRadius,
842cdf0e10cSrcweir             mnRelativeSecondHandWidth*nClockSize,
843cdf0e10cSrcweir             xBitmapCanvas, rViewState, aRenderState);
844cdf0e10cSrcweir     }
845cdf0e10cSrcweir 
846cdf0e10cSrcweir     aRenderState.AffineTransform.m00 = 1.0 / nSuperSampleFactor;
847cdf0e10cSrcweir     aRenderState.AffineTransform.m11 = 1.0 / nSuperSampleFactor;
848cdf0e10cSrcweir     rxCanvas->drawBitmap(mxBitmap,rViewState,aRenderState);
849cdf0e10cSrcweir }
850cdf0e10cSrcweir 
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 
853cdf0e10cSrcweir 
PaintAngledLine(const double nAngle,const double nInnerRadius,const double nOuterRadius,const double nStrokeWidth,const Reference<rendering::XCanvas> & rxCanvas,const rendering::ViewState & rViewState,const rendering::RenderState & rRenderState)854cdf0e10cSrcweir void AnalogDefaultPainter::PaintAngledLine (
855cdf0e10cSrcweir     const double nAngle,
856cdf0e10cSrcweir     const double nInnerRadius,
857cdf0e10cSrcweir     const double nOuterRadius,
858cdf0e10cSrcweir     const double nStrokeWidth,
859cdf0e10cSrcweir     const Reference<rendering::XCanvas>& rxCanvas,
860cdf0e10cSrcweir     const rendering::ViewState& rViewState,
861cdf0e10cSrcweir     const rendering::RenderState& rRenderState)
862cdf0e10cSrcweir {
863cdf0e10cSrcweir     if ( ! rxCanvas.is())
864cdf0e10cSrcweir         return;
865cdf0e10cSrcweir 
866cdf0e10cSrcweir     rendering::StrokeAttributes aStrokeAttributes;
867cdf0e10cSrcweir     aStrokeAttributes.StrokeWidth = nStrokeWidth;
868cdf0e10cSrcweir     aStrokeAttributes.StartCapType = rendering::PathCapType::SQUARE;
869cdf0e10cSrcweir     aStrokeAttributes.EndCapType = rendering::PathCapType::SQUARE;
870cdf0e10cSrcweir     aStrokeAttributes.StartCapType = rendering::PathCapType::BUTT;
871cdf0e10cSrcweir     aStrokeAttributes.EndCapType = rendering::PathCapType::BUTT;
872cdf0e10cSrcweir     const double nCos (cos(nAngle - M_PI/2));
873cdf0e10cSrcweir     const double nSin (sin(nAngle - M_PI/2));
874cdf0e10cSrcweir 
875cdf0e10cSrcweir     Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
876cdf0e10cSrcweir     aPoints[0] = Sequence<geometry::RealPoint2D>(2);
877cdf0e10cSrcweir     aPoints[0][0] = geometry::RealPoint2D(
878cdf0e10cSrcweir         maCenter.X + nInnerRadius*nCos + 0.5,
879cdf0e10cSrcweir         maCenter.Y + nInnerRadius*nSin + 0.5);
880cdf0e10cSrcweir     aPoints[0][1] = geometry::RealPoint2D(
881cdf0e10cSrcweir         maCenter.X + nOuterRadius*nCos + 0.5,
882cdf0e10cSrcweir         maCenter.Y + nOuterRadius*nSin + 0.5);
883cdf0e10cSrcweir 
884cdf0e10cSrcweir     Reference<rendering::XPolyPolygon2D> xLine (
885cdf0e10cSrcweir         rxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPoints),
886cdf0e10cSrcweir         UNO_QUERY);
887cdf0e10cSrcweir     if ( ! xLine.is())
888cdf0e10cSrcweir         return;
889cdf0e10cSrcweir     rxCanvas->strokePolyPolygon(
890cdf0e10cSrcweir         xLine,
891cdf0e10cSrcweir         rViewState,
892cdf0e10cSrcweir         rRenderState,
893cdf0e10cSrcweir         aStrokeAttributes);
894cdf0e10cSrcweir }
895cdf0e10cSrcweir 
896cdf0e10cSrcweir 
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 
Resize(const awt::Size & rWindowSize)899cdf0e10cSrcweir void AnalogDefaultPainter::Resize (const awt::Size& rWindowSize)
900cdf0e10cSrcweir {
901cdf0e10cSrcweir     maSize = rWindowSize;
902cdf0e10cSrcweir     maCenter = geometry::RealPoint2D(rWindowSize.Width/2.0, rWindowSize.Height/2.0);
903cdf0e10cSrcweir     mnOuterRadius = ::std::min(rWindowSize.Width, rWindowSize.Height) / 2.0 - 2;
904cdf0e10cSrcweir     mxBitmap = NULL;
905cdf0e10cSrcweir }
906cdf0e10cSrcweir 
907cdf0e10cSrcweir 
908cdf0e10cSrcweir 
909cdf0e10cSrcweir 
910cdf0e10cSrcweir //===== AnalogBitmapPainter ===================================================
911cdf0e10cSrcweir 
AnalogBitmapPainter(const Reference<XComponentContext> & rxContext,const OUString & rsThemeName)912cdf0e10cSrcweir AnalogBitmapPainter::AnalogBitmapPainter (
913cdf0e10cSrcweir     const Reference<XComponentContext>& rxContext,
914cdf0e10cSrcweir     const OUString& rsThemeName)
915cdf0e10cSrcweir     : mxComponentContext(rxContext),
916cdf0e10cSrcweir       msThemeName(rsThemeName),
917cdf0e10cSrcweir       mbThemeLoaded(false),
918cdf0e10cSrcweir       mbThemeLoadingFailed(false),
919cdf0e10cSrcweir       maCenter(),
920cdf0e10cSrcweir       mnOuterRadius(),
921cdf0e10cSrcweir       maFace(),
922cdf0e10cSrcweir       maMinuteHand(),
923cdf0e10cSrcweir       maHourHand()
924cdf0e10cSrcweir {
925cdf0e10cSrcweir }
926cdf0e10cSrcweir 
927cdf0e10cSrcweir 
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 
Paint(const Reference<rendering::XCanvas> & rxCanvas,const rendering::ViewState & rViewState,const rendering::RenderState & rRenderState,const util::Color & rBackgroundColor,const sal_Int32 nHour,const sal_Int32 nMinute,const sal_Int32 nSecond,const bool bShowSeconds)930cdf0e10cSrcweir void AnalogBitmapPainter::Paint (
931cdf0e10cSrcweir     const Reference<rendering::XCanvas>& rxCanvas,
932cdf0e10cSrcweir     const rendering::ViewState& rViewState,
933cdf0e10cSrcweir     const rendering::RenderState& rRenderState,
934cdf0e10cSrcweir     const util::Color& rBackgroundColor,
935cdf0e10cSrcweir     const sal_Int32 nHour,
936cdf0e10cSrcweir     const sal_Int32 nMinute,
937cdf0e10cSrcweir     const sal_Int32 nSecond,
938cdf0e10cSrcweir     const bool bShowSeconds)
939cdf0e10cSrcweir {
940cdf0e10cSrcweir     (void)rBackgroundColor;
941cdf0e10cSrcweir     (void)nSecond;
942cdf0e10cSrcweir     (void)bShowSeconds;
943cdf0e10cSrcweir 
944cdf0e10cSrcweir     if ( ! rxCanvas.is())
945cdf0e10cSrcweir         return;
946cdf0e10cSrcweir 
947cdf0e10cSrcweir     rendering::RenderState aRenderState = rRenderState;
948cdf0e10cSrcweir 
949cdf0e10cSrcweir     try
950cdf0e10cSrcweir     {
951cdf0e10cSrcweir         PrepareBitmaps(rxCanvas);
952cdf0e10cSrcweir 
953cdf0e10cSrcweir         if (maFace.mxScaledBitmap.is())
954cdf0e10cSrcweir         {
955cdf0e10cSrcweir             aRenderState.AffineTransform = geometry::AffineMatrix2D(
956cdf0e10cSrcweir                 1,0, maCenter.X - maFace.maScaledOffset.X,
957cdf0e10cSrcweir                 0,1, maCenter.Y - maFace.maScaledOffset.Y);
958cdf0e10cSrcweir             rxCanvas->drawBitmap(maFace.mxScaledBitmap, rViewState, aRenderState);
959cdf0e10cSrcweir         }
960cdf0e10cSrcweir 
961cdf0e10cSrcweir         if (maMinuteHand.mxScaledBitmap.is())
962cdf0e10cSrcweir         {
963cdf0e10cSrcweir             const double nMinuteAngle ((nMinute+nSecond/60.0) * 2.0 * M_PI / 60.0);
964cdf0e10cSrcweir             const double nCos (cos(nMinuteAngle - M_PI/2));
965cdf0e10cSrcweir             const double nSin (sin(nMinuteAngle - M_PI/2));
966cdf0e10cSrcweir             aRenderState.AffineTransform = geometry::AffineMatrix2D(
967cdf0e10cSrcweir                 nCos,
968cdf0e10cSrcweir                 -nSin,
969cdf0e10cSrcweir                 -maMinuteHand.maScaledOffset.X*nCos
970cdf0e10cSrcweir                     + maMinuteHand.maScaledOffset.Y*nSin+maCenter.X,
971cdf0e10cSrcweir                 nSin,
972cdf0e10cSrcweir                 nCos,
973cdf0e10cSrcweir                 -maMinuteHand.maScaledOffset.X*nSin
974cdf0e10cSrcweir                     - maMinuteHand.maScaledOffset.Y*nCos+maCenter.Y);
975cdf0e10cSrcweir             rxCanvas->drawBitmap(maMinuteHand.mxScaledBitmap, rViewState, aRenderState);
976cdf0e10cSrcweir         }
977cdf0e10cSrcweir 
978cdf0e10cSrcweir         if (maHourHand.mxScaledBitmap.is())
979cdf0e10cSrcweir         {
980cdf0e10cSrcweir             const double nHoursAngle ((nHour%12+nMinute/60.0) * 2.0 * M_PI / 12.0);
981cdf0e10cSrcweir             const double nCos (cos(nHoursAngle - M_PI/2));
982cdf0e10cSrcweir             const double nSin (sin(nHoursAngle - M_PI/2));
983cdf0e10cSrcweir             aRenderState.AffineTransform = geometry::AffineMatrix2D(
984cdf0e10cSrcweir                 nCos,
985cdf0e10cSrcweir                 -nSin,
986cdf0e10cSrcweir                 -maHourHand.maScaledOffset.X*nCos+maHourHand.maScaledOffset.Y*nSin+maCenter.X,
987cdf0e10cSrcweir                 nSin,
988cdf0e10cSrcweir                 nCos,
989cdf0e10cSrcweir                 -maHourHand.maScaledOffset.X*nSin-maHourHand.maScaledOffset.Y*nCos+maCenter.Y);
990cdf0e10cSrcweir             rxCanvas->drawBitmap(maHourHand.mxScaledBitmap, rViewState, aRenderState);
991cdf0e10cSrcweir         }
992cdf0e10cSrcweir     }
993cdf0e10cSrcweir     catch(beans::UnknownPropertyException&)
994cdf0e10cSrcweir     {
995cdf0e10cSrcweir     }
996cdf0e10cSrcweir     catch(RuntimeException&)
997cdf0e10cSrcweir     {
998cdf0e10cSrcweir     }
999cdf0e10cSrcweir }
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir 
Resize(const awt::Size & rWindowSize)1004cdf0e10cSrcweir void AnalogBitmapPainter::Resize (const awt::Size& rWindowSize)
1005cdf0e10cSrcweir {
1006cdf0e10cSrcweir     maCenter = geometry::RealPoint2D(rWindowSize.Width/2.0, rWindowSize.Height/2.0);
1007cdf0e10cSrcweir     mnOuterRadius = ::std::min(rWindowSize.Width, rWindowSize.Height) / 2.0 - 2;
1008cdf0e10cSrcweir     maFace.mxScaledBitmap = NULL;
1009cdf0e10cSrcweir     maHourHand.mxScaledBitmap = NULL;
1010cdf0e10cSrcweir     maMinuteHand.mxScaledBitmap = NULL;
1011cdf0e10cSrcweir }
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir 
PrepareBitmaps(const Reference<rendering::XCanvas> & rxCanvas)1016cdf0e10cSrcweir void AnalogBitmapPainter::PrepareBitmaps (const Reference<rendering::XCanvas>& rxCanvas)
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir     if (mbThemeLoadingFailed)
1019cdf0e10cSrcweir     {
1020cdf0e10cSrcweir         // Theme loading has failed previously.  Do not try a second time.
1021cdf0e10cSrcweir         return;
1022cdf0e10cSrcweir     }
1023cdf0e10cSrcweir     if ( ! rxCanvas.is())
1024cdf0e10cSrcweir     {
1025cdf0e10cSrcweir         // No canvas => bitmaps can neither be loaded, transformed into the
1026cdf0e10cSrcweir         // right format, nor can they be painted.
1027cdf0e10cSrcweir         return;
1028cdf0e10cSrcweir     }
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir     if ( ! mbThemeLoaded)
1031cdf0e10cSrcweir     {
1032cdf0e10cSrcweir         mbThemeLoaded = true;
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir         // Get access to the clock bitmaps in the configuration.
1035cdf0e10cSrcweir         PresenterConfigurationAccess aConfiguration (
1036cdf0e10cSrcweir             mxComponentContext,
1037*79e0a548SAriel Constenla-Haile             OUString::createFromAscii("org.openoffice.Office.PresenterScreen"),
1038cdf0e10cSrcweir             PresenterConfigurationAccess::READ_ONLY);
1039cdf0e10cSrcweir 
1040cdf0e10cSrcweir         Reference<container::XNameAccess> xTheme (GetTheme(aConfiguration));
1041cdf0e10cSrcweir         if (xTheme.is())
1042cdf0e10cSrcweir             LoadBitmaps(aConfiguration, xTheme, rxCanvas);
1043cdf0e10cSrcweir         else
1044cdf0e10cSrcweir             mbThemeLoadingFailed = true;
1045cdf0e10cSrcweir     }
1046cdf0e10cSrcweir 
1047cdf0e10cSrcweir     ScaleBitmaps();
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir 
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir 
GetTheme(PresenterConfigurationAccess & rConfiguration)1053cdf0e10cSrcweir Reference<container::XNameAccess> AnalogBitmapPainter::GetTheme (
1054cdf0e10cSrcweir     PresenterConfigurationAccess& rConfiguration)
1055cdf0e10cSrcweir {
1056cdf0e10cSrcweir     Reference<container::XNameAccess> xTheme;
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir     // Get root of clock themes.
1059cdf0e10cSrcweir     Reference<container::XHierarchicalNameAccess> xClock (
1060cdf0e10cSrcweir         rConfiguration.GetConfigurationNode(
1061cdf0e10cSrcweir             OUString::createFromAscii("PresenterScreenSettings/AnalogBitmapClock")),
1062cdf0e10cSrcweir         UNO_QUERY);
1063cdf0e10cSrcweir 
1064cdf0e10cSrcweir     // Determine the name of the theme to use.
1065cdf0e10cSrcweir     OUString sCurrentThemeName (OUString::createFromAscii("DefaultTheme"));
1066cdf0e10cSrcweir     rConfiguration.GetConfigurationNode(
1067cdf0e10cSrcweir         xClock,
1068cdf0e10cSrcweir         OUString::createFromAscii("CurrentTheme")) >>= sCurrentThemeName;
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir     // Load the clock theme.
1071cdf0e10cSrcweir     Reference<container::XNameAccess> xThemes (
1072cdf0e10cSrcweir         rConfiguration.GetConfigurationNode(
1073cdf0e10cSrcweir             xClock,
1074cdf0e10cSrcweir             OUString::createFromAscii("Themes")),
1075cdf0e10cSrcweir         UNO_QUERY);
1076cdf0e10cSrcweir     if (xThemes.is())
1077cdf0e10cSrcweir     {
1078cdf0e10cSrcweir         xTheme = Reference<container::XNameAccess>(
1079cdf0e10cSrcweir             PresenterConfigurationAccess::Find(
1080cdf0e10cSrcweir                 xThemes,
1081cdf0e10cSrcweir                 ::boost::bind(&AnalogBitmapPainter::ThemeNameComparator,
1082cdf0e10cSrcweir                     this, _1, _2, sCurrentThemeName)),
1083cdf0e10cSrcweir             UNO_QUERY);
1084cdf0e10cSrcweir     }
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir     return xTheme;
1087cdf0e10cSrcweir }
1088cdf0e10cSrcweir 
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir 
ThemeNameComparator(const OUString & rsKey,const Reference<container::XNameAccess> & rxCandidate,const OUString & rsCurrentThemeName)1092cdf0e10cSrcweir bool AnalogBitmapPainter::ThemeNameComparator (
1093cdf0e10cSrcweir     const OUString& rsKey,
1094cdf0e10cSrcweir     const Reference<container::XNameAccess>& rxCandidate,
1095cdf0e10cSrcweir     const OUString& rsCurrentThemeName)
1096cdf0e10cSrcweir {
1097cdf0e10cSrcweir     (void)rsKey;
1098cdf0e10cSrcweir     if (rxCandidate.is())
1099cdf0e10cSrcweir     {
1100cdf0e10cSrcweir         OUString sThemeName;
1101cdf0e10cSrcweir         if (rxCandidate->getByName(OUString::createFromAscii("ThemeName")) >>= sThemeName)
1102cdf0e10cSrcweir         {
1103cdf0e10cSrcweir             return sThemeName == rsCurrentThemeName;
1104cdf0e10cSrcweir         }
1105cdf0e10cSrcweir     }
1106cdf0e10cSrcweir     return false;
1107cdf0e10cSrcweir }
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir 
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir 
1112cdf0e10cSrcweir 
LoadBitmaps(PresenterConfigurationAccess & rConfiguration,const Reference<container::XNameAccess> & rxClockTheme,const Reference<rendering::XCanvas> & rxCanvas)1113cdf0e10cSrcweir void AnalogBitmapPainter::LoadBitmaps (
1114cdf0e10cSrcweir     PresenterConfigurationAccess& rConfiguration,
1115cdf0e10cSrcweir     const Reference<container::XNameAccess>& rxClockTheme,
1116cdf0e10cSrcweir     const Reference<rendering::XCanvas>& rxCanvas)
1117cdf0e10cSrcweir {
1118cdf0e10cSrcweir     (void)rConfiguration;
1119cdf0e10cSrcweir     // Create the bitmap loader.
1120cdf0e10cSrcweir     Reference<lang::XMultiComponentFactory> xFactory (
1121cdf0e10cSrcweir         mxComponentContext->getServiceManager(), UNO_QUERY);
1122cdf0e10cSrcweir     if ( ! xFactory.is())
1123cdf0e10cSrcweir         return;
1124cdf0e10cSrcweir     Sequence<Any> aArguments(1);
1125cdf0e10cSrcweir     aArguments[0] <<= rxCanvas;
1126cdf0e10cSrcweir     Reference<container::XNameAccess> xBitmapLoader(
1127cdf0e10cSrcweir         xFactory->createInstanceWithArgumentsAndContext(
1128cdf0e10cSrcweir             OUString::createFromAscii("com.sun.star.drawing.PresenterWorkaroundService"),
1129cdf0e10cSrcweir             aArguments,
1130cdf0e10cSrcweir             mxComponentContext),
1131cdf0e10cSrcweir         UNO_QUERY);
1132cdf0e10cSrcweir     if ( ! xBitmapLoader.is())
1133cdf0e10cSrcweir         return;
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir     // Iterate over all entries in the bitmap list and load the bitmaps.
1137cdf0e10cSrcweir     Reference<container::XNameAccess> xBitmaps (
1138cdf0e10cSrcweir         rxClockTheme->getByName(OUString::createFromAscii("Bitmaps")),
1139cdf0e10cSrcweir         UNO_QUERY);
1140cdf0e10cSrcweir     ::std::vector<rtl::OUString> aBitmapProperties (3);
1141cdf0e10cSrcweir     aBitmapProperties[0] = OUString::createFromAscii("FileName");
1142cdf0e10cSrcweir     aBitmapProperties[1] = OUString::createFromAscii("XOffset");
1143cdf0e10cSrcweir     aBitmapProperties[2] = OUString::createFromAscii("YOffset");
1144cdf0e10cSrcweir     PresenterConfigurationAccess::ForAll(
1145cdf0e10cSrcweir         xBitmaps,
1146cdf0e10cSrcweir         aBitmapProperties,
1147cdf0e10cSrcweir         ::boost::bind(&AnalogBitmapPainter::LoadBitmap,
1148cdf0e10cSrcweir             this,
1149cdf0e10cSrcweir             _1,
1150cdf0e10cSrcweir             _2,
1151cdf0e10cSrcweir             xBitmapLoader));
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir 
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir 
LoadBitmap(const OUString & rsKey,const::std::vector<Any> & rValues,const Reference<container::XNameAccess> & rxBitmapLoader)1157cdf0e10cSrcweir void AnalogBitmapPainter::LoadBitmap (
1158cdf0e10cSrcweir     const OUString& rsKey,
1159cdf0e10cSrcweir     const ::std::vector<Any>& rValues,
1160cdf0e10cSrcweir     const Reference<container::XNameAccess>& rxBitmapLoader)
1161cdf0e10cSrcweir {
1162cdf0e10cSrcweir     if (rValues.size() == 3)
1163cdf0e10cSrcweir     {
1164cdf0e10cSrcweir         BitmapDescriptor* pDescriptor = NULL;
1165cdf0e10cSrcweir         if (rsKey == OUString::createFromAscii("Face"))
1166cdf0e10cSrcweir             pDescriptor = &maFace;
1167cdf0e10cSrcweir         else if (rsKey == OUString::createFromAscii("HourHand"))
1168cdf0e10cSrcweir             pDescriptor = &maHourHand;
1169cdf0e10cSrcweir         else if (rsKey == OUString::createFromAscii("MinuteHand"))
1170cdf0e10cSrcweir             pDescriptor = &maMinuteHand;
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir         if (pDescriptor == NULL)
1173cdf0e10cSrcweir             return;
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir         OUString sFileName;
1176cdf0e10cSrcweir         if ( ! (rValues[0] >>= sFileName))
1177cdf0e10cSrcweir             return;
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir         rValues[1] >>= pDescriptor->maOffset.X;
1180cdf0e10cSrcweir         rValues[2] >>= pDescriptor->maOffset.Y;
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir         pDescriptor->mxBitmap = Reference<rendering::XBitmap>(
1183*79e0a548SAriel Constenla-Haile             rxBitmapLoader->getByName(sFileName), UNO_QUERY);
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir         if ( ! pDescriptor->mxBitmap.is())
1186cdf0e10cSrcweir             mbThemeLoadingFailed = true;
1187cdf0e10cSrcweir     }
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir 
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir 
ScaleBitmaps(void)1193cdf0e10cSrcweir void AnalogBitmapPainter::ScaleBitmaps (void)
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir     if (mbThemeLoadingFailed)
1196cdf0e10cSrcweir         return;
1197cdf0e10cSrcweir     if ( ! maFace.mxBitmap.is())
1198cdf0e10cSrcweir         return;
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir     const geometry::IntegerSize2D aFaceSize (maFace.mxBitmap->getSize());
1201cdf0e10cSrcweir     const sal_Int32 nSize = std::max(aFaceSize.Width, aFaceSize.Height);
1202cdf0e10cSrcweir     const double nScale = mnOuterRadius*2 / nSize;
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir     BitmapDescriptor* aDescriptors[3] = { &maFace, &maHourHand, &maMinuteHand };
1205cdf0e10cSrcweir     for (int nIndex=0; nIndex<3; ++nIndex)
1206cdf0e10cSrcweir     {
1207cdf0e10cSrcweir         BitmapDescriptor& rDescriptor (*aDescriptors[nIndex]);
1208cdf0e10cSrcweir         if ( ! rDescriptor.mxScaledBitmap.is() && rDescriptor.mxBitmap.is())
1209cdf0e10cSrcweir         {
1210cdf0e10cSrcweir             const geometry::IntegerSize2D aBitmapSize (rDescriptor.mxBitmap->getSize());
1211cdf0e10cSrcweir             rDescriptor.mxScaledBitmap = rDescriptor.mxBitmap->getScaledBitmap(
1212cdf0e10cSrcweir                 geometry::RealSize2D(aBitmapSize.Width*nScale, aBitmapSize.Height*nScale),
1213cdf0e10cSrcweir                 sal_False);
1214cdf0e10cSrcweir             rDescriptor.maScaledOffset = geometry::RealPoint2D(
1215cdf0e10cSrcweir                 rDescriptor.maOffset.X * nScale,
1216cdf0e10cSrcweir                 rDescriptor.maOffset.Y * nScale);
1217cdf0e10cSrcweir         }
1218cdf0e10cSrcweir     }
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir 
1224cdf0e10cSrcweir //===== DigitalDefaultPainter =================================================
1225cdf0e10cSrcweir 
DigitalDefaultPainter(const::rtl::Reference<PresenterController> & rpPresenterController,const Reference<XResourceId> & rxViewId)1226cdf0e10cSrcweir DigitalDefaultPainter::DigitalDefaultPainter (
1227cdf0e10cSrcweir     const ::rtl::Reference<PresenterController>& rpPresenterController,
1228cdf0e10cSrcweir     const Reference<XResourceId>& rxViewId)
1229cdf0e10cSrcweir     :  mpPresenterController(rpPresenterController),
1230cdf0e10cSrcweir        mbIs24HourFormat(false),
1231cdf0e10cSrcweir        mbIsAdaptFontSize(true),
1232cdf0e10cSrcweir        mxFont(),
1233cdf0e10cSrcweir        maWindowSize(0,0),
1234cdf0e10cSrcweir        msViewURL(rxViewId.is() ? rxViewId->getResourceURL() : OUString())
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir }
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir 
~DigitalDefaultPainter(void)1241cdf0e10cSrcweir DigitalDefaultPainter::~DigitalDefaultPainter (void)
1242cdf0e10cSrcweir {
1243cdf0e10cSrcweir }
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir 
Paint(const Reference<rendering::XCanvas> & rxCanvas,const rendering::ViewState & rViewState,const rendering::RenderState & rRenderState,const util::Color & rBackgroundColor,const sal_Int32 nHour,const sal_Int32 nMinute,const sal_Int32 nSecond,const bool bIsShowSeconds)1248cdf0e10cSrcweir void DigitalDefaultPainter::Paint (
1249cdf0e10cSrcweir     const Reference<rendering::XCanvas>& rxCanvas,
1250cdf0e10cSrcweir     const rendering::ViewState& rViewState,
1251cdf0e10cSrcweir     const rendering::RenderState& rRenderState,
1252cdf0e10cSrcweir     const util::Color& rBackgroundColor,
1253cdf0e10cSrcweir     const sal_Int32 nHour,
1254cdf0e10cSrcweir     const sal_Int32 nMinute,
1255cdf0e10cSrcweir     const sal_Int32 nSecond,
1256cdf0e10cSrcweir     const bool bIsShowSeconds)
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir     (void)rBackgroundColor;
1259cdf0e10cSrcweir     (void)rRenderState;
1260cdf0e10cSrcweir 
1261cdf0e10cSrcweir     if ( ! mxFont.is())
1262cdf0e10cSrcweir         CreateFont(rxCanvas,bIsShowSeconds);
1263cdf0e10cSrcweir     if ( ! mxFont.is())
1264cdf0e10cSrcweir         return;
1265cdf0e10cSrcweir 
1266cdf0e10cSrcweir     OUString sText;
1267cdf0e10cSrcweir 
1268cdf0e10cSrcweir     if (mbIs24HourFormat)
1269cdf0e10cSrcweir         sText = OUString::valueOf(nHour);
1270cdf0e10cSrcweir     else
1271cdf0e10cSrcweir     {
1272cdf0e10cSrcweir         sText = OUString::valueOf(nHour>12 ? nHour-12 : nHour);
1273cdf0e10cSrcweir     }
1274cdf0e10cSrcweir     sText += OUString::createFromAscii(":");
1275cdf0e10cSrcweir     const OUString sMinutes (OUString::valueOf(nMinute));
1276cdf0e10cSrcweir     switch (sMinutes.getLength())
1277cdf0e10cSrcweir     {
1278cdf0e10cSrcweir         case 1 :
1279cdf0e10cSrcweir             sText += OUString::createFromAscii("0") + sMinutes;
1280cdf0e10cSrcweir             break;
1281cdf0e10cSrcweir         case 2:
1282cdf0e10cSrcweir             sText += sMinutes;
1283cdf0e10cSrcweir             break;
1284cdf0e10cSrcweir 
1285cdf0e10cSrcweir         default:
1286cdf0e10cSrcweir             return;
1287cdf0e10cSrcweir     }
1288cdf0e10cSrcweir     if (bIsShowSeconds)
1289cdf0e10cSrcweir     {
1290cdf0e10cSrcweir         sText += OUString::createFromAscii(":");
1291cdf0e10cSrcweir         const OUString sSeconds (OUString::valueOf(nSecond));
1292cdf0e10cSrcweir         switch (sSeconds.getLength())
1293cdf0e10cSrcweir         {
1294cdf0e10cSrcweir             case 1 :
1295cdf0e10cSrcweir                 sText += OUString::createFromAscii("0") + sSeconds;
1296cdf0e10cSrcweir                 break;
1297cdf0e10cSrcweir             case 2:
1298cdf0e10cSrcweir                 sText += sSeconds;
1299cdf0e10cSrcweir                 break;
1300cdf0e10cSrcweir 
1301cdf0e10cSrcweir             default:
1302cdf0e10cSrcweir                 return;
1303cdf0e10cSrcweir         }
1304cdf0e10cSrcweir     }
1305cdf0e10cSrcweir 
1306cdf0e10cSrcweir     rendering::StringContext aContext (
1307cdf0e10cSrcweir         sText,
1308cdf0e10cSrcweir         0,
1309cdf0e10cSrcweir         sText.getLength());
1310cdf0e10cSrcweir     Reference<rendering::XTextLayout> xLayout (mxFont->createTextLayout(
1311cdf0e10cSrcweir         aContext,
1312cdf0e10cSrcweir         rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1313cdf0e10cSrcweir         0));
1314cdf0e10cSrcweir     if ( ! xLayout.is())
1315cdf0e10cSrcweir         return;
1316cdf0e10cSrcweir     geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir 
1319cdf0e10cSrcweir     rendering::RenderState aRenderState(
1320cdf0e10cSrcweir         geometry::AffineMatrix2D(1,0,0, 0,1,0),
1321cdf0e10cSrcweir         NULL,
1322cdf0e10cSrcweir         Sequence<double>(4),
1323cdf0e10cSrcweir         rendering::CompositeOperation::SOURCE);
1324cdf0e10cSrcweir 
1325cdf0e10cSrcweir     util::Color aFontColor (mpPresenterController->GetViewFontColor(msViewURL));
1326cdf0e10cSrcweir     PresenterCanvasHelper::SetDeviceColor(aRenderState, aFontColor);
1327cdf0e10cSrcweir     aRenderState.AffineTransform.m02
1328cdf0e10cSrcweir         = (maWindowSize.Width - (aBox.X2-aBox.X1+1)) / 2 - aBox.X1;
1329cdf0e10cSrcweir     aRenderState.AffineTransform.m12
1330cdf0e10cSrcweir         = (maWindowSize.Height - (aBox.Y2-aBox.Y1+1)) / 2 - aBox.Y1;
1331cdf0e10cSrcweir     rxCanvas->drawText(
1332cdf0e10cSrcweir         aContext,
1333cdf0e10cSrcweir         mxFont,
1334cdf0e10cSrcweir         rViewState,
1335cdf0e10cSrcweir         aRenderState,
1336cdf0e10cSrcweir         rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
1337cdf0e10cSrcweir }
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir 
Resize(const awt::Size & rSize)1342cdf0e10cSrcweir void DigitalDefaultPainter::Resize (const awt::Size& rSize)
1343cdf0e10cSrcweir {
1344cdf0e10cSrcweir     if (maWindowSize.Width != rSize.Width || maWindowSize.Height != rSize.Height)
1345cdf0e10cSrcweir     {
1346cdf0e10cSrcweir         maWindowSize = rSize;
1347cdf0e10cSrcweir         if (mbIsAdaptFontSize)
1348cdf0e10cSrcweir             mxFont = NULL;
1349cdf0e10cSrcweir     }
1350cdf0e10cSrcweir }
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir 
1354cdf0e10cSrcweir 
CreateFont(const Reference<rendering::XCanvas> & rxCanvas,const bool bIsShowSeconds)1355cdf0e10cSrcweir void DigitalDefaultPainter::CreateFont (
1356cdf0e10cSrcweir     const Reference<rendering::XCanvas>& rxCanvas,
1357cdf0e10cSrcweir     const bool bIsShowSeconds)
1358cdf0e10cSrcweir {
1359cdf0e10cSrcweir     if (rxCanvas.is()
1360cdf0e10cSrcweir         && rxCanvas->getDevice().is()
1361cdf0e10cSrcweir         && maWindowSize.Width>0
1362cdf0e10cSrcweir         && maWindowSize.Height>0)
1363cdf0e10cSrcweir     {
1364cdf0e10cSrcweir         // Create a time template for determinging the right font size.
1365cdf0e10cSrcweir         // Assume that 0 is the widest digit or that all digits have the
1366cdf0e10cSrcweir         // same width.
1367cdf0e10cSrcweir         OUString sTimeTemplate;
1368cdf0e10cSrcweir         // For the case that not all digits have the same width, create
1369cdf0e10cSrcweir         // different templates for 12 and 24 hour mode.
1370cdf0e10cSrcweir         if (mbIs24HourFormat)
1371cdf0e10cSrcweir             sTimeTemplate = OUString::createFromAscii("20");
1372cdf0e10cSrcweir         else
1373cdf0e10cSrcweir             sTimeTemplate = OUString::createFromAscii("10");
1374cdf0e10cSrcweir         if (bIsShowSeconds)
1375cdf0e10cSrcweir             sTimeTemplate += OUString::createFromAscii(":00:00");
1376cdf0e10cSrcweir         else
1377cdf0e10cSrcweir             sTimeTemplate += OUString::createFromAscii(":00");
1378cdf0e10cSrcweir 
1379cdf0e10cSrcweir         rendering::StringContext aContext (
1380cdf0e10cSrcweir             sTimeTemplate,
1381cdf0e10cSrcweir             0,
1382cdf0e10cSrcweir             sTimeTemplate.getLength());
1383cdf0e10cSrcweir 
1384cdf0e10cSrcweir         // When the font size is adapted to the window size (as large as
1385cdf0e10cSrcweir         // possible without overlapping) then that is done in a four step
1386cdf0e10cSrcweir         // process:
1387cdf0e10cSrcweir         // 1. Create a font in a default size, e.g. 10pt.
1388cdf0e10cSrcweir         // 2. Determine a scale factor from enlarging the text bounding box
1389cdf0e10cSrcweir         // to maximal size inside the window.
1390cdf0e10cSrcweir         // 3. Create a new font by scaling the default size with the factor
1391cdf0e10cSrcweir         // calculated in step 2.
1392cdf0e10cSrcweir         // 4. Text may be rendered differently in different sizes.
1393cdf0e10cSrcweir         // Therefore repeat step 2 and 3 once.  More iterations may lead to
1394cdf0e10cSrcweir         // even better results but probably not to visible differences.
1395cdf0e10cSrcweir         rendering::FontRequest aFontRequest (mpPresenterController->GetViewFontRequest(msViewURL));
1396cdf0e10cSrcweir         // TODO: use font from view style from configuration
1397cdf0e10cSrcweir         aFontRequest.CellSize = 10;
1398cdf0e10cSrcweir 
1399cdf0e10cSrcweir         for (sal_Int32 nLoop=0; nLoop<3; ++nLoop)
1400cdf0e10cSrcweir         {
1401cdf0e10cSrcweir             mxFont = rxCanvas->createFont(
1402cdf0e10cSrcweir                 aFontRequest,
1403cdf0e10cSrcweir                 Sequence<beans::PropertyValue>(),
1404cdf0e10cSrcweir                 geometry::Matrix2D(1,0,0,1));
1405cdf0e10cSrcweir             if (mxFont.is())
1406cdf0e10cSrcweir             {
1407cdf0e10cSrcweir                 Reference<rendering::XTextLayout> xLayout (mxFont->createTextLayout(
1408cdf0e10cSrcweir                     aContext,
1409cdf0e10cSrcweir                     rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
1410cdf0e10cSrcweir                     0));
1411cdf0e10cSrcweir 
1412cdf0e10cSrcweir                 if ( ! xLayout.is())
1413cdf0e10cSrcweir                     break;
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir                 geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
1416cdf0e10cSrcweir                 if (aBox.X2<=aBox.X1 || aBox.Y2<=aBox.Y1)
1417cdf0e10cSrcweir                     break;
1418cdf0e10cSrcweir                 const double nHorizontalFactor = maWindowSize.Width / (aBox.X2-aBox.X1+1);
1419cdf0e10cSrcweir                 const double nVerticalFactor = maWindowSize.Height / (aBox.Y2-aBox.Y1+1);
1420cdf0e10cSrcweir                 aFontRequest.CellSize *= ::std::min(nHorizontalFactor,nVerticalFactor);
1421cdf0e10cSrcweir             }
1422cdf0e10cSrcweir         }
1423cdf0e10cSrcweir     }
1424cdf0e10cSrcweir }
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir } // end of anonymous namespace
1428cdf0e10cSrcweir 
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir } } // end of namespace ::sdext::presenter
1431