pulsatingscience.cpp 16.6 KB
Newer Older
Oliver Bock's avatar
Oliver Bock committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/******************************************************************************
 *   Copyright (C) 2008 by Oliver Bock                                        *
 *   oliver.bock[AT]aei.mpg.de                                                *
 *                                                                            *
 *   This file is part of PulsatingScience.                                   *
 *                                                                            *
 *   PulsatingScience is free software: you can redistribute it and/or modify *
 *   it under the terms of the GNU General Public License as published        *
 *   by the Free Software Foundation, version 3 of the License.               *
 *                                                                            *
 *   PulsatingScience is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
 *   GNU General Public License for more details.                             *
 *                                                                            *
 *   You should have received a copy of the GNU General Public License        *
 *   along with PulsatingScience. If not, see <http://www.gnu.org/licenses/>. *
 *                                                                            *
 ******************************************************************************/

#include "pulsatingscience.h"

23
24
25
26
#ifdef __APPLE__
#include "/System/Library/Frameworks/Carbon.framework/Versions/A/Headers/Carbon.h"
#endif

Oliver Bock's avatar
Oliver Bock committed
27
28
PulsatingScience::PulsatingScience(QWidget *parent) : QMainWindow(parent)
{
29
    ui.setupUi(this);
30

31
32
33
34
    QAction* animControl = ui.dockAnimControl->toggleViewAction();
    animControl->setStatusTip(tr("Toggle the animation control visibility"));
    animControl->setShortcut(QKeySequence(tr("Alt+A")));
    ui.menuView->addAction(animControl);
35

36
37
38
39
#ifdef __APPLE__
    ui.actionMenu_bar->setEnabled(false);
#endif

40
41
42
43
44
45
46
47
    // inital status (based on GUI)
    m_permanentOrbits = ui.actionPermanent_orbits->isChecked();
    m_rotationAxesVisible = ui.actionRotationAxes->isChecked();
    m_menuBarVisible = ui.actionMenu_bar->isChecked();
    m_statusBarVisible = ui.actionStatus_bar->isChecked();
    m_animControlVisible = true;
    m_animControlFloating = ui.dockAnimControl->isFloating();
    m_hiddenDemoModeActivated = false;
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    // register alternate shortcuts (will be enabled when menu is hidden)
    m_runShortcut = new QShortcut(ui.actionRun->shortcut(), this);
    m_runShortcut->setEnabled(false);
    m_pauseShortcut = new QShortcut(ui.actionPause->shortcut(), this);
    m_pauseShortcut->setEnabled(false);
    m_stopShortcut = new QShortcut(ui.actionStop->shortcut(), this);
    m_stopShortcut->setEnabled(false);
    m_permanentOrbitsShortcut = new QShortcut(ui.actionPermanent_orbits->shortcut(), this);
    m_permanentOrbitsShortcut->setEnabled(false);
    m_rotationAxesShortcut = new QShortcut(ui.actionRotationAxes->shortcut(), this);
    m_rotationAxesShortcut->setEnabled(false);
    m_menuBarShortcut = new QShortcut(ui.actionMenu_bar->shortcut(), this);
    m_menuBarShortcut->setEnabled(false);
    m_fullscreenShortcut = new QShortcut(ui.actionFullscreen->shortcut(), this);
    m_fullscreenShortcut->setEnabled(false);
64

65
66
    // register "hidden" demo mode shortcut for IYA2009 exhibition
    m_hiddenShortcut = new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::ALT + Qt::Key_D, this);
Oliver Bock's avatar
Oliver Bock committed
67

68
69
70
    // establish object communications
    connect(ui.pushRun, SIGNAL(clicked()),
            ui.pulsarGlWidget, SLOT(runAnimation()));
71

72
73
    connect(ui.actionRun, SIGNAL(triggered()),
            ui.pulsarGlWidget, SLOT(runAnimation()));
74

75
76
    connect(ui.actionRun, SIGNAL(triggered()),
            this, SLOT(on_pushRun_clicked()));
77

78
79
    connect(ui.pushPause, SIGNAL(clicked()),
            ui.pulsarGlWidget, SLOT(pauseAnimation()));
80

81
82
    connect(ui.actionPause, SIGNAL(triggered()),
            ui.pulsarGlWidget, SLOT(pauseAnimation()));
83

84
85
    connect(ui.actionPause, SIGNAL(triggered()),
            this, SLOT(on_pushPause_clicked()));
86

87
88
    connect(ui.pushStop, SIGNAL(clicked()),
            ui.pulsarGlWidget, SLOT(stopAnimation()));
89

90
91
    connect(ui.actionStop, SIGNAL(triggered()),
            ui.pulsarGlWidget, SLOT(stopAnimation()));
92

93
94
    connect(ui.actionStop, SIGNAL(triggered()),
            this, SLOT(on_pushStop_clicked()));
95

96
97
    connect(ui.actionPermanent_orbits, SIGNAL(toggled(bool)),
            ui.pulsarGlWidget, SLOT(showOrbits(bool)));
98

99
100
    connect(ui.actionRotationAxes, SIGNAL(toggled(bool)),
            ui.pulsarGlWidget, SLOT(showRotationAxes(bool)));
Oliver Bock's avatar
Oliver Bock committed
101

102
103
    connect(ui.pulsarGlWidget, SIGNAL(pulsarSemiMajorAxisUpdated(double)),
            this, SLOT(updatePulsarSemiMajorAxisValue(double)));
Oliver Bock's avatar
Oliver Bock committed
104

105
106
    connect(ui.pulsarGlWidget, SIGNAL(pulsarAnimationStep(double)),
            ui.pulseScopeWidget, SLOT(setMarker(double)), Qt::DirectConnection);
Oliver Bock's avatar
Oliver Bock committed
107

108
109
    connect(ui.pulsarGlWidget, SIGNAL(pulseProfileUpdated(const QVector<double>&)),
            ui.pulseScopeWidget, SLOT(drawCurve(const QVector<double>&)), Qt::DirectConnection);
Oliver Bock's avatar
Oliver Bock committed
110

111
112
    connect(m_hiddenShortcut, SIGNAL(activated()),
            this, SLOT(toggleHiddenDemoMode()));
Oliver Bock's avatar
Oliver Bock committed
113
114
115
116
}

PulsatingScience::~PulsatingScience()
{
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    if(m_runShortcut) {
        m_runShortcut->disconnect();
        delete m_runShortcut;
    }

    if(m_pauseShortcut) {
        m_pauseShortcut->disconnect();
        delete m_pauseShortcut;
    }

    if(m_stopShortcut) {
        m_stopShortcut->disconnect();
        delete m_stopShortcut;
    }

    if(m_permanentOrbitsShortcut) {
        m_permanentOrbitsShortcut->disconnect();
        delete m_permanentOrbitsShortcut;
    }

    if(m_rotationAxesShortcut) {
        m_rotationAxesShortcut->disconnect();
        delete m_rotationAxesShortcut;
    }

    if(m_menuBarShortcut) {
        m_menuBarShortcut->disconnect();
        delete m_menuBarShortcut;
    }

    if(m_fullscreenShortcut) {
        m_fullscreenShortcut->disconnect();
        delete m_fullscreenShortcut;
    }

    if(m_hiddenShortcut) {
        m_hiddenShortcut->disconnect();
        delete m_hiddenShortcut;
    }
Oliver Bock's avatar
Oliver Bock committed
156
157
158
159
160
}

void PulsatingScience::closeEvent(QCloseEvent *event)
{
    if(m_hiddenDemoModeActivated) {
161
        event->ignore();
Oliver Bock's avatar
Oliver Bock committed
162
163
164
165
    }
    else {
        event->accept();
    }
Oliver Bock's avatar
Oliver Bock committed
166
}
167

Oliver Bock's avatar
Oliver Bock committed
168
169
void PulsatingScience::on_pushRun_clicked()
{
170
171
172
173
174
175
176
177
178
179
    if(ui.pushRun->isEnabled()) {
        ui.pushRun->setEnabled(false);
        ui.pushPause->setEnabled(true);
        ui.pushStop->setEnabled(true);
    }
    else {
        ui.pushRun->setEnabled(true);
        ui.pushPause->setEnabled(false);
        ui.pushStop->setEnabled(false);
    }
Oliver Bock's avatar
Oliver Bock committed
180
181
182
183
}

void PulsatingScience::on_pushPause_clicked()
{
184
185
186
    ui.pushRun->setEnabled(true);
    ui.pushPause->setEnabled(false);
    ui.pushStop->setEnabled(true);
Oliver Bock's avatar
Oliver Bock committed
187
188
189
190
}

void PulsatingScience::on_pushStop_clicked()
{
191
192
193
    ui.pushRun->setEnabled(true);
    ui.pushPause->setEnabled(false);
    ui.pushStop->setEnabled(false);
Oliver Bock's avatar
Oliver Bock committed
194
195
}

Oliver Bock's avatar
Oliver Bock committed
196
197
void PulsatingScience::on_radioCompanionWD_toggled(bool checked)
{
198
199
200
201
    if(checked) {
        ui.pulsarGlWidget->setCompanionMass(0.6);
        ui.lcdCompanionMass->display(QString::number(0.6, 'f', 1));
    }
Oliver Bock's avatar
Oliver Bock committed
202
203
204
205
}

void PulsatingScience::on_radioCompanionSun_toggled(bool checked)
{
206
207
208
209
    if(checked) {
        ui.pulsarGlWidget->setCompanionMass(1.0);
        ui.lcdCompanionMass->display(QString::number(1.0, 'f', 1));
    }
Oliver Bock's avatar
Oliver Bock committed
210
211
212
213
}

void PulsatingScience::on_radioCompanionNS_toggled(bool checked)
{
214
215
216
217
    if(checked) {
        ui.pulsarGlWidget->setCompanionMass(1.4);
        ui.lcdCompanionMass->display(QString::number(1.4, 'f', 1));
    }
Oliver Bock's avatar
Oliver Bock committed
218
219
220
221
}

void PulsatingScience::on_sliderPulsarMass_valueChanged(int value)
{
222
223
    ui.pulsarGlWidget->setPulsarMass(value * 0.1);
    ui.lcdPulsarMass->display(QString::number(value * 0.1, 'f', 1));
Oliver Bock's avatar
Oliver Bock committed
224
225
}

Oliver Bock's avatar
Oliver Bock committed
226
void PulsatingScience::on_sliderPulsarSpinFrequency_valueChanged(int value)
227
{
228
229
    ui.pulsarGlWidget->setPulsarSpinFrequency(value * 0.1);
    ui.lcdPulsarSpinFrequency->display(QString::number(value * 0.1, 'f', 1));
Oliver Bock's avatar
Oliver Bock committed
230
231
}

232
233
void PulsatingScience::on_sliderPulsarSpinAxisInclination_valueChanged(int value)
{
234
235
    ui.pulsarGlWidget->setPulsarSpinAxisInclination(value);
    ui.lcdPulsarSpinAxisInclination->display(QString::number(value));
236
237
}

238
239
void PulsatingScience::on_sliderPulsarMagneticAxisInclination_valueChanged(int value)
{
240
241
    ui.pulsarGlWidget->setPulsarMagneticAxisInclination(value);
    ui.lcdPulsarMagneticAxisInclination->display(QString::number(value));
242
243
}

Oliver Bock's avatar
Oliver Bock committed
244
void PulsatingScience::on_sliderPulsarSemiMajorAxis_valueChanged(int value)
Oliver Bock's avatar
Oliver Bock committed
245
{
246
247
248
    ui.pulsarGlWidget->setPulsarSemiMajorAxis(value * 0.001);
    ui.lcdPulsarSemiMajorAxis->display(QString::number(value * 0.001, 'f', 1));
    ui.lcdPulsarSemiMajorAxis->setStyleSheet("color: black");
249
}
Oliver Bock's avatar
Oliver Bock committed
250

251
void PulsatingScience::permanentOrbitsToggled() {
252
253
254
255
256
257
258
259
    if(m_permanentOrbits) {
        on_actionPermanent_orbits_toggled(false);
        ui.actionPermanent_orbits->setChecked(false);
    }
    else {
        on_actionPermanent_orbits_toggled(true);
        ui.actionPermanent_orbits->setChecked(true);
    }
260
261
262
}

void PulsatingScience::on_actionPermanent_orbits_toggled(bool checked) {
263
    m_permanentOrbits = checked;
264
265
}

266
void PulsatingScience::rotationAxesToggled() {
267
268
269
270
271
272
273
274
    if(m_rotationAxesVisible) {
        on_actionRotationAxes_toggled(false);
        ui.actionRotationAxes->setChecked(false);
    }
    else {
        on_actionRotationAxes_toggled(true);
        ui.actionRotationAxes->setChecked(true);
    }
275
276
277
}

void PulsatingScience::on_actionRotationAxes_toggled(bool checked) {
278
    m_rotationAxesVisible = checked;
279
280
281
282
}

void PulsatingScience::menuBarToggled()
{
283
284
285
286
287
288
289
290
291
    if(ui.menuBar->isVisible()) {
        on_actionMenu_bar_toggled(false);
        ui.actionMenu_bar->setChecked(false);
    }
    else if(!ui.actionFullscreen->isChecked()) {
        // allow menu bar only when NOT in fullscreen mode
        on_actionMenu_bar_toggled(true);
        ui.actionMenu_bar->setChecked(true);
    }
292
293
}

Oliver Bock's avatar
Oliver Bock committed
294
295
void PulsatingScience::on_actionMenu_bar_toggled(bool checked)
{
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
    if(checked) {
        ui.menuBar->show();
        m_menuBarVisible = true;

        // deactivate alternate shortcuts
        m_runShortcut->disconnect();
        m_runShortcut->setEnabled(false);
        m_pauseShortcut->disconnect();
        m_pauseShortcut->setEnabled(false);
        m_stopShortcut->disconnect();
        m_stopShortcut->setEnabled(false);
        m_permanentOrbitsShortcut->disconnect();
        m_permanentOrbitsShortcut->setEnabled(false);
        m_rotationAxesShortcut->disconnect();
        m_rotationAxesShortcut->setEnabled(false);
        m_fullscreenShortcut->disconnect();
        m_fullscreenShortcut->setEnabled(false);
        m_menuBarShortcut->disconnect();
        m_menuBarShortcut->setEnabled(false);
    }
    else {
        ui.menuBar->hide();
        m_menuBarVisible = false;

        // activate alternate shortcuts
        m_runShortcut->setEnabled(true);
        connect(m_runShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(runAnimation()));
        m_pauseShortcut->setEnabled(true);
        connect(m_pauseShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(pauseAnimation()));
        m_stopShortcut->setEnabled(true);
        connect(m_stopShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(stopAnimation()));
        m_permanentOrbitsShortcut->setEnabled(true);
        connect(m_permanentOrbitsShortcut, SIGNAL(activated()), this, SLOT(permanentOrbitsToggled()));
        m_rotationAxesShortcut->setEnabled(true);
        connect(m_rotationAxesShortcut, SIGNAL(activated()), this, SLOT(rotationAxesToggled()));
        m_fullscreenShortcut->setEnabled(true);
        connect(m_fullscreenShortcut, SIGNAL(activated()), this, SLOT(fullscreenToggled()));
        m_menuBarShortcut->setEnabled(true);
        connect(m_menuBarShortcut, SIGNAL(activated()), this, SLOT(menuBarToggled()));
    }
336
337
338
339
}

void PulsatingScience::fullscreenToggled()
{
340
341
342
343
344
345
346
347
    if((windowState() & Qt::WindowFullScreen) > 0) {
        on_actionFullscreen_toggled(false);
        ui.actionFullscreen->setChecked(false);
    }
    else {
        on_actionFullscreen_toggled(true);
        ui.actionFullscreen->setChecked(true);
    }
348
349
350
351
}

void PulsatingScience::on_actionFullscreen_toggled(bool checked)
{
352
353
354
355
    if(checked) {
        window()->setWindowState(windowState() | Qt::WindowFullScreen);
        // assuming text being black
        setBackgroundRole(QPalette::Text);
356
#ifndef __APPLE__
357
358
359
360
361
        if(m_menuBarVisible) {
            on_actionMenu_bar_toggled(false);
            // keep visibility setting
            m_menuBarVisible = true;
        }
362
#endif
363
364
365
366
367
368
369
370
371
372
        if(m_statusBarVisible) ui.statusbar->hide();
        if(m_animControlVisible && !m_animControlFloating) {
            ui.dockAnimControl->hide();
            // keep visibility setting
            m_animControlVisible = true;
        }
    }
    else {
        window()->setWindowState(windowState() & ~Qt::WindowFullScreen);
        setBackgroundRole(QPalette::Window);
373
#ifndef __APPLE__
374
        if(m_menuBarVisible) on_actionMenu_bar_toggled(true);
375
376
#endif
        if(m_statusBarVisible) ui.statusbar->show();
377
378
        if(m_animControlVisible && !m_animControlFloating) ui.dockAnimControl->show();
    }
Oliver Bock's avatar
Oliver Bock committed
379
380
381
382
}

void PulsatingScience::on_actionStatus_bar_toggled(bool checked)
{
383
384
385
386
387
388
389
390
    if(checked) {
        ui.statusbar->show();
        m_statusBarVisible = true;
    }
    else {
        ui.statusbar->hide();
        m_statusBarVisible = false;
    }
391
392
393
}

void PulsatingScience::on_dockAnimControl_visibilityChanged(bool visible) {
394
    m_animControlVisible = visible;
395
396
397
}

