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