pulsatingscience.cpp 18.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 <QSettings>

Oliver Bock's avatar
Oliver Bock committed
24

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

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

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

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

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

52
53
54
55
56
57
58
59
60
61
62
    // 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);
63
64
    m_pulseFlashesShortcut = new QShortcut(ui.actionPulseFlashes->shortcut(), this);
    m_pulseFlashesShortcut->setEnabled(false);
65
66
67
68
    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);
69
70
    m_fullscreenESCShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
    m_fullscreenESCShortcut->setEnabled(false);
71

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

75
76
77
    // establish object communications
    connect(ui.actionRun, SIGNAL(triggered()),
            ui.pulsarGlWidget, SLOT(runAnimation()));
78

79
80
    connect(ui.actionPause, SIGNAL(triggered()),
            ui.pulsarGlWidget, SLOT(pauseAnimation()));
81

82
83
    connect(ui.actionStop, SIGNAL(triggered()),
            ui.pulsarGlWidget, SLOT(stopAnimation()));
84

85
86
    connect(ui.actionPermanent_orbits, SIGNAL(toggled(bool)),
            ui.pulsarGlWidget, SLOT(showOrbits(bool)));
87

88
89
    connect(ui.actionRotationAxes, SIGNAL(toggled(bool)),
            ui.pulsarGlWidget, SLOT(showRotationAxes(bool)));
Oliver Bock's avatar
Oliver Bock committed
90

91
92
93
    connect(ui.actionPulseFlashes, SIGNAL(toggled(bool)),
            ui.pulsarGlWidget, SLOT(showPulseFlashes(bool)));

94
95
    connect(ui.pulsarGlWidget, SIGNAL(pulsarAnimationStep(double)),
            ui.pulseScopeWidget, SLOT(setMarker(double)), Qt::DirectConnection);
Oliver Bock's avatar
Oliver Bock committed
96

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

100
101
    connect(m_hiddenShortcut, SIGNAL(activated()),
            this, SLOT(toggleHiddenDemoMode()));
102

103
104
105
106
107
    // prepare inactivity timer
    saveOrRestoreInitialAnimationSettings();
    m_inactivityTimer = new QTimer(this);
    connect(m_inactivityTimer, SIGNAL(timeout()), this, SLOT(userInactivityCallback()));

108
109
110
111
112
113
114
115
116
    // restore previously saved window and splitter layout
    QCoreApplication::setOrganizationName("Max-Planck-Insitut für Gravitationsphysik");
    QCoreApplication::setOrganizationDomain("aei.mpg.de");
    QCoreApplication::setApplicationName("Pulsating Science");
    QSettings settings;

    restoreGeometry(settings.value("windowGeometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());
    ui.splitter->restoreState(settings.value("splitterSizes").toByteArray());
117
118
119
120
121

    // restore view features
    ui.actionPermanent_orbits->setChecked(settings.value("viewOrbitalPlanes", m_permanentOrbits).toBool());
    ui.actionRotationAxes->setChecked(settings.value("viewRotationAxes", m_rotationAxesVisible).toBool());
    ui.actionPulseFlashes->setChecked(settings.value("viewPulseFlashes", m_pulseFlashesVisible).toBool());
Oliver Bock's avatar
Oliver Bock committed
122
123
124
125
}

PulsatingScience::~PulsatingScience()
{
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
    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;
    }

151
152
153
154
155
    if(m_pulseFlashesShortcut) {
        m_pulseFlashesShortcut->disconnect();
        delete m_pulseFlashesShortcut;
    }

156
157
158
159
160
161
162
163
164
165
    if(m_menuBarShortcut) {
        m_menuBarShortcut->disconnect();
        delete m_menuBarShortcut;
    }

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

166
167
168
169
170
    if(m_fullscreenESCShortcut) {
        m_fullscreenESCShortcut->disconnect();
        delete m_fullscreenESCShortcut;
    }

171
172
173
174
    if(m_hiddenShortcut) {
        m_hiddenShortcut->disconnect();
        delete m_hiddenShortcut;
    }
175
176
177
178

    if(m_inactivityTimer) {
        delete m_inactivityTimer;
    }
Oliver Bock's avatar
Oliver Bock committed
179
180
181
182
183
}

void PulsatingScience::closeEvent(QCloseEvent *event)
{
    if(m_hiddenDemoModeActivated) {
184
        event->ignore();
Oliver Bock's avatar
Oliver Bock committed
185
186
    }
    else {
Oliver Bock's avatar
Oliver Bock committed
187
        // save window and splitter layout
188
189
190
191
192
        QSettings settings;
        settings.setValue("windowGeometry", saveGeometry());
        settings.setValue("windowState", saveState());
        settings.setValue("splitterSizes", ui.splitter->saveState());

193
194
195
196
197
        // save view features
        settings.setValue("viewOrbitalPlanes", m_permanentOrbits);
        settings.setValue("viewRotationAxes", m_rotationAxesVisible);
        settings.setValue("viewPulseFlashes", m_pulseFlashesVisible);

Oliver Bock's avatar
Oliver Bock committed
198
199
        event->accept();
    }
Oliver Bock's avatar
Oliver Bock committed
200
}
201

202
void PulsatingScience::on_sliderLHOAngle_valueChanged(int value)
Oliver Bock's avatar
Oliver Bock committed
203
{
Oliver Bock's avatar
Oliver Bock committed
204
    ui.pulsarGlWidget->setLHOAngle(value);
205
    ui.lcdLHOAngle->display(QString::number(value));
Oliver Bock's avatar
Oliver Bock committed
206
207
}

208
void PulsatingScience::on_sliderLLOAngle_valueChanged(int value)
209
{
210
211
    ui.pulsarGlWidget->setLLOAngle(value);
    ui.lcdLLOAngle->display(QString::number(value));
Oliver Bock's avatar
Oliver Bock committed
212
213
}

214
void PulsatingScience::on_sliderVirgoAngle_valueChanged(int value)
215
{
Oliver Bock's avatar
Oliver Bock committed
216
    ui.pulsarGlWidget->setVirgoAngle(value);
217
    ui.lcdVirgoAngle->display(QString::number(value));
218
219
}

220
void PulsatingScience::on_sliderPulsarSpinAxisInclination_valueChanged(int value)
221
{
222
223
    ui.pulsarGlWidget->setPulsarSpinAxisInclination(value);
    ui.lcdPulsarSpinAxisInclination->display(QString::number(value));
224
225
}

226
void PulsatingScience::on_sliderSourceInclination_valueChanged(int value)
Oliver Bock's avatar
Oliver Bock committed
227
{
228
229
    ui.pulsarGlWidget->setSourceInclination(value);
    ui.lcdSourceInclination->display(QString::number(value));
230
}
Oliver Bock's avatar
Oliver Bock committed
231

232
void PulsatingScience::permanentOrbitsToggled() {
233
234
235
236
237
238
239
240
    if(m_permanentOrbits) {
        on_actionPermanent_orbits_toggled(false);
        ui.actionPermanent_orbits->setChecked(false);
    }
    else {
        on_actionPermanent_orbits_toggled(true);
        ui.actionPermanent_orbits->setChecked(true);
    }
241
242
243
}

void PulsatingScience::on_actionPermanent_orbits_toggled(bool checked) {
244
    m_permanentOrbits = checked;
245
246
}

247
void PulsatingScience::rotationAxesToggled() {
248
249
250
251
252
253
254
255
    if(m_rotationAxesVisible) {
        on_actionRotationAxes_toggled(false);
        ui.actionRotationAxes->setChecked(false);
    }
    else {
        on_actionRotationAxes_toggled(true);
        ui.actionRotationAxes->setChecked(true);
    }
256
257
258
}

