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