File indexing completed on 2024-05-05 03:50:46

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 "ui_navigation.h"
0019 #include "ViewportParams.h"
0020 #include "MarbleDebug.h"
0021 #include "MarbleWidget.h"
0022 #include "MarbleModel.h"
0023 #include "PositionTracking.h"
0024 #include "WidgetGraphicsItem.h"
0025 #include "MarbleGraphicsGridLayout.h"
0026 
0027 using namespace Marble;
0028 /* TRANSLATOR Marble::NavigationFloatItem */
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 tr("Navigation");
0062 }
0063 
0064 QString NavigationFloatItem::guiString() const
0065 {
0066     return tr("&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 tr("A 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(QStringLiteral(":/icons/navigation.png"));
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( "marble/navigation/navigational_backdrop_top" ) );
0230     painter->drawPixmap( 0, 70, pixmap( "marble/navigation/navigational_backdrop_center" ) );
0231     painter->drawPixmap( 0, 311, pixmap( "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                                                              tr( "Current Location Button" ),
0241                                                              m_contextMenu );
0242         m_activateHomeButtonAction = new QAction(QIcon(QStringLiteral(":/icons/go-home.png")),
0243                                                              tr( "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("marble/navigation/navigational_currentlocation"), QIcon::Normal );
0267     icon.addPixmap( pixmap("marble/navigation/navigational_currentlocation_hover"), QIcon::Active );
0268     icon.addPixmap( pixmap("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     emit repaintNeeded();
0281     m_showHomeButton = false;
0282     emit settingsChanged( nameId() );
0283 }
0284 
0285 void NavigationFloatItem::activateHomeButton()
0286 {
0287     if ( !isInitialized() ) {
0288         return;
0289     }
0290 
0291     QIcon icon;
0292     icon.addPixmap( pixmap("marble/navigation/navigational_homebutton"), QIcon::Normal );
0293     icon.addPixmap( pixmap("marble/navigation/navigational_homebutton_hover"), QIcon::Active );
0294     icon.addPixmap( pixmap("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     emit repaintNeeded();
0307     m_showHomeButton = true;
0308     emit settingsChanged( nameId() );
0309 }
0310 
0311 void NavigationFloatItem::centerOnCurrentLocation()
0312 {
0313     if ( m_marbleWidget->model()->positionTracking()->currentLocation().isValid() ) {
0314         m_marbleWidget->centerOn( m_marbleWidget->model()->positionTracking()->currentLocation(), true );
0315     }
0316 }
0317 
0318 QHash<QString,QVariant> NavigationFloatItem::settings() const
0319 {
0320     QHash<QString, QVariant> settings = AbstractFloatItem::settings();
0321     settings.insert(QStringLiteral("showHomeButton"), m_showHomeButton);
0322     return settings;
0323 }
0324 
0325 void NavigationFloatItem::setSettings( const QHash<QString, QVariant> &settings )
0326 {
0327     AbstractFloatItem::setSettings( settings );
0328     m_showHomeButton = settings.value(QStringLiteral("showHomeButton"), true).toBool();
0329     if ( m_showHomeButton ) {
0330         activateHomeButton();
0331     } else {
0332         activateCurrentPositionButton();
0333     }
0334 }
0335 
0336 #include "moc_NavigationFloatItem.cpp"