File indexing completed on 2025-01-05 03:59:25
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2008 Dennis Nienhüser <nienhueser@kde.org> 0004 // SPDX-FileCopyrightText: 2010 Bastian Holst <bastianholst@gmx.de> 0005 // SPDX-FileCopyrightText: 2013 Mohammed Nafees <nafees.technocool@gmail.com> 0006 // 0007 0008 #include "NavigationFloatItem.h" 0009 0010 #include <qmath.h> 0011 #include <QContextMenuEvent> 0012 #include <QRect> 0013 #include <QSlider> 0014 #include <QWidget> 0015 #include <QPainter> 0016 #include <QPixmapCache> 0017 0018 #include <klocalizedstring.h> 0019 0020 #include "ui_navigation.h" 0021 #include "ViewportParams.h" 0022 #include "MarbleWidget.h" 0023 #include "MarbleModel.h" 0024 #include "WidgetGraphicsItem.h" 0025 #include "MarbleGraphicsGridLayout.h" 0026 0027 namespace Marble 0028 { 0029 0030 NavigationFloatItem::NavigationFloatItem( const MarbleModel *marbleModel ) 0031 : AbstractFloatItem( marbleModel, QPointF( -10, -30 ) ), 0032 m_marbleWidget( nullptr ), 0033 m_widgetItem( nullptr ), 0034 m_navigationWidget( nullptr ), 0035 m_oldViewportRadius( 0 ), 0036 m_contextMenu( nullptr ), 0037 m_showHomeButton( true ) 0038 { 0039 // Plugin is visible by default on desktop systems 0040 const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen; 0041 setEnabled( !smallScreen ); 0042 setVisible( true ); 0043 0044 setCacheMode( NoCache ); 0045 setBackground( QBrush( QColor( Qt::transparent ) ) ); 0046 setFrame( NoFrame ); 0047 } 0048 0049 NavigationFloatItem::~NavigationFloatItem() 0050 { 0051 delete m_navigationWidget; 0052 } 0053 0054 QStringList NavigationFloatItem::backendTypes() const 0055 { 0056 return QStringList(QStringLiteral("navigation")); 0057 } 0058 0059 QString NavigationFloatItem::name() const 0060 { 0061 return i18n("Navigation"); 0062 } 0063 0064 QString NavigationFloatItem::guiString() const 0065 { 0066 return i18n("&Navigation"); 0067 } 0068 0069 QString NavigationFloatItem::nameId() const 0070 { 0071 return QStringLiteral("navigation"); 0072 } 0073 0074 QString NavigationFloatItem::version() const 0075 { 0076 return QStringLiteral("1.0"); 0077 } 0078 0079 QString NavigationFloatItem::description() const 0080 { 0081 return i18n("A plugin to add mouse control to zoom and move the map"); 0082 } 0083 0084 QString NavigationFloatItem::copyrightYears() const 0085 { 0086 return QStringLiteral("2008, 2010, 2013"); 0087 } 0088 0089 QVector<PluginAuthor> NavigationFloatItem::pluginAuthors() const 0090 { 0091 return QVector<PluginAuthor>() 0092 << PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org")) 0093 << PluginAuthor(QStringLiteral("Bastian Holst"), QStringLiteral("bastianholst@gmx.de")) 0094 << PluginAuthor(QStringLiteral("Mohammed Nafees"), QStringLiteral("nafees.technocool@gmail.com")); 0095 } 0096 0097 QIcon NavigationFloatItem::icon() const 0098 { 0099 return QIcon::fromTheme(QStringLiteral("circular-arrow-shape")); 0100 } 0101 0102 void NavigationFloatItem::initialize() 0103 { 0104 QWidget *navigationParent = new QWidget( nullptr ); 0105 navigationParent->setAttribute( Qt::WA_NoSystemBackground, true ); 0106 0107 m_navigationWidget = new Ui::Navigation; 0108 m_navigationWidget->setupUi( navigationParent ); 0109 0110 m_widgetItem = new WidgetGraphicsItem( this ); 0111 m_widgetItem->setWidget( navigationParent ); 0112 0113 MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 ); 0114 layout->addItem( m_widgetItem, 0, 0 ); 0115 0116 setLayout( layout ); 0117 0118 if ( m_showHomeButton ) { 0119 activateHomeButton(); 0120 } else { 0121 activateCurrentPositionButton(); 0122 } 0123 } 0124 0125 bool NavigationFloatItem::isInitialized() const 0126 { 0127 return m_widgetItem; 0128 } 0129 0130 void NavigationFloatItem::setProjection( const ViewportParams *viewport ) 0131 { 0132 if ( viewport->radius() != m_oldViewportRadius ) { 0133 m_oldViewportRadius = viewport->radius(); 0134 // The slider depends on the map state (zoom factor) 0135 update(); 0136 } 0137 0138 AbstractFloatItem::setProjection( viewport ); 0139 } 0140 0141 bool NavigationFloatItem::eventFilter( QObject *object, QEvent *e ) 0142 { 0143 if ( !enabled() || !visible() ) { 0144 return false; 0145 } 0146 0147 MarbleWidget *widget = dynamic_cast<MarbleWidget*> (object); 0148 if ( !widget ) { 0149 return AbstractFloatItem::eventFilter( object, e ); 0150 } 0151 0152 if ( m_marbleWidget != widget ) { 0153 // Delayed initialization 0154 m_marbleWidget = widget; 0155 0156 m_maxZoom = m_marbleWidget->maximumZoom(); 0157 m_minZoom = m_marbleWidget->minimumZoom(); 0158 0159 m_navigationWidget->arrowDisc->setMarbleWidget( m_marbleWidget ); 0160 connect( m_navigationWidget->arrowDisc, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) ); 0161 0162 connect( m_navigationWidget->homeButton, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) ); 0163 if ( m_showHomeButton ) { 0164 activateHomeButton(); 0165 } else { 0166 activateCurrentPositionButton(); 0167 } 0168 0169 connect( m_navigationWidget->zoomInButton, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) ); 0170 connect( m_navigationWidget->zoomInButton, SIGNAL(clicked()), 0171 m_marbleWidget, SLOT(zoomIn()) ); 0172 0173 m_navigationWidget->zoomSlider->setMaximum( m_maxZoom ); 0174 m_navigationWidget->zoomSlider->setMinimum( m_minZoom ); 0175 connect( m_navigationWidget->zoomSlider, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) ); 0176 connect( m_navigationWidget->zoomSlider, SIGNAL(valueChanged(int)), 0177 m_marbleWidget, SLOT(setZoom(int)) ); 0178 0179 connect( m_navigationWidget->zoomOutButton, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) ); 0180 connect( m_navigationWidget->zoomOutButton, SIGNAL(clicked()), 0181 m_marbleWidget, SLOT(zoomOut()) ); 0182 0183 connect( m_marbleWidget, SIGNAL(zoomChanged(int)), SLOT(updateButtons(int)) ); 0184 updateButtons( m_marbleWidget->zoom() ); 0185 connect( m_marbleWidget, SIGNAL(themeChanged(QString)), this, SLOT(selectTheme(QString)) ); 0186 } 0187 0188 return AbstractFloatItem::eventFilter(object, e); 0189 } 0190 0191 void NavigationFloatItem::selectTheme( const QString& ) 0192 { 0193 if ( m_marbleWidget ) { 0194 m_maxZoom = m_marbleWidget->maximumZoom(); 0195 m_minZoom = m_marbleWidget->minimumZoom(); 0196 m_navigationWidget->zoomSlider->setMaximum( m_maxZoom ); 0197 m_navigationWidget->zoomSlider->setMinimum( m_minZoom ); 0198 updateButtons( m_marbleWidget->zoom() ); 0199 } 0200 } 0201 0202 void NavigationFloatItem::updateButtons( int zoomValue ) 0203 { 0204 bool const zoomInEnabled = m_navigationWidget->zoomInButton->isEnabled(); 0205 bool const zoomOutEnabled = m_navigationWidget->zoomOutButton->isEnabled(); 0206 int const oldZoomValue = m_navigationWidget->zoomSlider->value(); 0207 m_navigationWidget->zoomInButton->setEnabled( zoomValue < m_maxZoom ); 0208 m_navigationWidget->zoomOutButton->setEnabled( zoomValue > m_minZoom ); 0209 m_navigationWidget->zoomSlider->setValue( zoomValue ); 0210 if ( zoomInEnabled != m_navigationWidget->zoomInButton->isEnabled() || 0211 zoomOutEnabled != m_navigationWidget->zoomOutButton->isEnabled() || 0212 oldZoomValue != zoomValue ) { 0213 update(); 0214 } 0215 } 0216 0217 QPixmap NavigationFloatItem::pixmap( const QString &id ) 0218 { 0219 QPixmap result; 0220 if ( !QPixmapCache::find( id, &result ) ) { 0221 result = QPixmap(QLatin1String(":/") + id + QLatin1String(".png")); 0222 QPixmapCache::insert( id, result ); 0223 } 0224 return result; 0225 } 0226 0227 void NavigationFloatItem::paintContent( QPainter *painter ) 0228 { 0229 painter->drawPixmap( 0, 0, pixmap( QLatin1String("marble/navigation/navigational_backdrop_top") ) ); 0230 painter->drawPixmap( 0, 70, pixmap( QLatin1String("marble/navigation/navigational_backdrop_center") ) ); 0231 painter->drawPixmap( 0, 311, pixmap( QLatin1String("marble/navigation/navigational_backdrop_bottom") ) ); 0232 } 0233 0234 void NavigationFloatItem::contextMenuEvent( QWidget *w, QContextMenuEvent *e ) 0235 { 0236 if ( !m_contextMenu ) { 0237 m_contextMenu = contextMenu(); 0238 0239 m_activateCurrentPositionButtonAction = new QAction( QIcon(), 0240 i18n( "Current Location Button" ), 0241 m_contextMenu ); 0242 m_activateHomeButtonAction = new QAction(QIcon::fromTheme(QStringLiteral("go-home")), 0243 i18n( "Home Button" ), 0244 m_contextMenu ); 0245 m_activateHomeButtonAction->setVisible( !m_showHomeButton ); 0246 m_activateCurrentPositionButtonAction->setVisible( m_showHomeButton ); 0247 m_contextMenu->addSeparator(); 0248 m_contextMenu->addAction( m_activateCurrentPositionButtonAction ); 0249 m_contextMenu->addAction( m_activateHomeButtonAction ); 0250 0251 connect( m_activateCurrentPositionButtonAction, SIGNAL(triggered()), SLOT(activateCurrentPositionButton()) ); 0252 connect( m_activateHomeButtonAction, SIGNAL(triggered()), SLOT(activateHomeButton()) ); 0253 } 0254 0255 Q_ASSERT( m_contextMenu ); 0256 m_contextMenu->exec( w->mapToGlobal( e->pos() ) ); 0257 } 0258 0259 void NavigationFloatItem::activateCurrentPositionButton() 0260 { 0261 if ( !isInitialized() ) { 0262 return; 0263 } 0264 0265 QIcon icon; 0266 icon.addPixmap( pixmap(QLatin1String("marble/navigation/navigational_currentlocation")), QIcon::Normal ); 0267 icon.addPixmap( pixmap(QLatin1String("marble/navigation/navigational_currentlocation_hover")), QIcon::Active ); 0268 icon.addPixmap( pixmap(QLatin1String("marble/navigation/navigational_currentlocation_pressed")), QIcon::Selected ); 0269 m_navigationWidget->homeButton->setProperty("icon", QVariant(icon)); 0270 0271 if ( m_contextMenu ) { 0272 m_activateCurrentPositionButtonAction->setVisible( false ); 0273 m_activateHomeButtonAction->setVisible( true ); 0274 } 0275 0276 if (m_marbleWidget) { 0277 disconnect( m_navigationWidget->homeButton, SIGNAL(clicked()), m_marbleWidget, SLOT(goHome()) ); 0278 } 0279 connect( m_navigationWidget->homeButton, SIGNAL(clicked()), SLOT(centerOnCurrentLocation()) ); 0280 Q_EMIT repaintNeeded(); 0281 m_showHomeButton = false; 0282 Q_EMIT settingsChanged( nameId() ); 0283 } 0284 0285 void NavigationFloatItem::activateHomeButton() 0286 { 0287 if ( !isInitialized() ) { 0288 return; 0289 } 0290 0291 QIcon icon; 0292 icon.addPixmap( pixmap(QLatin1String("marble/navigation/navigational_homebutton")), QIcon::Normal ); 0293 icon.addPixmap( pixmap(QLatin1String("marble/navigation/navigational_homebutton_hover")), QIcon::Active ); 0294 icon.addPixmap( pixmap(QLatin1String("marble/navigation/navigational_homebutton_press")), QIcon::Selected ); 0295 m_navigationWidget->homeButton->setProperty("icon", QVariant(icon)); 0296 0297 if ( m_contextMenu ) { 0298 m_activateCurrentPositionButtonAction->setVisible( true ); 0299 m_activateHomeButtonAction->setVisible( false ); 0300 } 0301 0302 disconnect( m_navigationWidget->homeButton, SIGNAL(clicked()), this, SLOT(centerOnCurrentLocation()) ); 0303 if (m_marbleWidget) { 0304 connect( m_navigationWidget->homeButton, SIGNAL(clicked()), m_marbleWidget, SLOT(goHome()) ); 0305 } 0306 Q_EMIT repaintNeeded(); 0307 m_showHomeButton = true; 0308 Q_EMIT settingsChanged( nameId() ); 0309 } 0310 0311 void NavigationFloatItem::centerOnCurrentLocation() 0312 { 0313 } 0314 0315 QHash<QString,QVariant> NavigationFloatItem::settings() const 0316 { 0317 QHash<QString, QVariant> settings = AbstractFloatItem::settings(); 0318 settings.insert(QStringLiteral("showHomeButton"), m_showHomeButton); 0319 return settings; 0320 } 0321 0322 void NavigationFloatItem::setSettings( const QHash<QString, QVariant> &settings ) 0323 { 0324 AbstractFloatItem::setSettings( settings ); 0325 m_showHomeButton = settings.value(QStringLiteral("showHomeButton"), true).toBool(); 0326 if ( m_showHomeButton ) { 0327 activateHomeButton(); 0328 } else { 0329 activateCurrentPositionButton(); 0330 } 0331 } 0332 0333 } // namespace Marble 0334 0335 #include "moc_NavigationFloatItem.cpp"