1 /*******************************************************************************
2 *                         Goggles Music Manager                                *
3 ********************************************************************************
4 *           Copyright (C) 2006-2021 by Sander Jansen. All Rights Reserved      *
5 *                               ---                                            *
6 * This program is free software: you can redistribute it and/or modify         *
7 * it under the terms of the GNU General Public License as published by         *
8 * the Free Software Foundation, either version 3 of the License, or            *
9 * (at your option) any later version.                                          *
10 *                                                                              *
11 * This program is distributed in the hope that it will be useful,              *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of               *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                *
14 * GNU General Public License for more details.                                 *
15 *                                                                              *
16 * You should have received a copy of the GNU General Public License            *
17 * along with this program.  If not, see http://www.gnu.org/licenses.           *
18 ********************************************************************************/
19 #include "gmdefs.h"
20 #ifdef HAVE_OPENGL
21 #include <FXPNGIcon.h>
22 #include <FXPNGImage.h>
23 #include "GMTrack.h"
24 #include "GMList.h"
25 #include "GMSource.h"
26 #include "GMPlayerManager.h"
27 #include "GMCover.h"
28 #include "GMCoverManager.h"
29 #include "GMWindow.h"
30 #include "GMPresenter.h"
31 #include "GMIconTheme.h"
32 #include "GMImageView.h"
33 
34 #include <GL/glu.h>
35 
36 
37 
38 
39 class GMBouncingImage {
40 protected:
41   GMImageTexture * texture;
42   FXVec2f     pos;
43   FXVec2f     dir;
44   FXfloat     size;
45 public:
GMBouncingImage(GMImageTexture * t)46   GMBouncingImage(GMImageTexture*t) : texture(t), pos(0.0f,0.0f),dir(0.001f,0.001f),size(0.4f) {}
47 
move(FXVec2f range)48   void move(FXVec2f range) {
49     if (texture) {
50       FXVec2f n = pos+dir;
51       if (n.x+(size*texture->aspect)>range.x)
52         dir.x=-dir.x;
53       if (n.y+size>range.y)
54         dir.y=-dir.y;
55       if (n.x<0.0f)
56         dir.x=-dir.x;
57       if (n.y<0.0f)
58         dir.y=-dir.y;
59       pos+=dir;
60       }
61     }
62 
setTexture(GMImageTexture * t)63   void setTexture(GMImageTexture * t) {
64     texture=t;
65     }
66 
draw()67   void draw() {
68     if (texture && texture->id)
69       texture->drawQuad(pos.x,pos.y,(size*texture->aspect),size,0);
70     }
71   };
72 
73 
74 
75 // Map
76 FXDEFMAP(GMPresenter) GMPresenterMap[]={
77   FXMAPFUNC(SEL_PAINT,GMPresenter::ID_CANVAS,GMPresenter::onCanvasPaint),
78   FXMAPFUNC(SEL_TIMEOUT,GMPresenter::ID_ANIMATION,GMPresenter::onAnimation),
79   };
80 
81 // Implementation
FXIMPLEMENT(GMPresenter,FXDialogBox,GMPresenterMap,ARRAYNUMBER (GMPresenterMap))82 FXIMPLEMENT(GMPresenter,FXDialogBox,GMPresenterMap,ARRAYNUMBER(GMPresenterMap))
83 
84 GMPresenter::GMPresenter(FXApp* a,FXGLContext * ctx,FXObject * /*tgt*/,FXSelector /*msg*/):FXDialogBox(a,FXString::null,DECOR_TITLE|DECOR_RESIZE,0,0,400,300,0,0,0,0,0,0){
85   glcanvas = new FXGLCanvas(this,ctx,this,ID_CANVAS,LAYOUT_FILL);
86   }
87 
88 // Destroy main window
~GMPresenter()89 GMPresenter::~GMPresenter(){
90   setImage(nullptr);
91   if (effect)
92     delete effect;
93   getApp()->removeTimeout(this,ID_ANIMATION);
94   }
95 
create()96 void GMPresenter::create() {
97   FXDialogBox::create();
98   getApp()->addTimeout(this,ID_ANIMATION,100000000);
99   }
100 
setImage(FXImage * image)101 void GMPresenter::setImage(FXImage * image) {
102   if (glcanvas->makeCurrent()) {
103     if (image) {
104       if (texture==nullptr) {
105         texture = new GMImageTexture();
106         }
107       if (effect==nullptr) {
108         effect  = new GMBouncingImage(texture);
109         }
110       else {
111         effect->setTexture(texture);
112         }
113       texture->setImage(image);
114       }
115     else {
116       if (texture) {
117         texture->setImage(nullptr);
118         delete texture;
119         texture=nullptr;
120         }
121       }
122     glcanvas->makeNonCurrent();
123     }
124   recalc();
125   update();
126   }
127 
128 
129 
130 
131 
132 
execute(FXuint placement)133 FXuint GMPresenter::execute(FXuint placement) {
134   create();
135   show(placement);
136 #ifndef DEBUG
137   fullScreen(true);
138   glcanvas->showCursor(false);
139 #endif
140   getApp()->refresh();
141   return getApp()->runModalFor(this);
142   }
143 
onAnimation(FXObject *,FXSelector,void *)144 long GMPresenter::onAnimation(FXObject*,FXSelector,void*){
145   FXfloat aspect=getWidth()/(float)getHeight();
146   if (effect) effect->move(FXVec2f(aspect*1.0f,1.0f));
147   getApp()->addTimeout(this,ID_ANIMATION,10000000);
148   glcanvas->update();
149   return 1;
150   }
151 
onCanvasPaint(FXObject *,FXSelector,void *)152 long GMPresenter::onCanvasPaint(FXObject*,FXSelector,void*){
153   const FXfloat aspect=getWidth()/(float)getHeight();
154   FXVec4f background=colorToVec4f(FXRGBA(0,0,0,0));
155   if (glcanvas->makeCurrent()) {
156     glViewport(0,0,getWidth(),getHeight());
157     glClearColor(background.x,background.y,background.z,background.w);
158     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
159     if (effect) {
160       glMatrixMode(GL_MODELVIEW);
161       glLoadIdentity();
162       gluOrtho2D(0.0f,1.0f*aspect,0.0f,1.0f);
163       effect->draw();
164       }
165     if (glcanvas->getContext()->isDoubleBuffer()) glcanvas->swapBuffers();
166     glcanvas->makeNonCurrent();
167     }
168   return 1;
169   }
170 
171 #endif
172