File indexing completed on 2024-06-16 06:48:05

0001 /*
0002     SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "config-kstars.h"
0010 
0011 #include "skymapdrawabstract.h"
0012 #include "printing/legend.h"
0013 #include "skyobjects/skypoint.h"
0014 #include "skyobjects/skyline.h"
0015 #include "nan.h"
0016 
0017 #include <QGraphicsView>
0018 #include <QtGlobal>
0019 #include <QTimer>
0020 
0021 class QPainter;
0022 class QPaintDevice;
0023 
0024 class dms;
0025 class InfoBoxes;
0026 class InfoBoxWidget;
0027 class KSPopupMenu;
0028 class KStarsData;
0029 class Projector;
0030 class SkyObject;
0031 
0032 #ifdef HAVE_OPENGL
0033 class SkyMapGLDraw;
0034 class SkyMapQDraw;
0035 #endif
0036 
0037 /**
0038  * @class SkyMap
0039  *
0040  * This is the canvas on which the sky is painted.  It's the main widget for KStars.
0041  * Contains SkyPoint members for the map's Focus (current central position), Destination
0042  * (requested central position), FocusPoint (next queued position to be focused),
0043  * MousePoint (position of mouse cursor), and ClickedPoint (position of last mouse click).
0044  * Also contains the InfoBoxes for on-screen data display.
0045  *
0046  * SkyMap handles most user interaction events (both mouse and keyboard).
0047  *
0048  * @short Canvas widget for displaying the sky bitmap; also handles user interaction events.
0049  *
0050  * @author Jason Harris
0051  * @version 1.0
0052  */
0053 class SkyMap : public QGraphicsView
0054 {
0055         Q_OBJECT
0056 
0057         friend class SkyMapDrawAbstract; // FIXME: SkyMapDrawAbstract requires a lot of access to SkyMap
0058         friend class SkyMapQDraw;        // FIXME: SkyMapQDraw requires access to computeSkymap
0059 
0060     protected:
0061         /**
0062             *Constructor.  Read stored settings from KConfig object (focus position,
0063             *zoom factor, sky color, etc.).  Run initPopupMenus().
0064             */
0065         SkyMap();
0066 
0067     public:
0068         static SkyMap *Create();
0069 
0070         static SkyMap *Instance();
0071 
0072         static bool IsFocused()
0073         {
0074             //return (pinstance->focusObject() || pinstance->focusPoint());
0075             return (pinstance->focusObject());
0076         }
0077 
0078         static bool IsSlewing()
0079         {
0080             return pinstance->isSlewing();
0081         }
0082 
0083         /** Destructor (empty) */
0084         ~SkyMap() override;
0085 
0086         enum Projection
0087         {
0088             Lambert,
0089             AzimuthalEquidistant,
0090             Orthographic,
0091             Equirectangular,
0092             Stereographic,
0093             Gnomonic,
0094             UnknownProjection
0095         };
0096 
0097         enum Cursor
0098         {
0099             NoCursor,
0100             Cross,
0101             Circle,
0102         };
0103 
0104         /** @return the angular field of view of the sky map, in degrees.
0105             *@note it must use either the height or the width of the window to calculate the
0106             *FOV angle.  It chooses whichever is larger.
0107             */
0108         float fov();
0109 
0110         /** @short Update object name and coordinates in the Focus InfoBox */
0111         void showFocusCoords();
0112 
0113         /** @brief Update info boxes coordinates */
0114         void updateInfoBoxes();
0115 
0116         /** @short Update the focus position according to current options. */
0117         void updateFocus();
0118 
0119         /** @short Retrieve the Focus point; the position on the sky at the
0120                 *center of the skymap.
0121                 *@return a pointer to the central focus point of the sky map
0122                 */
0123         SkyPoint *focus()
0124         {
0125             return &Focus;
0126         }
0127 
0128         /** @short retrieve the Destination position.
0129                 *
0130                 *The Destination is the point on the sky to which the focus will
0131                 *be moved.
0132                 *
0133                 *@return a pointer to the destination point of the sky map
0134                 */
0135         SkyPoint *destination()
0136         {
0137             return &Destination;
0138         }
0139 
0140         /** @short retrieve the FocusPoint position.
0141                 *
0142                 *The FocusPoint stores the position on the sky that is to be
0143                 *focused next.  This is not exactly the same as the Destination
0144                 *point, because when the Destination is set, it will begin slewing
0145                 *immediately.
0146                 *
0147                 *@return a pointer to the sky point which is to be focused next.
0148                 */
0149         SkyPoint *focusPoint()
0150         {
0151             return &FocusPoint;
0152         }
0153 
0154         /** @short sets the central focus point of the sky map.
0155                 *@param f a pointer to the SkyPoint the map should be centered on
0156                 */
0157         void setFocus(SkyPoint *f);
0158 
0159         /** @short sets the focus point of the skymap, using ra/dec coordinates
0160                 *
0161                 *@note This function behaves essentially like the above function.
0162                 *It differs only in the data types of its arguments.
0163                 *
0164                 *@param ra the new right ascension
0165                 *@param dec the new declination
0166                 */
0167         void setFocus(const dms &ra, const dms &dec);
0168 
0169         /** @short sets the focus point of the sky map, using its alt/az coordinates
0170                 *@param alt the new altitude (actual, without refraction correction)
0171                 *@param az the new azimuth
0172                 */
0173         void setFocusAltAz(const dms &alt, const dms &az);
0174 
0175         /** @short sets the destination point of the sky map.
0176                 *@note setDestination() emits the destinationChanged() SIGNAL,
0177                 *which triggers the SLOT function SkyMap::slewFocus().  This
0178                 *function iteratively steps the Focus point toward Destination,
0179                 *repainting the sky at each step (if Options::useAnimatedSlewing()==true).
0180                 *@param f a pointer to the SkyPoint the map should slew to
0181                 */
0182         void setDestination(const SkyPoint &f);
0183 
0184         /** @short sets the destination point of the skymap, using ra/dec coordinates.
0185                 *
0186                 *@note This function behaves essentially like the above function.
0187                 *It differs only in the data types of its arguments.
0188                 *
0189                 *@param ra the new right ascension
0190                 *@param dec the new declination
0191                 */
0192         void setDestination(const dms &ra, const dms &dec);
0193 
0194         /** @short sets the destination point of the sky map, using its alt/az coordinates.
0195                 *@param alt the new altitude
0196                 *@param az the new azimuth
0197                 *@param altIsRefracted set to true if the altitude supplied is apparent
0198                 */
0199         void setDestinationAltAz(const dms &alt, const dms &az, bool altIsRefracted);
0200 
0201         /** @short set the FocusPoint; the position that is to be the next Destination.
0202                 *@param f a pointer to the FocusPoint SkyPoint.
0203                 */
0204         void setFocusPoint(SkyPoint *f)
0205         {
0206             if (f)
0207                 FocusPoint = *f;
0208         }
0209 
0210         /** @short Retrieve the ClickedPoint position.
0211                 *
0212                 *When the user clicks on a point in the sky map, the sky coordinates of the mouse
0213                 *cursor are stored in the private member ClickedPoint.  This function retrieves
0214                 *a pointer to ClickedPoint.
0215                 *@return a pointer to ClickedPoint, the sky coordinates where the user clicked.
0216                 */
0217         SkyPoint *clickedPoint()
0218         {
0219             return &ClickedPoint;
0220         }
0221 
0222         /**
0223          * @short Retrieve the mouse pointer position.
0224          *
0225          * @return The sky coordinates where the mouse pointer is over.
0226          */
0227         SkyPoint *mousePoint()
0228         {
0229             return &m_MousePoint;
0230         }
0231 
0232         /** @short Set the ClickedPoint to the skypoint given as an argument.
0233                 *@param f pointer to the new ClickedPoint.
0234                 */
0235         void setClickedPoint(const SkyPoint *f);
0236 
0237         /** @short Retrieve the object nearest to a mouse click event.
0238                 *
0239                 *If the user clicks on the sky map, a pointer to the nearest SkyObject is stored in
0240                 *the private member ClickedObject.  This function returns the ClickedObject pointer,
0241                 *or nullptr if there is no CLickedObject.
0242                 *@return a pointer to the object nearest to a user mouse click.
0243                 */
0244         SkyObject *clickedObject() const
0245         {
0246             return ClickedObject;
0247         }
0248 
0249         /** @short Set the ClickedObject pointer to the argument.
0250                 *@param o pointer to the SkyObject to be assigned as the ClickedObject
0251                 */
0252         void setClickedObject(SkyObject *o);
0253 
0254         /** @short Retrieve the object which is centered in the sky map.
0255                 *
0256                 *If the user centers the sky map on an object (by double-clicking or using the
0257                 *Find Object dialog), a pointer to the "focused" object is stored in
0258                 *the private member FocusObject.  This function returns a pointer to the
0259                 *FocusObject, or nullptr if there is not FocusObject.
0260                 *@return a pointer to the object at the center of the sky map.
0261                 */
0262         SkyObject *focusObject() const
0263         {
0264             return FocusObject;
0265         }
0266 
0267         /** @short Set the FocusObject pointer to the argument.
0268                 *@param o pointer to the SkyObject to be assigned as the FocusObject
0269                 */
0270         void setFocusObject(SkyObject *o);
0271 
0272         /** @short Call to set up the projector before a draw cycle. */
0273         void setupProjector();
0274 
0275         /** @ Set zoom factor.
0276               *@param factor zoom factor
0277               */
0278         void setZoomFactor(double factor);
0279 
0280         bool isSlewing() const;
0281 
0282         // NOTE: This method is draw-backend independent.
0283         /** @short update the geometry of the angle ruler. */
0284         void updateAngleRuler();
0285 
0286         /** @return true if the object currently has a user label attached.
0287                 *@note this function only checks for a label explicitly added to the object
0288                 *with the right-click popup menu; other kinds of labels are not detected by
0289                 *this function.
0290                 *@param o pointer to the sky object to be tested for a User label.
0291                 */
0292         bool isObjectLabeled(SkyObject *o);
0293 
0294         /*@*@short Convenience function for shutting off tracking mode.  Just calls KStars::slotTrack().
0295                 */
0296         void stopTracking();
0297 
0298         /** Get the current projector.
0299                 @return a pointer to the current projector. */
0300         inline const Projector *projector() const
0301         {
0302             return m_proj;
0303         }
0304 
0305         // NOTE: These dynamic casts must not segfault. If they do, it's good because we know that there is a problem.
0306         /**
0307              *@short Proxy method for SkyMapDrawAbstract::exportSkyImage()
0308              */
0309         inline void exportSkyImage(QPaintDevice *pd, bool scale = false)
0310         {
0311             dynamic_cast<SkyMapDrawAbstract *>(m_SkyMapDraw)->exportSkyImage(pd, scale);
0312         }
0313 
0314         inline void exportSkyImage(SkyQPainter *painter, bool scale = false)
0315         {
0316             dynamic_cast<SkyMapDrawAbstract *>(m_SkyMapDraw)->exportSkyImage(painter, scale);
0317         }
0318 
0319         SkyMapDrawAbstract *getSkyMapDrawAbstract()
0320         {
0321             return dynamic_cast<SkyMapDrawAbstract *>(m_SkyMapDraw);
0322         }
0323 
0324         /**
0325              *@short Proxy method for SkyMapDrawAbstract::drawObjectLabels()
0326              */
0327         inline void drawObjectLabels(QList<SkyObject *> &labelObjects)
0328         {
0329             dynamic_cast<SkyMapDrawAbstract *>(m_SkyMapDraw)->drawObjectLabels(labelObjects);
0330         }
0331 
0332         void setPreviewLegend(bool preview)
0333         {
0334             m_previewLegend = preview;
0335         }
0336 
0337         void setLegend(const Legend &legend)
0338         {
0339             m_legend = legend;
0340         }
0341 
0342         bool isInObjectPointingMode() const
0343         {
0344             return m_objPointingMode;
0345         }
0346 
0347         void setObjectPointingMode(bool enabled)
0348         {
0349             m_objPointingMode = enabled;
0350         }
0351 
0352         void setFovCaptureMode(bool enabled)
0353         {
0354             m_fovCaptureMode = enabled;
0355         }
0356 
0357         bool isInFovCaptureMode() const
0358         {
0359             return m_fovCaptureMode;
0360         }
0361 
0362         /** @short Sets the shape of the default mouse cursor. */
0363         void setMouseCursorShape(Cursor type);
0364 
0365         SkyPoint getCenterPoint();
0366 
0367     public slots:
0368         /** Recalculates the positions of objects in the sky, and then repaints the sky map.
0369              * If the positions don't need to be recalculated, use update() instead of forceUpdate().
0370              * This saves a lot of CPU time.
0371              * @param now if true, paintEvent() is run immediately.  Otherwise, it is added to the event queue
0372              */
0373         void forceUpdate(bool now = false);
0374 
0375         /** @short Convenience function; simply calls forceUpdate(true).
0376              * @see forceUpdate()
0377              */
0378         void forceUpdateNow()
0379         {
0380             forceUpdate(true);
0381         }
0382 
0383         /**
0384              * @short Update the focus point and call forceUpdate()
0385              * @param now is passed on to forceUpdate()
0386              */
0387         void slotUpdateSky(bool now);
0388 
0389         /** Toggle visibility of geo infobox */
0390         void slotToggleGeoBox(bool);
0391 
0392         /** Toggle visibility of focus infobox */
0393         void slotToggleFocusBox(bool);
0394 
0395         /** Toggle visibility of time infobox */
0396         void slotToggleTimeBox(bool);
0397 
0398         /** Toggle visibility of all infoboxes */
0399         void slotToggleInfoboxes(bool);
0400 
0401         /** Sets the base sky rotation (before correction) to the given angle */
0402         void slotSetSkyRotation(double angle);
0403 
0404         /** Step the Focus point toward the Destination point.  Do this iteratively, redrawing the Sky
0405              * Map after each step, until the Focus point is within 1 step of the Destination point.
0406              * For the final step, snap directly to Destination, and redraw the map.
0407              */
0408         void slewFocus();
0409 
0410         /** @short Center the display at the point ClickedPoint.
0411              *
0412              * The essential part of the function is to simply set the Destination point, which will emit
0413              * the destinationChanged() SIGNAL, which triggers the slewFocus() SLOT.  Additionally, this
0414              * function performs some bookkeeping tasks, such updating whether we are tracking the new
0415              * object/position, adding a Planet Trail if required, etc.
0416              *
0417              * @see destinationChanged()
0418              * @see slewFocus()
0419              */
0420         void slotCenter();
0421 
0422         /** @short Popup menu function: Display 1st-Generation DSS image with the Image Viewer.
0423              * @note the URL is generated using the coordinates of ClickedPoint.
0424              */
0425         void slotDSS();
0426 
0427         /** @short Popup menu function: Display Sloan Digital Sky Survey image with the Image Viewer.
0428              * @note the URL is generated using the coordinates of ClickedPoint.
0429              */
0430         void slotSDSS();
0431 
0432         /**
0433          * @brief slotCopyCoordinates Copies J2000 and JNow equatorial coordinates to the clipboard in addition to horizontal coords.
0434          */
0435         void slotCopyCoordinates();
0436 
0437         /**
0438          * @brief slotCopyTLE Copy satellite TLE to clipboard.
0439          */
0440         void slotCopyTLE();
0441 
0442         /** @short Popup menu function: Show webpage about ClickedObject
0443              * (only available for some objects).
0444              */
0445         void slotInfo();
0446 
0447         /** @short Popup menu function: Show image of ClickedObject
0448              * (only available for some objects).
0449              */
0450         void slotImage();
0451 
0452         /** @short Popup menu function: Show the Detailed Information window for ClickedObject. */
0453         void slotDetail();
0454 
0455         /** Add ClickedObject to KStarsData::ObjLabelList, which stores pointers to SkyObjects which
0456              * have User Labels attached.
0457              */
0458         void slotAddObjectLabel();
0459 
0460         /** Remove ClickedObject from KStarsData::ObjLabelList, which stores pointers to SkyObjects which
0461              * have User Labels attached.
0462              */
0463         void slotRemoveObjectLabel();
0464 
0465         /** Remove custom object from internet search in the local catalog */
0466         void slotRemoveCustomObject();
0467 
0468         /** @short Add a Planet Trail to ClickedObject.
0469              * @note Trails are added simply by calling KSPlanetBase::addToTrail() to add the first point.
0470              * as long as the trail is not empty, new points will be automatically appended to it.
0471              * @note if ClickedObject is not a Solar System body, this function does nothing.
0472              * @see KSPlanetBase::addToTrail()
0473              */
0474         void slotAddPlanetTrail();
0475 
0476         /** @short Remove the PlanetTrail from ClickedObject.
0477              * @note The Trail is removed by simply calling KSPlanetBase::clearTrail().  As long as
0478              * the trail is empty, no new points will be automatically appended.
0479              * @see KSPlanetBase::clearTrail()
0480              */
0481         void slotRemovePlanetTrail();
0482 
0483         /** Checks whether the timestep exceeds a threshold value.  If so, sets
0484              * ClockSlewing=true and sets the SimClock to ManualMode.
0485              */
0486         void slotClockSlewing();
0487 
0488         /** Enables the angular distance measuring mode. It saves the first
0489              * position of the ruler in a SkyPoint. It makes difference between
0490              * having clicked on the skymap and not having done so
0491              * \note This method is draw-backend independent.
0492             */
0493         void slotBeginAngularDistance();
0494 
0495         void slotBeginStarHop(); // TODO: Add docs
0496 
0497         /** Computes the angular distance, prints the result in the status
0498              * bar and disables the angular distance measuring mode
0499              * If the user has clicked on the map the status bar shows the
0500              * name of the clicked object plus the angular distance. If
0501              * the user did not clicked on the map, just pressed ], only
0502              * the angular distance is printed
0503              * \note This method is draw-backend independent.
0504             */
0505         void slotEndRulerMode();
0506 
0507         /** Disables the angular distance measuring mode. Nothing is printed
0508              * in the status bar */
0509         void slotCancelRulerMode();
0510 
0511         /** @short Open Flag Manager window with clickedObject() RA and Dec entered.
0512               */
0513         void slotAddFlag();
0514 
0515         /** @short Open Flag Manager window with selected flag focused and ready to edit.
0516               *@param flagIdx index of flag to be edited.
0517               */
0518         void slotEditFlag(int flagIdx);
0519 
0520         /** @short Delete selected flag.
0521               *@param flagIdx index of flag to be deleted.
0522               */
0523         void slotDeleteFlag(int flagIdx);
0524 
0525 #ifdef HAVE_OPENGL
0526         void slotToggleGL();
0527 #endif
0528 
0529         /** Run Xplanet Viewer to display images of the planets*/
0530         void slotStartXplanetViewer();
0531 
0532         /** Render eyepiece view */
0533         void slotEyepieceView();
0534 
0535         /** Zoom in one step. */
0536         void slotZoomIn();
0537 
0538         /** Zoom out one step. */
0539         void slotZoomOut();
0540 
0541         /** Set default zoom. */
0542         void slotZoomDefault();
0543 
0544         /** Object pointing for Printing Wizard done */
0545         void slotObjectSelected();
0546 
0547         void slotCancelLegendPreviewMode();
0548 
0549         void slotFinishFovCaptureMode();
0550 
0551         void slotCaptureFov();
0552 
0553     signals:
0554         /** Emitted by setDestination(), and connected to slewFocus().  Whenever the Destination
0555              * point is changed, slewFocus() will iteratively step the Focus toward Destination
0556              * until it is reached.
0557              * @see SkyMap::setDestination()
0558              * @see SkyMap::slewFocus()
0559              */
0560         void destinationChanged();
0561 
0562         /** Emitted when zoom level is changed. */
0563         void zoomChanged();
0564 
0565         /** Emitted when current object changed. */
0566         void objectChanged(SkyObject *);
0567 
0568         /** Emitted when pointing changed. (At least should) */
0569         void positionChanged(SkyPoint *);
0570 
0571         /** Emitted when position under mouse changed. */
0572         void mousePointChanged(SkyPoint *);
0573 
0574         /** Emitted when a position is clicked */
0575         void positionClicked(SkyPoint *);
0576 
0577         /** Emitted when a position is clicked */
0578         void objectClicked(SkyObject *);
0579 
0580         /** Emitted when a sky object is removed from the database */
0581         void removeSkyObject(SkyObject *object);
0582 
0583         /** Emitter when mosaic center is dragged in the sky map */
0584         void mosaicCenterChanged(dms dRA, dms dDE);
0585 
0586         void updateQueued();
0587 
0588     protected:
0589         bool event(QEvent *event) override;
0590 
0591         /** Process keystrokes:
0592              * @li arrow keys  Slew the map
0593              * @li +/- keys  Zoom in and out
0594              * @li <i>Space</i>  Toggle between Horizontal and Equatorial coordinate systems
0595              * @li 0-9  Go to a major Solar System body (0=Sun; 1-9 are the major planets, except 3=Moon)
0596              * @li [  Place starting point for measuring an angular distance
0597              * @li ]  End point for Angular Distance; display measurement.
0598              * @li <i>Escape</i>  Cancel Angular measurement
0599              * @li ,/<  Step backward one time step
0600              * @li ./>  Step forward one time step
0601              */
0602         void keyPressEvent(QKeyEvent *e) override;
0603 
0604         /** When keyRelease is triggered, just set the "slewing" flag to false,
0605              * and update the display (to draw objects that are hidden when slewing==true). */
0606         void keyReleaseEvent(QKeyEvent *e) override;
0607 
0608         /** Determine RA, Dec coordinates of clicked location.  Find the SkyObject
0609              * which is nearest to the clicked location.
0610              *
0611              * If left-clicked: Set set mouseButtonDown==true, slewing==true; display
0612              * nearest object name in status bar.
0613              * If right-clicked: display popup menu appropriate for nearest object.
0614              */
0615         void mousePressEvent(QMouseEvent *e) override;
0616 
0617         /** set mouseButtonDown==false, slewing==false */
0618         void mouseReleaseEvent(QMouseEvent *e) override;
0619 
0620         /** Center SkyMap at double-clicked location  */
0621         void mouseDoubleClickEvent(QMouseEvent *e) override;
0622 
0623         /** This function does several different things depending on the state of the program:
0624              * @li If Angle-measurement mode is active, update the end-ruler point to the mouse cursor,
0625              *     and continue this function.
0626              * @li If we are defining a ZoomBox, update the ZoomBox rectangle, redraw the screen,
0627              *     and return.
0628              * @li If dragging the mouse in the map, update focus such that RA, Dec under the mouse
0629              *     cursor remains constant.
0630              * @li If just moving the mouse, simply update the curso coordinates in the status bar.
0631              */
0632         void mouseMoveEvent(QMouseEvent *e) override;
0633 
0634         /** Zoom in and out with the mouse wheel. */
0635         void wheelEvent(QWheelEvent *e) override;
0636 
0637         /** If the skymap will be resized, the sky must be new computed. So this
0638              * function calls explicitly new computing of the skymap.
0639              */
0640         void resizeEvent(QResizeEvent *) override;
0641 
0642     private slots:
0643         /** @short display tooltip for object under cursor. It's called by m_HoverTimer.
0644              *  if mouse didn't moved for last HOVER_INTERVAL milliseconds.
0645              */
0646         void slotTransientLabel();
0647 
0648         /** Set the shape of mouse cursor to a cross with 4 arrows. */
0649         void setMouseMoveCursor();
0650 
0651         /** Set the shape of mouse cursor to an open hand. */
0652         void setMouseDragCursor();
0653 
0654     private:
0655 
0656         /** @short Sets the shape of the mouse cursor to a magnifying glass. */
0657         void setZoomMouseCursor();
0658 
0659         /** @short Sets the shape of the mouse cursor to a rotation symbol. */
0660         void setRotationMouseCursor();
0661 
0662         /** Calculate the zoom factor for the given keyboard modifier
0663              */
0664         double zoomFactor(const int modifier);
0665 
0666         /** calculate the magnitude factor (1, .5, .2, or .1) for the given
0667              * keyboard modifier.
0668              */
0669         double magFactor(const int modifier);
0670 
0671         /** Decrease the magnitude limit by a step size determined by the
0672              * keyboard modifier.
0673              * @param modifier
0674              */
0675         void decMagLimit(const int modifier);
0676 
0677         /** Increase the magnitude limit by a step size determined by the
0678             * keyboard modifier.
0679             * @param modifier
0680             */
0681         void incMagLimit(const int modifier);
0682 
0683         /** Convenience routine to either zoom in or increase mag limit
0684              * depending on the Alt modifier.  The Shift and Control modifiers
0685              * will adjust the size of the zoom or the mag step.
0686              * @param modifier
0687              */
0688         void zoomInOrMagStep(const int modifier);
0689 
0690         /** Convenience routine to either zoom out or decrease mag limit
0691              * depending on the Alt modifier.  The Shift and Control modifiers
0692              * will adjust the size of the zoom or the mag step.
0693              * @param modifier
0694              */
0695         void zoomOutOrMagStep(const int modifier);
0696 
0697         void beginRulerMode(bool starHopRuler); // TODO: Add docs
0698 
0699         /**
0700          * Determine the rotation angle of the SkyMap
0701          *
0702          * This is simply Options::skyRotation() if the erect observer
0703          * correction is not applicable, but otherwise it is
0704          * determined by adding a correction amount dependent on the
0705          * focus of the sky map
0706          */
0707         dms determineSkyRotation();
0708 
0709         /**
0710          * @short Strart xplanet.
0711          * @param outputFile Output file path.
0712          */
0713         void startXplanet(const QString &outputFile = "");
0714 
0715         bool mouseButtonDown { false };
0716         bool midMouseButtonDown { false };
0717         /// True if mouseMoveEvent; needed by setMouseMoveCursor
0718         bool mouseMoveCursor { false };
0719         bool mouseDragCursor { false };
0720         bool slewing { false };
0721         bool clockSlewing { false };
0722         //if false only old pixmap will repainted with bitBlt(), this
0723         // saves a lot of cpu usage
0724         bool computeSkymap { false };
0725         // True if we are either looking for angular distance or star hopping directions
0726         bool rulerMode { false };
0727         // True only if we are looking for star hopping directions. If
0728         // false while rulerMode is true, it means we are measuring angular
0729         // distance. FIXME: Find a better way to do this
0730         bool starHopDefineMode { false };
0731         double y0;
0732 
0733         QPoint rotationStart;
0734         dms rotationStartAngle;
0735 
0736         double m_Scale;
0737 
0738         KStarsData *data { nullptr };
0739         KSPopupMenu *pmenu { nullptr };
0740 
0741         /// Coordinates of point under cursor. It's update in function mouseMoveEvent
0742         SkyPoint m_MousePoint;
0743 
0744         SkyPoint Focus, ClickedPoint, FocusPoint, Destination;
0745         SkyObject *ClickedObject { nullptr };
0746         SkyObject *FocusObject { nullptr };
0747 
0748         Projector *m_proj { nullptr };
0749 
0750         SkyLine AngularRuler; //The line for measuring angles in the map
0751         QRect ZoomRect;       //The manual-focus circle.
0752 
0753         // Mouse should not move for that interval to display tooltip
0754         static const int HOVER_INTERVAL = 500;
0755         // Timer for tooltips
0756         QTimer m_HoverTimer;
0757 
0758         // InfoBoxes. Used in destructor to save state
0759         InfoBoxWidget *m_timeBox { nullptr };
0760         InfoBoxWidget *m_geoBox { nullptr };
0761         InfoBoxWidget *m_objBox { nullptr };
0762         InfoBoxes *m_iboxes { nullptr };
0763 
0764         // legend
0765         bool m_previewLegend { false };
0766         Legend m_legend;
0767 
0768         bool m_objPointingMode { false };
0769         bool m_fovCaptureMode { false };
0770         bool m_touchMode { false };
0771         bool m_pinchMode { false };
0772         bool m_tapAndHoldMode { false };
0773         qreal m_pinchScale { 0.0 };
0774 
0775         QWidget *m_SkyMapDraw { nullptr }; // Can be dynamic_cast<> to SkyMapDrawAbstract
0776 
0777         // NOTE: These are pointers to the individual widgets
0778 #ifdef HAVE_OPENGL
0779         SkyMapQDraw *m_SkyMapQDraw { nullptr };
0780         SkyMapGLDraw *m_SkyMapGLDraw { nullptr };
0781 #endif
0782 
0783         static SkyMap *pinstance;
0784         /// Good to keep the original ruler start-point for purposes of dynamic_cast
0785         const SkyPoint *m_rulerStartPoint { nullptr };
0786 };