From cfcad30e3e840675aa030580f5293a7ef5f7d473 Mon Sep 17 00:00:00 2001 From: Clayton Groeneveld Date: Thu, 10 Sep 2020 15:55:03 -0500 Subject: [PATCH] UI, image-source: Add slide counter to slideshow toolbar This shows the current slide and total number of slides in the slideshow toolbar. --- UI/media-controls.cpp | 58 +++++++++++++++++++++++++--- UI/media-controls.hpp | 4 ++ plugins/image-source/obs-slideshow.c | 48 +++++++++++++++-------- 3 files changed, 87 insertions(+), 23 deletions(-) diff --git a/UI/media-controls.cpp b/UI/media-controls.cpp index 0cebe0f59..016094530 100644 --- a/UI/media-controls.cpp +++ b/UI/media-controls.cpp @@ -31,6 +31,18 @@ void MediaControls::OBSMediaStarted(void *data, calldata_t *) QMetaObject::invokeMethod(media, "SetPlayingState"); } +void MediaControls::OBSMediaNext(void *data, calldata_t *) +{ + MediaControls *media = static_cast(data); + QMetaObject::invokeMethod(media, "UpdateSlideCounter"); +} + +void MediaControls::OBSMediaPrevious(void *data, calldata_t *) +{ + MediaControls *media = static_cast(data); + QMetaObject::invokeMethod(media, "UpdateSlideCounter"); +} + MediaControls::MediaControls(QWidget *parent) : QWidget(parent), ui(new Ui::MediaControls) { @@ -196,6 +208,7 @@ void MediaControls::SetPlayingState() prevPaused = false; + UpdateSlideCounter(); StartMediaTimer(); } @@ -219,8 +232,15 @@ void MediaControls::SetRestartState() QTStr("ContextBar.MediaControls.RestartMedia")); ui->slider->setValue(0); - ui->timerLabel->setText("--:--:--"); - ui->durationLabel->setText("--:--:--"); + + if (!isSlideshow) { + ui->timerLabel->setText("--:--:--"); + ui->durationLabel->setText("--:--:--"); + } else { + ui->timerLabel->setText("-"); + ui->durationLabel->setText("-"); + } + ui->slider->setEnabled(false); StopMediaTimer(); @@ -255,9 +275,6 @@ void MediaControls::RefreshControls() isSlideshow = strcmp(id, "slideshow") == 0; ui->slider->setVisible(!isSlideshow); - ui->timerLabel->setVisible(!isSlideshow); - ui->label->setVisible(!isSlideshow); - ui->durationLabel->setVisible(!isSlideshow); ui->emptySpaceAgain->setVisible(isSlideshow); obs_media_state state = obs_source_media_get_state(source); @@ -278,7 +295,10 @@ void MediaControls::RefreshControls() break; } - SetSliderPosition(); + if (isSlideshow) + UpdateSlideCounter(); + else + SetSliderPosition(); } OBSSource MediaControls::GetSource() @@ -299,6 +319,8 @@ void MediaControls::SetSource(OBSSource source) sigs.emplace_back(sh, "media_stopped", OBSMediaStopped, this); sigs.emplace_back(sh, "media_started", OBSMediaStarted, this); sigs.emplace_back(sh, "media_ended", OBSMediaStopped, this); + sigs.emplace_back(sh, "media_next", OBSMediaNext, this); + sigs.emplace_back(sh, "media_previous", OBSMediaPrevious, this); } else { weakSource = nullptr; } @@ -467,3 +489,27 @@ void MediaControls::MoveSliderBackwards(int seconds) obs_source_media_set_time(source, ms); SetSliderPosition(); } + +void MediaControls::UpdateSlideCounter() +{ + if (!isSlideshow) + return; + + OBSSource source = OBSGetStrongRef(weakSource); + + if (!source) + return; + + proc_handler_t *ph = obs_source_get_proc_handler(source); + calldata_t cd = {}; + + proc_handler_call(ph, "current_index", &cd); + int slide = calldata_int(&cd, "current_index"); + + proc_handler_call(ph, "total_files", &cd); + int total = calldata_int(&cd, "total_files"); + calldata_free(&cd); + + ui->timerLabel->setText(QString::number(slide + 1)); + ui->durationLabel->setText(QString::number(total)); +} diff --git a/UI/media-controls.hpp b/UI/media-controls.hpp index 01310b186..82bfd6004 100644 --- a/UI/media-controls.hpp +++ b/UI/media-controls.hpp @@ -33,6 +33,8 @@ private: static void OBSMediaPlay(void *data, calldata_t *calldata); static void OBSMediaPause(void *data, calldata_t *calldata); static void OBSMediaStarted(void *data, calldata_t *calldata); + static void OBSMediaNext(void *data, calldata_t *calldata); + static void OBSMediaPrevious(void *data, calldata_t *calldata); std::unique_ptr ui; @@ -61,6 +63,8 @@ private slots: void MoveSliderFoward(int seconds = 5); void MoveSliderBackwards(int seconds = 5); + void UpdateSlideCounter(); + public slots: void PlayMedia(); void PauseMedia(); diff --git a/plugins/image-source/obs-slideshow.c b/plugins/image-source/obs-slideshow.c index 8ae970c25..4158f59c9 100644 --- a/plugins/image-source/obs-slideshow.c +++ b/plugins/image-source/obs-slideshow.c @@ -186,7 +186,14 @@ static void free_files(struct darray *array) static inline size_t random_file(struct slideshow *ss) { - return (size_t)rand() % ss->files.num; + size_t next = ss->cur_item; + + if (ss->files.num > 1) { + while (next == ss->cur_item) + next = (size_t)rand() % ss->files.num; + } + + return next; } /* ------------------------------------------------------------------------- */ @@ -539,7 +546,9 @@ static void ss_next_slide(void *data) if (!ss->files.num || obs_transition_get_time(ss->transition) < 1.0f) return; - if (++ss->cur_item >= ss->files.num) + if (ss->randomize) + ss->cur_item = random_file(ss); + else if (++ss->cur_item >= ss->files.num) ss->cur_item = 0; do_transition(ss, false); @@ -552,7 +561,9 @@ static void ss_previous_slide(void *data) if (!ss->files.num || obs_transition_get_time(ss->transition) < 1.0f) return; - if (ss->cur_item == 0) + if (ss->randomize) + ss->cur_item = random_file(ss); + else if (ss->cur_item == 0) ss->cur_item = ss->files.num - 1; else --ss->cur_item; @@ -626,6 +637,18 @@ static void previous_slide_hotkey(void *data, obs_hotkey_id id, obs_source_media_previous(ss->source); } +static void current_slide_proc(void *data, calldata_t *cd) +{ + struct slideshow *ss = data; + calldata_set_int(cd, "current_index", ss->cur_item); +} + +static void total_slides_proc(void *data, calldata_t *cd) +{ + struct slideshow *ss = data; + calldata_set_int(cd, "total_files", ss->files.num); +} + static void ss_destroy(void *data) { struct slideshow *ss = data; @@ -639,6 +662,7 @@ static void ss_destroy(void *data) static void *ss_create(obs_data_t *settings, obs_source_t *source) { struct slideshow *ss = bzalloc(sizeof(*ss)); + proc_handler_t *ph = obs_source_get_proc_handler(source); ss->source = source; @@ -667,6 +691,9 @@ static void *ss_create(obs_data_t *settings, obs_source_t *source) obs_module_text("SlideShow.PreviousSlide"), previous_slide_hotkey, ss); + proc_handler_add(ph, "int current_index()", current_slide_proc, ss); + proc_handler_add(ph, "int total_files()", total_slides_proc, ss); + pthread_mutex_init_value(&ss->mutex); if (pthread_mutex_init(&ss->mutex, NULL) != 0) goto error; @@ -742,20 +769,7 @@ static void ss_video_tick(void *data, float seconds) return; } - if (ss->randomize) { - size_t next = ss->cur_item; - if (ss->files.num > 1) { - while (next == ss->cur_item) - next = random_file(ss); - } - ss->cur_item = next; - - } else if (++ss->cur_item >= ss->files.num) { - ss->cur_item = 0; - } - - if (ss->files.num) - do_transition(ss, false); + obs_source_media_next(ss->source); } }