pulsatingscience.cpp 14.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 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
	// inital status (based on GUI)
37
	m_permanentOrbits = ui.actionPermanent_orbits->isChecked();
38
	m_rotationAxesVisible = ui.actionRotationAxes->isChecked();
39
	m_menuBarVisible = ui.actionMenu_bar->isChecked();
40 41 42
	m_statusBarVisible = ui.actionStatus_bar->isChecked();
	m_animControlVisible = true;
	m_animControlFloating = ui.dockAnimControl->isFloating();
Oliver Bock's avatar
Oliver Bock committed
43
	m_hiddenDemoModeActivated = false;
44 45

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

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

64
	// establish object communications
65 66 67
	connect(ui.pushRun, SIGNAL(clicked()),
			ui.pulsarGlWidget, SLOT(runAnimation()));

68
	connect(ui.actionRun, SIGNAL(triggered()),
69 70
			ui.pulsarGlWidget, SLOT(runAnimation()));

71
	connect(ui.actionRun, SIGNAL(triggered()),
72 73 74 75 76
				this, SLOT(on_pushRun_clicked()));

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

77
	connect(ui.actionPause, SIGNAL(triggered()),
78 79
				ui.pulsarGlWidget, SLOT(pauseAnimation()));

80
	connect(ui.actionPause, SIGNAL(triggered()),
81 82 83 84 85
				this, SLOT(on_pushPause_clicked()));

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

86
	connect(ui.actionStop, SIGNAL(triggered()),
87 88
				ui.pulsarGlWidget, SLOT(stopAnimation()));

89
	connect(ui.actionStop, SIGNAL(triggered()),
90 91
				this, SLOT(on_pushStop_clicked()));

92 93 94
	connect(ui.actionPermanent_orbits, SIGNAL(toggled(bool)),
				ui.pulsarGlWidget, SLOT(showOrbits(bool)));

Oliver Bock's avatar
Oliver Bock committed
95 96 97
	connect(ui.actionRotationAxes, SIGNAL(toggled(bool)),
				ui.pulsarGlWidget, SLOT(showRotationAxes(bool)));

Oliver Bock's avatar
Oliver Bock committed
98 99 100
	connect(ui.pulsarGlWidget, SIGNAL(pulsarSemiMajorAxisUpdated(double)),
				this, SLOT(updatePulsarSemiMajorAxisValue(double)));

Oliver Bock's avatar
Oliver Bock committed
101
	connect(ui.pulsarGlWidget, SIGNAL(pulsarAnimationStep(double)),
102
				ui.pulseScopeWidget, SLOT(setMarker(double)), Qt::DirectConnection);
Oliver Bock's avatar
Oliver Bock committed
103

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

	connect(m_hiddenShortcut, SIGNAL(activated()),
				this, SLOT(toggleHiddenDemoMode()));
Oliver Bock's avatar
Oliver Bock committed
109 110 111 112
}

PulsatingScience::~PulsatingScience()
{
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
	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;
	}

128 129 130 131 132
	if(m_permanentOrbitsShortcut) {
		m_permanentOrbitsShortcut->disconnect();
		delete m_permanentOrbitsShortcut;
	}

133 134 135 136 137 138 139 140 141
	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
142

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

	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
162
}
163

Oliver Bock's avatar
Oliver Bock committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
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
192 193 194
void PulsatingScience::on_radioCompanionWD_toggled(bool checked)
{
	if(checked) {
Oliver Bock's avatar
Oliver Bock committed
195 196
		ui.pulsarGlWidget->setCompanionMass(0.6);
		ui.lcdCompanionMass->display(QString::number(0.6, 'f', 1));
Oliver Bock's avatar
Oliver Bock committed
197 198 199 200 201 202
	}
}

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

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

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

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

228 229 230 231 232 233
void PulsatingScience::on_sliderPulsarSpinAxisInclination_valueChanged(int value)
{
	ui.pulsarGlWidget->setPulsarSpinAxisInclination(value);
	ui.lcdPulsarSpinAxisInclination->display(QString::number(value));
}

234 235 236 237 238 239
void PulsatingScience::on_sliderPulsarMagneticAxisInclination_valueChanged(int value)
{
	ui.pulsarGlWidget->setPulsarMagneticAxisInclination(value);
	ui.lcdPulsarMagneticAxisInclination->display(QString::number(value));
}

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

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
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;
}

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
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);
	}
