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;
	}
}