void PulsatingScience::on_dockAnimControl_topLevelChanged(bool topLevel) {
398
    m_animControlFloating = topLevel;
Oliver Bock's avatar
Oliver Bock committed
399
}
Oliver Bock's avatar
Oliver Bock committed
400

401
void PulsatingScience::on_actionHelp_triggered()
402
{
403
404
    PulsatingScienceHelp help(this);
    help.exec();
405
406
}

407
void PulsatingScience::on_actionWebsite_triggered()
Oliver Bock's avatar
Oliver Bock committed
408
{
409
    QDesktopServices::openUrl(QUrl("http://www.aei.mpg.de"));
Oliver Bock's avatar
Oliver Bock committed
410
411
}

412
void PulsatingScience::on_actionAbout_triggered()
Oliver Bock's avatar
Oliver Bock committed
413
{
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
    QString content = "<b>%1</b><br>"
            "%2<br><br>"
            "%3: Oliver Bock, Benjamin Knispel<br><br>"
            "%4<br>"
            "(%5 ESO/IDA/Danish 1.5 m/R.Gendler, J-E. Ovaldsen, C. Th&ouml;ne, C. Feron)<br><br>"
            "%6: GNU General Public License (Version 3)<br><br>"
            "Copyright &copy; 2009 Max-Planck-Institut f&uuml;r Gravitationsphysik";

    content = content.arg(
                tr("Pulsating Science"),
                tr("International Year of Astronomy 2009"),
                tr("Authors"),
                tr("Background image: The Carina Nebula"),
                tr("Courtesy of"),
                tr("License"));

    QMessageBox::about(this, tr("About \"Pulsating Science\""), content);
Oliver Bock's avatar
Oliver Bock committed
431
}
Oliver Bock's avatar
Oliver Bock committed
432
433
434

void PulsatingScience::updatePulsarSemiMajorAxisValue(double value)
{
435
436
437
438
439
440
441
442
443
444
445
    ui.sliderPulsarSemiMajorAxis->setValue(qRound(value * 1000.0));

    if((int)value <= 1 || (int)value >= 20) {
        if((int)value < 1 || (int)value > 20) {
            ui.lcdPulsarSemiMajorAxis->setStyleSheet("color: red");
        }
        else {
            ui.lcdPulsarSemiMajorAxis->setStyleSheet("color: black");
        }
        ui.lcdPulsarSemiMajorAxis->display(QString::number(value, 'f', 1));
    }
Oliver Bock's avatar
Oliver Bock committed
446
}
Oliver Bock's avatar
Oliver Bock committed
447
448
449

void PulsatingScience::toggleHiddenDemoMode()
{
450
    if(m_hiddenDemoModeActivated) {
451
#ifdef __APPLE__
452
453
454
455
456
457
        // show Menubar & Dock
        // unavailable in Qt 4.6: SetSystemUIMode(kUIModeNormal, 0);
        window()->setWindowFlags(windowFlags()
                                 & ~Qt::FramelessWindowHint
                                 & ~Qt::WindowStaysOnTopHint);
        window()->showNormal();
458
#endif
459
460
461
462
463
464
465
466
467
        on_actionMenu_bar_toggled(true);
        ui.actionMenu_bar->setChecked(true);
        window()->setWindowState(windowState() & ~Qt::WindowFullScreen);
        ui.dockAnimControl->setFeatures(QDockWidget::DockWidgetClosable
                                        | QDockWidget::DockWidgetMovable
                                        | QDockWidget::DockWidgetFloatable);
        m_hiddenDemoModeActivated = false;
    }
    else {
468
#ifdef __APPLE__
469
        // hide Menubar & Dock
Oliver Bock's avatar
Oliver Bock committed
470
        // unavailable in Qt 4.6: SetSystemUIMode(kUIModeAllHidden, 0);
471
472
473
474
475
476
477
        // don't ever ask me why this works _only_ in exactly this order on the Mac
        window()->setWindowFlags(windowFlags()
                                 | Qt::FramelessWindowHint
                                 | Qt::WindowStaysOnTopHint);
        window()->showMaximized();
        // might be needed to remove the resize handle on some systems
        // window()->setFixedSize(width(), height());
478
#endif
479
480
481
482
483
484
        on_actionMenu_bar_toggled(false);
        ui.actionMenu_bar->setChecked(false);
        window()->setWindowState(windowState() | Qt::WindowFullScreen);
        ui.dockAnimControl->setFeatures(QDockWidget::NoDockWidgetFeatures);
        m_hiddenDemoModeActivated = true;
    }
Oliver Bock's avatar
Oliver Bock committed
485
}