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