From 7549b3a0926e5c9f6131ec5423e81eac2cf896d8 Mon Sep 17 00:00:00 2001 From: cg2121 Date: Fri, 4 Aug 2017 21:10:05 -0700 Subject: [PATCH] image-source: Add "manual (hotkey)" mode to image slideshow Allows traversing/stopping the slideshow via hotkeys. Split from jp9000/obs-studio#976 --- plugins/image-source/data/locale/en-US.ini | 8 + plugins/image-source/obs-slideshow.c | 180 ++++++++++++++++++++- 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/plugins/image-source/data/locale/en-US.ini b/plugins/image-source/data/locale/en-US.ini index f90a7c9ba..21c275ec7 100644 --- a/plugins/image-source/data/locale/en-US.ini +++ b/plugins/image-source/data/locale/en-US.ini @@ -19,6 +19,14 @@ SlideShow.PlaybackBehavior="Visibility Behavior" SlideShow.PlaybackBehavior.StopRestart="Stop when not visible, restart when visible" SlideShow.PlaybackBehavior.PauseUnpause="Pause when not visible, unpause when 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" ColorSource="Color Source" diff --git a/plugins/image-source/obs-slideshow.c b/plugins/image-source/obs-slideshow.c index 00ca48969..7a688d63e 100644 --- a/plugins/image-source/obs-slideshow.c +++ b/plugins/image-source/obs-slideshow.c @@ -22,6 +22,9 @@ #define S_BEHAVIOR_STOP_RESTART "stop_restart" #define S_BEHAVIOR_PAUSE_UNPAUSE "pause_unpause" #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_FADE "fade" @@ -42,6 +45,9 @@ #define T_BEHAVIOR_STOP_RESTART T_("PlaybackBehavior.StopRestart") #define T_BEHAVIOR_PAUSE_UNPAUSE T_("PlaybackBehavior.PauseUnpause") #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_CUT T_TR_("Cut") @@ -70,6 +76,7 @@ struct slideshow { bool restart_on_activate; bool pause_on_deactivate; bool restart; + bool manual; bool hide; bool use_cut; bool paused; @@ -89,6 +96,12 @@ struct slideshow { DARRAY(struct image_file_data) files; 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) @@ -241,6 +254,7 @@ static void ss_update(void *data, obs_data_t *settings) uint32_t cy = 0; size_t count; const char *behavior; + const char *mode; /* ------------------------------------- */ /* get settings data */ @@ -256,6 +270,10 @@ static void ss_update(void *data, obs_data_t *settings) else /* S_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); if (astrcmpi(tr_name, TR_CUT) == 0) tr_name = "cut_transition"; @@ -411,6 +429,134 @@ static void ss_update(void *data, obs_data_t *settings) 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) { struct slideshow *ss = data; @@ -427,9 +573,35 @@ static void *ss_create(obs_data_t *settings, obs_source_t *source) ss->source = source; + ss->manual = false; ss->paused = 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); if (pthread_mutex_init(&ss->mutex, NULL) != 0) goto error; @@ -474,7 +646,7 @@ static void ss_video_tick(void *data, float seconds) return; } - if (ss->pause_on_deactivate || ss->stop || ss->paused) + if (ss->pause_on_deactivate || ss->manual || ss->stop || ss->paused) return; 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_BEHAVIOR, S_BEHAVIOR_ALWAYS_PLAY); + obs_data_set_default_string(settings, S_MODE, S_MODE_AUTO); 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, 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, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_TR_CUT, TR_CUT);