MythTV  master
galleryslide.cpp
Go to the documentation of this file.
1 // C++
2 #include <algorithm>
3 #include <cmath> // for roundf
4 
5 // MythTV
10 
11 // MythFrontend
12 #include "galleryslide.h"
13 
14 #define LOC QString("Slide: ")
15 #define SBLOC QString("SlideBuffer: ")
16 
17 
18 // Number of slides to use for buffering image requests.
19 // When browsing quickly the buffer will load consecutive slides until it fills.
20 // If too large, rapid browsing will be stodgy (sequential access) for images that
21 // aren't cached (Cached images are always fast).
22 // If too small, rapid browsing will result in skipping slides rather than flicking
23 // quickly through them.
24 // Minimum is 4: 3 for displaying a transition, 1 to handle load requests
25 static constexpr size_t SLIDE_BUFFER_SIZE { 9 };
26 
27 
33 void AbstractAnimation::Start(bool forwards, float speed)
34 {
35  m_forwards = forwards;
36  m_speed = speed;
37  m_running = true;
38 }
39 
40 
49 void Animation::Set(const QVariant& from, const QVariant& to,
50  std::chrono::milliseconds duration,
51  const QEasingCurve& curve, UIEffects::Centre centre)
52 {
53  setStartValue(from);
54  setEndValue(to);
55  m_centre = centre;
56  setDuration(duration.count());
57  setEasingCurve(curve);
58 }
59 
60 
66 void Animation::Start(bool forwards, float speed)
67 {
68  auto duration_ms = std::chrono::milliseconds(duration());
69  if (duration_ms == 0ms)
70  return;
71 
72  m_elapsed = forwards ? 0ms : duration_ms;
73  setCurrentTime(m_elapsed.count());
74 
75  AbstractAnimation::Start(forwards, speed);
76 }
77 
78 
82 {
83  if (!m_running)
84  return;
85 
86  std::chrono::milliseconds current = MythDate::currentMSecsSinceEpochAsDuration();
87  std::chrono::milliseconds interval = std::min(current - m_lastUpdate, 50ms);
89  m_elapsed += (m_forwards ? interval : -interval) * static_cast<int>(m_speed);
90  setCurrentTime(m_elapsed.count());
91 
92  // Detect completion
93  if ((m_forwards && m_elapsed.count() >= duration()) || (!m_forwards && m_elapsed <= 0ms))
94  Finished();
95 }
96 
97 
102 void Animation::updateCurrentValue(const QVariant &value)
103 {
104  if (m_parent && m_running)
105  {
107 
108  switch (m_type)
109  {
110  case None: break;
111  case Position: m_parent->SetPosition(value.toPoint()); break;
112  case Alpha: m_parent->SetAlpha(value.toInt()); break;
113  case Zoom: m_parent->SetZoom(value.toFloat()); break;
114  case HorizontalZoom: m_parent->SetHorizontalZoom(value.toFloat()); break;
115  case VerticalZoom: m_parent->SetVerticalZoom(value.toFloat()); break;
116  case Angle: m_parent->SetAngle(value.toFloat()); break;
117  }
118  }
119 }
120 
121 
127 {
128  // Signal group when child completes
129  m_group.append(child);
130  connect(child, &AbstractAnimation::finished, this, &GroupAnimation::Finished);
131 }
132 
133 
138 {
139  qDeleteAll(m_group);
140  m_group.clear();
141 }
142 
143 
147 {
148  if (!m_running || m_current < 0 || m_current >= m_group.size())
149  return;
150 
151  // Pulse current running child
152  m_group.at(m_current)->Pulse();
153 }
154 
155 
161 void SequentialAnimation::Start(bool forwards, float speed)
162 {
163  if (m_group.empty())
164  return;
165 
166  m_current = forwards ? 0 : m_group.size() - 1;
167 
168  // Start group, then first child
169  GroupAnimation::Start(forwards, speed);
170  m_group.at(m_current)->Start(m_forwards, m_speed);
171 }
172 
173 
179 {
180  // Set group speed for subsequent children
182 
183  // Set active child
184  if (!m_running || m_current < 0 || m_current >= m_group.size())
185  return;
186 
187  m_group.at(m_current)->SetSpeed(speed);
188 }
189 
190 
195 {
196  // Finish group when last child finishes
197  if ((m_forwards && ++m_current == m_group.size())
198  || (!m_forwards && --m_current < 0))
200  else
201  // Start next child
202  m_group.at(m_current)->Start(m_forwards, m_speed);
203 }
204 
205 
209 {
210  if (m_running)
211  {
212  // Pulse all children
213  for (AbstractAnimation *animation : qAsConst(m_group))
214  animation->Pulse();
215  }
216 }
217 
218 
224 void ParallelAnimation::Start(bool forwards, float speed)
225 {
226  if (m_group.empty())
227  return;
228 
229  m_finished = m_group.size();
230 
231  // Start group, then all children
232  GroupAnimation::Start(forwards, speed);
233  for (AbstractAnimation *animation : qAsConst(m_group))
234  animation->Start(m_forwards, m_speed);
235 }
236 
237 
243 {
244  // Set group speed, then all children
246  for (AbstractAnimation *animation : qAsConst(m_group))
247  animation->SetSpeed(m_speed);
248 }
249 
250 
255 {
256  // Finish group when last child finishes
257  if (--m_finished == 0)
259 }
260 
261 
266 void PanAnimation::updateCurrentValue(const QVariant &value)
267 {
268  if (m_parent && m_running)
269  {
270  Slide *image = m_parent;
271  image->SetPan(value.toPoint());
272  }
273 }
274 
275 
282 Slide::Slide(MythUIType *parent, const QString& name, MythUIImage *image)
283  : MythUIImage(parent, name)
284 {
285  // Clone from image
286  CopyFrom(image);
287 
288  // Null parent indicates we should become a child of the image (after
289  // copy to avoid recursion)
290  if (!parent)
291  {
292  // Slides sit on top of parent image area
293  SetArea(MythRect(image->GetArea().toQRect()));
294  m_area.moveTo(0, 0);
295  setParent(image);
296  m_parent = image;
297  image->AddChild(this);
298  }
299 
300  // Provide animations for pan & zoom
301  if (GetPainter()->SupportsAnimation())
302  {
304  m_panAnimation = new PanAnimation(this);
305  }
306 
307  connect(this, &MythUIImage::LoadComplete, this, &Slide::SlideLoaded);
308 }
309 
310 
315 {
316  delete m_zoomAnimation;
317  delete m_panAnimation;
318  LOG(VB_GUI, LOG_DEBUG, "Deleted Slide " + objectName());
319 }
320 
321 
326 {
327  m_state = kEmpty;
328  m_data.clear();
329  m_waitingFor.clear();
330  SetCropRect(0, 0, 0, 0);
331  SetVisible(false);
332 }
333 
334 
339 QChar Slide::GetDebugState() const
340 {
341  switch (m_state)
342  {
343  case kEmpty: return 'e';
344  case kFailed: return 'f';
345  case kLoaded: return m_waitingFor ? 'r' : 'a';
346  case kLoading: return m_waitingFor ? 'l' : 'p';
347  }
348  return '?';
349 }
350 
351 
364 bool Slide::LoadSlide(const ImagePtrK& im, int direction, bool notifyCompletion)
365 {
366  m_direction = direction;
367  m_waitingFor = notifyCompletion ? im : ImagePtrK();
368 
369  if (im == m_data)
370  {
371  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Already loading/loaded %1 in %2")
372  .arg(im->m_filePath, objectName()));
373 
374  if (m_state >= kLoaded && notifyCompletion)
375  // Image has been pre-loaded
376  emit ImageLoaded(this);
377 
378  return (m_state >= kLoaded);
379  }
380 
381  // Is a different image loading ?
382  if (m_state == kLoading)
383  {
384  // Can't abort image loads, so must wait for it to finish
385  // before starting new load
386  m_waitingFor = im;
387 
388  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Postponing load of %1 in %2")
389  .arg(im->m_filePath, objectName()));
390 
391  return false;
392  }
393 
394  // Start load
395  m_data = im;
396  m_state = kLoading;
397 
398  if (im->m_type == kVideoFile)
399  {
400  // Use thumbnail, which has already been orientated
401  SetFilename(im->m_thumbNails.at(0).second);
402  SetOrientation(1);
403  }
404  else
405  {
406  // Load image, compensating for any Qt auto-orientation
407  SetFilename(im->m_url);
408  SetOrientation(Orientation(m_data->m_orientation).GetCurrent(true));
409  }
410 
411  // Load in background
412  Load(true);
413  return false;
414 }
415 
416 
424 {
425  m_state = m_images[0] ? kLoaded : kFailed;
426  if (m_state == kFailed)
427  LOG(VB_GENERAL, LOG_ERR, LOC +
428  QString("Failed to load %1").arg(m_data->m_filePath));
429 
430  // Ignore superseded requests and preloads
431  if (m_data == m_waitingFor)
432  {
433  // Loaded image is the latest requested
434  emit ImageLoaded(this);
435  }
436  else if (m_waitingFor)
437  {
438  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Starting delayed load %1")
439  .arg(m_waitingFor->m_filePath));
440 
441  // Start latest postponed load
443  }
444 }
445 
446 
452 void Slide::Zoom(int percentage)
453 {
454  // Sentinel indicates reset to default zoom
455  float newZoom = (percentage == 0)
456  ? 1.0F
457  : std::clamp(m_zoom * (1.0F + percentage / 100.0F), MIN_ZOOM, MAX_ZOOM);
458  if (newZoom != m_zoom)
459  {
460  if (m_zoomAnimation)
461  {
462  m_zoomAnimation->Set(m_zoom, newZoom, 250ms, QEasingCurve::OutQuad);
464  }
465  else
466  SetZoom(newZoom);
467  }
468 }
469 
470 
477 void Slide::SetZoom(float zoom)
478 {
479  m_zoom = zoom;
481 
482  // TODO
483  // MythUIImage displaces widget or doesn't centre for some combinations of
484  // zoom centre/cropping so frig centre for now.
486 
487  SetPan(m_pan);
488 }
489 
490 
495 void Slide::Pan(QPoint offset)
496 {
497  // Panning only possible when zoomed in
498  if (m_zoom > 1.0F)
499  {
500  QPoint start = m_pan;
501 
502  // Sentinel indicates reset to centre
503  // Panning is applied to original (unzoomed) image co-ords.
504  // Adjust offset for zoom so that pan moves a constant screen distance rather
505  // than constant image distance
506  QPoint dest = offset.isNull() ? QPoint(0, 0) : start + offset / m_zoom;
507 
508  if (m_panAnimation)
509  {
510  m_panAnimation->Set(start, dest, 250ms, QEasingCurve::Linear);
512  }
513  else
514  SetPan(dest);
515  }
516 }
517 
518 
525 void Slide::SetPan(QPoint pos)
526 {
527  if (m_state == kFailed)
528  {
529  m_pan = pos;
530  return;
531  }
532 
533  // Determine zoom of largest dimension
534  QRect imageArea = m_images[m_curPos]->rect();
535  float hRatio = float(imageArea.height()) / m_area.height();
536  float wRatio = float(imageArea.width()) / m_area.width();
537  float ratio = std::max(hRatio, wRatio); // TODO create a Rational number class
538 
539  if (m_zoom != 0.0F)
540  ratio /= m_zoom;
541 
542  // Determine crop area
543  int h = std::min(int(roundf(m_area.height() * ratio)), imageArea.height());
544  int w = std::min(int(roundf(m_area.width() * ratio)), imageArea.width());
545  int x = imageArea.center().x() - w / 2;
546  int y = imageArea.center().y() - h / 2;
547 
548  // Constrain pan to boundaries
549  int limitX = (imageArea.width() - w) / 2;
550  int limitY = (imageArea.height() - h) / 2;
551  m_pan.setX(std::clamp(pos.x(), -limitX, limitX));
552  m_pan.setY(std::clamp(pos.y(), -limitY, limitY));
553 
554  SetCropRect(x + m_pan.x(), y + m_pan.y(), w, h);
555  SetRedraw();
556 }
557 
558 
563 {
564  // Update zoom/pan animations
565  if (m_zoomAnimation)
567 
568  if (m_panAnimation)
570 }
571 
572 
574 {
575  LOG(VB_GUI, LOG_DEBUG, "Deleted Slidebuffer");
576 }
577 
578 
580 {
581  QMutexLocker lock(&m_mutexQ);
582  for (Slide *s : qAsConst(m_queue))
583  s->Clear();
584  LOG(VB_GUI, LOG_DEBUG, "Aborted Slidebuffer");
585 }
586 
587 
594 {
595  // Require at least 4 slides: 2 for transitions, 1 to handle further requests
596  // and 1 to prevent solitary slide from being used whilst it is loading
597  size_t size = std::max(SLIDE_BUFFER_SIZE, 4_UZ);
598 
599  // Fill buffer with slides cloned from the XML image widget
600 
601  // Create first as a child of the XML image.
602  auto *slide = new Slide(nullptr, "slide0", &image);
603 
604  // Buffer is notified when it has loaded image
605  connect(slide, &Slide::ImageLoaded,
606  this, qOverload<Slide*>(&SlideBuffer::Flush));
607 
608  m_queue.enqueue(slide);
609 
610  // Rest are simple clones of first
611  for (size_t i = 1; i < size; ++i)
612  {
613  slide = new Slide(&image, QString("slide%1").arg(i), slide);
614 
615  // All slides (except first) start off hidden
616  slide->SetVisible(false);
617 
618  // Buffer is notified when it has loaded image
619  connect(slide, &Slide::ImageLoaded,
620  this, qOverload<Slide*>(&SlideBuffer::Flush));
621 
622  m_queue.enqueue(slide);
623  }
624 
625  m_nextLoad = 1;
626 }
627 
628 
634 {
635  QMutexLocker lock(&m_mutexQ);
636 
637  QString state;
638  for (int i = 0; i < m_queue.size(); ++i)
639  {
640  QChar code(m_queue.at(i)->GetDebugState());
641  state += (i == m_nextLoad ? code.toUpper() : code);
642  }
643  return QString("[%1] (%2)").arg(state, m_queue.head()->objectName());
644 }
645 
646 
654 bool SlideBuffer::Load(const ImagePtrK& im, int direction)
655 {
656  if (!im)
657  return false;
658 
659  QMutexLocker lock(&m_mutexQ);
660 
661  // Start loading image in next available slide
662  Slide *slide = m_queue.at(m_nextLoad);
663 
664  // Further load requests will go to same slide if no free ones are available
665  if (m_nextLoad < m_queue.size() - 1)
666  ++m_nextLoad;
667 
668  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("Loading %1 in %2, %3")
669  .arg(im->m_filePath, slide->objectName(), BufferState()));
670 
671  return slide->LoadSlide(im, direction, true);
672 }
673 
674 
680 {
681  if (!im)
682  return;
683 
684  QMutexLocker lock(&m_mutexQ);
685 
686  // Start loading image in next available slide
687  Slide *slide = m_queue.at(m_nextLoad);
688 
689  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("Preloading %1 in %2, %3")
690  .arg(im->m_filePath, slide->objectName(), BufferState()));
691 
692  // Load silently
693  slide->LoadSlide(im);
694 }
695 
696 
702 {
703  QMutexLocker lock(&m_mutexQ);
704 
705  // Reset slide & return to buffer for re-use
706  Slide *slide = m_queue.dequeue();
707  slide->Clear();
708  m_queue.enqueue(slide);
709 
710  QString name = slide->objectName();
711 
712  // Free constrained load ptr now a spare slide is available
713  if (!m_queue.at(--m_nextLoad)->IsEmpty())
714  ++m_nextLoad;
715 
716  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("Released %1").arg(name));
717 
718  // Flush any pending slides that originate from multiple requests (skipping)
719  Flush(m_queue.head(), "Pending");
720 }
721 
722 
729 void SlideBuffer::Flush(Slide *slide, const QString& reason)
730 {
731  QMutexLocker lock(&m_mutexQ);
732 
733  // Determine number of consecutive slides that are now available after head
734  // Include last slide to ensure transition speed is consistent: it will never
735  // be displayed because queue size is always > 2
736  int available = 1;
737  while (available < m_queue.size() && m_queue.at(available)->IsLoaded())
738  ++available;
739 
740  if (available == 1)
741  return;
742 
743  // Notify that more slides are available
744  ImagePtrK im = slide->GetImageData();
745  QString path = im ? im->m_filePath : "Unknown";
746 
747  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("%1 %2 in %3, %4")
748  .arg(reason, path, slide->objectName(), BufferState()));
749 
750  emit SlideReady(--available);
751 }
752 
754 {
755  Flush(slide, "Loaded");
756 };
Slide::kFailed
@ kFailed
Definition: galleryslide.h:188
Slide::~Slide
~Slide() override
Destructor.
Definition: galleryslide.cpp:314
MythUIType::m_area
MythRect m_area
Definition: mythuitype.h:274
Animation::m_elapsed
std::chrono::milliseconds m_elapsed
Current millisec position within animation, 0..duration.
Definition: galleryslide.h:84
ImagePtrK
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:165
Slide
A specialised image for slideshows.
Definition: galleryslide.h:156
UIEffects::TopLeft
@ TopLeft
Definition: mythuianimation.h:16
build_compdb.dest
dest
Definition: build_compdb.py:9
Slide::SetZoom
void SetZoom(float zoom)
Sets slide zoom.
Definition: galleryslide.cpp:477
ParallelAnimation::SetSpeed
void SetSpeed(float speed) override
Change speed of group and all child animations.
Definition: galleryslide.cpp:242
Slide::m_pan
QPoint m_pan
Pan position (0,0) = no pan.
Definition: galleryslide.h:199
MythUIImage
Image widget, displays a single image or multiple images in sequence.
Definition: mythuiimage.h:97
MIN_ZOOM
#define MIN_ZOOM
Definition: galleryslide.h:19
kVideoFile
@ kVideoFile
A video.
Definition: imagetypes.h:40
AbstractAnimation::Finished
virtual void Finished()
To be called when animation completes.
Definition: galleryslide.h:39
Animation::m_centre
UIEffects::Centre m_centre
Definition: galleryslide.h:81
MythUIImage::m_images
QHash< int, MythImage * > m_images
Definition: mythuiimage.h:170
Animation::HorizontalZoom
@ HorizontalZoom
Definition: galleryslide.h:58
SequentialAnimation::Finished
void Finished() override
A child animation has completed.
Definition: galleryslide.cpp:194
MythRect::toQRect
QRect toQRect(void) const
Definition: mythrect.cpp:405
Slide::Pulse
void Pulse() override
Update pan & zoom animations.
Definition: galleryslide.cpp:562
SlideBuffer::SlideReady
void SlideReady(int count)
Signals that buffer has (count) loaded slides awaiting display.
ParallelAnimation::Finished
void Finished() override
A child animation has completed.
Definition: galleryslide.cpp:254
Slide::m_panAnimation
PanAnimation * m_panAnimation
Dedicated animation for panning, if supported.
Definition: galleryslide.h:198
Slide::Slide
Slide(MythUIType *parent, const QString &name, MythUIImage *image)
Clone slide from a theme MythUIImage.
Definition: galleryslide.cpp:282
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:966
Slide::SlideLoaded
void SlideLoaded()
An image has completed loading.
Definition: galleryslide.cpp:423
SequentialAnimation::m_current
int m_current
Index of child currently playing.
Definition: galleryslide.h:123
Animation::m_lastUpdate
std::chrono::milliseconds m_lastUpdate
Definition: galleryslide.h:85
MythUIType::GetPainter
virtual MythPainter * GetPainter(void)
Definition: mythuitype.cpp:1421
AbstractAnimation::m_forwards
bool m_forwards
Play direction.
Definition: galleryslide.h:46
MythUIImage::SetOrientation
void SetOrientation(int orientation)
Saves the exif orientation value of the first image in the widget.
Definition: mythuiimage.cpp:919
MythUIType::SetArea
virtual void SetArea(const MythRect &rect)
Definition: mythuitype.cpp:609
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
GroupAnimation::m_group
QList< AbstractAnimation * > m_group
Definition: galleryslide.h:104
Slide::kLoading
@ kLoading
Definition: galleryslide.h:188
MythRect
Wrapper around QRect allowing us to handle percentage and other relative values for areas in mythui.
Definition: mythrect.h:17
AbstractAnimation
Base animation class that is driven by a Myth pulse and implements variable speed.
Definition: galleryslide.h:26
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
MAX_ZOOM
#define MAX_ZOOM
Definition: galleryslide.h:20
Orientation::GetCurrent
int GetCurrent(bool compensate)
Determines orientation required for an image.
Definition: imagemetadata.cpp:83
Animation::Angle
@ Angle
Definition: galleryslide.h:58
MythUIType::GetArea
virtual MythRect GetArea(void) const
If the object has a minimum area defined, return it, other wise return the default area.
Definition: mythuitype.cpp:884
MythUIType::AddChild
void AddChild(MythUIType *child)
Add a child UIType.
Definition: mythuitype.cpp:88
MythUIType::m_effects
UIEffects m_effects
Definition: mythuitype.h:281
SlideBuffer::ReleaseCurrent
void ReleaseCurrent()
Move head slide to back of queue and flush waiting slides.
Definition: galleryslide.cpp:701
Slide::m_data
ImagePtrK m_data
The image currently loading/loaded.
Definition: galleryslide.h:191
Animation::m_type
Type m_type
Definition: galleryslide.h:80
Animation::Pulse
void Pulse() override
Progress single animation.
Definition: galleryslide.cpp:81
MythUIImage::SetCropRect
void SetCropRect(int x, int y, int width, int height)
Crop the image using the given rectangle, useful for removing unsightly edges from imported images or...
Definition: mythuiimage.cpp:947
Animation::Set
void Set(const QVariant &from, const QVariant &to, std::chrono::milliseconds duration=500ms, const QEasingCurve &curve=QEasingCurve::InOutCubic, UIEffects::Centre centre=UIEffects::Middle)
Initialises an animation.
Definition: galleryslide.cpp:49
Slide::kEmpty
@ kEmpty
Definition: galleryslide.h:188
SlideBuffer::Load
bool Load(const ImagePtrK &im, int direction)
Assign an image to next available slide, start loading and signal when done.
Definition: galleryslide.cpp:654
SlideBuffer::m_nextLoad
int m_nextLoad
Index of first spare slide, (or last slide if none spare)
Definition: galleryslide.h:257
MythUIType::SetAlpha
void SetAlpha(int newalpha)
Definition: mythuitype.cpp:945
AbstractAnimation::Start
virtual void Start(bool forwards, float speed=1.0)
Initialise & start base animation.
Definition: galleryslide.cpp:33
AbstractAnimation::m_speed
float m_speed
Real-time = 1.0, Double-speed = 2.0.
Definition: galleryslide.h:48
mythlogging.h
SlideBuffer::Teardown
void Teardown()
Definition: galleryslide.cpp:579
PanAnimation::updateCurrentValue
void updateCurrentValue(const QVariant &value) override
Update pan value.
Definition: galleryslide.cpp:266
MythUIImage::LoadComplete
void LoadComplete()
MythUIImage::m_curPos
unsigned int m_curPos
Definition: mythuiimage.h:178
LOC
#define LOC
Definition: galleryslide.cpp:14
MythUIType::SetPosition
void SetPosition(int x, int y)
Convenience method, calls SetPosition(const MythPoint&) Override that instead to change functionality...
Definition: mythuitype.cpp:532
SlideBuffer::Flush
void Flush(Slide *slide, const QString &reason)
Signal if any slides are waiting to be displayed.
Definition: galleryslide.cpp:729
SBLOC
#define SBLOC
Definition: galleryslide.cpp:15
UIEffects::Middle
@ Middle
Definition: mythuianimation.h:17
Slide::Clear
void Clear()
Reset slide to unused state.
Definition: galleryslide.cpp:325
Slide::m_zoom
float m_zoom
Current zoom, 1.0 = fullsize.
Definition: galleryslide.h:194
GroupAnimation::Start
void Start(bool forwards, float speed=1.0) override
Initialise & start base animation.
Definition: galleryslide.h:96
Slide::Pan
void Pan(QPoint offset)
Initiate pan.
Definition: galleryslide.cpp:495
Slide::LoadSlide
bool LoadSlide(const ImagePtrK &im, int direction=0, bool notifyCompletion=false)
Load slide with an image.
Definition: galleryslide.cpp:364
Slide::SetPan
void SetPan(QPoint pos)
Sets slide pan.
Definition: galleryslide.cpp:525
MythUIType::m_parent
MythUIType * m_parent
Definition: mythuitype.h:294
Slide::ImageLoaded
void ImageLoaded(Slide *)
Generated when the last requested image has loaded.
Slide::GetImageData
ImagePtrK GetImageData() const
Definition: galleryslide.h:165
sizetliteral.h
Animation::m_parent
Slide * m_parent
Image to be animated.
Definition: galleryslide.h:79
Slide::m_state
SlideState m_state
Slide validity.
Definition: galleryslide.h:190
SLIDE_BUFFER_SIZE
static constexpr size_t SLIDE_BUFFER_SIZE
Definition: galleryslide.cpp:25
MythUIImage::CopyFrom
void CopyFrom(MythUIType *base) override
Copy this widgets state from another.
Definition: mythuiimage.cpp:1427
UIEffects::m_centre
Centre m_centre
Definition: mythuianimation.h:43
AbstractAnimation::m_running
bool m_running
True whilst animation is active.
Definition: galleryslide.h:47
SlideBuffer::Preload
void Preload(const ImagePtrK &im)
Load an image in next available slide.
Definition: galleryslide.cpp:679
Slide::GetDebugState
QChar GetDebugState() const
Return debug status.
Definition: galleryslide.cpp:339
MythUIType
The base class on which all widgets and screens are based.
Definition: mythuitype.h:85
SlideBuffer::Initialise
void Initialise(MythUIImage &image)
Construct buffer.
Definition: galleryslide.cpp:593
Animation::Zoom
@ Zoom
Definition: galleryslide.h:58
Animation
A single animation controlling alpha, zoom, rotation and position.
Definition: galleryslide.h:54
Animation::Position
@ Position
Definition: galleryslide.h:58
MythDate::currentMSecsSinceEpochAsDuration
std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
Definition: mythdate.cpp:198
galleryslide.h
Defines specialised images used by the Gallery slideshow and the animation framework used by transfor...
Slide::Zoom
void Zoom(int percentage)
Initiate slide zoom.
Definition: galleryslide.cpp:452
SlideBuffer::m_mutexQ
QRecursiveMutex m_mutexQ
Queue protection.
Definition: galleryslide.h:254
UIEffects::m_vzoom
float m_vzoom
Definition: mythuianimation.h:41
SequentialAnimation::Start
void Start(bool forwards, float speed=1.0) override
Start sequential animation.
Definition: galleryslide.cpp:161
Slide::kLoaded
@ kLoaded
Definition: galleryslide.h:188
Slide::m_zoomAnimation
Animation * m_zoomAnimation
Dedicated animation for zoom, if supported.
Definition: galleryslide.h:197
ParallelAnimation::Start
void Start(bool forwards, float speed=1.0) override
Start parallel group. All children play simultaneously.
Definition: galleryslide.cpp:224
GroupAnimation::SetSpeed
void SetSpeed(float speed) override
Definition: galleryslide.h:98
imagemetadata.h
Handles Exif/FFMpeg metadata tags for images.
SequentialAnimation::Pulse
void Pulse() override
Progress sequential animation.
Definition: galleryslide.cpp:146
SlideBuffer::BufferState
QString BufferState()
Determines buffer state for debug logging.
Definition: galleryslide.cpp:633
GroupAnimation::Add
virtual void Add(AbstractAnimation *child)
Add child animation to group.
Definition: galleryslide.cpp:126
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1108
SequentialAnimation::SetSpeed
void SetSpeed(float speed) override
Change speed of current child animation and all subsequent ones.
Definition: galleryslide.cpp:178
UIEffects::Centre
Centre
Definition: mythuianimation.h:16
ParallelAnimation::m_finished
int m_finished
Count of child animations that have finished.
Definition: galleryslide.h:141
ParallelAnimation::Pulse
void Pulse() override
Progress parallel animations.
Definition: galleryslide.cpp:208
Slide::m_direction
int m_direction
Navigation that created this image, -1 = Prev, 0 = Update, 1 = Next.
Definition: galleryslide.h:196
MythUIType::SetHorizontalZoom
void SetHorizontalZoom(float zoom)
Definition: mythuitype.cpp:970
Animation::VerticalZoom
@ VerticalZoom
Definition: galleryslide.h:58
GroupAnimation::Clear
void Clear() override
Delete all child animations.
Definition: galleryslide.cpp:137
PanAnimation
Specialised animation for panning slideshow images (MythUI doesn't support panning)
Definition: galleryslide.h:147
SlideBuffer::m_queue
QQueue< Slide * > m_queue
Queue of slides.
Definition: galleryslide.h:256
MythUIType::SetCentre
void SetCentre(UIEffects::Centre centre)
Definition: mythuitype.cpp:959
MythUIType::SetAngle
void SetAngle(float angle)
Definition: mythuitype.cpp:982
UIEffects::m_hzoom
float m_hzoom
Definition: mythuianimation.h:40
MythUIType::SetVerticalZoom
void SetVerticalZoom(float zoom)
Definition: mythuitype.cpp:976
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:674
Slide::m_waitingFor
ImagePtrK m_waitingFor
The most recently requested image. Null for preloads. Differs from m_data when skipping.
Definition: galleryslide.h:193
Animation::Start
void Start(bool forwards=true, float speed=1.0) override
Start a single animation.
Definition: galleryslide.cpp:66
mythmainwindow.h
SlideBuffer::~SlideBuffer
~SlideBuffer() override
Definition: galleryslide.cpp:573
MythUIType::SetRedraw
void SetRedraw(void)
Definition: mythuitype.cpp:308
Animation::None
@ None
Definition: galleryslide.h:58
Animation::Alpha
@ Alpha
Definition: galleryslide.h:58
AbstractAnimation::finished
void finished()
Signals animation has finished.
Orientation
Encapsulates Exif orientation processing.
Definition: imagemetadata.h:62
Animation::updateCurrentValue
void updateCurrentValue(const QVariant &value) override
Update animated value.
Definition: galleryslide.cpp:102