Bump version to 6.0-36
[LibreOffice.git] / slideshow / source / engine / usereventqueue.cxx
blobc0f03576181845f6397535e90483c8184df84bf0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include <tools/diagnose_ex.h>
23 #include <comphelper/anytostring.hxx>
24 #include <cppuhelper/exc_hlp.hxx>
26 #include <com/sun/star/awt/SystemPointer.hpp>
27 #include <com/sun/star/awt/MouseButton.hpp>
28 #include <com/sun/star/awt/MouseEvent.hpp>
30 #include <delayevent.hxx>
31 #include <usereventqueue.hxx>
32 #include <cursormanager.hxx>
33 #include <slideshowexceptions.hxx>
35 #include <vector>
36 #include <queue>
37 #include <map>
38 #include <functional>
39 #include <algorithm>
42 using namespace com::sun::star;
44 /* Implementation of UserEventQueue class */
46 namespace slideshow {
47 namespace internal {
49 namespace {
51 typedef std::vector<EventSharedPtr> ImpEventVector;
52 typedef std::queue<EventSharedPtr> ImpEventQueue;
53 typedef std::map<uno::Reference<animations::XAnimationNode>,
54 ImpEventVector> ImpAnimationEventMap;
55 typedef std::map<ShapeSharedPtr, ImpEventQueue,
56 Shape::lessThanShape> ImpShapeEventMap;
58 // MouseEventHandler base class, not consuming any event:
59 class MouseEventHandler_ : public MouseEventHandler
61 public:
62 virtual bool handleMousePressed( awt::MouseEvent const& /*e*/ ) override { return false;}
63 virtual bool handleMouseReleased( awt::MouseEvent const& /*e*/) override { return false;}
64 virtual bool handleMouseDragged( awt::MouseEvent const& /*e*/ ) override { return false;}
65 virtual bool handleMouseMoved( awt::MouseEvent const& /*e*/ ) override { return false; }
68 /** @return one event has been posted
70 template <typename ContainerT>
71 bool fireSingleEvent( ContainerT & rQueue, EventQueue & rEventQueue )
73 // post next event in given queue:
74 while (! rQueue.empty())
76 EventSharedPtr const pEvent(rQueue.front());
77 rQueue.pop();
79 // skip all inactive events (as the purpose of
80 // nextEventFromQueue() is to activate the next
81 // event, and events which return false on
82 // isCharged() will never be activated by the
83 // EventQueue)
84 if(pEvent->isCharged())
85 return rEventQueue.addEvent( pEvent );
87 return false; // no more (active) events in queue
90 /** @return at least one event has been posted
92 template <typename ContainerT>
93 bool fireAllEvents( ContainerT & rQueue, EventQueue & rEventQueue )
95 bool bFiredAny = false;
96 while (fireSingleEvent( rQueue, rEventQueue ))
97 bFiredAny = true;
98 return bFiredAny;
101 class EventContainer
103 public:
104 EventContainer() :
105 maEvents()
108 void addEvent( const EventSharedPtr& rEvent )
110 maEvents.push( rEvent );
113 protected:
114 ImpEventQueue maEvents;
117 } // anon namespace
119 class AllAnimationEventHandler : public AnimationEventHandler
121 public:
122 explicit AllAnimationEventHandler( EventQueue& rEventQueue ) :
123 mrEventQueue( rEventQueue ),
124 maAnimationEventMap()
127 virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode ) override
129 ENSURE_OR_RETURN_FALSE(
130 rNode,
131 "AllAnimationEventHandler::handleAnimationEvent(): Invalid node" );
133 bool bRet( false );
135 ImpAnimationEventMap::iterator aIter;
136 if( (aIter=maAnimationEventMap.find(
137 rNode->getXAnimationNode() )) != maAnimationEventMap.end() )
139 ImpEventVector& rVec( aIter->second );
141 bRet = !rVec.empty();
143 // registered node found -> fire all events in the vector
144 for( const auto& pEvent : rVec )
145 mrEventQueue.addEvent( pEvent );
147 rVec.clear();
150 return bRet;
153 void addEvent( const EventSharedPtr& rEvent,
154 const uno::Reference< animations::XAnimationNode >& xNode )
156 ImpAnimationEventMap::iterator aIter;
157 if( (aIter=maAnimationEventMap.find( xNode )) ==
158 maAnimationEventMap.end() )
160 // no entry for this animation -> create one
161 aIter = maAnimationEventMap.emplace( xNode, ImpEventVector() ).first;
164 // add new event to queue
165 aIter->second.push_back( rEvent );
168 private:
169 EventQueue& mrEventQueue;
170 ImpAnimationEventMap maAnimationEventMap;
173 class ClickEventHandler : public MouseEventHandler_,
174 public EventHandler,
175 public EventContainer
177 public:
178 explicit ClickEventHandler( EventQueue& rEventQueue ) :
179 EventContainer(),
180 mrEventQueue( rEventQueue ),
181 mbAdvanceOnClick( true )
184 void setAdvanceOnClick( bool bAdvanceOnClick )
186 mbAdvanceOnClick = bAdvanceOnClick;
189 private:
191 // triggered by API calls, e.g. space bar
192 virtual bool handleEvent() override
194 return handleEvent_impl();
197 // triggered by mouse release:
198 virtual bool handleMouseReleased( const awt::MouseEvent& evt ) override
200 if(evt.Buttons != awt::MouseButton::LEFT)
201 return false;
203 if( mbAdvanceOnClick ) {
204 // fire next event
205 return handleEvent_impl();
207 else {
208 return false; // advance-on-click disabled
212 // triggered by both:
213 virtual bool handleEvent_impl()
215 // fire next event:
216 return fireSingleEvent( maEvents, mrEventQueue );
219 private:
220 EventQueue& mrEventQueue;
221 bool mbAdvanceOnClick;
224 class SkipEffectEventHandler : public ClickEventHandler
226 public:
227 SkipEffectEventHandler( EventQueue & rEventQueue,
228 EventMultiplexer & rEventMultiplexer )
229 : ClickEventHandler(rEventQueue),
230 mrEventQueue(rEventQueue),
231 mrEventMultiplexer(rEventMultiplexer),
232 mbSkipTriggersNextEffect(true) {}
234 /** Remember to trigger (or not to trigger) the next effect after the
235 current effect is skipped.
237 void setSkipTriggersNextEffect (const bool bSkipTriggersNextEffect)
238 { mbSkipTriggersNextEffect = bSkipTriggersNextEffect; }
240 /// Skip the current effect but do not trigger the next effect.
241 void skipEffect() { handleEvent_impl(false); }
243 private:
244 virtual bool handleEvent_impl() override
246 return handleEvent_impl(true);
249 bool handleEvent_impl (bool bNotifyNextEffect)
251 // fire all events, so animation nodes can register their
252 // next effect listeners:
253 if(fireAllEvents( maEvents, mrEventQueue ))
255 if (mbSkipTriggersNextEffect && bNotifyNextEffect)
257 // then simulate a next effect event: this skip effect
258 // handler is triggered upon next effect events (multiplexer
259 // prio=-1)! Posting a notifyNextEffect() here is only safe
260 // (we don't run into busy loop), because we assume that
261 // someone has registerered above for next effects
262 // (multiplexer prio=0) at the user event queue.
263 return mrEventQueue.addEventWhenQueueIsEmpty(
264 makeEvent( [this] () {
265 this->mrEventMultiplexer.notifyNextEffect();
266 }, "EventMultiplexer::notifyNextEffect") );
268 else
269 return true;
271 return false;
274 private:
275 EventQueue & mrEventQueue;
276 EventMultiplexer & mrEventMultiplexer;
277 bool mbSkipTriggersNextEffect;
280 /** Base class to share some common code between
281 ShapeClickEventHandler and MouseMoveHandler
283 @derive override necessary MouseEventHandler interface methods,
284 call sendEvent() method to actually process the event.
286 class MouseHandlerBase : public MouseEventHandler_
288 public:
289 explicit MouseHandlerBase( EventQueue& rEventQueue ) :
290 mrEventQueue( rEventQueue ),
291 maShapeEventMap()
294 void addEvent( const EventSharedPtr& rEvent,
295 const ShapeSharedPtr& rShape )
297 ImpShapeEventMap::iterator aIter;
298 if( (aIter=maShapeEventMap.find( rShape )) == maShapeEventMap.end() )
300 // no entry for this shape -> create one
301 aIter = maShapeEventMap.emplace(rShape, ImpEventQueue()).first;
304 // add new event to queue
305 aIter->second.push( rEvent );
308 protected:
309 bool hitTest( const awt::MouseEvent& e,
310 ImpShapeEventMap::reverse_iterator& o_rHitShape )
312 // find hit shape in map
313 const basegfx::B2DPoint aPosition( e.X, e.Y );
315 // find matching shape (scan reversely, to coarsely match
316 // paint order)
317 ImpShapeEventMap::reverse_iterator aCurrShape(maShapeEventMap.rbegin());
318 const ImpShapeEventMap::reverse_iterator aEndShape( maShapeEventMap.rend() );
319 while( aCurrShape != aEndShape )
321 // TODO(F2): Get proper geometry polygon from the
322 // shape, to avoid having areas outside the shape
323 // react on the mouse
324 if( aCurrShape->first->getBounds().isInside( aPosition ) &&
325 aCurrShape->first->isVisible() )
327 // shape hit, and shape is visible - report a
328 // hit
329 o_rHitShape = aCurrShape;
330 return true;
333 ++aCurrShape;
336 return false; // nothing hit
339 bool sendEvent( ImpShapeEventMap::reverse_iterator const & io_rHitShape )
341 // take next event from queue
342 const bool bRet( fireSingleEvent( io_rHitShape->second,
343 mrEventQueue ) );
345 // clear shape entry, if its queue is
346 // empty. This is important, since the shapes
347 // are held by shared ptr, and might otherwise
348 // not get released, even after their owning
349 // slide is long gone.
350 if( io_rHitShape->second.empty() )
352 // this looks funny, since ::std::map does
353 // provide an erase( iterator )
354 // method. Unfortunately, C++ does not
355 // declare the obvious erase(
356 // reverse_iterator ) needed here (missing
357 // orthogonality, eh?)
358 maShapeEventMap.erase( io_rHitShape->first );
361 return bRet;
364 bool processEvent( const awt::MouseEvent& e )
366 ImpShapeEventMap::reverse_iterator aCurrShape;
368 if( hitTest( e, aCurrShape ) )
369 return sendEvent( aCurrShape );
371 return false; // did not handle the event
374 private:
375 EventQueue& mrEventQueue;
376 ImpShapeEventMap maShapeEventMap;
379 class ShapeClickEventHandler : public MouseHandlerBase
381 public:
382 ShapeClickEventHandler( CursorManager& rCursorManager,
383 EventQueue& rEventQueue ) :
384 MouseHandlerBase( rEventQueue ),
385 mrCursorManager( rCursorManager )
388 virtual bool handleMouseReleased( const awt::MouseEvent& e ) override
390 if(e.Buttons != awt::MouseButton::LEFT)
391 return false;
392 return processEvent( e );
395 virtual bool handleMouseMoved( const awt::MouseEvent& e ) override
397 // TODO(P2): Maybe buffer last shape touched
399 // if we have a shape click event, and the mouse
400 // hovers over this shape, change cursor to hand
401 ImpShapeEventMap::reverse_iterator aDummy;
402 if( hitTest( e, aDummy ) )
403 mrCursorManager.requestCursor( awt::SystemPointer::REFHAND );
405 return false; // we don't /eat/ this event. Lower prio
406 // handler should see it, too.
409 private:
410 CursorManager& mrCursorManager;
413 class MouseEnterHandler : public MouseHandlerBase
415 public:
416 explicit MouseEnterHandler( EventQueue& rEventQueue )
417 : MouseHandlerBase( rEventQueue ),
418 mpLastShape() {}
420 virtual bool handleMouseMoved( const awt::MouseEvent& e ) override
422 // TODO(P2): Maybe buffer last shape touched, and
423 // check against that _first_
425 ImpShapeEventMap::reverse_iterator aCurr;
426 if( hitTest( e, aCurr ) )
428 if( aCurr->first != mpLastShape )
430 // we actually hit a shape, and it's different
431 // from the previous one - thus we just
432 // entered it, raise event
433 sendEvent( aCurr );
434 mpLastShape = aCurr->first;
437 else
439 // don't hit no shape - thus, last shape is NULL
440 mpLastShape.reset();
443 return false; // we don't /eat/ this event. Lower prio
444 // handler should see it, too.
447 private:
448 ShapeSharedPtr mpLastShape;
451 class MouseLeaveHandler : public MouseHandlerBase
453 public:
454 explicit MouseLeaveHandler( EventQueue& rEventQueue )
455 : MouseHandlerBase( rEventQueue ),
456 maLastIter() {}
458 virtual bool handleMouseMoved( const awt::MouseEvent& e ) override
460 // TODO(P2): Maybe buffer last shape touched, and
461 // check against that _first_
463 ImpShapeEventMap::reverse_iterator aCurr;
464 if( hitTest( e, aCurr ) )
466 maLastIter = aCurr;
468 else
470 if( maLastIter->first )
472 // last time, we were over a shape, now we're
473 // not - we thus just left that shape, raise
474 // event
475 sendEvent( maLastIter );
478 // in any case, when we hit this else-branch: no
479 // shape hit, thus have to clear maLastIter
480 maLastIter = ImpShapeEventMap::reverse_iterator();
483 return false; // we don't /eat/ this event. Lower prio
484 // handler should see it, too.
487 private:
488 ImpShapeEventMap::reverse_iterator maLastIter;
491 template< typename Handler, typename Functor >
492 void UserEventQueue::registerEvent(
493 std::shared_ptr< Handler >& rHandler,
494 const EventSharedPtr& rEvent,
495 const Functor& rRegistrationFunctor )
497 ENSURE_OR_THROW( rEvent,
498 "UserEventQueue::registerEvent(): Invalid event" );
500 if( !rHandler ) {
501 // create handler
502 rHandler.reset( new Handler( mrEventQueue ) );
503 // register handler on EventMultiplexer
504 rRegistrationFunctor( rHandler );
507 rHandler->addEvent( rEvent );
510 template< typename Handler, typename Arg, typename Functor >
511 void UserEventQueue::registerEvent(
512 std::shared_ptr< Handler >& rHandler,
513 const EventSharedPtr& rEvent,
514 const Arg& rArg,
515 const Functor& rRegistrationFunctor )
517 ENSURE_OR_THROW( rEvent,
518 "UserEventQueue::registerEvent(): Invalid event" );
520 if( !rHandler ) {
521 // create handler
522 rHandler.reset( new Handler( mrEventQueue ) );
524 // register handler on EventMultiplexer
525 rRegistrationFunctor( rHandler );
528 rHandler->addEvent( rEvent, rArg );
532 UserEventQueue::UserEventQueue( EventMultiplexer& rMultiplexer,
533 EventQueue& rEventQueue,
534 CursorManager& rCursorManager )
535 : mrMultiplexer( rMultiplexer ),
536 mrEventQueue( rEventQueue ),
537 mrCursorManager( rCursorManager ),
538 mpAnimationStartEventHandler(),
539 mpAnimationEndEventHandler(),
540 mpAudioStoppedEventHandler(),
541 mpClickEventHandler(),
542 mpSkipEffectEventHandler(),
543 mpDoubleClickEventHandler(),
544 mpMouseEnterHandler(),
545 mpMouseLeaveHandler(),
546 mbAdvanceOnClick( true )
550 UserEventQueue::~UserEventQueue()
554 // unregister all handlers
555 clear();
557 catch (const uno::Exception& e)
559 SAL_WARN("slideshow", e);
563 void UserEventQueue::clear()
565 // unregister and delete all handlers
566 if( mpAnimationStartEventHandler ) {
567 mrMultiplexer.removeAnimationStartHandler(
568 mpAnimationStartEventHandler );
569 mpAnimationStartEventHandler.reset();
571 if( mpAnimationEndEventHandler ) {
572 mrMultiplexer.removeAnimationEndHandler( mpAnimationEndEventHandler );
573 mpAnimationEndEventHandler.reset();
575 if( mpAudioStoppedEventHandler ) {
576 mrMultiplexer.removeAudioStoppedHandler( mpAudioStoppedEventHandler );
577 mpAudioStoppedEventHandler.reset();
579 if( mpShapeClickEventHandler ) {
580 mrMultiplexer.removeClickHandler( mpShapeClickEventHandler );
581 mrMultiplexer.removeMouseMoveHandler( mpShapeClickEventHandler );
582 mpShapeClickEventHandler.reset();
584 if( mpClickEventHandler ) {
585 mrMultiplexer.removeClickHandler( mpClickEventHandler );
586 mrMultiplexer.removeNextEffectHandler( mpClickEventHandler );
587 mpClickEventHandler.reset();
589 if(mpSkipEffectEventHandler) {
590 mrMultiplexer.removeClickHandler( mpSkipEffectEventHandler );
591 mrMultiplexer.removeNextEffectHandler( mpSkipEffectEventHandler );
592 mpSkipEffectEventHandler.reset();
594 if( mpShapeDoubleClickEventHandler ) {
595 mrMultiplexer.removeDoubleClickHandler( mpShapeDoubleClickEventHandler );
596 mrMultiplexer.removeMouseMoveHandler( mpShapeDoubleClickEventHandler );
597 mpShapeDoubleClickEventHandler.reset();
599 if( mpDoubleClickEventHandler ) {
600 mrMultiplexer.removeDoubleClickHandler( mpDoubleClickEventHandler );
601 mpDoubleClickEventHandler.reset();
603 if( mpMouseEnterHandler ) {
604 mrMultiplexer.removeMouseMoveHandler( mpMouseEnterHandler );
605 mpMouseEnterHandler.reset();
607 if( mpMouseLeaveHandler ) {
608 mrMultiplexer.removeMouseMoveHandler( mpMouseLeaveHandler );
609 mpMouseLeaveHandler.reset();
613 void UserEventQueue::setAdvanceOnClick( bool bAdvanceOnClick )
615 mbAdvanceOnClick = bAdvanceOnClick;
617 // forward to handler, if existing. Otherwise, the handler
618 // creation will do the forwarding.
619 if( mpClickEventHandler )
620 mpClickEventHandler->setAdvanceOnClick( bAdvanceOnClick );
623 void UserEventQueue::registerAnimationStartEvent(
624 const EventSharedPtr& rEvent,
625 const uno::Reference< animations::XAnimationNode>& xNode )
627 registerEvent( mpAnimationStartEventHandler,
628 rEvent,
629 xNode,
630 [this]( const AnimationEventHandlerSharedPtr& rHandler )
631 { return this->mrMultiplexer.addAnimationStartHandler( rHandler ); } );
634 void UserEventQueue::registerAnimationEndEvent(
635 const EventSharedPtr& rEvent,
636 const uno::Reference<animations::XAnimationNode>& xNode )
638 registerEvent( mpAnimationEndEventHandler,
639 rEvent,
640 xNode,
641 [this]( const AnimationEventHandlerSharedPtr& rHandler )
642 { return this->mrMultiplexer.addAnimationEndHandler( rHandler ); } );
645 void UserEventQueue::registerAudioStoppedEvent(
646 const EventSharedPtr& rEvent,
647 const uno::Reference<animations::XAnimationNode>& xNode )
649 registerEvent( mpAudioStoppedEventHandler,
650 rEvent,
651 xNode,
652 [this]( const AnimationEventHandlerSharedPtr& rHandler )
653 { return this->mrMultiplexer.addAudioStoppedHandler( rHandler ); } );
656 void UserEventQueue::registerShapeClickEvent( const EventSharedPtr& rEvent,
657 const ShapeSharedPtr& rShape )
659 ENSURE_OR_THROW(
660 rEvent,
661 "UserEventQueue::registerShapeClickEvent(): Invalid event" );
663 if( !mpShapeClickEventHandler )
665 // create handler
666 mpShapeClickEventHandler.reset(
667 new ShapeClickEventHandler(mrCursorManager,
668 mrEventQueue) );
670 // register handler on EventMultiplexer
671 mrMultiplexer.addClickHandler( mpShapeClickEventHandler, 1.0 );
672 mrMultiplexer.addMouseMoveHandler( mpShapeClickEventHandler, 1.0 );
675 mpShapeClickEventHandler->addEvent( rEvent, rShape );
678 namespace {
679 class ClickEventRegistrationFunctor
681 public:
682 ClickEventRegistrationFunctor( EventMultiplexer& rMultiplexer,
683 double nPrio,
684 bool bAdvanceOnClick )
685 : mrMultiplexer( rMultiplexer ),
686 mnPrio(nPrio),
687 mbAdvanceOnClick( bAdvanceOnClick ) {}
689 void operator()( const std::shared_ptr<ClickEventHandler>& rHandler )const
691 // register the handler on _two_ sources: we want the
692 // nextEffect events, e.g. space bar, to trigger clicks, as well!
693 mrMultiplexer.addClickHandler( rHandler, mnPrio );
694 mrMultiplexer.addNextEffectHandler( rHandler, mnPrio );
696 // forward advance-on-click state to newly
697 // generated handler (that's the only reason why
698 // we're called here)
699 rHandler->setAdvanceOnClick( mbAdvanceOnClick );
702 private:
703 EventMultiplexer& mrMultiplexer;
704 double const mnPrio;
705 bool const mbAdvanceOnClick;
707 } // anon namespace
709 void UserEventQueue::registerNextEffectEvent( const EventSharedPtr& rEvent )
711 // TODO: better name may be mpNextEffectEventHandler? then we have
712 // next effect (=> waiting to be started)
713 // skip effect (skipping the currently running one)
714 // rewind effect (rewinding back running one and waiting (again)
715 // to be started)
716 registerEvent( mpClickEventHandler,
717 rEvent,
718 ClickEventRegistrationFunctor( mrMultiplexer,
719 0.0 /* default prio */,
720 mbAdvanceOnClick ) );
723 void UserEventQueue::registerSkipEffectEvent(
724 EventSharedPtr const & pEvent,
725 const bool bSkipTriggersNextEffect)
727 if(!mpSkipEffectEventHandler)
729 mpSkipEffectEventHandler.reset(
730 new SkipEffectEventHandler( mrEventQueue, mrMultiplexer ) );
731 // register the handler on _two_ sources: we want the
732 // nextEffect events, e.g. space bar, to trigger clicks, as well!
733 mrMultiplexer.addClickHandler( mpSkipEffectEventHandler,
734 -1.0 /* prio below default */ );
735 mrMultiplexer.addNextEffectHandler( mpSkipEffectEventHandler,
736 -1.0 /* prio below default */ );
737 // forward advance-on-click state to newly
738 // generated handler (that's the only reason why
739 // we're called here)
740 mpSkipEffectEventHandler->setAdvanceOnClick( mbAdvanceOnClick );
742 mpSkipEffectEventHandler->setSkipTriggersNextEffect(bSkipTriggersNextEffect);
743 mpSkipEffectEventHandler->addEvent( pEvent );
746 void UserEventQueue::registerShapeDoubleClickEvent(
747 const EventSharedPtr& rEvent,
748 const ShapeSharedPtr& rShape )
750 ENSURE_OR_THROW(
751 rEvent,
752 "UserEventQueue::registerShapeDoubleClickEvent(): Invalid event" );
754 if( !mpShapeDoubleClickEventHandler )
756 // create handler
757 mpShapeDoubleClickEventHandler.reset(
758 new ShapeClickEventHandler(mrCursorManager,
759 mrEventQueue) );
761 // register handler on EventMultiplexer
762 mrMultiplexer.addDoubleClickHandler( mpShapeDoubleClickEventHandler,
763 1.0 );
764 mrMultiplexer.addMouseMoveHandler( mpShapeDoubleClickEventHandler,
765 1.0 );
768 mpShapeDoubleClickEventHandler->addEvent( rEvent, rShape );
771 void UserEventQueue::registerMouseEnterEvent( const EventSharedPtr& rEvent,
772 const ShapeSharedPtr& rShape )
774 registerEvent( mpMouseEnterHandler,
775 rEvent,
776 rShape,
777 [this]( const MouseEventHandlerSharedPtr& rHandler )
778 { return this->mrMultiplexer.addMouseMoveHandler( rHandler, 0.0 ); } );
781 void UserEventQueue::registerMouseLeaveEvent( const EventSharedPtr& rEvent,
782 const ShapeSharedPtr& rShape )
784 registerEvent( mpMouseLeaveHandler,
785 rEvent,
786 rShape,
787 [this]( const MouseEventHandlerSharedPtr& rHandler )
788 { return this->mrMultiplexer.addMouseMoveHandler( rHandler, 0.0 ); } );
791 void UserEventQueue::callSkipEffectEventHandler()
793 ::std::shared_ptr<SkipEffectEventHandler> pHandler (
794 ::std::dynamic_pointer_cast<SkipEffectEventHandler>(mpSkipEffectEventHandler));
795 if (pHandler)
796 pHandler->skipEffect();
799 } // namespace internal
800 } // namespace presentation
802 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */