mirror of
https://github.com/kr15h/ofxPiMapper.git
synced 2026-06-16 12:31:49 +02:00
Rename example to example_fbo-sources and move magSlideShowSource there
This commit is contained in:
@@ -1,202 +0,0 @@
|
||||
//
|
||||
// magSlide.cpp
|
||||
// Copyright (c) 2017 Cristobal Mendoza
|
||||
// http://cuppetellimendoza.com
|
||||
//
|
||||
|
||||
#include "magSlide.h"
|
||||
#include "magSlideTransition.h"
|
||||
|
||||
#pragma mark magSlide
|
||||
|
||||
int magSlide::idCount = 0;
|
||||
|
||||
magSlide::magSlide(std::string type)
|
||||
{
|
||||
this->type = type;
|
||||
position = ofPoint(0, 0);
|
||||
id = magSlide::idCount;
|
||||
magSlide::idCount++;
|
||||
}
|
||||
|
||||
void magSlide::update(u_int64_t deltaTime)
|
||||
{
|
||||
transition->update(deltaTime);
|
||||
runningTime += deltaTime;
|
||||
|
||||
switch (slideState){
|
||||
// case SlideState::BuildIn:
|
||||
// if (runningTime >= buildInDuration)
|
||||
// {
|
||||
// setState(Normal);
|
||||
// activeTransition = nullptr;
|
||||
// }
|
||||
// break;
|
||||
|
||||
case SlideState::Normal:
|
||||
if (runningTime >= buildOutStartTime){
|
||||
setState(BuildOut);
|
||||
}
|
||||
break;
|
||||
|
||||
case SlideState::BuildOut:
|
||||
if (runningTime >= endTime){
|
||||
setState(Complete);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void magSlide::setSize(float w, float h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
void magSlide::setResizeOption(magSlide::ResizeOptions resizeOption)
|
||||
{
|
||||
this->resizeOption = resizeOption;
|
||||
}
|
||||
|
||||
magSlide::ResizeOptions magSlide::getResizeOption() const
|
||||
{
|
||||
return resizeOption;
|
||||
}
|
||||
|
||||
void magSlide::setDuration(u_int64_t duration)
|
||||
{
|
||||
this->duration = duration;
|
||||
}
|
||||
|
||||
void magSlide::setState(SlideState state)
|
||||
{
|
||||
// Don't do anything if the new state is the same
|
||||
// as the current one:
|
||||
if (slideState == state) return;
|
||||
|
||||
slideState = state;
|
||||
ofEventArgs args;
|
||||
ofNotifyEvent(slideStateChangedEvent, args, this);
|
||||
|
||||
if (slideState == Complete)
|
||||
{
|
||||
ofNotifyEvent(slideCompleteEvent, args, this);
|
||||
}
|
||||
}
|
||||
|
||||
void magSlide::setTransitionDuration(u_int64_t tDuration)
|
||||
{
|
||||
buildOutDuration = tDuration;
|
||||
}
|
||||
|
||||
const std::string magSlide::getSlideStateName()
|
||||
{
|
||||
switch (slideState)
|
||||
{
|
||||
// case SlideState::BuildIn:
|
||||
// return "BuildIn";
|
||||
case SlideState::BuildOut:
|
||||
return "BuildOut";
|
||||
case Normal:
|
||||
return "Normal";
|
||||
case SlideState::Complete:
|
||||
return "Complete";
|
||||
case SlideState::Off:
|
||||
return "Off";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void magSlide::start(u_int64_t startTime)
|
||||
{
|
||||
this->startTime = startTime;
|
||||
runningTime = 0;
|
||||
endTime = duration + (buildOutDuration*2); // *2 because we take into account transition in and out
|
||||
buildOutStartTime = duration + buildOutDuration;
|
||||
slideState = magSlide::SlideState::Normal;
|
||||
position.set(0, 0);
|
||||
opacity = 255;
|
||||
isComplete = false;
|
||||
}
|
||||
|
||||
void magSlide::draw()
|
||||
{
|
||||
ofSetColor(255, opacity);
|
||||
if(transition->isActive())
|
||||
{
|
||||
transition->draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
#pragma mark MAG_IMAGE_SLIDE
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
magImageSlide::magImageSlide() : magSlide("magImageSlide") {}
|
||||
|
||||
magImageSlide::~magImageSlide() {}
|
||||
|
||||
void magImageSlide::setup(ofImage &image)
|
||||
{
|
||||
// Make a copy of the image:
|
||||
this->image = ofImage(image);
|
||||
image.setAnchorPercent(0.5, 0.5);
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
}
|
||||
|
||||
void magImageSlide::draw()
|
||||
{
|
||||
magSlide::draw();
|
||||
image.draw(position, width, height);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
#pragma mark MAG_VIDEO_SLIDE
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
magVideoSlide::magVideoSlide() : magSlide("magVideoSlide")
|
||||
{}
|
||||
|
||||
magVideoSlide::~magVideoSlide()
|
||||
{
|
||||
videoPlayer.stop();
|
||||
}
|
||||
|
||||
bool magVideoSlide::setup(ofFile &file, bool useVideoDuration)
|
||||
{
|
||||
|
||||
bool success = videoPlayer.load(file.getAbsolutePath());
|
||||
|
||||
if (success)
|
||||
{
|
||||
videoPlayer.setAnchorPercent(0.5, 0.5);
|
||||
if (useVideoDuration)
|
||||
{
|
||||
useVideoForDuration();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void magVideoSlide::update()
|
||||
{
|
||||
videoPlayer.update();
|
||||
}
|
||||
|
||||
void magVideoSlide::draw()
|
||||
{
|
||||
magSlide::draw();
|
||||
videoPlayer.draw(position.x, position.y, width, height);
|
||||
}
|
||||
|
||||
void magVideoSlide::useVideoForDuration()
|
||||
{
|
||||
duration = u_int64_t((videoPlayer.getDuration()*1000)) - buildOutDuration;
|
||||
}
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
//
|
||||
// Created by Cristobal Mendoza on 11/9/17.
|
||||
//
|
||||
|
||||
#ifndef MAGSLIDE_H
|
||||
#define MAGSLIDE_H
|
||||
|
||||
#include "ofMain.h"
|
||||
|
||||
class magSlideTransition;
|
||||
|
||||
class magSlide
|
||||
{
|
||||
public:
|
||||
magSlide(std::string type);
|
||||
// ~magSlide();
|
||||
virtual void update(u_int64_t deltaTime);
|
||||
virtual void draw();
|
||||
|
||||
/**
|
||||
* Sets the slide up for playback. This method must be
|
||||
* called before displaying the slide.
|
||||
* @param startTime
|
||||
*/
|
||||
void start(u_int64_t startTime);
|
||||
|
||||
enum ResizeOptions : short
|
||||
{
|
||||
/**
|
||||
* No resizing applied, displays the slide in its native pixel dimensions.
|
||||
* This is the default behavior.
|
||||
*/
|
||||
NoResize = 0,
|
||||
/**
|
||||
* Explicitly set a slide to display in its native dimension.
|
||||
* None and NoResize result in the same output, but if you specify
|
||||
* a default resizing option in your slideshow and you want a particular
|
||||
* slide not to resize, you must specify this option. Otherwise the
|
||||
* slide show option will apply.
|
||||
*/
|
||||
Native,
|
||||
|
||||
/**
|
||||
* Sets width and height to match the source's.
|
||||
* This will distort the slide if the aspect ratios
|
||||
* don't match.
|
||||
*/
|
||||
Fit,
|
||||
|
||||
/**
|
||||
* Resizes the largest dimension to the source's max,
|
||||
* the other dimension is resized proportionally.
|
||||
*/
|
||||
FitProportionally,
|
||||
|
||||
/**
|
||||
* Resizes the shortest dimensions to the source's max,
|
||||
*/
|
||||
FillProportionally,
|
||||
};
|
||||
|
||||
enum SlideState : short
|
||||
{
|
||||
Off = 0,
|
||||
// BuildIn,
|
||||
Normal,
|
||||
BuildOut,
|
||||
Complete
|
||||
};
|
||||
|
||||
const std::string &getType()
|
||||
{ return type; }
|
||||
|
||||
float getWidth()
|
||||
{ return width; }
|
||||
|
||||
float getHeight()
|
||||
{ return height; }
|
||||
|
||||
float getOpacity() const
|
||||
{
|
||||
return opacity;
|
||||
}
|
||||
|
||||
void setOpacity(float opacity)
|
||||
{
|
||||
magSlide::opacity = opacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the display size of a slide. This will implicitly
|
||||
* set resizeOptions to ResizeOption.NoResize.
|
||||
* This method does not resize the pixel source of the slide.
|
||||
* @param w The new width
|
||||
* @param h The new height
|
||||
*/
|
||||
virtual void setSize(float w, float h);
|
||||
|
||||
u_int64_t getDuration()
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the display time of the slide, excluding
|
||||
* builds (in or out)
|
||||
* @param duration in milliseconds.
|
||||
*/
|
||||
void setDuration(u_int64_t duration);
|
||||
|
||||
/**
|
||||
* Sets the duration of the buildIn and buildOut
|
||||
* transitions. Transition times are added to the
|
||||
* duration of the slide.
|
||||
* @param tDuration in milliseconds.
|
||||
*/
|
||||
void setTransitionDuration(u_int64_t tDuration);
|
||||
|
||||
ResizeOptions getResizeOption() const;
|
||||
void setResizeOption(ResizeOptions resizeOption);
|
||||
|
||||
SlideState getSlideState() const
|
||||
{
|
||||
return slideState;
|
||||
}
|
||||
|
||||
bool isSlideComplete()
|
||||
{ return isComplete; }
|
||||
|
||||
int getId()
|
||||
{ return id; }
|
||||
|
||||
const std::string getSlideStateName();
|
||||
|
||||
//////////////////////////////
|
||||
/// Events
|
||||
//////////////////////////////
|
||||
ofEvent<ofEventArgs> slideCompleteEvent;
|
||||
ofEvent<ofEventArgs> slideStateChangedEvent;
|
||||
|
||||
friend class magSlideShowSource;
|
||||
|
||||
protected:
|
||||
int id;
|
||||
std::string type;
|
||||
float width;
|
||||
float height;
|
||||
ofPoint position;
|
||||
public:
|
||||
const ofPoint &getPosition() const
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
void setPosition(const ofPoint &position)
|
||||
{
|
||||
magSlide::position = position;
|
||||
}
|
||||
|
||||
void setPosition(float x, float y)
|
||||
{
|
||||
position.set(x, y);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
float opacity = 255;
|
||||
ResizeOptions resizeOption = NoResize;
|
||||
SlideState slideState = Off;
|
||||
bool isComplete = false;
|
||||
|
||||
// std::shared_ptr<magSlideTransition> buildIn = nullptr;
|
||||
// std::shared_ptr<magSlideTransition> buildOut = nullptr;
|
||||
std::shared_ptr<magSlideTransition> transition = nullptr;
|
||||
public:
|
||||
const shared_ptr<magSlideTransition> &getTransition() const
|
||||
{
|
||||
return transition;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The duration of the slide in millis, not counting builds
|
||||
*/
|
||||
u_int64_t duration;
|
||||
|
||||
/**
|
||||
* The start time of the slide in milliseconds, in "local time".
|
||||
* In practice, this means that the start time is always 0.
|
||||
*/
|
||||
u_int64_t startTime;
|
||||
|
||||
/**
|
||||
* The end time of the slide in milliseconds, in "local time".
|
||||
* The endTime is startTime + buildInDuration + duration + buildOutDuration.
|
||||
*/
|
||||
u_int64_t endTime;
|
||||
|
||||
/**
|
||||
* The duration of the build in transition or effect, in milliseconds.
|
||||
*/
|
||||
// u_int64_t buildInDuration;
|
||||
|
||||
/**
|
||||
* The duration of the build out transition or effect, in milliseconds.
|
||||
*/
|
||||
u_int64_t buildOutDuration;
|
||||
|
||||
/**
|
||||
* The "local time" start of the build out transition. This time should also
|
||||
* signal the enqueuing of the next slide, if applicable.
|
||||
*/
|
||||
u_int64_t buildOutStartTime;
|
||||
|
||||
/**
|
||||
* The amount of time the slide has been displayed, in milliseconds.
|
||||
* This constitutes the "local time" of the slide.
|
||||
*/
|
||||
u_int64_t runningTime;
|
||||
|
||||
void setState(SlideState state);
|
||||
|
||||
static int idCount;
|
||||
};
|
||||
|
||||
class magImageSlide : public magSlide
|
||||
{
|
||||
public:
|
||||
magImageSlide();
|
||||
~ magImageSlide();
|
||||
/**
|
||||
* Sets up an image slide.
|
||||
* @param image is copied into the member magImageSlide::image and is
|
||||
* not modified in any way.
|
||||
*/
|
||||
void setup(ofImage &image);
|
||||
|
||||
void draw();
|
||||
|
||||
protected:
|
||||
ofImage image;
|
||||
};
|
||||
|
||||
class magVideoSlide : public magSlide
|
||||
{
|
||||
public:
|
||||
magVideoSlide();
|
||||
~magVideoSlide();
|
||||
bool setup(ofFile &file, bool useVideoDuration = false);
|
||||
void update();
|
||||
void draw();
|
||||
|
||||
/**
|
||||
* Sets the slide duration to the duration of the video.
|
||||
* magSlide::duration will be changed by this call, so if you later
|
||||
* change your mind you'll have to use magSlide::setDuration.
|
||||
*/
|
||||
void useVideoForDuration();
|
||||
protected:
|
||||
ofVideoPlayer videoPlayer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,531 +0,0 @@
|
||||
//
|
||||
// magSlideShowSource.cpp
|
||||
// Copyright (c) 2017 Cristobal Mendoza
|
||||
// http://cuppetellimendoza.com
|
||||
//
|
||||
|
||||
|
||||
#include "magSlideShowSource.h"
|
||||
#include "magSlideTransition.h"
|
||||
#include "SettingsLoader.h"
|
||||
#include "magSlideTransitionFactory.h"
|
||||
|
||||
const std::string magSlideShowSource::SettingsFileName = "magslideshow_settings.xml";
|
||||
|
||||
magSlideShowSource::magSlideShowSource() {
|
||||
name = "Slide Show Source";
|
||||
currentSlideIndex = 0;
|
||||
isPlaying = false;
|
||||
directoryWatcher = 0;
|
||||
doInit = false;
|
||||
if (!loadFromXml(SettingsFileName))
|
||||
{
|
||||
ofLogError("magSlideShowSource") << "Could not find slide show settings file " << SettingsFileName;
|
||||
Settings sets;
|
||||
initialize(sets);
|
||||
}
|
||||
}
|
||||
|
||||
magSlideShowSource::~magSlideShowSource(){
|
||||
if(directoryWatcher != 0){
|
||||
delete directoryWatcher;
|
||||
}
|
||||
}
|
||||
|
||||
bool magSlideShowSource::initialize(magSlideShowSource::Settings settings) {
|
||||
this->settings = settings;
|
||||
bool success = true;
|
||||
|
||||
if (settings.width <= 0 || settings.height <= 0)
|
||||
{
|
||||
ofLogError("magSlideShowSource::initialize") << "Invalid value for width or height. Width and height "
|
||||
"must be assigned in your Settings struct!";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate the FBO:
|
||||
allocate(settings.width, settings.height);
|
||||
|
||||
// If there is a path in slidesFolderPath, attempt
|
||||
// to load the folder and any files in it:
|
||||
if (!settings.slidesFolderPath.empty())
|
||||
{
|
||||
// ofDirectory dir = ofDirectory(settings.slidesFolderPath);
|
||||
success = createFromFolderContents(settings.slidesFolderPath);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
ofLogError("magSlideShowSource::initialize") << "Failed to create slide show from folder "
|
||||
<< settings.slidesFolderPath;
|
||||
return success;
|
||||
}
|
||||
{
|
||||
if (directoryWatcher == 0)
|
||||
{
|
||||
|
||||
using namespace ofx::piMapper;
|
||||
directoryWatcher = new DirectoryWatcher(settings.slidesFolderPath,
|
||||
SourceTypeHelper::GetSourceTypeHelperEnum(
|
||||
SOURCE_TYPE_NAME_IMAGE));
|
||||
ofAddListener(directoryWatcher->directoryFileAddedEvent, this, &magSlideShowSource::fileAddedListener);
|
||||
ofAddListener(directoryWatcher->directoryFileRemovedEvent, this,
|
||||
&magSlideShowSource::fileRemovedListener);
|
||||
directoryWatcher->beginWatch();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (!settings.slideshowFilePath.empty())
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void magSlideShowSource::setup() {
|
||||
ofx::piMapper::FboSource::setup();
|
||||
}
|
||||
|
||||
void magSlideShowSource::update() {
|
||||
|
||||
// Perform re-initialization if the DirectoryWatcher
|
||||
// detects file changes:
|
||||
if (doInit)
|
||||
{
|
||||
initialize(settings);
|
||||
doInit = false;
|
||||
}
|
||||
|
||||
if (!isPlaying) return;
|
||||
|
||||
auto nowTime = ofGetElapsedTimeMillis();
|
||||
deltaTime = nowTime-lastTime;
|
||||
runningTime += deltaTime;
|
||||
lastTime = nowTime;
|
||||
|
||||
for (auto &slide : activeSlides)
|
||||
{
|
||||
slide->update(deltaTime);
|
||||
}
|
||||
|
||||
// Queue the next slide if it is time
|
||||
if (doPlayNextSlide)
|
||||
{
|
||||
playNextSlide();
|
||||
if (activeSlides.size() > 1)
|
||||
{
|
||||
activeSlides[1]->transition->start(activeSlides[0]);
|
||||
}
|
||||
doPlayNextSlide = false;
|
||||
}
|
||||
|
||||
// Erase any complete slides:
|
||||
auto iter = activeSlides.begin();
|
||||
for (; iter < activeSlides.end(); iter++)
|
||||
{
|
||||
if ((*iter)->isSlideComplete())
|
||||
{
|
||||
// ofLogVerbose() << "Removing from active slides id: " << (*iter)->getId();
|
||||
activeSlides.erase(iter);
|
||||
--iter;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeSlides.size() == 0 && isPlaying)
|
||||
{
|
||||
ofEventArgs args;
|
||||
isPlaying = false;
|
||||
ofNotifyEvent(slideshowCompleteEvent, args, this);
|
||||
}
|
||||
}
|
||||
|
||||
void magSlideShowSource::draw() {
|
||||
ofBackground(0, 0);
|
||||
ofPushMatrix();
|
||||
ofPushStyle();
|
||||
ofTranslate(getWidth()/2.0f, getHeight()/2.0f);
|
||||
ofEnableAlphaBlending();
|
||||
ofSetRectMode(OF_RECTMODE_CENTER);
|
||||
ofFill();
|
||||
ofSetColor(255, 255);
|
||||
for (auto &slide : activeSlides)
|
||||
{
|
||||
slide->draw();
|
||||
}
|
||||
ofPopStyle();
|
||||
ofPopMatrix();
|
||||
ofDisableAlphaBlending();
|
||||
}
|
||||
|
||||
bool magSlideShowSource::createFromFolderContents(std::string path) {
|
||||
ofDirectory dir = ofDirectory(path);
|
||||
slides.clear();
|
||||
|
||||
if (!dir.isDirectory())
|
||||
{
|
||||
ofLogError("magSlideShowSource::createFromFolderContents") << "Folder path " << dir.getAbsolutePath()
|
||||
<< " is not a directory";
|
||||
return false;
|
||||
}
|
||||
|
||||
ofDirectory sortedDir = dir.getSorted();
|
||||
std::vector<ofFile> files = sortedDir.getFiles();
|
||||
|
||||
if (files.size() < 1){
|
||||
ofLogError("magSlideShowSource::createFromFolderContents") << "Folder " << dir.getAbsolutePath() << " is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
ofImage tempImage;
|
||||
for(ofFile &file : files){
|
||||
if (tempImage.load(file.getFileName())){
|
||||
|
||||
// make a new image slide
|
||||
auto slide = std::make_shared<magImageSlide>();
|
||||
slide->setup(tempImage);
|
||||
slide->setDuration(static_cast<u_int64_t>(settings.slideDuration*1000));
|
||||
slide->setTransitionDuration(static_cast<u_int64_t>(settings.transitionDuration*1000));
|
||||
// if (settings.transitionName == "")
|
||||
addSlide(slide);
|
||||
}else{
|
||||
auto ext = ofToLower(file.getExtension());
|
||||
|
||||
static std::vector<std::string> movieExtensions = {
|
||||
"mov", "qt", // Mac
|
||||
"mp4", "m4p", "m4v", // MPEG
|
||||
"mpg", "mp2", "mpeg", "mpe", "mpv", "m2v", // MPEG
|
||||
"3gp", // Phones
|
||||
"avi", "wmv", "asf", // Windows
|
||||
"webm", "mkv", "flv", "vob", // Other containers
|
||||
"ogv", "ogg",
|
||||
"drc", "mxf"
|
||||
};
|
||||
|
||||
// Check if the extension matches known movie formats:
|
||||
if (ofContains(movieExtensions, ext))
|
||||
{
|
||||
// Make a new video slide
|
||||
auto slide = std::make_shared<magVideoSlide>();
|
||||
if (slide->setup(file))
|
||||
{
|
||||
slide->setDuration(settings.slideDuration*1000.0);
|
||||
slide->setTransitionDuration(settings.transitionDuration*1000.0);
|
||||
addSlide(slide);
|
||||
}
|
||||
else
|
||||
{
|
||||
ofLogError("magSlideShowSource") << "Failed loading video: " << file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (slides.size() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool magSlideShowSource::loadFromXml(std::string path) {
|
||||
auto xml = ofxXmlSettings();
|
||||
Settings settings;
|
||||
|
||||
if (!xml.load(path))
|
||||
{
|
||||
ofLogError("magSlideShowSource") << "Could not load settings file " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
// xml.pushTag("surfaces");
|
||||
if (!xml.pushTag("magSlideShow"))
|
||||
{
|
||||
ofLogError("magSlideShowSource") << "Slide show settings not found in " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.width = xml.getValue("Width", settings.width);
|
||||
settings.height = xml.getValue("Height", settings.height);
|
||||
|
||||
// Default slide duration:
|
||||
settings.slideDuration = xml.getValue("SlideDuration", settings.slideDuration);
|
||||
|
||||
// Default loop:
|
||||
if (xml.pushTag("Loop"))
|
||||
{
|
||||
auto type = xml.getValue("Type", "");
|
||||
if (type == "NONE")
|
||||
{
|
||||
settings.loopType = LoopType::NONE;
|
||||
}
|
||||
else if (type == "NORMAL")
|
||||
{
|
||||
settings.loopType = LoopType::NORMAL;
|
||||
}
|
||||
else if (type == "PING-PONG")
|
||||
{
|
||||
settings.loopType = LoopType::PING_PONG;
|
||||
}
|
||||
|
||||
settings.numLoops = xml.getValue("Count", settings.numLoops);
|
||||
xml.popTag();
|
||||
}
|
||||
|
||||
if (xml.pushTag("Transition"))
|
||||
{
|
||||
settings.transitionName = xml.getValue("Type", settings.transitionName);
|
||||
settings.transitionDuration = xml.getValue("Duration", settings.transitionDuration);
|
||||
xml.popTag();
|
||||
}
|
||||
|
||||
// Default resize options:
|
||||
auto ropts = xml.getValue("ResizeOption", "");
|
||||
if (ropts == "NoResize")
|
||||
{
|
||||
settings.resizeOption = magSlide::NoResize;
|
||||
}
|
||||
else if (ropts == "Native")
|
||||
{
|
||||
settings.resizeOption = magSlide::Native;
|
||||
}
|
||||
else if (ropts == "Fit")
|
||||
{
|
||||
settings.resizeOption = magSlide::Fit;
|
||||
}
|
||||
else if (ropts == "FitProportionally")
|
||||
{
|
||||
settings.resizeOption = magSlide::FitProportionally;
|
||||
}
|
||||
else if (ropts == "FillProportionally")
|
||||
{
|
||||
settings.resizeOption = magSlide::FillProportionally;
|
||||
}
|
||||
|
||||
initialize(settings);
|
||||
return true;
|
||||
}
|
||||
|
||||
void magSlideShowSource::addSlide(std::shared_ptr<magSlide> slide) {
|
||||
// ofLogVerbose("addSlide") << slide->getId();
|
||||
slides.insert(slides.begin(), slide);
|
||||
auto rOption = slide->getResizeOption();
|
||||
|
||||
// If the slide does not have a resize option assign
|
||||
// the slide show's option
|
||||
if (rOption == magSlide::ResizeOptions::NoResize)
|
||||
{
|
||||
rOption = settings.resizeOption;
|
||||
}
|
||||
|
||||
// Resize the slide according to the resize option:
|
||||
switch (rOption){
|
||||
float sw, sh, ratio;
|
||||
|
||||
case magSlide::ResizeOptions::FitProportionally:
|
||||
sw = slide->getWidth();
|
||||
sh = slide->getHeight();
|
||||
|
||||
if (sw > sh)
|
||||
{
|
||||
ratio = (float) getWidth()/sw;
|
||||
}
|
||||
else
|
||||
{
|
||||
ratio = (float) getHeight()/sh;
|
||||
}
|
||||
|
||||
slide->setSize(sw*ratio, sh*ratio);
|
||||
break;
|
||||
|
||||
case magSlide::ResizeOptions::FillProportionally:
|
||||
sw = slide->getWidth();
|
||||
sh = slide->getHeight();
|
||||
|
||||
if (sw > sh)
|
||||
{
|
||||
ratio = (float) getHeight()/sh;
|
||||
}
|
||||
else
|
||||
{
|
||||
ratio = (float) getWidth()/sw;
|
||||
}
|
||||
|
||||
slide->setSize(sw*ratio, sh*ratio);
|
||||
break;
|
||||
|
||||
case magSlide::Fit:
|
||||
slide->setSize(getWidth(), getHeight());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Add transitions:
|
||||
|
||||
static ofParameterGroup bogusParamGroup; // This is temporary so that things compile
|
||||
|
||||
auto tf = magSlideTransitionFactory::instance();
|
||||
// slide->buildIn = tf->createTransition(settings.transitionName,
|
||||
// slide,
|
||||
// bogusParamGroup,
|
||||
// slide->buildInDuration);
|
||||
slide->transition = tf->createTransition(settings.transitionName,
|
||||
slide,
|
||||
bogusParamGroup,
|
||||
slide->buildOutDuration);
|
||||
|
||||
//// void method(const void * sender, ArgumentsType &args)
|
||||
ofAddListener(slide->slideStateChangedEvent, this, &magSlideShowSource::slideStateChanged);
|
||||
ofAddListener(slide->slideCompleteEvent, this, &magSlideShowSource::slideComplete);
|
||||
|
||||
}
|
||||
|
||||
void magSlideShowSource::play() {
|
||||
if (!isPlaying && slides.size()){
|
||||
runningTime = 0;
|
||||
lastTime = ofGetElapsedTimeMillis();
|
||||
isPlaying = true;
|
||||
auto currentSlide = slides[currentSlideIndex];
|
||||
enqueueSlide(currentSlide, ofGetElapsedTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
void magSlideShowSource::pause() {
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
void magSlideShowSource::playNextSlide() {
|
||||
//TODO
|
||||
// I should check here to see if there are less than two slides.
|
||||
// If so, we should probably return
|
||||
|
||||
currentSlideIndex += direction;
|
||||
ofEventArgs args;
|
||||
|
||||
// This makes sure that we are doing a signed integer comparison,
|
||||
// otherwise things get weird
|
||||
int num = slides.size();
|
||||
switch (settings.loopType)
|
||||
{
|
||||
case LoopType::NONE:
|
||||
if (currentSlideIndex >= slides.size() || currentSlideIndex < 0)
|
||||
{
|
||||
// If we are not looping and we are out of bounds, return
|
||||
// without enqueueing a slide. This will cause the slide show
|
||||
// to end once the last slide builds out.
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case LoopType::NORMAL:
|
||||
if (currentSlideIndex >= num)
|
||||
{
|
||||
loopCount++;
|
||||
if (loopCount == settings.numLoops)
|
||||
{
|
||||
// Return without enqueueing a new slide if we have
|
||||
// reached the max number of loops.
|
||||
return;
|
||||
}
|
||||
currentSlideIndex = 0;
|
||||
ofNotifyEvent(slideshowWillLoopEvent, args, this);
|
||||
}
|
||||
else if (currentSlideIndex < 0)
|
||||
{
|
||||
loopCount++;
|
||||
if (loopCount == settings.numLoops)
|
||||
{
|
||||
// Return without enqueueing a new slide if we have
|
||||
// reached the max number of loops.
|
||||
return;
|
||||
}
|
||||
currentSlideIndex = slides.size()-1;
|
||||
ofNotifyEvent(slideshowWillLoopEvent, args, this);
|
||||
}
|
||||
break;
|
||||
case LoopType::PING_PONG:
|
||||
|
||||
int num = slides.size();
|
||||
if (currentSlideIndex >= num)
|
||||
{
|
||||
loopCount++;
|
||||
if (loopCount == settings.numLoops)
|
||||
{
|
||||
// Return without enqueueing a new slide if we have
|
||||
// reached the max number of loops.
|
||||
return;
|
||||
}
|
||||
|
||||
direction = -1;
|
||||
currentSlideIndex = slides.size()-2;
|
||||
ofNotifyEvent(slideshowWillLoopEvent, args, this);
|
||||
}
|
||||
else if (currentSlideIndex < 0)
|
||||
{
|
||||
loopCount++;
|
||||
if (loopCount == settings.numLoops)
|
||||
{
|
||||
// Return without enqueueing a new slide if we have
|
||||
// reached the max number of loops.
|
||||
return;
|
||||
}
|
||||
|
||||
direction = 1;
|
||||
currentSlideIndex = 1;
|
||||
ofNotifyEvent(slideshowWillLoopEvent, args, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
enqueueSlide(slides[currentSlideIndex], ofGetElapsedTimeMillis());
|
||||
}
|
||||
|
||||
void magSlideShowSource::playPrevSlide() {
|
||||
currentSlideIndex -= (direction*2);
|
||||
playNextSlide();
|
||||
}
|
||||
|
||||
void magSlideShowSource::playSlide(int slideIndex) {
|
||||
currentSlideIndex = slideIndex-direction;
|
||||
playNextSlide();
|
||||
}
|
||||
|
||||
void magSlideShowSource::enqueueSlide(std::shared_ptr<magSlide> slide, u_int64_t startTime) {
|
||||
// ofLogVerbose() << "Enqueuing slide " << currentSlideIndex << " slide id: " << slide->getId();
|
||||
slide->start(startTime);
|
||||
activeSlides.insert(activeSlides.begin(), slide);
|
||||
}
|
||||
|
||||
void magSlideShowSource::slideStateChanged(const void *sender, ofEventArgs &args) {
|
||||
magSlide *slide = (magSlide *) sender;
|
||||
|
||||
// ofLogVerbose("slideStateChanged") << "Slide id: " << slide->getId() << " Slide state: "
|
||||
// << slide->getSlideStateName();
|
||||
if (slide->getSlideState() == magSlide::SlideState::BuildOut)
|
||||
{
|
||||
// Flag that we need to load the next slide:
|
||||
doPlayNextSlide = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void magSlideShowSource::slideComplete(const void *sender, ofEventArgs &args) {
|
||||
magSlide *slide = (magSlide *) sender;
|
||||
// ofLogVerbose() << "Slide Complete. id: " << slide->getId();
|
||||
slide->isComplete = true;
|
||||
}
|
||||
|
||||
void magSlideShowSource::fileAddedListener(const void *sender) {
|
||||
doInit = true;
|
||||
}
|
||||
|
||||
void magSlideShowSource::fileRemovedListener(const void *sender) {
|
||||
doInit = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
//
|
||||
// magSlideShowSource.h
|
||||
// Copyright (c) 2017 Cristobal Mendoza
|
||||
// http://cuppetellimendoza.com
|
||||
//
|
||||
|
||||
#ifndef MAGSLIDESHOWSOURCE_H
|
||||
#define MAGSLIDESHOWSOURCE_H
|
||||
|
||||
#include "FboSource.h"
|
||||
#include "magSlide.h"
|
||||
#include "DirectoryWatcher.h"
|
||||
|
||||
class magSlide;
|
||||
|
||||
class magSlideShowSource : public ofx::piMapper::FboSource {
|
||||
public:
|
||||
magSlideShowSource();
|
||||
|
||||
/**
|
||||
* Default settings file name.
|
||||
*/
|
||||
static const std::string SettingsFileName;
|
||||
struct Settings; // forward declaration
|
||||
bool initialize(magSlideShowSource::Settings settings);
|
||||
void setup() override;
|
||||
void update() override;
|
||||
void draw() override;
|
||||
|
||||
/**
|
||||
* Removes all slides and then attempts to create a new slide show
|
||||
* based on the contents of the ofDirectory specified. The files may
|
||||
* be images or videos, which will be transformed into the appropriate slide type.
|
||||
* Any other file type in the directory is ignored (including other directories).
|
||||
* The slide order is alphabetical according to filename.
|
||||
*
|
||||
* @param dir The ofDirectory to use as a source for a slide show.
|
||||
* @return true if at least one slide was created. false is returned
|
||||
* otherwise. Check the console for the specific error.
|
||||
*/
|
||||
bool createFromFolderContents(std::string path);
|
||||
bool loadFromXml(std::string path);
|
||||
void addSlide(std::shared_ptr<magSlide> slide);
|
||||
void play();
|
||||
void pause();
|
||||
void playNextSlide();
|
||||
void playPrevSlide();
|
||||
void playSlide(int slideIndex);
|
||||
|
||||
enum LoopType : int {
|
||||
NONE = 0,
|
||||
NORMAL,
|
||||
PING_PONG
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
/**
|
||||
* The pixel width of the FBO.
|
||||
*/
|
||||
float width = 1280;
|
||||
|
||||
/**
|
||||
* The pixel height of the FBO.
|
||||
*/
|
||||
float height = 720;
|
||||
/**
|
||||
* An optional default slide duration, in seconds.
|
||||
* If a slide specifies a duration this value is ignored.
|
||||
*/
|
||||
float slideDuration = 5;
|
||||
|
||||
/**
|
||||
* The default transition for the slide show.
|
||||
*/
|
||||
std::string transitionName = "Dissolve";
|
||||
|
||||
/**
|
||||
* Default transition duration.
|
||||
*/
|
||||
float transitionDuration = 1;
|
||||
|
||||
/**
|
||||
* If specified, all applicable files in the folder will
|
||||
* be used as slides in the slide show. They will be ordered
|
||||
* alphabetically according to their file names.
|
||||
*
|
||||
* If path is relative, the root will likely be the Data folder.
|
||||
*/
|
||||
std::string slidesFolderPath = "sources/images";
|
||||
|
||||
/**
|
||||
* If specified,
|
||||
*/
|
||||
std::string slideshowFilePath;
|
||||
|
||||
|
||||
/**
|
||||
* Loop type for the slide show. See @code LoopType for options.
|
||||
* The default is @code LoopType:None.
|
||||
*/
|
||||
LoopType loopType = LoopType::NONE;
|
||||
|
||||
/**
|
||||
* The number of loops to perform, if the loopType is not NONE.
|
||||
* If the value is 0 or less than 0, the slide show loops forever.
|
||||
*/
|
||||
int numLoops = 0;
|
||||
|
||||
/**
|
||||
* The resizing option for the slide show. The default is FitProportionally.
|
||||
* If a slide already has a resizing option applied, that option will be
|
||||
* respected and this resizeOption will not be used.
|
||||
*/
|
||||
magSlide::ResizeOptions resizeOption = magSlide::ResizeOptions::FitProportionally;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
//// Event Listeners
|
||||
////////////////////////////////////////////
|
||||
void slideStateChanged(const void *sender, ofEventArgs &args);
|
||||
void slideComplete(const void *sender, ofEventArgs &args);
|
||||
virtual ~magSlideShowSource();
|
||||
|
||||
|
||||
/**
|
||||
* Fires when the slide show is done, which happens when
|
||||
* the loop count is equal to Settings::numLoops, or when
|
||||
* the last slide is played when @code LoopType::NONE is specified.
|
||||
* Sender is this slide show.
|
||||
*/
|
||||
ofEvent<ofEventArgs> slideshowCompleteEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Fires when the slide show reaches the last slide
|
||||
* and will perform a loop in the next call.
|
||||
* Sender is this slide show.
|
||||
*/
|
||||
ofEvent<ofEventArgs> slideshowWillLoopEvent;
|
||||
|
||||
protected:
|
||||
Settings settings;
|
||||
std::vector<std::shared_ptr<magSlide>> slides;
|
||||
|
||||
private:
|
||||
// std::shared_ptr<magSlide> currentSlide;
|
||||
std::vector<std::shared_ptr<magSlide>> activeSlides;
|
||||
void enqueueSlide(std::shared_ptr<magSlide> slide, u_int64_t startTime);
|
||||
|
||||
u_int64_t lastTime;
|
||||
u_int64_t deltaTime;
|
||||
u_int64_t runningTime;
|
||||
|
||||
bool isInitialized = false;
|
||||
bool isPlaying = false;
|
||||
int currentSlideIndex = 0;
|
||||
int direction = 1;
|
||||
int loopCount = 0;
|
||||
ofx::piMapper::DirectoryWatcher * directoryWatcher;
|
||||
void fileAddedListener(const void * sender);
|
||||
void fileRemovedListener(const void * sender);
|
||||
bool doInit;
|
||||
bool doPlayNextSlide = false;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
//
|
||||
// magSlideTransition.cpp
|
||||
// Copyright (c) 2017 Cristobal Mendoza
|
||||
// http://cuppetellimendoza.com
|
||||
//
|
||||
|
||||
#include "magSlideTransition.h"
|
||||
|
||||
void magSlideTransition::start(std::shared_ptr<magSlide> nextSlide)
|
||||
{
|
||||
runningTime = 0;
|
||||
active = true;
|
||||
this->nextSlide = nextSlide;
|
||||
}
|
||||
|
||||
void magSlideTransition::update(u_int64_t timeDelta)
|
||||
{
|
||||
if (!active) return;
|
||||
|
||||
runningTime += timeDelta;
|
||||
if (runningTime >= duration)
|
||||
{
|
||||
ofEventArgs arghh; // arghhhh...
|
||||
nextSlide->setOpacity(255);
|
||||
nextSlide->setPosition(0, 0);
|
||||
end();
|
||||
transitionCompleteEvent.notify(this, arghh);
|
||||
active = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u_int64_t magSlideTransition::getRunningTime()
|
||||
{
|
||||
return runningTime;
|
||||
}
|
||||
|
||||
float magSlideTransition::getNormalizedTime()
|
||||
{
|
||||
return (double)runningTime / (double)duration;
|
||||
}
|
||||
|
||||
|
||||
void magDissolveTransition::draw()
|
||||
{
|
||||
slide->setOpacity(255 - (getNormalizedTime() * 255));
|
||||
nextSlide->setOpacity(getNormalizedTime()*255);
|
||||
}
|
||||
|
||||
void magDissolveTransition::start(std::shared_ptr<magSlide> nextSlide)
|
||||
{
|
||||
magSlideTransition::start(nextSlide);
|
||||
nextSlide->setOpacity(0);
|
||||
}
|
||||
|
||||
void magDissolveTransition::end()
|
||||
{
|
||||
nextSlide->setOpacity(255);
|
||||
slide->setOpacity(0);
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
//
|
||||
// magSlideTransition.h
|
||||
// Copyright (c) 2017 Cristobal Mendoza
|
||||
// http://cuppetellimendoza.com
|
||||
//
|
||||
|
||||
#ifndef MAGSLIDETRANSITION_H
|
||||
#define MAGSLIDETRANSITION_H
|
||||
|
||||
#include "magSlide.h"
|
||||
|
||||
class magSlideTransitionFactory;
|
||||
|
||||
class magSlideTransition
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Subclassing notes: Make sure to provide a value for name in your
|
||||
* magSlideTransition subclass.
|
||||
*/
|
||||
magSlideTransition() { name = "Void"; }
|
||||
/**
|
||||
* Begins the transition. This needs to be called in order for the
|
||||
* transition to do anything.
|
||||
* @param nextSlide The subsequent slide in the slide show needs to be
|
||||
* passed here.
|
||||
*
|
||||
* You can override this call to set any initial conditions to the transition,
|
||||
* but make sure to call this method in your override.
|
||||
*/
|
||||
virtual void start(std::shared_ptr<magSlide> nextSlide);
|
||||
|
||||
/**
|
||||
* Called automatically when the transition is complete. Useful to set
|
||||
* end states for the parameters of the slide and nextSlide. Default implementation
|
||||
* does nothing.
|
||||
*/
|
||||
virtual void end(){}
|
||||
|
||||
/**
|
||||
* NOTE: The transition settings system is not yet implemented.
|
||||
* Called when the transition is created. Loads settings for magSlideTransition
|
||||
* subclasses. The default implementation does nothing.
|
||||
* @param settings ofParameterGroup with settings for your custom magSlideTransition
|
||||
* subclass.
|
||||
*/
|
||||
virtual void loadSettings(ofParameterGroup &settings){}
|
||||
|
||||
/**
|
||||
* Updates the transition.
|
||||
* @param timeDelta The elapsed time (in ms.) between the last call to update() and
|
||||
* this one (i.e. the frame time).
|
||||
*
|
||||
* If you need to override update, make sure to call this implementation
|
||||
* in your subclass.
|
||||
*/
|
||||
virtual void update(u_int64_t timeDelta);
|
||||
|
||||
/**
|
||||
* Draws the transition. Default implementation does nothing.
|
||||
*/
|
||||
virtual void draw(){
|
||||
ofLogNotice("magSlideTransition") << "transition draw - this should be overriden " << getNormalizedTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Current running time in milliseconds.
|
||||
* @return u_int64_t
|
||||
*/
|
||||
u_int64_t getRunningTime();
|
||||
|
||||
/**
|
||||
* Returns the current time in normalized form.
|
||||
* 0 = start, 1 = end.
|
||||
* @return Float between 0 and 1.
|
||||
*/
|
||||
float getNormalizedTime();
|
||||
|
||||
std::string const &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const shared_ptr<magSlide> &getNextSlide() const
|
||||
{
|
||||
return nextSlide;
|
||||
}
|
||||
|
||||
bool isActive() const
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sender is a raw pointer to this magSlideTransition
|
||||
*/
|
||||
ofEvent<ofEventArgs> transitionCompleteEvent;
|
||||
|
||||
protected:
|
||||
std::string name;
|
||||
std::shared_ptr<magSlide> slide;
|
||||
std::shared_ptr<magSlide> nextSlide;
|
||||
|
||||
u_int64_t runningTime;
|
||||
u_int64_t duration;
|
||||
u_int64_t endTime;
|
||||
bool active = false;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
friend class magSlideTransitionFactory;
|
||||
};
|
||||
|
||||
class magDissolveTransition : public magSlideTransition
|
||||
{
|
||||
public:
|
||||
magDissolveTransition()
|
||||
{
|
||||
name = "Dissolve";
|
||||
}
|
||||
|
||||
void start(std::shared_ptr<magSlide> nextSlide) override;
|
||||
|
||||
void draw() override;
|
||||
void end() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,76 +0,0 @@
|
||||
//
|
||||
// Created by Cristobal Mendoza on 12/3/17.
|
||||
//
|
||||
|
||||
#include "magSlideTransitionFactory.h"
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
class Base {};
|
||||
|
||||
class DerivedA : public Base {};
|
||||
class DerivedB : public Base {};
|
||||
class DerivedC : public Base {};
|
||||
|
||||
Base* create(const std::string& type)
|
||||
{
|
||||
static std::map<std::string, std::function<Base*()>> type_creator_map =
|
||||
{
|
||||
{"DerivedA", [](){return new DerivedA();}},
|
||||
{"DerivedB", [](){return new DerivedB();}},
|
||||
{"DerivedC", [](){return new DerivedC();}}
|
||||
};
|
||||
|
||||
auto it = type_creator_map.find(type);
|
||||
if(it != type_creator_map.end())
|
||||
{
|
||||
return it->second();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
*/
|
||||
|
||||
magSlideTransitionFactory* magSlideTransitionFactory::_instance = 0;
|
||||
|
||||
magSlideTransitionFactory::magSlideTransitionFactory()
|
||||
{
|
||||
magSlideTransition voidTransition;
|
||||
magDissolveTransition dissolve;
|
||||
|
||||
registerTransition<magSlideTransition>(voidTransition);
|
||||
registerTransition<magDissolveTransition>(dissolve);
|
||||
}
|
||||
|
||||
magSlideTransitionFactory* magSlideTransitionFactory::instance()
|
||||
{
|
||||
if (_instance == 0)
|
||||
{
|
||||
_instance = new magSlideTransitionFactory();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
std::shared_ptr<magSlideTransition>
|
||||
magSlideTransitionFactory::createTransition(std::string transitionName, std::shared_ptr<magSlide> slide,
|
||||
ofParameterGroup &settings, u_int64_t duration)
|
||||
{
|
||||
std::shared_ptr<magSlideTransition> transition;
|
||||
|
||||
if (transitionsMap.count(transitionName) > 0)
|
||||
{
|
||||
transition = transitionsMap[transitionName]();
|
||||
}
|
||||
else
|
||||
{
|
||||
transition = transitionsMap[transition->getName()]();
|
||||
}
|
||||
|
||||
transition->slide = slide;
|
||||
transition->duration = duration;
|
||||
transition->loadSettings(settings);
|
||||
return transition;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
//
|
||||
// Created by Cristobal Mendoza on 12/3/17.
|
||||
//
|
||||
|
||||
#ifndef MAGSLIDETRANSITIONFACTORY_H
|
||||
#define MAGSLIDETRANSITIONFACTORY_H
|
||||
|
||||
#include "magSlide.h"
|
||||
#include "magSlideTransition.h"
|
||||
|
||||
/**
|
||||
* Factory class to register and instantiate transitions.
|
||||
*/
|
||||
class magSlideTransitionFactory
|
||||
{
|
||||
public:
|
||||
static magSlideTransitionFactory* instance();
|
||||
|
||||
std::shared_ptr<magSlideTransition> createTransition(std::string transitionName,
|
||||
std::shared_ptr<magSlide> slide,
|
||||
ofParameterGroup &group,
|
||||
u_int64_t duration);
|
||||
template<typename T>
|
||||
void registerTransition(T transition)
|
||||
{
|
||||
if (transitionsMap.count(transition.getName()) == 0)
|
||||
{
|
||||
transitionsMap[transition.getName()] = [](){
|
||||
return std::make_shared<T>();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unordered_map<std::string, std::function<std::shared_ptr<magSlideTransition>()>> transitionsMap;
|
||||
private:
|
||||
static magSlideTransitionFactory* _instance;
|
||||
magSlideTransitionFactory();
|
||||
};
|
||||
|
||||
#endif //MAGSLIDETRANSITIONFACTORY_H
|
||||
Reference in New Issue
Block a user