1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <boost/current_function.hpp>
32*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
33*cdf0e10cSrcweir #include <vcl/svapp.hxx>
34*cdf0e10cSrcweir #include <vcl/gdimtf.hxx>
35*cdf0e10cSrcweir #include <vcl/virdev.hxx>
36*cdf0e10cSrcweir #include <vcl/metric.hxx>
37*cdf0e10cSrcweir #include <cppcanvas/vclfactory.hxx>
38*cdf0e10cSrcweir #include <cppcanvas/basegfxfactory.hxx>
39*cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include <comphelper/anytostring.hxx>
42*cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <com/sun/star/awt/MouseButton.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/awt/MouseEvent.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/rendering/XBitmap.hpp>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include "eventqueue.hxx"
49*cdf0e10cSrcweir #include "screenupdater.hxx"
50*cdf0e10cSrcweir #include "eventmultiplexer.hxx"
51*cdf0e10cSrcweir #include "activitiesqueue.hxx"
52*cdf0e10cSrcweir #include "slideshowcontext.hxx"
53*cdf0e10cSrcweir #include "mouseeventhandler.hxx"
54*cdf0e10cSrcweir #include "rehearsetimingsactivity.hxx"
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir #include <boost/bind.hpp>
57*cdf0e10cSrcweir #include <algorithm>
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir using namespace com::sun::star;
60*cdf0e10cSrcweir using namespace com::sun::star::uno;
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir namespace slideshow {
63*cdf0e10cSrcweir namespace internal {
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir class RehearseTimingsActivity::WakeupEvent : public Event,
66*cdf0e10cSrcweir                                              private ::boost::noncopyable
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir public:
69*cdf0e10cSrcweir     WakeupEvent( boost::shared_ptr< ::canvas::tools::ElapsedTime > const& pTimeBase,
70*cdf0e10cSrcweir                  ActivitySharedPtr const&                                 rActivity,
71*cdf0e10cSrcweir                  ActivitiesQueue &                                        rActivityQueue ) :
72*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
73*cdf0e10cSrcweir         Event(::rtl::OUString::createFromAscii("WakeupEvent")),
74*cdf0e10cSrcweir #endif
75*cdf0e10cSrcweir         maTimer(pTimeBase),
76*cdf0e10cSrcweir         mnNextTime(0.0),
77*cdf0e10cSrcweir         mpActivity(rActivity),
78*cdf0e10cSrcweir         mrActivityQueue( rActivityQueue )
79*cdf0e10cSrcweir     {}
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir     virtual void dispose() {}
82*cdf0e10cSrcweir     virtual bool fire()
83*cdf0e10cSrcweir     {
84*cdf0e10cSrcweir         ActivitySharedPtr pActivity( mpActivity.lock() );
85*cdf0e10cSrcweir         if( !pActivity )
86*cdf0e10cSrcweir             return false;
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir         return mrActivityQueue.addActivity( pActivity );
89*cdf0e10cSrcweir     }
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir     virtual bool isCharged() const { return true; }
92*cdf0e10cSrcweir     virtual double getActivationTime( double nCurrentTime ) const
93*cdf0e10cSrcweir     {
94*cdf0e10cSrcweir         const double nElapsedTime( maTimer.getElapsedTime() );
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir         return ::std::max( nCurrentTime,
97*cdf0e10cSrcweir                            nCurrentTime - nElapsedTime + mnNextTime );
98*cdf0e10cSrcweir     }
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir     /// Start the internal timer
101*cdf0e10cSrcweir     void start() { maTimer.reset(); }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir     /** Set the next timeout this object should generate.
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir         @param nextTime
106*cdf0e10cSrcweir         Absolute time, measured from the last start() call,
107*cdf0e10cSrcweir         when this event should wakeup the Activity again. If
108*cdf0e10cSrcweir         your time is relative, simply call start() just before
109*cdf0e10cSrcweir         every setNextTimeout() call.
110*cdf0e10cSrcweir     */
111*cdf0e10cSrcweir     void setNextTimeout( double nextTime ) { mnNextTime = nextTime; }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir private:
114*cdf0e10cSrcweir     ::canvas::tools::ElapsedTime    maTimer;
115*cdf0e10cSrcweir     double                          mnNextTime;
116*cdf0e10cSrcweir     boost::weak_ptr<Activity>       mpActivity;
117*cdf0e10cSrcweir     ActivitiesQueue&                mrActivityQueue;
118*cdf0e10cSrcweir };
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir class RehearseTimingsActivity::MouseHandler : public MouseEventHandler,
121*cdf0e10cSrcweir                                               private boost::noncopyable
122*cdf0e10cSrcweir {
123*cdf0e10cSrcweir public:
124*cdf0e10cSrcweir     explicit MouseHandler( RehearseTimingsActivity& rta );
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir     void reset();
127*cdf0e10cSrcweir     bool hasBeenClicked() const { return mbHasBeenClicked; }
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir     // MouseEventHandler
130*cdf0e10cSrcweir     virtual bool handleMousePressed( awt::MouseEvent const & evt );
131*cdf0e10cSrcweir     virtual bool handleMouseReleased( awt::MouseEvent const & evt );
132*cdf0e10cSrcweir     virtual bool handleMouseEntered( awt::MouseEvent const & evt );
133*cdf0e10cSrcweir     virtual bool handleMouseExited( awt::MouseEvent const & evt );
134*cdf0e10cSrcweir     virtual bool handleMouseDragged( awt::MouseEvent const & evt );
135*cdf0e10cSrcweir     virtual bool handleMouseMoved( awt::MouseEvent const & evt );
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir private:
138*cdf0e10cSrcweir     bool isInArea( com::sun::star::awt::MouseEvent const & evt ) const;
139*cdf0e10cSrcweir     void updatePressedState( const bool pressedState ) const;
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     RehearseTimingsActivity& mrActivity;
142*cdf0e10cSrcweir     bool                     mbHasBeenClicked;
143*cdf0e10cSrcweir     bool                     mbMouseStartedInArea;
144*cdf0e10cSrcweir };
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir const sal_Int32 LEFT_BORDER_SPACE  = 10;
147*cdf0e10cSrcweir const sal_Int32 LOWER_BORDER_SPACE = 30;
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir RehearseTimingsActivity::RehearseTimingsActivity( const SlideShowContext& rContext ) :
150*cdf0e10cSrcweir     mrEventQueue(rContext.mrEventQueue),
151*cdf0e10cSrcweir     mrScreenUpdater(rContext.mrScreenUpdater),
152*cdf0e10cSrcweir     mrEventMultiplexer(rContext.mrEventMultiplexer),
153*cdf0e10cSrcweir     mrActivitiesQueue(rContext.mrActivitiesQueue),
154*cdf0e10cSrcweir     maElapsedTime( rContext.mrEventQueue.getTimer() ),
155*cdf0e10cSrcweir     maViews(),
156*cdf0e10cSrcweir     maSpriteRectangle(),
157*cdf0e10cSrcweir     maFont( Application::GetSettings().GetStyleSettings().GetInfoFont() ),
158*cdf0e10cSrcweir     mpWakeUpEvent(),
159*cdf0e10cSrcweir     mpMouseHandler(),
160*cdf0e10cSrcweir     maSpriteSizePixel(),
161*cdf0e10cSrcweir     mnYOffset(0),
162*cdf0e10cSrcweir     mbActive(false),
163*cdf0e10cSrcweir     mbDrawPressed(false)
164*cdf0e10cSrcweir {
165*cdf0e10cSrcweir     maFont.SetHeight( maFont.GetHeight() * 2 );
166*cdf0e10cSrcweir     maFont.SetWidth( maFont.GetWidth() * 2 );
167*cdf0e10cSrcweir     maFont.SetAlign( ALIGN_BASELINE );
168*cdf0e10cSrcweir     maFont.SetColor( COL_BLACK );
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir     // determine sprite size (in pixel):
171*cdf0e10cSrcweir     VirtualDevice blackHole;
172*cdf0e10cSrcweir     blackHole.EnableOutput(false);
173*cdf0e10cSrcweir     blackHole.SetFont( maFont );
174*cdf0e10cSrcweir     blackHole.SetMapMode( MAP_PIXEL );
175*cdf0e10cSrcweir     Rectangle rect;
176*cdf0e10cSrcweir     const FontMetric metric( blackHole.GetFontMetric() );
177*cdf0e10cSrcweir     blackHole.GetTextBoundRect(
178*cdf0e10cSrcweir         rect, String(RTL_CONSTASCII_USTRINGPARAM("XX:XX:XX")) );
179*cdf0e10cSrcweir     maSpriteSizePixel.setX( rect.getWidth() * 12 / 10 );
180*cdf0e10cSrcweir     maSpriteSizePixel.setY( metric.GetLineHeight() * 11 / 10 );
181*cdf0e10cSrcweir     mnYOffset = (metric.GetAscent() + (metric.GetLineHeight() / 20));
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir     std::for_each( rContext.mrViewContainer.begin(),
184*cdf0e10cSrcweir                    rContext.mrViewContainer.end(),
185*cdf0e10cSrcweir                    boost::bind( &RehearseTimingsActivity::viewAdded,
186*cdf0e10cSrcweir                                 this,
187*cdf0e10cSrcweir                                 _1 ));
188*cdf0e10cSrcweir }
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir RehearseTimingsActivity::~RehearseTimingsActivity()
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir     try
193*cdf0e10cSrcweir     {
194*cdf0e10cSrcweir         stop();
195*cdf0e10cSrcweir     }
196*cdf0e10cSrcweir     catch (uno::Exception &)
197*cdf0e10cSrcweir     {
198*cdf0e10cSrcweir         OSL_ENSURE( false, rtl::OUStringToOString(
199*cdf0e10cSrcweir                         comphelper::anyToString(
200*cdf0e10cSrcweir                             cppu::getCaughtException() ),
201*cdf0e10cSrcweir                         RTL_TEXTENCODING_UTF8 ).getStr() );
202*cdf0e10cSrcweir     }
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir boost::shared_ptr<RehearseTimingsActivity> RehearseTimingsActivity::create(
206*cdf0e10cSrcweir     const SlideShowContext& rContext )
207*cdf0e10cSrcweir {
208*cdf0e10cSrcweir     boost::shared_ptr<RehearseTimingsActivity> pActivity(
209*cdf0e10cSrcweir         new RehearseTimingsActivity( rContext ));
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir     pActivity->mpMouseHandler.reset(
212*cdf0e10cSrcweir         new MouseHandler(*pActivity.get()) );
213*cdf0e10cSrcweir     pActivity->mpWakeUpEvent.reset(
214*cdf0e10cSrcweir         new WakeupEvent( rContext.mrEventQueue.getTimer(),
215*cdf0e10cSrcweir                          pActivity,
216*cdf0e10cSrcweir                          rContext.mrActivitiesQueue ));
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir     rContext.mrEventMultiplexer.addViewHandler( pActivity );
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir     return pActivity;
221*cdf0e10cSrcweir }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir void RehearseTimingsActivity::start()
224*cdf0e10cSrcweir {
225*cdf0e10cSrcweir     maElapsedTime.reset();
226*cdf0e10cSrcweir     mbDrawPressed = false;
227*cdf0e10cSrcweir     mbActive = true;
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir     // paint and show all sprites:
230*cdf0e10cSrcweir     paintAllSprites();
231*cdf0e10cSrcweir     for_each_sprite( boost::bind( &cppcanvas::Sprite::show, _1 ) );
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir     mrActivitiesQueue.addActivity( shared_from_this() );
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir     mpMouseHandler->reset();
236*cdf0e10cSrcweir     mrEventMultiplexer.addClickHandler(
237*cdf0e10cSrcweir         mpMouseHandler, 42 /* highest prio of all, > 3.0 */ );
238*cdf0e10cSrcweir     mrEventMultiplexer.addMouseMoveHandler(
239*cdf0e10cSrcweir         mpMouseHandler, 42 /* highest prio of all, > 3.0 */ );
240*cdf0e10cSrcweir }
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir double RehearseTimingsActivity::stop()
243*cdf0e10cSrcweir {
244*cdf0e10cSrcweir     mrEventMultiplexer.removeMouseMoveHandler( mpMouseHandler );
245*cdf0e10cSrcweir     mrEventMultiplexer.removeClickHandler( mpMouseHandler );
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir     mbActive = false; // will be removed from queue
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir     for_each_sprite( boost::bind( &cppcanvas::Sprite::hide, _1 ) );
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir     return maElapsedTime.getElapsedTime();
252*cdf0e10cSrcweir }
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir bool RehearseTimingsActivity::hasBeenClicked() const
255*cdf0e10cSrcweir {
256*cdf0e10cSrcweir     if (mpMouseHandler)
257*cdf0e10cSrcweir         return mpMouseHandler->hasBeenClicked();
258*cdf0e10cSrcweir     return false;
259*cdf0e10cSrcweir }
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir // Disposable:
262*cdf0e10cSrcweir void RehearseTimingsActivity::dispose()
263*cdf0e10cSrcweir {
264*cdf0e10cSrcweir     stop();
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir     mpWakeUpEvent.reset();
267*cdf0e10cSrcweir     mpMouseHandler.reset();
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir     ViewsVecT().swap( maViews );
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir // Activity:
273*cdf0e10cSrcweir double RehearseTimingsActivity::calcTimeLag() const
274*cdf0e10cSrcweir {
275*cdf0e10cSrcweir     return 0.0;
276*cdf0e10cSrcweir }
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir bool RehearseTimingsActivity::perform()
279*cdf0e10cSrcweir {
280*cdf0e10cSrcweir     if( !isActive() )
281*cdf0e10cSrcweir         return false;
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir     if( !mpWakeUpEvent )
284*cdf0e10cSrcweir         return false;
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     mpWakeUpEvent->start();
287*cdf0e10cSrcweir     mpWakeUpEvent->setNextTimeout( 0.5 );
288*cdf0e10cSrcweir     mrEventQueue.addEvent( mpWakeUpEvent );
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir     paintAllSprites();
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir     // sprites changed, need screen update
293*cdf0e10cSrcweir     mrScreenUpdater.notifyUpdate();
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir     return false; // don't reinsert, WakeupEvent will perform
296*cdf0e10cSrcweir                   // that after the given timeout
297*cdf0e10cSrcweir }
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir bool RehearseTimingsActivity::isActive() const
300*cdf0e10cSrcweir {
301*cdf0e10cSrcweir     return mbActive;
302*cdf0e10cSrcweir }
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir void RehearseTimingsActivity::dequeued()
305*cdf0e10cSrcweir {
306*cdf0e10cSrcweir     // not used here
307*cdf0e10cSrcweir }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir void RehearseTimingsActivity::end()
310*cdf0e10cSrcweir {
311*cdf0e10cSrcweir     if (isActive())
312*cdf0e10cSrcweir     {
313*cdf0e10cSrcweir         stop();
314*cdf0e10cSrcweir         mbActive = false;
315*cdf0e10cSrcweir     }
316*cdf0e10cSrcweir }
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir basegfx::B2DRange RehearseTimingsActivity::calcSpriteRectangle( UnoViewSharedPtr const& rView ) const
319*cdf0e10cSrcweir {
320*cdf0e10cSrcweir     const Reference<rendering::XBitmap> xBitmap( rView->getCanvas()->getUNOCanvas(),
321*cdf0e10cSrcweir                                                  UNO_QUERY );
322*cdf0e10cSrcweir     if( !xBitmap.is() )
323*cdf0e10cSrcweir         return basegfx::B2DRange();
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     const geometry::IntegerSize2D realSize( xBitmap->getSize() );
326*cdf0e10cSrcweir     // pixel:
327*cdf0e10cSrcweir     basegfx::B2DPoint spritePos(
328*cdf0e10cSrcweir         std::min<sal_Int32>( realSize.Width, LEFT_BORDER_SPACE ),
329*cdf0e10cSrcweir         std::max<sal_Int32>( 0, realSize.Height - maSpriteSizePixel.getY()
330*cdf0e10cSrcweir                                                 - LOWER_BORDER_SPACE ) );
331*cdf0e10cSrcweir     basegfx::B2DHomMatrix transformation( rView->getTransformation() );
332*cdf0e10cSrcweir     transformation.invert();
333*cdf0e10cSrcweir     spritePos *= transformation;
334*cdf0e10cSrcweir     basegfx::B2DSize spriteSize( maSpriteSizePixel.getX(),
335*cdf0e10cSrcweir                                  maSpriteSizePixel.getY() );
336*cdf0e10cSrcweir     spriteSize *= transformation;
337*cdf0e10cSrcweir     return basegfx::B2DRange(
338*cdf0e10cSrcweir         spritePos.getX(), spritePos.getY(),
339*cdf0e10cSrcweir         spritePos.getX() + spriteSize.getX(),
340*cdf0e10cSrcweir         spritePos.getY() + spriteSize.getY() );
341*cdf0e10cSrcweir }
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir void RehearseTimingsActivity::viewAdded( const UnoViewSharedPtr& rView )
344*cdf0e10cSrcweir {
345*cdf0e10cSrcweir     cppcanvas::CustomSpriteSharedPtr sprite(
346*cdf0e10cSrcweir         rView->createSprite( basegfx::B2DSize(
347*cdf0e10cSrcweir                                  maSpriteSizePixel.getX()+2,
348*cdf0e10cSrcweir                                  maSpriteSizePixel.getY()+2 ),
349*cdf0e10cSrcweir                              1001.0 )); // sprite should be in front of all
350*cdf0e10cSrcweir                                         // other sprites
351*cdf0e10cSrcweir     sprite->setAlpha( 0.8 );
352*cdf0e10cSrcweir     const basegfx::B2DRange spriteRectangle(
353*cdf0e10cSrcweir         calcSpriteRectangle( rView ) );
354*cdf0e10cSrcweir     sprite->move( basegfx::B2DPoint(
355*cdf0e10cSrcweir                       spriteRectangle.getMinX(),
356*cdf0e10cSrcweir                       spriteRectangle.getMinY() ) );
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir     if( maViews.empty() )
359*cdf0e10cSrcweir         maSpriteRectangle = spriteRectangle;
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir     maViews.push_back( ViewsVecT::value_type( rView, sprite ) );
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir     if (isActive())
364*cdf0e10cSrcweir         sprite->show();
365*cdf0e10cSrcweir }
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir void RehearseTimingsActivity::viewRemoved( const UnoViewSharedPtr& rView )
368*cdf0e10cSrcweir {
369*cdf0e10cSrcweir     maViews.erase(
370*cdf0e10cSrcweir         std::remove_if(
371*cdf0e10cSrcweir             maViews.begin(), maViews.end(),
372*cdf0e10cSrcweir             boost::bind(
373*cdf0e10cSrcweir                 std::equal_to<UnoViewSharedPtr>(),
374*cdf0e10cSrcweir                 rView,
375*cdf0e10cSrcweir                 // select view:
376*cdf0e10cSrcweir                 boost::bind( std::select1st<ViewsVecT::value_type>(), _1 ))),
377*cdf0e10cSrcweir         maViews.end() );
378*cdf0e10cSrcweir }
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir void RehearseTimingsActivity::viewChanged( const UnoViewSharedPtr& rView )
381*cdf0e10cSrcweir {
382*cdf0e10cSrcweir     // find entry corresponding to modified view
383*cdf0e10cSrcweir     ViewsVecT::iterator aModifiedEntry(
384*cdf0e10cSrcweir         std::find_if(
385*cdf0e10cSrcweir             maViews.begin(),
386*cdf0e10cSrcweir             maViews.end(),
387*cdf0e10cSrcweir             boost::bind(
388*cdf0e10cSrcweir                 std::equal_to<UnoViewSharedPtr>(),
389*cdf0e10cSrcweir                 rView,
390*cdf0e10cSrcweir                 // select view:
391*cdf0e10cSrcweir                 boost::bind( std::select1st<ViewsVecT::value_type>(), _1 ))));
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     OSL_ASSERT( aModifiedEntry != maViews.end() );
394*cdf0e10cSrcweir     if( aModifiedEntry == maViews.end() )
395*cdf0e10cSrcweir         return;
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir     // new sprite pos, transformation might have changed:
398*cdf0e10cSrcweir     maSpriteRectangle = calcSpriteRectangle( rView );
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir     // reposition sprite:
401*cdf0e10cSrcweir     aModifiedEntry->second->move( maSpriteRectangle.getMinimum() );
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir     // sprites changed, need screen update
404*cdf0e10cSrcweir     mrScreenUpdater.notifyUpdate( rView );
405*cdf0e10cSrcweir }
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir void RehearseTimingsActivity::viewsChanged()
408*cdf0e10cSrcweir {
409*cdf0e10cSrcweir     if( !maViews.empty() )
410*cdf0e10cSrcweir     {
411*cdf0e10cSrcweir         // new sprite pos, transformation might have changed:
412*cdf0e10cSrcweir         maSpriteRectangle = calcSpriteRectangle( maViews.front().first );
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir         // reposition sprites
415*cdf0e10cSrcweir         for_each_sprite( boost::bind( &cppcanvas::Sprite::move,
416*cdf0e10cSrcweir                                       _1,
417*cdf0e10cSrcweir                                       boost::cref(maSpriteRectangle.getMinimum())) );
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir         // sprites changed, need screen update
420*cdf0e10cSrcweir         mrScreenUpdater.notifyUpdate();
421*cdf0e10cSrcweir     }
422*cdf0e10cSrcweir }
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir void RehearseTimingsActivity::paintAllSprites() const
425*cdf0e10cSrcweir {
426*cdf0e10cSrcweir     for_each_sprite(
427*cdf0e10cSrcweir         boost::bind( &RehearseTimingsActivity::paint, this,
428*cdf0e10cSrcweir                      // call getContentCanvas() on each sprite:
429*cdf0e10cSrcweir                      boost::bind(
430*cdf0e10cSrcweir                          &cppcanvas::CustomSprite::getContentCanvas, _1 ) ) );
431*cdf0e10cSrcweir }
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir void RehearseTimingsActivity::paint( cppcanvas::CanvasSharedPtr const & canvas ) const
434*cdf0e10cSrcweir {
435*cdf0e10cSrcweir     // build timer string:
436*cdf0e10cSrcweir     const sal_Int32 nTimeSecs =
437*cdf0e10cSrcweir         static_cast<sal_Int32>(maElapsedTime.getElapsedTime());
438*cdf0e10cSrcweir     rtl::OUStringBuffer buf;
439*cdf0e10cSrcweir     sal_Int32 n = (nTimeSecs / 3600);
440*cdf0e10cSrcweir     if (n < 10)
441*cdf0e10cSrcweir         buf.append( static_cast<sal_Unicode>('0') );
442*cdf0e10cSrcweir     buf.append( n );
443*cdf0e10cSrcweir     buf.append( static_cast<sal_Unicode>(':') );
444*cdf0e10cSrcweir     n = ((nTimeSecs % 3600) / 60);
445*cdf0e10cSrcweir     if (n < 10)
446*cdf0e10cSrcweir         buf.append( static_cast<sal_Unicode>('0') );
447*cdf0e10cSrcweir     buf.append( n );
448*cdf0e10cSrcweir     buf.append( static_cast<sal_Unicode>(':') );
449*cdf0e10cSrcweir     n = (nTimeSecs % 60);
450*cdf0e10cSrcweir     if (n < 10)
451*cdf0e10cSrcweir         buf.append( static_cast<sal_Unicode>('0') );
452*cdf0e10cSrcweir     buf.append( n );
453*cdf0e10cSrcweir     const rtl::OUString time = buf.makeStringAndClear();
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir 	// create the MetaFile:
456*cdf0e10cSrcweir 	GDIMetaFile metaFile;
457*cdf0e10cSrcweir 	VirtualDevice blackHole;
458*cdf0e10cSrcweir 	metaFile.Record( &blackHole );
459*cdf0e10cSrcweir     metaFile.SetPrefSize( Size( 1, 1 ) );
460*cdf0e10cSrcweir 	blackHole.EnableOutput(false);
461*cdf0e10cSrcweir     blackHole.SetMapMode( MAP_PIXEL );
462*cdf0e10cSrcweir     blackHole.SetFont( maFont );
463*cdf0e10cSrcweir     Rectangle rect = Rectangle( 0,0,
464*cdf0e10cSrcweir                                 maSpriteSizePixel.getX(),
465*cdf0e10cSrcweir                                 maSpriteSizePixel.getY());
466*cdf0e10cSrcweir     if (mbDrawPressed)
467*cdf0e10cSrcweir     {
468*cdf0e10cSrcweir         blackHole.SetTextColor( COL_BLACK );
469*cdf0e10cSrcweir         blackHole.SetFillColor( COL_LIGHTGRAY );
470*cdf0e10cSrcweir         blackHole.SetLineColor( COL_GRAY );
471*cdf0e10cSrcweir     }
472*cdf0e10cSrcweir     else
473*cdf0e10cSrcweir     {
474*cdf0e10cSrcweir         blackHole.SetTextColor( COL_BLACK );
475*cdf0e10cSrcweir         blackHole.SetFillColor( COL_WHITE );
476*cdf0e10cSrcweir         blackHole.SetLineColor( COL_GRAY );
477*cdf0e10cSrcweir     }
478*cdf0e10cSrcweir     blackHole.DrawRect( rect );
479*cdf0e10cSrcweir     blackHole.GetTextBoundRect( rect, time );
480*cdf0e10cSrcweir     blackHole.DrawText(
481*cdf0e10cSrcweir         Point( (maSpriteSizePixel.getX() - rect.getWidth()) / 2,
482*cdf0e10cSrcweir                mnYOffset ), time );
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir 	metaFile.Stop();
485*cdf0e10cSrcweir 	metaFile.WindStart();
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir     cppcanvas::RendererSharedPtr renderer(
488*cdf0e10cSrcweir         cppcanvas::VCLFactory::getInstance().createRenderer(
489*cdf0e10cSrcweir             canvas, metaFile, cppcanvas::Renderer::Parameters() ) );
490*cdf0e10cSrcweir     const bool succ = renderer->draw();
491*cdf0e10cSrcweir     OSL_ASSERT( succ );
492*cdf0e10cSrcweir     (void)succ;
493*cdf0e10cSrcweir }
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir RehearseTimingsActivity::MouseHandler::MouseHandler( RehearseTimingsActivity& rta ) :
497*cdf0e10cSrcweir     mrActivity(rta),
498*cdf0e10cSrcweir     mbHasBeenClicked(false),
499*cdf0e10cSrcweir     mbMouseStartedInArea(false)
500*cdf0e10cSrcweir {}
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir void RehearseTimingsActivity::MouseHandler::reset()
503*cdf0e10cSrcweir {
504*cdf0e10cSrcweir     mbHasBeenClicked = false;
505*cdf0e10cSrcweir     mbMouseStartedInArea = false;
506*cdf0e10cSrcweir }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir bool RehearseTimingsActivity::MouseHandler::isInArea(
509*cdf0e10cSrcweir     awt::MouseEvent const & evt ) const
510*cdf0e10cSrcweir {
511*cdf0e10cSrcweir     return mrActivity.maSpriteRectangle.isInside(
512*cdf0e10cSrcweir         basegfx::B2DPoint( evt.X, evt.Y ) );
513*cdf0e10cSrcweir }
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir void RehearseTimingsActivity::MouseHandler::updatePressedState(
516*cdf0e10cSrcweir     const bool pressedState ) const
517*cdf0e10cSrcweir {
518*cdf0e10cSrcweir     if( pressedState != mrActivity.mbDrawPressed )
519*cdf0e10cSrcweir     {
520*cdf0e10cSrcweir         mrActivity.mbDrawPressed = pressedState;
521*cdf0e10cSrcweir         mrActivity.paintAllSprites();
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir         mrActivity.mrScreenUpdater.notifyUpdate();
524*cdf0e10cSrcweir     }
525*cdf0e10cSrcweir }
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir // MouseEventHandler
528*cdf0e10cSrcweir bool RehearseTimingsActivity::MouseHandler::handleMousePressed(
529*cdf0e10cSrcweir     awt::MouseEvent const & evt )
530*cdf0e10cSrcweir {
531*cdf0e10cSrcweir     if( evt.Buttons == awt::MouseButton::LEFT && isInArea(evt) )
532*cdf0e10cSrcweir     {
533*cdf0e10cSrcweir         mbMouseStartedInArea = true;
534*cdf0e10cSrcweir         updatePressedState(true);
535*cdf0e10cSrcweir         return true; // consume event
536*cdf0e10cSrcweir     }
537*cdf0e10cSrcweir     return false;
538*cdf0e10cSrcweir }
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir bool RehearseTimingsActivity::MouseHandler::handleMouseReleased(
541*cdf0e10cSrcweir     awt::MouseEvent const & evt )
542*cdf0e10cSrcweir {
543*cdf0e10cSrcweir     if( evt.Buttons == awt::MouseButton::LEFT && mbMouseStartedInArea )
544*cdf0e10cSrcweir     {
545*cdf0e10cSrcweir         mbHasBeenClicked = isInArea(evt); // fini if in
546*cdf0e10cSrcweir         mbMouseStartedInArea = false;
547*cdf0e10cSrcweir         updatePressedState(false);
548*cdf0e10cSrcweir         if( !mbHasBeenClicked )
549*cdf0e10cSrcweir             return true; // consume event, else next slide (manual advance)
550*cdf0e10cSrcweir     }
551*cdf0e10cSrcweir     return false;
552*cdf0e10cSrcweir }
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir bool RehearseTimingsActivity::MouseHandler::handleMouseEntered(
555*cdf0e10cSrcweir     awt::MouseEvent const & /*evt*/ )
556*cdf0e10cSrcweir {
557*cdf0e10cSrcweir     return false;
558*cdf0e10cSrcweir }
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir bool RehearseTimingsActivity::MouseHandler::handleMouseExited(
561*cdf0e10cSrcweir     awt::MouseEvent const & /*evt*/ )
562*cdf0e10cSrcweir {
563*cdf0e10cSrcweir     return false;
564*cdf0e10cSrcweir }
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir bool RehearseTimingsActivity::MouseHandler::handleMouseDragged(
567*cdf0e10cSrcweir     awt::MouseEvent const & evt )
568*cdf0e10cSrcweir {
569*cdf0e10cSrcweir     if( mbMouseStartedInArea )
570*cdf0e10cSrcweir         updatePressedState( isInArea(evt) );
571*cdf0e10cSrcweir     return false;
572*cdf0e10cSrcweir }
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir bool RehearseTimingsActivity::MouseHandler::handleMouseMoved(
575*cdf0e10cSrcweir     awt::MouseEvent const & /*evt*/ )
576*cdf0e10cSrcweir {
577*cdf0e10cSrcweir     return false;
578*cdf0e10cSrcweir }
579*cdf0e10cSrcweir 
580*cdf0e10cSrcweir } // namespace internal
581*cdf0e10cSrcweir } // namespace presentation
582