diff options
Diffstat (limited to 'slideshow/source/engine/usereventqueue.cxx')
-rw-r--r-- | slideshow/source/engine/usereventqueue.cxx | 1009 |
1 files changed, 0 insertions, 1009 deletions
diff --git a/slideshow/source/engine/usereventqueue.cxx b/slideshow/source/engine/usereventqueue.cxx deleted file mode 100644 index 1e7aa801d..000000000 --- a/slideshow/source/engine/usereventqueue.cxx +++ /dev/null @@ -1,1009 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_slideshow.hxx" - -// must be first -#include <canvas/debug.hxx> -#include <tools/diagnose_ex.h> - -#include <comphelper/anytostring.hxx> -#include <cppuhelper/exc_hlp.hxx> - -#include <com/sun/star/awt/SystemPointer.hpp> -#include <com/sun/star/awt/MouseButton.hpp> -#include <com/sun/star/awt/MouseEvent.hpp> - -#include <boost/bind.hpp> - -#include "delayevent.hxx" -#include "usereventqueue.hxx" -#include "cursormanager.hxx" -#include "slideshowexceptions.hxx" - -#include <vector> -#include <queue> -#include <map> -#include <functional> -#include <algorithm> - - -using namespace com::sun::star; - -/* Implementation of UserEventQueue class */ - -namespace slideshow { -namespace internal { - -namespace { - -typedef std::vector<EventSharedPtr> ImpEventVector; -typedef std::queue<EventSharedPtr> ImpEventQueue; -typedef std::map<uno::Reference<animations::XAnimationNode>, - ImpEventVector> ImpAnimationEventMap; -typedef std::map<ShapeSharedPtr, ImpEventQueue, - Shape::lessThanShape> ImpShapeEventMap; - -// MouseEventHandler base class, not consuming any event: -class MouseEventHandler_ : public MouseEventHandler -{ -public: - virtual bool handleMousePressed( awt::MouseEvent const& /*e*/ ) { return false;} - virtual bool handleMouseReleased( awt::MouseEvent const& /*e*/) { return false;} - virtual bool handleMouseEntered( awt::MouseEvent const& /*e*/ ) { return false;} - virtual bool handleMouseExited( awt::MouseEvent const& /*e*/ ) { return false; } - virtual bool handleMouseDragged( awt::MouseEvent const& /*e*/ ) { return false;} - virtual bool handleMouseMoved( awt::MouseEvent const& /*e*/ ) { return false; } -}; - -/** @return one event has been posted - */ -template <typename ContainerT> -bool fireSingleEvent( ContainerT & rQueue, EventQueue & rEventQueue ) -{ - // post next event in given queue: - while (! rQueue.empty()) - { - EventSharedPtr const pEvent(rQueue.front()); - rQueue.pop(); - - // skip all inactive events (as the purpose of - // nextEventFromQueue() is to activate the next - // event, and events which return false on - // isCharged() will never be activated by the - // EventQueue) - if(pEvent->isCharged()) - return rEventQueue.addEvent( pEvent ); - } - return false; // no more (active) events in queue -} - -/** @return at least one event has been posted - */ -template <typename ContainerT> -bool fireAllEvents( ContainerT & rQueue, EventQueue & rEventQueue ) -{ - bool bFiredAny = false; - while (fireSingleEvent( rQueue, rEventQueue )) - bFiredAny = true; - return bFiredAny; -} - -class EventContainer -{ -public: - EventContainer() : - maEvents() - {} - - void clearContainer() - { - maEvents = ImpEventQueue(); - } - - void addEvent( const EventSharedPtr& rEvent ) - { - maEvents.push( rEvent ); - } - - bool isEmpty() - { - return maEvents.empty(); - } - -protected: - ImpEventQueue maEvents; -}; - -} // anon namespace - -class PlainEventHandler : public EventHandler, - public EventContainer -{ -public: - PlainEventHandler( EventQueue & rEventQueue ) - : EventContainer(), mrEventQueue(rEventQueue) {} - - virtual void dispose() - { - clearContainer(); - } - - virtual bool handleEvent() - { - return fireAllEvents( maEvents, mrEventQueue ); - } - -private: - EventQueue & mrEventQueue; -}; - -class AllAnimationEventHandler : public AnimationEventHandler -{ -public: - AllAnimationEventHandler( EventQueue& rEventQueue ) : - mrEventQueue( rEventQueue ), - maAnimationEventMap() - {} - - virtual void dispose() - { - maAnimationEventMap.clear(); - } - - virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode ) - { - ENSURE_OR_RETURN_FALSE( - rNode, - "AllAnimationEventHandler::handleAnimationEvent(): Invalid node" ); - - bool bRet( false ); - - ImpAnimationEventMap::iterator aIter; - if( (aIter=maAnimationEventMap.find( - rNode->getXAnimationNode() )) != maAnimationEventMap.end() ) - { - ImpEventVector& rVec( aIter->second ); - - bRet = !rVec.empty(); - - // registered node found -> fire all events in the vector - std::for_each( rVec.begin(), rVec.end(), - boost::bind( &EventQueue::addEvent, - boost::ref( mrEventQueue ), _1 ) ); - - rVec.clear(); - } - - return bRet; - } - - void addEvent( const EventSharedPtr& rEvent, - const uno::Reference< animations::XAnimationNode >& xNode ) - { - ImpAnimationEventMap::iterator aIter; - if( (aIter=maAnimationEventMap.find( xNode )) == - maAnimationEventMap.end() ) - { - // no entry for this animation -> create one - aIter = maAnimationEventMap.insert( - ImpAnimationEventMap::value_type( xNode, - ImpEventVector() ) ).first; - } - - // add new event to queue - aIter->second.push_back( rEvent ); - } - - bool isEmpty() - { - // find at least one animation with a non-empty vector - ImpAnimationEventMap::const_iterator aCurr( maAnimationEventMap.begin() ); - const ImpAnimationEventMap::const_iterator aEnd( maAnimationEventMap.end() ); - while( aCurr != aEnd ) - { - if( !aCurr->second.empty() ) - return false; // at least one non-empty entry found - - ++aCurr; - } - - return true; // not a single non-empty entry found - } - -private: - EventQueue& mrEventQueue; - ImpAnimationEventMap maAnimationEventMap; -}; - -class ClickEventHandler : public MouseEventHandler_, - public EventHandler, - public EventContainer -{ -public: - ClickEventHandler( EventQueue& rEventQueue ) : - EventContainer(), - mrEventQueue( rEventQueue ), - mbAdvanceOnClick( true ) - {} - - void setAdvanceOnClick( bool bAdvanceOnClick ) - { - mbAdvanceOnClick = bAdvanceOnClick; - } - -private: - virtual void dispose() - { - clearContainer(); - } - - // triggered by API calls, e.g. space bar - virtual bool handleEvent() - { - return handleEvent_impl(); - } - - // triggered by mouse release: - virtual bool handleMouseReleased( const awt::MouseEvent& evt ) - { - if(evt.Buttons != awt::MouseButton::LEFT) - return false; - - if( mbAdvanceOnClick ) { - // fire next event - return handleEvent_impl(); - } - else { - return false; // advance-on-click disabled - } - } - - // triggered by both: - virtual bool handleEvent_impl() - { - // fire next event: - return fireSingleEvent( maEvents, mrEventQueue ); - } - -private: - EventQueue& mrEventQueue; - bool mbAdvanceOnClick; -}; - -class SkipEffectEventHandler : public ClickEventHandler -{ -public: - SkipEffectEventHandler( EventQueue & rEventQueue, - EventMultiplexer & rEventMultiplexer ) - : ClickEventHandler(rEventQueue), - mrEventQueue(rEventQueue), - mrEventMultiplexer(rEventMultiplexer), - mbSkipTriggersNextEffect(true) {} - - /** Remember to trigger (or not to trigger) the next effect after the - current effect is skiped. - */ - void setSkipTriggersNextEffect (const bool bSkipTriggersNextEffect) - { mbSkipTriggersNextEffect = bSkipTriggersNextEffect; } - - /// Skip the current effect but do not triggere the next effect. - void skipEffect (void) { handleEvent_impl(false); } - -private: - virtual bool handleEvent_impl() - { - return handleEvent_impl(true); - } - - bool handleEvent_impl (bool bNotifyNextEffect) - { - // fire all events, so animation nodes can register their - // next effect listeners: - if(fireAllEvents( maEvents, mrEventQueue )) - { - if (mbSkipTriggersNextEffect && bNotifyNextEffect) - { - // then simulate a next effect event: this skip effect - // handler is triggered upon next effect events (multiplexer - // prio=-1)! Posting a notifyNextEffect() here is only safe - // (we don't run into busy loop), because we assume that - // someone has registerered above for next effects - // (multiplexer prio=0) at the user event queue. - return mrEventQueue.addEventWhenQueueIsEmpty( - makeEvent( boost::bind( &EventMultiplexer::notifyNextEffect, - boost::ref(mrEventMultiplexer) ), - "EventMultiplexer::notifyNextEffect") ); - } - else - return true; - } - return false; - } - -private: - EventQueue & mrEventQueue; - EventMultiplexer & mrEventMultiplexer; - bool mbSkipTriggersNextEffect; -}; - -class RewindEffectEventHandler : public MouseEventHandler_, - public EventContainer -{ -public: - RewindEffectEventHandler( EventQueue & rEventQueue ) - : EventContainer(), mrEventQueue(rEventQueue) {} - -private: - virtual void dispose() - { - clearContainer(); - } - - virtual bool handleMouseReleased( awt::MouseEvent const& evt ) - { - if(evt.Buttons != awt::MouseButton::RIGHT) - return false; - - return fireAllEvents( maEvents, mrEventQueue ); - } - -private: - EventQueue & mrEventQueue; -}; - -/** Base class to share some common code between - ShapeClickEventHandler and MouseMoveHandler - - @derive override necessary MouseEventHandler interface methods, - call sendEvent() method to actually process the event. -*/ -class MouseHandlerBase : public MouseEventHandler_ -{ -public: - MouseHandlerBase( EventQueue& rEventQueue ) : - mrEventQueue( rEventQueue ), - maShapeEventMap() - {} - - virtual void dispose() - { - // TODO(Q1): Check whether plain vector with swap idiom is - // okay here - maShapeEventMap = ImpShapeEventMap(); - } - - void addEvent( const EventSharedPtr& rEvent, - const ShapeSharedPtr& rShape ) - { - ImpShapeEventMap::iterator aIter; - if( (aIter=maShapeEventMap.find( rShape )) == maShapeEventMap.end() ) - { - // no entry for this shape -> create one - aIter = maShapeEventMap.insert( - ImpShapeEventMap::value_type( rShape, - ImpEventQueue() ) ).first; - } - - // add new event to queue - aIter->second.push( rEvent ); - } - - bool isEmpty() - { - // find at least one shape with a non-empty queue - ImpShapeEventMap::reverse_iterator aCurrShape( maShapeEventMap.begin()); - ImpShapeEventMap::reverse_iterator aEndShape( maShapeEventMap.end() ); - while( aCurrShape != aEndShape ) - { - if( !aCurrShape->second.empty() ) - return false; // at least one non-empty entry found - - ++aCurrShape; - } - - return true; // not a single non-empty entry found - } - -protected: - bool hitTest( const awt::MouseEvent& e, - ImpShapeEventMap::reverse_iterator& o_rHitShape ) - { - // find hit shape in map - const basegfx::B2DPoint aPosition( e.X, e.Y ); - - // find matching shape (scan reversely, to coarsely match - // paint order) - ImpShapeEventMap::reverse_iterator aCurrShape(maShapeEventMap.rbegin()); - const ImpShapeEventMap::reverse_iterator aEndShape( maShapeEventMap.rend() ); - while( aCurrShape != aEndShape ) - { - // TODO(F2): Get proper geometry polygon from the - // shape, to avoid having areas outside the shape - // react on the mouse - if( aCurrShape->first->getBounds().isInside( aPosition ) && - aCurrShape->first->isVisible() ) - { - // shape hit, and shape is visible - report a - // hit - o_rHitShape = aCurrShape; - return true; - } - - ++aCurrShape; - } - - return false; // nothing hit - } - - bool sendEvent( ImpShapeEventMap::reverse_iterator& io_rHitShape ) - { - // take next event from queue - const bool bRet( fireSingleEvent( io_rHitShape->second, - mrEventQueue ) ); - - // clear shape entry, if its queue is - // empty. This is important, since the shapes - // are held by shared ptr, and might otherwise - // not get released, even after their owning - // slide is long gone. - if( io_rHitShape->second.empty() ) - { - // this looks funny, since ::std::map does - // provide an erase( iterator ) - // method. Unfortunately, stlport does not - // declare the obvious erase( - // reverse_iterator ) needed here (missing - // orthogonality, eh?) - maShapeEventMap.erase( io_rHitShape->first ); - } - - return bRet; - } - - bool processEvent( const awt::MouseEvent& e ) - { - ImpShapeEventMap::reverse_iterator aCurrShape; - - if( hitTest( e, aCurrShape ) ) - return sendEvent( aCurrShape ); - - return false; // did not handle the event - } - -private: - EventQueue& mrEventQueue; - ImpShapeEventMap maShapeEventMap; -}; - -class ShapeClickEventHandler : public MouseHandlerBase -{ -public: - ShapeClickEventHandler( CursorManager& rCursorManager, - EventQueue& rEventQueue ) : - MouseHandlerBase( rEventQueue ), - mrCursorManager( rCursorManager ) - {} - - virtual bool handleMouseReleased( const awt::MouseEvent& e ) - { - if(e.Buttons != awt::MouseButton::LEFT) - return false; - return processEvent( e ); - } - - virtual bool handleMouseMoved( const awt::MouseEvent& e ) - { - // TODO(P2): Maybe buffer last shape touched - - // if we have a shape click event, and the mouse - // hovers over this shape, change cursor to hand - ImpShapeEventMap::reverse_iterator aDummy; - if( hitTest( e, aDummy ) ) - mrCursorManager.requestCursor( awt::SystemPointer::REFHAND ); - - return false; // we don't /eat/ this event. Lower prio - // handler should see it, too. - } - -private: - CursorManager& mrCursorManager; -}; - -class MouseEnterHandler : public MouseHandlerBase -{ -public: - MouseEnterHandler( EventQueue& rEventQueue ) - : MouseHandlerBase( rEventQueue ), - mpLastShape() {} - - virtual bool handleMouseMoved( const awt::MouseEvent& e ) - { - // TODO(P2): Maybe buffer last shape touched, and - // check against that _first_ - - ImpShapeEventMap::reverse_iterator aCurr; - if( hitTest( e, aCurr ) ) - { - if( aCurr->first != mpLastShape ) - { - // we actually hit a shape, and it's different - // from the previous one - thus we just - // entered it, raise event - sendEvent( aCurr ); - mpLastShape = aCurr->first; - } - } - else - { - // don't hit no shape - thus, last shape is NULL - mpLastShape.reset(); - } - - return false; // we don't /eat/ this event. Lower prio - // handler should see it, too. - } - -private: - ShapeSharedPtr mpLastShape; -}; - -class MouseLeaveHandler : public MouseHandlerBase -{ -public: - MouseLeaveHandler( EventQueue& rEventQueue ) - : MouseHandlerBase( rEventQueue ), - maLastIter() {} - - virtual bool handleMouseMoved( const awt::MouseEvent& e ) - { - // TODO(P2): Maybe buffer last shape touched, and - // check against that _first_ - - ImpShapeEventMap::reverse_iterator aCurr; - if( hitTest( e, aCurr ) ) - { - maLastIter = aCurr; - } - else - { - if( maLastIter->first ) - { - // last time, we were over a shape, now we're - // not - we thus just left that shape, raise - // event - sendEvent( maLastIter ); - } - - // in any case, when we hit this else-branch: no - // shape hit, thus have to clear maLastIter - maLastIter = ImpShapeEventMap::reverse_iterator(); - } - - return false; // we don't /eat/ this event. Lower prio - // handler should see it, too. - } - -private: - ImpShapeEventMap::reverse_iterator maLastIter; -}; - -template< typename Handler, typename Functor > -void UserEventQueue::registerEvent( - boost::shared_ptr< Handler >& rHandler, - const EventSharedPtr& rEvent, - const Functor& rRegistrationFunctor ) -{ - ENSURE_OR_THROW( rEvent, - "UserEventQueue::registerEvent(): Invalid event" ); - - if( !rHandler ) { - // create handler - rHandler.reset( new Handler( mrEventQueue ) ); - // register handler on EventMultiplexer - rRegistrationFunctor( rHandler ); - } - - rHandler->addEvent( rEvent ); -} - -template< typename Handler, typename Arg, typename Functor > -void UserEventQueue::registerEvent( - boost::shared_ptr< Handler >& rHandler, - const EventSharedPtr& rEvent, - const Arg& rArg, - const Functor& rRegistrationFunctor ) -{ - ENSURE_OR_THROW( rEvent, - "UserEventQueue::registerEvent(): Invalid event" ); - - if( !rHandler ) { - // create handler - rHandler.reset( new Handler( mrEventQueue ) ); - - // register handler on EventMultiplexer - rRegistrationFunctor( rHandler ); - } - - rHandler->addEvent( rEvent, rArg ); -} - - -// Public methods -// ===================================================== - -UserEventQueue::UserEventQueue( EventMultiplexer& rMultiplexer, - EventQueue& rEventQueue, - CursorManager& rCursorManager ) - : mrMultiplexer( rMultiplexer ), - mrEventQueue( rEventQueue ), - mrCursorManager( rCursorManager ), - mpStartEventHandler(), - mpEndEventHandler(), - mpAnimationStartEventHandler(), - mpAnimationEndEventHandler(), - mpAudioStoppedEventHandler(), - mpClickEventHandler(), - mpSkipEffectEventHandler(), - mpRewindEffectEventHandler(), - mpDoubleClickEventHandler(), - mpMouseEnterHandler(), - mpMouseLeaveHandler(), - mbAdvanceOnClick( true ) -{ -} - -UserEventQueue::~UserEventQueue() -{ - try - { - // unregister all handlers - clear(); - } - catch (uno::Exception &) { - OSL_FAIL( rtl::OUStringToOString( - comphelper::anyToString( - cppu::getCaughtException() ), - RTL_TEXTENCODING_UTF8 ).getStr() ); - } -} - -bool UserEventQueue::isEmpty() const -{ - // TODO(T2): This is not thread safe, the handlers are all - // only separately synchronized. This poses the danger of - // generating false empty status on XSlideShow::update(), such - // that the last events of a slide are not triggered. - - // we're empty iff all handler queues are empty - return - (mpStartEventHandler ? mpStartEventHandler->isEmpty() : true) && - (mpEndEventHandler ? mpEndEventHandler->isEmpty() : true) && - (mpAnimationStartEventHandler ? mpAnimationStartEventHandler->isEmpty() : true) && - (mpAnimationEndEventHandler ? mpAnimationEndEventHandler->isEmpty() : true) && - (mpAudioStoppedEventHandler ? mpAudioStoppedEventHandler->isEmpty() : true) && - (mpShapeClickEventHandler ? mpShapeClickEventHandler->isEmpty() : true) && - (mpClickEventHandler ? mpClickEventHandler->isEmpty() : true) && - (mpSkipEffectEventHandler ? mpSkipEffectEventHandler->isEmpty() : true) && - (mpRewindEffectEventHandler ? mpRewindEffectEventHandler->isEmpty() : true) && - (mpShapeDoubleClickEventHandler ? mpShapeDoubleClickEventHandler->isEmpty() : true) && - (mpDoubleClickEventHandler ? mpDoubleClickEventHandler->isEmpty() : true) && - (mpMouseEnterHandler ? mpMouseEnterHandler->isEmpty() : true) && - (mpMouseLeaveHandler ? mpMouseLeaveHandler->isEmpty() : true); -} - -void UserEventQueue::clear() -{ - // unregister and delete all handlers - if( mpStartEventHandler ) { - mrMultiplexer.removeSlideStartHandler( mpStartEventHandler ); - mpStartEventHandler.reset(); - } - if( mpEndEventHandler ) { - mrMultiplexer.removeSlideEndHandler( mpEndEventHandler ); - mpEndEventHandler.reset(); - } - if( mpAnimationStartEventHandler ) { - mrMultiplexer.removeAnimationStartHandler( - mpAnimationStartEventHandler ); - mpAnimationStartEventHandler.reset(); - } - if( mpAnimationEndEventHandler ) { - mrMultiplexer.removeAnimationEndHandler( mpAnimationEndEventHandler ); - mpAnimationEndEventHandler.reset(); - } - if( mpAudioStoppedEventHandler ) { - mrMultiplexer.removeAudioStoppedHandler( mpAudioStoppedEventHandler ); - mpAudioStoppedEventHandler.reset(); - } - if( mpShapeClickEventHandler ) { - mrMultiplexer.removeClickHandler( mpShapeClickEventHandler ); - mrMultiplexer.removeMouseMoveHandler( mpShapeClickEventHandler ); - mpShapeClickEventHandler.reset(); - } - if( mpClickEventHandler ) { - mrMultiplexer.removeClickHandler( mpClickEventHandler ); - mrMultiplexer.removeNextEffectHandler( mpClickEventHandler ); - mpClickEventHandler.reset(); - } - if(mpSkipEffectEventHandler) { - mrMultiplexer.removeClickHandler( mpSkipEffectEventHandler ); - mrMultiplexer.removeNextEffectHandler( mpSkipEffectEventHandler ); - mpSkipEffectEventHandler.reset(); - } - if(mpRewindEffectEventHandler) { - mrMultiplexer.removeClickHandler( mpRewindEffectEventHandler ); - mpRewindEffectEventHandler.reset(); - } - if( mpShapeDoubleClickEventHandler ) { - mrMultiplexer.removeDoubleClickHandler( mpShapeDoubleClickEventHandler ); - mrMultiplexer.removeMouseMoveHandler( mpShapeDoubleClickEventHandler ); - mpShapeDoubleClickEventHandler.reset(); - } - if( mpDoubleClickEventHandler ) { - mrMultiplexer.removeDoubleClickHandler( mpDoubleClickEventHandler ); - mpDoubleClickEventHandler.reset(); - } - if( mpMouseEnterHandler ) { - mrMultiplexer.removeMouseMoveHandler( mpMouseEnterHandler ); - mpMouseEnterHandler.reset(); - } - if( mpMouseLeaveHandler ) { - mrMultiplexer.removeMouseMoveHandler( mpMouseLeaveHandler ); - mpMouseLeaveHandler.reset(); - } -} - -void UserEventQueue::setAdvanceOnClick( bool bAdvanceOnClick ) -{ - mbAdvanceOnClick = bAdvanceOnClick; - - // forward to handler, if existing. Otherwise, the handler - // creation will do the forwarding. - if( mpClickEventHandler ) - mpClickEventHandler->setAdvanceOnClick( bAdvanceOnClick ); -} - - -void UserEventQueue::registerSlideStartEvent( const EventSharedPtr& rEvent ) -{ - registerEvent( mpStartEventHandler, - rEvent, - boost::bind( &EventMultiplexer::addSlideStartHandler, - boost::ref( mrMultiplexer ), _1 ) ); -} - -void UserEventQueue::registerSlideEndEvent( const EventSharedPtr& rEvent ) -{ - registerEvent( mpEndEventHandler, - rEvent, - boost::bind( &EventMultiplexer::addSlideEndHandler, - boost::ref( mrMultiplexer ), _1 ) ); -} - -void UserEventQueue::registerAnimationStartEvent( - const EventSharedPtr& rEvent, - const uno::Reference< animations::XAnimationNode>& xNode ) -{ - registerEvent( mpAnimationStartEventHandler, - rEvent, - xNode, - boost::bind( &EventMultiplexer::addAnimationStartHandler, - boost::ref( mrMultiplexer ), _1 ) ); -} - -void UserEventQueue::registerAnimationEndEvent( - const EventSharedPtr& rEvent, - const uno::Reference<animations::XAnimationNode>& xNode ) -{ - registerEvent( mpAnimationEndEventHandler, - rEvent, - xNode, - boost::bind( &EventMultiplexer::addAnimationEndHandler, - boost::ref( mrMultiplexer ), _1 ) ); -} - -void UserEventQueue::registerAudioStoppedEvent( - const EventSharedPtr& rEvent, - const uno::Reference<animations::XAnimationNode>& xNode ) -{ - registerEvent( mpAudioStoppedEventHandler, - rEvent, - xNode, - boost::bind( &EventMultiplexer::addAudioStoppedHandler, - boost::ref( mrMultiplexer ), _1 ) ); -} - -void UserEventQueue::registerShapeClickEvent( const EventSharedPtr& rEvent, - const ShapeSharedPtr& rShape ) -{ - ENSURE_OR_THROW( - rEvent, - "UserEventQueue::registerShapeClickEvent(): Invalid event" ); - - if( !mpShapeClickEventHandler ) - { - // create handler - mpShapeClickEventHandler.reset( - new ShapeClickEventHandler(mrCursorManager, - mrEventQueue) ); - - // register handler on EventMultiplexer - mrMultiplexer.addClickHandler( mpShapeClickEventHandler, 1.0 ); - mrMultiplexer.addMouseMoveHandler( mpShapeClickEventHandler, 1.0 ); - } - - mpShapeClickEventHandler->addEvent( rEvent, rShape ); -} - -namespace { -class ClickEventRegistrationFunctor -{ -public: - ClickEventRegistrationFunctor( EventMultiplexer& rMultiplexer, - double nPrio, - bool bAdvanceOnClick ) - : mrMultiplexer( rMultiplexer ), - mnPrio(nPrio), - mbAdvanceOnClick( bAdvanceOnClick ) {} - - void operator()( const boost::shared_ptr<ClickEventHandler>& rHandler )const - { - // register the handler on _two_ sources: we want the - // nextEffect events, e.g. space bar, to trigger clicks, as well! - mrMultiplexer.addClickHandler( rHandler, mnPrio ); - mrMultiplexer.addNextEffectHandler( rHandler, mnPrio ); - - // forward advance-on-click state to newly - // generated handler (that's the only reason why - // we're called here) - rHandler->setAdvanceOnClick( mbAdvanceOnClick ); - } - -private: - EventMultiplexer& mrMultiplexer; - double const mnPrio; - bool const mbAdvanceOnClick; -}; -} // anon namespace - -void UserEventQueue::registerNextEffectEvent( const EventSharedPtr& rEvent ) -{ - // TODO: better name may be mpNextEffectEventHandler? then we have - // next effect (=> waiting to be started) - // skip effect (skipping the currently running one) - // rewind effect (rewinding back running one and waiting (again) - // to be started) - registerEvent( mpClickEventHandler, - rEvent, - ClickEventRegistrationFunctor( mrMultiplexer, - 0.0 /* default prio */, - mbAdvanceOnClick ) ); -} - -void UserEventQueue::registerSkipEffectEvent( - EventSharedPtr const & pEvent, - const bool bSkipTriggersNextEffect) -{ - if(!mpSkipEffectEventHandler) - { - mpSkipEffectEventHandler.reset( - new SkipEffectEventHandler( mrEventQueue, mrMultiplexer ) ); - // register the handler on _two_ sources: we want the - // nextEffect events, e.g. space bar, to trigger clicks, as well! - mrMultiplexer.addClickHandler( mpSkipEffectEventHandler, - -1.0 /* prio below default */ ); - mrMultiplexer.addNextEffectHandler( mpSkipEffectEventHandler, - -1.0 /* prio below default */ ); - // forward advance-on-click state to newly - // generated handler (that's the only reason why - // we're called here) - mpSkipEffectEventHandler->setAdvanceOnClick( mbAdvanceOnClick ); - } - mpSkipEffectEventHandler->setSkipTriggersNextEffect(bSkipTriggersNextEffect); - mpSkipEffectEventHandler->addEvent( pEvent ); -} - -void UserEventQueue::registerRewindEffectEvent( EventSharedPtr const& pEvent ) -{ - registerEvent( mpRewindEffectEventHandler, - pEvent, - boost::bind( &EventMultiplexer::addClickHandler, - boost::ref(mrMultiplexer), _1, - -1.0 /* prio below default */ ) ); -} - -void UserEventQueue::registerShapeDoubleClickEvent( - const EventSharedPtr& rEvent, - const ShapeSharedPtr& rShape ) -{ - ENSURE_OR_THROW( - rEvent, - "UserEventQueue::registerShapeDoubleClickEvent(): Invalid event" ); - - if( !mpShapeDoubleClickEventHandler ) - { - // create handler - mpShapeDoubleClickEventHandler.reset( - new ShapeClickEventHandler(mrCursorManager, - mrEventQueue) ); - - // register handler on EventMultiplexer - mrMultiplexer.addDoubleClickHandler( mpShapeDoubleClickEventHandler, - 1.0 ); - mrMultiplexer.addMouseMoveHandler( mpShapeDoubleClickEventHandler, - 1.0 ); - } - - mpShapeDoubleClickEventHandler->addEvent( rEvent, rShape ); -} - -void UserEventQueue::registerDoubleClickEvent( const EventSharedPtr& rEvent ) -{ - registerEvent( mpDoubleClickEventHandler, - rEvent, - boost::bind( &EventMultiplexer::addDoubleClickHandler, - boost::ref( mrMultiplexer ), _1, - 0.0 /* default prio */ ) ); -} - -void UserEventQueue::registerMouseEnterEvent( const EventSharedPtr& rEvent, - const ShapeSharedPtr& rShape ) -{ - registerEvent( mpMouseEnterHandler, - rEvent, - rShape, - boost::bind( &EventMultiplexer::addMouseMoveHandler, - boost::ref( mrMultiplexer ), _1, - 0.0 /* default prio */ ) ); -} - -void UserEventQueue::registerMouseLeaveEvent( const EventSharedPtr& rEvent, - const ShapeSharedPtr& rShape ) -{ - registerEvent( mpMouseLeaveHandler, - rEvent, - rShape, - boost::bind( &EventMultiplexer::addMouseMoveHandler, - boost::ref( mrMultiplexer ), _1, - 0.0 /* default prio */ ) ); -} - -void UserEventQueue::callSkipEffectEventHandler (void) -{ - ::boost::shared_ptr<SkipEffectEventHandler> pHandler ( - ::boost::dynamic_pointer_cast<SkipEffectEventHandler>(mpSkipEffectEventHandler)); - if (pHandler) - pHandler->skipEffect(); -} - -} // namespace internal -} // namespace presentation - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |