pulsatingscience.cpp 15 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
29
PulsatingScience::PulsatingScience(QWidget *parent) : QMainWindow(parent)
{
	ui.setupUi(this);
30

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

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

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

	// register alternate shortcuts (will be enabled when menu is hidden)
50
51
52
53
54
55
	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);
56
57
	m_permanentOrbitsShortcut = new QShortcut(ui.actionPermanent_orbits->shortcut(), this);
	m_permanentOrbitsShortcut->setEnabled(false);
58
	m_rotationAxesShortcut = new QShortcut(ui.actionRotationAxes->shortcut(), this);
59
	m_rotationAxesShortcut->setEnabled(false);
60
	m_menuBarShortcut = new QShortcut(ui.actionMenu_bar->shortcut(), this);
61
	m_menuBarShortcut->setEnabled(false);
62
	m_fullscreenShortcut = new QShortcut(ui.actionFullscreen->shortcut(), this);
63
64
	m_fullscreenShortcut->setEnabled(false);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Oliver Bock's avatar
Oliver Bock committed
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
	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;
	}

132
133
134
135
136
	if(m_permanentOrbitsShortcut) {
		m_permanentOrbitsShortcut->disconnect();
		delete m_permanentOrbitsShortcut;
	}

137
138
139
140
141
142
143
144
145
	if(m_rotationAxesShortcut) {
		m_rotationAxesShortcut->disconnect();
		delete m_rotationAxesShortcut;
	}

	if(m_menuBarShortcut) {
		m_menuBarShortcut->disconnect();
		delete m_menuBarShortcut;
	}
Oliver Bock's avatar
Oliver Bock committed
146

147
148
149
150
	if(m_fullscreenShortcut) {
		m_fullscreenShortcut->disconnect();
		delete m_fullscreenShortcut;
	}
Oliver Bock's avatar
Oliver Bock committed
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

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

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

Oliver Bock's avatar
Oliver Bock committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
void PulsatingScience::on_pushRun_clicked()
{
	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);
	}
}

void PulsatingScience::on_pushPause_clicked()
{
	ui.pushRun->setEnabled(true);
	ui.pushPause->setEnabled(false);
	ui.pushStop->setEnabled(true);
}

void PulsatingScience::on_pushStop_clicked()
{
	ui.pushRun->setEnabled(true);
	ui.pushPause->setEnabled(false);
	ui.pushStop->setEnabled(false);
}

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

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

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

