File indexing completed on 2024-04-28 03:50:25
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2008 Torsten Rahn <tackat@kde.org> 0004 // SPDX-FileCopyrightText: 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de> 0005 // 0006 0007 #include "StarsPlugin.h" 0008 0009 #include "ui_StarsConfigWidget.h" 0010 #include <QRectF> 0011 #include <QSize> 0012 #include <QDateTime> 0013 #include <QRegion> 0014 #include <QContextMenuEvent> 0015 #include <QMenu> 0016 #include <QColorDialog> 0017 #include <QPainterPath> 0018 #include <qmath.h> 0019 0020 #include "MarbleClock.h" 0021 #include "MarbleColors.h" 0022 #include "MarbleDebug.h" 0023 #include "MarbleDirs.h" 0024 #include "MarbleModel.h" 0025 #include "MarbleWidget.h" 0026 #include "AbstractFloatItem.h" 0027 #include "GeoPainter.h" 0028 #include "Planet.h" 0029 #include "PlanetFactory.h" 0030 #include "SunLocator.h" 0031 #include "ViewportParams.h" 0032 0033 #include "src/lib/astro/solarsystem.h" 0034 0035 namespace Marble 0036 { 0037 0038 StarsPlugin::StarsPlugin( const MarbleModel *marbleModel ) 0039 : RenderPlugin( marbleModel ), 0040 m_nameIndex( 0 ), 0041 m_configDialog( nullptr ), 0042 ui_configWidget( nullptr ), 0043 m_renderStars( true ), 0044 m_renderConstellationLines( true ), 0045 m_renderConstellationLabels( true ), 0046 m_renderDsos( true ), 0047 m_renderDsoLabels( true ), 0048 m_renderSun( true ), 0049 m_renderMoon( true ), 0050 m_renderEcliptic( true ), 0051 m_renderCelestialEquator( true ), 0052 m_renderCelestialPole( true ), 0053 m_starsLoaded( false ), 0054 m_starPixmapsCreated( false ), 0055 m_constellationsLoaded( false ), 0056 m_dsosLoaded( false ), 0057 m_zoomSunMoon( true ), 0058 m_viewSolarSystemLabel( true ), 0059 m_magnitudeLimit( 100 ), 0060 m_zoomCoefficient( 4 ), 0061 m_constellationBrush( Marble::Oxygen::aluminumGray5 ), 0062 m_constellationLabelBrush( Marble::Oxygen::aluminumGray5 ), 0063 m_dsoLabelBrush( Marble::Oxygen::aluminumGray5 ), 0064 m_eclipticBrush( Marble::Oxygen::aluminumGray5 ), 0065 m_celestialEquatorBrush( Marble::Oxygen::aluminumGray5 ), 0066 m_celestialPoleBrush( Marble::Oxygen::aluminumGray5 ), 0067 m_contextMenu(nullptr), 0068 m_constellationsAction(nullptr), 0069 m_sunMoonAction(nullptr), 0070 m_planetsAction(nullptr), 0071 m_dsoAction(nullptr), 0072 m_doRender( false ) 0073 { 0074 bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen; 0075 if (smallScreen) m_magnitudeLimit = 5; 0076 0077 prepareNames(); 0078 } 0079 0080 StarsPlugin::~StarsPlugin() 0081 { 0082 delete m_contextMenu; 0083 } 0084 0085 QStringList StarsPlugin::backendTypes() const 0086 { 0087 return QStringList(QStringLiteral("stars")); 0088 } 0089 0090 QString StarsPlugin::renderPolicy() const 0091 { 0092 return QStringLiteral("SPECIFIED_ALWAYS"); 0093 } 0094 0095 QStringList StarsPlugin::renderPosition() const 0096 { 0097 return QStringList(QStringLiteral("STARS")); 0098 } 0099 0100 RenderPlugin::RenderType StarsPlugin::renderType() const 0101 { 0102 return RenderPlugin::ThemeRenderType; 0103 } 0104 0105 QString StarsPlugin::name() const 0106 { 0107 return tr( "Stars" ); 0108 } 0109 0110 QString StarsPlugin::guiString() const 0111 { 0112 return tr( "&Stars" ); 0113 } 0114 0115 QString StarsPlugin::nameId() const 0116 { 0117 return QStringLiteral("stars"); 0118 } 0119 0120 QString StarsPlugin::version() const 0121 { 0122 return QStringLiteral("1.2"); 0123 } 0124 0125 QString StarsPlugin::description() const 0126 { 0127 return tr( "A plugin that shows the Starry Sky and the Sun." ); 0128 } 0129 0130 QString StarsPlugin::copyrightYears() const 0131 { 0132 return QStringLiteral("2008-2012"); 0133 } 0134 0135 QVector<PluginAuthor> StarsPlugin::pluginAuthors() const 0136 { 0137 return QVector<PluginAuthor>() 0138 << PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org")) 0139 << PluginAuthor(QStringLiteral("Rene Kuettner"), QStringLiteral("rene@bitkanal.net")) 0140 << PluginAuthor(QStringLiteral("Timothy Lanzi"), QStringLiteral("trlanzi@gmail.com")); 0141 } 0142 0143 QIcon StarsPlugin::icon() const 0144 { 0145 return QIcon(QStringLiteral(":/icons/stars.png")); 0146 } 0147 0148 void StarsPlugin::initialize() 0149 { 0150 } 0151 0152 bool StarsPlugin::isInitialized() const 0153 { 0154 return true; 0155 } 0156 0157 QDialog *StarsPlugin::configDialog() 0158 { 0159 if (!m_configDialog) { 0160 // Initializing configuration dialog 0161 m_configDialog = new QDialog; 0162 ui_configWidget = new Ui::StarsConfigWidget; 0163 ui_configWidget->setupUi( m_configDialog ); 0164 0165 readSettings(); 0166 0167 connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()), SLOT(writeSettings()) ); 0168 connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()), SLOT(readSettings()) ); 0169 0170 connect( ui_configWidget->m_constellationColorButton, SIGNAL(clicked()), this, 0171 SLOT(constellationGetColor()) ); 0172 0173 connect( ui_configWidget->m_constellationLabelColorButton, SIGNAL(clicked()), this, 0174 SLOT(constellationLabelGetColor()) ); 0175 0176 connect( ui_configWidget->m_dsoLabelColorButton, SIGNAL(clicked()), this, 0177 SLOT(dsoLabelGetColor()) ); 0178 0179 connect( ui_configWidget->m_eclipticColorButton, SIGNAL(clicked()), this, 0180 SLOT(eclipticGetColor()) ); 0181 0182 connect( ui_configWidget->m_celestialEquatorColorButton, SIGNAL(clicked()), this, 0183 SLOT(celestialEquatorGetColor()) ); 0184 0185 connect( ui_configWidget->m_celestialPoleColorButton, SIGNAL(clicked()), this, 0186 SLOT(celestialPoleGetColor()) ); 0187 } 0188 0189 return m_configDialog; 0190 } 0191 0192 QHash<QString, QVariant> StarsPlugin::settings() const 0193 { 0194 QHash<QString, QVariant> settings = RenderPlugin::settings(); 0195 0196 settings.insert(QStringLiteral("nameIndex"), m_nameIndex); 0197 settings.insert(QStringLiteral("renderStars"), m_renderStars); 0198 settings.insert(QStringLiteral("renderConstellationLines"), m_renderConstellationLines); 0199 settings.insert(QStringLiteral("renderConstellationLabels"), m_renderConstellationLabels); 0200 settings.insert(QStringLiteral("renderDsos"), m_renderDsos); 0201 settings.insert(QStringLiteral("renderDsoLabels"), m_renderDsoLabels); 0202 settings.insert(QStringLiteral("renderSun"), m_renderSun); 0203 settings.insert(QStringLiteral("renderMoon"), m_renderMoon); 0204 0205 QStringList planetState; 0206 for (const QString &key: m_renderPlanet.keys()) 0207 planetState += key + QLatin1Char(':') + QString::number((int)m_renderPlanet[key]); 0208 settings.insert(QStringLiteral("renderPlanet"), planetState.join(QLatin1Char('|'))); 0209 0210 settings.insert(QStringLiteral("renderEcliptic"), m_renderEcliptic); 0211 settings.insert(QStringLiteral("renderCelestialEquator"), m_renderCelestialEquator); 0212 settings.insert(QStringLiteral("renderCelestialPole"), m_renderCelestialPole); 0213 settings.insert(QStringLiteral("zoomSunMoon"), m_zoomSunMoon); 0214 settings.insert(QStringLiteral("viewSolarSystemLabel"), m_viewSolarSystemLabel); 0215 settings.insert(QStringLiteral("magnitudeLimit"), m_magnitudeLimit); 0216 settings.insert(QStringLiteral("constellationBrush"), m_constellationBrush.color().rgb()); 0217 settings.insert(QStringLiteral("constellationLabelBrush"), m_constellationLabelBrush.color().rgb()); 0218 settings.insert(QStringLiteral("dsoLabelBrush"), m_dsoLabelBrush.color().rgb()); 0219 settings.insert(QStringLiteral("eclipticBrush"), m_eclipticBrush.color().rgb()); 0220 settings.insert(QStringLiteral("celestialEaquatorBrush"), m_celestialEquatorBrush.color().rgb()); 0221 settings.insert(QStringLiteral("celestialPoleBrush"), m_celestialPoleBrush.color().rgb()); 0222 0223 return settings; 0224 } 0225 0226 void StarsPlugin::setSettings( const QHash<QString, QVariant> &settings ) 0227 { 0228 RenderPlugin::setSettings( settings ); 0229 0230 m_nameIndex = readSetting<int>(settings, QStringLiteral("nameIndex"), 0); 0231 m_renderStars = readSetting<bool>(settings, QStringLiteral("renderStars"), true); 0232 m_renderConstellationLines = readSetting<bool>(settings, QStringLiteral("renderConstellationLines"), true); 0233 m_renderConstellationLabels = readSetting<bool>(settings, QStringLiteral("renderConstellationLabels"), true); 0234 m_renderDsos = readSetting<bool>(settings, QStringLiteral("renderDsos"), true); 0235 m_renderDsoLabels = readSetting<bool>(settings, QStringLiteral("renderDsoLabels"), true); 0236 m_renderSun = readSetting<bool>(settings, QStringLiteral("renderSun"), true); 0237 m_renderMoon = readSetting<bool>(settings, QStringLiteral("renderMoon"), true); 0238 0239 m_renderPlanet.clear(); 0240 const QString renderPlanet = readSetting<QString>(settings, QStringLiteral("renderPlanet"), QString()); 0241 const QStringList renderStates = renderPlanet.split(QLatin1Char('|')); 0242 for(const QString &state: renderStates) { 0243 const QStringList stateList = state.split(QLatin1Char(':')); 0244 if (stateList.size() == 2) 0245 m_renderPlanet[stateList[0]] = (bool)stateList[1].toInt(); 0246 } 0247 0248 m_renderEcliptic = readSetting<bool>(settings, QStringLiteral("renderEcliptic"), true); 0249 m_renderCelestialEquator = readSetting<bool>(settings, QStringLiteral("renderCelestialEquator"), true); 0250 m_renderCelestialPole = readSetting<bool>(settings, QStringLiteral("renderCelestialPole"), true); 0251 m_zoomSunMoon = readSetting<bool>(settings, QStringLiteral("zoomSunMoon"), true); 0252 m_viewSolarSystemLabel = readSetting<bool>(settings, QStringLiteral("viewSolarSystemLabel"), true); 0253 m_magnitudeLimit = readSetting<int>(settings, QStringLiteral("magnitudeLimit"), 100); 0254 QColor const defaultColor = Marble::Oxygen::aluminumGray5; 0255 m_constellationBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("constellationBrush"), defaultColor.rgb())); 0256 m_constellationLabelBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("constellationLabelBrush"), defaultColor.rgb())); 0257 m_dsoLabelBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("dsoLabelBrush"), defaultColor.rgb())); 0258 m_eclipticBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("eclipticBrush"), defaultColor.rgb())); 0259 m_celestialEquatorBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("celestialEquatorBrush"), defaultColor.rgb())); 0260 m_celestialPoleBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("celestialPoleBrush"), defaultColor.rgb())); 0261 } 0262 0263 QPixmap StarsPlugin::starPixmap(qreal mag, int colorId) const 0264 { 0265 if ( mag < -1 ) { 0266 return m_pixN1Stars.at(colorId); 0267 } else if ( mag < 0 ) { 0268 return m_pixP0Stars.at(colorId); 0269 } else if ( mag < 1 ) { 0270 return m_pixP1Stars.at(colorId); 0271 } else if ( mag < 2 ) { 0272 return m_pixP2Stars.at(colorId); 0273 } else if ( mag < 3 ) { 0274 return m_pixP3Stars.at(colorId); 0275 } else if ( mag < 4 ) { 0276 return m_pixP4Stars.at(colorId); 0277 } else if ( mag < 5 ) { 0278 return m_pixP5Stars.at(colorId); 0279 } else if ( mag < 6 ) { 0280 return m_pixP6Stars.at(colorId); 0281 } else { 0282 return m_pixP7Stars.at(colorId); 0283 } 0284 0285 return QPixmap(); 0286 } 0287 0288 void StarsPlugin::prepareNames() 0289 { 0290 0291 QFile names(MarbleDirs::path(QStringLiteral("stars/names.csv"))); 0292 if ( !names.open( QIODevice::ReadOnly ) ) { 0293 return; 0294 } 0295 0296 QTextStream in( &names ); 0297 while ( !in.atEnd() ) { 0298 QString line = in.readLine(); 0299 const QStringList list = line.split(QLatin1Char(';')); 0300 if ( list.size() == 3 ) { 0301 m_nativeHash[ list.at( 0 ) ] = QCoreApplication::translate( "StarNames", list.at( 1 ).toUtf8().constData() ); 0302 m_abbrHash[ list.at( 0 ) ] = list.at( 2 ); 0303 } 0304 } 0305 names.close(); 0306 0307 } 0308 0309 QString StarsPlugin::assembledConstellation(const QString &name) 0310 { 0311 switch (m_nameIndex) { 0312 case 0: 0313 return name; 0314 case 1: 0315 return m_nativeHash[name]; 0316 case 2: 0317 return m_abbrHash[name]; 0318 default: 0319 return name; 0320 } 0321 } 0322 0323 void StarsPlugin::readSettings() 0324 { 0325 if ( !m_configDialog ) { 0326 return; 0327 } 0328 0329 ui_configWidget->constellationNamesComboBox->setCurrentIndex(m_nameIndex); 0330 0331 Qt::CheckState const constellationLineState = m_renderConstellationLines ? Qt::Checked : Qt::Unchecked; 0332 ui_configWidget->m_viewConstellationLinesCheckbox->setCheckState( constellationLineState ); 0333 0334 Qt::CheckState const constellationLabelState = m_renderConstellationLabels ? Qt::Checked : Qt::Unchecked; 0335 ui_configWidget->m_viewConstellationLabelsCheckbox->setCheckState( constellationLabelState ); 0336 0337 Qt::CheckState const dsoState = m_renderDsos ? Qt::Checked : Qt::Unchecked; 0338 ui_configWidget->m_viewDsosCheckbox->setCheckState( dsoState ); 0339 0340 Qt::CheckState const dsoLabelState = m_renderDsoLabels ? Qt::Checked : Qt::Unchecked; 0341 ui_configWidget->m_viewDsoLabelCheckbox->setCheckState( dsoLabelState ); 0342 0343 Qt::CheckState const sunState = m_renderSun ? Qt::Checked : Qt::Unchecked; 0344 ui_configWidget->m_solarSystemListWidget->item( 0 )->setCheckState( sunState ); 0345 0346 Qt::CheckState const moonState = m_renderMoon ? Qt::Checked : Qt::Unchecked; 0347 ui_configWidget->m_solarSystemListWidget->item( 1 )->setCheckState( moonState ); 0348 0349 Qt::CheckState const mercuryState = m_renderPlanet["mercury"] ? Qt::Checked : Qt::Unchecked; 0350 ui_configWidget->m_solarSystemListWidget->item( 2 )->setCheckState(mercuryState); 0351 0352 Qt::CheckState const venusState = m_renderPlanet["venus"] ? Qt::Checked : Qt::Unchecked; 0353 ui_configWidget->m_solarSystemListWidget->item( 3 )->setCheckState(venusState); 0354 0355 Qt::CheckState const marsState = m_renderPlanet["mars"] ? Qt::Checked : Qt::Unchecked; 0356 ui_configWidget->m_solarSystemListWidget->item( 5 )->setCheckState(marsState); 0357 0358 Qt::CheckState const jupiterState = m_renderPlanet["jupiter"] ? Qt::Checked : Qt::Unchecked; 0359 ui_configWidget->m_solarSystemListWidget->item( 6 )->setCheckState(jupiterState); 0360 0361 Qt::CheckState const saturnState = m_renderPlanet["saturn"] ? Qt::Checked : Qt::Unchecked; 0362 ui_configWidget->m_solarSystemListWidget->item( 7 )->setCheckState(saturnState); 0363 0364 Qt::CheckState const uranusState = m_renderPlanet["uranus"] ? Qt::Checked : Qt::Unchecked; 0365 ui_configWidget->m_solarSystemListWidget->item( 8 )->setCheckState(uranusState); 0366 0367 Qt::CheckState const neptuneState = m_renderPlanet["neptune"] ? Qt::Checked : Qt::Unchecked; 0368 ui_configWidget->m_solarSystemListWidget->item( 9 )->setCheckState(neptuneState); 0369 0370 Qt::CheckState const eclipticState = m_renderEcliptic ? Qt::Checked : Qt::Unchecked; 0371 ui_configWidget->m_viewEclipticCheckbox->setCheckState( eclipticState ); 0372 0373 Qt::CheckState const celestialEquatorState = m_renderCelestialEquator ? Qt::Checked : Qt::Unchecked; 0374 ui_configWidget->m_viewCelestialEquatorCheckbox->setCheckState( celestialEquatorState ); 0375 0376 Qt::CheckState const celestialPoleState = m_renderCelestialPole ? Qt::Checked : Qt::Unchecked; 0377 ui_configWidget->m_viewCelestialPoleCheckbox->setCheckState( celestialPoleState ); 0378 0379 Qt::CheckState const zoomSunMoonState = m_zoomSunMoon ? Qt::Checked : Qt::Unchecked; 0380 ui_configWidget->m_zoomSunMoonCheckbox->setCheckState( zoomSunMoonState ); 0381 0382 Qt::CheckState const viewSolarSystemLabelState = m_viewSolarSystemLabel ? Qt::Checked : Qt::Unchecked; 0383 ui_configWidget->m_viewSolarSystemLabelCheckbox->setCheckState( viewSolarSystemLabelState ); 0384 0385 int magState = m_magnitudeLimit; 0386 if ( magState < ui_configWidget->m_magnitudeSlider->minimum() ) { 0387 magState = ui_configWidget->m_magnitudeSlider->minimum(); 0388 } 0389 else if ( magState > ui_configWidget->m_magnitudeSlider->maximum() ) { 0390 magState = ui_configWidget->m_magnitudeSlider->maximum(); 0391 } 0392 0393 ui_configWidget->m_magnitudeSlider->setValue(magState); 0394 0395 QPalette constellationPalette; 0396 constellationPalette.setColor( QPalette::Button, m_constellationBrush.color() ); 0397 ui_configWidget->m_constellationColorButton->setPalette( constellationPalette ); 0398 0399 QPalette constellationLabelPalette; 0400 constellationLabelPalette.setColor( QPalette::Button, m_constellationLabelBrush.color() ); 0401 ui_configWidget->m_constellationLabelColorButton->setPalette( constellationLabelPalette ); 0402 0403 QPalette dsoLabelPalette; 0404 dsoLabelPalette.setColor( QPalette::Button, m_dsoLabelBrush.color() ); 0405 ui_configWidget->m_dsoLabelColorButton->setPalette( dsoLabelPalette ); 0406 0407 QPalette eclipticPalette; 0408 eclipticPalette.setColor( QPalette::Button, m_eclipticBrush.color() ); 0409 ui_configWidget->m_eclipticColorButton->setPalette( eclipticPalette ); 0410 0411 QPalette celestialEquatorPalette; 0412 celestialEquatorPalette.setColor( QPalette::Button, m_celestialEquatorBrush.color() ); 0413 ui_configWidget->m_celestialEquatorColorButton->setPalette( celestialEquatorPalette ); 0414 0415 QPalette celestialPolePalette; 0416 celestialPolePalette.setColor( QPalette::Button, m_celestialPoleBrush.color() ); 0417 ui_configWidget->m_celestialPoleColorButton->setPalette( celestialPolePalette ); 0418 0419 0420 } 0421 0422 void StarsPlugin::writeSettings() 0423 { 0424 m_nameIndex = ui_configWidget->constellationNamesComboBox->currentIndex(); 0425 m_renderConstellationLines = ui_configWidget->m_viewConstellationLinesCheckbox->checkState() == Qt::Checked; 0426 m_renderConstellationLabels = ui_configWidget->m_viewConstellationLabelsCheckbox->checkState() == Qt::Checked; 0427 m_renderDsos = ui_configWidget->m_viewDsosCheckbox->checkState() == Qt::Checked; 0428 m_renderDsoLabels = ui_configWidget->m_viewDsoLabelCheckbox->checkState() == Qt::Checked; 0429 m_renderSun = ui_configWidget->m_solarSystemListWidget->item( 0 )->checkState() == Qt::Checked; 0430 m_renderMoon = ui_configWidget->m_solarSystemListWidget->item( 1 )->checkState() == Qt::Checked; 0431 0432 m_renderPlanet["mercury"] = ui_configWidget->m_solarSystemListWidget->item( 2 )->checkState() 0433 == Qt::Checked; 0434 m_renderPlanet["venus"] = ui_configWidget->m_solarSystemListWidget->item( 3 )->checkState() 0435 == Qt::Checked; 0436 m_renderPlanet["mars"] = ui_configWidget->m_solarSystemListWidget->item( 5 )->checkState() 0437 == Qt::Checked; 0438 m_renderPlanet["jupiter"] = ui_configWidget->m_solarSystemListWidget->item( 6 )->checkState() 0439 == Qt::Checked; 0440 m_renderPlanet["saturn"] = ui_configWidget->m_solarSystemListWidget->item( 7 )->checkState() 0441 == Qt::Checked; 0442 m_renderPlanet["uranus"] = ui_configWidget->m_solarSystemListWidget->item( 8 )->checkState() 0443 == Qt::Checked; 0444 m_renderPlanet["neptune"] = ui_configWidget->m_solarSystemListWidget->item( 9 )->checkState() 0445 == Qt::Checked; 0446 0447 m_renderEcliptic = ui_configWidget->m_viewEclipticCheckbox->checkState() == Qt::Checked; 0448 m_renderCelestialEquator = ui_configWidget->m_viewCelestialEquatorCheckbox->checkState() == Qt::Checked; 0449 m_renderCelestialPole = ui_configWidget->m_viewCelestialPoleCheckbox->checkState() == Qt::Checked; 0450 m_zoomSunMoon = ui_configWidget->m_zoomSunMoonCheckbox->checkState() == Qt::Checked; 0451 m_viewSolarSystemLabel = ui_configWidget->m_viewSolarSystemLabelCheckbox->checkState() == Qt::Checked; 0452 m_magnitudeLimit = ui_configWidget->m_magnitudeSlider->value(); 0453 m_constellationBrush = QBrush( ui_configWidget->m_constellationColorButton->palette().color( QPalette::Button) ); 0454 m_constellationLabelBrush = QBrush( ui_configWidget->m_constellationLabelColorButton->palette().color( QPalette::Button) ); 0455 m_dsoLabelBrush = QBrush( ui_configWidget->m_dsoLabelColorButton->palette().color( QPalette::Button) ); 0456 m_eclipticBrush = QBrush( ui_configWidget->m_eclipticColorButton->palette().color( QPalette::Button) ); 0457 m_celestialEquatorBrush = QBrush( ui_configWidget->m_celestialEquatorColorButton->palette().color( QPalette::Button) ); 0458 m_celestialPoleBrush = QBrush( ui_configWidget->m_celestialPoleColorButton->palette().color( QPalette::Button) ); 0459 emit settingsChanged( nameId() ); 0460 } 0461 0462 void StarsPlugin::constellationGetColor() 0463 { 0464 const QColor c = QColorDialog::getColor( m_constellationBrush.color(), nullptr, tr("Please choose the color for the constellation lines.") ); 0465 0466 if ( c.isValid() ) { 0467 QPalette palette = ui_configWidget->m_constellationColorButton->palette(); 0468 palette.setColor( QPalette::Button, c ); 0469 ui_configWidget->m_constellationColorButton->setPalette( palette ); 0470 } 0471 } 0472 0473 void StarsPlugin::constellationLabelGetColor() 0474 { 0475 const QColor c = QColorDialog::getColor( m_constellationLabelBrush.color(), nullptr, tr("Please choose the color for the constellation labels.") ); 0476 0477 if ( c.isValid() ) { 0478 QPalette palette = ui_configWidget->m_constellationLabelColorButton->palette(); 0479 palette.setColor( QPalette::Button, c ); 0480 ui_configWidget->m_constellationLabelColorButton->setPalette( palette ); 0481 } 0482 } 0483 0484 void StarsPlugin::dsoLabelGetColor() 0485 { 0486 const QColor c = QColorDialog::getColor( m_dsoLabelBrush.color(), nullptr, tr("Please choose the color for the dso labels.") ); 0487 0488 if ( c.isValid() ) { 0489 QPalette palette = ui_configWidget->m_dsoLabelColorButton->palette(); 0490 palette.setColor( QPalette::Button, c ); 0491 ui_configWidget->m_dsoLabelColorButton->setPalette( palette ); 0492 } 0493 } 0494 0495 void StarsPlugin::eclipticGetColor() 0496 { 0497 const QColor c = QColorDialog::getColor( m_eclipticBrush.color(), nullptr, tr("Please choose the color for the ecliptic.") ); 0498 0499 if ( c.isValid() ) { 0500 QPalette palette = ui_configWidget->m_eclipticColorButton->palette(); 0501 palette.setColor( QPalette::Button, c ); 0502 ui_configWidget->m_eclipticColorButton->setPalette( palette ); 0503 } 0504 } 0505 0506 void StarsPlugin::celestialEquatorGetColor() 0507 { 0508 const QColor c = QColorDialog::getColor( m_celestialEquatorBrush.color(), nullptr, tr("Please choose the color for the celestial equator.") ); 0509 0510 if ( c.isValid() ) { 0511 QPalette palette = ui_configWidget->m_celestialEquatorColorButton->palette(); 0512 palette.setColor( QPalette::Button, c ); 0513 ui_configWidget->m_celestialEquatorColorButton->setPalette( palette ); 0514 } 0515 } 0516 0517 void StarsPlugin::celestialPoleGetColor() 0518 { 0519 const QColor c = QColorDialog::getColor( m_celestialPoleBrush.color(), nullptr, tr("Please choose the color for the celestial equator.") ); 0520 0521 if ( c.isValid() ) { 0522 QPalette palette = ui_configWidget->m_celestialPoleColorButton->palette(); 0523 palette.setColor( QPalette::Button, c ); 0524 ui_configWidget->m_celestialPoleColorButton->setPalette( palette ); 0525 } 0526 } 0527 0528 void StarsPlugin::loadStars() 0529 { 0530 //mDebug(); 0531 // Load star data 0532 m_stars.clear(); 0533 0534 QFile starFile(MarbleDirs::path(QStringLiteral("stars/stars.dat"))); 0535 starFile.open( QIODevice::ReadOnly ); 0536 QDataStream in( &starFile ); 0537 0538 // Read and check the header 0539 quint32 magic; 0540 in >> magic; 0541 if ( magic != 0x73746172 ) { 0542 return; 0543 } 0544 0545 // Read the version 0546 qint32 version; 0547 in >> version; 0548 if ( version > 004 ) { 0549 mDebug() << "stars.dat: file too new."; 0550 return; 0551 } 0552 0553 if ( version == 003 ) { 0554 mDebug() << "stars.dat: file version no longer supported."; 0555 return; 0556 } 0557 0558 int maxid = 0; 0559 int id = 0; 0560 int starIndex = 0; 0561 double ra; 0562 double de; 0563 double mag; 0564 int colorId = 2; 0565 0566 mDebug() << "Star Catalog Version " << version; 0567 0568 while ( !in.atEnd() ) { 0569 if ( version >= 2 ) { 0570 in >> id; 0571 } 0572 if ( id > maxid ) { 0573 maxid = id; 0574 } 0575 in >> ra; 0576 in >> de; 0577 in >> mag; 0578 0579 if ( version >= 4 ) { 0580 in >> colorId; 0581 } 0582 0583 StarPoint star( id, ( qreal )( ra ), ( qreal )( de ), ( qreal )( mag ), colorId ); 0584 // Create entry in stars database 0585 m_stars << star; 0586 // Create key,value pair in idHash table to map from star id to 0587 // index in star database vector 0588 m_idHash[id] = starIndex; 0589 // Increment Index for use in hash 0590 ++starIndex; 0591 } 0592 0593 // load the Sun pixmap 0594 // TODO: adjust pixmap size according to distance 0595 m_pixmapSun.load(MarbleDirs::path(QStringLiteral("svg/sun.png"))); 0596 m_pixmapMoon.load(MarbleDirs::path(QStringLiteral("svg/moon.png"))); 0597 0598 m_starsLoaded = true; 0599 } 0600 0601 void StarsPlugin::createStarPixmaps() 0602 { 0603 // Load star pixmaps 0604 QVector<QPixmap> pixBigStars; 0605 pixBigStars.clear(); 0606 pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_blue.png")))); 0607 pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_bluewhite.png")))); 0608 pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_white.png")))); 0609 pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_yellow.png")))); 0610 pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_orange.png")))); 0611 pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_red.png")))); 0612 pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_garnetred.png")))); 0613 0614 QVector<QPixmap> pixSmallStars; 0615 pixSmallStars.clear(); 0616 pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_blue.png")))); 0617 pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_bluewhite.png")))); 0618 pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_white.png")))); 0619 pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_yellow.png")))); 0620 pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_orange.png")))); 0621 pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_red.png")))); 0622 pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_garnetred.png")))); 0623 0624 0625 // Pre-Scale Star Pixmaps 0626 m_pixN1Stars.clear(); 0627 for ( int p=0; p < pixBigStars.size(); ++p) { 0628 int width = 1.0*pixBigStars.at(p).width(); 0629 m_pixN1Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0630 } 0631 0632 m_pixP0Stars.clear(); 0633 for ( int p=0; p < pixBigStars.size(); ++p) { 0634 int width = 0.90*pixBigStars.at(p).width(); 0635 m_pixP0Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0636 } 0637 0638 m_pixP1Stars.clear(); 0639 for ( int p=0; p < pixBigStars.size(); ++p) { 0640 int width = 0.80*pixBigStars.at(p).width(); 0641 m_pixP1Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0642 } 0643 0644 m_pixP2Stars.clear(); 0645 for ( int p=0; p < pixBigStars.size(); ++p) { 0646 int width = 0.70*pixBigStars.at(p).width(); 0647 m_pixP2Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0648 } 0649 0650 m_pixP3Stars.clear(); 0651 for ( int p=0; p < pixSmallStars.size(); ++p) { 0652 int width = 14; 0653 m_pixP3Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0654 } 0655 0656 m_pixP4Stars.clear(); 0657 for ( int p=0; p < pixSmallStars.size(); ++p) { 0658 int width = 10; 0659 m_pixP4Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0660 } 0661 0662 m_pixP5Stars.clear(); 0663 for ( int p=0; p < pixSmallStars.size(); ++p) { 0664 int width = 6; 0665 m_pixP5Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0666 } 0667 0668 m_pixP6Stars.clear(); 0669 for ( int p=0; p < pixSmallStars.size(); ++p) { 0670 int width = 4; 0671 m_pixP6Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0672 } 0673 0674 m_pixP7Stars.clear(); 0675 for ( int p=0; p < pixSmallStars.size(); ++p) { 0676 int width = 1; 0677 m_pixP7Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation)); 0678 } 0679 0680 m_starPixmapsCreated = true; 0681 } 0682 0683 void StarsPlugin::loadConstellations() 0684 { 0685 // Load star data 0686 m_constellations.clear(); 0687 0688 QFile constellationFile(MarbleDirs::path(QStringLiteral("stars/constellations.dat"))); 0689 constellationFile.open( QIODevice::ReadOnly ); 0690 QTextStream in( &constellationFile ); 0691 QString line; 0692 QString indexList; 0693 0694 while ( !in.atEnd() ) { 0695 line = in.readLine(); 0696 0697 // Check for null line at end of file 0698 if ( line.isNull() ) { 0699 continue; 0700 } 0701 0702 // Ignore Comment lines in header and 0703 // between constellation entries 0704 if (line.startsWith(QLatin1Char('#'))) { 0705 continue; 0706 } 0707 0708 indexList = in.readLine(); 0709 0710 // Make sure we have a valid label and indexList 0711 if ( indexList.isNull() ) { 0712 break; 0713 } 0714 0715 Constellation constellation( this, line, indexList ); 0716 m_constellations << constellation; 0717 0718 } 0719 m_constellationsLoaded = true; 0720 0721 } 0722 0723 void StarsPlugin::loadDsos() 0724 { 0725 // Load star data 0726 m_dsos.clear(); 0727 0728 QFile dsoFile(MarbleDirs::path(QStringLiteral("stars/dso.dat"))); 0729 dsoFile.open( QIODevice::ReadOnly ); 0730 QTextStream in( &dsoFile ); 0731 QString line; 0732 0733 while ( !in.atEnd() ) { 0734 line = in.readLine(); 0735 0736 // Check for null line at end of file 0737 if ( line.isNull() ) { 0738 continue; 0739 } 0740 0741 // Ignore Comment lines in header and 0742 // between dso entries 0743 if (line.startsWith(QLatin1Char('#'))) { 0744 continue; 0745 } 0746 0747 QStringList entries = line.split( QLatin1Char( ',' ) ); 0748 0749 QString id = entries.at( 0 ); 0750 0751 double raH = entries.at( 1 ).toDouble(); 0752 double raM = entries.at( 2 ).toDouble(); 0753 double raS = entries.at( 3 ).toDouble(); 0754 double decD = entries.at( 4 ).toDouble(); 0755 double decM = entries.at( 5 ).toDouble(); 0756 double decS = entries.at( 6 ).toDouble(); 0757 0758 double raRad = ( raH+raM/60.0+raS/3600.0 )*15.0*M_PI/180.0; 0759 double decRad; 0760 0761 if ( decD >= 0.0 ) { 0762 decRad = ( decD+decM/60.0+decS/3600.0 )*M_PI/180.0; 0763 } 0764 else { 0765 decRad = ( decD-decM/60.0-decS/3600.0 )*M_PI/180.0; 0766 } 0767 0768 DsoPoint dso( id, ( qreal )( raRad ), ( qreal )( decRad ) ); 0769 // Create entry in stars database 0770 m_dsos << dso; 0771 } 0772 0773 m_dsoImage.load(MarbleDirs::path(QStringLiteral("stars/deepsky.png"))); 0774 m_dsosLoaded = true; 0775 } 0776 0777 bool StarsPlugin::render( GeoPainter *painter, ViewportParams *viewport, 0778 const QString& renderPos, GeoSceneLayer * layer ) 0779 { 0780 Q_UNUSED( renderPos ) 0781 Q_UNUSED( layer ) 0782 0783 QString planetId = marbleModel()->planetId(); 0784 const bool doRender = !viewport->mapCoversViewport() && 0785 ( (viewport->projection() == Spherical || viewport->projection() == VerticalPerspective) && 0786 planetId == QLatin1String("earth")); // So far displaying stars is only supported on earth. 0787 0788 if ( doRender != m_doRender ) { 0789 if ( doRender ) { 0790 connect( marbleModel()->clock(), SIGNAL(timeChanged()), 0791 this, SLOT(requestRepaint()) ); 0792 } else { 0793 disconnect( marbleModel()->clock(), SIGNAL(timeChanged()), 0794 this, SLOT(requestRepaint()) ); 0795 } 0796 0797 m_doRender = doRender; 0798 } 0799 0800 painter->save(); 0801 0802 SolarSystem sys; 0803 QDateTime dateTime = marbleModel()->clock()->dateTime(); 0804 sys.setCurrentMJD( 0805 dateTime.date().year(), dateTime.date().month(), dateTime.date().day(), 0806 dateTime.time().hour(), dateTime.time().minute(), 0807 (double)dateTime.time().second()); 0808 QString const pname = planetId.at(0).toUpper() + planetId.right(planetId.size() - 1); 0809 QByteArray name = pname.toLatin1(); 0810 sys.setCentralBody( name.data() ); 0811 0812 Vec3 skyVector = sys.getPlanetocentric (0.0, 0.0); 0813 qreal skyRotationAngle = -atan2(skyVector[1], skyVector[0]); 0814 0815 const qreal centerLon = viewport->centerLongitude(); 0816 const qreal centerLat = viewport->centerLatitude(); 0817 0818 const qreal skyRadius = 0.6 * sqrt( ( qreal )viewport->width() * viewport->width() + viewport->height() * viewport->height() ); 0819 0820 if ( doRender ) { 0821 if (!m_starPixmapsCreated) { 0822 createStarPixmaps(); 0823 m_starPixmapsCreated = true; 0824 } 0825 0826 // Delayed initialization: 0827 // Load the star database only if the sky is actually being painted... 0828 if ( !m_starsLoaded ) { 0829 loadStars(); 0830 m_starsLoaded = true; 0831 } 0832 0833 if ( !m_constellationsLoaded ) { 0834 loadConstellations(); 0835 m_constellationsLoaded = true; 0836 } 0837 0838 if ( !m_dsosLoaded ) { 0839 loadDsos(); 0840 m_dsosLoaded = true; 0841 } 0842 0843 const qreal earthRadius = viewport->radius(); 0844 0845 // List of Pens used to draw the sky 0846 QPen polesPen( m_celestialPoleBrush, 2, Qt::SolidLine ); 0847 QPen constellationPenSolid( m_constellationBrush, 1, Qt::SolidLine ); 0848 QPen constellationPenDash( m_constellationBrush, 1, Qt::DashLine ); 0849 QPen constellationLabelPen( m_constellationLabelBrush, 1, Qt::SolidLine ); 0850 QPen eclipticPen( m_eclipticBrush, 1, Qt::DotLine ); 0851 QPen equatorPen( m_celestialEquatorBrush, 1, Qt::DotLine ); 0852 QPen dsoLabelPen (m_dsoLabelBrush, 1, Qt::SolidLine); 0853 0854 0855 const Quaternion skyAxis = Quaternion::fromEuler( -centerLat , centerLon + skyRotationAngle, 0.0 ); 0856 matrix skyAxisMatrix; 0857 skyAxis.inverse().toMatrix( skyAxisMatrix ); 0858 0859 if ( m_renderCelestialPole ) { 0860 0861 polesPen.setWidth( 2 ); 0862 painter->setPen( polesPen ); 0863 0864 Quaternion qpos1; 0865 qpos1 = Quaternion::fromSpherical( 0, 90 * DEG2RAD ); 0866 qpos1.rotateAroundAxis( skyAxisMatrix ); 0867 0868 if ( qpos1.v[Q_Z] < 0 ) { 0869 const int x1 = ( int )( viewport->width() / 2 + skyRadius * qpos1.v[Q_X] ); 0870 const int y1 = ( int )( viewport->height() / 2 - skyRadius * qpos1.v[Q_Y] ); 0871 painter->drawLine( x1, y1, x1+10, y1 ); 0872 painter->drawLine( x1+5, y1-5, x1+5, y1+5 ); 0873 painter->drawText( x1+8, y1+12, "NP" ); 0874 } 0875 0876 Quaternion qpos2; 0877 qpos2 = Quaternion::fromSpherical( 0, -90 * DEG2RAD ); 0878 qpos2.rotateAroundAxis( skyAxisMatrix ); 0879 if ( qpos2.v[Q_Z] < 0 ) { 0880 const int x1 = ( int )( viewport->width() / 2 + skyRadius * qpos2.v[Q_X] ); 0881 const int y1 = ( int )( viewport->height() / 2 - skyRadius * qpos2.v[Q_Y] ); 0882 painter->drawLine( x1, y1, x1+10, y1 ); 0883 painter->drawLine( x1+5, y1-5, x1+5, y1+5 ); 0884 painter->drawText( x1+8, y1+12, "SP" ); 0885 } 0886 } 0887 0888 if( m_renderEcliptic ) { 0889 const Quaternion eclipticAxis = Quaternion::fromEuler( 0.0, 0.0, -marbleModel()->planet()->epsilon() ); 0890 matrix eclipticAxisMatrix; 0891 (eclipticAxis * skyAxis).inverse().toMatrix( eclipticAxisMatrix ); 0892 0893 painter->setPen(eclipticPen); 0894 0895 int previousX = -1; 0896 int previousY = -1; 0897 for ( int i = 0; i <= 36; ++i) { 0898 Quaternion qpos; 0899 qpos = Quaternion::fromSpherical( i * 10 * DEG2RAD, 0 ); 0900 qpos.rotateAroundAxis( eclipticAxisMatrix ); 0901 0902 int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] ); 0903 int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] ); 0904 0905 if ( qpos.v[Q_Z] < 0 && previousX >= 0 ) painter->drawLine(previousX, previousY, x, y); 0906 0907 previousX = x; 0908 previousY = y; 0909 } 0910 } 0911 0912 if( m_renderCelestialEquator ) { 0913 painter->setPen(equatorPen); 0914 0915 int previousX = -1; 0916 int previousY = -1; 0917 for ( int i = 0; i <= 36; ++i) { 0918 Quaternion qpos; 0919 qpos = Quaternion::fromSpherical( i * 10 * DEG2RAD, 0 ); 0920 qpos.rotateAroundAxis( skyAxisMatrix ); 0921 0922 int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] ); 0923 int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] ); 0924 0925 if ( qpos.v[Q_Z] < 0 && previousX > 0 ) painter->drawLine(previousX, previousY, x, y); 0926 0927 previousX = x; 0928 previousY = y; 0929 } 0930 } 0931 0932 if ( m_renderDsos ) { 0933 painter->setPen(dsoLabelPen); 0934 // Render Deep Space Objects 0935 for ( int d = 0; d < m_dsos.size(); ++d ) { 0936 Quaternion qpos = m_dsos.at( d ).quaternion(); 0937 qpos.rotateAroundAxis( skyAxisMatrix ); 0938 0939 if ( qpos.v[Q_Z] > 0 ) { 0940 continue; 0941 } 0942 0943 qreal earthCenteredX = qpos.v[Q_X] * skyRadius; 0944 qreal earthCenteredY = qpos.v[Q_Y] * skyRadius; 0945 0946 // Don't draw high placemarks (e.g. satellites) that aren't visible. 0947 if ( qpos.v[Q_Z] < 0 0948 && ( ( earthCenteredX * earthCenteredX 0949 + earthCenteredY * earthCenteredY ) 0950 < earthRadius * earthRadius ) ) { 0951 continue; 0952 } 0953 0954 // Let (x, y) be the position on the screen of the placemark.. 0955 const int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] ); 0956 const int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] ); 0957 0958 // Skip placemarks that are outside the screen area 0959 if ( x < 0 || x >= viewport->width() || 0960 y < 0 || y >= viewport->height() ) { 0961 continue; 0962 } 0963 0964 // Hard Code DSO Size for now 0965 qreal size = 20; 0966 0967 // Center Image on x,y location 0968 painter->drawImage( QRectF( x-size/2, y-size/2, size, size ),m_dsoImage ); 0969 if (m_renderDsoLabels) { 0970 painter->drawText( x+8, y+12, m_dsos.at( d ).id() ); 0971 } 0972 } 0973 } 0974 0975 if ( m_renderConstellationLines || m_renderConstellationLabels ) 0976 { 0977 // Render Constellations 0978 for ( int c = 0; c < m_constellations.size(); ++c ) { 0979 int xMean = 0; 0980 int yMean = 0; 0981 int endptCount = 0; 0982 painter->setPen( constellationPenSolid ); 0983 0984 for ( int s = 0; s < ( m_constellations.at( c ).size() - 1 ); ++s ) { 0985 int starId1 = m_constellations.at( c ).at( s ); 0986 int starId2 = m_constellations.at( c ).at( s + 1 ); 0987 0988 if ( starId1 == -1 || starId2 == -1 ) { 0989 // starId == -1 means we don't draw this segment 0990 continue; 0991 } else if ( starId1 == -2 || starId2 == -2 ) { 0992 painter->setPen( constellationPenDash ); 0993 } else if ( starId1 == -3 || starId2 == -3 ) { 0994 painter->setPen( constellationPenSolid ); 0995 } 0996 0997 int idx1 = m_idHash.value( starId1,-1 ); 0998 int idx2 = m_idHash.value( starId2,-1 ); 0999 1000 1001 if ( idx1 < 0 ) { 1002 // mDebug() << "unknown star, " 1003 // << starId1 << ", in constellation " 1004 // << m_constellations.at( c ).name(); 1005 continue; 1006 } 1007 1008 if ( idx2 < 0 ) { 1009 // mDebug() << "unknown star, " 1010 // << starId1 << ", in constellation " 1011 // << m_constellations.at( c ).name(); 1012 continue; 1013 } 1014 // Fetch quaternion from star s in constellation c 1015 Quaternion q1 = m_stars.at( idx1 ).quaternion(); 1016 // Fetch quaternion from star s+1 in constellation c 1017 Quaternion q2 = m_stars.at( idx2 ).quaternion(); 1018 1019 q1.rotateAroundAxis( skyAxisMatrix ); 1020 q2.rotateAroundAxis( skyAxisMatrix ); 1021 1022 if ( q1.v[Q_Z] > 0 || q2.v[Q_Z] > 0 ) { 1023 continue; 1024 } 1025 1026 1027 // Let (x, y) be the position on the screen of the placemark.. 1028 int x1 = ( int )( viewport->width() / 2 + skyRadius * q1.v[Q_X] ); 1029 int y1 = ( int )( viewport->height() / 2 - skyRadius * q1.v[Q_Y] ); 1030 int x2 = ( int )( viewport->width() / 2 + skyRadius * q2.v[Q_X] ); 1031 int y2 = ( int )( viewport->height() / 2 - skyRadius * q2.v[Q_Y] ); 1032 1033 1034 xMean = xMean + x1 + x2; 1035 yMean = yMean + y1 + y2; 1036 endptCount = endptCount + 2; 1037 1038 if ( m_renderConstellationLines ) { 1039 painter->drawLine( x1, y1, x2, y2 ); 1040 } 1041 1042 } 1043 1044 // Skip constellation labels that are outside the screen area 1045 if ( endptCount > 0 ) { 1046 xMean = xMean / endptCount; 1047 yMean = yMean / endptCount; 1048 } 1049 1050 if ( endptCount < 1 || xMean < 0 || xMean >= viewport->width() 1051 || yMean < 0 || yMean >= viewport->height() ) 1052 continue; 1053 1054 painter->setPen( constellationLabelPen ); 1055 if ( m_renderConstellationLabels ) { 1056 painter->drawText( xMean, yMean, m_constellations.at( c ).name() ); 1057 } 1058 1059 } 1060 } 1061 1062 // Render Stars 1063 1064 for ( int s = 0; s < m_stars.size(); ++s ) { 1065 Quaternion qpos = m_stars.at(s).quaternion(); 1066 1067 qpos.rotateAroundAxis( skyAxisMatrix ); 1068 1069 if ( qpos.v[Q_Z] > 0 ) { 1070 continue; 1071 } 1072 1073 qreal earthCenteredX = qpos.v[Q_X] * skyRadius; 1074 qreal earthCenteredY = qpos.v[Q_Y] * skyRadius; 1075 1076 // Don't draw high placemarks (e.g. satellites) that aren't visible. 1077 if ( qpos.v[Q_Z] < 0 1078 && ( ( earthCenteredX * earthCenteredX 1079 + earthCenteredY * earthCenteredY ) 1080 < earthRadius * earthRadius ) ) { 1081 continue; 1082 } 1083 1084 // Let (x, y) be the position on the screen of the placemark.. 1085 const int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] ); 1086 const int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] ); 1087 1088 // Skip placemarks that are outside the screen area 1089 if ( x < 0 || x >= viewport->width() 1090 || y < 0 || y >= viewport->height() ) 1091 continue; 1092 1093 // Show star if it is brighter than magnitude threshold 1094 if ( m_stars.at(s).magnitude() < m_magnitudeLimit ) { 1095 1096 // colorId is used to select which pixmap in vector to display 1097 int colorId = m_stars.at(s).colorId(); 1098 QPixmap s_pixmap = starPixmap(m_stars.at(s).magnitude(), colorId); 1099 int sizeX = s_pixmap.width(); 1100 int sizeY = s_pixmap.height(); 1101 painter->drawPixmap( x-sizeX/2, y-sizeY/2 ,s_pixmap ); 1102 } 1103 } 1104 1105 if ( m_renderSun ) { 1106 // sun 1107 double ra = 0.0; 1108 double decl = 0.0; 1109 sys.getSun( ra, decl ); 1110 ra = 15.0 * sys.DmsDegF( ra ); 1111 decl = sys.DmsDegF( decl ); 1112 1113 Quaternion qpos = Quaternion::fromSpherical( ra * DEG2RAD, decl * DEG2RAD ); 1114 qpos.rotateAroundAxis( skyAxisMatrix ); 1115 1116 if ( qpos.v[Q_Z] <= 0 ) { 1117 QPixmap glow(MarbleDirs::path(QStringLiteral("svg/glow.png"))); 1118 qreal deltaX = glow.width() / 2.; 1119 qreal deltaY = glow.height() / 2.; 1120 int x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]); 1121 int y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]); 1122 1123 bool glowDrawn = false; 1124 if (!(x < -glow.width() || x >= viewport->width() || 1125 y < -glow.height() || y >= viewport->height())) { 1126 painter->drawPixmap( x - deltaX, y - deltaY, glow ); 1127 glowDrawn = true; 1128 } 1129 1130 if (glowDrawn) { 1131 double diameter = 0.0, mag = 0.0; 1132 sys.getPhysSun(diameter, mag); 1133 const int coefficient = m_zoomSunMoon ? m_zoomCoefficient : 1; 1134 const qreal size = skyRadius * qSin(diameter) * coefficient; 1135 const qreal factor = size/m_pixmapSun.width(); 1136 QPixmap sun = m_pixmapSun.transformed(QTransform().scale(factor, factor), 1137 Qt::SmoothTransformation); 1138 deltaX = sun.width() / 2.; 1139 deltaY = sun.height() / 2.; 1140 x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]); 1141 y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]); 1142 1143 painter->drawPixmap( x - deltaX, y - deltaY, sun ); 1144 } 1145 1146 // It's labels' time! 1147 if (m_viewSolarSystemLabel) 1148 painter->drawText(x+deltaX*1.5, y+deltaY*1.5, tr("Sun")); 1149 } 1150 } 1151 1152 if ( m_renderMoon && marbleModel()->planetId() == QLatin1String("earth")) { 1153 // moon 1154 double ra=0.0; 1155 double decl=0.0; 1156 sys.getMoon(ra, decl); 1157 ra = 15.0 * sys.DmsDegF(ra); 1158 decl = sys.DmsDegF(decl); 1159 1160 Quaternion qpos = Quaternion::fromSpherical( ra * DEG2RAD, 1161 decl * DEG2RAD ); 1162 qpos.rotateAroundAxis( skyAxisMatrix ); 1163 1164 if ( qpos.v[Q_Z] <= 0 ) { 1165 // If zoom Sun and Moon is enabled size is multiplied by zoomCoefficient. 1166 const int coefficient = m_zoomSunMoon ? m_zoomCoefficient : 1; 1167 1168 QPixmap moon = m_pixmapMoon.copy(); 1169 1170 const qreal size = skyRadius * qSin(sys.getDiamMoon()) * coefficient; 1171 qreal deltaX = size / 2.; 1172 qreal deltaY = size / 2.; 1173 const int x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]); 1174 const int y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]); 1175 1176 1177 if (!(x < -size || x >= viewport->width() || 1178 y < -size || y >= viewport->height())) { 1179 // Moon phases 1180 double phase = 0.0, ildisk = 0.0, amag = 0.0; 1181 sys.getLunarPhase(phase, ildisk, amag); 1182 1183 QPainterPath path; 1184 1185 QRectF fullMoonRect = moon.rect(); 1186 if (ildisk < 0.05) { 1187 // small enough, so it's not visible 1188 path.addEllipse(fullMoonRect); 1189 } else if (ildisk < 0.95) { // makes sense to do smth 1190 QRectF halfEllipseRect; 1191 qreal ellipseWidth = 2 * qAbs(ildisk-0.5) * moon.width(); 1192 halfEllipseRect.setX((fullMoonRect.width() - ellipseWidth) * 0.5); 1193 halfEllipseRect.setWidth(ellipseWidth); 1194 halfEllipseRect.setHeight(moon.height()); 1195 1196 if (phase < 0.5) { 1197 if (ildisk < 0.5) { 1198 path.moveTo(fullMoonRect.width()/2, moon.height()); 1199 path.arcTo(fullMoonRect, -90, -180); 1200 path.arcTo(halfEllipseRect, 90, -180); 1201 } else { 1202 path.moveTo(fullMoonRect.width()/2, 0); 1203 path.arcTo(fullMoonRect, 90, 180); 1204 path.arcTo(halfEllipseRect, -90, -180); 1205 } 1206 } else { 1207 if (ildisk < 0.5) { 1208 path.moveTo(fullMoonRect.width()/2, moon.height()); 1209 path.arcTo(fullMoonRect, -90, 180); 1210 path.arcTo(halfEllipseRect, 90, 180); 1211 } else { 1212 path.moveTo(fullMoonRect.width()/2, 0); 1213 path.arcTo(fullMoonRect, 90, -180); 1214 path.arcTo(halfEllipseRect, -90, 180); 1215 } 1216 } 1217 1218 path.closeSubpath(); 1219 } 1220 1221 QPainter overlay; 1222 overlay.begin(&moon); 1223 overlay.setPen(Qt::NoPen); 1224 overlay.setBrush(QBrush(QColor(0, 0, 0, 180))); 1225 overlay.setRenderHint(QPainter::Antialiasing, true); 1226 overlay.drawPath(path); 1227 overlay.end(); 1228 1229 qreal angle = marbleModel()->planet()->epsilon() * qCos(ra * DEG2RAD) * RAD2DEG; 1230 if (viewport->polarity() < 0) angle += 180; 1231 1232 QTransform form; 1233 const qreal factor = size / moon.size().width(); 1234 moon = moon.transformed(form.rotate(angle).scale(factor, factor), 1235 Qt::SmoothTransformation); 1236 1237 painter->drawPixmap( x - deltaX, y - deltaY, moon ); 1238 1239 // It's labels' time! 1240 if (m_viewSolarSystemLabel) 1241 painter->drawText(x+deltaX, y+deltaY, PlanetFactory::localizedName("moon")); 1242 } 1243 } 1244 } 1245 1246 for(const QString &planet: m_renderPlanet.keys()) { 1247 if (m_renderPlanet[planet]) 1248 renderPlanet(planet, painter, sys, viewport, skyRadius, skyAxisMatrix); 1249 } 1250 } 1251 1252 painter->restore(); 1253 1254 return true; 1255 } 1256 1257 void StarsPlugin::renderPlanet(const QString &planetId, 1258 GeoPainter *painter, 1259 SolarSystem &sys, 1260 ViewportParams *viewport, 1261 qreal skyRadius, 1262 matrix &skyAxisMatrix) const 1263 { 1264 double ra(.0), decl(.0), diam(.0), mag(.0), phase(.0); 1265 int color=0; 1266 1267 // venus, mars, jupiter, uranus, neptune, saturn 1268 if (planetId == QLatin1String("venus")) { 1269 sys.getVenus(ra, decl); 1270 sys.getPhysVenus(diam, mag, phase); 1271 color = 2; 1272 } else if (planetId == QLatin1String("mars")) { 1273 sys.getMars(ra, decl); 1274 sys.getPhysMars(diam, mag, phase); 1275 color = 5; 1276 } else if (planetId == QLatin1String("jupiter")) { 1277 sys.getJupiter(ra, decl); 1278 sys.getPhysJupiter(diam, mag, phase); 1279 color = 2; 1280 } else if (planetId == QLatin1String("mercury")) { 1281 sys.getMercury(ra, decl); 1282 sys.getPhysMercury(diam, mag, phase); 1283 color = 3; 1284 } else if (planetId == QLatin1String("saturn")) { 1285 sys.getSaturn(ra, decl); 1286 sys.getPhysSaturn(diam, mag, phase); 1287 color = 3; 1288 } else if (planetId == QLatin1String("uranus")) { 1289 sys.getUranus(ra, decl); 1290 sys.getPhysUranus(diam, mag, phase); 1291 color = 0; 1292 } else if (planetId == QLatin1String("neptune")) { 1293 sys.getNeptune(ra, decl); 1294 sys.getPhysNeptune(diam, mag, phase); 1295 color = 0; 1296 } else { 1297 return; 1298 } 1299 1300 ra = 15.0 * sys.DmsDegF(ra); 1301 decl = sys.DmsDegF(decl); 1302 1303 Quaternion qpos = Quaternion::fromSpherical( ra * DEG2RAD, 1304 decl * DEG2RAD ); 1305 qpos.rotateAroundAxis( skyAxisMatrix ); 1306 1307 if ( qpos.v[Q_Z] <= 0 ) { 1308 QPixmap planetPixmap = starPixmap(mag, color); 1309 1310 qreal deltaX = planetPixmap.width() / 2.; 1311 qreal deltaY = planetPixmap.height() / 2.; 1312 const int x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]); 1313 const int y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]); 1314 1315 if (!(x < 0 || x >= viewport->width() || 1316 y < 0 || y >= viewport->height())) { 1317 painter->drawPixmap( x - deltaX, y - deltaY, planetPixmap ); 1318 } 1319 1320 // It's labels' time! 1321 if (m_viewSolarSystemLabel) 1322 painter->drawText(x+deltaX, y+deltaY, PlanetFactory::localizedName(planetId)); 1323 } 1324 } 1325 1326 void StarsPlugin::requestRepaint() 1327 { 1328 emit repaintNeeded( QRegion() ); 1329 } 1330 1331 void StarsPlugin::toggleSunMoon(bool on) 1332 { 1333 m_renderSun = on; 1334 m_renderMoon = on; 1335 if (on) { 1336 m_viewSolarSystemLabel = true; 1337 } 1338 1339 const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked; 1340 if ( m_configDialog ) { 1341 ui_configWidget->m_solarSystemListWidget->item( 0 )->setCheckState( state ); 1342 ui_configWidget->m_solarSystemListWidget->item( 1 )->setCheckState( state ); 1343 ui_configWidget->m_viewSolarSystemLabelCheckbox->setChecked(m_viewSolarSystemLabel); 1344 } 1345 emit settingsChanged( nameId() ); 1346 requestRepaint(); 1347 } 1348 1349 void StarsPlugin::toggleDsos(bool on) 1350 { 1351 m_renderDsos = on; 1352 // only enable labels if set to true 1353 if (on) { 1354 m_renderDsoLabels = true; 1355 } 1356 1357 const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked; 1358 if ( m_configDialog ) { 1359 ui_configWidget->m_viewDsosCheckbox->setChecked(state); 1360 ui_configWidget->m_viewDsoLabelCheckbox->setChecked(state); 1361 } 1362 emit settingsChanged( nameId() ); 1363 requestRepaint(); 1364 } 1365 1366 void StarsPlugin::toggleConstellations(bool on) 1367 { 1368 m_renderConstellationLines = on; 1369 m_renderConstellationLabels = on; 1370 1371 const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked; 1372 if ( m_configDialog ) { 1373 ui_configWidget->m_viewConstellationLinesCheckbox->setChecked( state ); 1374 ui_configWidget->m_viewConstellationLabelsCheckbox->setChecked( state ); 1375 } 1376 emit settingsChanged( nameId() ); 1377 requestRepaint(); 1378 } 1379 1380 void StarsPlugin::togglePlanets(bool on) 1381 { 1382 m_renderPlanet["venus"] = on; 1383 m_renderPlanet["mars"] = on; 1384 m_renderPlanet["jupiter"] = on; 1385 m_renderPlanet["mercury"] = on; 1386 m_renderPlanet["saturn"] = on; 1387 m_renderPlanet["uranus"] = on; 1388 m_renderPlanet["neptune"] = on; 1389 1390 const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked; 1391 if ( m_configDialog ) { 1392 // Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune 1393 ui_configWidget->m_solarSystemListWidget->item(2)->setCheckState(state); 1394 ui_configWidget->m_solarSystemListWidget->item(3)->setCheckState(state); 1395 ui_configWidget->m_solarSystemListWidget->item(5)->setCheckState(state); 1396 ui_configWidget->m_solarSystemListWidget->item(6)->setCheckState(state); 1397 ui_configWidget->m_solarSystemListWidget->item(7)->setCheckState(state); 1398 ui_configWidget->m_solarSystemListWidget->item(8)->setCheckState(state); 1399 ui_configWidget->m_solarSystemListWidget->item(9)->setCheckState(state); 1400 } 1401 1402 emit settingsChanged( nameId() ); 1403 requestRepaint(); 1404 } 1405 1406 void StarsPlugin::executeConfigDialog() 1407 { 1408 QDialog *dialog = configDialog(); 1409 Q_ASSERT( dialog ); 1410 dialog->exec(); 1411 } 1412 1413 bool StarsPlugin::eventFilter( QObject *object, QEvent *e ) 1414 { 1415 if ( !enabled() || !visible() ) { 1416 return false; 1417 } 1418 1419 if( e->type() == QEvent::ContextMenu ) 1420 { 1421 MarbleWidget *widget = dynamic_cast<MarbleWidget *>( object ); 1422 QContextMenuEvent *menuEvent = dynamic_cast<QContextMenuEvent *> ( e ); 1423 if( widget && menuEvent ) 1424 { 1425 qreal mouseLon, mouseLat; 1426 const bool aboveMap = widget->geoCoordinates( menuEvent->x(), menuEvent->y(), 1427 mouseLon, mouseLat, GeoDataCoordinates::Radian ); 1428 if ( aboveMap ) { 1429 return false; 1430 } 1431 1432 for ( AbstractFloatItem *floatItem: widget->floatItems() ) { 1433 if ( floatItem->enabled() && floatItem->visible() 1434 && floatItem->contains( menuEvent->pos() ) ) 1435 { 1436 return false; 1437 } 1438 } 1439 1440 if (!m_contextMenu) { 1441 m_contextMenu = new QMenu; 1442 m_constellationsAction = m_contextMenu->addAction(tr("Show &Constellations"), 1443 this, SLOT(toggleConstellations(bool))); 1444 m_constellationsAction->setCheckable(true); 1445 1446 m_sunMoonAction = m_contextMenu->addAction(tr("Show &Sun and Moon"), 1447 this, SLOT(toggleSunMoon(bool))); 1448 m_sunMoonAction->setCheckable(true); 1449 1450 m_planetsAction = m_contextMenu->addAction(tr("Show &Planets"), 1451 this, SLOT(togglePlanets(bool))); 1452 m_planetsAction->setCheckable(true); 1453 1454 m_dsoAction = m_contextMenu->addAction(tr("Show &Deep Sky Objects"), 1455 this, SLOT(toggleDsos(bool)) ); 1456 m_dsoAction->setCheckable(true); 1457 1458 m_contextMenu->addSeparator(); 1459 m_contextMenu->addAction(tr("&Configure..."), 1460 this, SLOT(executeConfigDialog())); 1461 } 1462 1463 // update action states 1464 m_constellationsAction->setChecked(m_renderConstellationLines || m_renderConstellationLabels); 1465 m_sunMoonAction->setChecked(m_renderSun || m_renderMoon); 1466 m_dsoAction->setChecked(m_renderDsos); 1467 const bool isAnyPlanetRendered = 1468 m_renderPlanet["venus"] || m_renderPlanet["mars"] || 1469 m_renderPlanet["jupiter"] || m_renderPlanet["mercury"] || 1470 m_renderPlanet["saturn"] || m_renderPlanet["uranus"] || 1471 m_renderPlanet["neptune"]; 1472 m_planetsAction->setChecked(isAnyPlanetRendered); 1473 1474 m_contextMenu->exec(widget->mapToGlobal(menuEvent->pos())); 1475 return true; 1476 } 1477 return false; 1478 } else { 1479 return RenderPlugin::eventFilter( object, e ); 1480 } 1481 } 1482 1483 } 1484 1485 #include "moc_StarsPlugin.cpp"