void PulsatingScience::on_actionRotationAxes_toggled(bool checked) {
259
    m_rotationAxesVisible = checked;
260
261
}

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
void PulsatingScience::pulseFlashesToggled() {
    if(m_pulseFlashesVisible) {
        on_actionPulseFlashes_toggled(false);
        ui.actionPulseFlashes->setChecked(false);
    }
    else {
        on_actionPulseFlashes_toggled(true);
        ui.actionPulseFlashes->setChecked(true);
    }
}

void PulsatingScience::on_actionPulseFlashes_toggled(bool checked) {
    m_pulseFlashesVisible = checked;
}

277
278
void PulsatingScience::menuBarToggled()
{
279
280
281
282
283
284
285
286
287
    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);
    }
288
289
}

Oliver Bock's avatar
Oliver Bock committed
290
291
void PulsatingScience::on_actionMenu_bar_toggled(bool checked)
{
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
    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);
307
308
        m_pulseFlashesShortcut->disconnect();
        m_pulseFlashesShortcut->setEnabled(false);
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
        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()));
329
330
        m_pulseFlashesShortcut->setEnabled(true);
        connect(m_pulseFlashesShortcut, SIGNAL(activated()), this, SLOT(pulseFlashesToggled()));
331
332
333
334
335
        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
        if(m_statusBarVisible) ui.statusbar->hide();
        if(m_animControlVisible && !m_animControlFloating) {
            ui.dockAnimControl->hide();
            // keep visibility setting
            m_animControlVisible = true;
        }
369
370
371

        m_fullscreenESCShortcut->setEnabled(true);
        connect(m_fullscreenESCShortcut, SIGNAL(activated()), this, SLOT(fullscreenToggled()));
372
373
374
375
    }
    else {
        window()->setWindowState(windowState() & ~Qt::WindowFullScreen);
        setBackgroundRole(QPalette::Window);
376
#ifndef __APPLE__
377
        if(m_menuBarVisible) on_actionMenu_bar_toggled(true);
378
379
#endif
        if(m_statusBarVisible) ui.statusbar->show();
380
        if(m_animControlVisible && !m_animControlFloating) ui.dockAnimControl->show();
381
382
383

        m_fullscreenESCShortcut->disconnect();
        m_fullscreenESCShortcut->setEnabled(false);
384
    }
Oliver Bock's avatar
Oliver Bock committed
385
386
387
388
}

void PulsatingScience::on_actionStatus_bar_toggled(bool checked)
{
389
390
391
392
393
394
395
396
    if(checked) {
        ui.statusbar->show();
        m_statusBarVisible = true;
    }
    else {
        ui.statusbar->hide();
        m_statusBarVisible = false;
    }
397
398
399
}

void PulsatingScience::on_dockAnimControl_visibilityChanged(bool visible) {
400
    m_animControlVisible = visible;
401
402
403
}

void PulsatingScience::on_dockAnimControl_topLevelChanged(bool topLevel) {
404
    m_animControlFloating = topLevel;
Oliver Bock's avatar
Oliver Bock committed
405
}
Oliver Bock's avatar
Oliver Bock committed
406

407
void PulsatingScience::on_actionHelp_triggered()
408
{
409
410
    PulsatingScienceHelp help(this);
    help.exec();
411
412
}

413
void PulsatingScience::on_actionWebsite_triggered()
Oliver Bock's avatar
Oliver Bock committed
414
{
415
    QDesktopServices::openUrl(QUrl("http://www.aei.mpg.de"));
Oliver Bock's avatar
Oliver Bock committed
416
417
}

418
void PulsatingScience::on_actionAbout_triggered()
Oliver Bock's avatar
Oliver Bock committed
419
{
420
    QString content = "<b>%1</b><br>"
421
422
423
424
425
426
427
428
429
430
            "%2<br>"
            "<br>"
            "%3: Oliver Bock<br>"
            "%4: Benjamin Knispel<br>"
            "<br>"
            "%5<br>"
            "(%6 ESO/IDA/Danish 1.5m - R.Gendler, J-E. Ovaldsen, C. Th&ouml;ne, C. Feron)<br>"
            "<br>"
            "%7: GNU General Public License v3<br>"
            "<br>"
Oliver Bock's avatar
Oliver Bock committed
431
            "Copyright &copy; 2009-2013 %8";
432
433
434
435

    content = content.arg(
                tr("Pulsating Science"),
                tr("International Year of Astronomy 2009"),
436
437
                tr("Author"),
                tr("Consultant"),
438
439
                tr("Background image: The Carina Nebula"),
                tr("Courtesy of"),
440
441
                tr("License"),
                tr("Max Planck Institute for Gravitational Physics"));
442
443

    QMessageBox::about(this, tr("About \"Pulsating Science\""), content);
Oliver Bock's avatar
Oliver Bock committed
444
}
Oliver Bock's avatar
Oliver Bock committed
445

