Kstars

avtplotwidget.cpp
1/*
2 SPDX-FileCopyrightText: 2007 Jason Harris <kstars@30doradus.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "avtplotwidget.h"
8
9#include "kstarsdata.h"
10#include "Options.h"
11
12#include <QWidget>
13#include <QMouseEvent>
14#include <QPainter>
15#include <QTime>
16#include <QLinearGradient>
17
18#include <KLocalizedString>
19#include <KPlotting/KPlotObject>
20#include <QDebug>
21
22AVTPlotWidget::AVTPlotWidget(QWidget *parent) : KPlotWidget(parent)
23{
24 setAntialiasing(true);
25
26 MousePoint = QPoint(-1, -1);
27}
28
33
35{
36 MousePoint = QPoint(-1, -1);
37 update();
38}
39
41{
43 int Xcursor = e->x();
44 int Ycursor = e->y();
45
46 if (!checkRect.contains(e->x(), e->y()))
47 {
48 if (e->x() < checkRect.left())
49 Xcursor = checkRect.left();
50 if (e->x() > checkRect.right())
51 Xcursor = checkRect.right();
52 if (e->y() < checkRect.top())
53 Ycursor = checkRect.top();
54 if (e->y() > checkRect.bottom())
55 Ycursor = checkRect.bottom();
56 }
57
60
61 MousePoint = QPoint(Xcursor, Ycursor);
62 update();
63}
64
66{
67 Q_UNUSED(e)
68
69 QPainter p;
70
71 p.begin(this);
75
76 setPixRect();
78 p.setClipping(true);
79
80 int pW = pixRect().width();
81 int pH = pixRect().height();
82
83 QColor SkyColor(0, 100, 200);
84 /*
85 if (Options::darkAppColors())
86 SkyColor = QColor(200, 0, 0); // use something red, visible through a red filter
87 */
88
89 // Draw gradient representing lunar interference in the sky
90 if (MoonIllum > 0.01) // do this only if Moon illumination is reasonable so it's important
91 {
92 int moonrise = int(pW * (0.5 + MoonRise));
93 int moonset = int(pW * (MoonSet - 0.5));
94 if (moonset < 0)
95 moonset += pW;
96 if (moonrise > pW)
97 moonrise -= pW;
98 int moonalpha = int(10 + MoonIllum * 130);
99 int fadewidth =
100 pW *
101 0.01; // pW * fraction of day to fade the moon brightness over (0.01 corresponds to roughly 15 minutes, 0.007 to 10 minutes), both before and after actual set.
102 QColor MoonColor(255, 255, 255, moonalpha);
103
104 if (moonset < moonrise)
105 {
108 grad.setColorAt(0, MoonColor);
109 grad.setColorAt(1, Qt::transparent);
110 p.fillRect(QRectF(0.0, 0.0, moonset + fadewidth, pH),
111 grad); // gradient should be padded until moonset - fadewidth (see QLinearGradient docs)
112 grad.setStart(QPointF(moonrise + fadewidth, 0.0));
113 grad.setFinalStop(QPointF(moonrise - fadewidth, 0.0));
115 }
116 else
117 {
121 grad.setColorAt(0, MoonColor);
122 grad.setColorAt(1, Qt::transparent);
123 p.fillRect(QRectF(0.0, 0.0, moonrise + fadewidth, pH), grad);
124 grad.setStart(QPointF(moonset - fadewidth, 0.0));
125 grad.setFinalStop(QPointF(moonset + fadewidth, 0.0));
127 }
128 }
129 //draw daytime sky if the Sun rises for the current date/location
130 if (SunMaxAlt > -18.0)
131 {
132 //Display centered on midnight, so need to modulate dawn/dusk by 0.5
133 int rise = int(pW * (0.5 + SunRise));
134 int set = int(pW * (SunSet - 0.5));
135 int da = int(pW * (0.5 + Dawn));
136 int du = int(pW * (Dusk - 0.5));
137
138 if (SunMinAlt > 0.0)
139 {
140 // The sun never set and the sky is always blue
141 p.fillRect(rect(), SkyColor);
142 }
143 else if (SunMaxAlt < 0.0 && SunMinAlt < -18.0)
144 {
145 // The sun never rise but the sky is not completely dark
147
149 gradStartColor.setAlpha((1 - (SunMaxAlt / -18.0)) * 255);
150
151 grad.setColorAt(0, gradStartColor);
152 grad.setColorAt(1, Qt::transparent);
153 p.fillRect(QRectF(0.0, 0.0, du, pH), grad);
154 grad.setStart(QPointF(pW, 0.0));
155 grad.setFinalStop(QPointF(da, 0.0));
156 p.fillRect(QRectF(da, 0.0, pW, pH), grad);
157 }
158 else if (SunMaxAlt < 0.0 && SunMinAlt > -18.0)
159 {
160 // The sun never rise but the sky is NEVER completely dark
162
164 gradStartEndColor.setAlpha((1 - (SunMaxAlt / -18.0)) * 255);
166 gradMidColor.setAlpha((1 - (SunMinAlt / -18.0)) * 255);
167
168 grad.setColorAt(0, gradStartEndColor);
169 grad.setColorAt(0.5, gradMidColor);
170 grad.setColorAt(1, gradStartEndColor);
171 p.fillRect(QRectF(0.0, 0.0, pW, pH), grad);
172 }
173 else if (Dawn < 0.0)
174 {
175 // The sun sets and rises but the sky is never completely dark
176 p.fillRect(0, 0, set, int(0.5 * pH), SkyColor);
177 p.fillRect(rise, 0, pW, int(0.5 * pH), SkyColor);
178
180
182 gradMidColor.setAlpha((1 - (SunMinAlt / -18.0)) * 255);
183
184 grad.setColorAt(0, SkyColor);
185 grad.setColorAt(0.5, gradMidColor);
186 grad.setColorAt(1, SkyColor);
187 p.fillRect(QRectF(set, 0.0, rise - set, pH), grad);
188 }
189 else
190 {
191 p.fillRect(0, 0, set, pH, SkyColor);
192 p.fillRect(rise, 0, pW, pH, SkyColor);
193
195 grad.setColorAt(0, SkyColor);
196 grad.setColorAt(
197 1,
198 Qt::transparent); // FIXME?: The sky appears black well before the actual end of twilight if the gradient is too slow (eg: latitudes above arctic circle)
199 p.fillRect(QRectF(set, 0.0, du - set, pH), grad);
200
201 grad.setStart(QPointF(rise, 0.0));
202 grad.setFinalStop(QPointF(da, 0.0));
203 p.fillRect(QRectF(da, 0.0, rise - da, pH), grad);
204 }
205 }
206
207 //draw ground
208 p.fillRect(0, int(0.5 * pH), pW, int(0.5 * pH),
209 KStarsData::Instance()->colorScheme()->colorNamed(
210 "HorzColor")); // asimha changed to use color from scheme. Formerly was QColor( "#002200" )
211
212 foreach (KPlotObject *po, plotObjects())
213 {
214 po->draw(&p, this);
215 }
216
217 p.setClipping(false);
218 drawAxes(&p);
219
220 //Add vertical line indicating "now"
221 QFont smallFont = p.font();
222 smallFont.setPointSize(smallFont.pointSize()); // wat?
223 if (geo)
224 {
226 .time(); // convert the current system clock time to the TZ corresponding to geo
227 double x = 12.0 + t.hour() + t.minute() / 60.0 + t.second() / 3600.0;
228 while (x > 24.0)
229 x -= 24.0;
230 int ix = int(x * pW / 24.0); //convert to screen pixel coords
231 p.setPen(QPen(QBrush("white"), 2.0, Qt::DotLine));
232 p.drawLine(ix, 0, ix, pH);
233
234 //Label this vertical line with the current time
235 p.save();
236 p.setFont(smallFont);
237 p.translate(ix + 10, pH - 20);
238 p.rotate(-90);
239 p.drawText(
240 0, 0,
241 QLocale().toString(t, QLocale::ShortFormat)); // short format necessary to avoid false time-zone labeling
242 p.restore();
243 }
244
245 //Draw crosshairs at clicked position
246 if (MousePoint.x() > 0)
247 {
248 p.setPen(QPen(QBrush("gold"), 1.0, Qt::SolidLine));
249 p.drawLine(QLineF(MousePoint.x() + 0.5, 0.5, MousePoint.x() + 0.5, pixRect().height() - 0.5));
250 p.drawLine(QLineF(0.5, MousePoint.y() + 0.5, pixRect().width() - 0.5, MousePoint.y() + 0.5));
251
252 //Label each crosshair line (time and altitude)
253 p.setFont(smallFont);
254 double a = (pH - MousePoint.y()) * 180.0 / pH - 90.0;
255 p.drawText(20, MousePoint.y() + 10, QString::number(a, 'f', 2) + QChar(176));
256
257 double h = MousePoint.x() * 24.0 / pW - 12.0;
258 if (h < 0.0)
259 h += 24.0;
260 QTime t = QTime(int(h), int(60. * (h - int(h))));
261 p.save();
262 p.translate(MousePoint.x() + 10, pH - 20);
263 p.rotate(-90);
264 p.drawText(
265 0, 0,
266 QLocale().toString(t, QLocale::ShortFormat)); // short format necessary to avoid false time-zone labeling
267 p.restore();
268 }
269
270 p.end();
271}
272
273void AVTPlotWidget::setDawnDuskTimes(double da, double du)
274{
275 Dawn = da;
276 Dusk = du;
277 update(); // fixme: should we always be calling update? It's probably cheap enough that we can.
278}
279
280void AVTPlotWidget::setMinMaxSunAlt(double min, double max)
281{
282 SunMinAlt = min;
283 SunMaxAlt = max;
284 update();
285}
286
288{
289 SunRise = sr;
290 SunSet = ss;
291 update();
292}
293
295{
296 MoonRise = mr;
297 MoonSet = ms;
298 update();
299}
300
302{
303 MoonIllum = mi;
304 update();
305}
void setSunRiseSetTimes(double sr, double ss)
Set the fractional positions of the Sunrise and Sunset positions, in units where last midnight was 0....
void setMoonRiseSetTimes(double mr, double ms)
Set the fractional positions of moonrise and moon set in units where last midnight was 0....
void paintEvent(QPaintEvent *e) override
Redraw the plot.
void mouseDoubleClickEvent(QMouseEvent *e) override
Reset the MousePoint to a null value, to erase the crosshairs.
void setMoonIllum(double mi)
Set the moon illumination.
void mousePressEvent(QMouseEvent *e) override
Simply calls mouseMoveEvent().
void mouseMoveEvent(QMouseEvent *e) override
Handle mouse move events.
QList< KPlotObject * > plotObjects() const
void setPixRect()
int leftPadding() const
int topPadding() const
virtual void drawAxes(QPainter *p)
QRect pixRect() const
QColor backgroundColor() const
bool antialiasing() const
static KStarsDateTime currentDateTimeUtc()
int pointSize() const const
void setPointSize(int pointSize)
int x() const const
int y() const const
bool begin(QPaintDevice *device)
void drawLine(const QLine &line)
void drawText(const QPoint &position, const QString &text)
bool end()
void fillRect(const QRect &rectangle, QGradient::Preset preset)
const QFont & font() const const
void restore()
void rotate(qreal angle)
void save()
void setClipRect(const QRect &rectangle, Qt::ClipOperation operation)
void setClipping(bool enable)
void setFont(const QFont &font)
void setPen(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
void translate(const QPoint &offset)
int x() const const
int y() const const
int height() const const
int width() const const
QString number(double n, char format, int precision)
transparent
int hour() const const
int minute() const const
int second() const const
void update()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:04 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.