File indexing completed on 2024-04-21 14:46:58

0001 /*
0002     SPDX-FileCopyrightText: 2005 Jason Harris <kstars@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "pvplotwidget.h"
0008 
0009 #include "planetviewer.h"
0010 
0011 #include <KPlotObject>
0012 #include <KPlotPoint>
0013 
0014 #include <QKeyEvent>
0015 #include <QMouseEvent>
0016 #include <QWheelEvent>
0017 
0018 #include <cmath>
0019 
0020 PVPlotWidget::PVPlotWidget(QWidget *parent) : KPlotWidget(parent)
0021 {
0022     setFocusPolicy(Qt::StrongFocus);
0023     setMouseTracking(true);
0024     setAntialiasing(true);
0025     //FIXME: Evil cast!
0026     pv = (PlanetViewer *)topLevelWidget();
0027 }
0028 
0029 void PVPlotWidget::keyPressEvent(QKeyEvent *e)
0030 {
0031     double xc    = (dataRect().right() + dataRect().x()) * 0.5;
0032     double yc    = (dataRect().bottom() + dataRect().y()) * 0.5;
0033     double xstep = 0.01 * (dataRect().right() - dataRect().x());
0034     double ystep = 0.01 * (dataRect().bottom() - dataRect().y());
0035     double dx    = 0.5 * dataRect().width();
0036     double dy    = 0.5 * dataRect().height();
0037 
0038     switch (e->key())
0039     {
0040         case Qt::Key_Left:
0041             if (xc - xstep > -AUMAX)
0042             {
0043                 setLimits(dataRect().x() - xstep, dataRect().right() - xstep, dataRect().y(), dataRect().bottom());
0044                 pv->setCenterPlanet(QString());
0045                 update();
0046             }
0047             break;
0048 
0049         case Qt::Key_Right:
0050             if (xc + xstep < AUMAX)
0051             {
0052                 setLimits(dataRect().x() + xstep, dataRect().right() + xstep, dataRect().y(), dataRect().bottom());
0053                 pv->setCenterPlanet(QString());
0054                 update();
0055             }
0056             break;
0057 
0058         case Qt::Key_Down:
0059             if (yc - ystep > -AUMAX)
0060             {
0061                 setLimits(dataRect().x(), dataRect().right(), dataRect().y() - ystep, dataRect().bottom() - ystep);
0062                 pv->setCenterPlanet(QString());
0063                 update();
0064             }
0065             break;
0066 
0067         case Qt::Key_Up:
0068             if (yc + ystep < AUMAX)
0069             {
0070                 setLimits(dataRect().x(), dataRect().right(), dataRect().y() + ystep, dataRect().bottom() + ystep);
0071                 pv->setCenterPlanet(QString());
0072                 update();
0073             }
0074             break;
0075 
0076         case Qt::Key_Plus:
0077         case Qt::Key_Equal:
0078         {
0079             updateFactor(e->modifiers());
0080             slotZoomIn();
0081             break;
0082         }
0083 
0084         case Qt::Key_Minus:
0085         case Qt::Key_Underscore:
0086         {
0087             updateFactor(e->modifiers());
0088             slotZoomOut();
0089             break;
0090         }
0091 
0092         case Qt::Key_0: //Sun
0093             setLimits(-dx, dx, -dy, dy);
0094             pv->setCenterPlanet(i18n("Sun"));
0095             update();
0096             break;
0097 
0098         case Qt::Key_1: //Mercury
0099         {
0100             KPlotPoint *p = plotObjects().at(10)->points().at(0);
0101             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0102             pv->setCenterPlanet(i18n("Mercury"));
0103             update();
0104             break;
0105         }
0106 
0107         case Qt::Key_2: //Venus
0108         {
0109             KPlotPoint *p = plotObjects().at(11)->points().at(0);
0110             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0111             pv->setCenterPlanet(i18n("Venus"));
0112             update();
0113             break;
0114         }
0115 
0116         case Qt::Key_3: //Earth
0117         {
0118             KPlotPoint *p = plotObjects().at(12)->points().at(0);
0119             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0120             pv->setCenterPlanet(i18n("Earth"));
0121             update();
0122             break;
0123         }
0124 
0125         case Qt::Key_4: //Mars
0126         {
0127             KPlotPoint *p = plotObjects().at(13)->points().at(0);
0128             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0129             pv->setCenterPlanet(i18n("Mars"));
0130             update();
0131             break;
0132         }
0133 
0134         case Qt::Key_5: //Jupiter
0135         {
0136             KPlotPoint *p = plotObjects().at(14)->points().at(0);
0137             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0138             pv->setCenterPlanet(i18n("Jupiter"));
0139             update();
0140             break;
0141         }
0142 
0143         case Qt::Key_6: //Saturn
0144         {
0145             KPlotPoint *p = plotObjects().at(15)->points().at(0);
0146             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0147             pv->setCenterPlanet(i18n("Saturn"));
0148             update();
0149             break;
0150         }
0151 
0152         case Qt::Key_7: //Uranus
0153         {
0154             KPlotPoint *p = plotObjects().at(16)->points().at(0);
0155             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0156             pv->setCenterPlanet("Uranus");
0157             update();
0158             break;
0159         }
0160 
0161         case Qt::Key_8: //Neptune
0162         {
0163             KPlotPoint *p = plotObjects().at(17)->points().at(0);
0164             setLimits(p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy);
0165             pv->setCenterPlanet(i18n("Neptune"));
0166             update();
0167             break;
0168         }
0169 
0170         /*case Qt::Key_9: //Pluto
0171             {
0172                 KPlotPoint *p = plotObjects().at(18)->points().at(0);
0173                 setLimits( p->x() - dx, p->x() + dx, p->y() - dy, p->y() + dy );
0174                 pv->setCenterPlanet( "Pluto" );
0175                 update();
0176                 break;
0177             }*/
0178 
0179         default:
0180             e->ignore();
0181             break;
0182     }
0183 }
0184 
0185 void PVPlotWidget::mousePressEvent(QMouseEvent *e)
0186 {
0187     mouseButtonDown = true;
0188     oldx            = e->x();
0189     oldy            = e->y();
0190 }
0191 
0192 void PVPlotWidget::mouseReleaseEvent(QMouseEvent *)
0193 {
0194     mouseButtonDown = false;
0195     update();
0196 }
0197 
0198 void PVPlotWidget::mouseMoveEvent(QMouseEvent *e)
0199 {
0200     if (mouseButtonDown)
0201     {
0202         //Determine how far we've moved
0203         double xc     = (dataRect().right() + dataRect().x()) * 0.5;
0204         double yc     = (dataRect().bottom() + dataRect().y()) * 0.5;
0205         double xscale = dataRect().width() / (width() - leftPadding() - rightPadding());
0206         double yscale = dataRect().height() / (height() - topPadding() - bottomPadding());
0207 
0208         xc += (oldx - e->x()) * xscale;
0209         yc -= (oldy - e->y()) * yscale; //Y data axis is reversed...
0210 
0211         if (xc > -AUMAX && xc < AUMAX && yc > -AUMAX && yc < AUMAX)
0212         {
0213             setLimits(xc - 0.5 * dataRect().width(), xc + 0.5 * dataRect().width(), yc - 0.5 * dataRect().height(),
0214                       yc + 0.5 * dataRect().height());
0215             update();
0216             qApp->processEvents();
0217         }
0218 
0219         oldx = e->x();
0220         oldy = e->y();
0221     }
0222 }
0223 
0224 void PVPlotWidget::mouseDoubleClickEvent(QMouseEvent *e)
0225 {
0226     double xscale = dataRect().width() / (width() - leftPadding() - rightPadding());
0227     double yscale = dataRect().height() / (height() - topPadding() - bottomPadding());
0228 
0229     double xc = dataRect().x() + xscale * (e->x() - leftPadding());
0230     double yc = dataRect().bottom() - yscale * (e->y() - topPadding());
0231 
0232     if (xc > -AUMAX && xc < AUMAX && yc > -AUMAX && yc < AUMAX)
0233     {
0234         setLimits(xc - 0.5 * dataRect().width(), xc + 0.5 * dataRect().width(), yc - 0.5 * dataRect().height(),
0235                   yc + 0.5 * dataRect().height());
0236         update();
0237     }
0238 
0239     pv->setCenterPlanet(QString());
0240     for (unsigned int i = 0; i < 9; ++i)
0241     {
0242         KPlotPoint *point = pv->planetObject(i)->points().at(0);
0243         double dx         = (point->x() - xc) / xscale;
0244         if (dx < 4.0)
0245         {
0246             double dy = (point->y() - yc) / yscale;
0247             if (sqrt(dx * dx + dy * dy) < 4.0)
0248             {
0249                 pv->setCenterPlanet(pv->planetName(i));
0250             }
0251         }
0252     }
0253 }
0254 
0255 void PVPlotWidget::wheelEvent(QWheelEvent *e)
0256 {
0257     updateFactor(e->modifiers());
0258     if (e->angleDelta().y() > 0)
0259         slotZoomIn();
0260     else
0261         slotZoomOut();
0262 }
0263 
0264 void PVPlotWidget::slotZoomIn()
0265 {
0266     double size = dataRect().width();
0267     if (size > 0.8)
0268     {
0269         setLimits(dataRect().x() + factor * 0.01 * size, dataRect().right() - factor * 0.01 * size,
0270                   dataRect().y() + factor * 0.01 * size, dataRect().bottom() - factor * 0.01 * size);
0271         update();
0272     }
0273 }
0274 
0275 void PVPlotWidget::slotZoomOut()
0276 {
0277     double size = dataRect().width();
0278     if ((size) < 100.0)
0279     {
0280         setLimits(dataRect().x() - factor * 0.01 * size, dataRect().right() + factor * 0.01 * size,
0281                   dataRect().y() - factor * 0.01 * size, dataRect().bottom() + factor * 0.01 * size);
0282         update();
0283     }
0284 }
0285 
0286 void PVPlotWidget::updateFactor(const int modifier)
0287 {
0288     factor = (modifier & Qt::ControlModifier) ? 1 : 25;
0289 }