Rename example to example_fbo-sources and move magSlideShowSource there

This commit is contained in:
Krisjanis Rijnieks
2018-03-30 20:05:17 +02:00
parent 95209d320d
commit 79b6ec8a7e
45 changed files with 81 additions and 270 deletions
-202
View File
@@ -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;
}
-263
View File
@@ -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
-531
View File
@@ -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;
}
-167
View File
@@ -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
-60
View File
@@ -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);
}
-129
View File
@@ -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
-76
View File
@@ -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;
}
-41
View File
@@ -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