void PulsatingScience::on_sliderPulsarMass_valueChanged(int value)
{
Oliver Bock's avatar
Oliver Bock committed
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
{
Oliver Bock's avatar
Oliver Bock committed
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
234
235
236
237
void PulsatingScience::on_sliderPulsarSpinAxisInclination_valueChanged(int value)
{
	ui.pulsarGlWidget->setPulsarSpinAxisInclination(value);
	ui.lcdPulsarSpinAxisInclination->display(QString::number(value));
}

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

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

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

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

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
void PulsatingScience::rotationAxesToggled() {
	if(m_rotationAxesVisible) {
		on_actionRotationAxes_toggled(false);
		ui.actionRotationAxes->setChecked(false);
	}
	else {
		on_actionRotationAxes_toggled(true);
		ui.actionRotationAxes->setChecked(true);
	}
}

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

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

Oliver Bock's avatar
Oliver Bock committed
294
295
void PulsatingScience::on_actionMenu_bar_toggled(bool checked)
{
296
297
298
299
300
	if(checked) {
		ui.menuBar->show();
		m_menuBarVisible = true;

		// deactivate alternate shortcuts
301
302
303
304
305
306
		m_runShortcut->disconnect();
		m_runShortcut->setEnabled(false);
		m_pauseShortcut->disconnect();
		m_pauseShortcut->setEnabled(false);
		m_stopShortcut->disconnect();
		m_stopShortcut->setEnabled(false);
307
308
		m_permanentOrbitsShortcut->disconnect();
		m_permanentOrbitsShortcut->setEnabled(false);
309
310
311
312
313
314
315
316
317
318
319
320
		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
321
		m_runShortcut->setEnabled(true);
322
		connect(m_runShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(runAnimation()));
323
		m_pauseShortcut->setEnabled(true);
324
		connect(m_pauseShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(pauseAnimation()));
325
		m_stopShortcut->setEnabled(true);
326
		connect(m_stopShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(stopAnimation()));
327
		m_permanentOrbitsShortcut->setEnabled(true);
328
		connect(m_permanentOrbitsShortcut, SIGNAL(activated()), this, SLOT(permanentOrbitsToggled()));
329
		m_rotationAxesShortcut->setEnabled(true);
330
		connect(m_rotationAxesShortcut, SIGNAL(activated()), this, SLOT(rotationAxesToggled()));
331
		m_fullscreenShortcut->setEnabled(true);
332
		connect(m_fullscreenShortcut, SIGNAL(activated()), this, SLOT(fullscreenToggled()));
333
		m_menuBarShortcut->setEnabled(true);
334
		connect(m_menuBarShortcut, SIGNAL(activated()), this, SLOT(menuBarToggled()));
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
	}
}

void PulsatingScience::fullscreenToggled()
{
	if((windowState() & Qt::WindowFullScreen) > 0) {
		on_actionFullscreen_toggled(false);
		ui.actionFullscreen->setChecked(false);
	}
	else {
		on_actionFullscreen_toggled(true);
		ui.actionFullscreen->setChecked(true);
	}
}

void PulsatingScience::on_actionFullscreen_toggled(bool checked)
{
	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
391
392
393
394
395
396
397
398
	if(checked) {
		ui.statusbar->show();
		m_statusBarVisible = true;
	}
	else {
		ui.statusbar->hide();
		m_statusBarVisible = false;
	}
}

void PulsatingScience::on_dockAnimControl_visibilityChanged(bool visible) {
	m_animControlVisible = visible;
}

void PulsatingScience::on_dockAnimControl_topLevelChanged(bool topLevel) {
	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
405
406
{
	PulsatingScienceHelp help(this);
	help.exec();
}

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

412
void PulsatingScience::on_actionAbout_triggered()
Oliver Bock's avatar
Oliver Bock committed
413
{
Oliver Bock's avatar
Oliver Bock committed
414
415
416
417
418
419
	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>"
420
		"Copyright &copy; 2009 Max-Planck-Institut f&uuml;r Gravitationsphysik";
Oliver Bock's avatar
Oliver Bock committed
421
422
423
424
425
426
427
428
429
430

	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)
{
Oliver Bock's avatar
Oliver Bock committed
435
	ui.sliderPulsarSemiMajorAxis->setValue(qRound(value * 1000.0));
436

437
438
439
440
441
442
443
	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");
		}
444
445
		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
450

void PulsatingScience::toggleHiddenDemoMode()
{
	if(m_hiddenDemoModeActivated) {
451
452
453
454
455
456
457
458
#ifdef __APPLE__
		// show Menubar & Dock
		SetSystemUIMode(kUIModeNormal, 0);
		window()->setWindowFlags(windowFlags()
							   & ~Qt::FramelessWindowHint
							   & ~Qt::WindowStaysOnTopHint);
		window()->showNormal();
#endif
459
460
		on_actionMenu_bar_toggled(true);
		ui.actionMenu_bar->setChecked(true);
Oliver Bock's avatar
Oliver Bock committed
461
		window()->setWindowState(windowState() & ~Qt::WindowFullScreen);
462
463
464
		ui.dockAnimControl->setFeatures(QDockWidget::DockWidgetClosable
									  | QDockWidget::DockWidgetMovable
									  | QDockWidget::DockWidgetFloatable);
Oliver Bock's avatar
Oliver Bock committed
465
466
467
		m_hiddenDemoModeActivated = false;
	}
	else {
468
469
470
471
472
473
474
475
476
477
478
#ifdef __APPLE__
		// hide Menubar & Dock
		SetSystemUIMode(kUIModeAllHidden, 0);
		// don't ever ask my 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());
#endif
479
480
		on_actionMenu_bar_toggled(false);
		ui.actionMenu_bar->setChecked(false);
Oliver Bock's avatar
Oliver Bock committed
481
482
483
484
485
		window()->setWindowState(windowState() | Qt::WindowFullScreen);
		ui.dockAnimControl->setFeatures(QDockWidget::NoDockWidgetFeatures);
		m_hiddenDemoModeActivated = true;
	}
}