3
* Copyright (C) 2007 Fabien Chereau
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
#include "StelAppQt4.hpp"
26
#include "StelCore.hpp"
27
#include "StelFileMgr.hpp"
28
#include "Projector.hpp"
29
#include "InitParser.hpp"
34
#include <QtGui/QImage>
35
#include <QtGui/QApplication>
37
#include <QMainWindow>
38
#include <QStringList>
39
#include <QCoreApplication>
45
class StelMainWindow : public QMainWindow
48
StelMainWindow(class StelAppQt4* app) : stelApp(app) {setWindowTitle(StelApp::getApplicationName());}
49
void keyPressEvent(QKeyEvent*);
50
void keyReleaseEvent(QKeyEvent*);
52
class StelAppQt4* stelApp;
55
class GLWidget : public QGLWidget
58
GLWidget(QWidget *parent, class StelAppQt4* app);
61
void resizeGL(int w, int h);
63
void timerEvent(QTimerEvent*);
64
void mousePressEvent(QMouseEvent*);
65
void mouseReleaseEvent(QMouseEvent*);
66
void mouseMoveEvent(QMouseEvent*);
67
void wheelEvent(QWheelEvent*);
68
//! Notify that an event was handled by the program and therefore the FPS should be maximized for a couple of seconds
69
void thereWasAnEvent();
75
class StelAppQt4* stelApp;
77
double lastEventTimeSec;
81
StelAppQt4::StelAppQt4(int argc, char **argv) : StelApp(argc, argv)
85
StelAppQt4::~StelAppQt4()
89
void StelAppQt4::initOpenGL(int w, int h, int bbpMode, bool fullScreen, const QString& iconFile)
91
mainWindow->setWindowIcon(QIcon(iconFile));
92
mainWindow->resize(w, h);
95
mainWindow->showFullScreen();
96
QDesktopWidget* desktop = QApplication::desktop();
97
mainWindow->resize(desktop->screenGeometry(mainWindow).width(),desktop->screenGeometry(mainWindow).height());
102
// Get the width of the openGL screen
103
int StelAppQt4::getScreenW() const
105
return winOpenGL->width();
108
// Get the height of the openGL screen
109
int StelAppQt4::getScreenH() const
111
return winOpenGL->height();
114
QString StelAppQt4::getVideoModeList(void) const
120
// Terminate the application
121
void StelAppQt4::terminateApplication(void)
123
QCoreApplication::quit();
126
// Set mouse cursor display
127
void StelAppQt4::showCursor(bool b)
129
winOpenGL->setCursor(b ? Qt::ArrowCursor : Qt::BlankCursor);
132
//! Swap GL buffer, should be called only for special condition
133
void StelAppQt4::swapGLBuffers()
135
winOpenGL->swapBuffers();
138
//! Return the time since when stellarium is running in second
139
double StelAppQt4::getTotalRunTime() const
141
return (double)(winOpenGL->qtime.elapsed())/1000;
144
void StelAppQt4::startMainLoop()
148
// Update GL screen size because the last time it was called, the Projector was not yet properly initialized
149
winOpenGL->resizeGL(getScreenW(), getScreenH());
150
winOpenGL->timerId = winOpenGL->startTimer(10);
151
winOpenGL->qtime.start();
154
void StelAppQt4::saveScreenShot(const QString& filePrefix, const QString& saveDir) const
157
QImage im = winOpenGL->grabFrameBuffer();
163
shotDir = StelApp::getInstance().getFileMgr().getScreenshotDir();
164
if (!StelApp::getInstance().getFileMgr().isWritable(shotDir))
166
cerr << "ERROR StelAppSdl::saveScreenShot: screenshot directory is not writable: " << qPrintable(shotDir) << endl;
172
cerr << "ERROR StelAppSdl::saveScreenShot: could not determine screenshot directory: " << e.what() << endl;
182
for(int j=0; j<1000; ++j)
184
shotPath = shotDir+"/"+filePrefix + QString("%1").arg(j, 3, 10, QLatin1Char('0')) + ".bmp";
185
if (!StelApp::getInstance().getFileMgr().exists(shotPath))
188
// TODO - if no more filenames available, don't just overwrite the last one
189
// we should at least warn the user, perhaps prompt her, "do you want to overwrite?"
191
cout << "Saving screenshot in file: " << qPrintable(shotPath) << endl;
195
void StelAppQt4::setResizable(bool resizable)
199
mainWindow->setMaximumSize(10000,10000);
203
mainWindow->setFixedSize(mainWindow->size());
207
/*************************************************************************
208
Alternate fullscreen mode/windowed mode if possible
209
*************************************************************************/
210
void StelAppQt4::toggleFullScreen()
212
// Toggle full screen
213
if (!mainWindow->isFullScreen())
215
mainWindow->showFullScreen();
219
mainWindow->showNormal();
224
bool StelAppQt4::getFullScreen() const
226
return mainWindow->isFullScreen();
229
//////////////////////////////////////////////////////////////////////////
231
//////////////////////////////////////////////////////////////////////////
234
GLWidget::GLWidget(QWidget *parent, StelAppQt4* stapp) : QGLWidget(QGLFormat::defaultFormat(), parent), stelApp(stapp)
236
lastEventTimeSec = (double)(qtime.elapsed()/1000);
237
previousTime = qtime.elapsed();
238
setFocusPolicy(Qt::ClickFocus);
239
setMouseTracking(true);
240
// make openGL context current
242
setAutoBufferSwap(false);
245
GLWidget::~GLWidget()
249
void GLWidget::initializeGL()
251
//cerr << "GLWidget::initializeGL()" << endl;
252
glClearColor(0.0, 0.0, 0.0, 0.0);
253
glClear(GL_COLOR_BUFFER_BIT);
255
glClear(GL_COLOR_BUFFER_BIT);
258
void GLWidget::resizeGL(int w, int h)
260
//cerr << "GLWidget::resizeGL(" << w << "x" << h << ")" << endl;
261
stelApp->glWindowHasBeenResized(w, h);
264
void GLWidget::paintGL()
266
int dt = qtime.elapsed()-previousTime;
267
previousTime = qtime.elapsed();
269
if (dt<0) // This fix the star scale bug!!
276
void GLWidget::timerEvent(QTimerEvent *)
280
double duration = 1./stelApp->minfps;
281
if (stelApp->getTotalRunTime()-lastEventTimeSec<2.5)
282
duration = 1./stelApp->maxfps;
283
timerId = startTimer((int)(duration*1000));
286
void GLWidget::thereWasAnEvent()
288
// Refresh screen ASAP
290
timerId = startTimer(0);
291
lastEventTimeSec = stelApp->getTotalRunTime();
294
StelMod qtModToStelMod(Qt::KeyboardModifiers m)
296
StelMod out = StelMod_NONE;
297
if (m.testFlag(Qt::ShiftModifier))
299
out = (StelMod)((int)out|(int)StelMod_SHIFT);
301
if (m.testFlag(Qt::ControlModifier))
303
out = (StelMod)((int)out|(int)COMPATIBLE_StelMod_CTRL);
305
if (m.testFlag(Qt::AltModifier))
307
out = (StelMod)((int)out|(int)StelMod_ALT);
309
if (m.testFlag(Qt::MetaModifier))
311
out = (StelMod)((int)out|(int)StelMod_META);
317
void GLWidget::mousePressEvent(QMouseEvent* event)
319
Uint8 button = Stel_NOEVENT;
320
if (event->button() == Qt::LeftButton)
321
button = Stel_BUTTON_LEFT;
322
if (event->button() == Qt::RightButton)
323
button = Stel_BUTTON_RIGHT;
324
if (event->button() == Qt::MidButton)
325
button = Stel_BUTTON_MIDDLE;
327
Uint8 state = Stel_NOEVENT;
328
if (event->type() == QEvent::MouseButtonPress)
329
state = Stel_MOUSEBUTTONDOWN;
330
if (event->type() == QEvent::MouseButtonRelease)
331
state = Stel_MOUSEBUTTONUP;
333
stelApp->handleClick(event->x(), event->y(), button, state, qtModToStelMod(event->modifiers()));
335
// Refresh screen ASAP
339
void GLWidget::mouseReleaseEvent(QMouseEvent* event)
341
Uint8 button = Stel_NOEVENT;
342
if (event->button() == Qt::LeftButton)
343
button = Stel_BUTTON_LEFT;
344
if (event->button() == Qt::RightButton)
345
button = Stel_BUTTON_RIGHT;
346
if (event->button() == Qt::MidButton)
347
button = Stel_BUTTON_MIDDLE;
349
Uint8 state = Stel_NOEVENT;
350
if (event->type() == QEvent::MouseButtonPress)
351
state = Stel_MOUSEBUTTONDOWN;
352
if (event->type() == QEvent::MouseButtonRelease)
353
state = Stel_MOUSEBUTTONUP;
355
stelApp->handleClick(event->x(), event->y(), button, state, qtModToStelMod(event->modifiers()));
357
// Refresh screen ASAP
361
void GLWidget::mouseMoveEvent(QMouseEvent* event)
363
stelApp->handleMove(event->x(), event->y(), qtModToStelMod(event->modifiers()));
365
// Refresh screen ASAP
369
void GLWidget::wheelEvent(QWheelEvent* event)
372
if (event->delta()>0)
373
button = Stel_BUTTON_WHEELUP;
375
button = Stel_BUTTON_WHEELDOWN;
377
StelMod mod = StelMod_NONE;
378
if (event->modifiers() == Qt::ShiftModifier)
380
if (event->modifiers() == Qt::ControlModifier)
381
mod = COMPATIBLE_StelMod_CTRL;
383
stelApp->handleClick(event->x(), event->y(), button, Stel_MOUSEBUTTONDOWN, mod);
384
stelApp->handleClick(event->x(), event->y(), button, Stel_MOUSEBUTTONUP, mod);
386
// Refresh screen ASAP
390
StelKey qtKeyToStelKey(Qt::Key k)
394
case Qt::Key_Escape: return StelKey_ESCAPE ;
395
case Qt::Key_Tab : return StelKey_TAB ;
396
case Qt::Key_Backspace : return StelKey_BACKSPACE ;
397
case Qt::Key_Return : return StelKey_RETURN ;
398
//case Qt::Key_Enter : return StelKey_ENTER ;
399
case Qt::Key_Insert : return StelKey_INSERT ;
400
case Qt::Key_Delete : return StelKey_DELETE ;
401
case Qt::Key_Pause : return StelKey_PAUSE ;
402
case Qt::Key_Print : return StelKey_PRINT ;
403
case Qt::Key_Clear : return StelKey_CLEAR ;
404
case Qt::Key_Home : return StelKey_HOME ;
405
case Qt::Key_End : return StelKey_END ;
406
case Qt::Key_Left : return StelKey_LEFT ;
407
case Qt::Key_Up : return StelKey_UP ;
408
case Qt::Key_Right : return StelKey_RIGHT ;
409
case Qt::Key_Down : return StelKey_DOWN ;
410
case Qt::Key_PageUp : return StelKey_PAGEUP ;
411
case Qt::Key_PageDown : return StelKey_PAGEDOWN ;
412
case Qt::Key_Shift : return StelKey_LSHIFT ;
413
case Qt::Key_Control : return StelKey_LCTRL ;
414
case Qt::Key_Meta : return StelKey_LMETA ;
415
case Qt::Key_Alt : return StelKey_LALT ;
416
case Qt::Key_AltGr : return StelKey_RALT ;
417
case Qt::Key_CapsLock : return StelKey_CAPSLOCK ;
418
case Qt::Key_NumLock : return StelKey_NUMLOCK ;
419
case Qt::Key_ScrollLock : return StelKey_SCROLLOCK ;
420
case Qt::Key_F1 : return StelKey_F1 ;
421
case Qt::Key_F2 : return StelKey_F2 ;
422
case Qt::Key_F3 : return StelKey_F3 ;
423
case Qt::Key_F4 : return StelKey_F4 ;
424
case Qt::Key_F5 : return StelKey_F5 ;
425
case Qt::Key_F6 : return StelKey_F6 ;
426
case Qt::Key_F7 : return StelKey_F7 ;
427
case Qt::Key_F8 : return StelKey_F8 ;
428
case Qt::Key_F9 : return StelKey_F9 ;
429
case Qt::Key_F10 : return StelKey_F10 ;
430
case Qt::Key_F11 : return StelKey_F11 ;
431
case Qt::Key_F12 : return StelKey_F12 ;
432
case Qt::Key_F13 : return StelKey_F13 ;
433
case Qt::Key_F14 : return StelKey_F14 ;
434
case Qt::Key_F15 : return StelKey_F15 ;
435
case Qt::Key_Space : return StelKey_SPACE ;
436
case Qt::Key_Exclam : return StelKey_EXCLAIM ;
437
case Qt::Key_QuoteDbl : return StelKey_QUOTEDBL ;
438
case Qt::Key_NumberSign : return StelKey_HASH ;
439
case Qt::Key_Dollar : return StelKey_DOLLAR ;
440
case Qt::Key_Ampersand : return StelKey_AMPERSAND ;
441
case Qt::Key_Apostrophe : return StelKey_QUOTE ;
442
case Qt::Key_ParenLeft : return StelKey_LEFTPAREN ;
443
case Qt::Key_ParenRight : return StelKey_RIGHTPAREN ;
444
case Qt::Key_Asterisk : return StelKey_ASTERISK ;
445
case Qt::Key_Plus : return StelKey_PLUS ;
446
case Qt::Key_Comma : return StelKey_COMMA ;
447
case Qt::Key_Minus : return StelKey_MINUS ;
448
case Qt::Key_Period : return StelKey_PERIOD ;
449
case Qt::Key_Slash : return StelKey_SLASH ;
450
case Qt::Key_0 : return StelKey_0 ;
451
case Qt::Key_1 : return StelKey_1 ;
452
case Qt::Key_2 : return StelKey_2 ;
453
case Qt::Key_3 : return StelKey_3 ;
454
case Qt::Key_4 : return StelKey_4 ;
455
case Qt::Key_5 : return StelKey_5 ;
456
case Qt::Key_6 : return StelKey_6 ;
457
case Qt::Key_7 : return StelKey_7 ;
458
case Qt::Key_8 : return StelKey_8 ;
459
case Qt::Key_9 : return StelKey_9 ;
460
case Qt::Key_Colon : return StelKey_COLON ;
461
case Qt::Key_Semicolon : return StelKey_SEMICOLON ;
462
case Qt::Key_Less : return StelKey_LESS ;
463
case Qt::Key_Equal : return StelKey_EQUALS ;
464
case Qt::Key_Greater : return StelKey_GREATER ;
465
case Qt::Key_Question : return StelKey_QUESTION ;
466
case Qt::Key_At : return StelKey_AT ;
467
case Qt::Key_A : return StelKey_a ;
468
case Qt::Key_B : return StelKey_b ;
469
case Qt::Key_C : return StelKey_c ;
470
case Qt::Key_D : return StelKey_d ;
471
case Qt::Key_E : return StelKey_e ;
472
case Qt::Key_F : return StelKey_f ;
473
case Qt::Key_G : return StelKey_g ;
474
case Qt::Key_H : return StelKey_h ;
475
case Qt::Key_I : return StelKey_i ;
476
case Qt::Key_J : return StelKey_j ;
477
case Qt::Key_K : return StelKey_k ;
478
case Qt::Key_L : return StelKey_l ;
479
case Qt::Key_M : return StelKey_m ;
480
case Qt::Key_N : return StelKey_n ;
481
case Qt::Key_O : return StelKey_o ;
482
case Qt::Key_P : return StelKey_p ;
483
case Qt::Key_Q : return StelKey_q ;
484
case Qt::Key_R : return StelKey_r ;
485
case Qt::Key_S : return StelKey_s ;
486
case Qt::Key_T : return StelKey_t ;
487
case Qt::Key_U : return StelKey_u ;
488
case Qt::Key_V : return StelKey_v ;
489
case Qt::Key_W : return StelKey_w ;
490
case Qt::Key_X : return StelKey_x ;
491
case Qt::Key_Y : return StelKey_y ;
492
case Qt::Key_Z : return StelKey_z ;
493
case Qt::Key_BracketLeft : return StelKey_LEFTBRACKET ;
494
case Qt::Key_Backslash : return StelKey_BACKSLASH ;
495
case Qt::Key_BracketRight : return StelKey_RIGHTBRACKET ;
496
case Qt::Key_AsciiCircum : return StelKey_CARET ;
497
case Qt::Key_Underscore : return StelKey_UNDERSCORE ;
498
case Qt::Key_QuoteLeft : return StelKey_BACKQUOTE ;
499
default: return StelKey_UNKNOWN ;
501
return StelKey_UNKNOWN;
504
void StelMainWindow::keyPressEvent(QKeyEvent* event)
506
if ((Qt::Key)event->key()==Qt::Key_F1)
508
stelApp->toggleFullScreen();
510
stelApp->handleKeys(qtKeyToStelKey((Qt::Key)event->key()), qtModToStelMod(event->modifiers()), event->text().utf16()[0], Stel_KEYDOWN);
511
// Refresh screen ASAP
512
stelApp->winOpenGL->thereWasAnEvent();
515
void StelMainWindow::keyReleaseEvent(QKeyEvent* event)
517
stelApp->handleKeys(qtKeyToStelKey((Qt::Key)event->key()), qtModToStelMod(event->modifiers()), event->text().utf16()[0], Stel_KEYUP);
518
// Refresh screen ASAP
519
stelApp->winOpenGL->thereWasAnEvent();
522
void StelAppQt4::setQtWins( StelMainWindow* mW, GLWidget* glW)
528
void StelAppQt4::runStellarium(int argc, char **argv)
530
QApplication app(argc, argv);
531
if (!QGLFormat::hasOpenGL())
533
QMessageBox::information(0, "Stellarium", "This system does not support OpenGL.");
536
StelAppQt4* stelApp = new StelAppQt4(argc, argv);
538
StelMainWindow mainWin(stelApp);
539
mainWin.setMinimumSize(400,400);
541
GLWidget openGLWin(&mainWin, stelApp);
542
openGLWin.setObjectName(QString::fromUtf8("stellariumOpenGLWin"));
543
mainWin.setCentralWidget(&openGLWin);
548
stelApp->setQtWins(&mainWin, &openGLWin);
549
stelApp->startMainLoop();
552
// At this point it is important to still have a valid GL context because the textures are deallocated
553
// The GL Context is still valid because openGLWin is still in the current scope