build fix
[LibreOffice.git] / slideshow / source / engine / usereventqueue.cxx
blobd221de285a0c962f3f87a9f39260bd668964dd26
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.insert(
162 ImpAnimationEventMap::value_type( xNode,
163 ImpEventVector() ) ).first;
166 // add new event to queue
167 aIter->second.push_back( rEvent );
170 private:
171 EventQueue& mrEventQueue;
172 ImpAnimationEventMap maAnimationEventMap;
175 class ClickEventHandler : public MouseEventHandler_,
176 public EventHandler,
177 public EventContainer
179 public:
180 explicit ClickEventHandler( EventQueue& rEventQueue ) :
181 EventContainer(),
182 mrEventQueue( rEventQueue ),
183 mbAdvanceOnClick( true )
186 void setAdvanceOnClick( bool bAdvanceOnClick )
188 mbAdvanceOnClick = bAdvanceOnClick;
191 private:
193 // triggered by API calls, e.g. space bar
194 virtual bool handleEvent() override
196 return handleEvent_impl();
199 // triggered by mouse release:
200 virtual bool handleMouseReleased( const awt::MouseEvent& evt ) override
202 if(evt.Buttons != awt::MouseButton::LEFT)
203 return false;
205 if( mbAdvanceOnClick ) {
206 // fire next event
207 return handleEvent_impl();
209 else {
210 return false; // advance-on-click disabled
214 // triggered by both:
215 virtual bool handleEvent_impl()
217 // fire next event:
218 return fireSingleEvent( maEvents, mrEventQueue );
221 private:
222 EventQueue& mrEventQueue;
223 bool mbAdvanceOnClick;
226 class SkipEffectEventHandler : public ClickEventHandler
228 public:
229 SkipEffectEventHandler( EventQueue & rEventQueue,
230 EventMultiplexer & rEventMultiplexer )
231 : ClickEventHandler(rEventQueue),
232 mrEventQueue(rEventQueue),
233 mrEventMultiplexer(rEventMultiplexer),
234 mbSkipTriggersNextEffect(true) {}
236 /** Remember to trigger (or not to trigger) the next effect after the
237 current effect is skipped.
239 void setSkipTriggersNextEffect (const bool bSkipTriggersNextEffect)
240 { mbSkipTriggersNextEffect = bSkipTriggersNextEffect; }
242 /// Skip the current effect but do not trigger the next effect.
243 void skipEffect() { handleEvent_impl(false); }
245 private:
246 virtual bool handleEvent_impl() override
248 return handleEvent_impl(true);
251 bool handleEvent_impl (bool bNotifyNextEffect)
253 // fire all events, so animation nodes can register their
254 // next effect listeners:
255 if(fireAllEvents( maEvents, mrEventQueue ))
257 if (mbSkipTriggersNextEffect && bNotifyNextEffect)
259 // then simulate a next effect event: this skip effect
260 // handler is triggered upon next effect events (multiplexer
261 // prio=-1)! Posting a notifyNextEffect() here is only safe
262 // (we don't run into busy loop), because we assume that
263 // someone has registerered above for next effects
264 // (multiplexer prio=0) at the user event queue.
265 return mrEventQueue.addEventWhenQueueIsEmpty(
266 makeEvent( [this] () {
267 this->mrEventMultiplexer.notifyNextEffect();
268 }, "EventMultiplexer::notifyNextEffect") );
270 else
271 return true;
273 return false;
276 private:
277 EventQueue & mrEventQueue;
278 EventMultiplexer & mrEventMultiplexer;
279 bool mbSkipTriggersNextEffect;
282 /** Base class to share some common code between
283 ShapeClickEventHandler and MouseMoveHandler
285 @derive override necessary MouseEventHandler interface methods,
286 call sendEvent() method to actually process the event.
288 class MouseHandlerBase : public MouseEventHandler_
290 public:
291 explicit MouseHandlerBase( EventQueue& rEventQueue ) :
292 mrEventQueue( rEventQueue ),
293 maShapeEventMap()
296 void addEvent( const EventSharedPtr& rEvent,
297 const ShapeSharedPtr& rShape )
299 ImpShapeEventMap::iterator aIter;
300 if( (aIter=maShapeEventMap.find( rShape )) == maShapeEventMap.end() )
302 // no entry for this shape -> create one
303 aIter = maShapeEventMap.insert(
304 ImpShapeEventMap::value_type( rShape,
305 ImpEventQueue() ) ).first;
308 // add new event to queue
309 aIter->second.push( rEvent );
312 protected:
313 bool hitTest( const awt::MouseEvent& e,
314 ImpShapeEventMap::reverse_iterator& o_rHitShape )
316 // find hit shape in map
317 const basegfx::B2DPoint aPosition( e.X, e.Y );
319 // find matching shape (scan reversely, to coarsely match
320 // paint order)
321 ImpShapeEventMap::reverse_iterator aCurrShape(maShapeEventMap.rbegin());
322 const ImpShapeEventMap::reverse_iterator aEndShape( maShapeEventMap.rend() );
323 while( aCurrShape != aEndShape )
325 // TODO(F2): Get proper geometry polygon from the
326 // shape, to avoid having areas outside the shape
327 // react on the mouse
328 if( aCurrShape->first->getBounds().isInside( aPosition ) &&
329 aCurrShape->first->isVisible() )
331 // shape hit, and shape is visible - report a
332 // hit
333 o_rHitShape = aCurrShape;
334 return true;
337 ++aCurrShape;
340 return false; // nothing hit
343 bool sendEvent( ImpShapeEventMap::reverse_iterator& io_rHitShape )
345 // take next event from queue
346 const bool bRet( fireSingleEvent( io_rHitShape->second,
347 mrEventQueue ) );
349 // clear shape entry, if its queue is
350 // empty. This is important, since the shapes
351 // are held by shared ptr, and might otherwise
352 // not get released, even after their owning
353 // slide is long gone.
354 if( io_rHitShape->second.empty() )
356 // this looks funny, since ::std::map does
357 // provide an erase( iterator )
358 // method. Unfortunately, C++ does not
359 // declare the obvious erase(
360 // reverse_iterator ) needed here (missing
361 // orthogonality, eh?)
362 maShapeEventMap.erase( io_rHitShape->first );
365 return bRet;
368 bool processEvent( const awt::MouseEvent& e )
370 ImpShapeEventMap::reverse_iterator aCurrShape;
372 if( hitTest( e, aCurrShape ) )
373 return sendEvent( aCurrShape );
375 return false; // did not handle the event
378 private:
379 EventQueue& mrEventQueue;
380 ImpShapeEventMap maShapeEventMap;
383 class ShapeClickEventHandler : public MouseHandlerBase
385 public:
386 ShapeClickEventHandler( CursorManager& rCursorManager,
387 EventQueue& rEventQueue ) :
388 MouseHandlerBase( rEventQueue ),
389 mrCursorManager( rCursorManager )
392 virtual bool handleMouseReleased( const awt::MouseEvent& e ) override
394 if(e.Buttons != awt::MouseButton::LEFT)
395 return false;
396 return processEvent( e );
399 virtual bool handleMouseMoved( const awt::MouseEvent& e ) override
401 // TODO(P2): Maybe buffer last shape touched
403 // if we have a shape click event, and the mouse
404 // hovers over this shape, change cursor to hand
405 ImpShapeEventMap::reverse_iterator aDummy;
406 if( hitTest( e, aDummy ) )
407 mrCursorManager.requestCursor( awt::SystemPointer::REFHAND );
409 return false; // we don't /eat/ this event. Lower prio
410 // handler should see it, too.
413 private:
414 CursorManager& mrCursorManager;
417 class MouseEnterHandler : public MouseHandlerBase
419 public:
420 explicit MouseEnterHandler( EventQueue& rEventQueue )
421 : MouseHandlerBase( rEventQueue ),
422 mpLastShape() {}
424 virtual bool handleMouseMoved( const awt::MouseEvent& e ) override
426 // TODO(P2): Maybe buffer last shape touched, and
427 // check against that _first_
429 ImpShapeEventMap::reverse_iterator aCurr;
430 if( hitTest( e, aCurr ) )
432 if( aCurr->first != mpLastShape )
434 // we actually hit a shape, and it's different
435 // from the previous one - thus we just
436 // entered it, raise event
437 sendEvent( aCurr );
438 mpLastShape = aCurr->first;
441 else
443 // don't hit no shape - thus, last shape is NULL
444 mpLastShape.reset();
447 return false; // we don't /eat/ this event. Lower prio
448 // handler should see it, too.
451 private:
452 ShapeSharedPtr mpLastShape;
455 class MouseLeaveHandler : public MouseHandlerBase
457 public:
458 explicit MouseLeaveHandler( EventQueue& rEventQueue )
459 : MouseHandlerBase( rEventQueue ),
460 maLastIter() {}
462 virtual bool handleMouseMoved( const awt::MouseEvent& e ) override
464 // TODO(P2): Maybe buffer last shape touched, and
465 // check against that _first_
467 ImpShapeEventMap::reverse_iterator aCurr;
468 if( hitTest( e, aCurr ) )
470 maLastIter = aCurr;
472 else
474 if( maLastIter->first )
476 // last time, we were over a shape, now we're
477 // not - we thus just left that shape, raise
478 // event
479 sendEvent( maLastIter );
482 // in any case, when we hit this else-branch: no
483 // shape hit, thus have to clear maLastIter
484 maLastIter = ImpShapeEventMap::reverse_iterator();
487 return false; // we don't /eat/ this event. Lower prio
488 // handler should see it, too.
491 private:
492 ImpShapeEventMap::reverse_iterator maLastIter;
495 template< typename Handler, typename Functor >
496 void UserEventQueue::registerEvent(
497 std::shared_ptr< Handler >& rHandler,
498 const EventSharedPtr& rEvent,
499 const Functor& rRegistrationFunctor )
501 ENSURE_OR_THROW( rEvent,
502 "UserEventQueue::registerEvent(): Invalid event" );
504 if( !rHandler ) {
505 // create handler
506 rHandler.reset( new Handler( mrEventQueue ) );
507 // register handler on EventMultiplexer
508 rRegistrationFunctor( rHandler );
511 rHandler->addEvent( rEvent );
514 template< typename Handler, typename Arg, typename Functor >
515 void UserEventQueue::registerEvent(
516 std::shared_ptr< Handler >& rHandler,
517 const EventSharedPtr& rEvent,
518 const Arg& rArg,
519 const Functor& rRegistrationFunctor )
521 ENSURE_OR_THROW( rEvent,
522 "UserEventQueue::registerEvent(): Invalid event" );
524 if( !rHandler ) {
525 // create handler
526 rHandler.reset( new Handler( mrEventQueue ) );
528 // register handler on EventMultiplexer
529 rRegistrationFunctor( rHandler );
532 rHandler->addEvent( rEvent, rArg );
536 UserEventQueue::UserEventQueue( EventMultiplexer& rMultiplexer,
537 EventQueue& rEventQueue,
538 CursorManager& rCursorManager )
539 : mrMultiplexer( rMultiplexer ),
540 mrEventQueue( rEventQueue ),
541 mrCursorManager( rCursorManager ),
542 mpAnimationStartEventHandler(),
543 mpAnimationEndEventHandler(),
544 mpAudioStoppedEventHandler(),
545 mpClickEventHandler(),
546 mpSkipEffectEventHandler(),
547 mpDoubleClickEventHandler(),
548 mpMouseEnterHandler(),
549 mpMouseLeaveHandler(),
550 mbAdvanceOnClick( true )
554 UserEventQueue::~UserEventQueue()
558 // unregister all handlers
559 clear();
561 catch (uno::Exception &) {
562 OSL_FAIL( OUStringToOString(
563 comphelper::anyToString(
564 cppu::getCaughtException() ),
565 RTL_TEXTENCODING_UTF8 ).getStr() );
569 void UserEventQueue::clear()
571 // unregister and delete all handlers
572 if( mpAnimationStartEventHandler ) {
573 mrMultiplexer.removeAnimationStartHandler(
574 mpAnimationStartEventHandler );
575 mpAnimationStartEventHandler.reset();
577 if( mpAnimationEndEventHandler ) {
578 mrMultiplexer.removeAnimationEndHandler( mpAnimationEndEventHandler );
579 mpAnimationEndEventHandler.reset();
581 if( mpAudioStoppedEventHandler ) {
582 mrMultiplexer.removeAudioStoppedHandler( mpAudioStoppedEventHandler );
583 mpAudioStoppedEventHandler.reset();
585 if( mpShapeClickEventHandler ) {
586 mrMultiplexer.removeClickHandler( mpShapeClickEventHandler );
587 mrMultiplexer.removeMouseMoveHandler( mpShapeClickEventHandler );
588 mpShapeClickEventHandler.reset();
590 if( mpClickEventHandler ) {
591 mrMultiplexer.removeClickHandler( mpClickEventHandler );
592 mrMultiplexer.removeNextEffectHandler( mpClickEventHandler );
593 mpClickEventHandler.reset();
595 if(mpSkipEffectEventHandler) {
596 mrMultiplexer.removeClickHandler( mpSkipEffectEventHandler );
597 mrMultiplexer.removeNextEffectHandler( mpSkipEffectEventHandler );
598 mpSkipEffectEventHandler.reset();
600 if( mpShapeDoubleClickEventHandler ) {
601 mrMultiplexer.removeDoubleClickHandler( mpShapeDoubleClickEventHandler );
602 mrMultiplexer.removeMouseMoveHandler( mpShapeDoubleClickEventHandler );
603 mpShapeDoubleClickEventHandler.reset();
605 if( mpDoubleClickEventHandler ) {
606 mrMultiplexer.removeDoubleClickHandler( mpDoubleClickEventHandler );
607 mpDoubleClickEventHandler.reset();
609 if( mpMouseEnterHandler ) {
610 mrMultiplexer.removeMouseMoveHandler( mpMouseEnterHandler );
611 mpMouseEnterHandler.reset();
613 if( mpMouseLeaveHandler ) {
614 mrMultiplexer.removeMouseMoveHandler( mpMouseLeaveHandler );
615 mpMouseLeaveHandler.reset();
619 void UserEventQueue::setAdvanceOnClick( bool bAdvanceOnClick )
621 mbAdvanceOnClick = bAdvanceOnClick;
623 // forward to handler, if existing. Otherwise, the handler
624 // creation will do the forwarding.
625 if( mpClickEventHandler )
626 mpClickEventHandler->setAdvanceOnClick( bAdvanceOnClick );
629 void UserEventQueue::registerAnimationStartEvent(
630 const EventSharedPtr& rEvent,
631 const uno::Reference< animations::XAnimationNode>& xNode )
633 registerEvent( mpAnimationStartEventHandler,
634 rEvent,
635 xNode,
636 [this]( const AnimationEventHandlerSharedPtr& rHandler )
637 { return this->mrMultiplexer.addAnimationStartHandler( rHandler ); } );
640 void UserEventQueue::registerAnimationEndEvent(
641 const EventSharedPtr& rEvent,
642 const uno::Reference<animations::XAnimationNode>& xNode )
644 registerEvent( mpAnimationEndEventHandler,
645 rEvent,
646 xNode,
647 [this]( const AnimationEventHandlerSharedPtr& rHandler )
648 { return this->mrMultiplexer.addAnimationEndHandler( rHandler ); } );
651 void UserEventQueue::registerAudioStoppedEvent(
652 const EventSharedPtr& rEvent,
653 const uno::Reference<animations::XAnimationNode>& xNode )
655 registerEvent( mpAudioStoppedEventHandler,
656 rEvent,
657 xNode,
658 [this]( const AnimationEventHandlerSharedPtr& rHandler )
659 { return this->mrMultiplexer.addAudioStoppedHandler( rHandler ); } );
662 void UserEventQueue::registerShapeClickEvent( const EventSharedPtr& rEvent,
663 const ShapeSharedPtr& rShape )
665 ENSURE_OR_THROW(
666 rEvent,
667 "UserEventQueue::registerShapeClickEvent(): Invalid event" );
669 if( !mpShapeClickEventHandler )
671 // create handler
672 mpShapeClickEventHandler.reset(
673 new ShapeClickEventHandler(mrCursorManager,
674 mrEventQueue) );
676 // register handler on EventMultiplexer
677 mrMultiplexer.addClickHandler( mpShapeClickEventHandler, 1.0 );
678 mrMultiplexer.addMouseMoveHandler( mpShapeClickEventHandler, 1.0 );
681 mpShapeClickEventHandler->addEvent( rEvent, rShape );
684 namespace {
685 class ClickEventRegistrationFunctor
687 public:
688 ClickEventRegistrationFunctor( EventMultiplexer& rMultiplexer,
689 double nPrio,
690 bool bAdvanceOnClick )
691 : mrMultiplexer( rMultiplexer ),
692 mnPrio(nPrio),
693 mbAdvanceOnClick( bAdvanceOnClick ) {}
695 void operator()( const std::shared_ptr<ClickEventHandler>& rHandler )const
697 // register the handler on _two_ sources: we want the
698 // nextEffect events, e.g. space bar, to trigger clicks, as well!
699 mrMultiplexer.addClickHandler( rHandler, mnPrio );
700 mrMultiplexer.addNextEffectHandler( rHandler, mnPrio );
702 // forward advance-on-click state to newly
703 // generated handler (that's the only reason why
704 // we're called here)
705 rHandler->setAdvanceOnClick( mbAdvanceOnClick );
708 private:
709 EventMultiplexer& mrMultiplexer;
710 double const mnPrio;
711 bool const mbAdvanceOnClick;
713 } // anon namespace
715 void UserEventQueue::registerNextEffectEvent( const EventSharedPtr& rEvent )
717 // TODO: better name may be mpNextEffectEventHandler? then we have
718 // next effect (=> waiting to be started)
719 // skip effect (skipping the currently running one)
720 // rewind effect (rewinding back running one and waiting (again)
721 // to be started)
722 registerEvent( mpClickEventHandler,
723 rEvent,
724 ClickEventRegistrationFunctor( mrMultiplexer,
725 0.0 /* default prio */,
726 mbAdvanceOnClick ) );
729 void UserEventQueue::registerSkipEffectEvent(
730 EventSharedPtr const & pEvent,
731 const bool bSkipTriggersNextEffect)
733 if(!mpSkipEffectEventHandler)
735 mpSkipEffectEventHandler.reset(
736 new SkipEffectEventHandler( mrEventQueue, mrMultiplexer ) );
737 // register the handler on _two_ sources: we want the
738 // nextEffect events, e.g. space bar, to trigger clicks, as well!
739 mrMultiplexer.addClickHandler( mpSkipEffectEventHandler,
740 -1.0 /* prio below default */ );
741 mrMultiplexer.addNextEffectHandler( mpSkipEffectEventHandler,
742 -1.0 /* prio below default */ );
743 // forward advance-on-click state to newly
744 // generated handler (that's the only reason why
745 // we're called here)
746 mpSkipEffectEventHandler->setAdvanceOnClick( mbAdvanceOnClick );
748 mpSkipEffectEventHandler->setSkipTriggersNextEffect(bSkipTriggersNextEffect);
749 mpSkipEffectEventHandler->addEvent( pEvent );
752 void UserEventQueue::registerShapeDoubleClickEvent(
753 const EventSharedPtr& rEvent,
754 const ShapeSharedPtr& rShape )
756 ENSURE_OR_THROW(
757 rEvent,
758 "UserEventQueue::registerShapeDoubleClickEvent(): Invalid event" );
760 if( !mpShapeDoubleClickEventHandler )
762 // create handler
763 mpShapeDoubleClickEventHandler.reset(
764 new ShapeClickEventHandler(mrCursorManager,
765 mrEventQueue) );
767 // register handler on EventMultiplexer
768 mrMultiplexer.addDoubleClickHandler( mpShapeDoubleClickEventHandler,
769 1.0 );
770 mrMultiplexer.addMouseMoveHandler( mpShapeDoubleClickEventHandler,
771 1.0 );
774 mpShapeDoubleClickEventHandler->addEvent( rEvent, rShape );
777 void UserEventQueue::registerMouseEnterEvent( const EventSharedPtr& rEvent,
778 const ShapeSharedPtr& rShape )
780 registerEvent( mpMouseEnterHandler,
781 rEvent,
782 rShape,
783 [this]( const MouseEventHandlerSharedPtr& rHandler )
784 { return this->mrMultiplexer.addMouseMoveHandler( rHandler, 0.0 ); } );
787 void UserEventQueue::registerMouseLeaveEvent( const EventSharedPtr& rEvent,
788 const ShapeSharedPtr& rShape )
790 registerEvent( mpMouseLeaveHandler,
791 rEvent,
792 rShape,
793 [this]( const MouseEventHandlerSharedPtr& rHandler )
794 { return this->mrMultiplexer.addMouseMoveHandler( rHandler, 0.0 ); } );
797 void UserEventQueue::callSkipEffectEventHandler()
799 ::std::shared_ptr<SkipEffectEventHandler> pHandler (
800 ::std::dynamic_pointer_cast<SkipEffectEventHandler>(mpSkipEffectEventHandler));
801 if (pHandler)
802 pHandler->skipEffect();
805 } // namespace internal
806 } // namespace presentation
808 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */