image-source: Add "manual (hotkey)" mode to image slideshow

Allows traversing/stopping the slideshow via hotkeys.

Split from jp9000/obs-studio#976
master
cg2121 2017-08-04 21:10:05 -07:00 committed by jp9000
parent 1666abe8e6
commit 7549b3a092
2 changed files with 187 additions and 1 deletions

View File

@ -19,6 +19,14 @@ SlideShow.PlaybackBehavior="Visibility Behavior"
SlideShow.PlaybackBehavior.StopRestart="Stop when not visible, restart when visible" SlideShow.PlaybackBehavior.StopRestart="Stop when not visible, restart when visible"
SlideShow.PlaybackBehavior.PauseUnpause="Pause when not visible, unpause when visible" SlideShow.PlaybackBehavior.PauseUnpause="Pause when not visible, unpause when visible"
SlideShow.PlaybackBehavior.AlwaysPlay="Always play even when not visible" SlideShow.PlaybackBehavior.AlwaysPlay="Always play even when not visible"
SlideShow.SlideMode="Slide Mode"
SlideShow.SlideMode.Auto="Automatic"
SlideShow.SlideMode.Manual="Manual (Use hotkeys to control slideshow)"
SlideShow.PlayPause="Play/Pause"
SlideShow.Restart="Restart"
SlideShow.Stop="Stop"
SlideShow.NextSlide="Next Slide"
SlideShow.PreviousSlide="Previous Slide"
SlideShow.HideWhenDone="Hide when slideshow is done" SlideShow.HideWhenDone="Hide when slideshow is done"
ColorSource="Color Source" ColorSource="Color Source"

View File

@ -22,6 +22,9 @@
#define S_BEHAVIOR_STOP_RESTART "stop_restart" #define S_BEHAVIOR_STOP_RESTART "stop_restart"
#define S_BEHAVIOR_PAUSE_UNPAUSE "pause_unpause" #define S_BEHAVIOR_PAUSE_UNPAUSE "pause_unpause"
#define S_BEHAVIOR_ALWAYS_PLAY "always_play" #define S_BEHAVIOR_ALWAYS_PLAY "always_play"
#define S_MODE "slide_mode"
#define S_MODE_AUTO "mode_auto"
#define S_MODE_MANUAL "mode_manual"
#define TR_CUT "cut" #define TR_CUT "cut"
#define TR_FADE "fade" #define TR_FADE "fade"
@ -42,6 +45,9 @@
#define T_BEHAVIOR_STOP_RESTART T_("PlaybackBehavior.StopRestart") #define T_BEHAVIOR_STOP_RESTART T_("PlaybackBehavior.StopRestart")
#define T_BEHAVIOR_PAUSE_UNPAUSE T_("PlaybackBehavior.PauseUnpause") #define T_BEHAVIOR_PAUSE_UNPAUSE T_("PlaybackBehavior.PauseUnpause")
#define T_BEHAVIOR_ALWAYS_PLAY T_("PlaybackBehavior.AlwaysPlay") #define T_BEHAVIOR_ALWAYS_PLAY T_("PlaybackBehavior.AlwaysPlay")
#define T_MODE T_("SlideMode")
#define T_MODE_AUTO T_("SlideMode.Auto")
#define T_MODE_MANUAL T_("SlideMode.Manual")
#define T_TR_(text) obs_module_text("SlideShow.Transition." text) #define T_TR_(text) obs_module_text("SlideShow.Transition." text)
#define T_TR_CUT T_TR_("Cut") #define T_TR_CUT T_TR_("Cut")
@ -70,6 +76,7 @@ struct slideshow {
bool restart_on_activate; bool restart_on_activate;
bool pause_on_deactivate; bool pause_on_deactivate;
bool restart; bool restart;
bool manual;
bool hide; bool hide;
bool use_cut; bool use_cut;
bool paused; bool paused;
@ -89,6 +96,12 @@ struct slideshow {
DARRAY(struct image_file_data) files; DARRAY(struct image_file_data) files;
enum behavior behavior; enum behavior behavior;
obs_hotkey_id play_pause_hotkey;
obs_hotkey_id restart_hotkey;
obs_hotkey_id stop_hotkey;
obs_hotkey_id next_hotkey;
obs_hotkey_id prev_hotkey;
}; };
static obs_source_t *get_transition(struct slideshow *ss) static obs_source_t *get_transition(struct slideshow *ss)
@ -241,6 +254,7 @@ static void ss_update(void *data, obs_data_t *settings)
uint32_t cy = 0; uint32_t cy = 0;
size_t count; size_t count;
const char *behavior; const char *behavior;
const char *mode;
/* ------------------------------------- */ /* ------------------------------------- */
/* get settings data */ /* get settings data */
@ -256,6 +270,10 @@ static void ss_update(void *data, obs_data_t *settings)
else /* S_BEHAVIOR_STOP_RESTART */ else /* S_BEHAVIOR_STOP_RESTART */
ss->behavior = BEHAVIOR_STOP_RESTART; ss->behavior = BEHAVIOR_STOP_RESTART;
mode = obs_data_get_string(settings, S_MODE);
ss->manual = (astrcmpi(mode, S_MODE_MANUAL) == 0);
tr_name = obs_data_get_string(settings, S_TRANSITION); tr_name = obs_data_get_string(settings, S_TRANSITION);
if (astrcmpi(tr_name, TR_CUT) == 0) if (astrcmpi(tr_name, TR_CUT) == 0)
tr_name = "cut_transition"; tr_name = "cut_transition";
@ -411,6 +429,134 @@ static void ss_update(void *data, obs_data_t *settings)
obs_data_array_release(array); obs_data_array_release(array);
} }
static void ss_play_pause(void *data)
{
struct slideshow *ss = data;
ss->paused = !ss->paused;
ss->manual = ss->paused;
}
static void ss_restart(void *data)
{
struct slideshow *ss = data;
ss->elapsed = 0.0f;
ss->cur_item = 0;
obs_transition_set(ss->transition,
ss->files.array[ss->cur_item].source);
ss->stop = false;
ss->paused = false;
}
static void ss_stop(void *data)
{
struct slideshow *ss = data;
ss->elapsed = 0.0f;
ss->cur_item = 0;
do_transition(ss, true);
ss->stop = true;
ss->paused = false;
}
static void ss_next_slide(void *data)
{
struct slideshow *ss = data;
if (!ss->files.num)
return;
if (++ss->cur_item >= ss->files.num)
ss->cur_item = 0;
do_transition(ss, false);
}
static void ss_previous_slide(void *data)
{
struct slideshow *ss = data;
if (!ss->files.num)
return;
if (ss->cur_item == 0)
ss->cur_item = ss->files.num - 1;
else
--ss->cur_item;
do_transition(ss, false);
}
static void play_pause_hotkey(void *data, obs_hotkey_id id,
obs_hotkey_t *hotkey, bool pressed)
{
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(hotkey);
struct slideshow *ss = data;
if (pressed && obs_source_active(ss->source))
ss_play_pause(ss);
}
static void restart_hotkey(void *data, obs_hotkey_id id,
obs_hotkey_t *hotkey, bool pressed)
{
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(hotkey);
struct slideshow *ss = data;
if (pressed && obs_source_active(ss->source))
ss_restart(ss);
}
static void stop_hotkey(void *data, obs_hotkey_id id,
obs_hotkey_t *hotkey, bool pressed)
{
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(hotkey);
struct slideshow *ss = data;
if (pressed && obs_source_active(ss->source))
ss_stop(ss);
}
static void next_slide_hotkey(void *data, obs_hotkey_id id,
obs_hotkey_t *hotkey, bool pressed)
{
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(hotkey);
struct slideshow *ss = data;
if (!ss->manual)
return;
if (pressed && obs_source_active(ss->source))
ss_next_slide(ss);
}
static void previous_slide_hotkey(void *data, obs_hotkey_id id,
obs_hotkey_t *hotkey, bool pressed)
{
UNUSED_PARAMETER(id);
UNUSED_PARAMETER(hotkey);
struct slideshow *ss = data;
if (!ss->manual)
return;
if (pressed && obs_source_active(ss->source))
ss_previous_slide(ss);
}
static void ss_destroy(void *data) static void ss_destroy(void *data)
{ {
struct slideshow *ss = data; struct slideshow *ss = data;
@ -427,9 +573,35 @@ static void *ss_create(obs_data_t *settings, obs_source_t *source)
ss->source = source; ss->source = source;
ss->manual = false;
ss->paused = false; ss->paused = false;
ss->stop = false; ss->stop = false;
ss->play_pause_hotkey = obs_hotkey_register_source(source,
"SlideShow.PlayPause",
obs_module_text("SlideShow.PlayPause"),
play_pause_hotkey, ss);
ss->restart_hotkey = obs_hotkey_register_source(source,
"SlideShow.Restart",
obs_module_text("SlideShow.Restart"),
restart_hotkey, ss);
ss->stop_hotkey = obs_hotkey_register_source(source,
"SlideShow.Stop",
obs_module_text("SlideShow.Stop"),
stop_hotkey, ss);
ss->prev_hotkey = obs_hotkey_register_source(source,
"SlideShow.NextSlide",
obs_module_text("SlideShow.NextSlide"),
next_slide_hotkey, ss);
ss->prev_hotkey = obs_hotkey_register_source(source,
"SlideShow.PreviousSlide",
obs_module_text("SlideShow.PreviousSlide"),
previous_slide_hotkey, ss);
pthread_mutex_init_value(&ss->mutex); pthread_mutex_init_value(&ss->mutex);
if (pthread_mutex_init(&ss->mutex, NULL) != 0) if (pthread_mutex_init(&ss->mutex, NULL) != 0)
goto error; goto error;
@ -474,7 +646,7 @@ static void ss_video_tick(void *data, float seconds)
return; return;
} }
if (ss->pause_on_deactivate || ss->stop || ss->paused) if (ss->pause_on_deactivate || ss->manual || ss->stop || ss->paused)
return; return;
ss->elapsed += seconds; ss->elapsed += seconds;
@ -590,6 +762,7 @@ static void ss_defaults(obs_data_t *settings)
obs_data_set_default_string(settings, S_CUSTOM_SIZE, T_CUSTOM_SIZE_AUTO); obs_data_set_default_string(settings, S_CUSTOM_SIZE, T_CUSTOM_SIZE_AUTO);
obs_data_set_default_string(settings, S_BEHAVIOR, obs_data_set_default_string(settings, S_BEHAVIOR,
S_BEHAVIOR_ALWAYS_PLAY); S_BEHAVIOR_ALWAYS_PLAY);
obs_data_set_default_string(settings, S_MODE, S_MODE_AUTO);
obs_data_set_default_bool(settings, S_LOOP, true); obs_data_set_default_bool(settings, S_LOOP, true);
} }
@ -632,6 +805,11 @@ static obs_properties_t *ss_properties(void *data)
obs_property_list_add_string(p, T_BEHAVIOR_PAUSE_UNPAUSE, obs_property_list_add_string(p, T_BEHAVIOR_PAUSE_UNPAUSE,
S_BEHAVIOR_PAUSE_UNPAUSE); S_BEHAVIOR_PAUSE_UNPAUSE);
p = obs_properties_add_list(ppts, S_MODE, T_MODE,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_list_add_string(p, T_MODE_AUTO, S_MODE_AUTO);
obs_property_list_add_string(p, T_MODE_MANUAL, S_MODE_MANUAL);
p = obs_properties_add_list(ppts, S_TRANSITION, T_TRANSITION, p = obs_properties_add_list(ppts, S_TRANSITION, T_TRANSITION,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_list_add_string(p, T_TR_CUT, TR_CUT); obs_property_list_add_string(p, T_TR_CUT, TR_CUT);