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  bool finished { false };
197 
198  // Finish group when last child finishes
199  if (m_forwards)
200  {
201  m_current++;
202  finished = (m_current == m_group.size());
203  }
204  else
205  {
206  m_current--;
207  finished = (m_current < 0);
208  }
209 
210  if (finished)
212  else
213  // Start next child
214  m_group.at(m_current)->Start(m_forwards, m_speed);
215 }
216 
217 
221 {
222  if (m_running)
223  {
224  // Pulse all children
225  for (AbstractAnimation *animation : std::as_const(m_group))
226  animation->Pulse();
227  }
228 }
229 
230 
236 void ParallelAnimation::Start(bool forwards, float speed)
237 {
238  if (m_group.empty())
239  return;
240 
241  m_finished = m_group.size();
242 
243  // Start group, then all children
244  GroupAnimation::Start(forwards, speed);
245  for (AbstractAnimation *animation : std::as_const(m_group))
246  animation->Start(m_forwards, m_speed);
247 }
248 
249 
255 {
256  // Set group speed, then all children
258  for (AbstractAnimation *animation : std::as_const(m_group))
259  animation->SetSpeed(m_speed);
260 }
261 
262 
267 {
268  // Finish group when last child finishes
269  if (--m_finished == 0)
271 }
272 
273 
278 void PanAnimation::updateCurrentValue(const QVariant &value)
279 {
280  if (m_parent && m_running)
281  {
282  Slide *image = m_parent;
283  image->SetPan(value.toPoint());
284  }
285 }
286 
287 
294 Slide::Slide(MythUIType *parent, const QString& name, MythUIImage *image)
295  : MythUIImage(parent, name)
296 {
297  // Clone from image
298  CopyFrom(image);
299 
300  // Null parent indicates we should become a child of the image (after
301  // copy to avoid recursion)
302  if (!parent)
303  {
304  // Slides sit on top of parent image area
305  SetArea(MythRect(image->GetArea().toQRect()));
306  m_area.moveTo(0, 0);
307  setParent(image);
308  m_parent = image;
309  image->AddChild(this);
310  }
311 
312  // Provide animations for pan & zoom
313  if (GetPainter()->SupportsAnimation())
314  {
316  m_panAnimation = new PanAnimation(this);
317  }
318 
319  connect(this, &MythUIImage::LoadComplete, this, &Slide::SlideLoaded);
320 }
321 
322 
327 {
328  delete m_zoomAnimation;
329  delete m_panAnimation;
330  LOG(VB_GUI, LOG_DEBUG, "Deleted Slide " + objectName());
331 }
332 
333 
338 {
339  m_state = kEmpty;
340  m_data.clear();
341  m_waitingFor.clear();
342  SetCropRect(0, 0, 0, 0);
343  SetVisible(false);
344 }
345 
346 
351 QChar Slide::GetDebugState() const
352 {
353  switch (m_state)
354  {
355  case kEmpty: return 'e';
356  case kFailed: return 'f';
357  case kLoaded: return m_waitingFor ? 'r' : 'a';
358  case kLoading: return m_waitingFor ? 'l' : 'p';
359  }
360  return '?';
361 }
362 
363 
376 bool Slide::LoadSlide(const ImagePtrK& im, int direction, bool notifyCompletion)
377 {
378  m_direction = direction;
379  m_waitingFor = notifyCompletion ? im : ImagePtrK();
380 
381  if (im == m_data)
382  {
383  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Already loading/loaded %1 in %2")
384  .arg(im->m_filePath, objectName()));
385 
386  if (m_state >= kLoaded && notifyCompletion)
387  // Image has been pre-loaded
388  emit ImageLoaded(this);
389 
390  return (m_state >= kLoaded);
391  }
392 
393  // Is a different image loading ?
394  if (m_state == kLoading)
395  {
396  // Can't abort image loads, so must wait for it to finish
397  // before starting new load
398  m_waitingFor = im;
399 
400  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Postponing load of %1 in %2")
401  .arg(im->m_filePath, objectName()));
402 
403  return false;
404  }
405 
406  // Start load
407  m_data = im;
408  m_state = kLoading;
409 
410  if (im->m_type == kVideoFile)
411  {
412  // Use thumbnail, which has already been orientated
413  SetFilename(im->m_thumbNails.at(0).second);
414  SetOrientation(1);
415  }
416  else
417  {
418  // Load image, compensating for any Qt auto-orientation
419  SetFilename(im->m_url);
420  SetOrientation(Orientation(m_data->m_orientation).GetCurrent(true));
421  }
422 
423  // Load in background
424  Load(true);
425  return false;
426 }
427 
428 
436 {
437  m_state = m_images[0] ? kLoaded : kFailed;
438  if (m_state == kFailed)
439  LOG(VB_GENERAL, LOG_ERR, LOC +
440  QString("Failed to load %1").arg(m_data->m_filePath));
441 
442  // Ignore superseded requests and preloads
443  if (m_data == m_waitingFor)
444  {
445  // Loaded image is the latest requested
446  emit ImageLoaded(this);
447  }
448  else if (m_waitingFor)
449  {
450  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Starting delayed load %1")
451  .arg(m_waitingFor->m_filePath));
452 
453  // Start latest postponed load
455  }
456 }
457 
458 
464 void Slide::Zoom(int percentage)
465 {
466  // Sentinel indicates reset to default zoom
467  float newZoom = (percentage == 0)
468  ? 1.0F
469  : std::clamp(m_zoom * (1.0F + percentage / 100.0F), MIN_ZOOM, MAX_ZOOM);
470  if (newZoom != m_zoom)
471  {
472  if (m_zoomAnimation)
473  {
474  m_zoomAnimation->Set(m_zoom, newZoom, 250ms, QEasingCurve::OutQuad);
476  }
477  else
478  {
479  SetZoom(newZoom);
480  }
481  }
482 }
483 
484 
491 void Slide::SetZoom(float zoom)
492 {
493  m_zoom = zoom;
495 
496  // TODO
497  // MythUIImage displaces widget or doesn't centre for some combinations of
498  // zoom centre/cropping so frig centre for now.
500 
501  SetPan(m_pan);
502 }
503 
504 
509 void Slide::Pan(QPoint offset)
510 {
511  // Panning only possible when zoomed in
512  if (m_zoom > 1.0F)
513  {
514  QPoint start = m_pan;
515 
516  // Sentinel indicates reset to centre
517  // Panning is applied to original (unzoomed) image co-ords.
518  // Adjust offset for zoom so that pan moves a constant screen distance rather
519  // than constant image distance
520  QPoint dest = offset.isNull() ? QPoint(0, 0) : start + offset / m_zoom;
521 
522  if (m_panAnimation)
523  {
524  m_panAnimation->Set(start, dest, 250ms, QEasingCurve::Linear);
526  }
527  else
528  {
529  SetPan(dest);
530  }
531  }
532 }
533 
534 
541 void Slide::SetPan(QPoint pos)
542 {
543  if (m_state == kFailed)
544  {
545  m_pan = pos;
546  return;
547  }
548 
549  // Determine zoom of largest dimension
550  QRect imageArea = m_images[m_curPos]->rect();
551  float hRatio = float(imageArea.height()) / m_area.height();
552  float wRatio = float(imageArea.width()) / m_area.width();
553  float ratio = std::max(hRatio, wRatio); // TODO create a Rational number class
554 
555  if (m_zoom != 0.0F)
556  ratio /= m_zoom;
557 
558  // Determine crop area
559  int h = std::min(int(roundf(m_area.height() * ratio)), imageArea.height());
560  int w = std::min(int(roundf(m_area.width() * ratio)), imageArea.width());
561  int x = imageArea.center().x() - (w / 2);
562  int y = imageArea.center().y() - (h / 2);
563 
564  // Constrain pan to boundaries
565  int limitX = (imageArea.width() - w) / 2;
566  int limitY = (imageArea.height() - h) / 2;
567  m_pan.setX(std::clamp(pos.x(), -limitX, limitX));
568  m_pan.setY(std::clamp(pos.y(), -limitY, limitY));
569 
570  SetCropRect(x + m_pan.x(), y + m_pan.y(), w, h);
571  SetRedraw();
572 }
573 
574 
579 {
580  // Update zoom/pan animations
581  if (m_zoomAnimation)
583 
584  if (m_panAnimation)
586 }
587 
588 
590 {
591  LOG(VB_GUI, LOG_DEBUG, "Deleted Slidebuffer");
592 }
593 
594 
596 {
597  QMutexLocker lock(&m_mutexQ);
598  for (Slide *s : std::as_const(m_queue))
599  s->Clear();
600  LOG(VB_GUI, LOG_DEBUG, "Aborted Slidebuffer");
601 }
602 
603 
610 {
611  // Require at least 4 slides: 2 for transitions, 1 to handle further requests
612  // and 1 to prevent solitary slide from being used whilst it is loading
613  size_t size = std::max(SLIDE_BUFFER_SIZE, 4_UZ);
614 
615  // Fill buffer with slides cloned from the XML image widget
616 
617  // Create first as a child of the XML image.
618  auto *slide = new Slide(nullptr, "slide0", &image);
619 
620  // Buffer is notified when it has loaded image
621  connect(slide, &Slide::ImageLoaded,
622  this, qOverload<Slide*>(&SlideBuffer::Flush));
623 
624  m_queue.enqueue(slide);
625 
626  // Rest are simple clones of first
627  for (size_t i = 1; i < size; ++i)
628  {
629  slide = new Slide(&image, QString("slide%1").arg(i), slide);
630 
631  // All slides (except first) start off hidden
632  slide->SetVisible(false);
633 
634  // Buffer is notified when it has loaded image
635  connect(slide, &Slide::ImageLoaded,
636  this, qOverload<Slide*>(&SlideBuffer::Flush));
637 
638  m_queue.enqueue(slide);
639  }
640 
641  m_nextLoad = 1;
642 }
643 
644 
650 {
651  QMutexLocker lock(&m_mutexQ);
652 
653  QString state;
654  for (int i = 0; i < m_queue.size(); ++i)
655  {
656  QChar code(m_queue.at(i)->GetDebugState());
657  state += (i == m_nextLoad ? code.toUpper() : code);
658  }
659  return QString("[%1] (%2)").arg(state, m_queue.head()->objectName());
660 }
661 
662 
670 bool SlideBuffer::Load(const ImagePtrK& im, int direction)
671 {
672  if (!im)
673  return false;
674 
675  QMutexLocker lock(&m_mutexQ);
676 
677  // Start loading image in next available slide
678  Slide *slide = m_queue.at(m_nextLoad);
679 
680  // Further load requests will go to same slide if no free ones are available
681  if (m_nextLoad < m_queue.size() - 1)
682  ++m_nextLoad;
683 
684  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("Loading %1 in %2, %3")
685  .arg(im->m_filePath, slide->objectName(), BufferState()));
686 
687  return slide->LoadSlide(im, direction, true);
688 }
689 
690 
696 {
697  if (!im)
698  return;
699 
700  QMutexLocker lock(&m_mutexQ);
701 
702  // Start loading image in next available slide
703  Slide *slide = m_queue.at(m_nextLoad);
704 
705  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("Preloading %1 in %2, %3")
706  .arg(im->m_filePath, slide->objectName(), BufferState()));
707 
708  // Load silently
709  slide->LoadSlide(im);
710 }
711 
712 
718 {
719  QMutexLocker lock(&m_mutexQ);
720 
721  // Reset slide & return to buffer for re-use
722  Slide *slide = m_queue.dequeue();
723  slide->Clear();
724  m_queue.enqueue(slide);
725 
726  QString name = slide->objectName();
727 
728  // Free constrained load ptr now a spare slide is available
729  if (!m_queue.at(--m_nextLoad)->IsEmpty())
730  ++m_nextLoad;
731 
732  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("Released %1").arg(name));
733 
734  // Flush any pending slides that originate from multiple requests (skipping)
735  Flush(m_queue.head(), "Pending");
736 }
737 
738 
745 void SlideBuffer::Flush(Slide *slide, const QString& reason)
746 {
747  QMutexLocker lock(&m_mutexQ);
748 
749  // Determine number of consecutive slides that are now available after head
750  // Include last slide to ensure transition speed is consistent: it will never
751  // be displayed because queue size is always > 2
752  int available = 1;
753  while (available < m_queue.size() && m_queue.at(available)->IsLoaded())
754  ++available;
755 
756  if (available == 1)
757  return;
758 
759  // Notify that more slides are available
760  ImagePtrK im = slide->GetImageData();
761  QString path = im ? im->m_filePath : "Unknown";
762 
763  LOG(VB_FILE, LOG_DEBUG, SBLOC + QString("%1 %2 in %3, %4")
764  .arg(reason, path, slide->objectName(), BufferState()));
765 
766  emit SlideReady(--available);
767 }
768 
770 {
771  Flush(slide, "Loaded");
772 };
Slide::~Slide
~Slide() override
Destructor.
Definition: galleryslide.cpp:326
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:17
build_compdb.dest
dest
Definition: build_compdb.py:9
Slide::SetZoom
void SetZoom(float zoom)
Sets slide zoom.
Definition: galleryslide.cpp:491
Animation::Zoom
@ Zoom
Definition: galleryslide.h:58
ParallelAnimation::SetSpeed
void SetSpeed(float speed) override
Change speed of group and all child animations.
Definition: galleryslide.cpp:254
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
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
Animation::Alpha
@ Alpha
Definition: galleryslide.h:58
Animation::Position
@ Position
Definition: galleryslide.h:58
MythUIImage::m_images
QHash< int, MythImage * > m_images
Definition: mythuiimage.h:170
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:578
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:266
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:294
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:971
Slide::SlideLoaded
void SlideLoaded()
An image has completed loading.
Definition: galleryslide.cpp:435
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:1417
AbstractAnimation::m_forwards
bool m_forwards
Play direction.
Definition: galleryslide.h:46
Animation::VerticalZoom
@ VerticalZoom
Definition: galleryslide.h:58
MythUIImage::SetOrientation
void SetOrientation(int orientation)
Saves the exif orientation value of the first image in the widget.
Definition: mythuiimage.cpp:924
MythUIType::SetArea
virtual void SetArea(const MythRect &rect)
Definition: mythuitype.cpp:610
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
GroupAnimation::m_group
QList< AbstractAnimation * > m_group
Definition: galleryslide.h:104
UIEffects::Middle
@ Middle
Definition: mythuianimation.h:18
MythRect
Wrapper around QRect allowing us to handle percentage and other relative values for areas in mythui.
Definition: mythrect.h:17
kVideoFile
@ kVideoFile
A video.
Definition: imagetypes.h:40
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:15
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::None
@ None
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:885
MythUIType::AddChild
void AddChild(MythUIType *child)
Add a child UIType.
Definition: mythuitype.cpp:89
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:717
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:952
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
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:670
SlideBuffer::m_nextLoad
int m_nextLoad
Index of first spare slide, (or last slide if none spare)
Definition: galleryslide.h:253
MythUIType::SetAlpha
void SetAlpha(int newalpha)
Definition: mythuitype.cpp:942
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:595
PanAnimation::updateCurrentValue
void updateCurrentValue(const QVariant &value) override
Update pan value.
Definition: galleryslide.cpp:278
MythUIImage::LoadComplete
void LoadComplete()
MythUIImage::m_curPos
unsigned int m_curPos
Definition: mythuiimage.h:178
LOC
#define LOC
Definition: galleryslide.cpp:14
Slide::kLoading
@ kLoading
Definition: galleryslide.h:188
MythUIType::SetPosition
void SetPosition(int x, int y)
Convenience method, calls SetPosition(const MythPoint&) Override that instead to change functionality...
Definition: mythuitype.cpp:533
SlideBuffer::Flush
void Flush(Slide *slide, const QString &reason)
Signal if any slides are waiting to be displayed.
Definition: galleryslide.cpp:745
SBLOC
#define SBLOC
Definition: galleryslide.cpp:15
Slide::Clear
void Clear()
Reset slide to unused state.
Definition: galleryslide.cpp:337
Animation::HorizontalZoom
@ HorizontalZoom
Definition: galleryslide.h:58
Slide::m_zoom
float m_zoom
Current zoom, 1.0 = fullsize.
Definition: galleryslide.h:194
UIEffects::Centre
Centre
Definition: mythuianimation.h:16
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:509
Slide::LoadSlide
bool LoadSlide(const ImagePtrK &im, int direction=0, bool notifyCompletion=false)
Load slide with an image.
Definition: galleryslide.cpp:376
Slide::SetPan
void SetPan(QPoint pos)
Sets slide pan.
Definition: galleryslide.cpp:541
MythUIType::m_parent
MythUIType * m_parent
Definition: mythuitype.h:294
Slide::kLoaded
@ kLoaded
Definition: galleryslide.h:188
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::Angle
@ Angle
Definition: galleryslide.h:58
clamp
static eu8 clamp(eu8 value, eu8 low, eu8 high)
Definition: pxsup2dast.c:204
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:1438
UIEffects::m_centre
Centre m_centre
Definition: mythuianimation.h:44
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:695
Slide::GetDebugState
QChar GetDebugState() const
Return debug status.
Definition: galleryslide.cpp:351
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:609
Animation
A single animation controlling alpha, zoom, rotation and position.
Definition: galleryslide.h:54
MythDate::currentMSecsSinceEpochAsDuration
std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
Definition: mythdate.cpp:207
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:464
SlideBuffer::m_mutexQ
QRecursiveMutex m_mutexQ
Queue protection.
Definition: galleryslide.h:251
UIEffects::m_vzoom
float m_vzoom
Definition: mythuianimation.h:42
SequentialAnimation::Start
void Start(bool forwards, float speed=1.0) override
Start sequential animation.
Definition: galleryslide.cpp:161
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:236
GroupAnimation::SetSpeed
void SetSpeed(float speed) override
Definition: galleryslide.h:98
Slide::kFailed
@ kFailed
Definition: galleryslide.h:188
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:649
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:1105
SequentialAnimation::SetSpeed
void SetSpeed(float speed) override
Change speed of current child animation and all subsequent ones.
Definition: galleryslide.cpp:178
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:220
Slide::m_direction
int m_direction
Navigation that created this image, -1 = Prev, 0 = Update, 1 = Next.
Definition: galleryslide.h:196
Slide::kEmpty
@ kEmpty
Definition: galleryslide.h:188
MythUIType::SetHorizontalZoom
void SetHorizontalZoom(float zoom)
Definition: mythuitype.cpp:967
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:252
MythUIType::SetCentre
void SetCentre(UIEffects::Centre centre)
Definition: mythuitype.cpp:956
MythUIType::SetAngle
void SetAngle(float angle)
Definition: mythuitype.cpp:979
UIEffects::m_hzoom
float m_hzoom
Definition: mythuianimation.h:41
MythUIType::SetVerticalZoom
void SetVerticalZoom(float zoom)
Definition: mythuitype.cpp:973
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:677
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:589
MythUIType::SetRedraw
void SetRedraw(void)
Definition: mythuitype.cpp:313
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