1 /** 2 * projectM-qt -- Qt4 based projectM GUI 3 * Copyright (C)2003-2004 projectM Team 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * See 'LICENSE.txt' included within this release 19 * 20 */ 21 22 #ifndef QPROJECTM_WIDGET_HPP 23 #define QPROJECTM_WIDGET_HPP 24 25 #include <iostream> 26 #include "qprojectm.hpp" 27 #include <QGLWidget> 28 #include <QMutex> 29 #include <QtDebug> 30 #include <QKeyEvent> 31 #include <QTimer> 32 #include <QApplication> 33 #include <QSettings> 34 35 class QProjectMWidget : public QGLWidget 36 { 37 38 Q_OBJECT // must include this if you use Qt signals/slots 39 40 public: 41 static const int MOUSE_VISIBLE_TIMEOUT_MS = 5000; QProjectMWidget(const std::string & config_file,QWidget * parent,QMutex * audioMutex=0)42 QProjectMWidget ( const std::string & config_file, QWidget * parent, QMutex * audioMutex = 0 ) 43 : QGLWidget ( parent ), m_config_file ( config_file ), m_projectM ( 0 ), m_mouseTimer ( 0 ), m_audioMutex ( audioMutex ) 44 { 45 46 m_mouseTimer = new QTimer ( this ); 47 48 QSettings settings("projectM", "qprojectM"); 49 mouseHideTimeoutSeconds = 50 settings.value("MouseHideOnTimeout", MOUSE_VISIBLE_TIMEOUT_MS/1000).toInt(); 51 52 if (mouseHideTimeoutSeconds > 0) 53 m_mouseTimer->start ( mouseHideTimeoutSeconds * 1000); 54 55 connect ( m_mouseTimer, SIGNAL ( timeout() ), this, SLOT ( hideMouse() ) ); 56 this->setMouseTracking ( true ); 57 58 } 59 ~QProjectMWidget()60 ~QProjectMWidget() { destroyProjectM(); } 61 62 63 resizeGL(int w,int h)64 void resizeGL ( int w, int h ) 65 { 66 // Setup viewport, projection etc 67 setup_opengl ( w,h ); 68 m_projectM->projectM_resetGL ( w, h ); 69 } 70 configFile()71 inline const std::string & configFile() 72 { 73 return m_config_file; 74 } 75 seizePresetLock()76 inline void seizePresetLock() 77 { 78 79 m_presetSeizeMutex.lock(); 80 m_presetWasLocked = qprojectM()->isPresetLocked(); 81 qprojectM()->setPresetLock ( true ); 82 83 } 84 releasePresetLock()85 inline void releasePresetLock() 86 { 87 qprojectM()->setPresetLock ( m_presetWasLocked ); 88 m_presetSeizeMutex.unlock(); 89 } 90 91 qprojectM()92 inline QProjectM * qprojectM() { return m_projectM; } 93 94 protected slots: mouseMoveEvent(QMouseEvent * event)95 inline void mouseMoveEvent ( QMouseEvent * event ) 96 { 97 Q_UNUSED(event); 98 99 m_mouseTimer->stop(); 100 QApplication::restoreOverrideCursor(); 101 if (mouseHideTimeoutSeconds > 0) 102 m_mouseTimer->start ( mouseHideTimeoutSeconds*1000 ); 103 104 } 105 leaveEvent(QEvent * event)106 inline void leaveEvent ( QEvent * event ) 107 { 108 Q_UNUSED(event); 109 /// @bug testing if this resolves a bug for ubuntu users 110 QApplication::restoreOverrideCursor(); 111 } 112 113 public slots: 114 resetProjectM()115 void resetProjectM() 116 { 117 std::cout << "resetting" << std::endl; 118 qDebug() << "reset start"; 119 120 emit ( projectM_BeforeDestroy() ); 121 122 if ( m_audioMutex ) 123 m_audioMutex->lock(); 124 125 destroyProjectM(); 126 127 // Make a new projectM instance and reset the opengl state 128 initializeGL(); 129 130 // Allow audio thread to continue its business 131 if ( m_audioMutex ) 132 { 133 m_audioMutex->unlock(); 134 } 135 qDebug() << "reinit'ed"; 136 } 137 setAudioMutex(QMutex * mutex)138 void setAudioMutex ( QMutex * mutex ) 139 { 140 m_audioMutex = mutex; 141 } 142 setPresetLock(int state)143 void setPresetLock ( int state ) 144 { 145 m_projectM->setPresetLock ( ( bool ) state ); 146 emit ( presetLockChanged ( ( bool ) state ) ); 147 } 148 setShuffleEnabled(int state)149 void setShuffleEnabled ( int state ) 150 { 151 m_projectM->setShuffleEnabled ( ( bool ) state ); 152 emit ( shuffleEnabledChanged ( ( bool ) state ) ); 153 } 154 mousePressEvent(QMouseEvent * event)155 void mousePressEvent ( QMouseEvent * event ) 156 { 157 Q_UNUSED(event); 158 159 this->setFocus(); 160 } 161 162 signals: 163 void projectM_Initialized ( QProjectM * ); 164 void projectM_BeforeDestroy(); 165 void presetLockChanged ( bool isLocked ); 166 void shuffleEnabledChanged ( bool isShuffleEnabled ); 167 168 private slots: hideMouse()169 void hideMouse() 170 { 171 if ( this->underMouse() && this->hasFocus() ) 172 QApplication::setOverrideCursor ( Qt::BlankCursor ); 173 } 174 private: 175 std::string m_config_file; 176 QProjectM * m_projectM; destroyProjectM()177 void destroyProjectM() 178 { 179 180 if ( m_projectM ) 181 { 182 delete ( m_projectM ); 183 m_projectM = 0; 184 } 185 } 186 187 QTimer * m_mouseTimer; 188 QMutex * m_audioMutex; 189 QMutex m_presetSeizeMutex; 190 bool m_presetWasLocked; 191 protected: 192 193 keyReleaseEvent(QKeyEvent * e)194 void keyReleaseEvent ( QKeyEvent * e ) 195 { 196 197 projectMKeycode pkey; 198 bool ignore = false; 199 switch ( e->key() ) 200 { 201 case Qt::Key_F4: 202 pkey = PROJECTM_K_F4; 203 break; 204 case Qt::Key_F3: 205 pkey = PROJECTM_K_F3; 206 break; 207 case Qt::Key_F2: 208 pkey = PROJECTM_K_F2; 209 break; 210 case Qt::Key_F1: 211 pkey = PROJECTM_K_F1; 212 break; 213 case Qt::Key_R: 214 if (e->modifiers() & Qt::ShiftModifier) 215 pkey = PROJECTM_K_R; 216 else 217 pkey = PROJECTM_K_r; 218 break; 219 case Qt::Key_L: 220 pkey = PROJECTM_K_l; 221 ignore = true; 222 break; 223 case Qt::Key_N: 224 if (e->modifiers() & Qt::ShiftModifier) 225 pkey = PROJECTM_K_N; 226 else 227 pkey = PROJECTM_K_n; 228 break; 229 case Qt::Key_P: 230 if (e->modifiers() & Qt::ShiftModifier) 231 pkey = PROJECTM_K_P; 232 else 233 pkey = PROJECTM_K_p; 234 break; 235 case Qt::Key_F5: 236 pkey = PROJECTM_K_F5; 237 break; 238 case Qt::Key_Plus: 239 pkey = PROJECTM_K_PLUS; 240 break; 241 case Qt::Key_Minus: 242 pkey = PROJECTM_K_MINUS; 243 break; 244 case Qt::Key_Equal: 245 pkey = PROJECTM_K_EQUALS; 246 break; 247 default: 248 e->ignore(); 249 return; 250 } 251 projectMModifier modifier = PROJECTM_KMOD_NONE; 252 253 m_projectM->key_handler ( PROJECTM_KEYDOWN, pkey, modifier ); 254 if ( ignore ) 255 e->ignore(); 256 257 258 } 259 initializeGL()260 void initializeGL() 261 { 262 263 if (m_projectM == 0) { 264 this->m_projectM = new QProjectM ( m_config_file ); 265 projectM_Initialized ( m_projectM ); 266 } 267 } 268 paintGL()269 inline void paintGL() 270 { 271 m_projectM->renderFrame(); 272 } 273 274 private: 275 int mouseHideTimeoutSeconds; setup_opengl(int w,int h)276 void setup_opengl ( int w, int h ) 277 { 278 279 /* Our shading model--Gouraud (smooth). */ 280 glShadeModel ( GL_SMOOTH ); 281 /* Culling. */ 282 // glCullFace( GL_BACK ); 283 // glFrontFace( GL_CCW ); 284 // glEnable( GL_CULL_FACE ); 285 /* Set the clear color. */ 286 glClearColor ( 0, 0, 0, 0 ); 287 /* Setup our viewport. */ 288 glViewport ( 0, 0, w, h ); 289 /* 290 * Change to the projection matrix and set 291 * our viewing volume. 292 */ 293 glMatrixMode ( GL_TEXTURE ); 294 glLoadIdentity(); 295 296 // gluOrtho2D(0.0, (GLfloat) width, 0.0, (GLfloat) height); 297 glMatrixMode ( GL_PROJECTION ); 298 glLoadIdentity(); 299 300 // glFrustum(0.0, height, 0.0,width,10,40); 301 glMatrixMode ( GL_MODELVIEW ); 302 glLoadIdentity(); 303 304 glDrawBuffer ( GL_BACK ); 305 glReadBuffer ( GL_BACK ); 306 glEnable ( GL_BLEND ); 307 308 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); 309 // glBlendFunc(GL_SRC_ALPHA, GL_ONE); 310 glEnable ( GL_LINE_SMOOTH ); 311 glEnable ( GL_POINT_SMOOTH ); 312 glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); 313 // glClear(GL_COLOR_BUFFER_BIT); 314 315 // glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGB,0,0,texsize,texsize,0); 316 //glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,texsize,texsize); 317 glLineStipple ( 2, 0xAAAA ); 318 } 319 320 321 }; 322 #endif 323