1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <canvas/debug.hxx>
23 #include <tools/diagnose_ex.h>
25 #include <comphelper/anytostring.hxx>
26 #include <cppuhelper/exc_hlp.hxx>
28 #include <com/sun/star/awt/SystemPointer.hpp>
29 #include <com/sun/star/awt/MouseButton.hpp>
30 #include <com/sun/star/awt/MouseEvent.hpp>
32 #include <boost/bind.hpp>
34 #include "delayevent.hxx"
35 #include "usereventqueue.hxx"
36 #include "cursormanager.hxx"
37 #include "slideshowexceptions.hxx"
46 using namespace com::sun::star
;
48 /* Implementation of UserEventQueue class */
55 typedef std::vector
<EventSharedPtr
> ImpEventVector
;
56 typedef std::queue
<EventSharedPtr
> ImpEventQueue
;
57 typedef std::map
<uno::Reference
<animations::XAnimationNode
>,
58 ImpEventVector
> ImpAnimationEventMap
;
59 typedef std::map
<ShapeSharedPtr
, ImpEventQueue
,
60 Shape::lessThanShape
> ImpShapeEventMap
;
62 // MouseEventHandler base class, not consuming any event:
63 class MouseEventHandler_
: public MouseEventHandler
66 virtual bool handleMousePressed( awt::MouseEvent
const& /*e*/ ) SAL_OVERRIDE
{ return false;}
67 virtual bool handleMouseReleased( awt::MouseEvent
const& /*e*/) SAL_OVERRIDE
{ return false;}
68 virtual bool handleMouseEntered( awt::MouseEvent
const& /*e*/ ) SAL_OVERRIDE
{ return false;}
69 virtual bool handleMouseExited( awt::MouseEvent
const& /*e*/ ) SAL_OVERRIDE
{ return false; }
70 virtual bool handleMouseDragged( awt::MouseEvent
const& /*e*/ ) SAL_OVERRIDE
{ return false;}
71 virtual bool handleMouseMoved( awt::MouseEvent
const& /*e*/ ) SAL_OVERRIDE
{ return false; }
74 /** @return one event has been posted
76 template <typename ContainerT
>
77 bool fireSingleEvent( ContainerT
& rQueue
, EventQueue
& rEventQueue
)
79 // post next event in given queue:
80 while (! rQueue
.empty())
82 EventSharedPtr
const pEvent(rQueue
.front());
85 // skip all inactive events (as the purpose of
86 // nextEventFromQueue() is to activate the next
87 // event, and events which return false on
88 // isCharged() will never be activated by the
90 if(pEvent
->isCharged())
91 return rEventQueue
.addEvent( pEvent
);
93 return false; // no more (active) events in queue
96 /** @return at least one event has been posted
98 template <typename ContainerT
>
99 bool fireAllEvents( ContainerT
& rQueue
, EventQueue
& rEventQueue
)
101 bool bFiredAny
= false;
102 while (fireSingleEvent( rQueue
, rEventQueue
))
114 void addEvent( const EventSharedPtr
& rEvent
)
116 maEvents
.push( rEvent
);
120 ImpEventQueue maEvents
;
125 class AllAnimationEventHandler
: public AnimationEventHandler
128 AllAnimationEventHandler( EventQueue
& rEventQueue
) :
129 mrEventQueue( rEventQueue
),
130 maAnimationEventMap()
133 virtual bool handleAnimationEvent( const AnimationNodeSharedPtr
& rNode
) SAL_OVERRIDE
135 ENSURE_OR_RETURN_FALSE(
137 "AllAnimationEventHandler::handleAnimationEvent(): Invalid node" );
141 ImpAnimationEventMap::iterator aIter
;
142 if( (aIter
=maAnimationEventMap
.find(
143 rNode
->getXAnimationNode() )) != maAnimationEventMap
.end() )
145 ImpEventVector
& rVec( aIter
->second
);
147 bRet
= !rVec
.empty();
149 // registered node found -> fire all events in the vector
150 std::for_each( rVec
.begin(), rVec
.end(),
151 boost::bind( &EventQueue::addEvent
,
152 boost::ref( mrEventQueue
), _1
) );
160 void addEvent( const EventSharedPtr
& rEvent
,
161 const uno::Reference
< animations::XAnimationNode
>& xNode
)
163 ImpAnimationEventMap::iterator aIter
;
164 if( (aIter
=maAnimationEventMap
.find( xNode
)) ==
165 maAnimationEventMap
.end() )
167 // no entry for this animation -> create one
168 aIter
= maAnimationEventMap
.insert(
169 ImpAnimationEventMap::value_type( xNode
,
170 ImpEventVector() ) ).first
;
173 // add new event to queue
174 aIter
->second
.push_back( rEvent
);
178 EventQueue
& mrEventQueue
;
179 ImpAnimationEventMap maAnimationEventMap
;
182 class ClickEventHandler
: public MouseEventHandler_
,
184 public EventContainer
187 ClickEventHandler( EventQueue
& rEventQueue
) :
189 mrEventQueue( rEventQueue
),
190 mbAdvanceOnClick( true )
193 void setAdvanceOnClick( bool bAdvanceOnClick
)
195 mbAdvanceOnClick
= bAdvanceOnClick
;
200 // triggered by API calls, e.g. space bar
201 virtual bool handleEvent() SAL_OVERRIDE
203 return handleEvent_impl();
206 // triggered by mouse release:
207 virtual bool handleMouseReleased( const awt::MouseEvent
& evt
) SAL_OVERRIDE
209 if(evt
.Buttons
!= awt::MouseButton::LEFT
)
212 if( mbAdvanceOnClick
) {
214 return handleEvent_impl();
217 return false; // advance-on-click disabled
221 // triggered by both:
222 virtual bool handleEvent_impl()
225 return fireSingleEvent( maEvents
, mrEventQueue
);
229 EventQueue
& mrEventQueue
;
230 bool mbAdvanceOnClick
;
233 class SkipEffectEventHandler
: public ClickEventHandler
236 SkipEffectEventHandler( EventQueue
& rEventQueue
,
237 EventMultiplexer
& rEventMultiplexer
)
238 : ClickEventHandler(rEventQueue
),
239 mrEventQueue(rEventQueue
),
240 mrEventMultiplexer(rEventMultiplexer
),
241 mbSkipTriggersNextEffect(true) {}
243 /** Remember to trigger (or not to trigger) the next effect after the
244 current effect is skipped.
246 void setSkipTriggersNextEffect (const bool bSkipTriggersNextEffect
)
247 { mbSkipTriggersNextEffect
= bSkipTriggersNextEffect
; }
249 /// Skip the current effect but do not trigger the next effect.
250 void skipEffect() { handleEvent_impl(false); }
253 virtual bool handleEvent_impl() SAL_OVERRIDE
255 return handleEvent_impl(true);
258 bool handleEvent_impl (bool bNotifyNextEffect
)
260 // fire all events, so animation nodes can register their
261 // next effect listeners:
262 if(fireAllEvents( maEvents
, mrEventQueue
))
264 if (mbSkipTriggersNextEffect
&& bNotifyNextEffect
)
266 // then simulate a next effect event: this skip effect
267 // handler is triggered upon next effect events (multiplexer
268 // prio=-1)! Posting a notifyNextEffect() here is only safe
269 // (we don't run into busy loop), because we assume that
270 // someone has registerered above for next effects
271 // (multiplexer prio=0) at the user event queue.
272 return mrEventQueue
.addEventWhenQueueIsEmpty(
273 makeEvent( boost::bind( &EventMultiplexer::notifyNextEffect
,
274 boost::ref(mrEventMultiplexer
) ),
275 "EventMultiplexer::notifyNextEffect") );
284 EventQueue
& mrEventQueue
;
285 EventMultiplexer
& mrEventMultiplexer
;
286 bool mbSkipTriggersNextEffect
;
289 /** Base class to share some common code between
290 ShapeClickEventHandler and MouseMoveHandler
292 @derive override necessary MouseEventHandler interface methods,
293 call sendEvent() method to actually process the event.
295 class MouseHandlerBase
: public MouseEventHandler_
298 MouseHandlerBase( EventQueue
& rEventQueue
) :
299 mrEventQueue( rEventQueue
),
303 void addEvent( const EventSharedPtr
& rEvent
,
304 const ShapeSharedPtr
& rShape
)
306 ImpShapeEventMap::iterator aIter
;
307 if( (aIter
=maShapeEventMap
.find( rShape
)) == maShapeEventMap
.end() )
309 // no entry for this shape -> create one
310 aIter
= maShapeEventMap
.insert(
311 ImpShapeEventMap::value_type( rShape
,
312 ImpEventQueue() ) ).first
;
315 // add new event to queue
316 aIter
->second
.push( rEvent
);
320 bool hitTest( const awt::MouseEvent
& e
,
321 ImpShapeEventMap::reverse_iterator
& o_rHitShape
)
323 // find hit shape in map
324 const basegfx::B2DPoint
aPosition( e
.X
, e
.Y
);
326 // find matching shape (scan reversely, to coarsely match
328 ImpShapeEventMap::reverse_iterator
aCurrShape(maShapeEventMap
.rbegin());
329 const ImpShapeEventMap::reverse_iterator
aEndShape( maShapeEventMap
.rend() );
330 while( aCurrShape
!= aEndShape
)
332 // TODO(F2): Get proper geometry polygon from the
333 // shape, to avoid having areas outside the shape
334 // react on the mouse
335 if( aCurrShape
->first
->getBounds().isInside( aPosition
) &&
336 aCurrShape
->first
->isVisible() )
338 // shape hit, and shape is visible - report a
340 o_rHitShape
= aCurrShape
;
347 return false; // nothing hit
350 bool sendEvent( ImpShapeEventMap::reverse_iterator
& io_rHitShape
)
352 // take next event from queue
353 const bool bRet( fireSingleEvent( io_rHitShape
->second
,
356 // clear shape entry, if its queue is
357 // empty. This is important, since the shapes
358 // are held by shared ptr, and might otherwise
359 // not get released, even after their owning
360 // slide is long gone.
361 if( io_rHitShape
->second
.empty() )
363 // this looks funny, since ::std::map does
364 // provide an erase( iterator )
365 // method. Unfortunately, C++ does not
366 // declare the obvious erase(
367 // reverse_iterator ) needed here (missing
368 // orthogonality, eh?)
369 maShapeEventMap
.erase( io_rHitShape
->first
);
375 bool processEvent( const awt::MouseEvent
& e
)
377 ImpShapeEventMap::reverse_iterator aCurrShape
;
379 if( hitTest( e
, aCurrShape
) )
380 return sendEvent( aCurrShape
);
382 return false; // did not handle the event
386 EventQueue
& mrEventQueue
;
387 ImpShapeEventMap maShapeEventMap
;
390 class ShapeClickEventHandler
: public MouseHandlerBase
393 ShapeClickEventHandler( CursorManager
& rCursorManager
,
394 EventQueue
& rEventQueue
) :
395 MouseHandlerBase( rEventQueue
),
396 mrCursorManager( rCursorManager
)
399 virtual bool handleMouseReleased( const awt::MouseEvent
& e
) SAL_OVERRIDE
401 if(e
.Buttons
!= awt::MouseButton::LEFT
)
403 return processEvent( e
);
406 virtual bool handleMouseMoved( const awt::MouseEvent
& e
) SAL_OVERRIDE
408 // TODO(P2): Maybe buffer last shape touched
410 // if we have a shape click event, and the mouse
411 // hovers over this shape, change cursor to hand
412 ImpShapeEventMap::reverse_iterator aDummy
;
413 if( hitTest( e
, aDummy
) )
414 mrCursorManager
.requestCursor( awt::SystemPointer::REFHAND
);
416 return false; // we don't /eat/ this event. Lower prio
417 // handler should see it, too.
421 CursorManager
& mrCursorManager
;
424 class MouseEnterHandler
: public MouseHandlerBase
427 MouseEnterHandler( EventQueue
& rEventQueue
)
428 : MouseHandlerBase( rEventQueue
),
431 virtual bool handleMouseMoved( const awt::MouseEvent
& e
) SAL_OVERRIDE
433 // TODO(P2): Maybe buffer last shape touched, and
434 // check against that _first_
436 ImpShapeEventMap::reverse_iterator aCurr
;
437 if( hitTest( e
, aCurr
) )
439 if( aCurr
->first
!= mpLastShape
)
441 // we actually hit a shape, and it's different
442 // from the previous one - thus we just
443 // entered it, raise event
445 mpLastShape
= aCurr
->first
;
450 // don't hit no shape - thus, last shape is NULL
454 return false; // we don't /eat/ this event. Lower prio
455 // handler should see it, too.
459 ShapeSharedPtr mpLastShape
;
462 class MouseLeaveHandler
: public MouseHandlerBase
465 MouseLeaveHandler( EventQueue
& rEventQueue
)
466 : MouseHandlerBase( rEventQueue
),
469 virtual bool handleMouseMoved( const awt::MouseEvent
& e
) SAL_OVERRIDE
471 // TODO(P2): Maybe buffer last shape touched, and
472 // check against that _first_
474 ImpShapeEventMap::reverse_iterator aCurr
;
475 if( hitTest( e
, aCurr
) )
481 if( maLastIter
->first
)
483 // last time, we were over a shape, now we're
484 // not - we thus just left that shape, raise
486 sendEvent( maLastIter
);
489 // in any case, when we hit this else-branch: no
490 // shape hit, thus have to clear maLastIter
491 maLastIter
= ImpShapeEventMap::reverse_iterator();
494 return false; // we don't /eat/ this event. Lower prio
495 // handler should see it, too.
499 ImpShapeEventMap::reverse_iterator maLastIter
;
502 template< typename Handler
, typename Functor
>
503 void UserEventQueue::registerEvent(
504 boost::shared_ptr
< Handler
>& rHandler
,
505 const EventSharedPtr
& rEvent
,
506 const Functor
& rRegistrationFunctor
)
508 ENSURE_OR_THROW( rEvent
,
509 "UserEventQueue::registerEvent(): Invalid event" );
513 rHandler
.reset( new Handler( mrEventQueue
) );
514 // register handler on EventMultiplexer
515 rRegistrationFunctor( rHandler
);
518 rHandler
->addEvent( rEvent
);
521 template< typename Handler
, typename Arg
, typename Functor
>
522 void UserEventQueue::registerEvent(
523 boost::shared_ptr
< Handler
>& rHandler
,
524 const EventSharedPtr
& rEvent
,
526 const Functor
& rRegistrationFunctor
)
528 ENSURE_OR_THROW( rEvent
,
529 "UserEventQueue::registerEvent(): Invalid event" );
533 rHandler
.reset( new Handler( mrEventQueue
) );
535 // register handler on EventMultiplexer
536 rRegistrationFunctor( rHandler
);
539 rHandler
->addEvent( rEvent
, rArg
);
544 UserEventQueue::UserEventQueue( EventMultiplexer
& rMultiplexer
,
545 EventQueue
& rEventQueue
,
546 CursorManager
& rCursorManager
)
547 : mrMultiplexer( rMultiplexer
),
548 mrEventQueue( rEventQueue
),
549 mrCursorManager( rCursorManager
),
550 mpAnimationStartEventHandler(),
551 mpAnimationEndEventHandler(),
552 mpAudioStoppedEventHandler(),
553 mpClickEventHandler(),
554 mpSkipEffectEventHandler(),
555 mpDoubleClickEventHandler(),
556 mpMouseEnterHandler(),
557 mpMouseLeaveHandler(),
558 mbAdvanceOnClick( true )
562 UserEventQueue::~UserEventQueue()
566 // unregister all handlers
569 catch (uno::Exception
&) {
570 OSL_FAIL( OUStringToOString(
571 comphelper::anyToString(
572 cppu::getCaughtException() ),
573 RTL_TEXTENCODING_UTF8
).getStr() );
577 void UserEventQueue::clear()
579 // unregister and delete all handlers
580 if( mpAnimationStartEventHandler
) {
581 mrMultiplexer
.removeAnimationStartHandler(
582 mpAnimationStartEventHandler
);
583 mpAnimationStartEventHandler
.reset();
585 if( mpAnimationEndEventHandler
) {
586 mrMultiplexer
.removeAnimationEndHandler( mpAnimationEndEventHandler
);
587 mpAnimationEndEventHandler
.reset();
589 if( mpAudioStoppedEventHandler
) {
590 mrMultiplexer
.removeAudioStoppedHandler( mpAudioStoppedEventHandler
);
591 mpAudioStoppedEventHandler
.reset();
593 if( mpShapeClickEventHandler
) {
594 mrMultiplexer
.removeClickHandler( mpShapeClickEventHandler
);
595 mrMultiplexer
.removeMouseMoveHandler( mpShapeClickEventHandler
);
596 mpShapeClickEventHandler
.reset();
598 if( mpClickEventHandler
) {
599 mrMultiplexer
.removeClickHandler( mpClickEventHandler
);
600 mrMultiplexer
.removeNextEffectHandler( mpClickEventHandler
);
601 mpClickEventHandler
.reset();
603 if(mpSkipEffectEventHandler
) {
604 mrMultiplexer
.removeClickHandler( mpSkipEffectEventHandler
);
605 mrMultiplexer
.removeNextEffectHandler( mpSkipEffectEventHandler
);
606 mpSkipEffectEventHandler
.reset();
608 if( mpShapeDoubleClickEventHandler
) {
609 mrMultiplexer
.removeDoubleClickHandler( mpShapeDoubleClickEventHandler
);
610 mrMultiplexer
.removeMouseMoveHandler( mpShapeDoubleClickEventHandler
);
611 mpShapeDoubleClickEventHandler
.reset();
613 if( mpDoubleClickEventHandler
) {
614 mrMultiplexer
.removeDoubleClickHandler( mpDoubleClickEventHandler
);
615 mpDoubleClickEventHandler
.reset();
617 if( mpMouseEnterHandler
) {
618 mrMultiplexer
.removeMouseMoveHandler( mpMouseEnterHandler
);
619 mpMouseEnterHandler
.reset();
621 if( mpMouseLeaveHandler
) {
622 mrMultiplexer
.removeMouseMoveHandler( mpMouseLeaveHandler
);
623 mpMouseLeaveHandler
.reset();
627 void UserEventQueue::setAdvanceOnClick( bool bAdvanceOnClick
)
629 mbAdvanceOnClick
= bAdvanceOnClick
;
631 // forward to handler, if existing. Otherwise, the handler
632 // creation will do the forwarding.
633 if( mpClickEventHandler
)
634 mpClickEventHandler
->setAdvanceOnClick( bAdvanceOnClick
);
637 void UserEventQueue::registerAnimationStartEvent(
638 const EventSharedPtr
& rEvent
,
639 const uno::Reference
< animations::XAnimationNode
>& xNode
)
641 registerEvent( mpAnimationStartEventHandler
,
644 boost::bind( &EventMultiplexer::addAnimationStartHandler
,
645 boost::ref( mrMultiplexer
), _1
) );
648 void UserEventQueue::registerAnimationEndEvent(
649 const EventSharedPtr
& rEvent
,
650 const uno::Reference
<animations::XAnimationNode
>& xNode
)
652 registerEvent( mpAnimationEndEventHandler
,
655 boost::bind( &EventMultiplexer::addAnimationEndHandler
,
656 boost::ref( mrMultiplexer
), _1
) );
659 void UserEventQueue::registerAudioStoppedEvent(
660 const EventSharedPtr
& rEvent
,
661 const uno::Reference
<animations::XAnimationNode
>& xNode
)
663 registerEvent( mpAudioStoppedEventHandler
,
666 boost::bind( &EventMultiplexer::addAudioStoppedHandler
,
667 boost::ref( mrMultiplexer
), _1
) );
670 void UserEventQueue::registerShapeClickEvent( const EventSharedPtr
& rEvent
,
671 const ShapeSharedPtr
& rShape
)
675 "UserEventQueue::registerShapeClickEvent(): Invalid event" );
677 if( !mpShapeClickEventHandler
)
680 mpShapeClickEventHandler
.reset(
681 new ShapeClickEventHandler(mrCursorManager
,
684 // register handler on EventMultiplexer
685 mrMultiplexer
.addClickHandler( mpShapeClickEventHandler
, 1.0 );
686 mrMultiplexer
.addMouseMoveHandler( mpShapeClickEventHandler
, 1.0 );
689 mpShapeClickEventHandler
->addEvent( rEvent
, rShape
);
693 class ClickEventRegistrationFunctor
696 ClickEventRegistrationFunctor( EventMultiplexer
& rMultiplexer
,
698 bool bAdvanceOnClick
)
699 : mrMultiplexer( rMultiplexer
),
701 mbAdvanceOnClick( bAdvanceOnClick
) {}
703 void operator()( const boost::shared_ptr
<ClickEventHandler
>& rHandler
)const
705 // register the handler on _two_ sources: we want the
706 // nextEffect events, e.g. space bar, to trigger clicks, as well!
707 mrMultiplexer
.addClickHandler( rHandler
, mnPrio
);
708 mrMultiplexer
.addNextEffectHandler( rHandler
, mnPrio
);
710 // forward advance-on-click state to newly
711 // generated handler (that's the only reason why
712 // we're called here)
713 rHandler
->setAdvanceOnClick( mbAdvanceOnClick
);
717 EventMultiplexer
& mrMultiplexer
;
719 bool const mbAdvanceOnClick
;
723 void UserEventQueue::registerNextEffectEvent( const EventSharedPtr
& rEvent
)
725 // TODO: better name may be mpNextEffectEventHandler? then we have
726 // next effect (=> waiting to be started)
727 // skip effect (skipping the currently running one)
728 // rewind effect (rewinding back running one and waiting (again)
730 registerEvent( mpClickEventHandler
,
732 ClickEventRegistrationFunctor( mrMultiplexer
,
733 0.0 /* default prio */,
734 mbAdvanceOnClick
) );
737 void UserEventQueue::registerSkipEffectEvent(
738 EventSharedPtr
const & pEvent
,
739 const bool bSkipTriggersNextEffect
)
741 if(!mpSkipEffectEventHandler
)
743 mpSkipEffectEventHandler
.reset(
744 new SkipEffectEventHandler( mrEventQueue
, mrMultiplexer
) );
745 // register the handler on _two_ sources: we want the
746 // nextEffect events, e.g. space bar, to trigger clicks, as well!
747 mrMultiplexer
.addClickHandler( mpSkipEffectEventHandler
,
748 -1.0 /* prio below default */ );
749 mrMultiplexer
.addNextEffectHandler( mpSkipEffectEventHandler
,
750 -1.0 /* prio below default */ );
751 // forward advance-on-click state to newly
752 // generated handler (that's the only reason why
753 // we're called here)
754 mpSkipEffectEventHandler
->setAdvanceOnClick( mbAdvanceOnClick
);
756 mpSkipEffectEventHandler
->setSkipTriggersNextEffect(bSkipTriggersNextEffect
);
757 mpSkipEffectEventHandler
->addEvent( pEvent
);
760 void UserEventQueue::registerShapeDoubleClickEvent(
761 const EventSharedPtr
& rEvent
,
762 const ShapeSharedPtr
& rShape
)
766 "UserEventQueue::registerShapeDoubleClickEvent(): Invalid event" );
768 if( !mpShapeDoubleClickEventHandler
)
771 mpShapeDoubleClickEventHandler
.reset(
772 new ShapeClickEventHandler(mrCursorManager
,
775 // register handler on EventMultiplexer
776 mrMultiplexer
.addDoubleClickHandler( mpShapeDoubleClickEventHandler
,
778 mrMultiplexer
.addMouseMoveHandler( mpShapeDoubleClickEventHandler
,
782 mpShapeDoubleClickEventHandler
->addEvent( rEvent
, rShape
);
785 void UserEventQueue::registerMouseEnterEvent( const EventSharedPtr
& rEvent
,
786 const ShapeSharedPtr
& rShape
)
788 registerEvent( mpMouseEnterHandler
,
791 boost::bind( &EventMultiplexer::addMouseMoveHandler
,
792 boost::ref( mrMultiplexer
), _1
,
793 0.0 /* default prio */ ) );
796 void UserEventQueue::registerMouseLeaveEvent( const EventSharedPtr
& rEvent
,
797 const ShapeSharedPtr
& rShape
)
799 registerEvent( mpMouseLeaveHandler
,
802 boost::bind( &EventMultiplexer::addMouseMoveHandler
,
803 boost::ref( mrMultiplexer
), _1
,
804 0.0 /* default prio */ ) );
807 void UserEventQueue::callSkipEffectEventHandler()
809 ::boost::shared_ptr
<SkipEffectEventHandler
> pHandler (
810 ::boost::dynamic_pointer_cast
<SkipEffectEventHandler
>(mpSkipEffectEventHandler
));
812 pHandler
->skipEffect();
815 } // namespace internal
816 } // namespace presentation
818 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */