pulsatingscience.cpp 12.8 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
/******************************************************************************
 *   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"
22
23
#include "plotdata.h"

24
25
#include <QSettings>

Oliver Bock's avatar
Oliver Bock committed
26

27
28
29
30
#ifdef __APPLE__
#include "/System/Library/Frameworks/Carbon.framework/Versions/A/Headers/Carbon.h"
#endif

Oliver Bock's avatar
Oliver Bock committed
31
32
PulsatingScience::PulsatingScience(QWidget *parent) : QMainWindow(parent)
{
33
    ui.setupUi(this);
34

35
36
37
38
    QAction* animControl = ui.dockAnimControl->toggleViewAction();
    animControl->setStatusTip(tr("Toggle the animation control visibility"));
    animControl->setShortcut(QKeySequence(tr("Alt+A")));
    ui.menuView->addAction(animControl);
39

40
41
42
43
#ifdef __APPLE__
    ui.actionMenu_bar->setEnabled(false);
#endif

44
45
46
47
48
49
    // inital status (based on GUI)
    m_menuBarVisible = ui.actionMenu_bar->isChecked();
    m_statusBarVisible = ui.actionStatus_bar->isChecked();
    m_animControlVisible = true;
    m_animControlFloating = ui.dockAnimControl->isFloating();
    m_hiddenDemoModeActivated = false;
50

51
52
53
54
55
    // register alternate shortcuts (will be enabled when menu is hidden)
    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);
56
57
    m_fullscreenESCShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
    m_fullscreenESCShortcut->setEnabled(false);
58

59
    // register "hidden" demo mode shortcut for IYA2009 exhibition
Oliver Bock's avatar
Oliver Bock committed
60
    m_hiddenShortcut = new QShortcut(QKeySequence(Qt::SHIFT + Qt::ALT + Qt::Key_D), this);
Oliver Bock's avatar
Oliver Bock committed
61

62
    // establish object communications
63
64
    connect(ui.pulsarGlWidget, SIGNAL(pulseProfileUpdated(const PlotData&)),
            ui.pulseScopeWidget, SLOT(plot(const PlotData&)));
Oliver Bock's avatar
Oliver Bock committed
65

66
67
    connect(m_hiddenShortcut, SIGNAL(activated()),
            this, SLOT(toggleHiddenDemoMode()));
68

69
70
71
72
    // prepare inactivity timer
    m_inactivityTimer = new QTimer(this);
    connect(m_inactivityTimer, SIGNAL(timeout()), this, SLOT(userInactivityCallback()));

73
74
75
    // restore previously saved window and splitter layout
    QCoreApplication::setOrganizationName("Max-Planck-Insitut für Gravitationsphysik");
    QCoreApplication::setOrganizationDomain("aei.mpg.de");
Oliver Bock's avatar
Oliver Bock committed
76
    QCoreApplication::setApplicationName("GW170817");
77
78
79
80
81
    QSettings settings;

    restoreGeometry(settings.value("windowGeometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());
    ui.splitter->restoreState(settings.value("splitterSizes").toByteArray());
82
83
84
85

    // For Bruce: set initial values for iota and psi
    ui.sliderSourceIota->setValue(146);
    ui.sliderSourceInclination->setValue(177);
86
87
88

    // save initial state
    saveOrRestoreInitialAnimationSettings();
Oliver Bock's avatar
Oliver Bock committed
89
90
91
92
}

PulsatingScience::~PulsatingScience()
{
93
94
95
96
97
98
99
100
101
102
    if(m_menuBarShortcut) {
        m_menuBarShortcut->disconnect();
        delete m_menuBarShortcut;
    }

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

103
104
105
106
107
    if(m_fullscreenESCShortcut) {
        m_fullscreenESCShortcut->disconnect();
        delete m_fullscreenESCShortcut;
    }

108
109
110
111
    if(m_hiddenShortcut) {
        m_hiddenShortcut->disconnect();
        delete m_hiddenShortcut;
    }
112
113
114
115

    if(m_inactivityTimer) {
        delete m_inactivityTimer;
    }
Oliver Bock's avatar
Oliver Bock committed
116
117
118
119
120
}

void PulsatingScience::closeEvent(QCloseEvent *event)
{
    if(m_hiddenDemoModeActivated) {
121
        event->ignore();
Oliver Bock's avatar
Oliver Bock committed
122
123
    }
    else {
Oliver Bock's avatar
Oliver Bock committed
124
        // save window and splitter layout
125
126
127
128
129
        QSettings settings;
        settings.setValue("windowGeometry", saveGeometry());
        settings.setValue("windowState", saveState());
        settings.setValue("splitterSizes", ui.splitter->saveState());

Oliver Bock's avatar
Oliver Bock committed
130
131
        event->accept();
    }
Oliver Bock's avatar
Oliver Bock committed
132
}
133

134
void PulsatingScience::on_sliderLHOAngle_valueChanged(int value)
Oliver Bock's avatar
Oliver Bock committed
135
{
Oliver Bock's avatar
Oliver Bock committed
136
    ui.pulsarGlWidget->setLHOAngle(value);
137
    ui.lcdLHOAngle->display(QString::number(value));
Oliver Bock's avatar
Oliver Bock committed
138
139
}

140
void PulsatingScience::on_sliderLLOAngle_valueChanged(int value)
141
{
142
143
    ui.pulsarGlWidget->setLLOAngle(value);
    ui.lcdLLOAngle->display(QString::number(value));
Oliver Bock's avatar
Oliver Bock committed
144
145
}

146
void PulsatingScience::on_sliderVirgoAngle_valueChanged(int value)
147
{
Oliver Bock's avatar
Oliver Bock committed
148
    ui.pulsarGlWidget->setVirgoAngle(value);
149
    ui.lcdVirgoAngle->display(QString::number(value));
150
151
}

Oliver Bock's avatar
Oliver Bock committed
152
void PulsatingScience::on_sliderSourceIota_valueChanged(int value)
153
{
Oliver Bock's avatar
Oliver Bock committed
154
    ui.pulsarGlWidget->setSourceIota(value);
Oliver Bock's avatar
Oliver Bock committed
155
    ui.lcdSourceIota->display(QString::number(value));
156
157
}

158
void PulsatingScience::on_sliderSourceInclination_valueChanged(int value)
Oliver Bock's avatar
Oliver Bock committed
159
{
160
161
    ui.pulsarGlWidget->setSourceInclination(value);
    ui.lcdSourceInclination->display(QString::number(value));
162
}
Oliver Bock's avatar
Oliver Bock committed
163

164
165
void PulsatingScience::menuBarToggled()
{
166
167
168
169
170
171
172
173
174
    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);
    }
175
176
}

Oliver Bock's avatar
Oliver Bock committed
177
178
void PulsatingScience::on_actionMenu_bar_toggled(bool checked)
{
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    if(checked) {
        ui.menuBar->show();
        m_menuBarVisible = true;

        // deactivate alternate shortcuts
        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_fullscreenShortcut->setEnabled(true);
        connect(m_fullscreenShortcut, SIGNAL(activated()), this, SLOT(fullscreenToggled()));
        m_menuBarShortcut->setEnabled(true);
        connect(m_menuBarShortcut, SIGNAL(activated()), this, SLOT(menuBarToggled()));
    }
199
200
201
202
}

void PulsatingScience::fullscreenToggled()
{
203
204
205
206
207
208
209
210
    if((windowState() & Qt::WindowFullScreen) > 0) {
        on_actionFullscreen_toggled(false);
        ui.actionFullscreen->setChecked(false);
    }
    else {
        on_actionFullscreen_toggled(true);
        ui.actionFullscreen->setChecked(true);
    }
211
212
}

213
214
215
216
217
void PulsatingScience::on_actionReset_triggered()
{
    saveOrRestoreInitialAnimationSettings();
}

218
219
void PulsatingScience::on_actionFullscreen_toggled(bool checked)
{
220
221
222
223
    if(checked) {
        window()->setWindowState(windowState() | Qt::WindowFullScreen);
        // assuming text being black
        setBackgroundRole(QPalette::Text);
224
#ifndef __APPLE__
225
226
227
228
229
        if(m_menuBarVisible) {
            on_actionMenu_bar_toggled(false);
            // keep visibility setting
            m_menuBarVisible = true;
        }
230
#endif
231
232
233
234
235
236
        if(m_statusBarVisible) ui.statusbar->hide();
        if(m_animControlVisible && !m_animControlFloating) {
            ui.dockAnimControl->hide();
            // keep visibility setting
            m_animControlVisible = true;
        }
237
238
239

        m_fullscreenESCShortcut->setEnabled(true);
        connect(m_fullscreenESCShortcut, SIGNAL(activated()), this, SLOT(fullscreenToggled()));
240
241
242
243
    }
    else {
        window()->setWindowState(windowState() & ~Qt::WindowFullScreen);
        setBackgroundRole(QPalette::Window);
244
#ifndef __APPLE__
245
        if(m_menuBarVisible) on_actionMenu_bar_toggled(true);
246
247
#endif
        if(m_statusBarVisible) ui.statusbar->show();
248
        if(m_animControlVisible && !m_animControlFloating) ui.dockAnimControl->show();
249
250
251

        m_fullscreenESCShortcut->disconnect();
        m_fullscreenESCShortcut->setEnabled(false);
252
    }
Oliver Bock's avatar
Oliver Bock committed
253
254
255
256
}

void PulsatingScience::on_actionStatus_bar_toggled(bool checked)
{
257
258
259
260
261
262
263
264
    if(checked) {
        ui.statusbar->show();
        m_statusBarVisible = true;
    }
    else {
        ui.statusbar->hide();
        m_statusBarVisible = false;
    }
265
266
267
}

void PulsatingScience::on_dockAnimControl_visibilityChanged(bool visible) {
268
    m_animControlVisible = visible;
269
270
271
}

void PulsatingScience::on_dockAnimControl_topLevelChanged(bool topLevel) {
272
    m_animControlFloating = topLevel;
Oliver Bock's avatar
Oliver Bock committed
273
}
Oliver Bock's avatar
Oliver Bock committed
274

275
void PulsatingScience::on_actionAbout_triggered()
Oliver Bock's avatar
Oliver Bock committed
276
{
277
    QString content = "<b>%1</b><br>"
278
            "<br>"
Oliver Bock's avatar
Oliver Bock committed
279
280
            "%2: Oliver Bock<br>"
            "%3: Bruce Allen<br>"
281
            "<br>"
Oliver Bock's avatar
Oliver Bock committed
282
            "%4: GNU General Public License v3<br>"
283
            "<br>"
Oliver Bock's avatar
Oliver Bock committed
284
            "Copyright &copy; 2017 %5";
285
286

    content = content.arg(
Oliver Bock's avatar
Oliver Bock committed
287
                tr("GW170817"),
Oliver Bock's avatar
Oliver Bock committed
288
289
                tr("UI/Graphics"),
                tr("Physics"),
290
291
                tr("License"),
                tr("Max Planck Institute for Gravitational Physics"));
292

Oliver Bock's avatar
Oliver Bock committed
293
    QMessageBox::about(this, tr("About \"GW170817\""), content);
Oliver Bock's avatar
Oliver Bock committed
294
}
Oliver Bock's avatar
Oliver Bock committed
295

Oliver Bock's avatar
Oliver Bock committed
296
297
void PulsatingScience::toggleHiddenDemoMode()
{
298
    if(m_hiddenDemoModeActivated) {
299
#ifdef __APPLE__
300
301
302
303
        window()->setWindowFlags(windowFlags()
                                 & ~Qt::FramelessWindowHint
                                 & ~Qt::WindowStaysOnTopHint);
        window()->showNormal();
304
#endif
Oliver Bock's avatar
Oliver Bock committed
305
        // show Menubar & Dock
306
307
308
309
310
311
        on_actionMenu_bar_toggled(true);
        ui.actionMenu_bar->setChecked(true);
        window()->setWindowState(windowState() & ~Qt::WindowFullScreen);
        ui.dockAnimControl->setFeatures(QDockWidget::DockWidgetClosable
                                        | QDockWidget::DockWidgetMovable
                                        | QDockWidget::DockWidgetFloatable);
312
        m_inactivityTimer->stop();
313
314
315
        m_hiddenDemoModeActivated = false;
    }
    else {
316
#ifdef __APPLE__
317
318
319
320
        window()->setWindowFlags(windowFlags()
                                 | Qt::FramelessWindowHint
                                 | Qt::WindowStaysOnTopHint);
        window()->showMaximized();
321
#endif
Oliver Bock's avatar
Oliver Bock committed
322
        // hide Menubar & Dock
323
324
325
326
        on_actionMenu_bar_toggled(false);
        ui.actionMenu_bar->setChecked(false);
        window()->setWindowState(windowState() | Qt::WindowFullScreen);
        ui.dockAnimControl->setFeatures(QDockWidget::NoDockWidgetFeatures);
327
        m_inactivityTimer->start(600000);
328
329
        m_hiddenDemoModeActivated = true;
    }
Oliver Bock's avatar
Oliver Bock committed
330
}
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

bool PulsatingScience::eventFilter(QObject *obj, QEvent *event)
{
    if(event->type() == QEvent::MouseButtonPress) {
        userActivity();
    }

    // return original event (we don't want to change any behavior)
    return QObject::eventFilter(obj, event);
}

void PulsatingScience::userActivity()
{
    if(m_hiddenDemoModeActivated) {
        // restart existing timer
        m_inactivityTimer->start();
    }
}

void PulsatingScience::userInactivityCallback()
{
    saveOrRestoreInitialAnimationSettings();
}

void PulsatingScience::saveOrRestoreInitialAnimationSettings()
{
    static bool initialized = false;

359
360
361
    static int sliderLHOAngle;
    static int sliderLLOAngle;
    static int sliderVirgoAngle;
Oliver Bock's avatar
Oliver Bock committed
362
    static int sliderSourceIota;
363
    static int sliderSourceInclination;
364
365
366
367
368
369
370

    static double cameraAngleH;
    static double cameraAngleV;
    static double cameraZoom;

    if(initialized) {
        // restore intial settings
371
372
        ui.sliderLHOAngle->setValue(sliderLHOAngle);
        ui.sliderLLOAngle->setValue(sliderLLOAngle);
Oliver Bock's avatar
Oliver Bock committed
373
        ui.sliderSourceIota->setValue(sliderSourceIota);
374
        ui.sliderVirgoAngle->setValue(sliderVirgoAngle);
375
        ui.sliderSourceInclination->setValue(sliderSourceInclination);
376
377
378
379
        ui.pulsarGlWidget->resetCameraPosition(cameraAngleH, cameraAngleV, cameraZoom);
    }
    else {
        // save initial settings
380
381
        sliderLHOAngle = ui.sliderLHOAngle->value();
        sliderLLOAngle = ui.sliderLLOAngle->value();
Oliver Bock's avatar
Oliver Bock committed
382
        sliderSourceIota = ui.sliderSourceIota->value();
383
        sliderVirgoAngle = ui.sliderVirgoAngle->value();
384
        sliderSourceInclination = ui.sliderSourceInclination->value();
385
386
387
388
        ui.pulsarGlWidget->getCameraPosition(cameraAngleH, cameraAngleV, cameraZoom);
        initialized = true;
    }
}