diff options
Diffstat (limited to '')
74 files changed, 9802 insertions, 0 deletions
diff --git a/slideshow/source/inc/activitiesfactory.hxx b/slideshow/source/inc/activitiesfactory.hxx new file mode 100644 index 000000000..69852489c --- /dev/null +++ b/slideshow/source/inc/activitiesfactory.hxx @@ -0,0 +1,308 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITIESFACTORY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITIESFACTORY_HXX + +#include <com/sun/star/animations/XAnimate.hpp> +#include <com/sun/star/animations/XAnimateColor.hpp> + +#include "animationactivity.hxx" +#include "activitiesqueue.hxx" +#include "event.hxx" +#include "eventqueue.hxx" +#include "shape.hxx" +#include "numberanimation.hxx" +#include "enumanimation.hxx" +#include "coloranimation.hxx" +#include "hslcoloranimation.hxx" +#include "stringanimation.hxx" +#include "boolanimation.hxx" +#include "pairanimation.hxx" + +#include <optional> + +/* Definition of ActivitiesFactory class */ + +namespace slideshow::internal::ActivitiesFactory +{ + /// Collection of common factory parameters + struct CommonParameters + { + CommonParameters( + const EventSharedPtr& rEndEvent, + EventQueue& rEventQueue, + ActivitiesQueue& rActivitiesQueue, + double nMinDuration, + sal_uInt32 nMinNumberOfFrames, + bool bAutoReverse, + ::std::optional<double> const& aRepeats, + double nAcceleration, + double nDeceleration, + const ShapeSharedPtr& rShape, + const ::basegfx::B2DVector& rSlideBounds ) + : mpEndEvent( rEndEvent ), + mrEventQueue( rEventQueue ), + mrActivitiesQueue( rActivitiesQueue ), + mnMinDuration( nMinDuration ), + mnMinNumberOfFrames( nMinNumberOfFrames ), + maRepeats( aRepeats ), + mnAcceleration( nAcceleration ), + mnDeceleration( nDeceleration ), + mpShape( rShape ), + maSlideBounds( rSlideBounds ), + mbAutoReverse( bAutoReverse ) {} + + /// End event to fire when animation is over + EventSharedPtr mpEndEvent; + + /// Event queue to insert the end event into. + EventQueue& mrEventQueue; + /// Event queue to insert the end event into. + ActivitiesQueue& mrActivitiesQueue; + + /** Simple duration of the activity + + Specifies the minimal simple duration of the + activity (minimal, because mnMinNumberOfFrames + might prolong the activity). According to SMIL, + this might also be indefinite, which for our + framework does not make much sense, though + (wouldn't have a clue, then, how to scale the + animation over time). + */ + double mnMinDuration; + + /** Minimal number of frames for this activity. + + This specifies the minimal number of frames this + activity will display per simple duration. If less + than this number are displayed until mnMinDuration + is over, the activity will be prolonged until + mnMinNumberOfFrames are rendered. + */ + sal_uInt32 mnMinNumberOfFrames; + + /** Number of repeats for the simple duration + + This specified the number of repeats. The + mnMinDuration times maRepeats yields the total + duration of this activity. If this value is + unspecified, the activity will repeat + indefinitely. + */ + ::std::optional<double> const maRepeats; + + /// Fraction of simple time to accelerate animation + double mnAcceleration; + + /// Fraction of simple time to decelerate animation + double mnDeceleration; + + /// Shape, to get bounds from + ShapeSharedPtr mpShape; + + /// LayerManager, to get page size from + ::basegfx::B2DVector maSlideBounds; + + /// When true, activity is played reversed after mnDuration. + bool mbAutoReverse; + }; + + /** Create an activity from an XAnimate node. + + This method creates an animated activity from the + given XAnimate node, extracting all necessary + animation parameters from that. Note that due to the + animator parameter, the animation values must be + convertible to a double value. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param xNode + The SMIL animation node to animate + */ + AnimationActivitySharedPtr createAnimateActivity( + const CommonParameters& rParms, + const NumberAnimationSharedPtr& rAnimator, + const css::uno::Reference< css::animations::XAnimate >& xNode ); + + /** Create an activity from an XAnimate node. + + This method creates an animated activity from the + given XAnimate node, extracting all necessary + animation parameters from that. Note that due to the + animator parameter, the animation values must be + convertible to a double value. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param xNode + The SMIL animation node to animate + */ + AnimationActivitySharedPtr createAnimateActivity( + const CommonParameters& rParms, + const EnumAnimationSharedPtr& rAnimator, + const css::uno::Reference< css::animations::XAnimate >& xNode ); + + /** Create an activity from an XAnimate node. + + This method creates an animated activity from the + given XAnimate node, extracting all necessary + animation parameters from that. Note that due to the + animator parameter, the animation values must be + convertible to a color value. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param xNode + The SMIL animation node to animate + */ + AnimationActivitySharedPtr createAnimateActivity( + const CommonParameters& rParms, + const ColorAnimationSharedPtr& rAnimator, + const css::uno::Reference< css::animations::XAnimate >& xNode ); + + /** Create an activity from an XAnimate node. + + This method creates an animated activity from the + given XAnimate node, extracting all necessary + animation parameters from that. Note that due to the + animator parameter, the animation values must be + convertible to a color value. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param xNode + The SMIL animation node to animate + */ + AnimationActivitySharedPtr createAnimateActivity( + const CommonParameters& rParms, + const HSLColorAnimationSharedPtr& rAnimator, + const css::uno::Reference< css::animations::XAnimateColor >& xNode ); + + /** Create an activity from an XAnimate node. + + This method creates an animated activity from the + given XAnimate node, extracting all necessary + animation parameters from that. Note that due to the + animator parameter, the animation values must be + convertible to a pair of double values. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param xNode + The SMIL animation node to animate + */ + AnimationActivitySharedPtr createAnimateActivity( + const CommonParameters& rParms, + const PairAnimationSharedPtr& rAnimator, + const css::uno::Reference< css::animations::XAnimate >& xNode ); + + /** Create an activity from an XAnimate node. + + This method creates an animated activity from the + given XAnimate node, extracting all necessary + animation parameters from that. Note that due to the + animator parameter, the animation values must be + convertible to a string. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param xNode + The SMIL animation node to animate + */ + AnimationActivitySharedPtr createAnimateActivity( + const CommonParameters& rParms, + const StringAnimationSharedPtr& rAnimator, + const css::uno::Reference< css::animations::XAnimate >& xNode ); + + /** Create an activity from an XAnimate node. + + This method creates an animated activity from the + given XAnimate node, extracting all necessary + animation parameters from that. Note that due to the + animator parameter, the animation values must be + convertible to a bool value. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param xNode + The SMIL animation node to animate + */ + AnimationActivitySharedPtr createAnimateActivity( + const CommonParameters& rParms, + const BoolAnimationSharedPtr& rAnimator, + const css::uno::Reference< css::animations::XAnimate >& xNode ); + + /** Create a simple activity for the given animator + + This method is suited to create activities for custom + animations, which need a simple double value and lasts + a given timespan. This activity always generates values + from the [0,1] range. + + @param rParms + Factory parameter structure + + @param rAnimator + Animator sub-object + + @param bDirectionForward + If true, the activity goes 'forward', i.e. from 0 to + 1. With false, the direction is reversed. + */ + AnimationActivitySharedPtr createSimpleActivity( + const CommonParameters& rParms, + const NumberAnimationSharedPtr& rAnimator, + bool bDirectionForward ); + +} // namespace presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITIESFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/activitiesqueue.hxx b/slideshow/source/inc/activitiesqueue.hxx new file mode 100644 index 000000000..9fd3df83a --- /dev/null +++ b/slideshow/source/inc/activitiesqueue.hxx @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITIESQUEUE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITIESQUEUE_HXX + +#include <deque> + +#include "activity.hxx" + +#include <canvas/elapsedtime.hxx> + +#include <memory> + + +/* Definition of ActivitiesQueue class */ + +namespace slideshow::internal + { + /** This class handles the XSprite updates needed for + animations, such as moves, scales etc. You can add + activity objects to this class, which are called in a + round-robin fashion. + */ + class ActivitiesQueue + { + public: + /** Create an ActivitiesQueue. + + @param pPresTimer + Pointer to global presentation timer. Used for + adjusting and holding global presentation time. + */ + explicit ActivitiesQueue( + const std::shared_ptr< ::canvas::tools::ElapsedTime >& pPresTimer ); + ~ActivitiesQueue(); + ActivitiesQueue(const ActivitiesQueue&) = delete; + ActivitiesQueue& operator=(const ActivitiesQueue&) = delete; + + /** Add the given activity to the queue. + */ + bool addActivity( const ActivitySharedPtr& pActivity ); + + /** Add the given activity prioritized last in the queue. + */ + bool addTailActivity( const ActivitySharedPtr& pActivity ); + + /** Process the activities queue. + + This method performs the smallest atomic processing + possible on the queue (typically, this means one + activity get processed). + */ + void process(); + + /** Call all dequeued activities' dequeued() method + */ + void processDequeued(); + + /** Query state of the queue + + @return false, if queue is empty, true otherwise + */ + bool isEmpty() const; + + /** Remove all pending activities from the queue. + */ + void clear(); + + /** Gets the queue's timer object. + */ + std::shared_ptr< ::canvas::tools::ElapsedTime > const & + getTimer() const { return mpTimer; } + + private: + std::shared_ptr< ::canvas::tools::ElapsedTime > mpTimer; + + typedef ::std::deque< ActivitySharedPtr > ActivityQueue; + + ActivityQueue maCurrentActivitiesWaiting; // currently running + // activities, that still + // await processing for this + // round + + ActivityQueue maCurrentTailActivitiesWaiting; // activities that will be + // processed last in the queue + + ActivityQueue maCurrentActivitiesReinsert; // currently running + // activities, that are + // already processed for + // this round, and wants + // to be reinserted next + // round + + ActivityQueue maDequeuedActivities; // This list collects all activities which did not request + // a reinsertion. After the screen update has been + // performed, those are notified via dequeued(). This + // facilitates cleanup actions taking place _after_ the + // current frame has been displayed. + }; + +} +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITIESQUEUE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/activity.hxx b/slideshow/source/inc/activity.hxx new file mode 100644 index 000000000..5de30c79d --- /dev/null +++ b/slideshow/source/inc/activity.hxx @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITY_HXX + +#include <memory> + +#include "disposable.hxx" + + +/* Definition of Activity interface */ + +namespace slideshow::internal + { + + class Activity : public Disposable, public virtual SharedPtrAble + { + public: + /** Perform the activity associated with this interface's + implementation. + + @return true, if activity continues, or false, if activity has + ended. + */ + virtual bool perform() = 0; + + /** Calculates whether the activity lags time. + + If this method returns a time lag greater than 0.0, + the ActivitiesQueue will adjust the global slideshow + time, by subtracting the given amount of lag. + + @return time lag or 0.0. Value must be greater or + equal than zero. + */ + virtual double calcTimeLag() const = 0; + + /** Query whether this activity is still continuing + + @return true, if this activity still + continues. Returns false, if activity has ended. It is + required that operator() returns false, when + isActive() returns false. Furthermore, it is required + that the inactive state is persistent; an activity + that has become inactive (i.e. isActive() once + returned false) must stay in that state eternally. + */ + virtual bool isActive() const = 0; + + /** Notifies the Activity that it has now left the + ActivitiesQueue + + Use this method to react on the queue removal + event. For animated shapes, this is e.g. used to + switch back to the non-sprite presentation mode of the + shape. + */ + virtual void dequeued() = 0; + + /** Forces this activity deactivate and get to its end state + (if possible), but does _not_ dispose. + */ + virtual void end() = 0; + }; + + typedef ::std::shared_ptr< Activity > ActivitySharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ACTIVITY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animatableshape.hxx b/slideshow/source/inc/animatableshape.hxx new file mode 100644 index 000000000..7cefad0f6 --- /dev/null +++ b/slideshow/source/inc/animatableshape.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATABLESHAPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATABLESHAPE_HXX + +#include <memory> + +#include "shape.hxx" + + +namespace slideshow::internal + { + /** Represents an animatable shape. + + This interface adds animation handling methods to a + shape. It allows transparent switching between + sprite-based viewing and static painting, depending on + whether animations are currently running. + */ + class AnimatableShape : public Shape + { + public: + // Animation methods + + + /** Notify the Shape that an animation starts now + + This method enters animation mode on all registered + views. + + @attention This method is supposed to be called only + from the LayerManager, since it might involve shifting + shapes between different layers (and removing this + shape from the background layer in the first place) + */ + virtual void enterAnimationMode() = 0; + + /** Notify the Shape that it is no longer animated + + This methods requests the Shape to end animation mode + on all registered views, if called more or equal the + times enterAnimationMode() was called. That is, the + Shape only leaves animation mode, if all requested + enterAnimationMode() call sites have issued their + matching leaveAnimationMode(). + + @attention This method is supposed to be called only + from the LayerManager, since it might involve shifting + shapes between different layers (and adding this + shape to the background layer again) + */ + virtual void leaveAnimationMode() = 0; + + }; + + typedef ::std::shared_ptr< AnimatableShape > AnimatableShapeSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATABLESHAPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animatedsprite.hxx b/slideshow/source/inc/animatedsprite.hxx new file mode 100644 index 000000000..18d4eecb2 --- /dev/null +++ b/slideshow/source/inc/animatedsprite.hxx @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATEDSPRITE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATEDSPRITE_HXX + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> + +#include "viewlayer.hxx" + +#include <optional> +#include <memory> + + +/* Definition of AnimatedSprite class */ + +namespace slideshow::internal + { + /** This class provides the sprite for animated shapes. + + Besides encapsulating the Canvas sprite for animated + shapes, this class also handles dynamic sprite resizing + and all the gory details of offset calculations and + rounding prevention. + */ + class AnimatedSprite + { + public: + /** Create a new AnimatedSprite, for the given metafile + shape. + + @param rViewLayer + The destination view layer, on which the animation should appear + + @param rSpriteSizePixel + The overall size of the sprite in device coordinate + space, sufficient to display all transformations, + shape changes and clips. + + @param nSpritePrio + Priority of the sprite. Must remain static over the + lifetime of this object + */ + AnimatedSprite( const ViewLayerSharedPtr& rViewLayer, + const ::basegfx::B2DSize& rSpriteSizePixel, + double nSpritePrio ); + AnimatedSprite(const AnimatedSprite&) = delete; + AnimatedSprite& operator=(const AnimatedSprite&) = delete; + + /** Resize the sprite. + + @param rSpriteSizePixel + The new size in pixel + */ + void resize( const ::basegfx::B2DSize& rSpriteSizePixel ); + + /** Set an offset for the content output in pixel + + This method offsets the output on the sprite content + canvas by the specified amount of device pixel (for + subsequent render operations). + */ + void setPixelOffset( const ::basegfx::B2DSize& rPixelOffset ); + + /// Show the sprite + void show(); + + /// Hide the sprite + void hide(); + + /** Query the content canvas for the current sprite. + + Note that this method must be called + <em>every time</em> something is rendered to the + sprite, because XCustomSprite does not guarantee the + validity of the canvas after a render operation. + + Furthermore, the view transformation on the returned + canvas is already correctly setup, matching the + associated destination canvas. + */ + ::cppcanvas::CanvasSharedPtr getContentCanvas() const; + + /** Move the sprite in device pixel space. + + If the sprite is not yet created, this method has no + effect. + */ + void movePixel( const ::basegfx::B2DPoint& rNewPos ); + + /** Set the alpha value of the sprite. + + If the sprite is not yet created, this method has no + effect. + */ + void setAlpha( double rAlpha ); + + /** Set a sprite clip in user coordinate space. + + If the sprite is not yet created, this method has no + effect. + */ + void clip( const ::basegfx::B2DPolyPolygon& rClip ); + + /** Clears a sprite clip + + If the sprite is not yet created, this method has no + effect. + */ + void clip(); + + /** Set a sprite transformation. + + If the sprite is not yet created, this method has no + effect. + */ + void transform( const ::basegfx::B2DHomMatrix& rTransform ); + + private: + ViewLayerSharedPtr mpViewLayer; + + ::cppcanvas::CustomSpriteSharedPtr mpSprite; + ::basegfx::B2DSize maEffectiveSpriteSizePixel; + ::basegfx::B2DSize maContentPixelOffset; + + double mnSpritePrio; + double mnAlpha; + ::std::optional< ::basegfx::B2DPoint > maPosPixel; + ::std::optional< ::basegfx::B2DPolyPolygon > maClip; + + bool mbSpriteVisible; + }; + + typedef ::std::shared_ptr< AnimatedSprite > AnimatedSpriteSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATEDSPRITE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animation.hxx b/slideshow/source/inc/animation.hxx new file mode 100644 index 000000000..a9264d76b --- /dev/null +++ b/slideshow/source/inc/animation.hxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATION_HXX + +#include "animatableshape.hxx" +#include "shapeattributelayer.hxx" +#include "disposable.hxx" + + +/* Definition of Animation interface */ + +namespace slideshow::internal + { + /** Interface defining a generic animation. + + This interface is used by objects implementing the + Activity interface to drive the animation effect. Objects + implementing this interface will receive time-varying + animation values, which they can forward to the + appropriate attributes. The type of these animation values + is given in derived interfaces. + + @see NumberAnimation + @see ColorAnimation + @see PairAnimation + */ + class Animation : public virtual SharedPtrAble + { + public: + /** Notify that the animation going active soon. + + Implementers should preload any buffers, and create + any expensive objects at this time. + + @param rShape + Shape to apply this animation to. + + @param rAttrLayer + Attribute layer to play the animation on. + */ + virtual void prefetch( ) = 0; + + /** Notify that the animation is about to begin. + + Implementers are free to start accompanying effects, + such as sounds, and the animation timer now. + + @param rShape + Shape to apply this animation to. + + @param rAttrLayer + Attribute layer to play the animation on. + */ + virtual void start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) = 0; + + /** Notify that the animation is about to end. + */ + virtual void end() = 0; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animationactivity.hxx b/slideshow/source/inc/animationactivity.hxx new file mode 100644 index 000000000..20454aa59 --- /dev/null +++ b/slideshow/source/inc/animationactivity.hxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONACTIVITY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONACTIVITY_HXX + +#include "activity.hxx" +#include "animatableshape.hxx" +#include "shapeattributelayer.hxx" + + +/* Definition of AnimationActivity interface */ + +namespace slideshow::internal + { + + /** Extends the Activity interface with animation-specific functions + */ + class AnimationActivity : public Activity + { + public: + /** Sets targets (shape and attributeLayer) + + Since attribute layers can only be generated when the + animation starts, the Activity owner must be able to + pass it into the Activity after initial creation. The + same applies to the actual shape the animation must + run for, since e.g. subsetted shapes are generated + close before the animation starts, too (this is not + necessary in and out of itself, but for performance + reasons. Otherwise, character iterations produce tons + of subset shapes). + + @param rShape + Shape to play the animation on. + + @param rAttrLayer + Attribute layer to change the animated values on. + */ + virtual void setTargets( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) = 0; + }; + + typedef ::std::shared_ptr< AnimationActivity > AnimationActivitySharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONACTIVITY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animationeventhandler.hxx b/slideshow/source/inc/animationeventhandler.hxx new file mode 100644 index 000000000..0c66ffd5a --- /dev/null +++ b/slideshow/source/inc/animationeventhandler.hxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONEVENTHANDLER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONEVENTHANDLER_HXX + +#include <memory> +#include "animationnode.hxx" + + +/* Definition of AnimationEventHandler interface */ + +namespace slideshow::internal + { + + /** Interface for handling animation events. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle animation state change events. + */ + class AnimationEventHandler + { + public: + virtual ~AnimationEventHandler() {} + + /** Handle the event. + + @param rNode + Animation node which caused this event to fire + + @return true, if this handler has successfully + processed the animation event. When this method + returns false, possibly other, less prioritized + handlers are called, too. + */ + virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode ) = 0; + }; + + typedef ::std::shared_ptr< AnimationEventHandler > AnimationEventHandlerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONEVENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animationfactory.hxx b/slideshow/source/inc/animationfactory.hxx new file mode 100644 index 000000000..3004c7130 --- /dev/null +++ b/slideshow/source/inc/animationfactory.hxx @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONFACTORY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONFACTORY_HXX + + +#include "numberanimation.hxx" +#include "enumanimation.hxx" +#include "coloranimation.hxx" +#include "stringanimation.hxx" +#include "boolanimation.hxx" +#include "pairanimation.hxx" + +#include "shapemanager.hxx" + +namespace box2d::utils { typedef ::std::shared_ptr< class box2DWorld > Box2DWorldSharedPtr; } + +/* Definition of AnimationFactory class */ + +namespace slideshow::internal + { + + /** Factory for Animation objects + + Given a SMIL XAnimate node, this factory generates the + appropriate Animation object from that, which will modify + the attribute as specified. + */ + namespace AnimationFactory + { + /** Classifies the attribute name. + + This enum maps names to appropriate factory methods. + */ + enum AttributeClass + { + /// Unknown, prolly invalid name + CLASS_UNKNOWN_PROPERTY, + /// Use createNumberPropertyAnimation + CLASS_NUMBER_PROPERTY, + /// Use createEnumPropertyAnimation + CLASS_ENUM_PROPERTY, + /// Use createColorPropertyAnimation + CLASS_COLOR_PROPERTY, + /// Use createStringPropertyAnimation + CLASS_STRING_PROPERTY, + /// Use createBoolPropertyAnimation + CLASS_BOOL_PROPERTY + }; + + AttributeClass classifyAttributeName( const OUString& rAttrName ); + + /// Collection of flags common to all factory methods + enum FactoryFlags + { + /** Don't call enter/leaveAnimation for the Shape. + + This is useful for set effects + */ + FLAG_NO_SPRITE = 1 + }; + + NumberAnimationSharedPtr createNumberPropertyAnimation( const OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + int nFlags=0 ); + + EnumAnimationSharedPtr createEnumPropertyAnimation( const OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + int nFlags ); + + ColorAnimationSharedPtr createColorPropertyAnimation( const OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + int nFlags=0 ); + + /** Create scale or move animation + + @param nTransformType + Must be one of + animations::AnimationTransformType::TRANSLATE or + animations::AnimationTransformType::SCALE. + */ + PairAnimationSharedPtr createPairPropertyAnimation( const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + sal_Int16 nTransformType, + int nFlags ); + + StringAnimationSharedPtr createStringPropertyAnimation( const OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + int nFlags ); + + BoolAnimationSharedPtr createBoolPropertyAnimation( const OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + int nFlags ); + + NumberAnimationSharedPtr createPathMotionAnimation( const OUString& rSVGDPath, + sal_Int16 nAdditive, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + int nFlags ); + + NumberAnimationSharedPtr createPhysicsAnimation( const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + const double fDuration, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + const ::basegfx::B2DVector& rStartVelocity, + const double fDensity, + const double fBounciness, + int nFlags ); + } + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animationnode.hxx b/slideshow/source/inc/animationnode.hxx new file mode 100644 index 000000000..14fd21ce9 --- /dev/null +++ b/slideshow/source/inc/animationnode.hxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONNODE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONNODE_HXX + +#include "disposable.hxx" + +#include <com/sun/star/animations/XAnimationNode.hpp> +#include <memory> + +namespace slideshow::internal +{ +class AnimationNode; +typedef ::std::shared_ptr<AnimationNode> AnimationNodeSharedPtr; + +/** This interface is used to mirror every XAnimateNode object + in the presentation core. +*/ +class AnimationNode : public Disposable +{ +public: + /** The current state of this AnimationNode + */ + enum NodeState + { + /// Invalid state, node is disposed or otherwise invalid + INVALID = 0, + /// Unresolved start time + UNRESOLVED = 1, + /// Resolved start time, node will start eventually + RESOLVED = 2, + /// Node is active + ACTIVE = 4, + /// Node is frozen (no longer active, but changes remain in place) + FROZEN = 8, + /// Node has completed an active lifecycle, + /// and any effect is removed from the document + ENDED = 16 + }; + + /** Query the corresponding XAnimationNode. + */ + virtual css::uno::Reference<css::animations::XAnimationNode> getXAnimationNode() const = 0; + + /** Init this node + + If this node is not in state INVALID, init() sets up the + node state and schedules necessary events. + If this node has children, they have their init() called, too. + You will call this method whenever a slide is going to be + shown. + + @return true, if init was successful; state has changed to UNRESOLVED + */ + virtual bool init() = 0; + + /** Resolve node start time + + Nodes can have unresolved start times, i.e. indefinite + start time for container nodes, or child nodes whose + parent has not yet started. Calling this method fixes + the node's start time. This does not mean that this + node immediately starts its animations, that is only + the case for begin=0.0. The node will change its state + to RESOLVED. + + @return true, if a start event was successfully scheduled. + */ + virtual bool resolve() = 0; + + /** Immediately start this node + + This method starts the animation on this node, without + begin timeout. The node will change its state to ACTIVE. + */ + virtual void activate() = 0; + + /** Immediately stop this node + + This method stops the animation on this node. The node + will change its state to either ENDED or FROZEN, + depending on XAnimationNode attributes. + */ + virtual void deactivate() = 0; + + /** End the animation on this node + + This method force-ends animation on this node. Parents + may call this for their children, if their active + duration ends. An ended animation will no longer have + any effect on the shape attributes. The node will + change its state to ENDED. + */ + virtual void end() = 0; + + /** Query node state + + @return the current state of this animation node. + */ + virtual NodeState getState() const = 0; + + /** Register a deactivating listener + + This method registers another AnimationNode as an + deactivating listener, which gets notified via a + notifyDeactivating() call. The node calls all + registered listener, when it leaves the ACTIVE state. + + @param rNotifee AnimationNode to notify + */ + virtual bool registerDeactivatingListener(const AnimationNodeSharedPtr& rNotifee) = 0; + + /** Called to notify another AnimationNode's deactivation + + @param rNotifier The instance who calls this method. + */ + virtual void notifyDeactivating(const AnimationNodeSharedPtr& rNotifier) = 0; + + /** Called by the container to remove the animation effect + to make the painted shape correct if it restart because + of repeat or rewind ( fill mode is AnimationFill::REMOVE ) + to start state. + */ + virtual void removeEffect() = 0; + + /** Query node whether it has an animation pending. + + @return true, if this node (or at least one of its children) + has an animation pending. Used to determine if the main + sequence is actually empty, or contains effects + */ + virtual bool hasPendingAnimation() const = 0; +}; + +} // namespace presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONNODE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/animationnodefactory.hxx b/slideshow/source/inc/animationnodefactory.hxx new file mode 100644 index 000000000..af424ec50 --- /dev/null +++ b/slideshow/source/inc/animationnodefactory.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONNODEFACTORY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONNODEFACTORY_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/animations/XAnimationNode.hpp> + +#include <basegfx/vector/b2dvector.hxx> + +#include "animationnode.hxx" +#include "slideshowcontext.hxx" + + +namespace slideshow::internal::AnimationNodeFactory +{ + /* Definition of AnimationNodeFactory class */ + + /** Create an AnimationNode for the given XAnimationNode + */ + AnimationNodeSharedPtr createAnimationNode( const css::uno::Reference< css::animations::XAnimationNode >& xNode, + const ::basegfx::B2DVector& rSlideSize, + const SlideShowContext& rContext ); + + +#if defined(DBG_UTIL) + void showTree( AnimationNodeSharedPtr const & pRootNode ); +# define SHOW_NODE_TREE(a) AnimationNodeFactory::showTree(a) +#else +# define SHOW_NODE_TREE(a) +#endif + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ANIMATIONNODEFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/attributableshape.hxx b/slideshow/source/inc/attributableshape.hxx new file mode 100644 index 000000000..d903c3b2a --- /dev/null +++ b/slideshow/source/inc/attributableshape.hxx @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ATTRIBUTABLESHAPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ATTRIBUTABLESHAPE_HXX + +#include <memory> + +#include "animatableshape.hxx" +#include "shapeattributelayer.hxx" +#include "doctreenodesupplier.hxx" + +namespace slideshow::internal + { + // forward declaration necessary, because methods use AttributableShapeSharedPtr + class AttributableShape; + + typedef ::std::shared_ptr< AttributableShape > AttributableShapeSharedPtr; + + /** Represents an animatable shape, that can have its + attributes changed. + + Over an animatable shape, this interface adds attribute + modification methods. Furthermore, the shape can be + queried for sub items, which in turn can be separated out + into own AttributableShapes. + */ + class AttributableShape : public AnimatableShape + { + public: + // Attribute layer methods + + + /** Create a new shape attribute layer. + + This method creates a new layer for shape attributes, + which lies atop of all previous attribute layers. That + is most typically used when a new SMIL animation + starts (which according to the spec always lies atop + of all previous animations). Thus, subsequent calls to + this method generate a sandwich of attribute layers, + which in total define the shape's attributes. + + Please note that the attribute layers do <em>not</em> + contain the underlying XShape's attributes as + default. Instead, attributes not explicitly set by + animations remain in invalid state, allowing the + shape's paint method to determine whether they have to + override the underlying graphical shape + representation. XShape attributes must be passed + explicitly to animations which need them (e.g. 'by' + animations). + + @return the new layer + */ + virtual ShapeAttributeLayerSharedPtr createAttributeLayer() = 0; + + /** Revoke a previously generated attribute layer. + + This method revokes a previously generated attribute + layer, and removes the effect of that layer from this + shape. The layer need not be the current toplevel + layer, it can also be revoked from in between. + + @param rLayer + Layer to revoke. Must have been generated by + createAttributeLayer() at the same Shape. + + @return true, if layer was successfully removed, false + otherwise (e.g. if the given layer was not generated + for this shape). + */ + virtual bool revokeAttributeLayer( const ShapeAttributeLayerSharedPtr& rLayer ) = 0; + + /** Get the topmost shape attribute layer (if any). + + This method returns the topmost layer for shape + attributes, i.e. the one which ultimately determines + the shape's look. + + Please note that the attribute layers do <em>not</em> + contain the underlying XShape's attributes as + default. Instead, attributes not explicitly set by + animations remain in invalid state, allowing the + shape's paint method to determine whether they have to + override the underlying graphical shape + representation. XShape attributes must be passed + explicitly to animations which need them (e.g. 'by' + animations). + + @return the topmost layer + */ + virtual ShapeAttributeLayerSharedPtr getTopmostAttributeLayer() const = 0; + + + /** Change default shape visibility + + This method hides or unhides a shape. Note that every + attribute layer generated for this shape is able to + override the setting given here, until it is revoked. + + @param bVisible + When true, shape will be visible, when false, + invisible (modulo attribute layer overrides). + */ + virtual void setVisibility( bool bVisible ) = 0; + + // Sub-item handling + + + /** Retrieve interface for DocTreeNode creation. + + This method provides the caller with a reference to + the DocTreeNodeSupplier interface, which can be used + to request specific tree nodes for this shape. + */ + virtual const DocTreeNodeSupplier& getTreeNodeSupplier() const = 0; + virtual DocTreeNodeSupplier& getTreeNodeSupplier() = 0; + + /** Query the subset this shape displays. + + This method returns a tree node denoting the subset + displayed by this shape. If this shape is not a subset + shape, an empty tree node should be returned. If this + shape is a subset, and itself has subsetted children, + this method might return more than the shape is + actually displaying (because a single DocTreeNode is + not able to model holes in the range). + */ + virtual DocTreeNode getSubsetNode() const = 0; + + /** Query a subset Shape, if already existent at this + object + + This method returns a clone of this Shape, which + renders only the selected subset of itself, but only + if such a subset has been explicitly created before. + + @param rTreeNode + A DocTreeNode instance queried from this Shape, which + specifies the subset of the Shape to render. + + @return a NULL Shape pointer, if no subset exists for + the given DocTreeNode. + */ + virtual AttributableShapeSharedPtr getSubset( const DocTreeNode& rTreeNode ) const = 0; + + /** Create a subset Shape + + This method creates a clone of this Shape, which + renders only the selected subset of itself. Multiple + createSubset() calls for the same DocTreeNode will all + share the same subset shape. + + The original shape (i.e. the one this method is called + on) will cease to display the selected subset + part. That is, together the shapes will display the + original content, but the content of all subset shapes + and their original shape will always be mutually + disjunct. + + After deregistering the subset shape a matching number + of times via revokeSubset(), the original shape will + resume displaying the subsetted part. + + @attention To maintain view integrity, this method + should only be called from the LayerManager + + @param o_rSubset + The requested Shape + + @param rTreeNode + A DocTreeNode instance queried from this Shape, which + specifies the subset of the Shape to render + + @return true, if the shape was newly created, and + false, if an already existing subset is returned. + */ + virtual bool createSubset( AttributableShapeSharedPtr& o_rSubset, + const DocTreeNode& rTreeNode ) = 0; + + /** Revoke a previously generated shape subset. + + After revoking a subset shape, the corresponding + subset part will become visible again on the original + shape. + + @attention To maintain view integrity, this method + should only be called from the LayerManager + + @param rShape + The subset to revoke + + @return true, if the last client called + revokeSubset(). + */ + virtual bool revokeSubset( const AttributableShapeSharedPtr& rShape ) = 0; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ATTRIBUTABLESHAPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/attributemap.hxx b/slideshow/source/inc/attributemap.hxx new file mode 100644 index 000000000..1cd9b0f30 --- /dev/null +++ b/slideshow/source/inc/attributemap.hxx @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ATTRIBUTEMAP_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ATTRIBUTEMAP_HXX + +#include <rtl/ustring.hxx> + +/* Definition of AttributeMap helper function */ + +namespace slideshow::internal + { + /** Type of to-be-animated attribute. + + This enum describes the type of an animated + attribute. + */ + enum class AttributeType + { + Invalid, + CharColor, + CharFontName, + CharHeight, + CharPosture, + CharUnderline, + CharWeight, + Color, + DimColor, + FillColor, + FillStyle, + Height, + LineColor, + LineStyle, + Opacity, + Rotate, + SkewX, + SkewY, + Visibility, + Width, + PosX, + PosY + }; + + /** Map attribute name to AttributeType enum + + @returns AttributeType::Invalid, if name was not found in the + mapping table. + */ + AttributeType mapAttributeName( const OUString& rAttrName ); + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ATTRIBUTEMAP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/basecontainernode.hxx b/slideshow/source/inc/basecontainernode.hxx new file mode 100644 index 000000000..79dbe3f2f --- /dev/null +++ b/slideshow/source/inc/basecontainernode.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_BASECONTAINERNODE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_BASECONTAINERNODE_HXX + +#include "basenode.hxx" + +namespace slideshow::internal { + +class BaseContainerNode; +typedef ::std::shared_ptr< BaseContainerNode > BaseContainerNodeSharedPtr; + + +/** This interface extends BaseNode with child handling methods. + Used for XAnimationNode objects which have children +*/ +class BaseContainerNode : public BaseNode +{ +public: + BaseContainerNode( + css::uno::Reference<css::animations::XAnimationNode> const& xNode, + BaseContainerNodeSharedPtr const& pParent, + NodeContext const& rContext ); + + /** Add given child node to this container + */ + void appendChildNode( AnimationNodeSharedPtr const& pNode ); + +#if defined(DBG_UTIL) + virtual void showState() const override; + virtual const char* getDescription() const override { return "BaseContainerNode"; } +#endif + +protected: + // overrides from BaseNode + virtual void dispose() override; + +private: + virtual bool init_st() override; + bool init_children(); + virtual void deactivate_st( NodeState eDestState ) override; + virtual bool hasPendingAnimation() const override; + // force to be implemented by derived class: + virtual void activate_st() override = 0; + virtual void notifyDeactivating( + AnimationNodeSharedPtr const& rNotifier ) override = 0; + +protected: + bool isDurationIndefinite() const { return mbDurationIndefinite; } + + bool isChildNode( AnimationNodeSharedPtr const& pNode ) const; + + /// @return true: if all children have been deactivated + bool notifyDeactivatedChild( AnimationNodeSharedPtr const& pChildNode ); + + void repeat(); + + template <typename FuncT> + void forEachChildNode( FuncT func, + int nodeStateMask ) const + { + for (AnimationNodeSharedPtr const& pNode : maChildren) { + if (nodeStateMask != -1 && (pNode->getState() & nodeStateMask) == 0) + continue; + func(pNode); + } + } + + typedef ::std::vector<AnimationNodeSharedPtr> VectorOfNodes; + VectorOfNodes maChildren; + ::std::size_t mnFinishedChildren; + double mnLeftIterations; + +private: + const bool mbRepeatIndefinite; + const bool mbRestart; + const bool mbDurationIndefinite; +}; + +} // namespace presentation::interface + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/basenode.hxx b/slideshow/source/inc/basenode.hxx new file mode 100644 index 000000000..668d9de93 --- /dev/null +++ b/slideshow/source/inc/basenode.hxx @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_BASENODE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_BASENODE_HXX + +#include <basegfx/vector/b2dvector.hxx> +#include <tools/diagnose_ex.h> +#include <osl/diagnose.hxx> + +#include "event.hxx" +#include "animationnode.hxx" +#include "slideshowcontext.hxx" +#include "shapesubset.hxx" + +#include <vector> + +namespace slideshow::internal { + +/** Context for every node. + + Besides the global AnimationNodeFactory::Context data, + this struct also contains the current DocTree subset + for this node. If start and end index of the + DocTreeNode are equal, the node should use the + complete shape. +*/ +struct NodeContext +{ + NodeContext( const SlideShowContext& rContext, + const ::basegfx::B2DVector& rSlideSize ) + : maContext( rContext ), + maSlideSize( rSlideSize ), + mpMasterShapeSubset(), + mnStartDelay(0.0), + mbIsIndependentSubset( true ) + {} + + /// Context as passed to createAnimationNode() + SlideShowContext maContext; + + /// Size in user coordinate space of the corresponding slide + ::basegfx::B2DVector maSlideSize; + + /// Shape to be used (provided by parent, e.g. for iterations) + ShapeSubsetSharedPtr mpMasterShapeSubset; + + /// Additional delay to node begin (to offset iterate effects) + double mnStartDelay; + + /// When true, subset must be created during slide initialization + bool mbIsIndependentSubset; +}; + +class BaseContainerNode; +typedef ::std::shared_ptr< BaseContainerNode > BaseContainerNodeSharedPtr; + +class BaseNode; +typedef ::std::shared_ptr< BaseNode > BaseNodeSharedPtr; + + +/** This interface extends AnimationNode with some + file-private accessor methods. +*/ +class BaseNode : public AnimationNode, + public ::osl::DebugBase<BaseNode> +{ +public: + BaseNode( css::uno::Reference<css::animations::XAnimationNode> const& xNode, + BaseContainerNodeSharedPtr const& pParent, + NodeContext const& rContext ); + BaseNode(const BaseNode&) = delete; + BaseNode& operator=(const BaseNode&) = delete; + + /** Provide the node with a shared_ptr to itself. + + Since implementation has to create objects which need + a shared_ptr to this node, and a pointee cannot + retrieve a shared_ptr to itself internally, have to + set that from the outside. + */ + void setSelf( const BaseNodeSharedPtr& rSelf ); + + +#if defined(DBG_UTIL) + virtual void showState() const; + virtual const char* getDescription() const; +#endif + + const ::std::shared_ptr< BaseContainerNode >& getParentNode() const + { return mpParent; } + + // Disposable: + virtual void dispose() override; + + // AnimationNode: + virtual bool init() override; + virtual bool resolve() override; + virtual void activate() override; + virtual void deactivate() override; + virtual void end() override; + virtual css::uno::Reference<css::animations::XAnimationNode> getXAnimationNode() const override; + virtual NodeState getState() const override; + virtual bool registerDeactivatingListener( + const AnimationNodeSharedPtr& rNotifee ) override; + // nop: + virtual void notifyDeactivating( const AnimationNodeSharedPtr& rNotifier ) override; + + bool isMainSequenceRootNode() const { return mbIsMainSequenceRootNode; } + + /// Get the node's fill mode + sal_Int16 getFillMode(); + + virtual void removeEffect() override {} +protected: + void scheduleDeactivationEvent( EventSharedPtr const& pEvent = + EventSharedPtr() ); + + SlideShowContext const& getContext() const { return maContext; } + ::std::shared_ptr<BaseNode> const& getSelf() const { return mpSelf; } + + bool checkValidNode() const { + ENSURE_OR_THROW( mpSelf, "no self ptr set!" ); + bool const bRet = (meCurrState != INVALID); + OSL_ENSURE( bRet, "### INVALID node!" ); + return bRet; + } + +private: + // all state affecting methods have "_st" counterparts being called at + // derived classes when in state transition: no-ops here at BaseNode... + virtual bool init_st(); + virtual bool resolve_st(); + virtual void activate_st(); + virtual void deactivate_st( NodeState eDestState ); + +private: + /// notifies + /// - all registered deactivation listeners + /// - single animation end (every node) + /// - slide animations (if main sequence root node) + void notifyEndListeners() const; + + /// Get the node's restart mode + sal_Int16 getRestartMode(); + + /** Get the default restart mode + + If this node's default mode is + AnimationRestart::DEFAULT, this method recursively + calls the parent node. + */ + sal_Int16 getRestartDefaultMode() const; + + /** Get the default fill mode. + + If this node's default mode is AnimationFill::DEFAULT, + this method recursively calls the parent node. + */ + sal_Int16 getFillDefaultMode() const; + + bool isTransition( NodeState eFromState, NodeState eToState, + bool debugAssert = true ) const { + bool const bRet =((mpStateTransitionTable[eFromState] & eToState) != 0); + OSL_ENSURE( !debugAssert || bRet, "### state unreachable!" ); + return bRet; + } + + bool inStateOrTransition( int mask ) const { + return ((meCurrState & mask) != 0 || + (meCurrentStateTransition & mask) != 0); + } + + class StateTransition; + friend class StateTransition; + +private: + SlideShowContext maContext; + + ::std::vector< AnimationNodeSharedPtr > maDeactivatingListeners; + css::uno::Reference< css::animations::XAnimationNode > mxAnimationNode; + ::std::shared_ptr< BaseContainerNode > mpParent; + ::std::shared_ptr< BaseNode > mpSelf; + const int* mpStateTransitionTable; + const double mnStartDelay; + NodeState meCurrState; + int meCurrentStateTransition; + EventSharedPtr mpCurrentEvent; + const bool mbIsMainSequenceRootNode; +}; + +} // namespace slideshow::internal + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/boolanimation.hxx b/slideshow/source/inc/boolanimation.hxx new file mode 100644 index 000000000..79744bc62 --- /dev/null +++ b/slideshow/source/inc/boolanimation.hxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_BOOLANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_BOOLANIMATION_HXX + +#include "animation.hxx" + + +/* Definition of BoolAnimation interface */ + +namespace slideshow::internal + { + /** Interface defining a bool animation. + + This interface is a specialization of the Animation + interface, and is used to animate attributes that have + only two discrete values (on and off, or true and false, + for example). + */ + class BoolAnimation : public Animation + { + public: + typedef bool ValueType; + + /** Set the animation to the given value + + @param bValue + Current animation value. + */ + virtual bool operator()( ValueType bValue ) = 0; + + /** Request the underlying value for this animation. + + This is necessary for pure To or By animations, as the + Activity cannot determine a sensible start value + otherwise. + + @attention Note that you are only permitted to query + for the underlying value, if the animation has actually + been started (via start() call). + */ + virtual ValueType getUnderlyingValue() const = 0; + }; + + typedef ::std::shared_ptr< BoolAnimation > BoolAnimationSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_BOOLANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/box2dtools.hxx b/slideshow/source/inc/box2dtools.hxx new file mode 100644 index 000000000..e876468df --- /dev/null +++ b/slideshow/source/inc/box2dtools.hxx @@ -0,0 +1,483 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "shape.hxx" +#include "shapeattributelayer.hxx" +#include "attributemap.hxx" +#include <unordered_map> +#include <queue> + +class b2Body; +class b2World; + +namespace slideshow::internal +{ +class ShapeManager; +typedef std::shared_ptr<ShapeManager> ShapeManagerSharedPtr; +} + +namespace box2d::utils +{ +class box2DBody; +class box2DWorld; +typedef std::shared_ptr<box2DWorld> Box2DWorldSharedPtr; +typedef std::shared_ptr<box2DBody> Box2DBodySharedPtr; + +enum box2DBodyType +{ + BOX2D_STATIC_BODY = 0, + BOX2D_KINEMATIC_BODY, + BOX2D_DYNAMIC_BODY +}; + +enum box2DNonsimulatedShapeUpdateType +{ + BOX2D_UPDATE_POSITION_CHANGE, + BOX2D_UPDATE_POSITION, + BOX2D_UPDATE_ANGLE, + BOX2D_UPDATE_SIZE, + BOX2D_UPDATE_VISIBILITY, + BOX2D_UPDATE_LINEAR_VELOCITY, + BOX2D_UPDATE_ANGULAR_VELOCITY +}; + +/// Holds required information to perform an update to box2d +/// body of a shape that was altered by an animation effect +struct Box2DDynamicUpdateInformation +{ + /// reference to the shape that the update belongs to + css::uno::Reference<css::drawing::XShape> mxShape; + union { + ::basegfx::B2DPoint maPosition; + ::basegfx::B2DVector maVelocity; + double mfAngle; + double mfAngularVelocity; + bool mbVisibility; + }; + box2DNonsimulatedShapeUpdateType meUpdateType; + /// amount of steps to delay the update for + int mnDelayForSteps = 0; +}; + +/** Class that manages the Box2D World + + This class is used when there's a physics animation going on, + it handles the stepping through the box2d world, updating the + shapes in the box2d world if they were changed by ongoing animations. + */ +class box2DWorld +{ +private: + /// Pointer to the real Box2D World that this class manages + std::unique_ptr<b2World> mpBox2DWorld; + /// Scale factor for conversions between LO user space coordinates to Box2D World coordinates + double mfScaleFactor; + bool mbShapesInitialized; + /// Holds whether or not there is a PhysicsAnimation that + /// is stepping the Box2D World. Used to create a lock mechanism + bool mbHasWorldStepper; + /// Flag used to stop overstepping that occurs when a physics + /// animation effect transfers step-lock to another one. + bool mbAlreadyStepped; + /// Number of Physics Animations going on + int mnPhysicsAnimationCounter; + std::unordered_map<css::uno::Reference<css::drawing::XShape>, Box2DBodySharedPtr> + mpXShapeToBodyMap; + + /** Queue that holds any required information to keep LO animation effects + and Box2DWorld in sync + + Is processed before every step of the box2d world by processUpdateQueue. + Holds position, rotation, visibility etc. changes and associated values. + */ + std::queue<Box2DDynamicUpdateInformation> maShapeParallelUpdateQueue; + + /// Creates a static frame in Box2D world that corresponds to the slide borders + void createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlideSize); + + /** Sets shape's corresponding Box2D body to the specified position + + Body is teleported to the specified position, not moved + + @param xShape + Shape reference + + @param rOutPos + Position in LO user space coordinates + */ + void setShapePosition(const css::uno::Reference<css::drawing::XShape> xShape, + const ::basegfx::B2DPoint& rOutPos); + + /** Moves shape's corresponding Box2D body to specified position + + Moves shape's corresponding Box2D body to specified position as if + the body had velocity to reach that point in given time frame. + + @param xShape + Shape reference + + @param rOutPos + Position in LO user space coordinates + + @param fPassedTime + Time frame which the Box2D body should move to the specified position. + */ + void setShapePositionByLinearVelocity(const css::uno::Reference<css::drawing::XShape> xShape, + const ::basegfx::B2DPoint& rOutPos, + const double fPassedTime); + + /** Sets linear velocity of the shape's corresponding Box2D body + + Moves shape's corresponding Box2D body to specified position as if + the body had velocity to reach that point in given time frame. + + @param xShape + Shape reference + + @param rVelocity + Velocity vector in LO user space coordinates. + */ + void setShapeLinearVelocity(const css::uno::Reference<com::sun::star::drawing::XShape> xShape, + const basegfx::B2DVector& rVelocity); + + /** Sets rotation angle of the shape's corresponding Box2D body + + @param xShape + Shape reference + + @param fAngle + Angle of rotation in degrees. + */ + void setShapeAngle(const css::uno::Reference<com::sun::star::drawing::XShape> xShape, + const double fAngle); + + /** Rotates shape's corresponding Box2D body to specified angle + + Rotates the Box2D body to specified angle as if the body + had exact angular velocity to reach that point in given + time frame + + @param xShape + Shape reference + + @param fAngle + Angle of rotation in degrees. + + @param fPassedTime + Time frame which the Box2D body should rotate to the specified angle. + */ + void setShapeAngleByAngularVelocity( + const css::uno::Reference<com::sun::star::drawing::XShape> xShape, const double fAngle, + const double fPassedTime); + + /** Sets angular velocity of the shape's corresponding Box2D body. + + @param xShape + Shape reference + + @param fAngularVelocity + Angular velocity in degrees per second. + */ + void setShapeAngularVelocity(const css::uno::Reference<com::sun::star::drawing::XShape> xShape, + const double fAngularVelocity); + + /** Sets whether a shape's corresponding Box2D body has collision in the Box2D World or not + + Used for animations that change the visibility of the shape. + + @param xShape + Shape reference + + @param bCanCollide + true if collisions should be enabled for the corresponding Box2D body of this shape + and false if it should be disabled. + */ + void setShapeCollision(const css::uno::Reference<com::sun::star::drawing::XShape> xShape, + const bool bCanCollide); + + /** Process the updates queued in the maShapeParallelUpdateQueue + + Called on each step of the box2DWorld. + + @param fPassedTime + Time frame to process the updates accordingly (needed for proper simulations) + */ + void processUpdateQueue(const double fPassedTime); + + /** Simulate and step through time in the Box2D World + + Used in stepAmount + + @attention fTimeStep should not vary. + */ + void step(const float fTimeStep = 1.0f / 100.0f, const int nVelocityIterations = 6, + const int nPositionIterations = 2); + + /// Queue a rotation update that is simulated as if shape's corresponding box2D body rotated to given angle when processed + void + queueDynamicRotationUpdate(const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, + const double fAngle); + + /// Queue an angular velocity update that sets the shape's corresponding box2D body angular velocity to the given value when processed + void + queueAngularVelocityUpdate(const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, + const double fAngularVelocity, const int nDelayForSteps = 0); + + /// Queue an collision update that sets the collision of shape's corresponding box2D body when processed + void queueShapeVisibilityUpdate(const css::uno::Reference<css::drawing::XShape>& xShape, + const bool bVisibility); + + void queueShapePositionUpdate(const css::uno::Reference<css::drawing::XShape>& xShape, + const ::basegfx::B2DPoint& rOutPos); + +public: + box2DWorld(const ::basegfx::B2DVector& rSlideSize); + ~box2DWorld(); + + bool initiateWorld(const ::basegfx::B2DVector& rSlideSize); + + /** Simulate and step through a given amount of time in the Box2D World + + @param fPassedTime + Amount of time to step through + + @return Amount of time actually stepped through, since it is possible + to only step through a multiple of fTimeStep + + @attention fTimeStep should not vary. + */ + double stepAmount(const double fPassedTime, const float fTimeStep = 1.0f / 100.0f, + const int nVelocityIterations = 6, const int nPositionIterations = 2); + + /// @return whether shapes in the slide are initialized as Box2D bodies or not + bool shapesInitialized(); + /// @return whether the Box2D World is initialized or not + bool isInitialized() const; + + /** Make the shape's corresponding box2D body a dynamic one. + + A dynamic body will be affected by other bodies and the gravity. + + @param xShape + Shape reference + + @param rStartVelocity + Velocity of the shape after making it dynamic + + @param fDensity + Density of the body that is in kg/m^2 + + @param fBounciness + Bounciness of the body that is usually in between [0,1]. + Even though it could take values that are >1, it is way too chaotic. + + @return box2d body pointer + */ + Box2DBodySharedPtr makeShapeDynamic(const css::uno::Reference<css::drawing::XShape>& xShape, + const basegfx::B2DVector& rStartVelocity, + const double fDensity, const double fBounciness); + + /** Make the Box2D body corresponding to the given shape a static one + + A static body will not be affected by other bodies and the gravity. But will + affect other bodies that are dynamic (will still collide with them but won't + move etc.) + + @param pShape + Pointer to the shape to alter the corresponding Box2D body of + + @return box2d body pointer + */ + Box2DBodySharedPtr makeShapeStatic(const slideshow::internal::ShapeSharedPtr& pShape); + + /** Create a static body that is represented by the shape's geometry + + @return pointer to the box2d body + */ + Box2DBodySharedPtr createStaticBody(const slideshow::internal::ShapeSharedPtr& rShape, + const float fDensity = 1.0f, const float fFriction = 0.3f); + + /// Initiate all the shapes in the current slide in the box2DWorld as static ones + void initiateAllShapesAsStaticBodies( + const slideshow::internal::ShapeManagerSharedPtr& pShapeManager); + + /// @return whether the box2DWorld has a stepper or not + bool hasWorldStepper() const; + + /// Set the flag for whether the box2DWorld has a stepper or not + void setHasWorldStepper(const bool bHasWorldStepper); + + /// Queue a position update that is simulated as if shape's corresponding box2D body moved to given position when processed + void queueDynamicPositionUpdate(const css::uno::Reference<css::drawing::XShape>& xShape, + const ::basegfx::B2DPoint& rOutPos); + + /// Queue a update that sets the corresponding box2D body's linear velocity to the given value when processed + void queueLinearVelocityUpdate(const css::uno::Reference<css::drawing::XShape>& xShape, + const ::basegfx::B2DVector& rVelocity, + const int nDelayForSteps = 0); + + /// Queue an appropriate update for the animation effect that is in parallel with a physics animation + void + queueShapeAnimationUpdate(const css::uno::Reference<css::drawing::XShape>& xShape, + const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer, + const slideshow::internal::AttributeType eAttrType, + const bool bIsFirstUpdate); + + /// Queue an appropriate update for a path animation that is in parallel with a physics animation + void queueShapePathAnimationUpdate( + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, + const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer, + const bool bIsFirstUpdate); + + /// Queue an appropriate update for the animation effect that just ended + void queueShapeAnimationEndUpdate(const css::uno::Reference<css::drawing::XShape>& xShape, + const slideshow::internal::AttributeType eAttrType); + + /** Alert that a physics animation effect has ended + + Makes the given shape static, if this was the last physics animation effect + that was in parallel, box2d bodies that are owned by the mpXShapeToBodyMap + are dumped and potentially destroyed. + + @attention the box2d body owned by the PhysicsAnimation won't be destroyed. + */ + void alertPhysicsAnimationEnd(const slideshow::internal::ShapeSharedPtr& pShape); + + /** Alert that a physics animation effect has started + + Initiates the box2D world if it is not initiated yet, and likewise constructs + box2d bodies for the shapes in the current slide if they are not constructed. + */ + void + alertPhysicsAnimationStart(const ::basegfx::B2DVector& rSlideSize, + const slideshow::internal::ShapeManagerSharedPtr& pShapeManager); +}; + +/// Class that manages a single box2D Body +class box2DBody +{ +private: + /// Pointer to the body that this class manages + std::shared_ptr<b2Body> mpBox2DBody; + /// Scale factor for conversions between LO user space coordinates to Box2D World coordinates + double mfScaleFactor; + +public: + box2DBody(std::shared_ptr<b2Body> pBox2DBody, double fScaleFactor); + + /// @return current position in LO user space coordinates + ::basegfx::B2DPoint getPosition() const; + + /** Set the position of box2d body + + @param rPos + Position in LO user space coordinates + */ + void setPosition(const ::basegfx::B2DPoint& rPos); + + /** Moves body to the specified position + + Moves body to the specified position by setting velocity of + the body so that it reaches to rDesiredPos in given time fram + + @param rDesiredPos + Position to arrive in the time frame + + @param fPassedTime + Amount of time for the movement to take place + */ + void setPositionByLinearVelocity(const ::basegfx::B2DPoint& rDesiredPos, + const double fPassedTime); + + /** Sets linear velocity of the body + + @param rVelocity + Velocity vector in LO user space coordinates + */ + void setLinearVelocity(const ::basegfx::B2DVector& rVelocity); + + /** Rotate body to specified angle of rotation + + Rotates body to specified rotation as if the body had + angular velocity to reach that state in given time frame + + @param fDesiredAngle + Rotation angle in degrees to arrive in the time frame + + @param fPassedTime + Amount of time for the movement to take place + */ + void setAngleByAngularVelocity(const double fDesiredAngle, const double fPassedTime); + + /** Sets angular velocity of the body + + @param fAngularVelocity + Angular velocity in degrees per second + */ + void setAngularVelocity(const double fAngularVelocity); + + /// Sets whether the body have collisions or not + void setCollision(const bool bCanCollide); + + /// @return current angle of rotation of the body + double getAngle() const; + + /** Set angle of the box2d body + + @param fAngle + Angle in degrees + */ + void setAngle(const double fAngle); + + /** Set density and restitution of the box2d body + + @param fDensity + Density in kg/m^2 + + @param fRestitution + Restitution (elasticity) coefficient, usually in the range [0,1] + */ + void setDensityAndRestitution(const double fDensity, const double fRestitution); + + /** Set restitution of the box2d body + + @param fRestitution + Restitution (elasticity) coefficient, usually in the range [0,1] + */ + void setRestitution(const double fRestitution); + + /// Set type of the body + void setType(box2DBodyType eType); + + /// @return type of the body + box2DBodyType getType() const; +}; + +/** Make the Box2D body a dynamic one + + A dynamic body will be affected by other bodies and the gravity. + + @param pBox2DBody + Pointer to the Box2D body + */ +Box2DBodySharedPtr makeBodyDynamic(const Box2DBodySharedPtr& pBox2DBody); + +/** Make the Box2D body a static one + + A static body will not be affected by other bodies and the gravity. + + @param pBox2DBody + Pointer to the Box2D body + */ +Box2DBodySharedPtr makeBodyStatic(const Box2DBodySharedPtr& pBox2DBody); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/slideshow/source/inc/coloranimation.hxx b/slideshow/source/inc/coloranimation.hxx new file mode 100644 index 000000000..21105166b --- /dev/null +++ b/slideshow/source/inc/coloranimation.hxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_COLORANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_COLORANIMATION_HXX + +#include "animation.hxx" +#include "rgbcolor.hxx" + + +/* Definition of ColorAnimation interface */ + +namespace slideshow::internal + { + /** Interface defining a color animation. + + This interface is a specialization of the Animation + interface, and is used to animate attributes representable + by a color value. + */ + class ColorAnimation : public Animation + { + public: + typedef RGBColor ValueType; + + /** Set the animation to the given color value + + @param rColor + Current animation value. + */ + virtual bool operator()( const ValueType& rColor ) = 0; + + /** Request the underlying value for this animation. + + This is necessary for pure To or By animations, as the + Activity cannot determine a sensible start value + otherwise. + + @attention Note that you are only permitted to query + for the underlying value, if the animation has actually + been started (via start() call). + */ + virtual ValueType getUnderlyingValue() const = 0; + }; + + typedef ::std::shared_ptr< ColorAnimation > ColorAnimationSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_COLORANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/cursormanager.hxx b/slideshow/source/inc/cursormanager.hxx new file mode 100644 index 000000000..cfd5f0a74 --- /dev/null +++ b/slideshow/source/inc/cursormanager.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_CURSORMANAGER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_CURSORMANAGER_HXX + +#include <sal/types.h> + + +/* Definition of CursorManager interface */ + +namespace slideshow::internal + { + + /** Interface for handling the view cursor. + + Classes implementing this interface interact with the + View, arbitrating access to the mouse cursor shape. + */ + class CursorManager + { + public: + virtual ~CursorManager() {} + + /** Request different cursor shape. + + @param nCursorShape + Shape ID of the new mouse cursor + */ + virtual bool requestCursor( sal_Int16 nCursorShape ) = 0; + + /** Reset cursor to default one. + + This method resets the cursor to whatever default to + manager deems appropriate. + */ + virtual void resetCursor() = 0; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_CURSORMANAGER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/delayevent.hxx b/slideshow/source/inc/delayevent.hxx new file mode 100644 index 000000000..631553915 --- /dev/null +++ b/slideshow/source/inc/delayevent.hxx @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_DELAYEVENT_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_DELAYEVENT_HXX + +#include "event.hxx" + +#include <functional> + +namespace slideshow::internal { + +/** Event, which delays the functor call the given amount of time + */ +class Delay : public Event +{ +public: + typedef ::std::function<void ()> FunctorT; + + template <typename FuncT> + Delay( FuncT const& func, + double nTimeout + , const OUString& rsDescription + ) : Event(rsDescription), + mnTimeout(nTimeout), maFunc(func), mbWasFired(false) {} + + Delay( const std::function<void ()>& func, + double nTimeout + , const OUString& rsDescription + ) : Event(rsDescription), + mnTimeout(nTimeout), + maFunc(func), + mbWasFired(false) {} + Delay(const Delay&) = delete; + Delay& operator=(const Delay&) = delete; + + // Event: + virtual bool fire() override; + virtual bool isCharged() const override; + virtual double getActivationTime( double nCurrentTime ) const override; + // Disposable: + virtual void dispose() override; + +private: + double const mnTimeout; + FunctorT maFunc; + bool mbWasFired; +}; + +#if OSL_DEBUG_LEVEL <= 1 + +/** Generate delay event + + @param func + Functor to call when the event fires. + + @param nTimeout + Timeout in seconds, to wait until functor is called. + + @return generated delay event +*/ +template <typename FuncT> +inline EventSharedPtr makeDelay_( FuncT const& func, double nTimeout, OUString const& rsDescription ) +{ + return std::make_shared<Delay>( func, nTimeout, rsDescription ); +} + +/** Generate immediate event + + @param func + Functor to call when the event fires. + + @return generated immediate event. +*/ +template <typename FuncT> +inline EventSharedPtr makeEvent_( FuncT const& func, OUString const& rsDescription) +{ + return std::make_shared<Delay>( func, 0.0, rsDescription ); +} + + +#define makeDelay(f, t, d) makeDelay_(f, t, d) +#define makeEvent(f, d) makeEvent_(f, d) + +#else // OSL_DEBUG_LEVEL > 0 + +class Delay_ : public Delay { +public: + template <typename FuncT> + Delay_( FuncT const& func, double nTimeout, + char const* from_function, char const* from_file, int from_line, + const OUString& rsDescription) + : Delay(func, nTimeout, rsDescription), + FROM_FUNCTION(from_function), + FROM_FILE(from_file), FROM_LINE(from_line) {} + + char const* const FROM_FUNCTION; + char const* const FROM_FILE; + int const FROM_LINE; +}; + +template <typename FuncT> +inline EventSharedPtr makeDelay_( + FuncT const& func, double nTimeout, + char const* from_function, char const* from_file, int from_line, + const OUString& rsDescription) +{ + return EventSharedPtr( new Delay_( func, nTimeout, + from_function, from_file, from_line, rsDescription) ); +} + +#define makeDelay(f, t, d) makeDelay_(f, t, \ + __func__, __FILE__, __LINE__, \ + d) +#define makeEvent(f, d) makeDelay_(f, 0.0, \ + __func__, __FILE__, __LINE__, \ + d) + +#endif // OSL_DEBUG_LEVEL <= 1 + +} // namespace presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_DELAYEVENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/disposable.hxx b/slideshow/source/inc/disposable.hxx new file mode 100644 index 000000000..a345d76e0 --- /dev/null +++ b/slideshow/source/inc/disposable.hxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_DISPOSABLE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_DISPOSABLE_HXX + +#include <memory> + + +/* Definition of Disposable interface */ + +namespace slideshow::internal + { + /** + * Base class for being a shared pointer, since quite a few of the downstream classes + * want to be stored using std::shared_ptr. + */ + class SharedPtrAble : public std::enable_shared_from_this<SharedPtrAble> + { + public: + virtual ~SharedPtrAble() {} + }; + + /** Disposable interface + + With ref-counted objects, deleting object networks + containing cycles requires a dispose() call, to enforce + every object to call dispose on and release local + references. + */ + class Disposable + { + public: + virtual ~Disposable() {} + + /** Dispose all object references. + + An implementor of this method must first call + dispose() on any of its external references, and + release them after that. + */ + virtual void dispose() = 0; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_DISPOSABLE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/doctreenode.hxx b/slideshow/source/inc/doctreenode.hxx new file mode 100644 index 000000000..45bbf77b0 --- /dev/null +++ b/slideshow/source/inc/doctreenode.hxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_DOCTREENODE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_DOCTREENODE_HXX + +#include <sal/types.h> +#include <vector> + + +/* Definition of DocTreeNode class */ + +namespace slideshow::internal + { + + /** This class represents kind of a DOM tree node for shape + text + + In order to animate subsets of shape text, we need + information about the logical and formatting structure of + that text (lines, paragraphs, words etc.). This is + represented in a tree structure, with DocTreeNodes as the + nodes. Instances of this class can be queried from the + DocTreeNodeSupplier interface. + + This class has nothing to do with the Draw document tree. + */ + class DocTreeNode + { + public: + /// Type of shape entity represented by this node + enum class NodeType + { + /// This node represents a paragraph + LogicalParagraph=129, + /// This node represents a word + LogicalWord=131, + /// This node represents a character + LogicalCharacterCell=132 + }; + + /** Create empty tree node + */ + DocTreeNode() : + mnStartIndex(-1), + mnEndIndex(-1) + { + } + + /** Create tree node from start and end index. + + Create a tree node for the given range and type. + + @param nStartIndex + Start index + + @param nEndIndex + End index (exclusive) + + @param eType + Node type + */ + DocTreeNode( sal_Int32 nStartIndex, + sal_Int32 nEndIndex ) : + mnStartIndex(nStartIndex), + mnEndIndex(nEndIndex) + { + } + + bool isEmpty() const { return mnStartIndex == mnEndIndex; } + + sal_Int32 getStartIndex() const { return mnStartIndex; } + void setStartIndex( sal_Int32 nIndex ) { mnStartIndex = nIndex; } + sal_Int32 getEndIndex() const { return mnEndIndex; } + void setEndIndex( sal_Int32 nIndex ) { mnEndIndex = nIndex; } + + void reset() + { + mnStartIndex = -1; + mnEndIndex = -1; + } + + private: + sal_Int32 mnStartIndex; + sal_Int32 mnEndIndex; + + }; + + typedef ::std::vector< DocTreeNode > VectorOfDocTreeNodes; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_DOCTREENODE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/doctreenodesupplier.hxx b/slideshow/source/inc/doctreenodesupplier.hxx new file mode 100644 index 000000000..5bf91d126 --- /dev/null +++ b/slideshow/source/inc/doctreenodesupplier.hxx @@ -0,0 +1,145 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_DOCTREENODESUPPLIER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_DOCTREENODESUPPLIER_HXX + +#include "doctreenode.hxx" + + +/* Definition of DocTreeNodeSupplier interface */ + +namespace slideshow::internal + { + /** Interface to retrieve DocTreeNodes from subsettable + shapes. + + Shapes which implement the AttributableShape interface + also provides this interface, providing methods to + retrieve specific DocTreeNode objects from the shape. The + methods mainly distinguish various ways on how to specify + the actual DocTreeNode to return. + + If a requested DocTreeNode is not available when one of + the methods below is called, an empty DocTreeNode will be + returned (the predicate DocTreeNode::isEmpty() will return + true). If, on the other hand, the shape cannot determine, + for internal reasons, the internal tree node structure, + all those methods will throw an + ShapeLoadFailedException. This is, in fact, a delayed error + that could also have been reported during shape + construction, but might be postponed until the missing + information is actually requested. + */ + class DocTreeNodeSupplier + { + public: + /** Query number of tree nodes of the given type this + shape contains. + + The value returned by this method minus one is the + maximum value permissible at the getTreeNode() + method, for the given node type. + + @throws ShapeLoadFailedException, if tree node structure + cannot be determined. + */ + virtual sal_Int32 getNumberOfTreeNodes( DocTreeNode::NodeType eNodeType ) const = 0; // throw ShapeLoadFailedException; + + /** Create DocTreeNode from shape. + + This method creates a DocTreeNode from a shape, a + given node type and a running index into the shape's + DocTreeNodes of the given type. + + @param nNodeIndex + Starting with 0, every DocTreeNode of the shape that + has type eNodeType is indexed. The DocTreeNode whose + index equals nNodeIndex will be returned. + + @param eNodeType + Type of the node to return + + @return the DocTreeNode found, or the empty + DocTreeNode, if nothing was found. + + @throws ShapeLoadFailedException, if tree node structure + cannot be determined. + */ + virtual DocTreeNode getTreeNode( sal_Int32 nNodeIndex, + DocTreeNode::NodeType eNodeType ) const = 0; // throw ShapeLoadFailedException; + + /** Query number of tree nodes of the given type this + subset contains. + + The value returned by this method minus one is the + maximum value permissible at the + getSubsetTreeNode() method, for the given node + type. + + @param rParentNode + The parent node, below which the number of tree nodes + of the given type shall be counted. + + @param eNodeType + Node type to count. + + @throws ShapeLoadFailedException, if tree node structure + cannot be determined. + */ + virtual sal_Int32 getNumberOfSubsetTreeNodes( const DocTreeNode& rParentNode, + DocTreeNode::NodeType eNodeType ) const = 0; // throw ShapeLoadFailedException; + + /** Create DocTreeNode from shape subset. + + This method creates a DocTreeNode from a shape, a + parent tree node, a given node type and a running + index into the shape's DocTreeNodes of the given type. + + @param rParentNode + Parent node, below which the tree node with the given + type shall be selected. + + @param nNodeIndex + Starting with 0, every DocTreeNode of the shape that + has type eNodeType is indexed. The DocTreeNode whose + index equals nNodeIndex will be returned. + + @param eNodeType + Type of the node to return + + @return the DocTreeNode found, or the empty + DocTreeNode, if nothing was found. + + @throws ShapeLoadFailedException, if tree node structure + cannot be determined. + */ + virtual DocTreeNode getSubsetTreeNode( const DocTreeNode& rParentNode, + sal_Int32 nNodeIndex, + DocTreeNode::NodeType eNodeType ) const = 0; // throw ShapeLoadFailedException; + + protected: + ~DocTreeNodeSupplier() {} + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_DOCTREENODESUPPLIER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/enumanimation.hxx b/slideshow/source/inc/enumanimation.hxx new file mode 100644 index 000000000..39a8a0251 --- /dev/null +++ b/slideshow/source/inc/enumanimation.hxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_ENUMANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_ENUMANIMATION_HXX + +#include "animation.hxx" + + +/* Definition of EnumAnimation interface */ + +namespace slideshow::internal + { + /** Interface defining an enum animation. + + This interface is a specialization of the Animation + interface, and is used to animate attributes representable + by a set of constant values, such as UNO constants, or enums. + */ + class EnumAnimation : public Animation + { + public: + typedef sal_Int16 ValueType; + + /** Set the animation to value k + + @param k + Current animation value (must be in an + attribute-specific permissible range). Overflowing + values will be clipped to the permissible range + internally. + */ + virtual bool operator()( ValueType k ) = 0; + + /** Request the underlying value for this animation. + + This is necessary for pure To or By animations, as the + Activity cannot determine a sensible start value + otherwise. + + @attention Note that you are only permitted to query + for the underlying value, if the animation has actually + been started (via start() call). + */ + virtual ValueType getUnderlyingValue() const = 0; + }; + + typedef ::std::shared_ptr< EnumAnimation > EnumAnimationSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_ENUMANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/event.hxx b/slideshow/source/inc/event.hxx new file mode 100644 index 000000000..9377bc9d7 --- /dev/null +++ b/slideshow/source/inc/event.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_EVENT_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_EVENT_HXX + +#include "disposable.hxx" +#include <rtl/ustring.hxx> +#include <memory> +#include <vector> + +namespace slideshow::internal +{ +/** Definition of Event interface + */ +class Event : public Disposable +{ +public: + Event(const OUString& rsDescription) + : msDescription(rsDescription) + { + } + + /** Execute the event. + + @return true, if event was successfully executed. + */ + virtual bool fire() = 0; + + /** Query whether this event is still charged, i.e. able + to fire. + + Inactive events are ignored by the normal event + containers (EventQueue, UserEventQueue etc.), and no + explicit fire() is called upon them. + + @return true, if this event has already been fired. + */ + virtual bool isCharged() const = 0; + + /** Query the activation time instant this event shall be + fired, if it was inserted at instant nCurrentTime into + the queue. + + @param nCurrentTime + The time from which the activation time is to be + calculated from. + + @return the time instant in seconds, on which this + event is to be fired. + */ + virtual double getActivationTime(double nCurrentTime) const = 0; + + const OUString& GetDescription() const { return msDescription; } + +private: + const OUString msDescription; +}; + +typedef ::std::shared_ptr<Event> EventSharedPtr; +typedef ::std::vector<EventSharedPtr> VectorOfEvents; + +} // namespace presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_EVENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/eventhandler.hxx b/slideshow/source/inc/eventhandler.hxx new file mode 100644 index 000000000..d74b13ecd --- /dev/null +++ b/slideshow/source/inc/eventhandler.hxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_EVENTHANDLER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_EVENTHANDLER_HXX + +#include <memory> + + +/* Definition of EventHandler interface */ + +namespace slideshow::internal + { + + /** Interface for event handling objects. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle events. + */ + class EventHandler + { + public: + virtual ~EventHandler() {} + + /** Handle the event. + + @return true, if this handler has successfully + processed the event. When this method returns false, + possibly other, less prioritized handlers are called, + too. + */ + virtual bool handleEvent() = 0; + }; + + typedef ::std::shared_ptr< EventHandler > EventHandlerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_EVENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/eventmultiplexer.hxx b/slideshow/source/inc/eventmultiplexer.hxx new file mode 100644 index 000000000..e0dd6fd31 --- /dev/null +++ b/slideshow/source/inc/eventmultiplexer.hxx @@ -0,0 +1,659 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_EVENTMULTIPLEXER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_EVENTMULTIPLEXER_HXX + +#include "eventhandler.hxx" +#include "mouseeventhandler.hxx" +#include "animationeventhandler.hxx" +#include "pauseeventhandler.hxx" +#include "shapelistenereventhandler.hxx" +#include "vieweventhandler.hxx" + +#include <memory> +#include <com/sun/star/uno/Reference.hxx> + +#include "unoview.hxx" + +namespace com::sun::star::drawing { class XShape; } + +namespace slideshow::internal { + +class EventQueue; +class UnoViewContainer; +class AnimationNode; + +struct EventMultiplexerImpl; + +class RGBColor; + +/** Interface for handling view repaint events. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle view repaint events. +*/ +class ViewRepaintHandler +{ +public: + virtual ~ViewRepaintHandler() {} + + /** Notify clobbered view. + + Reasons for a viewChanged notification can be + different view size, transformation, or other device + properties (color resolution or profile, etc.) + + @param rView + The changed view + */ + virtual void viewClobbered( const UnoViewSharedPtr& rView ) = 0; +}; + +typedef ::std::shared_ptr< ViewRepaintHandler > ViewRepaintHandlerSharedPtr; + +/** Interface for handling hyperlink clicks. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle hyperlink events. + */ +class HyperlinkHandler +{ +public: + /** Handle the event. + + @param rLink + The actual hyperlink URI + + @return true, if this handler has successfully + processed the event. When this method returns false, + possibly other, less prioritized handlers are called, + too. + */ + virtual bool handleHyperlink( OUString const& rLink ) = 0; + +protected: + ~HyperlinkHandler() {} +}; + +typedef ::std::shared_ptr< HyperlinkHandler > HyperlinkHandlerSharedPtr; + +/** Interface for handling user paint state changes. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle user paint events. +*/ +class UserPaintEventHandler +{ +public: + virtual ~UserPaintEventHandler() {} + virtual bool colorChanged( RGBColor const& rUserColor ) = 0; + virtual bool widthChanged( double nUserStrokeWidth ) = 0; + virtual bool eraseAllInkChanged(bool bEraseAllInk) =0; + virtual bool eraseInkWidthChanged(sal_Int32 rEraseInkSize) =0; + virtual bool switchEraserMode() = 0; + virtual bool switchPenMode() = 0; + virtual bool disable() = 0; +}; + +typedef ::std::shared_ptr< UserPaintEventHandler > UserPaintEventHandlerSharedPtr; + +/** This class multiplexes user-activated and + slide-show global events. + + This class listens at the XSlideShowView and fires events + registered for certain user actions. Furthermore, global + slide show state changes (such as start or end of a slide) + are handled as well. Note that registered events which + have a non-zero timeout (i.e. events that return non-zero + from getActivationTime()) will not be fired immediately + after the user action occurred, but only after the given + timeout. Which is actually a feature. +*/ +class EventMultiplexer +{ +public: + /** Create an event multiplexer + + @param rEventQueue + Reference to the main event queue. Since we hold this + object by plain reference, it must live longer than we + do. On the other hand, that queue must not fire events + after this object is destroyed, since we might + schedule events there which itself contain plain + references to this object. Basically, EventQueue and + EventMultiplexer should have the same lifetime, and since + this is not possible, both must be destructed in a + phased mode: first clear both of any remaining events, + then destruct them. + + @param rViewContainer + Globally managed list of all registered views. Used to + determine event sources, and for registering view listeners + at. + */ + EventMultiplexer( EventQueue& rEventQueue, + UnoViewContainer const& rViewContainer ); + ~EventMultiplexer(); + EventMultiplexer(const EventMultiplexer&) = delete; + EventMultiplexer& operator=(const EventMultiplexer&) = delete; + + // Management methods + + + /** Clear all registered handlers. + */ + void clear(); + + + // Automatic mode methods + + + /** Change automatic mode. + + @param bIsAuto + When true, events will be fired automatically, not + only triggered by UI events. When false, auto events + will quit. + */ + void setAutomaticMode( bool bIsAuto ); + + /** Get automatic mode setting. + */ + bool getAutomaticMode() const; + + /** Set the timeout for automatic mode. + + @param nTimeout + Timeout, between end of effect until start of next + effect. + */ + void setAutomaticTimeout( double nTimeout ); + + /** Get automatic mode timeout value. + */ + double getAutomaticTimeout() const; + + // Handler registration methods + + + /** Register an event handler that will be called when views are + changed. + + For each view added, viewAdded() will be called on the + handler. For each view removed, viewRemoved() will be + called. Each modified view will cause a viewChanged() call on + each handler. + + You don't need to deregister the handler, it will be + automatically removed, once the pointee becomes stale. + + @param rHandler + Handler to call. + */ + void addViewHandler( const ViewEventHandlerWeakPtr& rHandler ); + void removeViewHandler( const ViewEventHandlerWeakPtr& rHandler ); + + /** Register an event handler that will be called when a view gets + clobbered. + + Note that <em>all</em> registered handlers will be called when + the event. This is in contrast to the mouse events below. + + @param rHandler + Handler to call when a view needs a repaint + */ + void addViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler ); + void removeViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when + XShapeListeners are changed. + + @param rHandler + Handler to call when a shape listener changes + */ + void addShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler ); + void removeShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when + user paint parameters change. + + @param rHandler + Handler to call when a shape listener changes + */ + void addUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when the + user requests the next effect. + + For every nextEffect event, only one of the handlers + registered here is called. The handlers are considered + with decreasing priority, i.e. the handler with the + currently highest priority will be called. + + @param rHandler + Handler to call when the next effect should start + + @param nPriority + Priority with which the handlers are called. The + higher the priority, the earlier this handler will be + tried. + */ + void addNextEffectHandler( const EventHandlerSharedPtr& rHandler, + double nPriority ); + void removeNextEffectHandler( const EventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when the + slide is just shown. + + Note that <em>all</em> registered handlers will be called + when the slide start occurs. This is in contrast to + the mouse events below. + + @param rHandler + Handler to call when the next slide starts + */ + void addSlideStartHandler( const EventHandlerSharedPtr& rHandler ); + void removeSlideStartHandler( const EventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when the + slide is about to vanish. + + Note that <em>all</em> registered handlers will be + called when the slide end occurs. This is in contrast + to the mouse events below. + + @param rHandler + Handler to call when the current slide ends + */ + void addSlideEndHandler( const EventHandlerSharedPtr& rHandler ); + void removeSlideEndHandler( const EventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when an + XAnimationNode starts its active duration. + + Note that <em>all</em> registered handlers will be called + when the animation start occurs. This is in contrast to + the mouse events below. + + @param rHandler + Handler to call when the animation start + */ + void addAnimationStartHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + void removeAnimationStartHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when an + XAnimationNode ends its active duration. + + Note that <em>all</em> registered handlers will be called + when the animation end occurs. This is in contrast to + the mouse events below. + + @param rHandler + Handler to call when the animation ends + */ + void addAnimationEndHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + void removeAnimationEndHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when the + main animation sequence of a slide ends its active + duration. + + Note that <em>all</em> registered handlers will be + called when the animation end occurs. This is in + contrast to the mouse events below. + + @param rHandler + Handler to call when the animation ends + */ + void addSlideAnimationsEndHandler( + const EventHandlerSharedPtr& rHandler ); + void removeSlideAnimationsEndHandler( + const EventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when an + XAudio node's sound stops playing. + + Note that <em>all</em> registered handlers will be + called when the audio stops. This is in contrast to + the mouse events below. + + @param rHandler + Handler to call when the audio stops + */ + void addAudioStoppedHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + void removeAudioStoppedHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + + /** Register an event handler that will be called when an + XCommand node's with the command STOPAUDIO is activated. + + Note that <em>all</em> registered handlers will be + called when the audio stops. This is in contrast to + the mouse events below. + + @param rHandler + Handler to call when command is activated + */ + void addCommandStopAudioHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + void removeCommandStopAudioHandler( + const AnimationEventHandlerSharedPtr& rHandler ); + + /** Register a handler that is called when the show enters + or exits pause mode. + */ + void addPauseHandler( const PauseEventHandlerSharedPtr& rHandler ); + void removePauseHandler( const PauseEventHandlerSharedPtr& rHandler ); + + /** Register a mouse handler that is called on mouse click + + For every mouse click, only one of the handlers + registered here is called. The handlers are considered + with decreasing priority, i.e. the handler with the + currently highest priority will be called. + + Since the handlers can reject down and up events + individually, handlers should expect to be called with + non-matching down and up-press counts. If your handler + cannot cope with that, it must have the highest + priority of all added handlers. + */ + void addClickHandler( const MouseEventHandlerSharedPtr& rHandler, + double nPriority ); + void removeClickHandler( const MouseEventHandlerSharedPtr& rHandler ); + + /** Register a mouse handler that is called on a double + mouse click + + For every mouse double click, only one of the handlers + registered here is called. The handlers are considered + with decreasing priority, i.e. the handler with the + currently highest priority will be called. + + Since the handlers can reject down and up events + individually, handlers should expect to be called with + non-matching down and up-press counts. If your handler + cannot cope with that, it must have the highest + priority of all added handlers. + */ + void addDoubleClickHandler( const MouseEventHandlerSharedPtr& rHandler, + double nPriority ); + void removeDoubleClickHandler( const MouseEventHandlerSharedPtr& rHandler ); + + /** Register a mouse handler that is called for mouse moves. + + For every mouse move, only one of the handlers + registered here is called. The handlers are considered + with decreasing priority, i.e. the handler with the + currently highest priority will be called. + */ + void addMouseMoveHandler( const MouseEventHandlerSharedPtr& rHandler, + double nPriority ); + void removeMouseMoveHandler( const MouseEventHandlerSharedPtr& rHandler ); + + + /** Registers a hyperlink click handler. + + For every hyperlink click, only one of the handlers registered + here is called. The handlers are considered with decreasing + priority, i.e. the handler with the currently highest priority + will be called. + + @param rHandler + @param nPriority + */ + void addHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler, + double nPriority ); + void removeHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler ); + + + // External event notifications + + + /** View added. + + This method adds another view, which the show is + displayed on. On every added view, the EventMultiplexer + registers mouse and motion event listeners. + */ + void notifyViewAdded( const UnoViewSharedPtr& rView ); + + /** View removed + + This method removes a view. Registered mouse and + motion event listeners are revoked. + */ + void notifyViewRemoved( const UnoViewSharedPtr& rView ); + + /** View changed + + This method announces a changed view to all view + listeners. View changes include size and transformation. + + @param rView + View that has changed + */ + void notifyViewChanged( const UnoViewSharedPtr& rView ); + + /** View changed + + This method announces a changed view to all view + listeners. View changes include size and transformation. + + @param xView + View that has changed + */ + void notifyViewChanged( const css::uno::Reference<css::presentation::XSlideShowView>& xView ); + + /** All Views changed + + This method announces to all view listeners that + <em>every</em> known view has changed. View changes include + size and transformation. + */ + void notifyViewsChanged(); + + /** View clobbered + + This method announces that the given view has been clobbered + by something external to the slideshow, and needs an update. + + @param xView + View that has been clobbered + */ + void notifyViewClobbered( const css::uno::Reference<css::presentation::XSlideShowView>& xView ); + + /** New shape event listener added + + This method announces that the given listener was added for + the specified shape. + */ + void notifyShapeListenerAdded( const css::uno::Reference<css::drawing::XShape>& xShape ); + + /** A shape event listener was removed + + This method announces that the given listener was removed for + the specified shape. + */ + void notifyShapeListenerRemoved( const css::uno::Reference<css::drawing::XShape>& xShape ); + + /** Notify a new user paint color + + Sending this notification also implies that user paint is + enabled. User paint denotes the feature to draw colored lines + on top of the slide content. + */ + void notifyUserPaintColor( RGBColor const& rUserColor ); + + /** Notify a new user paint width + + Sending this notification also implies that user paint is + enabled. . + */ + void notifyUserPaintStrokeWidth( double rUserStrokeWidth ); + + + /** Notify a new user paint erase all ink mode + + Sending this notification also implies that user paint is + enabled. User paint denotes the feature to draw colored lines + on top of the slide content. + */ + void notifyEraseAllInk( bool bEraseAllInk ); + void notifySwitchPenMode(); + void notifySwitchEraserMode(); + void notifyEraseInkWidth( sal_Int32 rEraseInkSize ); + + /** Notify that user paint is disabled + + User paint denotes the feature to draw colored lines on top of + the slide content. + */ + void notifyUserPaintDisabled(); + + /** Notify that the user requested the next effect. + + This requests the slideshow to display the next + effect, or move to the next slide, if none are left. + + @return true, if this event was processed by + anybody. If false is returned, no handler processed + this event (and probably, nothing will happen at all) + */ + bool notifyNextEffect(); + + /** Notify that a new slide has started + + This method is to be used from the Presentation object + to signal that a new slide is starting now. This will + invoke all registered slide start handlers. + */ + void notifySlideStartEvent(); + + /** Notify that a slide has ended + + This method is to be used from the Presentation object + to signal that a slide is ending now. This will invoke + all registered slide end handlers. + + @return true, if this event was processed by + anybody. If false is returned, no handler processed + this event (and probably, nothing will happen at all) + */ + bool notifySlideEndEvent(); + + /** Notify that the given node enters its active duration. + + This method is to be used from the AnimationNode + objects to signal that the active duration + begins. This will invoke all registered animation + start handlers. + + @param rNode + Node which enters active duration. + + @return true, if this event was processed by + anybody. If false is returned, no handler processed + this event (and probably, nothing will happen at all) + */ + bool notifyAnimationStart( const AnimationNodeSharedPtr& rNode ); + + /** Notify that the given node leaves its active duration. + + This method is to be used from the AnimationNode + objects to signal that the active duration + ends now. This will invoke all registered animation + end handlers. + + @param rNode + Node which leaves active duration. + + @return true, if this event was processed by + anybody. If false is returned, no handler processed + this event (and probably, nothing will happen at all) + */ + bool notifyAnimationEnd( const AnimationNodeSharedPtr& rNode ); + + /** Notify that the slide animations sequence leaves its + active duration. + + @return true, if this event was processed by + anybody. If false is returned, no handler processed + this event (and probably, nothing will happen at all) + */ + bool notifySlideAnimationsEnd(); + + /** Notify that for the given node, audio output has stopped. + + This method is to be used from the AnimationNode + objects to signal that audio playback has just + stopped. This will invoke all registered audio + stopped handlers. + + @param rNode + Node for which audio has stopped. + + @return true, if this event was processed by + anybody. If false is returned, no handler processed + this event (and probably, nothing will happen at all) + */ + bool notifyAudioStopped( const AnimationNodeSharedPtr& rNode ); + + /** Notify that the show has entered or exited pause mode + + This method is to be used from the Presentation object + to signal that a slide is entering (bPauseShow=true) + or exiting (bPauseShow=false) pause mode. This will + invoke all registered slide end handlers. + */ + void notifyPauseMode( bool bPauseShow ); + + /** Notify that all audio has to be stopped. + + This method is used by XCommand nodes and all sound + playing nodes should listen for this command and + stop their sounds when it's fired. + + @return true, if this event was processed by + anybody. If false is returned, no handler processed + this event (and probably, nothing will happen at all) + */ + bool notifyCommandStopAudio( const AnimationNodeSharedPtr& rNode ); + + /** Notifies that a hyperlink has been clicked. + */ + void notifyHyperlinkClicked( OUString const& hyperLink ); + +private: + std::unique_ptr<EventMultiplexerImpl> mpImpl; +}; + +} // namespace Presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_EVENTMULTIPLEXER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/eventqueue.hxx b/slideshow/source/inc/eventqueue.hxx new file mode 100644 index 000000000..fb0f1b853 --- /dev/null +++ b/slideshow/source/inc/eventqueue.hxx @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_EVENTQUEUE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_EVENTQUEUE_HXX + +#include <canvas/elapsedtime.hxx> + +#include "event.hxx" + +#include <mutex> +#include <queue> +#include <vector> + + +/* Definition of ActivitiesQueue class */ + +namespace slideshow::internal + { + /** This class handles events in a presentation. Events are + time instants where e.g. effects start. + */ + class EventQueue + { + public: + EventQueue( + std::shared_ptr< ::canvas::tools::ElapsedTime > + const & pPresTimer ); + + ~EventQueue(); + + EventQueue(const EventQueue&) = delete; + EventQueue& operator=(const EventQueue&) = delete; + + /** Add the given event to the queue. The event is fired + at, or shortly after, its Event::getActivationTime instant. + */ + bool addEvent( const EventSharedPtr& event ); + + /** Add the given event to the queue. The event is fired + at, or shortly after, its Event::getActivationTime instant. + The difference to addEvent() is that events added during + process() are postponed to next process(). + */ + bool addEventForNextRound( const EventSharedPtr& event ); + + /** Another way to control the order of asynchronous event + execution. Use this method to schedule events that are to + be executed after all regular events that have no delay, + even when they schedule new regular events without delay. + */ + bool addEventWhenQueueIsEmpty (const EventSharedPtr& rpEvent); + + /** Process the event queue. + + This method executes all events whose timeout has + expired when calling this method (i.e. all events + whose scheduled time is less or equal the current + time). + + Check for the next available event's timeout via + nextTimeout(), or whether the queue is empty + altogether via isEmpty(). + */ + void process(); + + /** Query state of the queue + + @return false, if queue is empty, true otherwise + */ + bool isEmpty() const; + + /** Query timeout for the topmost event in the queue. + + @return Timeout in seconds, until the next event is + ready. The time returned here is relative to the pres + timer (i.e. the timer specified at the EventQueue + constructor). When the queue is empty (i.e. isEmpty() + returns true), the returned value is the highest + representable double value + (::std::numeric_limits<double>::max()). If the topmost + event in the queue is already pending, the timeout + returned here will actually be negative. + */ + double nextTimeout() const; + + /** Remove all pending events from the queue. + */ + void clear(); + + /** Forces an empty queue, firing all events immediately + without minding any times. + @attention do only call from event loop, this calls process_()! + */ + void forceEmpty(); + + /** Gets the queue's timer object. + */ + std::shared_ptr< ::canvas::tools::ElapsedTime > const & + getTimer() const { return mpTimer; } + + private: + mutable std::mutex maMutex; + + struct EventEntry + { + EventSharedPtr pEvent; + double nTime; + + bool operator<( const EventEntry& ) const; // to leverage priority_queue's default compare + + EventEntry( EventSharedPtr const& p, double t ) + : pEvent(p), nTime(t) {} + }; + + typedef ::std::priority_queue< EventEntry > ImplQueueType; + ImplQueueType maEvents; + typedef ::std::vector<EventEntry> EventEntryVector; + EventEntryVector maNextEvents; + ImplQueueType maNextNextEvents; + void process_( bool bFireAllEvents ); + + // perform timing of events via relative time + // measurements. The world time starts, when the + // EventQueue object is created + std::shared_ptr< ::canvas::tools::ElapsedTime > mpTimer; + }; + +} +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_EVENTQUEUE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/expressionnode.hxx b/slideshow/source/inc/expressionnode.hxx new file mode 100644 index 000000000..6f9139012 --- /dev/null +++ b/slideshow/source/inc/expressionnode.hxx @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_EXPRESSIONNODE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_EXPRESSIONNODE_HXX + +/* Definition of ExpressionNode interface */ + +namespace slideshow::internal + { + /** Interface describing an abstract animation function. + + Use this interface to model time-dependent animation + functions of one variable. + */ + class AnimationFunction + { + public: + virtual ~AnimationFunction() {} + + /** Operator to calculate function value. + + This method calculates the function value for the + given time instant t. + + @param t + Current time instant, must be in the range [0,1] + + @return the function value, typically in relative + user coordinate space ([0,1] range). + */ + virtual double operator()( double t ) const = 0; + + }; + + /** Refinement of AnimationFunction + + This interface is used by the SMIL function parser, to + collapse constant values into precalculated, single nodes. + */ + class ExpressionNode : public AnimationFunction + { + public: + /** Predicate whether this node is constant. + + This predicate returns true, if this node is + neither time- nor ViewInfo dependent. This allows + for certain optimizations, i.e. not the full + expression tree needs be represented by + ExpressionNodes. + + @returns true, if this node is neither time- nor + ViewInfo dependent + */ + virtual bool isConstant() const = 0; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_EXPRESSIONNODE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/expressionnodefactory.hxx b/slideshow/source/inc/expressionnodefactory.hxx new file mode 100644 index 000000000..97d047371 --- /dev/null +++ b/slideshow/source/inc/expressionnodefactory.hxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_EXPRESSIONNODEFACTORY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_EXPRESSIONNODEFACTORY_HXX + +#include "expressionnode.hxx" + +#include <memory> + + +/* Definition of ExpressionNodeFactory class */ + +namespace slideshow::internal + { + /** ExpressionNode factory + + This class can be used to generate a wide variety of + ExpressionNode objects, e.g. when parsing SMIL function + expressions. + */ + class ExpressionNodeFactory + { + public: + static std::shared_ptr<ExpressionNode> createConstantValueExpression( double rConstantValue ); + + static std::shared_ptr<ExpressionNode> createValueTExpression (); + + static std::shared_ptr<ExpressionNode> createPlusExpression ( const std::shared_ptr<ExpressionNode>& rLHS, + const std::shared_ptr<ExpressionNode>& rRHS ); + static std::shared_ptr<ExpressionNode> createMinusExpression ( const std::shared_ptr<ExpressionNode>& rLHS, + const std::shared_ptr<ExpressionNode>& rRHS ); + static std::shared_ptr<ExpressionNode> createMultipliesExpression( const std::shared_ptr<ExpressionNode>& rLHS, + const std::shared_ptr<ExpressionNode>& rRHS ); + static std::shared_ptr<ExpressionNode> createDividesExpression ( const std::shared_ptr<ExpressionNode>& rLHS, + const std::shared_ptr<ExpressionNode>& rRHS ); + + /** Composes two ExpressionNode function. + + The resulting expression will calculate + rOuterFunction( rInnerFunction(t) ). + */ + static std::shared_ptr<ExpressionNode> createMinExpression ( const std::shared_ptr<ExpressionNode>& rOuterFunction, + const std::shared_ptr<ExpressionNode>& rInnerFunction ); + + static std::shared_ptr<ExpressionNode> createMaxExpression ( const std::shared_ptr<ExpressionNode>& rOuterFunction, + const std::shared_ptr<ExpressionNode>& rInnerFunction ); + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_EXPRESSIONNODEFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/framerate.hxx b/slideshow/source/inc/framerate.hxx new file mode 100644 index 000000000..0d7e98126 --- /dev/null +++ b/slideshow/source/inc/framerate.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_FRAMERATE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_FRAMERATE_HXX + +#include <sal/types.h> + +namespace slideshow::internal +{ +/** Some frame rate related data. +*/ +class FrameRate +{ +public: + /** The minimum number of frames per second is used to calculate the + minimum number of frames that is to be shown for active activities. + */ + static const sal_Int32 MinimumFramesPerSecond = 10; + + /** Aim high with the number of preferred number of frames per second. + This number is the maximum as well and the true number will be lower. + */ + static const sal_Int32 PreferredFramesPerSecond = 50; +}; + +} // end of namespace slideshow::internal + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/hslcolor.hxx b/slideshow/source/inc/hslcolor.hxx new file mode 100644 index 000000000..b4fbb6109 --- /dev/null +++ b/slideshow/source/inc/hslcolor.hxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_HSLCOLOR_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_HSLCOLOR_HXX + + +/* Definition of HSLColor class */ + +namespace slideshow::internal + { + class RGBColor; + + /** HSL color space class. + */ + class HSLColor + { + public: + HSLColor(); + HSLColor( double nHue, double nSaturation, double nLuminance ); + explicit HSLColor( const RGBColor& rColor ); + + /** Hue of the color. + + @return hue, is in the range [0,360] + */ + double getHue() const { return maHSLTriple.mnHue; } + + /** Saturation of the color. + + @return saturation, is in the range [0,1] + */ + double getSaturation() const { return maHSLTriple.mnSaturation; } + + /** Luminance of the color. + + @return luminance, is in the range [0,1] + */ + double getLuminance() const { return maHSLTriple.mnLuminance; } + + struct HSLTriple + { + HSLTriple(); + HSLTriple( double nHue, double nSaturation, double nLuminance ); + + double mnHue; + double mnSaturation; + double mnLuminance; + }; + + private: + // default copy/assignment are okay + // HSLColor(const HSLColor&); + // HSLColor& operator=( const HSLColor& ); + + HSLTriple maHSLTriple; + + }; + + bool operator==( const HSLColor& rLHS, const HSLColor& rRHS ); + bool operator!=( const HSLColor& rLHS, const HSLColor& rRHS ); + HSLColor operator+( const HSLColor& rLHS, const HSLColor& rRHS ); + HSLColor operator*( double nFactor, const HSLColor& rRHS ); + + /** HSL color linear interpolator. + + @param t + As usual, t must be in the [0,1] range + + @param bCCW + When true, hue interpolation happens counter-clockwise + */ + HSLColor interpolate( const HSLColor& rFrom, const HSLColor& rTo, double t, bool bCCW ); + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_HSLCOLOR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/hslcoloranimation.hxx b/slideshow/source/inc/hslcoloranimation.hxx new file mode 100644 index 000000000..3d2bb34c9 --- /dev/null +++ b/slideshow/source/inc/hslcoloranimation.hxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_HSLCOLORANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_HSLCOLORANIMATION_HXX + +#include "animation.hxx" +#include "hslcolor.hxx" + + +/* Definition of HSLColorAnimation interface */ + +namespace slideshow::internal + { + /** Interface defining a HSL color animation. + + This interface is a specialization of the Animation + interface, and is used to animate attributes representable + by a HSL color value. + */ + class HSLColorAnimation : public Animation + { + public: + typedef HSLColor ValueType; + + /** Set the animation to the given color value + + @param rColor + Current animation value. + */ + virtual bool operator()( const HSLColor& rColor ) = 0; + + /** Request the underlying value for this animation. + + This is necessary for pure To or By animations, as the + Activity cannot determine a sensible start value + otherwise. + + @attention Note that you are only permitted to query + for the underlying value, if the animation has actually + been started (via start() call). + */ + virtual HSLColor getUnderlyingValue() const = 0; + }; + + typedef ::std::shared_ptr< HSLColorAnimation > HSLColorAnimationSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_HSLCOLORANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/hyperlinkarea.hxx b/slideshow/source/inc/hyperlinkarea.hxx new file mode 100644 index 000000000..d7d760c08 --- /dev/null +++ b/slideshow/source/inc/hyperlinkarea.hxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_HYPERLINKAREA_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_HYPERLINKAREA_HXX + +#include <rtl/ustring.hxx> + +#include <memory> +#include <vector> +#include <utility> + +namespace basegfx { + class B2DRange; +} + +/* Definition of HyperlinkArea interface */ + +namespace slideshow::internal + { + /** HyperlinkArea interface + + Implementers of this interface provide information for + hyperlink sensitive areas. + */ + class HyperlinkArea + { + public: + typedef std::pair< ::basegfx::B2DRange, + OUString > HyperlinkRegion; + + typedef std::vector<HyperlinkRegion> HyperlinkRegions; + + /** Request hyperlink-sensitive areas. + + @return a vector of hyperlink-sensitive areas, plus + the URI associated to them. + */ + virtual HyperlinkRegions getHyperlinkRegions() const = 0; + + /** Retrieve priority of link area + + @return the priority of the link area. Link areas with + higher priority will receive hyperlink clicks in favor + of areas with less priority, if they cover the same + place on screen. + */ + virtual double getHyperlinkPriority() const = 0; + + /** Functor struct, for area ordering + + This defines a strict weak ordering of areas, sort key + is the object ptr value. Most typical use is for + associative containers holding areas. + */ + struct lessThanArea + { + // make functor adaptable (to boost::bind) + typedef bool result_type; + + bool operator()(const std::shared_ptr< HyperlinkArea >& rLHS, + const std::shared_ptr< HyperlinkArea >& rRHS) const + { + const double nPrioL( rLHS->getHyperlinkPriority() ); + const double nPrioR( rRHS->getHyperlinkPriority() ); + + // if prios are equal, tie-break on ptr value + return nPrioL == nPrioR ? rLHS.get() < rRHS.get() : nPrioL < nPrioR; + } + }; + + protected: + ~HyperlinkArea() {} + }; + + typedef std::shared_ptr< HyperlinkArea > HyperlinkAreaSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_HYPERLINKAREA_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/iexternalmediashapebase.hxx b/slideshow/source/inc/iexternalmediashapebase.hxx new file mode 100644 index 000000000..1a70ae093 --- /dev/null +++ b/slideshow/source/inc/iexternalmediashapebase.hxx @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_IEXTERNALMEDIASHAPEBASE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_IEXTERNALMEDIASHAPEBASE_HXX + +#include <memory> + +#include "shape.hxx" + + +namespace slideshow::internal + { + /** Represents a shape containing playable content rendered by + external engine (e.g. media or applet). + + This interface adds media handling methods to a shape. It + allows starting/stopping and pausing playback. + */ + class IExternalMediaShapeBase : public Shape + { + public: + // Animation methods + + + /** Notify the Shape that it should start with playback + + This method enters playback mode on all registered + views. It makes the media initially visible (for videos). + */ + virtual void play() = 0; + + /** Notify the Shape that it should stop playback + + This method leaves playback mode on all registered + views. The media is then rewound to the start, and + removed from screen (for videos) + */ + virtual void stop() = 0; + + /** Notify the Shape that it should pause playback + + This method stops playback on all registered + views. The media stays visible (for videos) + */ + virtual void pause() = 0; + + /** Query whether the media is currently playing. + */ + virtual bool isPlaying() const = 0; + + /** Set media time in seconds. + + @param fTime + Time in seconds of the media time line, that should now be + presented + */ + virtual void setMediaTime(double fTime) = 0; + + virtual void setLooping(bool /*bLooping*/){}; + }; + + typedef ::std::shared_ptr< IExternalMediaShapeBase > IExternalMediaShapeBaseSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_IEXTERNALMEDIASHAPEBASE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/interruptabledelayevent.hxx b/slideshow/source/inc/interruptabledelayevent.hxx new file mode 100644 index 000000000..a877e206f --- /dev/null +++ b/slideshow/source/inc/interruptabledelayevent.hxx @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_INTERRUPTABLEDELAYEVENT_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_INTERRUPTABLEDELAYEVENT_HXX + +#include "delayevent.hxx" + +namespace slideshow::internal + { + /** Event, which delays calling passed Event's fire() method + the given amount of time. + + This is actually a facade around the passed event object, + that passes on all calls to that object, and the sole + contribution of itself is the delay. + */ + class DelayFacade : public Event + { + public: + DelayFacade( const EventSharedPtr& rEvent, + double nTimeout ) : + Event("DelayFacade"), + mpEvent( rEvent ), + mnTimeout( nTimeout ) + { + } + + virtual bool fire() override + { + if( mpEvent && isCharged() ) + { + // pass on directly - we're supposed to be called + // from EventQueue here, anyway - and if not, + // we're only keeping that incorrect transitively. + return mpEvent->fire(); + } + + return false; + } + + virtual bool isCharged() const override + { + // pass on to wrappee - this ensures that we return + // false on isCharged(), even if the other event has + // been fired outside our own fire() method + return mpEvent && mpEvent->isCharged(); + } + + virtual double getActivationTime( double nCurrentTime ) const override + { + // enforce _our_ timeout to our clients (this + // overrides any timeout possibly set at the wrappee!) + return nCurrentTime + mnTimeout; + } + + virtual void dispose() override + { + mpEvent.reset(); + } + + private: + EventSharedPtr mpEvent; + double mnTimeout; + }; + + /// Return value for makeInterruptableDelay() + struct InterruptableEventPair + { + /** This member contains a pointer to the timeout + event. When enqueued, this event will fire the + requested action only after the specified timeout. + */ + EventSharedPtr mpTimeoutEvent; + + /** This member contains a pointer to the interruption + event. When enqueued, this event will fire + immediately, interrupting a potentially waiting + timeout event. + */ + EventSharedPtr mpImmediateEvent; + }; + + /** Generate an interruptable delay event. + + This function generates a pair of events, that are + especially tailored to achieve the following behaviour: By + default, the given functor is called after the specified + timeout (after insertion of the event into the EventQueue, + of course). But optionally, when the interruption event + InterruptableEventPair::mpImmediateEvent is fired, the + given functor is called <em>at once</em>, and the delay is + ignored (that means, the given functor is guaranteed to be + called at utmost once, and never twice. Furthermore, it is + ensured that both events return false on isCharged(), once + anyone of them has been fired already). + + @param rFunctor + Functor to call when the event fires. + + @param nTimeout + Timeout in seconds, to wait until functor is called. + + @returns a pair of events, where the first one waits the + specified amount of time, and the other fires the given + functor immediately. + */ + template< typename Functor > InterruptableEventPair makeInterruptableDelay( const Functor& rFunctor, + double nTimeout ) + { + InterruptableEventPair aRes; + + aRes.mpImmediateEvent = makeEvent( rFunctor, "makeInterruptableDelay"); + aRes.mpTimeoutEvent = std::make_shared<DelayFacade>( aRes.mpImmediateEvent, + nTimeout ); + + return aRes; + } + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_INTERRUPTABLEDELAYEVENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/intrinsicanimationeventhandler.hxx b/slideshow/source/inc/intrinsicanimationeventhandler.hxx new file mode 100644 index 000000000..97ad6571c --- /dev/null +++ b/slideshow/source/inc/intrinsicanimationeventhandler.hxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_INTRINSICANIMATIONEVENTHANDLER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_INTRINSICANIMATIONEVENTHANDLER_HXX + +#include <memory> + +/* Definition of IntrinsicAnimationEventHandler interface */ + +namespace slideshow::internal + { + + /** Interface for handling intrinsic animation display modes. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle intrinsic animation events. + */ + class IntrinsicAnimationEventHandler + { + public: + virtual ~IntrinsicAnimationEventHandler() {} + + virtual bool enableAnimations() = 0; + virtual bool disableAnimations() = 0; + }; + + typedef ::std::shared_ptr< IntrinsicAnimationEventHandler > IntrinsicAnimationEventHandlerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_INTRINSICANIMATIONEVENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/listenercontainer.hxx b/slideshow/source/inc/listenercontainer.hxx new file mode 100644 index 000000000..8deb1be90 --- /dev/null +++ b/slideshow/source/inc/listenercontainer.hxx @@ -0,0 +1,418 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_LISTENERCONTAINER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_LISTENERCONTAINER_HXX + +#include <algorithm> +#include <memory> +#include <vector> +#include <iterator> + +namespace slideshow::internal { + +struct EmptyBase +{ + struct EmptyGuard{ explicit EmptyGuard(EmptyBase) {} }; + struct EmptyClearableGuard + { + explicit EmptyClearableGuard(EmptyBase) {} + static void clear() {} + }; + + typedef EmptyGuard Guard; + typedef EmptyClearableGuard ClearableGuard; +}; + +template< typename result_type, typename ListenerTargetT > struct FunctionApply +{ + template<typename FuncT> static bool apply( + FuncT func, + ListenerTargetT const& rArg ) + { + return func(rArg); + } +}; + +template<typename ListenerTargetT> struct FunctionApply<void,ListenerTargetT> +{ + template<typename FuncT> static bool apply( + FuncT func, + ListenerTargetT const& rArg ) + { + func(rArg); + return true; + } +}; + +template< typename ListenerT > struct ListenerOperations +{ + /// Notify a single one of the listeners + template< typename ContainerT, + typename FuncT > + static bool notifySingleListener( ContainerT& rContainer, + FuncT func ) + { + // true: a handler in this queue processed the event + // false: no handler in this queue finally processed the event + return std::any_of( rContainer.begin(), + rContainer.end(), + func ); + } + + /// Notify all listeners + template< typename ContainerT, + typename FuncT > + static bool notifyAllListeners( ContainerT& rContainer, + FuncT func ) + { + bool bRet(false); + for( const auto& rCurr : rContainer ) + { + if( FunctionApply< typename ::std::invoke_result< FuncT, const typename ContainerT::value_type& >::type, + typename ContainerT::value_type >::apply( + func, + rCurr) ) + { + bRet = true; + } + } + + // true: at least one handler returned true + // false: not a single handler returned true + return bRet; + } + + /// Prune container from deceased listeners + template< typename ContainerT > + static void pruneListeners( ContainerT&, size_t ) + { + } +}; + +template< typename ListenerTargetT > +struct ListenerOperations< std::weak_ptr<ListenerTargetT> > +{ + template< typename ContainerT, + typename FuncT > + static bool notifySingleListener( ContainerT& rContainer, + FuncT func ) + { + for( const auto& rCurr : rContainer ) + { + std::shared_ptr<ListenerTargetT> pListener( rCurr.lock() ); + + if( pListener && func(pListener) ) + return true; + } + + return false; + } + + template< typename ContainerT, + typename FuncT > + static bool notifyAllListeners( ContainerT& rContainer, + FuncT func ) + { + bool bRet(false); + for( const auto& rCurr : rContainer ) + { + std::shared_ptr<ListenerTargetT> pListener( rCurr.lock() ); + + if( pListener.get() && + FunctionApply<typename ::std::invoke_result<FuncT, std::shared_ptr<ListenerTargetT> const&>::type, + std::shared_ptr<ListenerTargetT> >::apply(func,pListener) ) + { + bRet = true; + } + } + + return bRet; + } + template< typename ContainerT > + static void pruneListeners( ContainerT& rContainer, + size_t nSizeThreshold ) + { + if( rContainer.size() <= nSizeThreshold ) + return; + + ContainerT aAliveListeners; + aAliveListeners.reserve(rContainer.size()); + + for( const auto& rCurr : rContainer ) + { + if( !rCurr.expired() ) + aAliveListeners.push_back( rCurr ); + } + + std::swap( rContainer, aAliveListeners ); + } +}; + +/** Container for objects that can be notified. + + This templatized container holds listener objects, then can get + notified (by calling certain methods on them). + + @tpl Listener + Type for the listener objects to be held + + @tpl ContainerT + Full type of the container to store the listener objects. Defaults + to std::vector<ListenerT> + + @tpl MaxDeceasedListenerUllage + Threshold, from which upwards the listener container gets + pruned. Avoids frequent copying of nearly empty containers. + + @attention internal class, not to be used. functionality is + incomplete, please use the Thread(Un)safeListenerContainer types + from below +*/ +template< typename ListenerT, + typename MutexHolderBaseT, + typename ContainerT=std::vector<ListenerT>, + size_t MaxDeceasedListenerUllage=16 > class ListenerContainerBase : public MutexHolderBaseT +{ + typedef typename MutexHolderBaseT::Guard Guard; + typedef typename MutexHolderBaseT::ClearableGuard ClearableGuard; + +public: + typedef ListenerT listener_type; + typedef ContainerT container_type; + + /** Check whether listener container is empty + + @return true, if currently no listeners registered. Note that + in a multi-threaded scenario, without external synchronisation + to this object, the return value might become wrong at any time. + */ + bool isEmpty() const + { + Guard aGuard(*this); + return maListeners.empty(); + } + + /** Check whether given listener is already added + + @return true, if given listener is already added. + */ + bool isAdded( listener_type const& rListener ) const + { + Guard aGuard(*this); + + const typename container_type::const_iterator aEnd( maListeners.end() ); + if( std::find( maListeners.begin(), + aEnd, + rListener ) != aEnd ) + { + return true; // already added + } + + return false; + } + + /** Add new listener + + @param rListener + Listener to add + */ + void add( listener_type const& rListener ) + { + Guard aGuard(*this); + + // ensure uniqueness + if( isAdded(rListener) ) + return; // already added + + maListeners.push_back( rListener ); + + ListenerOperations<ListenerT>::pruneListeners( + maListeners, + MaxDeceasedListenerUllage); + } + + /** Add new listener into sorted container + + The stored listeners are kept sorted (using this method + requires listener_type to have operator< defined on it). Make + sure to call addSorted() for <em>each</em> listener to add to + this container - sorting is performed under the assumption + that existing entries are already sorted. + + @param rListener + Listener to add + + @return false, if the listener is already added, true + otherwise + */ + bool addSorted( listener_type const& rListener ) + { + Guard aGuard(*this); + + // ensure uniqueness + if( isAdded(rListener) ) + return false; // already added + + maListeners.push_back( rListener ); + + // a single entry does not need to be sorted + if( maListeners.size() > 1 ) + { + std::inplace_merge( + maListeners.begin(), + std::prev(maListeners.end()), + maListeners.end() ); + } + + ListenerOperations<ListenerT>::pruneListeners( + maListeners, + MaxDeceasedListenerUllage); + + return true; + } + + /** Remove listener from container + + @param rListener + The listener to remove + + @return false, if listener not found in container, true + otherwise + */ + bool remove( listener_type const& rListener ) + { + Guard aGuard(*this); + + const typename container_type::iterator aEnd( maListeners.end() ); + typename container_type::iterator aIter; + if( (aIter=std::remove(maListeners.begin(), + aEnd, + rListener)) == aEnd ) + { + return false; // listener not found + } + + maListeners.erase( aIter, aEnd ); + + return true; + } + + /// Removes all listeners in one go + void clear() + { + Guard aGuard(*this); + + maListeners.clear(); + } + + /** Apply functor to one listener + + This method applies functor to one of the listeners. Starting + with the first entry of the container, the functor is called + with the listener entries, until it returns true. + + @param func + Given functor is called with listeners, until it returns true + + @return true, if functor was successfully applied to a + listener + */ + template< typename FuncT > bool apply( FuncT func ) const + { + ClearableGuard aGuard(*this); + + // generate a local copy of all handlers, to make method + // reentrant and thread-safe. + container_type const local( maListeners ); + aGuard.clear(); + + const bool bRet( + ListenerOperations<ListenerT>::notifySingleListener( + local, + func )); + + { + Guard aGuard2(*this); + ListenerOperations<ListenerT>::pruneListeners( + const_cast<container_type&>(maListeners), + MaxDeceasedListenerUllage); + } + + return bRet; + } + + /** Apply functor to all listeners + + This method applies functor to all of the listeners. Starting + with the first entry of the container, the functor is called + with the listener entries. + + @param func + Given functor is called with listeners. + + @return true, if functor was successfully applied to at least + one listener + */ + template< typename FuncT > bool applyAll( FuncT func ) const + { + ClearableGuard aGuard(*this); + + // generate a local copy of all handlers, to make method + // reentrant and thread-safe. + container_type const local( maListeners ); + aGuard.clear(); + + const bool bRet( + ListenerOperations<ListenerT>::notifyAllListeners( + local, + func )); + + { + Guard aGuard2(*this); + ListenerOperations<ListenerT>::pruneListeners( + const_cast<container_type&>(maListeners), + MaxDeceasedListenerUllage); + } + + return bRet; + } + +private: + ContainerT maListeners; +}; + + +/** ListenerContainer variant that does not serialize access + + This ListenerContainer version is not safe to use in a + multi-threaded scenario, but has less overhead. + */ +template< typename ListenerT, + typename ContainerT=std::vector<ListenerT> > +class ThreadUnsafeListenerContainer : public ListenerContainerBase<ListenerT, + EmptyBase, + ContainerT> +{ +}; + +} // namespace slideshow::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_LISTENERCONTAINER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/mediafilemanager.hxx b/slideshow/source/inc/mediafilemanager.hxx new file mode 100644 index 000000000..a0ec69556 --- /dev/null +++ b/slideshow/source/inc/mediafilemanager.hxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_MEDIAFILEMANAGER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_MEDIAFILEMANAGER_HXX + +#include <rtl/ustring.hxx> + +#include <memory> + +namespace avmedia +{ +struct MediaTempFile; +} + +namespace slideshow::internal +{ +class MediaFileManager +{ +public: + virtual ~MediaFileManager(){}; + virtual std::shared_ptr<avmedia::MediaTempFile> getMediaTempFile(const OUString& aUrl) = 0; +}; +} +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_MEDIAFILEMANAGER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/mouseeventhandler.hxx b/slideshow/source/inc/mouseeventhandler.hxx new file mode 100644 index 000000000..6be068e8a --- /dev/null +++ b/slideshow/source/inc/mouseeventhandler.hxx @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_MOUSEEVENTHANDLER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_MOUSEEVENTHANDLER_HXX + +#include <sal/types.h> + +#include <memory> + +namespace com::sun::star::awt { struct MouseEvent; } + + +/* Definition of MouseEventHandler interface */ + +namespace slideshow::internal + { + + /** Interface for handling mouse events. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle mouse events. + */ + class MouseEventHandler + { + public: + virtual ~MouseEventHandler() {} + + /** Handle a mouse button pressed event. + + @param e + The mouse event that occurred. The x,y coordinates of + the event are already transformed back to user + coordinate space, taking the inverse transform of the + view in which the event occurred. + + @return true, if this handler has successfully + processed the mouse event. When this method returns + false, possibly other, less prioritized handlers can be + called, too. + */ + virtual bool handleMousePressed( const css::awt::MouseEvent& e ) = 0; + + /** Handle a mouse button released event. + + @param e + The mouse event that occurred. The x,y coordinates of + the event are already transformed back to user + coordinate space, taking the inverse transform of the + view in which the event occurred. + + @return true, if this handler has successfully + processed the pause event. When this method returns + false, possibly other, less prioritized handlers are + called, too. + */ + virtual bool handleMouseReleased( const css::awt::MouseEvent& e ) = 0; + + /** Handle a mouse was moved with a pressed button event. + + @param e + The mouse event that occurred. The x,y coordinates of + the event are already transformed back to user + coordinate space, taking the inverse transform of the + view in which the event occurred. + + @return true, if this handler has successfully + processed the pause event. When this method returns + false, possibly other, less prioritized handlers are + called, too. + */ + virtual bool handleMouseDragged( const css::awt::MouseEvent& e ) = 0; + + /** Handle a mouse was moved event. + + @param e + The mouse event that occurred. The x,y coordinates of + the event are already transformed back to user + coordinate space, taking the inverse transform of the + view in which the event occurred. + + @return true, if this handler has successfully + processed the pause event. When this method returns + false, possibly other, less prioritized handlers are + called, too. + */ + virtual bool handleMouseMoved( const css::awt::MouseEvent& e ) = 0; + }; + + typedef ::std::shared_ptr< MouseEventHandler > MouseEventHandlerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_MOUSEEVENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/numberanimation.hxx b/slideshow/source/inc/numberanimation.hxx new file mode 100644 index 000000000..e35769e97 --- /dev/null +++ b/slideshow/source/inc/numberanimation.hxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_NUMBERANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_NUMBERANIMATION_HXX + +#include "animation.hxx" + + +/* Definition of NumberAnimation interface */ + +namespace slideshow::internal + { + /** Interface defining a number animation. + + This interface is a specialization of the Animation + interface, and is used to animate attributes representable + by a single floating point value. + */ + class NumberAnimation : public Animation + { + public: + typedef double ValueType; + + /** Set the animation to value x + + @param x + Current animation value (must be in an + attribute-specific permissible range). Overflowing + values will be clipped to the permissible range + internally. + */ + virtual bool operator()( double x ) = 0; + + /** Request the underlying value for this animation. + + This is necessary for pure To or By animations, as the + Activity cannot determine a sensible start value + otherwise. + + @attention Note that you are only permitted to query + for the underlying value, if the animation has actually + been started (via start() call). + */ + virtual double getUnderlyingValue() const = 0; + }; + + typedef ::std::shared_ptr< NumberAnimation > NumberAnimationSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_NUMBERANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/pairanimation.hxx b/slideshow/source/inc/pairanimation.hxx new file mode 100644 index 000000000..45b90ebbb --- /dev/null +++ b/slideshow/source/inc/pairanimation.hxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_PAIRANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_PAIRANIMATION_HXX + +#include "animation.hxx" +#include <basegfx/tuple/b2dtuple.hxx> + + +/* Definition of PairAnimation interface */ + +namespace slideshow::internal + { + /** Interface defining a pair of numbers animation. + + This interface is a specialization of the Animation + interface, and is used to animate attributes representable + by a pair of floating point values (e.g. a position or a + size). + */ + class PairAnimation : public Animation + { + public: + typedef ::basegfx::B2DTuple ValueType; + + /** Set the animation to the given value + + @param rValue + Current animation value. + */ + virtual bool operator()( const ::basegfx::B2DTuple& rValue ) = 0; + + /** Request the underlying value for this animation. + + This is necessary for pure To or By animations, as the + Activity cannot determine a sensible start value + otherwise. + + @attention Note that you are only permitted to query + for the underlying value, if the animation has actually + been started (via start() call). + */ + virtual ::basegfx::B2DTuple getUnderlyingValue() const = 0; + }; + + typedef ::std::shared_ptr< PairAnimation > PairAnimationSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_PAIRANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/pauseeventhandler.hxx b/slideshow/source/inc/pauseeventhandler.hxx new file mode 100644 index 000000000..3d61d6ee1 --- /dev/null +++ b/slideshow/source/inc/pauseeventhandler.hxx @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_PAUSEEVENTHANDLER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_PAUSEEVENTHANDLER_HXX + +#include <memory> + + +/* Definition of PauseHandler interface */ + +namespace slideshow::internal + { + + /** Interface for handling pause events. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle pause events. + */ + class PauseEventHandler + { + public: + /** Handle the event. + + @param bPauseShow + When true, the show is paused. When false, the show is + started again + + @return true, if this handler has successfully + processed the pause event. When this method returns + false, possibly other, less prioritized handlers are + called, too. + */ + virtual bool handlePause( bool bPauseShow ) = 0; + + protected: + ~PauseEventHandler() {} + }; + + typedef ::std::shared_ptr< PauseEventHandler > PauseEventHandlerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_PAUSEEVENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/rgbcolor.hxx b/slideshow/source/inc/rgbcolor.hxx new file mode 100644 index 000000000..b5f3f8e61 --- /dev/null +++ b/slideshow/source/inc/rgbcolor.hxx @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_RGBCOLOR_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_RGBCOLOR_HXX + +#include <cppcanvas/color.hxx> + + +/* Definition of RGBColor class */ + +namespace slideshow::internal + { + class HSLColor; + + /** RGB color space class. + */ + class RGBColor + { + public: + RGBColor(); + explicit RGBColor( ::cppcanvas::IntSRGBA nRGBColor ); + RGBColor( double nRed, double nGreen, double nBlue ); + explicit RGBColor( const HSLColor& rColor ); + + /** Get the RGB red value. + */ + double getRed() const { return maRGBTriple.mnRed; } + + /** Get the RGB green value. + */ + double getGreen() const { return maRGBTriple.mnGreen; } + + /** Get the RGB blue value. + */ + double getBlue() const { return maRGBTriple.mnBlue; } + + /** Create an integer sRGBA color. + */ + ::cppcanvas::IntSRGBA getIntegerColor() const; + + struct RGBTriple + { + RGBTriple(); + RGBTriple( double nRed, double nGreen, double nBlue ); + + double mnRed; + double mnGreen; + double mnBlue; + }; + + private: + // default copy/assignment are okay + // RGBColor(const RGBColor&); + // RGBColor& operator=( const RGBColor& ); + + RGBTriple maRGBTriple; + }; + + bool operator==( const RGBColor& rLHS, const RGBColor& rRHS ); + bool operator!=( const RGBColor& rLHS, const RGBColor& rRHS ); + RGBColor operator+( const RGBColor& rLHS, const RGBColor& rRHS ); + RGBColor operator*( const RGBColor& rLHS, const RGBColor& rRHS ); + RGBColor operator*( double nFactor, const RGBColor& rRHS ); + + + /** RGB color linear interpolator. + + @param t + As usual, t must be in the [0,1] range + */ + RGBColor interpolate( const RGBColor& rFrom, const RGBColor& rTo, double t ); +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_RGBCOLOR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/screenupdater.hxx b/slideshow/source/inc/screenupdater.hxx new file mode 100644 index 000000000..4ae477519 --- /dev/null +++ b/slideshow/source/inc/screenupdater.hxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SCREENUPDATER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SCREENUPDATER_HXX + +#include "viewupdate.hxx" +#include "unoviewcontainer.hxx" +#include <memory> + +/* Definition of ScreenUpdater class */ + +namespace slideshow::internal + { + /** Screen updater + + This class handles and synchronizes screen updates + centrally. Therefore, it can hold a number of ViewUpdate + objects, which are polled for pending updates on + commitUpdates(). Furthermore, external code can request + updates via notifyUpdate() calls. If neither such an + update was requested, nor any of the registered ViewUpdate + objects report any pending update, commitUpdates() does + nothing. + */ + class ScreenUpdater + { + public: + explicit ScreenUpdater( UnoViewContainer const& rViewContainer ); + ~ScreenUpdater(); + ScreenUpdater(const ScreenUpdater&) = delete; + ScreenUpdater& operator=(const ScreenUpdater&) = delete; + + /** Notify screen update + + This method records a screen content update request + for all views. + */ + void notifyUpdate(); + + /** Notify screen update + + This method records a screen content update request + for the given view. + + @param rView + The view that needs an update + + @param bViewClobbered + When true, notifies update that view content is + clobbered by external circumstances (e.g. by another + application), and needs update even if the + implementation 'thinks' it does not need to render + something to screen. + */ + void notifyUpdate( const UnoViewSharedPtr& rView, bool bViewClobbered ); + + /** Commits collected update actions + */ + void commitUpdates(); + + /** Register ViewUpdate + + @param rViewUpdate + Add this ViewUpdate to the list that's asked for + pending updates + */ + void addViewUpdate( ViewUpdateSharedPtr const& rViewUpdate ); + + /** Unregister ViewUpdate + + @param rViewUpdate + Remove this ViewUpdate from the list that's asked for + pending updates + */ + void removeViewUpdate( ViewUpdateSharedPtr const& ); + + /** A wart. + + Used to fire an immediate screen update. Currently + needed for the wait symbol, since switching that on + and off does get to commitUpdates() + */ + void requestImmediateUpdate(); + + class UpdateLock { + public: + virtual void Activate() = 0; + + protected: + ~UpdateLock() {} + }; + + /** Call this method to create a lock instead of calling + lockUpdates() and unlockUpdates() directly. + */ + ::std::shared_ptr<UpdateLock> createLock(); + + /** Lock updates to prevent intermediate repaints. + */ + void lockUpdates(); + + /** When called as often as lockUpdates() then commitUpdates() + is called. + */ + void unlockUpdates(); + + private: + struct ImplScreenUpdater; + std::unique_ptr<ImplScreenUpdater> mpImpl; + + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SCREENUPDATER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shape.hxx b/slideshow/source/inc/shape.hxx new file mode 100644 index 000000000..bbd2988e0 --- /dev/null +++ b/slideshow/source/inc/shape.hxx @@ -0,0 +1,283 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPE_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/drawing/XShape.hpp> + +#include <basegfx/range/b2drectangle.hxx> + +#include "viewlayer.hxx" + +#include <memory> +#include <set> + +namespace basegfx { + class B2DRange; +} + +namespace slideshow::internal + { + // forward declaration necessary, because methods use ShapeSharedPtr + class Shape; + + typedef ::std::shared_ptr< Shape > ShapeSharedPtr; + + /** Represents a slide's shape object. + + This interface represents the view-independent aspects of a + slide's shape, providing bound rect, underlying XShape and + basic paint methods. + */ + class Shape + { + public: + Shape() : mbIsForeground(true) {} + virtual ~Shape() {} + Shape(const Shape&) = delete; + Shape& operator=(const Shape&) = delete; + + /** Get the associated XShape of this shape. + + @return the associated XShape. If this method returns + an empty reference, this object might be one of the + special-purpose shapes of a slide, which have no + direct corresponding XShape (the background comes to + mind here). + */ + virtual css::uno::Reference< css::drawing::XShape > getXShape() const = 0; + + + // View layer methods + + + /** Add a new view layer. + + This method adds a new view layer, this shape shall + show itself on. + + @param rNewLayer + New layer to show on + + @param bRedrawLayer + Redraw shape on given layer + */ + virtual void addViewLayer( const ViewLayerSharedPtr& rNewLayer, + bool bRedrawLayer ) = 0; + + /** Withdraw the shape from a view layer + + This method removes the shape from the given view + layer. + + @return true, if the shape was successfully removed + */ + virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer ) = 0; + + /** Withdraw all view layers at once + + This method will be faster than repeated + removeViewLayer() calls. + */ + virtual void clearAllViewLayers() = 0; + + // render methods + + + /** Update the shape + + This method updates the Shape on all registered view + layers, but only if shape content has actually + changed. + + @return whether the update finished successfully. + */ + virtual bool update() const = 0; + + /** Render the shape. + + This method renders the shape on all registered view + layers, regardless of whether shape content has + changed or not. + + @return whether the rendering finished successfully. + */ + virtual bool render() const = 0; + + /** Query whether shape content changed + + This method returns true, if shape content changed + since the last rendering (i.e. the shape needs an + update to reflect that changed content on the views). + */ + virtual bool isContentChanged() const = 0; + + + // Shape attributes + + + /** Get the current shape position and size. + + This method yields the currently effective shape + bounds (which might change over time, for animated + shapes). Please note that possibly shape rotations + from its original document state must not be taken + into account here: if you need the screen bounding + box, use getUpdateArea() instead. Note further that + shape rotations, which are already contained in the + shape as displayed in the original document + <em>are</em> included herein (we currently take the + shape as-is from the document, assuming a rotation + angle of 0). + */ + virtual ::basegfx::B2DRectangle getBounds() const = 0; + + /** Get the DOM position and size of the shape. + + This method yields the underlying DOM shape bounds, + i.e. the original shape bounds from the document + model. This value is <em>always</em> unaffected by any + animation activity. Note that shape rotations, which + are already contained in the shape as displayed in the + original document are already included herein (we + currently take the shape as-is from the document, + assuming a rotation angle of 0). + */ + virtual ::basegfx::B2DRectangle getDomBounds() const = 0; + + /** Get the current shape update area. + + This method yields the currently effective update area + for the shape, i.e. the area that needs to be updated, + should the shape be painted. Normally, this will be + the (possibly rotated and sheared) area returned by + getBounds(). + */ + virtual ::basegfx::B2DRectangle getUpdateArea() const = 0; + + /** Query whether the shape is visible at all. + + @return true, if this shape is visible, false + otherwise. + */ + virtual bool isVisible() const = 0; + + /** Get the shape priority. + + The shape priority defines the relative order of the + shapes on the slide. + + @return the priority. Will be in the [0,+infty) range. + */ + virtual double getPriority() const = 0; + + /** Query whether the Shape is currently detached from the + background. + + This method checks whether the Shape is currently + detached from the slide background, i.e. whether shape + updates affect the underlying slide background or + not. A shape that returns true here must not alter + slide content in any way when called render() or + update() (this is normally achieved by making this + shape a sprite). + */ + virtual bool isBackgroundDetached() const = 0; + + /** Check whether the shape belongs to the foreground + + For instance, if the shape is in the master slide + it does not belong to the foreground. + + @return true if the shape is on the foreground + */ + virtual bool isForeground() const { return mbIsForeground; }; + + /** + Set the flag that holds whether the shape is + in the foreground or not + + @param bIsForeground + Shape is on the foreground + */ + virtual void setIsForeground( const bool bIsForeground ) { mbIsForeground = bIsForeground; }; + + // Misc + + + /** Functor struct, for shape ordering + + This defines a strict weak ordering of shapes, primary + sort key is the shape priority, and secondary sort key + the object ptr value. Most typical use is for + associative containers holding shapes (and which also + have to maintain something like a paint order). + */ + struct lessThanShape + { + // make functor adaptable (to boost::bind) + typedef bool result_type; + + // since the ZOrder property on the XShape has somewhat + // peculiar attributes (it's basically the index of the shapes + // in the drawing layer's SdrObjList - which means, it starts + // from 0 for children of group objects), we cannot use it to determine + // drawing order. Thus, we rely on importer-provided order values here, + // which is basically a running counter during shape import (i.e. denotes + // the order of shape import). This is the correct order, at least for the + // current drawing core. + + // If, someday, the above proposition is no longer true, one directly use + // the shape's ZOrder property + + static bool compare(const Shape* pLHS, const Shape* pRHS) + { + const double nPrioL( pLHS->getPriority() ); + const double nPrioR( pRHS->getPriority() ); + + // if prios are equal, tie-break on ptr value + return nPrioL == nPrioR ? pLHS < pRHS : nPrioL < nPrioR; + } + + bool operator()(const ShapeSharedPtr& rLHS, const ShapeSharedPtr& rRHS) const + { + return compare(rLHS.get(),rRHS.get()); + } + + }; + + private: + /** Flag to check whether the shape belongs to the foreground. + + For instance, it is false if the shape belongs to the master slide. + */ + bool mbIsForeground; + }; + + /** A set which contains all shapes in an ordered fashion. + */ + typedef ::std::set< ShapeSharedPtr, Shape::lessThanShape > ShapeSet; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SHAPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shapeattributelayer.hxx b/slideshow/source/inc/shapeattributelayer.hxx new file mode 100644 index 000000000..b97722fee --- /dev/null +++ b/slideshow/source/inc/shapeattributelayer.hxx @@ -0,0 +1,543 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEATTRIBUTELAYER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEATTRIBUTELAYER_HXX + +#include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/awt/FontSlant.hpp> + +#include <basegfx/vector/b2dsize.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> + +#include "rgbcolor.hxx" + +#include <memory> + + +namespace slideshow::internal + { + + /** This interface represents a stateful object. + + The state ID returned by the getStateId() method + abstractly encodes the object's state. When this ID + changes, clients can assume that the object's state has + changed. + */ + class State final + { + public: + + /// Abstract, numerically encoded state ID + typedef ::std::size_t StateId; + }; + + class ShapeAttributeLayer; + + typedef ::std::shared_ptr< ShapeAttributeLayer > ShapeAttributeLayerSharedPtr; + + /** Encapsulates all modifiable attributes of a shape. + + This class holds all modifiable attributes of a shape, and + at the same time provides means to layer attributes on top + of each other... + + And yes, there's a reason why we even pass bools and ints + by const reference. Namely, that makes the set* methods + differ only in the value type, which greatly reduces + template variability (e.g. in AnimationFactory). + */ + class ShapeAttributeLayer + { + public: + /** Create a ShapeAttributeLayer instance, with all + attributes set to default. + + Furthermore, this constructor gets a pointer to a + child layer, which is used as the fallback (or the + base value) for all attributes + + @param rChildLayer + Layer below this one + + @attention + This method is only supposed to be called from Shape objects + */ + explicit ShapeAttributeLayer( const ShapeAttributeLayerSharedPtr& rChildLayer ); + + // Children management methods + + + /** Revoke the given layer. + + This method revokes the given layer from this object + or one of the children. That is, if this object does + have children, and the given layer is no direct child, + it is recursively passed to the children for removal. + + @return true, if removal was successful. + + @attention + This method is only supposed to be called from Shape objects + */ + bool revokeChildLayer( const ShapeAttributeLayerSharedPtr& rChildLayer ); + + /** Query the child layer of this object. + + @attention + This method is only supposed to be called from Shape objects + */ + const ShapeAttributeLayerSharedPtr& getChildLayer() const; + + /** Set the additive mode for possible child attributes + + This method sets the additive mode for child + attributes. That is the way underlying attribute + layers are combined with this one (i.e. to overrule + lower layers, or how to combine the values). The + default is + css::animations::AnimationAdditiveMode::BASE, + which means, take the value of the underlying layers, + or from the model shape itself. + + @param nMode + Must be one of + css::animations::AnimationAdditiveMode. + */ + void setAdditiveMode( sal_Int16 nMode ); + + // Attribute methods + + + /** Query whether the width attribute is valid. + */ + bool isWidthValid() const; + /** Query the current width of the shape + */ + double getWidth() const; + /** Set the new width of the shape + + @param rNewWidth + A negative width mirrors the shape. + */ + void setWidth( const double& rNewWidth ); + + /** Query whether the height attribute is valid. + */ + bool isHeightValid() const; + /** Query the current height of the shape + */ + double getHeight() const; + /** Set the new height of the shape + + @param rNewHeight + A negative height mirrors the shape. + */ + void setHeight( const double& rNewHeight ); + + /** Set the new size of the shape + + @param rNewSize + A negative size mirrors the shape. + */ + void setSize( const ::basegfx::B2DSize& rNewSize ); + + /** Query whether the x position attribute is valid + */ + bool isPosXValid() const; + /** Query the current x position of the shape. + + The current x position of the shape is always relative + to the <em>center</em> of the shape (in contrast to + the Shape::getBounds() and Shape::getUpdateArea() + methods). + */ + double getPosX() const; + /** Set the new x position of the shape + + The current x position of the shape is always relative + to the <em>center</em> of the shape (in contrast to + the Shape::getBounds() and Shape::getUpdateArea() + methods). + */ + void setPosX( const double& rNewX ); + + /** Query whether the y position attribute is valid + */ + bool isPosYValid() const; + /** Query the current y position of the shape + + The current y position of the shape is always relative + to the <em>center</em> of the shape (in contrast to + the Shape::getBounds() and Shape::getUpdateArea() + methods). + */ + double getPosY() const; + /** Set the new y position of the shape + + The current y position of the shape is always relative + to the <em>center</em> of the shape (in contrast to + the Shape::getBounds() and Shape::getUpdateArea() + methods). + */ + void setPosY( const double& rNewY ); + + /** Set the new position of the shape + + The current position of the shape is always relative + to the <em>center</em> of the shape (in contrast to + the Shape::getBounds() and Shape::getUpdateArea() + methods). + */ + void setPosition( const ::basegfx::B2DPoint& rNewPos ); + + /** Query whether the rotation angle attribute is valid + */ + bool isRotationAngleValid() const; + /** Query the current rotation angle of the shape + + @return the rotation angle in degrees. + */ + double getRotationAngle() const; + /** Set the new rotation angle of the shape + + @param rNewAngle + New rotation angle in degrees. + */ + void setRotationAngle( const double& rNewAngle ); + + /** Query whether the shear x angle attribute is valid + */ + bool isShearXAngleValid() const; + /** Query the current shear angle at the x axis of the shape + + @return the shear angle in radians. + */ + double getShearXAngle() const; + /** Set the new shear angle at the x axis of the shape + + @param rNewAngle + New shear angle in radians. + */ + void setShearXAngle( const double& rNewAngle ); + + /** Query whether the shear y angle attribute is valid + */ + bool isShearYAngleValid() const; + /** Query the current shear angle at the y axis of the shape + + @return the shear angle in radians. + */ + double getShearYAngle() const; + /** Set the new shear angle at the y axis of the shape + + @param rNewAngle + New shear angle in radians. + */ + void setShearYAngle( const double& rNewAngle ); + + /** Query whether the alpha attribute is valid + */ + bool isAlphaValid() const; + /** Query the current alpha value of the shape + */ + double getAlpha() const; + /** Set the new alpha value of the shape + + @param rNewValue + New alpha value, must be in the [0,1] range + */ + void setAlpha( const double& rNewValue ); + + /** Query whether the clip attribute is valid + */ + bool isClipValid() const; + /** Query the current clip polygon of the shape + */ + ::basegfx::B2DPolyPolygon getClip() const; + /** Set the new clip polygon of the shape + + @param rNewClip + New clip polygon, is interpreted in shape view coordinates, but + relative to the shape (i.e. the origin of the shape coincides + with the origin of the clip polygon). + */ + void setClip( const ::basegfx::B2DPolyPolygon& rNewClip ); + + /** Query whether the dim color attribute is valid + + The dim color globally 'dims' the shape towards that + color + */ + bool isDimColorValid() const; + /** Get the dim color for the whole shape. + */ + RGBColor getDimColor() const; + /** Set the dim color globally for the whole shape. + */ + void setDimColor( const RGBColor& nNewColor ); + + /** Query whether the fill color attribute is valid + */ + bool isFillColorValid() const; + /** Get the fill color for the whole shape. + + If there's no unique fill color, the color from the + first filled polygon is returned. + */ + RGBColor getFillColor() const; + /** Set the fill color globally for the whole shape. + */ + void setFillColor( const RGBColor& nNewColor ); + + /** Query whether the line color attribute is valid + */ + bool isLineColorValid() const; + /** Get the line color for the whole shape. + + If there's no unique line color, the color from the + first line is returned. + */ + RGBColor getLineColor() const; + /** Set the line color globally for the whole shape. + */ + void setLineColor( const RGBColor& nNewColor ); + + /** Query whether the fill mode attribute is valid + */ + bool isFillStyleValid() const; + /** Get the current fill mode for polygon fillings. + + @returns the current style + */ + sal_Int16 getFillStyle() const; + /** Changes polygon fillings. + */ + void setFillStyle( const sal_Int16& rStyle ); + + /** Query whether the line mode attribute is valid + */ + bool isLineStyleValid() const; + /** Get the current line mode for line drawing. + + @returns the current line style + */ + sal_Int16 getLineStyle() const; + /** Set line style for the whole shape + */ + void setLineStyle( const sal_Int16& rStyle ); + + /** Query whether the visibility state attribute is valid + */ + bool isVisibilityValid() const; + /** Get the current shape visibility. + + @returns true for visible, false for invisible. + */ + bool getVisibility() const; + /** Set the shape visibility + */ + void setVisibility( const bool& bVisible ); + + /** Query whether the char color attribute is valid + */ + bool isCharColorValid() const; + /** Get the text color for the whole shape. + + If there's no unique text color, the color from the + first text drawn is returned. + */ + RGBColor getCharColor() const; + /** Set the text color globally for the whole shape. + */ + void setCharColor( const RGBColor& nNewColor ); + + /** Query whether the char weight attribute is valid + */ + bool isCharWeightValid() const; + /** Get the current char weight value for the whole shape. + + @returns the value for the char weight. The value must + be out of the css::awt::FontWeight + constant group. + */ + double getCharWeight() const; + /** Set the char weight globally for the whole shape. + + The value must be out of the + css::awt::FontWeight constant group. + */ + void setCharWeight( const double& rStyle ); + + /** Query whether the underline mode attribute is valid + */ + bool isUnderlineModeValid() const; + /** Get the current text underline status for the whole shape. + + If there is no unique underline status, false is returned. + + @returns true for underlined text, false for normal. + */ + sal_Int16 getUnderlineMode() const; + /** Set the underline status globally for the whole shape + */ + void setUnderlineMode( const sal_Int16& bUnderline ); + + /** Query whether the font family attribute is valid + */ + bool isFontFamilyValid() const; + /** Get the current text font family for the whole shape. + + If there is no unique font family, the font family of + the first text of the shape is returned. + */ + OUString getFontFamily() const; + /** Set the text font family name globally for the whole shape + */ + void setFontFamily( const OUString& rName ); + + /** Query whether the italic mode attribute is valid + */ + bool isCharPostureValid() const; + /** Get the current text italic style for the whole shape. + + @returns the italic style. The value returned is one + of the css::awt::FontSlant enums + */ + sal_Int16 getCharPosture() const; + /** Set the italic style globally for the whole shape. + + The value must be one of the + css::awt::FontSlant enums. + */ + void setCharPosture( const sal_Int16& rStyle ); + + /** Query whether the char scaling attribute is valid + */ + bool isCharScaleValid() const; + /** Query the current char scaling attribute globally for + the shape. + + The char scaling changes the scale of the whole shape + text (uniformly, i.e. both in x and in y direction). + */ + double getCharScale() const; + /** Set the new char scale globally for the shape + + @param rNewScale + New char scale + */ + void setCharScale( const double& rNewScale ); + + // State change query methods + + + State::StateId getTransformationState() const; + State::StateId getClipState() const; + State::StateId getAlphaState() const; + State::StateId getPositionState() const; + State::StateId getContentState() const; + State::StateId getVisibilityState() const; + + private: + // default copy/assignment operator is okay + // ShapeAttributeLayer(const ShapeAttributeLayer&); + // ShapeAttributeLayer& operator=( const ShapeAttributeLayer& ); + + bool haveChild() const { return static_cast< bool >(mpChild); } + void updateStateIds(); + + template< typename T > T calcValue( const T& rCurrValue, + bool bThisInstanceValid, + bool (ShapeAttributeLayer::*pIsValid)() const, + T (ShapeAttributeLayer::*pGetValue)() const ) const; + + ShapeAttributeLayerSharedPtr mpChild; // may be NULL + + ::basegfx::B2DSize maSize; + ::basegfx::B2DPoint maPosition; + ::basegfx::B2DPolyPolygon maClip; + + OUString maFontFamily; + + double mnRotationAngle; + double mnShearXAngle; + double mnShearYAngle; + double mnAlpha; + double mnCharScale; + double mnCharWeight; + + css::drawing::FillStyle meFillStyle; + css::drawing::LineStyle meLineStyle; + css::awt::FontSlant meCharPosture; + sal_Int16 mnUnderlineMode; + + RGBColor maDimColor; + RGBColor maFillColor; + RGBColor maLineColor; + RGBColor maCharColor; + + State::StateId mnTransformationState; + State::StateId mnClipState; + State::StateId mnAlphaState; + State::StateId mnPositionState; + State::StateId mnContentState; + State::StateId mnVisibilityState; + + sal_Int16 mnAdditiveMode; + + bool mbVisibility : 1; + + bool mbWidthValid : 1; + bool mbHeightValid : 1; + bool mbPosXValid : 1; + bool mbPosYValid : 1; + bool mbClipValid : 1; + + bool mbFontFamilyValid : 1; + + bool mbRotationAngleValid : 1; + bool mbShearXAngleValid : 1; + bool mbShearYAngleValid : 1; + + bool mbAlphaValid : 1; + + bool mbCharScaleValid : 1; + + bool mbDimColorValid : 1; + bool mbFillColorValid : 1; + bool mbLineColorValid : 1; + bool mbCharColorValid : 1; + + bool mbFillStyleValid : 1; + bool mbLineStyleValid : 1; + bool mbCharWeightValid : 1; + bool mbUnderlineModeValid : 1; + bool mbCharPostureValid : 1; + bool mbVisibilityValid : 1; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEATTRIBUTELAYER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shapeattributelayerholder.hxx b/slideshow/source/inc/shapeattributelayerholder.hxx new file mode 100644 index 000000000..4c123b4e5 --- /dev/null +++ b/slideshow/source/inc/shapeattributelayerholder.hxx @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEATTRIBUTELAYERHOLDER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEATTRIBUTELAYERHOLDER_HXX + +#include "attributableshape.hxx" +#include "shapeattributelayer.hxx" + +namespace slideshow::internal + { + /** Holds a ShapeAttributeLayer, together with the associated + Shape + + Use this class to hold ShapeAttributeLayer objects the + RAII way. When this object gets deleted, it will + automatically revoke the attribute layer for the given + shape (this encapsulates the somewhat clumsy notification + process that is required for shape and attribute layer + interaction). + */ + class ShapeAttributeLayerHolder + { + public: + /** Create a ShapeAttributeLayerHolder instance. + + This constructor creates an empty attribute holder, to + generate an attribute layer, you have to manually call + createAttributeLayer(). + */ + ShapeAttributeLayerHolder() : + mpShape(), + mpAttributeLayer() + { + } + + ~ShapeAttributeLayerHolder() + { + reset(); // ensures that the last attribute layer is + // correctly deregistered from the shape. + } + + ShapeAttributeLayerHolder(const ShapeAttributeLayerHolder&) = delete; + ShapeAttributeLayerHolder& operator=(const ShapeAttributeLayerHolder&) = delete; + + void reset() + { + if( mpShape && mpAttributeLayer ) + mpShape->revokeAttributeLayer( mpAttributeLayer ); + } + + /** This constructor receives a pointer to the Shape, from + which attribute layers should be generated. Initially, + this object does not create an attribute layer, you + have to manually call createAttributeLayer(). + + @param rShape + Shape for which attribute layers should be generated. + */ + bool createAttributeLayer( const AttributableShapeSharedPtr& rShape ) + { + reset(); + + mpShape = rShape; + + if( mpShape ) + mpAttributeLayer = mpShape->createAttributeLayer(); + + return static_cast< bool >(mpAttributeLayer); + } + + const ShapeAttributeLayerSharedPtr& get() const + { + return mpAttributeLayer; + } + + private: + AttributableShapeSharedPtr mpShape; + ShapeAttributeLayerSharedPtr mpAttributeLayer; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEATTRIBUTELAYERHOLDER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shapeimporter.hxx b/slideshow/source/inc/shapeimporter.hxx new file mode 100644 index 000000000..5254e0a9f --- /dev/null +++ b/slideshow/source/inc/shapeimporter.hxx @@ -0,0 +1,141 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEIMPORTER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEIMPORTER_HXX + +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/drawing/XLayer.hpp> + +#include <cppcanvas/canvasgraphic.hxx> + +#include "unoview.hxx" + +#include "shape.hxx" + +#include <stack> + +namespace slideshow::internal { + +struct SlideShowContext; + +typedef std::vector< ::cppcanvas::PolyPolygonSharedPtr> PolyPolygonVector; +typedef std::shared_ptr< UnoView > UnoViewSharedPtr; +typedef std::vector< UnoViewSharedPtr > UnoViewVector; + +/** This class imports all shapes from a given XShapes object + */ +class ShapeImporter +{ +public: + /** Create shape importer. + + @param xPage + Page containing the shapes + + @param xActualPage + Actual page that's imported - if xPage is a master + page, this argument must refer to the using, i.e the + page that embeds this specific masterpage. Otherwise, + this argument is probably equal to xPage. + + @param nOrdNumStart + Each shape receives a z order number, in order of + import (which relies on the fact that the API returns + the shapes in draw order - which it does, + currently). Since we might mix several pages on screen + (e.g. master page and foreground page), this value can + be used as an offset to distinguish those pages. + + @param bConvertingMasterPage + When true, then the master page is imported. Otherwise, this + object imports the draw page. + */ + ShapeImporter( const css::uno::Reference< css::drawing::XDrawPage >& xPage, + const css::uno::Reference< css::drawing::XDrawPage >& xActualPage, + const css::uno::Reference< css::drawing::XDrawPagesSupplier>& xPagesSupplier, + const SlideShowContext& rContext, + sal_Int32 nOrdNumStart, + bool bConvertingMasterPage ); + + /** This method imports the presentation background shape + */ + ShapeSharedPtr importBackgroundShape(); // throw (ShapeLoadFailedException) + + /** This method imports presentation-visible shapes (and skips all others). + + @return the generated Shape, or NULL for no more shapes. + */ + ShapeSharedPtr importShape(); // throw (ConversionFailedException) + + /** Test whether import is done. + + @return true, if all shapes are imported via the + importShape() call. + */ + bool isImportDone() const; + const PolyPolygonVector& getPolygons() const; + + double getImportedShapesCount() const{ return mnAscendingPrio; } +private: + bool isSkip( css::uno::Reference<css::beans::XPropertySet> const& xPropSet, + std::u16string_view shapeType, + css::uno::Reference<css::drawing::XLayer> const& xLayer); + + ShapeSharedPtr createShape( + css::uno::Reference<css::drawing::XShape> const& xCurrShape, + css::uno::Reference<css::beans::XPropertySet> const& xPropSet, + std::u16string_view shapeType ) const; + + void importPolygons(css::uno::Reference< css::beans::XPropertySet > const& xPropSet) ; + + struct XShapesEntry + { + ShapeSharedPtr const mpGroupShape; + css::uno::Reference<css::drawing::XShapes> const mxShapes; + sal_Int32 const mnCount; + sal_Int32 mnPos; + + explicit XShapesEntry( ShapeSharedPtr const& pGroupShape ) + : mpGroupShape(pGroupShape), + mxShapes( pGroupShape->getXShape(), + css::uno::UNO_QUERY_THROW ), + mnCount(mxShapes->getCount()), mnPos(0) {} + explicit XShapesEntry( css::uno::Reference< + css::drawing::XShapes> const& xShapes ) + : mpGroupShape(), mxShapes(xShapes), + mnCount(xShapes->getCount()), mnPos(0) {} + }; + + css::uno::Reference<css::drawing::XDrawPage> mxPage; + css::uno::Reference<css::drawing::XDrawPagesSupplier> mxPagesSupplier; + const SlideShowContext& mrContext; + PolyPolygonVector maPolygons; + ::std::stack<XShapesEntry> maShapesStack; + double mnAscendingPrio; + bool mbConvertingMasterPage; +}; + +} // namespace presentation::internal + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shapelistenereventhandler.hxx b/slideshow/source/inc/shapelistenereventhandler.hxx new file mode 100644 index 000000000..f8776e7c9 --- /dev/null +++ b/slideshow/source/inc/shapelistenereventhandler.hxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPELISTENEREVENTHANDLER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPELISTENEREVENTHANDLER_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <memory> + +namespace com::sun::star { + namespace drawing { + class XShape; + } + namespace presentation { + class XShapeEventListener; + } +} + +/* Definition of ShapeListenerEventHandler interface */ + +namespace slideshow::internal + { + + /** Interface for handling view events. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle view events. + */ + class ShapeListenerEventHandler + { + public: + virtual ~ShapeListenerEventHandler() {} + + virtual bool listenerAdded( const css::uno::Reference<css::drawing::XShape>& xShape ) = 0; + + virtual bool listenerRemoved( const css::uno::Reference<css::drawing::XShape>& xShape ) = 0; + }; + + typedef ::std::shared_ptr< ShapeListenerEventHandler > ShapeListenerEventHandlerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SHAPELISTENEREVENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shapemanager.hxx b/slideshow/source/inc/shapemanager.hxx new file mode 100644 index 000000000..28c89087d --- /dev/null +++ b/slideshow/source/inc/shapemanager.hxx @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEMANAGER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEMANAGER_HXX + +#include "disposable.hxx" +#include <com/sun/star/uno/Reference.hxx> +#include <memory> +#include <unordered_map> +#include "tools.hxx" + +namespace com::sun::star::drawing { class XShape; } + +/* Definition of ShapeManager interface */ + +namespace slideshow::internal + { + class HyperlinkArea; + class AnimatableShape; + class Shape; + typedef std::unordered_map< + css::uno::Reference< css::drawing::XShape >, + ShapeSharedPtr, + hash< css::uno::Reference< css::drawing::XShape > > + > XShapeToShapeMap; + typedef ::std::shared_ptr< AnimatableShape > AnimatableShapeSharedPtr; + typedef ::std::shared_ptr< Shape > ShapeSharedPtr; + typedef std::shared_ptr< HyperlinkArea > HyperlinkAreaSharedPtr; + + /** ShapeManager interface + + Implementers of this interface manage appearance and + animation of slideshow shapes. + */ + class ShapeManager : public Disposable + { + public: + /** Notify the ShapeManager that the given Shape starts an + animation now. + + This method enters animation mode for the Shape. If + the shape is already in animation mode, the call is + counted, and the shape only leaves animation mode + after a corresponding number of leaveAnimationMode() + calls. + */ + virtual void enterAnimationMode( const AnimatableShapeSharedPtr& rShape ) = 0; + + /** Notify the ShapeManager that the given Shape is no + longer animated. + + When called a corresponding number of times as + enterAnimationMode() for a given shape, this methods + ends animation mode for the given Shape. It is illegal + to call this method more often than + enterAnimationMode(). + */ + virtual void leaveAnimationMode( const AnimatableShapeSharedPtr& rShape ) = 0; + + /** Notify that a shape needs an update + + This method notifies the ShapeManager that a shape + update is necessary. Use this if e.g. a running + animation changed the shape appearance. + + @param rShape + Shape which needs an update + */ + virtual void notifyShapeUpdate( const ShapeSharedPtr& rShape ) = 0; + + /** Lookup a Shape from an XShape model object + + This method looks up the internal shape map for one + representing the given XShape. + + @param xShape + The XShape object, for which the representing Shape + should be looked up. + */ + virtual ShapeSharedPtr lookupShape( + css::uno::Reference< css::drawing::XShape > const & xShape ) const = 0; + + /** Get a map that maps all Shapes with their XShape reference as the key + * + * @return an unordered map that contains all shapes in the + * current page with their XShape reference as the key + */ + virtual const XShapeToShapeMap& getXShapeToShapeMap() const = 0; + + /** Register given shape as a hyperlink target + + @param rArea + Hyperlink sensitive area. Will participate in + hyperlink region lookup. Must be in absolute user + space coordinates. + */ + virtual void addHyperlinkArea( const HyperlinkAreaSharedPtr& rArea ) = 0; + }; + + typedef ::std::shared_ptr< ShapeManager > ShapeManagerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEMANAGER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shapemaps.hxx b/slideshow/source/inc/shapemaps.hxx new file mode 100644 index 000000000..cb5ba0950 --- /dev/null +++ b/slideshow/source/inc/shapemaps.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEMAPS_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEMAPS_HXX + +#include <comphelper/interfacecontainer3.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/presentation/XShapeEventListener.hpp> + +#include <memory> +#include <map> + +namespace com::sun::star::drawing { class XShape; } + +/* Definition of two shape maps */ + +namespace slideshow::internal + { + /// Maps XShape to shape listener + typedef ::std::map< css::uno::Reference< css::drawing::XShape>, + std::shared_ptr< ::comphelper::OInterfaceContainerHelper3<css::presentation::XShapeEventListener> > + > ShapeEventListenerMap; + + /// Maps XShape to mouse cursor + typedef ::std::map< css::uno::Reference< css::drawing::XShape>, + sal_Int16> ShapeCursorMap; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SHAPEMAPS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/shapesubset.hxx b/slideshow/source/inc/shapesubset.hxx new file mode 100644 index 000000000..ad420ef55 --- /dev/null +++ b/slideshow/source/inc/shapesubset.hxx @@ -0,0 +1,145 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SHAPESUBSET_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SHAPESUBSET_HXX + +#include "subsettableshapemanager.hxx" +#include "doctreenode.hxx" + +#include <memory> + +namespace slideshow::internal + { + class ShapeSubset; + typedef ::std::shared_ptr< ShapeSubset > ShapeSubsetSharedPtr; + + /* Definition of ShapeSubset class */ + + /** Subset RAII wrapper for shapes. + + This class wraps the plain Shape with a wrapper for subset + functionality. Subsetting can be turned on and off. Note + that the reason to have shape subsetting RAII implemented + separately (i.e. not within the DrawShape) was that + subsetting (and de-subsetting) needs the + SubsettableShapeManager. And holding that at the DrawShape + creates one heck of a circular reference. + */ + class ShapeSubset + { + public: + /** Create a subset directly from a Shape. + + @param rOriginalShape + Original shape to subset + + @param rTreeNode + Subset this object should represent + + @param rShapeManager + Manager object, where subsets are + registered/unregistered + */ + ShapeSubset( const AttributableShapeSharedPtr& rOriginalShape, + const DocTreeNode& rTreeNode, + const SubsettableShapeManagerSharedPtr& rSubsetManager ); + + /** Create a subset from another subset. + + Note: if you want this subset to subtract from the + passed subset reference (and not from the original, + unsubsetted shape), the passed subset must be enabled + (enableSubsetShape() must have been called) + + @param rOriginalSubset + Original subset, which to subset again. + + @param rTreeNode + Subset of the original subset + */ + ShapeSubset( const ShapeSubsetSharedPtr& rOriginalSubset, + const DocTreeNode& rTreeNode ); + + /** Create full set for the given shape. + + @param rOriginalShape + Original shape, which will be represented as a whole + by this object + */ + ShapeSubset( const AttributableShapeSharedPtr& rOriginalShape, + const SubsettableShapeManagerSharedPtr& rShapeManager ); + + ~ShapeSubset(); + + // For a rationale for this hacky combination of user-provided dtor, defaulted copy + // ctor, and deleted copy assignment op, see the "TODO(Q1)" comment in + // CloningNodeCreator (slideshow/source/engine/animationnodes/animationnodefactory.cxx): + ShapeSubset(ShapeSubset const &) = default; + void operator =(ShapeSubset const &) = delete; + + /** Get the actual subset shape. + + If the subset is currently revoked, this method + returns the original shape. + */ + AttributableShapeSharedPtr const & getSubsetShape() const; + + /** Enable the subset shape. + + This method enables the subset. That means, on + successful completion of this method, the original + shape will cease to show the subset range, and + getSubsetShape() will return a valid shape. + */ + void enableSubsetShape(); + + /** Disable the subset shape. + + This method revokes the subset from the original + shape. That means, the original shape will again show + the hidden range. + */ + void disableSubsetShape(); + + /** Query whether this subset actually is none, but + contains the whole original shape's content + */ + bool isFullSet() const; + + /** Query subset this object represents + */ + const DocTreeNode& getSubset() const; + + private: + // default copy/assignment are okay + //ShapeSubset(const ShapeSubset&); + //ShapeSubset& operator=( const ShapeSubset& ); + + AttributableShapeSharedPtr mpOriginalShape; + AttributableShapeSharedPtr mpSubsetShape; + DocTreeNode maTreeNode; + SubsettableShapeManagerSharedPtr mpShapeManager; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SHAPESUBSET_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/slide.hxx b/slideshow/source/inc/slide.hxx new file mode 100644 index 000000000..ea460582d --- /dev/null +++ b/slideshow/source/inc/slide.hxx @@ -0,0 +1,210 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SLIDE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SLIDE_HXX + +#include "unoviewcontainer.hxx" +#include "slidebitmap.hxx" +#include "shapemaps.hxx" + +#include <memory> + +namespace com::sun::star { + namespace drawing { + class XDrawPage; + class XDrawPagesSupplier; + } + namespace uno { + class XComponentContext; + } + namespace animations { + class XAnimationNode; + } +} + +namespace basegfx +{ + class B2IVector; +} + +/* Definition of Slide interface */ + +namespace slideshow::internal + { + class RGBColor; + class ScreenUpdater; + typedef ::std::vector< ::cppcanvas::PolyPolygonSharedPtr> PolyPolygonVector; + class Slide + { + public: + // Showing + + + /** Prepares to show slide. + + Call this method to reduce the timeout show(), and + getInitialSlideBitmap() need to complete. If + prefetch() is not called explicitly, the named + methods will call it implicitly. + */ + virtual void prefetch() = 0; + + /** Shows the slide on all registered views + + After this call, the slide will render itself to the + views, and start its animations. + + @param bSlideBackgroundPainted + When true, the initial slide content on the background + layer is already rendered (e.g. from a previous slide + transition). When false, Slide renders initial content of + slide. + */ + virtual void show( bool bSlideBackgroundPainted ) = 0; + + /** Force-ends the slide + + After this call, the slide has stopped all animations, + and ceased rendering/visualization on all views. + */ + virtual void hide() = 0; + + + // Queries + + + /** Query the size of this slide in user coordinates + + This value is retrieved from the XDrawPage properties. + */ + virtual basegfx::B2ISize getSlideSize() const = 0; + + /// Gets the underlying API page + virtual css::uno::Reference< css::drawing::XDrawPage > getXDrawPage() const = 0; + + /// Gets the animation node. + virtual css::uno::Reference< css::animations::XAnimationNode > getXAnimationNode() const = 0; + + ///Gets the slide Polygons + virtual PolyPolygonVector getPolygons() = 0; + + ///Draw the slide Polygons + virtual void drawPolygons() const = 0; + + ///Check if paint overlay is already active + virtual bool isPaintOverlayActive() const = 0; + + virtual void enablePaintOverlay() = 0; + + virtual void update_settings( bool bUserPaintEnabled, RGBColor const& aUserPaintColor, double dUserPaintStrokeWidth ) = 0; + + // Slide bitmaps + + + /** Request bitmap for current slide appearance. + + The bitmap returned by this method depends on the + current state of the slide and the contained + animations. A newly generated slide will return the + initial slide content here (e.g. with all 'appear' + effect shapes invisible), a slide whose effects are + currently running will return a bitmap corresponding + to the current position on the animation timeline, and + a slide whose effects have all been run will generate + a bitmap with the final slide appearance (e.g. with + all 'hide' effect shapes invisible). + + @param rView + View to retrieve bitmap for (note that the bitmap will + have device-pixel equivalence to the content that + would have been rendered onto the given view). Note + that the view must have been added to this slide + before via viewAdded(). + */ + virtual SlideBitmapSharedPtr + getCurrentSlideBitmap( const UnoViewSharedPtr& rView ) const = 0; + + protected: + ~Slide() {} + }; + + typedef ::std::shared_ptr< Slide > SlideSharedPtr; + + class EventQueue; + class CursorManager; + class MediaFileManager; + class EventMultiplexer; + class ActivitiesQueue; + class UserEventQueue; + class RGBColor; + + /** Construct from XDrawPage + + The Slide object generally works in XDrawPage model + coordinates, that is, the page will have the width and + height as specified in the XDrawPage's property + set. The top, left corner of the page will be rendered + at (0,0) in the given canvas' view coordinate system. + + Does not render anything initially + + @param xDrawPage + Page to display on this slide + + @param xRootNode + Root of the SMIL animation tree. Used to animate the slide. + + @param rEventQueue + EventQueue. Used to post events. + + @param rActivitiesQueue + ActivitiesQueue. Used to run animations. + + @param rEventMultiplexer + Event source + + @param rUserEventQueue + UserEeventQueue + */ + SlideSharedPtr createSlide( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage, + const css::uno::Reference< css::drawing::XDrawPagesSupplier >& xDrawPages, + const css::uno::Reference< css::animations::XAnimationNode >& xRootNode, + EventQueue& rEventQueue, + EventMultiplexer& rEventMultiplexer, + ScreenUpdater& rScreenUpdater, + ActivitiesQueue& rActivitiesQueue, + UserEventQueue& rUserEventQueue, + CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, + const UnoViewContainer& rViewContainer, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const ShapeEventListenerMap& rShapeListenerMap, + const ShapeCursorMap& rShapeCursorMap, + PolyPolygonVector&& rPolyPolygonVector, + RGBColor const& aUserPaintColor, + double dUserPaintStrokeWidth, + bool bUserPaintEnabled, + bool bIntrinsicAnimationsAllowed, + bool bDisableAnimationZOrder ); +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SLIDE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/slidebitmap.hxx b/slideshow/source/inc/slidebitmap.hxx new file mode 100644 index 000000000..ef3b41f2e --- /dev/null +++ b/slideshow/source/inc/slidebitmap.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SLIDEBITMAP_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SLIDEBITMAP_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <cppcanvas/canvas.hxx> +#include <cppcanvas/bitmap.hxx> + +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> + +#include <memory> + +namespace com::sun::star::rendering { class XBitmap; } + + +/* Definition of SlideBitmap class */ + +namespace slideshow::internal + { + + /** Little wrapper encapsulating an XBitmap + + This is to insulate us from changes to the preferred + transport format for bitmaps (using a sole XBitmap here is + a hack, since it is not guaranteed to work, or to work + without data loss, across different canvases). And since + we don't want to revert to a VCL Bitmap here, have to wait + until basegfx bitmap tooling is ready. + + TODO(F2): Add support for Canvas-independent bitmaps + here. Then, Slide::getInitialSlideBitmap and + Slide::getFinalSlideBitmap must also be adapted (they no + longer need a Canvas ptr, which is actually a hack now). + */ + class SlideBitmap + { + public: + explicit SlideBitmap( const ::cppcanvas::BitmapSharedPtr& rBitmap ); + SlideBitmap(const SlideBitmap&) = delete; + SlideBitmap& operator=(const SlideBitmap&) = delete; + + bool draw( const ::cppcanvas::CanvasSharedPtr& rCanvas ) const; + ::basegfx::B2ISize getSize() const; + void move( const ::basegfx::B2DPoint& rNewPos ); + void clip( const ::basegfx::B2DPolyPolygon& rClipPoly ); + + const css::uno::Reference< css::rendering::XBitmap >& getXBitmap() const; + + private: + ::basegfx::B2DPoint maOutputPos; + ::basegfx::B2DPolyPolygon maClipPoly; + + // TODO(Q2): Remove UNO bitmap as the transport medium + css::uno::Reference< css::rendering::XBitmap > mxBitmap; + }; + + typedef ::std::shared_ptr< SlideBitmap > SlideBitmapSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SLIDEBITMAP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/slideshowcontext.hxx b/slideshow/source/inc/slideshowcontext.hxx new file mode 100644 index 000000000..565f0ff41 --- /dev/null +++ b/slideshow/source/inc/slideshowcontext.hxx @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SLIDESHOWCONTEXT_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SLIDESHOWCONTEXT_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <memory> + +namespace com::sun::star::uno { class XComponentContext; } +namespace box2d::utils { class box2DWorld; + typedef ::std::shared_ptr< box2DWorld > Box2DWorldSharedPtr; } + + + +namespace slideshow::internal + { + class ShapeManager; + class EventQueue; + class ActivitiesQueue; + class UserEventQueue; + class EventMultiplexer; + class ScreenUpdater; + class UnoViewContainer; + class CursorManager; + class MediaFileManager; + class SubsettableShapeManager; + typedef ::std::shared_ptr< SubsettableShapeManager > SubsettableShapeManagerSharedPtr; + + /** Common arguments for slideshow objects. + + This struct combines a number of object references + ubiquitously needed throughout the slideshow. + */ + struct SlideShowContext + { + /** Common context for node creation + + @param rShapeManager + ShapeManager, which handles all shapes + + @param rEventQueue + Event queue, where time-based events are to be + scheduled. A node must not schedule events there + before it's not resolved. + + @param rEventMultiplexer + Event multiplexer. Clients can register there for + about any event that happens in the slideshow + + @param rScreenUpdater + Screen updater. Gets notified of necessary screen + updates. + + @param rActivitiesQueue + Activities queue, where repeating activities are + to be scheduled. + + @param rMediaFileManager + To handle media file with package urls. + + @param rUserEventQueue + User event queue + + @param rViewContainer + Holds all views added to slideshow + + @param rComponentContext + To create UNO services from + */ + SlideShowContext( SubsettableShapeManagerSharedPtr& rSubsettableShapeManager, + EventQueue& rEventQueue, + EventMultiplexer& rEventMultiplexer, + ScreenUpdater& rScreenUpdater, + ActivitiesQueue& rActivitiesQueue, + UserEventQueue& rUserEventQueue, + CursorManager& rCursorManager, + MediaFileManager& rMediaFileManager, + const UnoViewContainer& rViewContainer, + const css::uno::Reference< css::uno::XComponentContext>& rComponentContext, + box2d::utils::Box2DWorldSharedPtr& rBox2DWorldPtr ); + void dispose(); + + std::shared_ptr<SubsettableShapeManager>& mpSubsettableShapeManager; + EventQueue& mrEventQueue; + EventMultiplexer& mrEventMultiplexer; + ScreenUpdater& mrScreenUpdater; + ActivitiesQueue& mrActivitiesQueue; + UserEventQueue& mrUserEventQueue; + CursorManager& mrCursorManager; + MediaFileManager& mrMediaFileManager; + const UnoViewContainer& mrViewContainer; + css::uno::Reference< css::uno::XComponentContext> mxComponentContext; + box2d::utils::Box2DWorldSharedPtr& mpBox2DWorld; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SLIDESHOWCONTEXT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/slideshowdllapi.h b/slideshow/source/inc/slideshowdllapi.h new file mode 100644 index 000000000..048a83dd2 --- /dev/null +++ b/slideshow/source/inc/slideshowdllapi.h @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/types.h> + +#if defined(SLIDESHOW_DLLIMPLEMENTATION) +#define SLIDESHOW_DLLPUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define SLIDESHOW_DLLPUBLIC SAL_DLLPUBLIC_IMPORT +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/slideshowexceptions.hxx b/slideshow/source/inc/slideshowexceptions.hxx new file mode 100644 index 000000000..58ce41bf6 --- /dev/null +++ b/slideshow/source/inc/slideshowexceptions.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SLIDESHOWEXCEPTIONS_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SLIDESHOWEXCEPTIONS_HXX + + +namespace slideshow +{ + class SlideShowException {}; + + /** This exception is thrown, when the Shape class was not + able to convert an API object into our internal + representation. + */ + struct ShapeLoadFailedException : public SlideShowException {}; + + /** This exception is thrown, when the SMIL arithmetic expression + parser failed to parse a string. + */ + struct ParseError : public SlideShowException + { + ParseError() {} + explicit ParseError( const char* ) {} + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SLIDESHOWEXCEPTIONS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/slideview.hxx b/slideshow/source/inc/slideview.hxx new file mode 100644 index 000000000..bf95dc251 --- /dev/null +++ b/slideshow/source/inc/slideview.hxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SLIDEVIEW_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SLIDEVIEW_HXX + +#include "unoview.hxx" + +/* Definition of SlideView factory method */ +namespace slideshow::internal + { + class EventQueue; + class EventMultiplexer; + + /** Factory for SlideView + + @param xView + UNO slide view this object should encapsulate + + @param rEventQueue + Global event queue, to be used for notification + messages. + + @param rViewChangeFunc + Functor to call, when the UNO view signals a repaint. + */ + UnoViewSharedPtr createSlideView( + css::uno::Reference< css::presentation::XSlideShowView> const& xView, + EventQueue& rEventQueue, + EventMultiplexer& rEventMultiplexer ); +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SLIDEVIEW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/smilfunctionparser.hxx b/slideshow/source/inc/smilfunctionparser.hxx new file mode 100644 index 000000000..d2ef96abf --- /dev/null +++ b/slideshow/source/inc/smilfunctionparser.hxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SMILFUNCTIONPARSER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SMILFUNCTIONPARSER_HXX + +#include "expressionnode.hxx" + +#include <basegfx/range/b2drectangle.hxx> +#include <rtl/ustring.hxx> + +#include <memory> + + +/* Definition of SmilFunctionParser class */ + +namespace slideshow::internal + { + class SmilFunctionParser + { + public: + SmilFunctionParser() = delete; + SmilFunctionParser(const SmilFunctionParser&) = delete; + SmilFunctionParser& operator=(const SmilFunctionParser&) = delete; + + /** Parse a string containing a SMIL value. + + This method parses a string representing + a fixed value (i.e. a value that does not + change by time). Due to the dynamic view + capabilities of the presentation engine, + this value can sometimes only be determined + during runtime of the animation (because + e.g. mixed screen/view coordinates are + involved), and is thus still returned as an + ExpressionNode object. An example for + such a case is the "Width+1.0" string, which + contains the width of the shape in user + coordinate space, and the screen width + in device coordinate space. + + The following grammar is accepted by this method: + <code> + identifier = 'pi'|'e'|'X'|'Y'|'Width'|'Height' + + function = 'abs'|'sqrt'|'sin'|'cos'|'tan'|'atan'|'acos'|'asin'|'exp'|'log' + + basic_expression = + number | + identifier | + function '(' additive_expression ')' | + '(' additive_expression ')' + + unary_expression = + '-' basic_expression | + basic_expression + + multiplicative_expression = + unary_expression ( ( '*' unary_expression )* | + ( '/' unary_expression )* ) + + additive_expression = + multiplicative_expression ( ( '+' multiplicative_expression )* | + ( '-' multiplicative_expression )* ) + + </code> + + @param rSmilValue + The string to parse + + @param rRelativeShapeBounds + The bounds of the shape this SMIL value is to be + evaluated for. The bounds must be <em>relative</em> to + the page the shape is part of, i.e. within the [0,1] + range. This is necessary, since the string might + contain symbolic references to the shape bounding box. + + @throws ParseError if an invalid expression is given. + + @return the generated function object. + */ + static std::shared_ptr<ExpressionNode> const & parseSmilValue( const OUString& rSmilValue, + const ::basegfx::B2DRectangle& rRelativeShapeBounds ); // throw ParseError + + /** Parse a string containing a SMIL function. + + This method parses a string representing + a possibly time-varying SMIL function. + + The following grammar is accepted by this method: + <code> + identifier = 't'|'pi'|'e'|'X'|'Y'|'Width'|'Height' + + function = 'abs'|'sqrt'|'sin'|'cos'|'tan'|'atan'|'acos'|'asin'|'exp'|'log' + + basic_expression = + number | + identifier | + function '(' additive_expression ')' | + '(' additive_expression ')' + + unary_expression = + '-' basic_expression | + basic_expression + + multiplicative_expression = + unary_expression ( ( '*' unary_expression )* | + ( '/' unary_expression )* ) + + additive_expression = + multiplicative_expression ( ( '+' multiplicative_expression )* | + ( '-' multiplicative_expression )* ) + + </code> + + @param rSmilFunction + The string to parse + + @param rRelativeShapeBounds + The bounds of the shape this SMIL value is to be + evaluated for. The bounds must be <em>relative</em> to + the page the shape is part of, i.e. within the [0,1] + range. This is necessary, since the string might + contain symbolic references to the shape bounding box. + + @throws ParseError if an invalid expression is given. + + @return the generated function object. + */ + static std::shared_ptr<ExpressionNode> const & parseSmilFunction( const OUString& rSmilFunction, + const ::basegfx::B2DRectangle& rRelativeShapeBounds ); // throw ParseError + + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SMILFUNCTIONPARSER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/soundplayer.hxx b/slideshow/source/inc/soundplayer.hxx new file mode 100644 index 000000000..3914a08a2 --- /dev/null +++ b/slideshow/source/inc/soundplayer.hxx @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SOUNDPLAYER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SOUNDPLAYER_HXX + +#include <rtl/ustring.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/media/XPlayer.hpp> +#include <avmedia/mediaitem.hxx> + +#include <memory> + +#include "pauseeventhandler.hxx" +#include "disposable.hxx" +#include "eventmultiplexer.hxx" + + +/* Definition of SoundPlayer class */ + +namespace slideshow::internal + { + class MediaFileManager; + + /** Little class that plays a sound from a URL. + TODO: + Must be explicitly disposed (as long as enable_shared_ptr_from_this + isn't available)! + */ + class SoundPlayer : public PauseEventHandler, + public Disposable + { + public: + /** Create a sound player object. + + @param rSoundURL + URL to a sound file. + + @param rComponentContext + Reference to a component context, used to create the + needed services + + @throws css::lang::NoSupportException, if + the sound file is invalid, or not supported by the + player service. + */ + static ::std::shared_ptr<SoundPlayer> create( + EventMultiplexer & rEventMultiplexer, + const OUString& rSoundURL, + const css::uno::Reference< css::uno::XComponentContext>& rComponentContext, + MediaFileManager& rMediaFileManager); + + virtual ~SoundPlayer() override; + + /** Query duration of sound playback. + + If the sound is already playing, this method + returns the remaining playback time. + + @return the playback duration in seconds. + */ + double getDuration() const; + + bool startPlayback(); + bool stopPlayback(); + bool isPlaying() const; + + void setPlaybackLoop( bool bLoop ); + + // PauseEventHandler: + virtual bool handlePause( bool bPauseShow ) override; + + // Disposable + virtual void dispose() override; + + private: + SoundPlayer( + EventMultiplexer & rEventMultiplexer, + const OUString& rSoundURL, + const css::uno::Reference< css::uno::XComponentContext>& rComponentContext, + MediaFileManager & rMediaFileManager); + + EventMultiplexer & mrEventMultiplexer; + // TODO(Q3): obsolete when boost::enable_shared_ptr_from_this + // is available + ::std::shared_ptr<SoundPlayer> mThis; + // Temp file for package url. + ::std::shared_ptr<::avmedia::MediaTempFile> mpMediaTempFile; + css::uno::Reference< css::media::XPlayer > mxPlayer; + }; + + typedef ::std::shared_ptr< SoundPlayer > SoundPlayerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SOUNDPLAYER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/stringanimation.hxx b/slideshow/source/inc/stringanimation.hxx new file mode 100644 index 000000000..09a8f859e --- /dev/null +++ b/slideshow/source/inc/stringanimation.hxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_STRINGANIMATION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_STRINGANIMATION_HXX + +#include "animation.hxx" +#include <rtl/ustring.hxx> + + +/* Definition of StringAnimation interface */ + +namespace slideshow::internal + { + /** Interface defining a string animation. + + This interface is a specialization of the Animation + interface, and is used to animate attributes representable + by a discrete character string (e.g. font names) + */ + class StringAnimation : public Animation + { + public: + typedef OUString ValueType; + + /** Set the animation to value rStr + + @param rStr + Current animation value. + */ + virtual bool operator()( const ValueType& rStr ) = 0; + + /** Request the underlying value for this animation. + + This is necessary for pure To or By animations, as the + Activity cannot determine a sensible start value + otherwise. + + @attention Note that you are only permitted to query + for the underlying value, if the animation has actually + been started (via start() call). + */ + virtual ValueType getUnderlyingValue() const = 0; + }; + + typedef ::std::shared_ptr< StringAnimation > StringAnimationSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_STRINGANIMATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/subsettableshapemanager.hxx b/slideshow/source/inc/subsettableshapemanager.hxx new file mode 100644 index 000000000..9279bf017 --- /dev/null +++ b/slideshow/source/inc/subsettableshapemanager.hxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_SUBSETTABLESHAPEMANAGER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_SUBSETTABLESHAPEMANAGER_HXX + +#include "shapemanager.hxx" +#include "intrinsicanimationeventhandler.hxx" +#include <memory> + +/* Definition of SubsettableShapeManager interface */ + +namespace slideshow::internal + { + class DocTreeNode; + class AttributableShape; + typedef ::std::shared_ptr< AttributableShape > AttributableShapeSharedPtr; + + /** SubsettableShapeManager interface + + Implementers of this interface manage creation and + revocation of shape subsets. Shape subsets are shapes that + represent (and animate) only parts of an original's shape + content. + */ + class SubsettableShapeManager : public ShapeManager + { + public: + /** Query a subset of the given original shape + + This method queries a new (but not necessarily unique) + shape, which displays only the given subset of the + original one. Calling this method multiple times with + the same original shape and DocTreeNode content always + returns the same shape. + + Requesting a subset from an original shape leads to + the original shape ceasing to display the subsetted + content. In other words, shape content is always + displayed in exactly one shape. + + @param rOrigShape + The shape the subset is to be created for + + @param rSubsetShape + The subset to display in the generated shape. + */ + virtual AttributableShapeSharedPtr getSubsetShape( + const AttributableShapeSharedPtr& rOrigShape, + const DocTreeNode& rTreeNode ) = 0; + + /** Revoke a previously queried subset shape. + + With this method, a previously requested subset shape + is revoked again. If the last client revokes a given + subset, it will cease to be displayed, and the + original shape will again show the subset data. + + @param rOrigShape + The shape the subset was created from + + @param rSubsetShape + The subset created from rOrigShape + */ + virtual void revokeSubset( + const AttributableShapeSharedPtr& rOrigShape, + const AttributableShapeSharedPtr& rSubsetShape ) = 0; + + // Evil hackish way of getting intrinsic animation slide-wise + + /** Register an event handler that will be called when + user paint parameters change. + + @param rHandler + Handler to call when a shape listener changes + */ + virtual void addIntrinsicAnimationHandler( const IntrinsicAnimationEventHandlerSharedPtr& rHandler ) = 0; + virtual void removeIntrinsicAnimationHandler( const IntrinsicAnimationEventHandlerSharedPtr& rHandler ) = 0; + + /** Notify that shape-intrinsic animations are now enabled. + */ + virtual void notifyIntrinsicAnimationsEnabled() = 0; + + /** Notify that shape-intrinsic animations are now disabled. + */ + virtual void notifyIntrinsicAnimationsDisabled() = 0; + }; + + typedef ::std::shared_ptr< SubsettableShapeManager > SubsettableShapeManagerSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_SUBSETTABLESHAPEMANAGER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/tools.hxx b/slideshow/source/inc/tools.hxx new file mode 100644 index 000000000..edfefe246 --- /dev/null +++ b/slideshow/source/inc/tools.hxx @@ -0,0 +1,396 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_TOOLS_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_TOOLS_HXX + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/animations/XAnimationNode.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> +#include <comphelper/random.hxx> +#include <sal/log.hxx> + +#include <cppcanvas/color.hxx> + +#include "shapeattributelayer.hxx" +#include "shape.hxx" +#include "rgbcolor.hxx" +#include "hslcolor.hxx" + +#include <memory> + +namespace com::sun::star::beans { struct NamedValue; } +namespace basegfx +{ + class B2DRange; + class B2DVector; + class B2IVector; + class B2DHomMatrix; + typedef B2IVector B2ISize; +} +namespace cppcanvas{ class Canvas; } + +class GDIMetaFile; + +/* Definition of some animation tools */ +namespace slideshow +{ + namespace internal + { + class UnoView; + class Shape; + class ShapeAttributeLayer; + typedef std::shared_ptr< UnoView > UnoViewSharedPtr; + typedef std::shared_ptr< GDIMetaFile > GDIMetaFileSharedPtr; + + template <typename T> + inline ::std::size_t hash_value( T const * p ) + { + ::std::size_t d = static_cast< ::std::size_t >( + reinterpret_cast< ::std::ptrdiff_t >(p) ); + return d + (d >> 3); + } + + template <typename T> + struct hash + { + ::std::size_t operator()( T const& val ) const { + return hash_value(val); + } + }; + } +} + +namespace com::sun::star::uno { + + template <typename T> + inline ::std::size_t hash_value( + css::uno::Reference<T> const& x ) + { + // normalize to object root, because _only_ XInterface is defined + // to be stable during object lifetime: + css::uno::Reference< css::uno::XInterface> const xRoot( x, css::uno::UNO_QUERY ); + return slideshow::internal::hash<void *>()(xRoot.get()); + } + +} + +namespace slideshow +{ + namespace internal + { + // Value extraction from Any + // ========================= + + /// extract unary double value from Any + bool extractValue( double& o_rValue, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /// extract int from Any + bool extractValue( sal_Int32& o_rValue, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /// extract enum/constant group value from Any + bool extractValue( sal_Int16& o_rValue, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /// extract color value from Any + bool extractValue( RGBColor& o_rValue, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /// extract color value from Any + bool extractValue( HSLColor& o_rValue, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /// extract plain string from Any + bool extractValue( OUString& o_rValue, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /// extract bool value from Any + bool extractValue( bool& o_rValue, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /// extract double 2-tuple from Any + bool extractValue( basegfx::B2DTuple& o_rPair, + const css::uno::Any& rSourceAny, + const ShapeSharedPtr& rShape, + const basegfx::B2DVector& rSlideBounds ); + + /** Search a sequence of NamedValues for a given element. + + @return true, if the sequence contains the specified + element. + */ + bool findNamedValue( css::uno::Sequence< css::beans::NamedValue > const& rSequence, + const css::beans::NamedValue& rSearchKey ); + + basegfx::B2DRange calcRelativeShapeBounds( const basegfx::B2DVector& rPageSize, + const basegfx::B2DRange& rShapeBounds ); + + /** Get the shape transformation from the attribute set + + @param rBounds + Original shape bound rect (to substitute default attribute + layer values) + + @param pAttr + Attribute set. Might be NULL (then, rBounds is used to set + a simple scale and translate of the unit rect to rBounds). + */ + basegfx::B2DHomMatrix getShapeTransformation( + const basegfx::B2DRectangle& rBounds, + const ShapeAttributeLayerSharedPtr& pAttr ); + + /** Get a shape's sprite transformation from the attribute set + + @param rPixelSize + Pixel size of the sprite + + @param rOrigSize + Original shape size (i.e. the size of the actual sprite + content, in the user coordinate system) + + @param pAttr + Attribute set. Might be NULL (then, rBounds is used to set + a simple scale and translate of the unit rect to rBounds). + + @return the transformation to be applied to the sprite. + */ + basegfx::B2DHomMatrix getSpriteTransformation( + const basegfx::B2DVector& rPixelSize, + const basegfx::B2DVector& rOrigSize, + const ShapeAttributeLayerSharedPtr& pAttr ); + + /** Calc update area for a shape. + + This method calculates the 'covered' area for the shape, + i.e. the rectangle that is affected when rendering the + shape. Apart from applying the given transformation to the + shape rectangle, this method also takes attributes into + account, which further scale the output (e.g. character + sizes). + + @param rUnitBounds + Shape bounds, in the unit rect coordinate space + + @param rShapeTransform + Transformation matrix the shape should undergo. + + @param pAttr + Current shape attributes + */ + basegfx::B2DRectangle getShapeUpdateArea( + const basegfx::B2DRectangle& rUnitBounds, + const basegfx::B2DHomMatrix& rShapeTransform, + const ShapeAttributeLayerSharedPtr& pAttr ); + + /** Calc update area for a shape. + + This method calculates the 'covered' area for the shape, + i.e. the rectangle that is affected when rendering the + shape. The difference from the other getShapeUpdateArea() + method is the fact that this one works without + ShapeAttributeLayer, and only scales up the given shape + user coordinate bound rect. The method is typically used + to retrieve user coordinate system bound rects for shapes + which are smaller than the default unit bound rect + (because e.g. of subsetting) + + @param rUnitBounds + Shape bounds, in the unit rect coordinate space + + @param rShapeBounds + Current shape bounding box in user coordinate space. + */ + basegfx::B2DRange getShapeUpdateArea( const basegfx::B2DRange& rUnitBounds, + const basegfx::B2DRange& rShapeBounds ); + + /** Calc output position and size of shape, according to given + attribute layer. + + Rotations, shears etc. and not taken into account, + i.e. the returned rectangle is NOT the bounding box. Use + it as if aBounds.getMinimum() is the output position and + aBounds.getRange() the scaling of the shape. + */ + basegfx::B2DRectangle getShapePosSize( + const basegfx::B2DRectangle& rOrigBounds, + const ShapeAttributeLayerSharedPtr& pAttr ); + + /** Convert a plain UNO API 32 bit int to RGBColor + */ + RGBColor unoColor2RGBColor( sal_Int32 ); + /** Convert an IntSRGBA to plain UNO API 32 bit int + */ + sal_Int32 RGBAColor2UnoColor( cppcanvas::IntSRGBA ); + + /** Fill a plain rectangle on the given canvas with the given color + */ + void fillRect( const cppcanvas::CanvasSharedPtr& rCanvas, + const basegfx::B2DRectangle& rRect, + cppcanvas::IntSRGBA aFillColor ); + + /** Init canvas with default background (white) + */ + void initSlideBackground( const cppcanvas::CanvasSharedPtr& rCanvas, + const basegfx::B2ISize& rSize ); + + /// Gets a random ordinal [0,n) + inline ::std::size_t getRandomOrdinal( const ::std::size_t n ) + { + return comphelper::rng::uniform_size_distribution(0, n-1); + } + + template <typename ValueType> + inline bool getPropertyValue( + ValueType & rValue, + css::uno::Reference< + css::beans::XPropertySet> const & xPropSet, + OUString const & propName ) + { + try { + const css::uno::Any& a( + xPropSet->getPropertyValue( propName ) ); + bool const bRet = css::uno::fromAny(a, &rValue); +#if OSL_DEBUG_LEVEL > 0 + if( !bRet ) + SAL_INFO("slideshow", __func__ << ": while retrieving property " << propName << ", cannot extract Any of type " + << a.getValueTypeRef()->pTypeName); +#endif + return bRet; + } + catch (css::uno::RuntimeException &) + { + throw; + } + catch (css::uno::Exception &) + { + return false; + } + } + + template <typename ValueType> + inline bool getPropertyValue( + css::uno::Reference< ValueType >& rIfc, + css::uno::Reference< css::beans::XPropertySet> const & xPropSet, + OUString const & propName ) + { + try + { + const css::uno::Any& a(xPropSet->getPropertyValue( propName )); + rIfc.set( a, css::uno::UNO_QUERY ); + + bool const bRet = rIfc.is(); +#if OSL_DEBUG_LEVEL > 0 + if( !bRet ) + SAL_INFO("slideshow", __func__ << ": while retrieving property " << propName << ", cannot extract Any of type " + << a.getValueTypeRef()->pTypeName << " to interface"); +#endif + return bRet; + } + catch (css::uno::RuntimeException &) + { + throw; + } + catch (css::uno::Exception &) + { + return false; + } + } + + /// Get the content of the BoundRect shape property + basegfx::B2DRectangle getAPIShapeBounds( const css::uno::Reference< css::drawing::XShape >& xShape ); + +/* + TODO(F1): When ZOrder someday becomes usable enable this + + /// Get the content of the ZOrder shape property + double getAPIShapePrio( const css::uno::Reference< css::drawing::XShape >& xShape ); +*/ + + basegfx::B2IVector getSlideSizePixel( const basegfx::B2DVector& rSize, + const UnoViewSharedPtr& pView ); + } + + // TODO(Q1): this could possibly be implemented with a somewhat + // more lightweight template, by having the actual worker receive + // only a function pointer, and a thin templated wrapper around + // that which converts member functions into that. + + /** Apply given functor to every animation node child. + + @param xNode + Parent node + + @param rFunctor + Functor to apply. The functor must have an appropriate + operator()( const css::uno::Reference< css::animations::XAnimationNode >& ) member. + + @return true, if the functor was successfully applied to + all children, false otherwise. + */ + template< typename Functor > inline bool for_each_childNode( const css::uno::Reference< css::animations::XAnimationNode >& xNode, + Functor& rFunctor ) + { + try + { + // get an XEnumerationAccess to the children + css::uno::Reference< css::container::XEnumerationAccess > + xEnumerationAccess( xNode, + css::uno::UNO_QUERY_THROW ); + css::uno::Reference< css::container::XEnumeration > + xEnumeration( xEnumerationAccess->createEnumeration(), + css::uno::UNO_SET_THROW ); + + while( xEnumeration->hasMoreElements() ) + { + css::uno::Reference< css::animations::XAnimationNode > + xChildNode( xEnumeration->nextElement(), + css::uno::UNO_QUERY_THROW ); + rFunctor( xChildNode ); + } + return true; + } + catch( css::uno::Exception& ) + { + return false; + } + } +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_TOOLS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/transitionfactory.hxx b/slideshow/source/inc/transitionfactory.hxx new file mode 100644 index 000000000..ea645cbec --- /dev/null +++ b/slideshow/source/inc/transitionfactory.hxx @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_TRANSITIONFACTORY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_TRANSITIONFACTORY_HXX + +#include <com/sun/star/animations/XTransitionFilter.hpp> +#include <com/sun/star/presentation/XTransitionFactory.hpp> + +#include "rgbcolor.hxx" +#include "slide.hxx" +#include "screenupdater.hxx" +#include "animationactivity.hxx" +#include "activitiesfactory.hxx" +#include "numberanimation.hxx" +#include "soundplayer.hxx" +#include "shapemanager.hxx" + +namespace slideshow::internal + { + /* Definition of Transitionfactory class */ + namespace TransitionFactory + { + /** Create a transition effect for shapes. + + This method creates an AnimationActivity, which, when + run, performs the requested transition effect on the + given shape. + + @param rParms + Collection of activity parameters, see ActivitiesFactory + + @param rShape + Shape to animate + + @param rShapeManager + ShapeManager, to manage shape animation + + @param xTransition + The transition effect + + @return the created activity, or NULL for no + transition effect + */ + AnimationActivitySharedPtr createShapeTransition( + const ActivitiesFactory::CommonParameters& rParms, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + css::uno::Reference< css::animations::XTransitionFilter > const& xTransition ); + + + /** Create a transition effect for slides. + + This method creates a NumberAnimation, which, + when run, performs the requested transition effect + with the slide bitmaps. + + @param rEnteringBitmap + Bitmap of the slide which 'enters' the screen. + + @param rLeavingBitmap + Bitmap of the slide which 'leaves' the screen. + + @param nTransitionType + Type of the transition (see XTransitionFilter) + + @param nTransitionSubType + Subtype of the transition (see XTransitionFilter) + + @param bTransitionDirection + Direction of the transition (see XTransitionFilter) + + @param rTransitionFadeColor + Optional fade color for the transition + + @return the created animation, or NULL for no + transition effect + */ + NumberAnimationSharedPtr createSlideTransition( + const SlideSharedPtr& rLeavingSlide, + const SlideSharedPtr& rEnteringSlide, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + const css::uno::Reference< css::presentation::XTransitionFactory>& + xOptionalFactory, + sal_Int16 nTransitionType, + sal_Int16 nTransitionSubType, + bool bTransitionDirection, + const RGBColor& rTransitionFadeColor, + const SoundPlayerSharedPtr& rSoundPlayer ); + } + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_TRANSITIONFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/transitioninfo.hxx b/slideshow/source/inc/transitioninfo.hxx new file mode 100644 index 000000000..c0cd0aed1 --- /dev/null +++ b/slideshow/source/inc/transitioninfo.hxx @@ -0,0 +1,142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_TRANSITIONINFO_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_TRANSITIONINFO_HXX + +#include <sal/types.h> + + +namespace slideshow::internal { + +struct TransitionInfo +{ + // the following two member serve as the search key + // for an incoming XTransitionFilter node + + // { + + sal_Int16 mnTransitionType; + sal_Int16 mnTransitionSubType; + + // } + + + /** This enum classifies a transition type + */ + enum TransitionClass + { + /// Invalid type + TRANSITION_INVALID, + + /// Transition expressed by parametric clip polygon + TRANSITION_CLIP_POLYPOLYGON, + + /// Transition expressed by hand-crafted function + TRANSITION_SPECIAL + }; + + /// class of effect handling + TransitionClass meTransitionClass; + + /// Rotation angle of clip polygon + double mnRotationAngle; + + /// X scaling of clip polygon (negative values mirror) + double mnScaleX; + + /// Y scaling of clip polygon (negative values mirror) + double mnScaleY; + + /** This enum determines the method how to reverse + a parametric clip polygon transition. + + A reversed transition runs in the geometrically + opposite direction. For a left-to-right bar wipe, the + reversed transition is a right-to-left wipe, whereas + for an iris transition, the reversed mode will show + the target in the outer area (instead of in the inner + area, as in normal mode). + */ + enum class ReverseMethod + { + /** Ignore direction attribute altogether + (if it has no sensible meaning for this transition) + */ + Ignore, + + /** Combination of ReverseMethod::InvertSweep and + ReverseMethod::SubtractPolygon. + */ + SubtractAndInvert, + + /// Reverse by rotating polygon 180 degrees + Rotate180, + + /// Reverse by flipping polygon at the y (!) axis + FlipX, + + /// Reverse by flipping polygon at the x (!) axis + FlipY + }; + + /** Indicating the method to use when transition + should be 'reversed'. + + @see ReverseMethod + */ + ReverseMethod meReverseMethod; + + /** When true, transition 'out' effects are realized + by inverting the parameter sweep direction (1->0 + instead of 0->1). Otherwise, 'out' effects are + realized by changing inside and outside areas of + the parametric poly-polygon. + */ + bool mbOutInvertsSweep; + + /** when true, scale clip polygon isotropically to + target size. when false, scale is + anisotropically. + */ + bool mbScaleIsotrophically; + + + /// Compare against type and subtype + class Comparator + { + sal_Int16 mnTransitionType; + sal_Int16 mnTransitionSubType; + public: + Comparator( sal_Int16 nTransitionType, + sal_Int16 nTransitionSubType ) + : mnTransitionType( nTransitionType ), + mnTransitionSubType( nTransitionSubType ) {} + bool operator()( const TransitionInfo& rEntry ) const { + return rEntry.mnTransitionType == mnTransitionType && + rEntry.mnTransitionSubType == mnTransitionSubType; + } + }; +}; + +} // namespace presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_TRANSITIONINFO_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/unoview.hxx b/slideshow/source/inc/unoview.hxx new file mode 100644 index 000000000..7adec4c15 --- /dev/null +++ b/slideshow/source/inc/unoview.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_UNOVIEW_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_UNOVIEW_HXX + +#include "view.hxx" +#include <com/sun/star/uno/Reference.hxx> + +#include <vector> + +namespace com::sun::star::presentation { class XSlideShowView; } + + +/* Definition of UnoView interface */ + +namespace slideshow::internal + { + /** Extend View with UNO interface retrieval. + + This interface extends View with a UNO interface + retrieval, to be used for Views which are set from + external API. + */ + class UnoView : public View + { + public: + /** Retrieve the underlying UNO slide view. + */ + virtual css::uno::Reference< css::presentation::XSlideShowView > getUnoView() const = 0; + + /** Dispose view + + This needs to be different from Disposable interface, + as the UNO XComponent also provides a dispose() (only + with a different calling convention under Windows). + */ + virtual void _dispose() = 0; + + /** Return whether the sound play back is enabled. + */ + virtual bool isSoundEnabled() const = 0; + + /** Tell the view whether it may play sounds. Disabling this + can be used to prevent different views to play the same + sounds at the same time. + */ + virtual void setIsSoundEnabled (const bool bValue) = 0; + }; + + typedef std::shared_ptr< UnoView > UnoViewSharedPtr; + typedef std::vector< UnoViewSharedPtr > UnoViewVector; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_UNOVIEW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/unoviewcontainer.hxx b/slideshow/source/inc/unoviewcontainer.hxx new file mode 100644 index 000000000..54ee9d579 --- /dev/null +++ b/slideshow/source/inc/unoviewcontainer.hxx @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_UNOVIEWCONTAINER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_UNOVIEWCONTAINER_HXX + +#include <com/sun/star/uno/Reference.hxx> + +#include "unoview.hxx" + + +namespace com::sun::star::presentation { class XSlideShowView; } + +/* Definition of UnoViewContainer class */ + +namespace slideshow::internal + { + /** Contains UnoViews + */ + class UnoViewContainer + { + public: + UnoViewContainer(); + UnoViewContainer(const UnoViewContainer&) = delete; + UnoViewContainer& operator=(const UnoViewContainer&) = delete; + + /** Add a view to this container + + @return true, if the view was successfully added + (false is e.g. returned, if the view was already + added) + */ + bool addView( const UnoViewSharedPtr& rView ); + + /** Remove a previously added a view from this container + + @return the View object, if this view was successfully + removed, and an empty shared_ptr otherwise (e.g. if + this view wasn't added in the first place) + */ + UnoViewSharedPtr removeView( const css::uno::Reference<css::presentation::XSlideShowView >& xView ); + + /// Dispose all stored views. Implies clear(). + void dispose(); + + // the following parrots STL container concept methods + // =================================================== + + bool empty() const { return maViews.empty(); } + + UnoViewVector::iterator begin() { return maViews.begin(); } + UnoViewVector::const_iterator begin() const { return maViews.begin(); } + UnoViewVector::iterator end() { return maViews.end(); } + UnoViewVector::const_iterator end() const { return maViews.end(); } + + private: + /// All added views + UnoViewVector maViews; + }; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_UNOVIEWCONTAINER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/usereventqueue.hxx b/slideshow/source/inc/usereventqueue.hxx new file mode 100644 index 000000000..785a8bdf3 --- /dev/null +++ b/slideshow/source/inc/usereventqueue.hxx @@ -0,0 +1,269 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_USEREVENTQUEUE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_USEREVENTQUEUE_HXX + +#include <com/sun/star/animations/XAnimationNode.hpp> + +#include "eventmultiplexer.hxx" +#include "eventqueue.hxx" +#include "shape.hxx" + +/* Definition of UserEventQueue class */ + +namespace slideshow::internal { + +class AllAnimationEventHandler; +class ShapeClickEventHandler; +class ClickEventHandler; +class CursorManager; +class SkipEffectEventHandler; +class RewindEffectEventHandler; +class MouseEnterHandler; +class MouseLeaveHandler; + +/** This class schedules user-activated events. + + This class registers at the EventMultiplexer and fires + events registered for certain user actions. Note that all + events will not be fired immediately after the user action + occurred, but always added to the EventQueue (and fired the + next time that queue is processed). Which is actually a + feature. + + Conceptually, an event is an object that typically is + fired only once. After that, the event is exhausted, and + should be discarded. Therefore, all events registered on + this object are fired and then all references to them are + removed. +*/ +class UserEventQueue +{ +public: + /** Create a user event queue + + @param rEventMultiplexer + The slideshow-global event source, where this class + registers its event handlers. + + @param rEventQueue + Reference to the main event queue. Since we hold this + object by plain reference, it must live longer than we + do. On the other hand, that queue must not fire events + after this object is destroyed, since we might + schedule events there which itself contain plain + references to this object. Basically, EventQueue and + UserEventQueue should have the same lifetime, and since + this is not possible, both must be destructed in a + phased mode: first clear both of any remaining events, + then destruct them. + */ + UserEventQueue( EventMultiplexer& rMultiplexer, + EventQueue& rEventQueue, + CursorManager& rCursorManager ); + ~UserEventQueue(); + UserEventQueue(const UserEventQueue&) = delete; + UserEventQueue& operator=(const UserEventQueue&) = delete; + + /** Clear all registered events. + + This method clears all registered, but + not-yet-executed events. This comes in handy when + force-ending a slide, to avoid interference with the + next slide's event registration. + */ + void clear(); + + /** Set advance on click behaviour. + + @param bAdvanceOnClick + When true, a click somewhere on the slide will also + generate next effect event. In this case, it is + irrelevant where on the slide the mouse is clicked, + i.e. the shape need not be hit by the mouse. + */ + void setAdvanceOnClick( bool bAdvanceOnClick ); + + /** Register an event that will be fired when the given + animation node starts. + + Note that <em>all</em> registered events will be fired + when the animation start occurs. This is in contrast to + the mouse events below. + */ + void registerAnimationStartEvent( + const EventSharedPtr& rEvent, + const css::uno::Reference<css::animations::XAnimationNode>& xNode ); + + /** Register an event that will be fired when the given + animation node ends its active duration. + + Note that <em>all</em> registered events will be fired + when the animation end occurs. This is in contrast to + the mouse events below. + */ + void registerAnimationEndEvent( + const EventSharedPtr& rEvent, + const css::uno::Reference<css::animations::XAnimationNode>& xNode ); + + /** Register an event that will be fired when audio output + stopped for the given animation node. + + Note that <em>all</em> registered events will be fired + when the audio stopping occurs. This is in contrast to + the mouse events below. + */ + void registerAudioStoppedEvent( + const EventSharedPtr& rEvent, + const css::uno::Reference<css::animations::XAnimationNode>& xNode ); + + /** Register an event that is fired when a shape is clicked + + For every mouse click, only one of the events + registered here is fired. The order of fired events is + the order of registration, i.e. the first event + registered will be the one fired for the first mouse + click on the given shape. + */ + void registerShapeClickEvent( const EventSharedPtr& rEvent, + const ShapeSharedPtr& rShape ); + + /** Registers an event that is fired when the current effects(s) + are skipped, .e.g. when the left mouse button is pressed. + Then, all registered events are fired and removed from this + queue. After firing, a next effect event is issued to this + queue to start the next effect. + @param pEvent + The event to execute when skipping the current effect. + @param bSkipTriggersNextEffect + When <TRUE/> then after skipping the current effect the next + effect is triggered. When <FALSE/> then the next effect is not + triggered. + */ + void registerSkipEffectEvent( + EventSharedPtr const& pEvent, + const bool bSkipTriggersNextEffect); + + /** Register an event that is fired to show the next event + + For every next effect event, only one of the events + registered here is fired. The order of fired events is + the order of registration, i.e. the first event + registered will be the one fired for the first mouse + click. When advance-on-click (see method + setAdvanceOnClick()) is enabled, a mouse click + somewhere on the slide will also generate a next + effect event. In this case, it is irrelevant where on + the slide the mouse is clicked, i.e. the shape need + not be hit by the mouse. + */ + void registerNextEffectEvent( const EventSharedPtr& rEvent ); + + /** Register an event that is fired on a double mouse + click on a shape + + For every mouse double click, only one of the events + registered here is fired. The order of fired events is + the order of registration, i.e. the first event + registered will be the one fired for the first mouse + double click. It is irrelevant where on the slide the + mouse is clicked, i.e. the shape need not be hit by + the mouse. + */ + void registerShapeDoubleClickEvent( const EventSharedPtr& rEvent, + const ShapeSharedPtr& rShape ); + + /** Register an event that is fired when the mouse enters + the area of the given shape + + For every enter, only one of the events registered + here is fired. The order of fired events is the order + of registration, i.e. the first event registered will + be the one fired for the first time the mouse enters + the given shape. + */ + void registerMouseEnterEvent( const EventSharedPtr& rEvent, + const ShapeSharedPtr& rShape ); + + /** Register an event that is fired when the mouse leaves + the area of the given shape + + For every leave, only one of the events registered + here is fired. The order of fired events is the order + of registration, i.e. the first event registered will + be the one fired for the first time the mouse leaves + the given shape area. + */ + void registerMouseLeaveEvent( const EventSharedPtr& rEvent, + const ShapeSharedPtr& rShape ); + + /** Typically skipping the current effect is triggered by mouse clicks + or key presses that trigger the next effect. This method allows the + skipping of effects to be triggered programmatically. + */ + void callSkipEffectEventHandler(); + +private: + /** Generically register an event on one of the handlers. + + If the handler is not yet created, do that and + register it via the Functor + */ + template< typename Handler, typename Functor > + void registerEvent( ::std::shared_ptr< Handler >& rHandler, + const EventSharedPtr& rEvent, + const Functor& rRegistrationFunctor ); + + /** Generically register an event on one of the handlers. + + If the handler is not yet created, do that and + register it via the Functor. This version of the + registerEvent method takes an additional parameter + rArg, which is passed as the second argument to + rHandler's addEvent() method. + */ + template< typename Handler, typename Arg, typename Functor > + void registerEvent( ::std::shared_ptr< Handler >& rHandler, + const EventSharedPtr& rEvent, + const Arg& rArg, + const Functor& rRegistrationFunctor ); + + EventMultiplexer& mrMultiplexer; + EventQueue& mrEventQueue; + CursorManager& mrCursorManager; + + ::std::shared_ptr<AllAnimationEventHandler> mpAnimationStartEventHandler; + ::std::shared_ptr<AllAnimationEventHandler> mpAnimationEndEventHandler; + ::std::shared_ptr<AllAnimationEventHandler> mpAudioStoppedEventHandler; + ::std::shared_ptr<ShapeClickEventHandler> mpShapeClickEventHandler; + ::std::shared_ptr<ClickEventHandler> mpClickEventHandler; + ::std::shared_ptr<SkipEffectEventHandler> mpSkipEffectEventHandler; + ::std::shared_ptr<ShapeClickEventHandler> mpShapeDoubleClickEventHandler; + ::std::shared_ptr<MouseEnterHandler> mpMouseEnterHandler; + ::std::shared_ptr<MouseLeaveHandler> mpMouseLeaveHandler; + + bool mbAdvanceOnClick; +}; + +} // namespace presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_USEREVENTQUEUE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/view.hxx b/slideshow/source/inc/view.hxx new file mode 100644 index 000000000..0d1937b60 --- /dev/null +++ b/slideshow/source/inc/view.hxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_VIEW_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_VIEW_HXX + +#include "viewlayer.hxx" + +#include <memory> +#include <vector> + + +namespace basegfx { class B2DRange; class B2DVector; } + + +/* Definition of View interface */ + +namespace slideshow::internal + { + class View : public ViewLayer + { + public: + /** Create a new view layer for this view + + @param rLayerBounds + Specifies the bound rect of the layer relative to the + user view coordinate system. + + This method sets the bounds of the view layer in + document coordinates (i.e. 'logical' coordinates). The + resulting transformation is then concatenated with the + underlying view transformation, returned by the + getTransformation() method. + */ + virtual ViewLayerSharedPtr createViewLayer( const basegfx::B2DRange& rLayerBounds ) const = 0; + + /** Update screen representation from backbuffer + */ + virtual bool updateScreen() const = 0; + + /** Paint screen content unconditionally from backbuffer + */ + virtual bool paintScreen() const = 0; + + /** Set the size of the user view coordinate system. + + This method sets the width and height of the view in + document coordinates (i.e. 'logical' coordinates). The + resulting transformation is then concatenated with the + underlying view transformation, returned by the + getTransformation() method. + */ + virtual void setViewSize( const ::basegfx::B2DSize& ) = 0; + + /** Change the view's mouse cursor. + + @param nPointerShape + One of the css::awt::SystemPointer + constant group members. + */ + virtual void setCursorShape( sal_Int16 nPointerShape ) = 0; + }; + + typedef std::shared_ptr< View > ViewSharedPtr; + typedef std::vector< ViewSharedPtr > ViewVector; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_VIEW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/vieweventhandler.hxx b/slideshow/source/inc/vieweventhandler.hxx new file mode 100644 index 000000000..a375e047f --- /dev/null +++ b/slideshow/source/inc/vieweventhandler.hxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_VIEWEVENTHANDLER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_VIEWEVENTHANDLER_HXX + +#include <memory> + +#include "unoview.hxx" +#include "disposable.hxx" + + +/* Definition of ViewEventHandler interface */ + +namespace slideshow::internal + { + + /** Interface for handling view events. + + Classes implementing this interface can be added to an + EventMultiplexer object, and are called from there to + handle view events. + */ + class ViewEventHandler : public virtual SharedPtrAble + { + public: + /** Notify new view. + + @param rView + The newly added view + */ + virtual void viewAdded( const UnoViewSharedPtr& rView ) = 0; + + /** Notify removed view. + + @param rView + The removed view + */ + virtual void viewRemoved( const UnoViewSharedPtr& rView ) = 0; + + /** Notify changed view. + + Reasons for a viewChanged notification can be + different view size, transformation, or other device + properties (color resolution or profile, etc.) + + @param rView + The changed view + */ + virtual void viewChanged( const UnoViewSharedPtr& rView ) = 0; + + /** Notify that all views changed. + + Reasons for a viewChanged notification can be + different view size, transformation, or other device + properties (color resolution or profile, etc.) + + Note that this method avoids hidden inefficiencies + (O(n^2) behaviour when viewChanged() needs to perform + linear searches) + */ + virtual void viewsChanged() = 0; + }; + + typedef ::std::weak_ptr< ViewEventHandler > ViewEventHandlerWeakPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_VIEWEVENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/viewlayer.hxx b/slideshow/source/inc/viewlayer.hxx new file mode 100644 index 000000000..4fe8aa4e0 --- /dev/null +++ b/slideshow/source/inc/viewlayer.hxx @@ -0,0 +1,173 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_VIEWLAYER_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_VIEWLAYER_HXX + +#include <sal/config.h> +#include <memory> +#include <com/sun/star/geometry/IntegerSize2D.hpp> + +namespace basegfx +{ + class B1DRange; + class B2DRange; + class B2DVector; + class B2DHomMatrix; + class B2DPolyPolygon; + typedef B2DVector B2DSize; +} +namespace cppcanvas +{ + class Canvas; + class CustomSprite; + typedef std::shared_ptr< Canvas > CanvasSharedPtr; + typedef std::shared_ptr< ::cppcanvas::CustomSprite > CustomSpriteSharedPtr; +} + + +/* Definition of ViewLayer interface */ + +namespace slideshow::internal + { + class View; + typedef std::shared_ptr< View > ViewSharedPtr; + + class ViewLayer + { + public: + virtual ~ViewLayer() {} + + /** Query whether layer displays on given view. + + @return true, if this layer displays on the given + view. + */ + virtual bool isOnView(ViewSharedPtr const& rView) const = 0; + + /** Get the associated canvas of this layer. + + The canvas returned by this method must not change, as + long as this object is alive. + */ + virtual cppcanvas::CanvasSharedPtr getCanvas() const = 0; + + /** Clear the clipped view layer area + + This method clears the area inside the clip polygon, + if none is set, the transformed unit rectangle of the + view. + */ + virtual void clear() const = 0; + + /** Clear the complete view + + This method clears the full view area (not only the + transformed unit rectangle, or within the clip). If + this ViewLayer represents the background layer, the + whole XSlideShowView is cleared. If this ViewLayer is + implemented using sprites (i.e. one of the upper + layers), the sprite is cleared to fully transparent. + */ + virtual void clearAll() const = 0; + + /** Create a sprite for this layer + + @param rSpriteSizePixel + Sprite size in device pixel + + @param nPriority + Sprite priority. This value determines the priority of + this sprite, relative to all other sprites of this + ViewLayer. The higher the priority, the closer to the + foreground the sprite will be. + + @return the sprite, or NULL on failure (or if this + canvas does not support sprites). + */ + virtual cppcanvas::CustomSpriteSharedPtr + createSprite( const basegfx::B2DSize& rSpriteSizePixel, + double nPriority ) const = 0; + + /** Set the layer priority range + + This method influences the relative priority of this + layer, i.e. the z position in relation to other layers + on the parent view. The higher the priority range, the + further in front the layer resides. + + @param rRange + Priority range, must be in the range [0,1] + */ + virtual void setPriority( const basegfx::B1DRange& rRange ) = 0; + + /** Get the overall view transformation. + + This method should <em>not</em> simply return the + underlying canvas' transformation, but rather provide + a layer above that. This enables clients of the + slideshow to set their own user space transformation + at the canvas, whilst the slideshow adds their + transformation on top of that. Concretely, this method + returns the user transform (implicitly calculated + from the setViewSize() method), combined with the view + transformation. + */ + virtual basegfx::B2DHomMatrix getTransformation() const = 0; + + virtual css::geometry::IntegerSize2D getTranslationOffset() const = 0; + + /** Get the overall view transformation. + + Same transformation as with getTransformation(), only + that you can safely use this one to position sprites + on screen (no ViewLayer offsets included whatsoever). + */ + virtual basegfx::B2DHomMatrix getSpriteTransformation() const = 0; + + /** Set clipping on this view layer. + + @param rClip + Clip poly-polygon to set. The polygon is interpreted + in the user coordinate system, i.e. the view layer has + the size as given by setViewSize() on its + corresponding View. + */ + virtual void setClip( const basegfx::B2DPolyPolygon& rClip ) = 0; + + /** Resize this view layer. + + @param rArea + New area to cover. The area is interpreted in the user + coordinate system, i.e. relative to the size as given + by setViewSize() on the corresponding View. + + @return true, if layer was actually resized (which + invalidates its content) + */ + virtual bool resize( const basegfx::B2DRange& rArea ) = 0; + + }; + + typedef std::shared_ptr< ViewLayer > ViewLayerSharedPtr; +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_VIEWLAYER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/viewupdate.hxx b/slideshow/source/inc/viewupdate.hxx new file mode 100644 index 000000000..a5e2ee340 --- /dev/null +++ b/slideshow/source/inc/viewupdate.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_VIEWUPDATE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_VIEWUPDATE_HXX + +#include "disposable.hxx" +#include <memory> + +/* Definition of ViewUpdate interface */ + +namespace slideshow::internal + { + /** Interface for something that can perform view updates. + + Use this interface for objects that perform view updates + from time to time, e.g. slide content. Availability of + updates can be queried, and subsequently performed. + */ + class ViewUpdate : public Disposable + { + public: + /** Perform the update action on all views + + @return true, if the update was performed + successfully, false otherwise. + */ + virtual bool update() = 0; + + /** Query whether updates are pending + + @return true, if updates are pending. Calling update() + subsequently will perform the pending update then. + */ + virtual bool needsUpdate() const = 0; + }; + + typedef ::std::shared_ptr< ViewUpdate > ViewUpdateSharedPtr; + +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_VIEWUPDATE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/inc/wakeupevent.hxx b/slideshow/source/inc/wakeupevent.hxx new file mode 100644 index 000000000..8a1379f02 --- /dev/null +++ b/slideshow/source/inc/wakeupevent.hxx @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SLIDESHOW_SOURCE_INC_WAKEUPEVENT_HXX +#define INCLUDED_SLIDESHOW_SOURCE_INC_WAKEUPEVENT_HXX + +#include <canvas/elapsedtime.hxx> + +#include "event.hxx" +#include "activitiesqueue.hxx" + +namespace slideshow::internal { + +/** Little helper class, used to set Activities active again + after some sleep period. + + Clients can use this class to schedule wakeup events at + the EventQueue, to avoid busy-waiting for the next + discrete time instant. +*/ +class WakeupEvent : public Event +{ +public: + WakeupEvent( + std::shared_ptr< ::canvas::tools::ElapsedTime > const& pTimeBase, + ActivitiesQueue & rActivityQueue ); + WakeupEvent(const WakeupEvent&) = delete; + WakeupEvent& operator=(const WakeupEvent&) = delete; + + virtual void dispose() override; + virtual bool fire() override; + virtual bool isCharged() const override; + virtual double getActivationTime( double nCurrentTime ) const override; + + /// Start the internal timer + void start(); + + /** Set the next timeout this object should generate. + + @param nextTime + Absolute time, measured from the last start() call, + when this event should wakeup the Activity again. If + your time is relative, simply call start() just before + every setNextTimeout() call. + */ + void setNextTimeout( double nextTime ); + + /** Set activity to wakeup. + + The activity given here will be reinserted into the + ActivitiesQueue, once the timeout is reached. + */ + void setActivity( const ActivitySharedPtr& rActivity ); + +private: + ::canvas::tools::ElapsedTime maTimer; + double mnNextTime; + ActivitySharedPtr mpActivity; + ActivitiesQueue& mrActivityQueue; +}; + +typedef ::std::shared_ptr< WakeupEvent > WakeupEventSharedPtr; + +} // namespace presentation::internal + +#endif // INCLUDED_SLIDESHOW_SOURCE_INC_WAKEUPEVENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |