1 /*
2     SPDX-FileCopyrightText: Thomas Kabelmann
3     SPDX-FileCopyrightText: 2018 Robert Lancaster <rlancaste@gmail.com>
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #pragma once
9 
10 #include "auxiliary/filedownloader.h"
11 
12 #include <QDialog>
13 #include <QLineEdit>
14 #include <QSpinBox>
15 #include "nonlineardoublespinbox.h"
16 #include <QComboBox>
17 #include <QFile>
18 #include <QFrame>
19 #include <QImage>
20 #include <QPixmap>
21 #include "kstarsdata.h"
22 #include <QEvent>
23 #include <QGestureEvent>
24 #include <QPinchGesture>
25 
26 class QLabel;
27 /**
28  * @class XPlanetImageLabel
29  * @short XPlanet Image viewer QFrame for the KPlanetImageViewer for KStars
30  * @author Thomas Kabelmann
31  * @author Jasem Mutlaq
32  * @author Robert Lancaster
33  * @version 1.1
34  *
35  * This image-viewer QFrame automatically resizes the picture.  It also receives input from the mouse to
36  * zoom and pan the XPlanet Image.
37  */
38 class XPlanetImageLabel : public QFrame
39 {
40     Q_OBJECT
41   public:
42     explicit XPlanetImageLabel(QWidget *parent);
43     ~XPlanetImageLabel() override = default;
44     void setImage(const QImage &img);
45     void invertPixels();
46     void refreshImage();
47 
48   public slots:
49     void wheelEvent(QWheelEvent *e) override;
50     void mousePressEvent(QMouseEvent *e) override;
51     void mouseReleaseEvent(QMouseEvent *e) override;
52     void mouseMoveEvent(QMouseEvent *e) override;
53 
54   signals:
55     void zoomIn();
56     void zoomOut();
57     void changePosition(QPoint);
58     void changeLocation(QPoint);
59 
60   protected:
61     void paintEvent(QPaintEvent *e) override;
62     void resizeEvent(QResizeEvent *) override;
63 
64   private:
65     //Image related
66     QPixmap m_Pix;
67     QImage m_Image;
68 
69     //Mouse related
70     bool m_MouseButtonDown = false;
71     QPoint m_LastMousePoint;
72     bool event(QEvent *event) override;
73     bool gestureEvent(QGestureEvent *event);
74     void pinchTriggered(QPinchGesture *gesture);
75 };
76 
77 /**
78  * @class XPlanetImageViewer
79  * @short XPlanet Image viewer window for KStars
80  * @author Thomas Kabelmann
81  * @author Jasem Mutlaq
82  * @author Robert Lancaster
83  * @version 1.1
84  *
85  * This class is meant to interact with XPlanet and display the results.  It has interfaces to control many of the XPlanet Options.
86  * It can change a number of properties using controls.  It works with the XPlanetImageLabel to display the results.  It also can work
87  * with the XPlanetImageLabel to respond to mouse inputs on the ImageLabel and act on them in the Image Viewer.  It has a hover mode where
88  * it hovers over the same planetary body or a remote mode where it views one body from another.  It has interfaces for changing the field of
89  * view, the time, the rotation, and other settings.  In hover mode, it can change latitude, longitude, and radius with the mouse inputs.
90  * It also can animate events so that you can watch xplanet frames like a movie to see solar system events in action.
91  */
92 class XPlanetImageViewer : public QDialog
93 {
94     Q_OBJECT
95 
96   public:
97     /** Create xplanet image viewer from Object */
98     explicit XPlanetImageViewer(const QString &obj, QWidget *parent = nullptr);
99 
100     /** Destructor. If there is a partially downloaded image file, delete it.*/
101     ~XPlanetImageViewer() override;
102 
103     /**
104      * @brief loadImage Load image and display it
105      * @return True if opened and displayed, false otherwise
106      */
107     bool loadImage();
108 
109     void startXplanet();
110 
111   private:
112 
113 
114     /** prepares the output file**/
115     bool setupOutputFile();
116 
117     QImage m_Image;
118 
119     /** Save the downloaded image to a local file. */
120     void saveFile(const QString & fileName);
121 
122     QFile m_File;
123 
124     XPlanetImageLabel *m_View { nullptr };
125     QLabel *m_Caption { nullptr };
126 
127     QString m_LastFile;
128 
129     QStringList m_ObjectNames;
130     QList<double> m_objectDefaultFOVs;
131 
132     typedef enum { YEARS, MONTHS, DAYS, HOURS, MINS, SECS } timeUnits;
133 
134     void setXPlanetDate(KStarsDateTime time);
135 
136     //XPlanet strings
137     QString m_ObjectName;
138     QString m_OriginName;
139     QString m_Date;
140     QString m_DateText;
141 
142     //XPlanet numbers
143     int m_CurrentObjectIndex { 0 };
144     int m_CurrentOriginIndex { 0 };
145     int m_Rotation { 0 };
146     int m_CurrentTimeUnitIndex { 0 };
147     uint32_t m_Radius { 0 };
148     double m_FOV { 0 };
149     double m_lat { 0 };
150     double m_lon { 0 };
151     QPoint center;
152 
153 #ifndef Q_OS_WIN
154     QFutureWatcher<bool> fifoImageLoadWatcher;
155     QTimer watcherTimeout;
156 #endif
157 
158     // Time
159     KStarsDateTime m_XPlanetTime {};
160     bool m_XPlanetRunning = false;
161 
162     QComboBox *m_OriginSelector {nullptr};
163 
164     // Field of view controls
165     QPushButton *m_KStarsFOV  {nullptr};
166     QPushButton *m_setFOV  {nullptr};
167     QPushButton *m_NoFOV  {nullptr};
168     NonLinearDoubleSpinBox *m_FOVEdit {nullptr};
169 
170     // Rotation controls
171     QSpinBox *m_RotateEdit {nullptr};
172 
173     // Free rotation controls
174     QLabel *m_PositionDisplay {nullptr};
175     QPushButton *m_FreeRotate {nullptr};
176     bool m_ImageLoadSucceeded = false;
177 
178     // Time controls
179     QLabel *m_XPlanetTimeDisplay {nullptr};
180     QSlider *m_TimeSlider {nullptr};
181     QSpinBox *m_TimeEdit {nullptr};
182     QComboBox *m_TimeUnitsSelect {nullptr};
183 
184     //Animation controls
185     QPushButton *m_RunTime {nullptr};
186     QTimer *m_XPlanetTimer {nullptr};
187 
188 
189   private slots:
190 
191     /**
192      * Display the downloaded image.  Resize the window to fit the image,  If the image is
193      * larger than the screen, make the image as large as possible while preserving the
194      * original aspect ratio
195      */
196     bool showImage();
197 
198     // Saves file to disk.
199     void saveFileToDisk();
200 
201     // Inverts colors
202     void invertColors();
203 
204     // Rotation slots
205     void updateXPlanetRotationEdit();
206     void resetXPlanetRotation();
207     void invertXPlanetRotation();
208 
209     void reCenterXPlanet();
210 
211     // Free Rotation slots
212     void changeXPlanetPosition(QPoint delta);
213     void changeXPlanetLocation(QPoint delta);
214     void slotFreeRotate();
215     void updateStates();
216     void updatePositionDisplay();
217     void resetLocation();
218 
219     // Field of View slots
220     void zoomInXPlanetFOV();
221     void zoomOutXPlanetFOV();
222     void updateXPlanetFOVEdit();
223     void resetXPlanetFOV();
224     void setKStarsXPlanetFOV();
225     void setFOVfromList();
226 
227     // Time slots
228     void updateXPlanetTime(int timeShift);
229     void updateXPlanetObject(int objectIndex);
230     void updateXPlanetOrigin(int originIndex);
231     void updateXPlanetTimeUnits(int units);
232     void updateXPlanetTimeEdit();
233     void setXPlanetTime();
234     void setXPlanetTimetoKStarsTime();
235     void resetXPlanetTime();
236 
237     // Animation slots
238     void incrementXPlanetTime();
239     void toggleXPlanetRun();
240     void timeSliderDisplay(int timeShift);
241 
242 };
243