MythTV master
galleryslideview.cpp
Go to the documentation of this file.
1// C++
2#include <algorithm>
3#include <utility>
4
5// MythTV
11
12// MythFrontend
13#include "galleryslideview.h"
14#include "galleryviews.h"
15
16#define LOC QString("Slideview: ")
17
18// EXIF tag 0x9286 UserComment can contain garbage
19static QString clean_comment(const QString &comment)
20{
21 QString result;
22 std::ranges::copy_if(std::as_const(comment), std::back_inserter(result),
23 [](QChar x) { return x.isPrint(); } );
24 return result;
25}
26
35 bool editsAllowed)
36 : MythScreenType(parent, name),
37 m_mgr(ImageManagerFe::getInstance()),
38 m_availableTransitions(GetMythPainter()->SupportsAnimation()),
39 m_transition(m_availableTransitions.Select(
40 gCoreContext->GetNumSetting("GalleryTransitionType",
42 m_infoList(*this),
43 m_slideShowTime(gCoreContext->GetDurSetting<std::chrono::milliseconds>("GallerySlideShowTime", 3s)),
44 m_showCaptions(gCoreContext->GetBoolSetting("GalleryShowSlideCaptions", true)),
45 m_editsAllowed(editsAllowed)
46{
47 // Detect when transitions finish. Queued signal to allow redraw/pulse to
48 // complete before handling event.
50 this, &GallerySlideView::TransitionComplete, Qt::QueuedConnection);
52 this, &GallerySlideView::TransitionComplete, Qt::QueuedConnection);
53
54 // Initialise slideshow timer
55 m_timer.setSingleShot(true);
56 m_timer.setInterval(m_slideShowTime);
57 connect(&m_timer, &QTimer::timeout,
58 this, qOverload<>(&GallerySlideView::ShowNextSlide));
59
60 // Initialise status delay timer
61 m_delay.setSingleShot(true);
62 m_delay.setInterval(gCoreContext->GetDurSetting<std::chrono::milliseconds>("GalleryStatusDelay", 0s));
64
66 LOG(VB_GUI, LOG_DEBUG, "Created Slideview");
67}
68
69
74{
75 delete m_view;
77 LOG(VB_GUI, LOG_DEBUG, "Deleted Slideview");
78}
79
80
86{
87 if (!LoadWindowFromXML("image-ui.xml", "slideshow", this))
88 return false;
89
90 // Get widgets from XML
91 bool err = false;
92 UIUtilE::Assign(this, m_uiImage, "image", &err);
93 UIUtilW::Assign(this, m_uiStatus, "status");
94 UIUtilW::Assign(this, m_uiSlideCount, "slidecount");
95 UIUtilW::Assign(this, m_uiCaptionText, "caption");
96 UIUtilW::Assign(this, m_uiHideCaptions, "hidecaptions");
97
98 if (err)
99 {
100 LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot load screen 'Slideshow'");
101 return false;
102 }
103
104 // Initialise details list
105 if (!m_infoList.Create(true))
106 {
107 LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot load 'Info buttonlist'");
108 return false;
109 }
110
111 // Create display buffer
113
115 m_uiHideCaptions->SetText(m_showCaptions ? "" : tr("Hide"));
116
119
120 // Detect when slides are available for display.
121 // Queue so that keypress events always complete before transition starts
123 this, &GallerySlideView::SlideAvailable, Qt::QueuedConnection);
124
125 return true;
126}
127
128
133{
134 // Update transition animations
137}
138
139
146{
147 if (GetFocusWidget()->keyPressEvent(event))
148 return true;
149
150 QStringList actions;
151 bool handled = GetMythMainWindow()->TranslateKeyPress("Images", event, actions);
152
153 for (int i = 0; i < actions.size() && !handled; i++)
154 {
155 const QString& action = actions[i];
156 handled = true;
157
158 if (action == "LEFT")
159 {
160 ShowPrevSlide(1);
161 }
162 else if (action == "RIGHT")
163 {
164 ShowNextSlide(1);
165 }
166 else if (action == "UP")
167 {
168 ShowPrevSlide(10);
169 }
170 else if (action == "DOWN")
171 {
172 ShowNextSlide(10);
173 }
174 else if (action == "INFO")
175 {
176 ShowInfo();
177 }
178 else if (action == "MENU")
179 {
180 MenuMain();
181 }
182 else if (action == "PLAY")
183 {
184 if (m_playing)
185 Stop();
186 else
187 Play();
188 }
189 else if (action == "SELECT")
190 {
191 PlayVideo();
192 }
193 else if (action == "STOP")
194 {
195 Stop();
196 }
197 else if (action == "ROTRIGHT")
198 {
200 }
201 else if (action == "ROTLEFT")
202 {
204 }
205 else if (action == "FLIPHORIZONTAL")
206 {
208 }
209 else if (action == "FLIPVERTICAL")
210 {
212 }
213 else if (action == "ZOOMIN")
214 {
215 Zoom(10);
216 }
217 else if (action == "ZOOMOUT")
218 {
219 Zoom(-10);
220 }
221 else if (action == "FULLSIZE")
222 {
223 Zoom();
224 }
225 else if (action == "SCROLLUP")
226 {
227 Pan(QPoint(0, 100));
228 }
229 else if (action == "SCROLLDOWN")
230 {
231 Pan(QPoint(0, -100));
232 }
233 else if (action == "SCROLLLEFT")
234 {
235 Pan(QPoint(-120, 0));
236 }
237 else if (action == "SCROLLRIGHT")
238 {
239 Pan(QPoint(120, 0));
240 }
241 else if (action == "RECENTER")
242 {
243 Pan();
244 }
245 else if (action == "ESCAPE" && !GetMythMainWindow()->IsExitingToMain())
246 {
247 // Exit info details, if shown
248 handled = m_infoList.Hide();
249 }
250 else
251 {
252 handled = false;
253 }
254 }
255
256 if (!handled)
257 handled = MythScreenType::keyPressEvent(event);
258
259 return handled;
260}
261
262
268{
269 if (event->type() == MythEvent::kMythEventMessage)
270 {
271 auto *me = dynamic_cast<MythEvent *>(event);
272 if (me == nullptr)
273 return;
274
275 const QString& message = me->Message();
276
277 QStringList extra = me->ExtraDataList();
278
279 if (message == "IMAGE_METADATA" && !extra.isEmpty())
280 {
281 int id = extra[0].toInt();
282 ImagePtrK selected = m_view->GetSelected();
283
284 if (selected && selected->m_id == id)
285 m_infoList.Display(*selected, extra.mid(1));
286 }
287 else if (message == "THUMB_AVAILABLE")
288 {
289 if (!extra.isEmpty() && m_view->Update(extra[0].toInt()))
290 ShowSlide(0);
291 }
292 }
293 else if (event->type() == DialogCompletionEvent::kEventType)
294 {
295 auto *dce = (DialogCompletionEvent *)event;
296
297 QString resultid = dce->GetId();
298 int buttonnum = dce->GetResult();
299
300 if (resultid == "metadatamenu")
301 {
302 switch (buttonnum)
303 {
304 case 0: Transform(kRotateCW); break;
305 case 1: Transform(kRotateCCW); break;
306 case 2: Transform(kFlipHorizontal); break;
307 case 3: Transform(kFlipVertical); break;
308 case 4: Transform(kResetToExif); break;
309 case 5: Zoom(10); break;
310 case 6: Zoom(-10); break;
311 }
312 }
313 }
314}
315
316
321{
322 // Create the main menu that will contain the submenus above
323 auto *menu = new MythMenu(tr("Slideshow Options"), this, "mainmenu");
324
326 if (im && im->m_type == kVideoFile)
327 menu->AddItem(tr("Play Video"), qOverload<>(&GallerySlideView::PlayVideo));
328
329 if (m_playing)
330 menu->AddItem(tr("Stop"), &GallerySlideView::Stop);
331 else
332 menu->AddItem(tr("Start SlideShow"), qOverload<>(&GallerySlideView::Play));
333
334 if (gCoreContext->GetBoolSetting("GalleryRepeat", false))
335 menu->AddItem(tr("Turn Repeat Off"), &GallerySlideView::RepeatOff);
336 else
337 menu->AddItem(tr("Turn Repeat On"), qOverload<>(&GallerySlideView::RepeatOn));
338
340
342 {
343 if (m_showCaptions)
344 menu->AddItem(tr("Hide Captions"), &GallerySlideView::HideCaptions);
345 else
346 menu->AddItem(tr("Show Captions"), &GallerySlideView::ShowCaptions);
347 }
348
349 QString details;
350 switch (m_infoList.GetState())
351 {
352 case kBasicInfo: details = tr("More Details"); break;
353 case kFullInfo: details = tr("Less Details"); break;
354 default:
355 case kNoInfo: details = tr("Show Details"); break;
356 }
357 menu->AddItem(details, &GallerySlideView::ShowInfo);
358
359 if (m_infoList.GetState() != kNoInfo)
360 menu->AddItem(tr("Hide Details"), &GallerySlideView::HideInfo);
361
362 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
363 auto *menuPopup = new MythDialogBox(menu, popupStack, "menuPopup");
364 if (menuPopup->Create())
365 popupStack->AddScreen(menuPopup);
366 else
367 delete menuPopup;
368}
369
370
376{
378 if (im && !m_playing)
379 {
380 auto *menu = new MythMenu(tr("Transform Options"),
381 this, "metadatamenu");
382 if (m_editsAllowed)
383 {
384 menu->AddItem(tr("Rotate CW"));
385 menu->AddItem(tr("Rotate CCW"));
386 menu->AddItem(tr("Flip Horizontal"));
387 menu->AddItem(tr("Flip Vertical"));
388 menu->AddItem(tr("Reset to Exif"));
389 }
390
392 menu->AddItem(tr("Zoom In"));
393
395 menu->AddItem(tr("Zoom Out"));
396
397 mainMenu.AddItem(tr("Transforms"), nullptr, menu);
398 }
399}
400
401
410void GallerySlideView::Start(ImageSlideShowType type, int parentId, int selectedId)
411{
413
414 if (type == kBrowseSlides)
415 {
416 // Browsing views a single ordered directory
417 m_view = new FlatView(kOrdered);
418
419 // Load db images
420 m_view->LoadFromDb(parentId);
421
422 // Display current selection, falling back to first
423 m_view->Select(selectedId);
424
425 // Display slide immediately
426 ShowSlide();
427 }
428 else
429 {
430 int orderInt = gCoreContext->GetNumSetting("GallerySlideOrder", kOrdered);
431
432 SlideOrderType order = (orderInt < kOrdered) || (orderInt > kSeasonal)
433 ? kOrdered
434 : static_cast<SlideOrderType>(orderInt);
435
436 // Recursive uses a view of a directory subtree; Normal views a single directory
437 m_view = (type == kRecursiveSlideShow) ? new TreeView(order)
438 : new FlatView(order);
439 // Load db images
440 m_view->LoadFromDb(parentId);
441
442 // Ordered views start from selected image
443 if (order == kOrdered)
444 // Adjust view so that slideshows show count rather than position
445 m_view->Rotate(selectedId);
446
447 // No transition for first image
448 Play(false);
449 }
450}
451
452
454{
456
457 // Stop further loads
459
460 // Update gallerythumbview selection
462 if (im)
463 emit ImageSelected(im->m_id);
464
466}
467
468
473{
474 m_playing = false;
475 m_timer.stop();
476 SetStatus(tr("Stopped"));
477}
478
479
484void GallerySlideView::Play(bool useTransition)
485{
486 // Start from next slide
487 ShowNextSlide(1, useTransition);
488
489 m_playing = true;
490 if (!m_suspended)
491 m_timer.start();
492 SetStatus(tr("Playing"), true);
493}
494
495
500{
501 m_timer.stop();
502 m_suspended = true;
503}
504
505
510{
511 m_suspended = false;
512 if (m_playing)
513 m_timer.start();
514}
515
516
522{
524 if (im && !m_playing)
525 {
526 ImageIdList list;
527 list.append(im->m_id);
528 QString err = m_mgr.ChangeOrientation(state, list);
529 if (!err.isEmpty())
530 ShowOkPopup(err);
531 }
532}
533
534
539void GallerySlideView::Zoom(int increment)
540{
541 if (!m_playing)
542 m_slides.GetCurrent().Zoom(increment);
543}
544
545
550void GallerySlideView::Pan(QPoint offset)
551{
552 if (!m_playing)
553 m_slides.GetCurrent().Pan(offset);
554}
555
556
561{
563}
564
565
570{
572}
573
574
579{
580 m_showCaptions = true;
582}
583
584
589{
590 m_showCaptions = false;
591 m_uiHideCaptions->SetText(tr("Hide"));
592}
593
594
600{
602 if (!im)
603 // Reached view limits
604 return;
605
606 LOG(VB_FILE, LOG_DEBUG, LOC + QString("Selected %1").arg(im->m_filePath));
607
608 // Suspend the timer until the transition has finished
609 Suspend();
610
611 // Load image from file
612 if (!m_slides.Load(im, direction))
613 // Image not yet available: show loading status
614 SetStatus(tr("Loading"), true);
615}
616
617
624{
625 // Transition speed = 0.5x for every slide waiting. Min = 1x, Max = Half buffer size
626 float speed = 0.5F + (count / 2.0F);
627
628 // Are we transitioning ?
629 if (m_transitioning)
630 {
631 // More slides waiting for display: accelerate current transition
632 LOG(VB_FILE, LOG_DEBUG, LOC + QString("Changing speed to %1").arg(speed));
633 m_transition.SetSpeed(speed);
634 return;
635 }
636
637 // We've been waiting for this slide: transition immediately
638 m_transitioning = true;
639
640 // Take next slide
641 Slide &next = m_slides.GetNext();
642
643 // Update loading status
644 ClearStatus(next);
645
646 // Update slide counts
647 if (m_uiSlideCount)
649
650 int direction = next.GetDirection();
651
652 // Use instant transition for start-up & updates (dir = 0)
653 // and browsing with transitions turned off
654 Transition &transition =
655 (direction != 0 &&
656 (m_playing || gCoreContext->GetBoolSetting("GalleryBrowseTransition", false)))
658
659 // Reset any zoom before starting transition
660 Zoom();
661 transition.Start(m_slides.GetCurrent(), next, direction >= 0, speed);
662}
663
664
672{
673 if (m_isDeleting)
674 return;
675
676 m_transitioning = false;
677
678 // Release old slide, which may start a new transition
680
681 // No further actions when skipping
682 // cppcheck-suppress knownConditionTrueFalse
683 if (m_transitioning)
684 return;
685
686 // Preload next slide, if any
688
689 // Populate display for new slide
691
692 // Update any file details information
693 m_infoList.Update(im);
694
695 if (im && m_uiCaptionText)
696 {
697 // show the date & comment
698 QStringList text;
699 text << ImageManagerFe::LongDateOf(im);
700
701 QString comment = clean_comment(im->m_comment);
702 if (!comment.isEmpty())
703 text << comment;
704
705 m_uiCaptionText->SetText(text.join(" - "));
706 }
707
708 // Start any video unless we're paused or browsing
709 if (im && im->m_type == kVideoFile)
710 {
711 if (m_playing)
712 PlayVideo();
713 else
714 SetStatus(tr("Video"));
715 }
716
717 // Resume slideshow timer
718 Release();
719}
720
721
726{
727 if (m_playing && m_view->HasPrev(inc) == nullptr)
728 {
729 // Prohibit back-wrapping during slideshow: it will cause premature end
730 //: Cannot go back beyond first slide of slideshow
731 SetStatus(tr("Start"));
732 }
733 else if (m_view->Prev(inc))
734 {
735 ShowSlide(-1);
736 }
737}
738
739
745void GallerySlideView::ShowNextSlide(int inc, bool useTransition)
746{
747 // Browsing always wraps; slideshows depend on repeat setting
748 if (m_playing && m_view->HasNext(inc) == nullptr
749 && !gCoreContext->GetBoolSetting("GalleryRepeat", false))
750 {
751 // Don't stop due to jumping past end
752 if (inc == 1)
753 {
754 Stop();
755 //: Slideshow has reached last slide
756 SetStatus(tr("End"));
757 }
758 }
759 else if (m_view->Next(inc))
760 {
761 ShowSlide(useTransition ? 1 : 0);
762 }
763 else
764 {
765 // No images
766 Stop();
769 if (m_uiSlideCount)
770 m_uiSlideCount->SetText("0/0");
771 if (m_uiCaptionText)
773 }
774}
776{
777 ShowNextSlide(1, true);
778}
779
780
785{
787 return;
788
790
791 if (im && im->m_type == kVideoFile)
792 GetMythMainWindow()->HandleMedia("Internal", im->m_url);
793}
794
795
801void GallerySlideView::SetStatus(QString msg, bool delay)
802{
803 m_statusText = std::move(msg);
804 if (m_uiStatus)
805 {
806 if (delay)
807 m_delay.start();
808 else
809 ShowStatus();
810 }
811}
812
813
815{
816 if (m_uiStatus)
818}
819
820
822{
823 if (m_uiStatus)
824 {
825 m_delay.stop();
826
827 if (slide.FailedLoad())
828 {
829 ImagePtrK im = slide.GetImageData();
830 SetStatus(tr("Failed to load %1").arg(im ? im->m_filePath : "?"));
831 }
832 else
833 {
834 m_uiStatus->Reset();
835 }
836 }
837}
838
840{
841 gCoreContext->SaveSetting("GalleryRepeat", on);
842}
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:40
static const Type kEventType
Definition: mythdialogbox.h:55
A datastore of images for display by a screen.
Definition: galleryviews.h:102
bool Update(int id)
Updates view with images that have been updated.
ImagePtrK Prev(int inc)
Decrements iterator and returns previous image. Wraps at start.
bool Select(int id, int fallback=0)
Selects first occurrence of an image.
ImagePtrK HasNext(int inc) const
Peeks at next image in view but does not advance iterator.
ImagePtrK Next(int inc)
Advance iterator and return next image, wrapping if necessary. Regenerates unordered views on wrap.
QString GetPosition() const
Get positional status.
ImagePtrK GetSelected() const
Get current selection.
virtual bool LoadFromDb(int parentId)
Populate view with database images from a directory.
ImagePtrK HasPrev(int inc) const
Peeks at previous image in view but does not decrement iterator.
void Rotate(int id)
Rotate view so that starting image is at front.
void ClearStatus(const Slide &slide)
QString m_statusText
Text to display as status.
MythUIText * m_uiSlideCount
QTimer m_timer
Slide duration timer.
static void RepeatOn()
MythUIText * m_uiHideCaptions
ImageManagerFe & m_mgr
Manages the images.
bool m_showCaptions
If true, captions are shown.
void ShowInfo()
Show exif info list.
void HideCaptions()
Hide text widgets.
~GallerySlideView() override
Destructor.
void PlayVideo()
Starts internal player for video.
void Release()
Unpause transition timer.
FlatView * m_view
List of images comprising the slideshow.
void customEvent(QEvent *event) override
Handle custom events.
void ImageSelected(int)
void HideInfo()
Hide exif info list.
SlideBuffer m_slides
A queue of slides used to display images.
bool Create() override
Initialises the graphical elements.
static void RepeatOff()
bool m_editsAllowed
True when edits are enabled.
bool m_transitioning
True when a transition is in progress.
void ShowCaptions()
Show text widgets.
TransitionNone m_updateTransition
Instant transition that is always used for start-up & image updates.
void Start(ImageSlideShowType type, int parentId, int selectedId=0)
Start slideshow.
void TransitionComplete()
Transition to new slide has finished.
QTimer m_delay
Status delay timer.
void SetStatus(QString msg, bool delay=false)
Displays status text (Loading, Paused etc.)
void Close() override
void Pan(QPoint offset=QPoint(0, 0))
Pan current slide.
MythUIText * m_uiCaptionText
void MenuTransforms(MythMenu &mainMenu)
Add Transforms submenu.
InfoList m_infoList
Image details overlay.
void MenuMain()
Shows the popup menu.
GallerySlideView(MythScreenStack *parent, const char *name, bool editsAllowed)
Constructor.
void Stop()
Stop a playing slideshow.
void Zoom(int increment=0)
Zoom current slide.
bool m_playing
True when slideshow is running.
void Pulse() override
Update transition.
void Suspend()
Pause transition timer temporarily.
bool m_suspended
True when transition is running or video playing.
MythUIImage * m_uiImage
void SlideAvailable(int count)
Start transition.
Transition & m_transition
Selected transition.
bool keyPressEvent(QKeyEvent *event) override
Handle keypresses.
void ShowPrevSlide(int inc=1)
Display the previous slide in the sequence.
std::chrono::milliseconds m_slideShowTime
Time to display a slide in a slideshow.
void Transform(ImageFileTransform state)
Action transform request.
MythUIText * m_uiStatus
void ShowSlide(int direction=0)
Display slide.
The image manager for use by Frontends.
Definition: imagemanager.h:456
QString ChangeOrientation(ImageFileTransform transform, const ImageIdList &ids)
Apply an orientation transform to images.
static QString LongDateOf(const ImagePtrK &im)
Return a timestamp/datestamp for an image or dir.
void Display(ImageItemK &im, const QStringList &tagStrings)
Build list of metadata tags.
void Update(const ImagePtrK &im)
Populates available exif details for the current image/dir.
InfoVisibleState GetState() const
Definition: galleryinfo.h:34
bool Hide()
Remove infolist from display.
void Toggle(const ImagePtrK &im)
Toggle infolist state for an image. Focusable widgets toggle between Basic & Full info....
Definition: galleryinfo.cpp:86
bool Create(bool focusable)
Initialise buttonlist from XML.
Definition: galleryinfo.cpp:68
void SaveSetting(const QString &key, int newValue)
T GetDurSetting(const QString &key, T defaultval=T::zero())
int GetNumSetting(const QString &key, int defaultval=0)
bool GetBoolSetting(const QString &key, bool defaultval=false)
Basic menu dialog, message and a list of options.
This class is used as a container for messages.
Definition: mythevent.h:17
const QString & Message() const
Definition: mythevent.h:65
static const Type kMythEventMessage
Definition: mythevent.h:79
static void DisableScreensaver()
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MythScreenStack * GetStack(const QString &Stackname)
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
static void RestoreScreensaver()
void AddItem(const QString &title)
void addListener(QObject *listener)
Add a listener to the observable.
void removeListener(QObject *listener)
Remove a listener to the observable.
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
void BuildFocusList(void)
MythUIType * GetFocusWidget(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool SetFocusWidget(MythUIType *widget=nullptr)
virtual void Close()
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:65
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
virtual void Pulse(void)
Pulse is called 70 times a second to trigger a single frame of an animation.
Definition: mythuitype.cpp:442
Slide & GetNext()
Definition: galleryslide.h:235
void ReleaseCurrent()
Move head slide to back of queue and flush waiting slides.
void Initialise(MythUIImage &image)
Construct buffer.
Slide & GetCurrent()
Definition: galleryslide.h:229
bool Load(const ImagePtrK &im, int direction)
Assign an image to next available slide, start loading and signal when done.
void Preload(const ImagePtrK &im)
Load an image in next available slide.
void SlideReady(int count)
Signals that buffer has (count) loaded slides awaiting display.
A specialised image for slideshows.
Definition: galleryslide.h:159
void Pan(QPoint offset)
Initiate pan.
bool FailedLoad() const
Definition: galleryslide.h:176
void Zoom(int percentage)
Initiate slide zoom.
bool CanZoomOut() const
Definition: galleryslide.h:173
int GetDirection() const
Definition: galleryslide.h:177
ImagePtrK GetImageData() const
Definition: galleryslide.h:167
void Clear()
Reset slide to unused state.
bool CanZoomIn() const
Definition: galleryslide.h:172
Base class of an animated transition that can be accelerated & reversed.
virtual void Start(Slide &from, Slide &to, bool forwards, float speed=1.0)
Start base transition.
void finished()
virtual void Pulse()=0
virtual void SetSpeed(float)
A datastore of images for display by a screen. Provides an ordered list of images (no dirs) from a di...
Definition: galleryviews.h:218
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
@ kNoInfo
Details not displayed.
Definition: galleryinfo.h:17
@ kBasicInfo
Shows just the most useful exif tags.
Definition: galleryinfo.h:18
@ kFullInfo
Shows all exif tags.
Definition: galleryinfo.h:19
#define LOC
static QString clean_comment(const QString &comment)
Slideshow screen.
ImageSlideShowType
Type of slide show.
@ kRecursiveSlideShow
@ kBrowseSlides
@ kBlendTransition
Provides view datastores for Gallery screens.
SlideOrderType
Order of images in slideshow.
Definition: galleryviews.h:24
@ kSeasonal
Biased random selection so that images are more likely to appear on anniversaries.
Definition: galleryviews.h:28
@ kOrdered
Ordered as per user setting GallerySortOrder.
Definition: galleryviews.h:25
ImageFileTransform
Image transformations.
Definition: imagemetadata.h:46
@ kFlipVertical
Reflect about horizontal axis.
Definition: imagemetadata.h:51
@ kRotateCCW
Rotate anti-clockwise.
Definition: imagemetadata.h:49
@ kFlipHorizontal
Reflect about vertical axis.
Definition: imagemetadata.h:50
@ kRotateCW
Rotate clockwise.
Definition: imagemetadata.h:48
@ kResetToExif
Reset to Exif value.
Definition: imagemetadata.h:47
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:165
@ kVideoFile
A video.
Definition: imagetypes.h:40
QList< int > ImageIdList
Definition: imagetypes.h:60
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythPainter * GetMythPainter(void)
MythMainWindow * GetMythMainWindow(void)
static MythThemedMenu * menu
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:86