MythTV  master
glsingleview.cpp
Go to the documentation of this file.
1 /* ============================================================
2  * File : glsingleview.cpp
3  * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
4  * Date : 2004-01-13
5  * Description :
6  *
7  * Copyright 2004 by Renchi Raju
8  *
9  * This program is free software; you can redistribute it
10  * and/or modify it under the terms of the GNU General
11  * Public License as published bythe Free Software Foundation;
12  * either version 2, or (at your option)
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * ============================================================ */
21 
22 // Include own header first to catch missing includes
23 #include "glsingleview.h"
24 
25 // ANSI C headers
26 #include <cmath>
27 
28 // C++ headers
29 #include <algorithm>
30 using namespace std;
31 
32 // Qt headers
33 #include <QTimer>
34 #include <QImage>
35 #include <QDir>
36 #include <QPainter>
37 #include <qbuffer.h>
38 
39 // MythTV plugin headers
40 #include <mythcontext.h>
41 #include <mythdate.h>
42 #include <mythuihelper.h>
43 #include "mythlogging.h"
44 #if defined _MSC_VER || defined __MINGW32__
45 # include "compat.h" // for random
46 #endif
47 
48 // MythGallery headers
49 #include "galleryutil.h"
50 
51 #define LOC QString("GLView: ")
52 
54  int *pos, int slideShow, int sortOrder,
55  MythMainWindow *parent, const char *name)
56  : MythDialog(parent, name)
57 {
58  QBoxLayout *l = new QVBoxLayout(this);
59  l->setContentsMargins(0, 0, 0, 0);
60  m_view = new GLSingleView(itemList, pos, slideShow, sortOrder, this);
61  l->addWidget(m_view);
62 
63  setFocusProxy(m_view);
64  m_view->setFocus();
65 }
66 
67 // Have to clean up with this dirty hack because
68 // qglwidget segfaults with a destructive close
69 
70 void GLSDialog::closeEvent(QCloseEvent *e)
71 {
72  m_view->CleanUp();
73  e->accept();
74 
75  accept();
76 }
77 
78 GLSingleView::GLSingleView(ThumbList itemList, int *pos, int slideShow,
79  int sortorder, QWidget *parent)
80  : QGLWidget(parent),
81  ImageView(itemList, pos, slideShow, sortorder),
82  // General
83  m_source_x(0.0f),
84  m_source_y(0.0f),
85  m_scaleMax(kScaleToFit),
86 
87  // Texture variables (for display and effects)
88  m_texMaxDim(512),
89  m_texSize(512,512),
90  m_texCur(0),
91  m_tex1First(true),
92 
93  // Info variables
94  m_texInfo(0),
95 
96  // Common effect state variables
97  m_effect_rotate_direction(0),
98  m_effect_transition_timeout(2000),
99  m_effect_transition_timeout_inv(1.0f / m_effect_transition_timeout),
100 
101  // Unshared effect state variables
102  m_effect_cube_xrot(0.0f),
103  m_effect_cube_yrot(0.0f),
104  m_effect_cube_zrot(0.0f),
105  m_effect_kenBurns_image_timeout(0.0f),
106  m_effect_kenBurns_imageLoadThread(nullptr),
107  m_effect_kenBurns_image_ready(true),
108  m_effect_kenBurns_item(nullptr),
109  m_effect_kenBurns_initialized(false),
110  m_effect_kenBurns_new_image_started(true)
111 {
112  m_scaleMax = (ScaleMax) gCoreContext->GetNumSetting("GalleryScaleMax", 0);
113 
117 
118  m_slideshow_timer = new QTimer(this);
119  RegisterEffects();
120 
121  // --------------------------------------------------------------------
122 
123  setFocusPolicy(Qt::WheelFocus);
124 
125  // --------------------------------------------------------------------
126 
127  QString transType = gCoreContext->GetSetting("SlideshowOpenGLTransition");
128  if (!transType.isEmpty() && m_effect_map.contains(transType))
129  m_effect_method = m_effect_map[transType];
130 
131  if (m_effect_method.isEmpty() || transType == QString("random (gl)"))
132  {
134  m_effect_random = true;
135  }
136 
138  "SlideshowOpenGLTransitionLength", 2000));
139 
140  // --------------------------------------------------------------------
141 
142  connect(m_slideshow_timer, SIGNAL(timeout()), this, SLOT(SlideTimeout()));
143 
144  // --------------------------------------------------------------------
145 
146  if (slideShow)
147  {
149  m_slideshow_running = true;
150  m_slideshow_timer->stop();
151  m_slideshow_timer->setSingleShot(true);
154  }
155 }
156 
158 {
159  // save the current m_scaleMax setting so we can restore it later
160  gCoreContext->SaveSetting("GalleryScaleMax", m_scaleMax);
161  CleanUp();
162 }
163 
165 {
166  makeCurrent();
167 
169  {
172  }
173 
174  if (m_slideshow_timer)
175  {
176  m_slideshow_timer->stop();
177  m_slideshow_timer->deleteLater();
178  m_slideshow_timer = nullptr;
179  }
180 
181  m_texItem[0].Deinit();
182  m_texItem[1].Deinit();
183 
184  if (m_texInfo)
185  glDeleteTextures(1, &m_texInfo);
186 }
187 
189 {
190  // Enable Texture Mapping
191  glEnable(GL_TEXTURE_2D);
192  // Clear The Background Color
193  glClearColor(0.0, 0.0, 0.0, 1.0f);
194 
195  // Turn Blending On
196  glEnable(GL_BLEND);
197  // Blending Function For Translucency Based On Source Alpha Value
198  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
199 
200  // Enable perspective vision
201  glClearDepth(1.0f);
202 
203  GLint param;
204  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &param);
205  m_texMaxDim = param;
206 
207  Load();
208 }
209 
210 void GLSingleView::resizeGL(int w, int h)
211 {
212  // Reset The Current Viewport And Perspective Transformation
213  glViewport(0, 0, w, h);
214 
215  glMatrixMode(GL_PROJECTION);
216  glLoadIdentity();
217 }
218 
220 {
221  if (1 == m_movieState)
222  {
223  m_movieState = 2;
224 
225  ThumbItem *item = getCurrentItem();
226 
227  if (item)
228  {
230  makeCurrent();
231  }
232 
233  if (!m_slideshow_running && item)
234  {
235  QImage image;
236  GetScreenShot(image, item);
237  if (image.isNull())
238  return;
239 
240  image = image.scaled(800, 600);
241 
242  // overlay "Press SELECT to play again" text
243  QPainter p(&image);
244  QRect rect = QRect(20, image.height() - 100,
245  image.width() - 40, 80);
246  p.fillRect(rect, QBrush(QColor(0,0,0,100)));
247  p.setFont(QFont("Arial", 25, QFont::Bold));
248  p.setPen(QColor(255,255,255));
249  p.drawText(rect, Qt::AlignCenter, tr("Press SELECT to play again"));
250  p.end();
251 
252  m_texSize = QSize(
253  GetNearestGLTextureSize(image.size().width()),
254  GetNearestGLTextureSize(image.size().height()));
255  int a = m_tex1First ? 0 : 1;
256  m_texItem[a].SetItem(item, image.size());
258  m_texItem[a].Init(convertToGLFormat(
259  image.scaled(m_texSize,
260  Qt::IgnoreAspectRatio,
261  Qt::SmoothTransformation)));
262  }
263  }
264 
265  glDisable(GL_DEPTH_TEST);
266 
267  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
268  glLoadIdentity();
269 
270  glMatrixMode(GL_PROJECTION);
271  glLoadIdentity();
272 
273  glMatrixMode(GL_MODELVIEW);
274  glLoadIdentity();
275 
276  if (m_effect_running && !m_effect_method.isEmpty())
277  {
279  }
280  else
281  {
282  paintTexture();
283  }
284 
285  if (glGetError())
286  LOG(VB_GENERAL, LOG_ERR, LOC + "OpenGL error detected");
287 }
288 
289 void GLSingleView::keyPressEvent(QKeyEvent *e)
290 {
291  bool handled = false;
292 
295  bool wasRunning = m_slideshow_running;
296  if (m_slideshow_timer)
297  m_slideshow_timer->stop();
298  m_slideshow_running = false;
300  m_effect_running = false;
302 
303  bool wasInfo = m_info_show;
304  m_info_show = false;
305  bool wasInfoShort = m_info_show_short;
306  m_info_show_short = false;
307 
308  QStringList actions;
309  handled = GetMythMainWindow()->TranslateKeyPress("Gallery", e, actions);
310 
311  float scrollX = 0.2f;
312  float scrollY = 0.2f;
313 
314  for (int i = 0; i < actions.size() && !handled; i++)
315  {
316  QString action = actions[i];
317  handled = true;
318 
319  if (action == "LEFT" || action == "UP")
320  {
321  m_info_show = wasInfo;
322  m_slideshow_running = wasRunning;
323  DisplayPrev(true, true);
324  }
325  else if (action == "RIGHT" || action == "DOWN")
326  {
327  m_info_show = wasInfo;
328  m_slideshow_running = wasRunning;
329  DisplayNext(true, true);
330  }
331  else if (action == "ZOOMOUT")
332  {
333  if (m_zoom > 0.5f)
334  {
335  SetZoom(m_zoom - 0.5f);
336  if (m_zoom > 1.0f)
337  {
338  m_source_x -= m_source_x / ((m_zoom + 0.5f) * 2.0f);
339  m_source_y -= m_source_y / ((m_zoom + 0.5f) * 2.0f);
340 
341  checkPosition();
342  }
343  else
344  {
345  m_source_x = 0;
346  m_source_y = 0;
347  }
348  }
349  }
350  else if (action == "ZOOMIN")
351  {
352  if (m_zoom < 4.0f)
353  {
354  SetZoom(m_zoom + 0.5f);
355  if (m_zoom > 1.0f)
356  {
357  m_source_x += m_source_x / (m_zoom * 2.0f);
358  m_source_y += m_source_y / (m_zoom * 2.0f);
359 
360  checkPosition();
361  }
362  else
363  {
364  m_source_x = 0;
365  m_source_y = 0;
366  }
367  }
368  }
369  else if (action == "FULLSIZE")
370  {
371  m_source_x = 0;
372  m_source_y = 0;
373  if (m_zoom != 1)
374  SetZoom(1.0f);
375  }
376  else if (action == "SCROLLLEFT")
377  {
378  if (m_zoom > 1.0f && m_source_x < m_zoom - 1.0f)
379  {
380  m_source_x += scrollX;
381  m_source_x = min(m_source_x, m_zoom - 1.0f);
382  }
383  }
384  else if (action == "SCROLLRIGHT")
385  {
386  if (m_zoom > 1.0f && m_source_x > -m_zoom + 1.0f)
387  {
388  m_source_x -= scrollX;
389  m_source_x = max(m_source_x, -m_zoom + 1.0f);
390  }
391  }
392  else if (action == "SCROLLDOWN")
393  {
394  if (m_zoom > 1.0f && m_source_y < m_zoom - 1.0f)
395  {
396  m_source_y += scrollY;
397  m_source_y = min(m_source_y, m_zoom - 1.0f);
398  }
399  }
400  else if (action == "SCROLLUP")
401  {
402  if (m_zoom > 1.0f && m_source_y > -m_zoom + 1.0f)
403  {
404  m_source_y -= scrollY;
405  m_source_y = max(m_source_y, -m_zoom + 1.0f);
406  }
407  }
408  else if (action == "RECENTER")
409  {
410  if (m_zoom > 1.0f)
411  {
412  m_source_x = 0.0f;
413  m_source_y = 0.0f;
414  }
415  }
416  else if (action == "UPLEFT")
417  {
418  if (m_zoom > 1.0f)
419  {
420  m_source_x = 1.0f;
421  m_source_y = -1.0f;
422  }
423  }
424  else if (action == "LOWRIGHT")
425  {
426  if (m_zoom > 1.0f)
427  {
428  m_source_x = -1.0f;
429  m_source_y = 1.0f;
430  }
431  }
432  else if (action == "ROTRIGHT")
433  {
434  m_source_x = 0;
435  m_source_y = 0;
436  Rotate(90);
437  }
438  else if (action == "ROTLEFT")
439  {
440  m_source_x = 0;
441  m_source_y = 0;
442  Rotate(-90);
443  }
444  else if (action == "DELETE")
445  {
446  ThumbItem *item = getCurrentItem();
447  if (item && GalleryUtil::Delete(item->GetPath()))
448  {
449  item->SetPixmap(nullptr);
450  DisplayNext(true, true);
451  }
452  m_info_show = wasInfo;
453  m_slideshow_running = wasRunning;
454  }
455  else if ((action == "PLAY" || action == "SELECT") && m_movieState == 2)
456  {
457  m_movieState = 1;
458  }
459  else if (action == "PLAY" || action == "SLIDESHOW" ||
460  action == "RANDOMSHOW" || action == "SEASONALSHOW")
461  {
462  m_source_x = 0;
463  m_source_y = 0;
464  SetZoom(1.0f);
465  m_info_show = wasInfo;
466  m_info_show_short = true;
467  m_slideshow_running = !wasRunning;
468  }
469  else if (action == "INFO")
470  {
471  m_info_show = !wasInfo && !wasInfoShort;
472  m_slideshow_running = wasRunning;
473  }
474  else if (action == "FULLSCREEN")
475  {
477  m_source_x = 0;
478  m_source_y = 0;
479  SetZoom(1.0f);
480 
481  int a = m_tex1First ? 0 : 1;
483  }
484  else
485  {
486  handled = false;
487  }
488  }
489 
491  {
492  m_slideshow_timer->stop();
493  m_slideshow_timer->setSingleShot(true);
495  }
496 
498  {
501  }
502 
503  updateGL();
504 
505  if (handled)
506  {
507  e->accept();
508  }
509  else {
510  e->ignore();
511  }
512 }
513 
515 {
516  m_source_x = max(m_source_x, -m_zoom + 1.0f);
517  m_source_y = max(m_source_y, -m_zoom + 1.0f);
518  m_source_x = min(m_source_x, m_zoom - 1.0f);
519  m_source_y = min(m_source_y, m_zoom - 1.0f);
520 }
521 
523 {
524  glMatrixMode(GL_MODELVIEW);
525  glLoadIdentity();
526 
527  glTranslatef(m_source_x, m_source_y, 0.0f);
528  glScalef(m_zoom, m_zoom, 1.0f);
529 
531 
533  {
534  createTexInfo();
535 
536  glMatrixMode(GL_MODELVIEW);
537  glLoadIdentity();
538 
539  glMatrixMode(GL_TEXTURE);
540  glLoadIdentity();
541 
542  glBindTexture(GL_TEXTURE_2D, m_texInfo);
543  glBegin(GL_QUADS);
544  {
545  glColor4f(1.0f, 1.0f, 1.0f, 0.72f);
546  glTexCoord2f(0.0f, 0.0f);
547  glVertex3f(-0.75f, -0.75f, 0.0f);
548 
549  glTexCoord2f(1.0f, 0.0f);
550  glVertex3f(+0.75f, -0.75f, 0.0f);
551 
552  glTexCoord2f(1.0f, 1.0f);
553  glVertex3f(+0.75f, +0.75f, 0.0f);
554 
555  glTexCoord2f(0.0f, 1.0f);
556  glVertex3f(-0.75f, +0.75f, 0.0f);
557  }
558  glEnd();
559  }
560 }
561 
562 void GLSingleView::DisplayNext(bool reset, bool loadImage)
563 {
564  if (reset)
565  {
566  m_zoom = 1.0f;
567  m_source_x = 0.0f;
568  m_source_y = 0.0f;
569  }
570 
571  // Search for next item that hasn't been deleted.
572  // Close viewer if none remain.
573  int oldpos = m_pos;
574 
575  while (true)
576  {
577  ThumbItem *item = advanceItem();
578  if (item)
579  {
580  if (QFile::exists(item->GetPath()))
581  {
582  break;
583  }
584  }
585  if (m_pos == oldpos)
586  {
587  // No valid items!!!
588  close();
589  }
590  }
591 
593  m_texCur = (m_texCur) ? 0 : 1;
594 
595  if (loadImage)
596  Load();
597 }
598 
599 void GLSingleView::DisplayPrev(bool reset, bool loadImage)
600 {
601  if (reset)
602  {
603  m_zoom = 1.0f;
604  m_source_x = 0.0f;
605  m_source_y = 0.0f;
606  }
607 
608  // Search for next item that hasn't been deleted.
609  // Close viewer in none remain.
610  int oldpos = m_pos;
611  while (true)
612  {
613  ThumbItem *item = retreatItem();
614  if (item && QFile::exists(item->GetPath()))
615  break;
616 
617  if (m_pos == oldpos)
618  {
619  // No valid items!!!
620  close();
621  }
622  };
623 
625  m_texCur = (m_texCur) ? 0 : 1;
626 
627  if (loadImage)
628  Load();
629 }
630 
632 {
633  m_movieState = 0;
634  ThumbItem *item = getCurrentItem();
635  if (!item)
636  {
637  LOG(VB_GENERAL, LOG_ERR, LOC + QString("No item at %1").arg(m_pos));
638  return;
639  }
640 
641  if (GalleryUtil::IsMovie(item->GetPath()))
642  {
643  m_movieState = 1;
644  return;
645  }
646 
647  QImage image(item->GetPath());
648  if (image.isNull())
649  return;
650 
651  m_texSize = QSize(GetNearestGLTextureSize(image.size().width()),
652  GetNearestGLTextureSize(image.size().height()));
653  int a = m_tex1First ? 0 : 1;
654  m_texItem[a].SetItem(item, image.size());
656  m_texItem[a].Init(convertToGLFormat(
657  image.scaled(m_texSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)));
658 
659  UpdateLCD(item);
660 }
661 
662 void GLSingleView::Rotate(int angle)
663 {
664  int ang = m_texItem[m_texCur].GetAngle() + angle;
665 
666  ang = (ang >= 360) ? ang - 360 : ang;
667  ang = (ang < 0) ? ang + 360 : ang;
668 
670 
671  ThumbItem *item = getCurrentItem();
672  if (item)
673  item->SetRotationAngle(ang);
674 
677 }
678 
679 void GLSingleView::SetZoom(float zoom)
680 {
681  m_zoom = zoom;
682 }
683 
685 {
688  if (timeout)
690 }
691 
693 {
694  int n = 0, last = 0;
695  int s;
696 
697  for (s = 0; s < 32; ++s)
698  {
699  if (((v >> s) & 1) == 1)
700  {
701  ++n;
702  last = s;
703  }
704  }
705 
706  if (n > 1 && last < 31)
707  s = 1 << (last + 1);
708  else
709  s = 1 << last;
710 
711  return min(s, m_texMaxDim);
712 }
713 
715 {
716  m_effect_map.insert("none", "EffectNone");
717  m_effect_map.insert("blend (gl)", "EffectBlend");
718  m_effect_map.insert("zoom blend (gl)", "EffectZoomBlend");
719  m_effect_map.insert("fade (gl)", "EffectFade");
720  m_effect_map.insert("rotate (gl)", "EffectRotate");
721  m_effect_map.insert("bend (gl)", "EffectBend");
722  m_effect_map.insert("inout (gl)", "EffectInOut");
723  m_effect_map.insert("slide (gl)", "EffectSlide");
724  m_effect_map.insert("flutter (gl)", "EffectFlutter");
725  m_effect_map.insert("cube (gl)", "EffectCube");
726  m_effect_map.insert("Ken Burns (gl)", "EffectKenBurns");
727 }
728 
729 void GLSingleView::RunEffect(const QString &effect)
730 {
731  if (effect == "EffectBlend")
732  EffectBlend();
733  else if (effect == "EffectZoomBlend")
734  EffectZoomBlend();
735  else if (effect == "EffectFade")
736  EffectFade();
737  else if (effect == "EffectRotate")
738  EffectRotate();
739  else if (effect == "EffectBend")
740  EffectBend();
741  else if (effect == "EffectInOut")
742  EffectInOut();
743  else if (effect == "EffectSlide")
744  EffectSlide();
745  else if (effect == "EffectFlutter")
746  EffectFlutter();
747  else if (effect == "EffectCube")
748  EffectCube();
749  else if (effect == "EffectKenBurns")
750  EffectKenBurns();
751  else //if (effect == "EffectNone")
752  EffectNone();
753 }
754 
756 {
757  paintTexture();
758  m_effect_running = false;
760  return;
761 }
762 
764 {
766  {
767  paintTexture();
768  m_effect_running = false;
770  return;
771  }
772 
774 
775  m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
776 
777  glBegin(GL_QUADS);
778  {
779  glColor4f(0.0f, 0.0f, 0.0f, 1.0f * t);
780  glVertex3f(-1.0f, -1.0f, 0.0f);
781  glVertex3f(+1.0f, -1.0f, 0.0f);
782  glVertex3f(+1.0f, +1.0f, 0.0f);
783  glVertex3f(-1.0f, +1.0f, 0.0f);
784  }
785  glEnd();
786 
788 
790 }
791 
793 {
795  {
796  paintTexture();
797  m_effect_running = false;
799  return;
800  }
801 
803 
804  m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f - t, 1.0f + (0.75f * t));
806 
808 }
809 
811 {
813  {
814  paintTexture();
815  m_effect_running = false;
817  return;
818  }
819 
820  if (m_effect_current_frame == 0)
821  m_effect_rotate_direction = (int)((2.0*random()/(RAND_MAX+1.0)));
822 
824 
826 
827  glMatrixMode(GL_MODELVIEW);
828  glLoadIdentity();
829  float rotate = 360.0f * t;
830  glRotatef(((m_effect_rotate_direction == 0) ? -1 : 1) * rotate,
831  0.0f, 0.0f, 1.0f);
832  float scale = 1.0f * (1.0f - t);
833  glScalef(scale, scale, 1.0f);
834 
835  m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
836 
838 }
839 
841 {
843  {
844  paintTexture();
845  m_effect_running = false;
847  return;
848  }
849 
850  if (m_effect_current_frame == 0)
851  m_effect_rotate_direction = (int)((2.0f*random()/(RAND_MAX+1.0f)));
852 
854 
856 
857  glMatrixMode(GL_MODELVIEW);
858  glLoadIdentity();
859  glRotatef(90.0f * t,
860  (m_effect_rotate_direction == 0) ? 1.0f : 0.0f,
861  (m_effect_rotate_direction == 1) ? 1.0f : 0.0f,
862  0.0f);
863 
864  m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
865 
867 }
868 
870 {
872  {
873  paintTexture();
874  m_effect_running = false;
876  return;
877  }
878 
880 
882  m_texItem[(m_texCur) ? 0 : 1].MakeQuad(1.0f - (2.0f * t));
883  else
884  m_texItem[m_texCur].MakeQuad(2.0f * (t - 0.5f));
885 
887 }
888 
890 {
892  {
893  paintTexture();
894  m_effect_running = false;
896  return;
897  }
898 
899  if (m_effect_current_frame == 0)
900  {
901  m_effect_rotate_direction = 1 + (int)((4.0f*random()/(RAND_MAX+1.0f)));
902  }
903 
904  int texnum = m_texCur;
905  bool fadeout = false;
906  float const elapsed = m_effect_frame_time.elapsed();
907  if (elapsed <= m_effect_transition_timeout / 2)
908  {
909  texnum = (m_texCur) ? 0 : 1;
910  fadeout = true;
911  }
912 
913  glMatrixMode(GL_MODELVIEW);
914  glLoadIdentity();
915 
916  float tt = elapsed * m_effect_transition_timeout_inv;
917  float t = 2.0f * ((fadeout) ? (0.5f - tt) : (tt - 0.5f));
918 
919  glScalef(t, t, 1);
920  t = 1.0f - t;
921  glTranslatef((m_effect_rotate_direction % 2 == 0) ? ((m_effect_rotate_direction == 2)? t : -t) : 0,
922  (m_effect_rotate_direction % 2 == 1) ? ((m_effect_rotate_direction == 1)? t : -t) : 0,
923  0);
924 
925  m_texItem[texnum].MakeQuad();
926 
928 }
929 
931 {
933  {
934  paintTexture();
935  m_effect_running = false;
937  return;
938  }
939 
940  if (m_effect_current_frame == 0)
941  m_effect_rotate_direction = 1 + (int)((4.0f * random() / (RAND_MAX + 1.0f)));
942 
944 
945  glMatrixMode(GL_MODELVIEW);
946  glLoadIdentity();
948  float trans = 2.0f * t;
949  glTranslatef((m_effect_rotate_direction % 2 == 0) ? ((m_effect_rotate_direction == 2)? 1 : -1) * trans : 0.0f,
950  (m_effect_rotate_direction % 2 == 1) ? ((m_effect_rotate_direction == 1)? 1 : -1) * trans : 0.0f,
951  0.0f);
952 
953  m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
954 
956 }
957 
959 {
961  {
962  paintTexture();
963  m_effect_running = false;
965  return;
966  }
967 
968  GLTexture &ta = m_texItem[(m_texCur) ? 0 : 1];
969 
970  if (m_effect_current_frame == 0)
971  {
972  for (int x = 0; x < 40; x++)
973  {
974  for (int y = 0; y < 40; y++)
975  {
976  m_effect_flutter_points[x][y][0] =
977  (x / 20.0f - 1.0f) * ta.GetTextureX();
978  m_effect_flutter_points[x][y][1] =
979  (y / 20.0f - 1.0f) * ta.GetTextureY();
980  m_effect_flutter_points[x][y][2] =
981  sin((x / 20.0f - 1.0f) * static_cast<float>(M_PI) * 2.0f) / 5.0f;
982  }
983  }
984  }
985 
987 
989  float rotate = 60.0f * t;
990  float scale = 1.0f - t;
991 
992  glMatrixMode(GL_MODELVIEW);
993  glLoadIdentity();
994  glRotatef(rotate, 1.0f, 0.0f, 0.0f);
995  glScalef(scale, scale, scale);
996  glTranslatef(t, t, 0.0f);
997 
998  ta.Bind();
999 
1000  glBegin(GL_QUADS);
1001  {
1002  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1003 
1004  float float_x, float_y, float_xb, float_yb;
1005  int x, y;
1006 
1007  for (x = 0; x < 39; x++)
1008  {
1009  for (y = 0; y < 39; y++)
1010  {
1011  float_x = (float) x / 40.0f;
1012  float_y = (float) y / 40.0f;
1013  float_xb = (float) (x + 1) / 40.0f;
1014  float_yb = (float) (y + 1) / 40.0f;
1015  glTexCoord2f(float_x, float_y);
1016  glVertex3f(m_effect_flutter_points[x][y][0],
1017  m_effect_flutter_points[x][y][1],
1018  m_effect_flutter_points[x][y][2]);
1019  glTexCoord2f(float_x, float_yb);
1020  glVertex3f(m_effect_flutter_points[x][y + 1][0],
1021  m_effect_flutter_points[x][y + 1][1],
1022  m_effect_flutter_points[x][y + 1][2]);
1023  glTexCoord2f(float_xb, float_yb);
1024  glVertex3f(m_effect_flutter_points[x + 1][y + 1][0],
1025  m_effect_flutter_points[x + 1][y + 1][1],
1026  m_effect_flutter_points[x + 1][y + 1][2]);
1027  glTexCoord2f(float_xb, float_y);
1028  glVertex3f(m_effect_flutter_points[x + 1][y][0],
1029  m_effect_flutter_points[x + 1][y][1],
1030  m_effect_flutter_points[x + 1][y][2]);
1031  }
1032  }
1033  }
1034  glEnd();
1035 
1036  // wave every two iterations
1037  if (m_effect_current_frame%2 == 0)
1038  {
1039  for (int y = 0; y < 40; y++)
1040  {
1041  float hold = m_effect_flutter_points[0][y][2];
1042  for (int x = 0; x < 39; x++)
1043  {
1044  m_effect_flutter_points[x][y][2] = m_effect_flutter_points[x + 1][y][2];
1045  }
1046  m_effect_flutter_points[39][y][2] = hold;
1047  }
1048  }
1050 }
1051 
1053 {
1055  float const rotStart = 0.25 * m_effect_transition_timeout;
1056 
1058  {
1059  paintTexture();
1060  m_effect_running = false;
1062  return;
1063  }
1064 
1065  // Enable perspective vision
1066  glEnable(GL_DEPTH_TEST);
1067  glDepthFunc(GL_LEQUAL);
1068  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1069 
1070  GLTexture &ta = m_texItem[(m_texCur) ? 0 : 1];
1071  GLTexture &tb = m_texItem[m_texCur];
1072 
1073  glMatrixMode(GL_PROJECTION);
1074  glLoadIdentity();
1075 
1076 // float PI = 4.0f * atan(1.0f);
1077  float const znear = 3.0f;
1078 // float theta = 2.0f * atan2(2.0f / 2.0f, znear);
1079 // theta = theta * 180.0f/PI;
1080 
1081  glFrustum(-1, 1, -1, 1, znear, 10);
1082 
1083  if (m_effect_current_frame == 0)
1084  {
1085  m_effect_cube_xrot = 0;
1086  m_effect_cube_yrot = 0;
1087  m_effect_cube_zrot = 0;
1088  }
1089 
1090  glMatrixMode(GL_MODELVIEW);
1091  glLoadIdentity();
1092 
1093  float const elapsed = static_cast<float>(m_effect_frame_time.elapsed());
1094  float const tmp = (elapsed <= tot * 0.5f) ? elapsed : tot - elapsed;
1095  float const trans = 5.0f * tmp / tot;
1096 
1097  glTranslatef(0, 0, -znear - 1.0f - trans);
1098 
1099  glRotatef(m_effect_cube_xrot, 1, 0, 0);
1100  glRotatef(m_effect_cube_yrot, 0, 1, 0);
1101 
1102  glBindTexture(GL_TEXTURE_2D, 0);
1103 
1104  glBegin(GL_QUADS);
1105  {
1106  GLfloat const v = 0.999f; // <1 to avoid conflicts along edges
1107 
1108  glColor4f(0, 0, 0, 1);
1109 
1110  /* Front Face */
1111  glVertex3f(-1, -1, v);
1112  glVertex3f( 1, -1, v);
1113  glVertex3f( 1, 1, v);
1114  glVertex3f(-1, 1, v);
1115 
1116  /* Back Face */
1117  glVertex3f(-1, -1, -v);
1118  glVertex3f(-1, 1, -v);
1119  glVertex3f( 1, 1, -v);
1120  glVertex3f( 1, -1, -v);
1121 
1122  /* Top Face */
1123  glVertex3f(-1, v, -1);
1124  glVertex3f(-1, v, 1);
1125  glVertex3f( 1, v, 1);
1126  glVertex3f( 1, v, -1);
1127 
1128  /* Bottom Face */
1129  glVertex3f(-1, -v, -1);
1130  glVertex3f( 1, -v, -1);
1131  glVertex3f( 1, -v, 1);
1132  glVertex3f(-1, -v, 1);
1133 
1134  /* Right face */
1135  glVertex3f(v, -1, -1);
1136  glVertex3f(v, 1, -1);
1137  glVertex3f(v, 1, 1);
1138  glVertex3f(v, -1, 1);
1139 
1140  /* Left Face */
1141  glVertex3f(-v, -1, -1);
1142  glVertex3f(-v, -1, 1);
1143  glVertex3f(-v, 1, 1);
1144  glVertex3f(-v, 1, -1);
1145 
1146  }
1147  glEnd();
1148 
1149  ta.Bind();
1150 
1151  glBegin(GL_QUADS);
1152  {
1153  glColor4d(1, 1, 1, 1);
1154 
1155  // Front Face
1156  glTexCoord2f(0, 0);
1157  glVertex3f(-ta.GetTextureX(), -ta.GetTextureY(), 1);
1158  glTexCoord2f(1, 0);
1159  glVertex3f(+ta.GetTextureX(), -ta.GetTextureY(), 1);
1160  glTexCoord2f(1, 1);
1161  glVertex3f(+ta.GetTextureX(), +ta.GetTextureY(), 1);
1162  glTexCoord2f(0, 1);
1163  glVertex3f(-ta.GetTextureX(), +ta.GetTextureY(), 1);
1164 
1165  // Top Face
1166  glTexCoord2f(1, 1);
1167  glVertex3f(-ta.GetTextureX(), 1, -ta.GetTextureY());
1168  glTexCoord2f(1, 0);
1169  glVertex3f(-ta.GetTextureX(), 1, +ta.GetTextureY());
1170  glTexCoord2f(0, 0);
1171  glVertex3f(+ta.GetTextureX(), 1, +ta.GetTextureY());
1172  glTexCoord2f(0, 1);
1173  glVertex3f(+ta.GetTextureX(), 1, -ta.GetTextureY());
1174 
1175  // Bottom Face
1176  glTexCoord2f(0, 1);
1177  glVertex3f(-ta.GetTextureX(), -1, -ta.GetTextureY());
1178  glTexCoord2f(1, 1);
1179  glVertex3f(+ta.GetTextureX(), -1, -ta.GetTextureY());
1180  glTexCoord2f(1, 0);
1181  glVertex3f(+ta.GetTextureX(), -1, +ta.GetTextureY());
1182  glTexCoord2f(0, 0);
1183  glVertex3f(-ta.GetTextureX(), -1, +ta.GetTextureY());
1184 
1185  // Right face
1186  glTexCoord2f(0, 0);
1187  glVertex3f(1, -ta.GetTextureX(), -ta.GetTextureY());
1188  glTexCoord2f(0, 1);
1189  glVertex3f(1, -ta.GetTextureX(), +ta.GetTextureY());
1190  glTexCoord2f(1, 1);
1191  glVertex3f(1, +ta.GetTextureX(), +ta.GetTextureY());
1192  glTexCoord2f(1, 0);
1193  glVertex3f(1, +ta.GetTextureX(), -ta.GetTextureY());
1194 
1195  // Left Face
1196  glTexCoord2f(1, 0);
1197  glVertex3f(-1, -ta.GetTextureX(), -ta.GetTextureY());
1198  glTexCoord2f(0, 0);
1199  glVertex3f(-1, +ta.GetTextureX(), -ta.GetTextureY());
1200  glTexCoord2f(0, 1);
1201  glVertex3f(-1, +ta.GetTextureX(), +ta.GetTextureY());
1202  glTexCoord2f(1, 1);
1203  glVertex3f(-1, -ta.GetTextureX(), +ta.GetTextureY());
1204  }
1205  glEnd();
1206 
1207  tb.Bind();
1208 
1209  glBegin(GL_QUADS);
1210  {
1211  glColor4d(1, 1, 1, 1);
1212 
1213  // Back Face
1214  glTexCoord2f(1, 0);
1215  glVertex3f(-tb.GetTextureX(), -tb.GetTextureY(), -1);
1216  glTexCoord2f(1, 1);
1217  glVertex3f(-tb.GetTextureX(), +tb.GetTextureY(), -1);
1218  glTexCoord2f(0, 1);
1219  glVertex3f(+tb.GetTextureX(), +tb.GetTextureY(), -1);
1220  glTexCoord2f(0, 0);
1221  glVertex3f(+tb.GetTextureX(), -tb.GetTextureY(), -1);
1222  }
1223  glEnd();
1224 
1225  if (elapsed < rotStart)
1226  ;
1227  else if (elapsed < (tot - rotStart))
1228  {
1229  m_effect_cube_xrot = 360.0f * (elapsed - rotStart) / (tot - 2.0f * rotStart);
1231  }
1232  else
1233  {
1234  m_effect_cube_xrot = 0;
1235  m_effect_cube_yrot = 180.0f;
1236  }
1237 
1239 }
1240 
1242 {
1243 
1244  float single_image_pct = 0.75;
1245  float trans_pct = 1.0f - single_image_pct;
1246  float scale_max, x_loc, y_loc;
1247  float scale_factor = 0;
1248 
1249  //initialize effect
1251  {
1252 
1254  m_effect_kenBurns_item = nullptr;
1255  // Need to load images in the background to keep effect smooth
1257  //Since total image time is longer/different than effect time, create image timers
1259  // Pan image to a random location
1261  // Since first two images are preloaded, hardcode them to zoom in
1265  (m_effect_transition_timeout * trans_pct);
1266  }
1267 
1269  {
1270  // Effect timed out, move new image to old image but don't load new image yet...
1272  m_texCur = (m_texCur) ? 0 : 1;
1275 
1277 
1278  // Find next image to be loaded
1279  int oldpos = m_pos;
1280 
1281  while (true)
1282  {
1285  {
1286  // Skip movies
1288  {
1289  break;
1290  }
1291  }
1292  if (m_pos == oldpos)
1293  {
1294  // No valid items!!!
1295  close();
1296  }
1297  }
1299  }
1300 
1301  float t[2], elapsed[2], s[2], effect_pct;
1303  elapsed[m_texCur ? 0 : 1] = m_effect_kenBurns_image_time[m_texCur ? 0 : 1].elapsed();
1304  //progress linearly
1306  t[m_texCur ? 0 : 1] = elapsed[m_texCur ? 0 : 1] / m_effect_kenBurns_image_timeout;
1307  //progress faster initially then slowing down- this is needed to ensure images zoom faster than they pan and
1308  //therefore stay completely on the screen
1309  s[m_texCur] = sqrt(elapsed[m_texCur]) / sqrt(m_effect_kenBurns_image_timeout);
1310  s[m_texCur ? 0 : 1] = sqrt(elapsed[m_texCur ? 0 : 1]) / sqrt(m_effect_kenBurns_image_timeout);
1311 
1313 
1314  // Load new image if its ready
1315  if (effect_pct > single_image_pct && m_effect_kenBurns_image_ready)
1316  {
1318  {
1319  if (m_effect_kenBurns_item) //Do not create textures for first two images, since they are preloaded
1320  {
1325 
1326  //choose the location and projection (zoom in or out) randomly
1330  1 + (int)((2.0f * random() / (RAND_MAX + 1.0f)));
1331  }
1332  else //No item, must be 1 of the first two preloaded items
1333  {
1334  //start at random location and zoom out to face in center
1337  }
1338 
1341  }
1342  if (m_effect_kenBurns_projection[m_texCur] == 1) // Zoom in image
1343  {
1344  // Start in center and pan out
1347  scale_max = FindMaxScale(x_loc,y_loc);
1348  scale_factor = 1.0f + (scale_max * s[m_texCur]);
1349  }
1350  else // Zoom out image
1351  {
1352  // Start at random location and pan to center
1355  scale_max = FindMaxScale(x_loc,y_loc);
1356  scale_factor = 1.0f + scale_max - (scale_max * t[m_texCur]);
1357  }
1358 
1359  glMatrixMode(GL_MODELVIEW);
1360  glLoadIdentity();
1361  glTranslatef(x_loc, y_loc, 0.0f);
1362 
1363  m_texItem[m_texCur].MakeQuad((effect_pct-single_image_pct)*4, scale_factor);
1364  }
1365 
1366  //Load old picture
1367  if (m_effect_kenBurns_projection[m_texCur ? 0 : 1] == 1)// Zoom in image
1368  {
1369  x_loc = m_effect_kenBurns_location_x[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
1370  y_loc = m_effect_kenBurns_location_y[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
1371  scale_max = FindMaxScale(x_loc,y_loc);
1372  scale_factor = 1.0f + (scale_max * s[m_texCur ? 0 : 1]);
1373  }
1374  else // Zoom out image
1375  {
1376  x_loc = m_effect_kenBurns_location_x[m_texCur ? 0 : 1] -
1377  m_effect_kenBurns_location_x[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
1378  y_loc = m_effect_kenBurns_location_y[m_texCur ? 0 : 1] -
1379  m_effect_kenBurns_location_y[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
1380  scale_max = FindMaxScale(x_loc,y_loc);
1381  scale_factor = 1.0f + scale_max - (scale_max * t[m_texCur ? 0 : 1]);
1382  }
1383 
1384  glMatrixMode(GL_MODELVIEW);
1385  glLoadIdentity();
1386  glTranslatef(x_loc, y_loc, 0.0f);
1387 
1388  if (effect_pct<= single_image_pct)
1389  {
1391  m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f, scale_factor); //
1392  }
1393  else // Fade out image
1394  {
1395  m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f - ((effect_pct-single_image_pct)*4), scale_factor);
1396 
1397  }
1398 
1400 }
1401 
1403 {
1404  bool wasMovie = false, isMovie = false;
1405  if (m_effect_method.isEmpty())
1406  {
1407  LOG(VB_GENERAL, LOG_ERR, LOC + "No transition method");
1408  return;
1409  }
1410 
1411  if (m_effect_running)
1412  {
1414  }
1415  else
1416  {
1418  {
1419  // effect was running and is complete now
1420  // run timer while showing current image
1423  }
1424  else
1425  {
1426  // timed out after showing current image
1427  // load next image and start effect
1428 
1429  if (m_slideshow_running)
1430  {
1431  if (m_effect_random)
1433 
1434  DisplayNext(false, false);
1435 
1436  wasMovie = m_movieState > 0;
1437  Load();
1438  isMovie = m_movieState > 0;
1439  // If transitioning to/from a movie, don't do an effect,
1440  // and shorten timeout
1441  if (wasMovie || isMovie)
1442  {
1444  }
1445  else
1446  {
1448  m_effect_running = true;
1450  }
1452  }
1453  m_info_show_short = false;
1454  }
1455  }
1456 
1457  updateGL();
1459  {
1460  m_slideshow_timer->stop();
1461  m_slideshow_timer->setSingleShot(true);
1463 
1464  // If transitioning to/from a movie, no effect is running so
1465  // next timeout should trigger proper immage delay.
1466  if (wasMovie || isMovie)
1467  {
1469  }
1470  }
1471 }
1472 
1474 {
1475  if (m_texInfo)
1476  glDeleteTextures(1, &m_texInfo);
1477 
1479  if (info.isEmpty())
1480  return;
1481 
1482  QPixmap pix(512, 512);
1483 
1484  QPainter p(&pix);
1485  p.initFrom(this);
1486  p.fillRect(0, 0, pix.width(), pix.height(), Qt::black);
1487  p.setPen(Qt::white);
1488 
1489  p.drawText(10, 10, pix.width() - 20, pix.height() - 20,
1490  Qt::AlignLeft, info);
1491  p.end();
1492 
1493  QImage img = pix.toImage();
1494  img = img.convertToFormat(QImage::Format_ARGB32);
1495 
1496  QImage tex = convertToGLFormat(img);
1497 
1498  /* create the texture */
1499  glGenTextures(1, &m_texInfo);
1500  glBindTexture(GL_TEXTURE_2D, m_texInfo);
1501  /* actually generate the texture */
1502  glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
1503  GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());
1504  /* enable linear filtering */
1505  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1506  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1507 }
1508 
1509 void GLSingleView::LoadImage(QImage image, QSize origSize)
1510 {
1511  m_effect_kenBurns_image = image;
1513 }
1514 
1515 float GLSingleView::FindMaxScale(float x_loc, float y_loc)
1516 {
1517  // Zoom big enough to keep the entire image on screen when we pan
1518  if (abs(x_loc) > abs(y_loc))
1519  return abs(x_loc) * 2;
1520  else
1521  return abs(y_loc) * 2;
1522 }
1523 
1524 void GLSingleView::FindRandXY(float &x_loc, float &y_loc)
1525 {
1526  // Random number between .25 and .75
1527  x_loc = (0.5f * random() / (RAND_MAX + 1.0f)) + 0.25f;
1528  if ((int)(2.0f * random() / (RAND_MAX + 1.0f)) == 0)
1529  x_loc = -1 * x_loc;
1530  // Random number between .25 and .75
1531  y_loc = (0.5f * random() / (RAND_MAX + 1.0f)) + 0.25f;
1532  if ((int)(2.0f * random() / (RAND_MAX + 1.0f)) == 0)
1533  y_loc = -1 * y_loc;
1534 }
1535 
1537  QSize texSize, QSize screenSize) :
1538  MThread("KenBurnsImageLoader"),
1539  m_singleView(singleView),
1540  m_screenSize(screenSize),
1541  m_texSize(texSize)
1542 {
1543 }
1544 
1546 {
1547  RunProlog();
1549  if (!item)
1550  {
1551  LOG(VB_GENERAL, LOG_ERR, LOC + QString("No item at current position"));
1552  RunEpilog();
1553  return;
1554  }
1555  QImage image(item->GetPath());
1556  if (image.isNull())
1557  {
1558  RunEpilog();
1559  return;
1560  }
1561 
1562  image = image.scaled(m_texSize, Qt::IgnoreAspectRatio,
1563  Qt::SmoothTransformation);
1564  QImage glimage = QGLWidget::convertToGLFormat(image);
1565 
1566  m_singleView->LoadImage(glimage, glimage.size());
1567  m_singleView->Ready();
1568 
1569  RunEpilog();
1570 }
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:216
QImage m_effect_kenBurns_image
Definition: glsingleview.h:153
void start(QThread::Priority=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:295
int restart(void)
Returns milliseconds elapsed since last start() or restart() and resets the count.
Definition: mythtimer.cpp:62
void GetScreenShot(QImage &image, const ThumbItem *item)
Definition: imageview.cpp:269
float m_zoom
Definition: imageview.h:98
int m_pos
Definition: imageview.h:95
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
GLTexture m_texItem[2]
Definition: glsingleview.h:128
struct exc__state * last
Definition: pxsup2dast.c:98
float m_source_x
Definition: glsingleview.h:121
float GetTextureY(void) const
Definition: gltexture.h:63
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:91
void SetAngle(int newangle)
Definition: gltexture.h:57
void FindRandXY(float &x_loc, float &y_loc)
void SetItem(ThumbItem *, const QSize &sz)
Definition: gltexture.cpp:98
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
void EffectNone(void)
void DisableScreensaver(void)
float m_source_y
Definition: glsingleview.h:122
bool m_effect_kenBurns_new_image_started
Definition: glsingleview.h:157
void createTexInfo(void)
void SaveSetting(const QString &key, int newValue)
void RegisterEffects(void) override
static void PlayVideo(const QString &filename)
bool m_info_show_short
Definition: imageview.h:101
void keyPressEvent(QKeyEvent *e) override
float m_effect_kenBurns_image_timeout
Definition: glsingleview.h:150
int m_movieState
Definition: imageview.h:97
void EffectCube(void)
int m_slideshow_frame_delay_state
Definition: imageview.h:107
GLSingleView(ThumbList itemList, int *pos, int slideShow, int sordorder, QWidget *parent)
void resizeGL(int w, int h) override
ThumbItem * getCurrentItem() const
Definition: imageview.cpp:313
GLuint m_texInfo
Definition: glsingleview.h:133
void CleanUp(void)
int m_slideshow_frame_delay
Definition: imageview.h:106
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void SetPixmap(QPixmap *pixmap)
Definition: thumbview.cpp:74
void RunEffect(const QString &effect) override
ThumbItem * m_effect_kenBurns_item
Definition: glsingleview.h:155
float GetTextureX(void) const
Definition: gltexture.h:62
QList< ThumbItem * > ThumbList
Definition: thumbview.h:80
void Bind(void)
Definition: gltexture.cpp:58
void UpdateLCD(const ThumbItem *item)
Definition: imageview.cpp:234
static guint32 * tmp
Definition: goom_core.c:35
void EffectInOut(void)
int m_effect_kenBurns_projection[2]
Definition: glsingleview.h:148
bool m_effect_kenBurns_image_ready
Definition: glsingleview.h:152
GLSDialog(const ThumbList &itemList, int *pos, int slideShow, int sortOrder, MythMainWindow *parent, const char *name="GLSDialog")
void SetZoom(float zoom) override
QString GetDescriptionStatus(void) const
Definition: imageview.cpp:261
void SetTransitionTimeout(int timeout)
void paintTexture(void)
QSize m_effect_kenBurns_orig_image_size
Definition: glsingleview.h:154
QMap< QString, QString > m_effect_map
Definition: imageview.h:115
void closeEvent(QCloseEvent *e) override
static bool IsMovie(const QString &filePath)
void EffectRotate(void)
ThumbItem * retreatItem()
Definition: imageview.cpp:326
KenBurnsImageLoader * m_effect_kenBurns_imageLoadThread
Definition: glsingleview.h:151
int GetAngle(void) const
Definition: gltexture.h:64
void MakeQuad(float alpha=1.0f, float scale=1.0f)
Definition: gltexture.cpp:66
int m_effect_current_frame
Definition: imageview.h:113
virtual QString GetRandomEffect(void) const
Definition: imageview.cpp:224
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
void checkPosition(void)
void EffectKenBurns(void)
#define close
Definition: compat.h:16
bool m_effect_random
Definition: imageview.h:116
void Ready()
Definition: glsingleview.h:70
static bool Delete(const QFileInfo &file)
float m_effect_kenBurns_location_y[2]
Definition: glsingleview.h:147
bool m_effect_kenBurns_initialized
Definition: glsingleview.h:156
void EffectFlutter(void)
QString GetSetting(const QString &key, const QString &defaultval="")
float FindMaxScale(float x_loc, float y_loc)
unsigned char t
Definition: ParseText.cpp:340
void EffectZoomBlend(void)
QString m_effect_method
Definition: imageview.h:114
virtual void accept()
void DisplayNext(bool reset, bool loadImage) override
void SlideTimeout(void)
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
QSize m_screenSize
Definition: imageview.h:92
void initializeGL(void) override
const char * name
Definition: ParseText.cpp:339
QTimer * m_slideshow_timer
Definition: imageview.h:108
KenBurnsImageLoader(GLSingleView *singleView, QSize m_texSize, QSize m_screenSize)
void LoadImage(QImage image, QSize origSize)
GLSingleView * m_singleView
Definition: glsingleview.h:167
ScaleMax m_scaleMax
Definition: glsingleview.h:123
MythUIHelper * GetMythUI()
bool m_effect_running
Definition: imageview.h:112
int m_effect_rotate_direction
Definition: glsingleview.h:136
Base dialog for most dialogs in MythTV using the old UI.
Definition: mythdialogs.h:50
ScaleMax
Definition: galleryutil.h:28
MythMainWindow * GetMythMainWindow(void)
int elapsed(void) const
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
void Deinit(void)
Delete the texture.
Definition: gltexture.cpp:52
#define M_PI
Definition: goom_tools.h:5
QString GetPath(void) const
Definition: thumbview.h:61
void PauseIdleTimer(bool pause)
void RestoreScreensaver(void)
int GetNumSetting(const QString &key, int defaultval=0)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void SetRotationAngle(int angle)
Definition: thumbview.cpp:58
void EffectFade(void)
#define GL_RGBA
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:203
MythTimer m_effect_frame_time
Definition: glsingleview.h:137
void paintGL(void) override
int GetNearestGLTextureSize(int) const
int m_effect_transition_timeout
Definition: glsingleview.h:138
float m_effect_cube_zrot
Definition: glsingleview.h:145
void EffectSlide(void)
QString GetDescription(const QString &status) const
Definition: gltexture.cpp:111
void Rotate(int angle) override
GLSingleView * m_view
Definition: glsingleview.h:57
float m_effect_cube_xrot
Definition: glsingleview.h:143
static long int random(void)
Definition: compat.h:147
#define LOC
void ScaleTo(const QSize &dest, ScaleMax scaleMax)
Definition: gltexture.cpp:87
MythTimer m_effect_kenBurns_image_time[2]
Definition: glsingleview.h:149
ThumbItem * advanceItem()
Definition: imageview.cpp:319
void EffectBlend(void)
void Load(void) override
float m_effect_flutter_points[40][40][3]
Definition: glsingleview.h:142
void SwapWidthHeight(void)
Definition: gltexture.h:47
float m_effect_cube_yrot
Definition: glsingleview.h:144
float m_effect_transition_timeout_inv
Definition: glsingleview.h:139
bool m_slideshow_running
Definition: imageview.h:104
void DisplayPrev(bool reset, bool loadImage) override
float m_effect_kenBurns_location_x[2]
Definition: glsingleview.h:146
void EffectBend(void)
bool m_info_show
Definition: imageview.h:100
void Init(const QImage &image)
Create the texture initialized with QImage.
Definition: gltexture.cpp:34