Oliver Bock's avatar
Oliver Bock committed
446
447
void PulsatingScience::toggleHiddenDemoMode()
{
448
    if(m_hiddenDemoModeActivated) {
449
#ifdef __APPLE__
450
451
452
453
        window()->setWindowFlags(windowFlags()
                                 & ~Qt::FramelessWindowHint
                                 & ~Qt::WindowStaysOnTopHint);
        window()->showNormal();
454
#endif
Oliver Bock's avatar
Oliver Bock committed
455
        // show Menubar & Dock
456
457
458
459
460
461
        on_actionMenu_bar_toggled(true);
        ui.actionMenu_bar->setChecked(true);
        window()->setWindowState(windowState() & ~Qt::WindowFullScreen);
        ui.dockAnimControl->setFeatures(QDockWidget::DockWidgetClosable
                                        | QDockWidget::DockWidgetMovable
                                        | QDockWidget::DockWidgetFloatable);
462
        m_inactivityTimer->stop();
463
464
465
        m_hiddenDemoModeActivated = false;
    }
    else {
466
#ifdef __APPLE__
467
468
469
470
        window()->setWindowFlags(windowFlags()
                                 | Qt::FramelessWindowHint
                                 | Qt::WindowStaysOnTopHint);
        window()->showMaximized();
471
#endif
Oliver Bock's avatar
Oliver Bock committed
472
        // hide Menubar & Dock
473
474
475
476
        on_actionMenu_bar_toggled(false);
        ui.actionMenu_bar->setChecked(false);
        window()->setWindowState(windowState() | Qt::WindowFullScreen);
        ui.dockAnimControl->setFeatures(QDockWidget::NoDockWidgetFeatures);
477
        m_inactivityTimer->start(600000);
478
479
        m_hiddenDemoModeActivated = true;
    }
Oliver Bock's avatar
Oliver Bock committed
480
}
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508

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;

509
510
511
    static int sliderLHOAngle;
    static int sliderLLOAngle;
    static int sliderVirgoAngle;
512
    static int sliderPulsarSpinAxisInclination;
513
    static int sliderSourceInclination;
514
515
516
517
518
519
520

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

    if(initialized) {
        // restore intial settings
521
522
        ui.sliderLHOAngle->setValue(sliderLHOAngle);
        ui.sliderLLOAngle->setValue(sliderLLOAngle);
523
        ui.sliderPulsarSpinAxisInclination->setValue(sliderPulsarSpinAxisInclination);
524
        ui.sliderVirgoAngle->setValue(sliderVirgoAngle);
525
        ui.sliderSourceInclination->setValue(sliderSourceInclination);
526
527
528
529
        ui.pulsarGlWidget->resetCameraPosition(cameraAngleH, cameraAngleV, cameraZoom);
    }
    else {
        // save initial settings
530
531
        sliderLHOAngle = ui.sliderLHOAngle->value();
        sliderLLOAngle = ui.sliderLLOAngle->value();
532
        sliderPulsarSpinAxisInclination = ui.sliderPulsarSpinAxisInclination->value();
533
        sliderVirgoAngle = ui.sliderVirgoAngle->value();
534
        sliderSourceInclination = ui.sliderSourceInclination->value();
535
536
537
538
        ui.pulsarGlWidget->getCameraPosition(cameraAngleH, cameraAngleV, cameraZoom);
        initialized = true;
    }
}