283 284
	else if(!ui.actionFullscreen->isChecked()) {
		// allow menu bar only when NOT in fullscreen mode
285 286 287 288 289
		on_actionMenu_bar_toggled(true);
		ui.actionMenu_bar->setChecked(true);
	}
}

Oliver Bock's avatar
Oliver Bock committed
290 291
void PulsatingScience::on_actionMenu_bar_toggled(bool checked)
{
292 293 294 295 296
	if(checked) {
		ui.menuBar->show();
		m_menuBarVisible = true;

		// deactivate alternate shortcuts
297 298 299 300 301 302
		m_runShortcut->disconnect();
		m_runShortcut->setEnabled(false);
		m_pauseShortcut->disconnect();
		m_pauseShortcut->setEnabled(false);
		m_stopShortcut->disconnect();
		m_stopShortcut->setEnabled(false);
303 304
		m_permanentOrbitsShortcut->disconnect();
		m_permanentOrbitsShortcut->setEnabled(false);
305 306 307 308 309 310 311 312 313 314 315 316
		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
317
		m_runShortcut->setEnabled(true);
318
		connect(m_runShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(runAnimation()));
319
		m_pauseShortcut->setEnabled(true);
320
		connect(m_pauseShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(pauseAnimation()));
321
		m_stopShortcut->setEnabled(true);
322
		connect(m_stopShortcut, SIGNAL(activated()), ui.pulsarGlWidget, SLOT(stopAnimation()));
323
		m_permanentOrbitsShortcut->setEnabled(true);
324
		connect(m_permanentOrbitsShortcut, SIGNAL(activated()), this, SLOT(permanentOrbitsToggled()));
325
		m_rotationAxesShortcut->setEnabled(true);
326
		connect(m_rotationAxesShortcut, SIGNAL(activated()), this, SLOT(rotationAxesToggled()));
327
		m_fullscreenShortcut->setEnabled(true);
328
		connect(m_fullscreenShortcut, SIGNAL(activated()), this, SLOT(fullscreenToggled()));
329
		m_menuBarShortcut->setEnabled(true);
330
		connect(m_menuBarShortcut, SIGNAL(activated()), this, SLOT(menuBarToggled()));
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 359 360 361 362 363 364 365 366 367 368 369 370 371 372
	}
}

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

		if(m_menuBarVisible) {
			on_actionMenu_bar_toggled(false);
			// keep visibility setting
			m_menuBarVisible = true;
		}
		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);

		if(m_menuBarVisible) on_actionMenu_bar_toggled(true);
		if(m_statusBarVisible) ui.statusbar->show();
		if(m_animControlVisible && !m_animControlFloating) ui.dockAnimControl->show();
	}
Oliver Bock's avatar
Oliver Bock committed
373 374 375 376
}

void PulsatingScience::on_actionStatus_bar_toggled(bool checked)
{
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
	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
393
}
Oliver Bock's avatar
Oliver Bock committed
394

395
void PulsatingScience::on_actionHelp_triggered()
396 397 398 399 400
{
	PulsatingScienceHelp help(this);
	help.exec();
}

401
void PulsatingScience::on_actionWebsite_triggered()
Oliver Bock's avatar
Oliver Bock committed
402 403 404 405
{
	QDesktopServices::openUrl(QUrl("http://www.aei.mpg.de"));
}

406
void PulsatingScience::on_actionAbout_triggered()
Oliver Bock's avatar
Oliver Bock committed
407
{
Oliver Bock's avatar
Oliver Bock committed
408 409 410 411 412 413
	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>"
414
		"Copyright &copy; 2009 Max-Planck-Institut f&uuml;r Gravitationsphysik";
Oliver Bock's avatar
Oliver Bock committed
415 416 417 418 419 420 421 422 423 424

	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
425
}
Oliver Bock's avatar
Oliver Bock committed
426 427 428

void PulsatingScience::updatePulsarSemiMajorAxisValue(double value)
{
Oliver Bock's avatar
Oliver Bock committed
429
	ui.sliderPulsarSemiMajorAxis->setValue(qRound(value * 1000.0));
430

431 432 433 434 435 436 437
	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");
		}
438 439
		ui.lcdPulsarSemiMajorAxis->display(QString::number(value, 'f', 1));
	}
Oliver Bock's avatar
Oliver Bock committed
440
}
Oliver Bock's avatar
Oliver Bock committed
441 442 443 444

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