1 /*
2     SPDX-FileCopyrightText: 2007 Jason Harris <kstars@30doradus.org>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "trailobject.h"
8 
9 #include "kstarsdata.h"
10 #include "skymap.h"
11 #ifndef KSTARS_LITE
12 #include "kspopupmenu.h"
13 #endif
14 #include "skycomponents/skylabeler.h"
15 #include "skypainter.h"
16 #include "projections/projector.h"
17 #include "Options.h"
18 
19 #include <QPainter>
20 
21 #include <typeinfo>
22 
23 QSet<TrailObject *> TrailObject::trailObjects;
24 
TrailObject(int t,dms r,dms d,float m,const QString & n)25 TrailObject::TrailObject(int t, dms r, dms d, float m, const QString &n) : SkyObject(t, r, d, m, n)
26 {
27 }
28 
TrailObject(int t,double r,double d,float m,const QString & n)29 TrailObject::TrailObject(int t, double r, double d, float m, const QString &n) : SkyObject(t, r, d, m, n)
30 {
31 }
32 
~TrailObject()33 TrailObject::~TrailObject()
34 {
35     trailObjects.remove(this);
36 }
37 
clone() const38 TrailObject *TrailObject::clone() const
39 {
40     Q_ASSERT(typeid(this) ==
41              typeid(static_cast<const TrailObject *>(this))); // Ensure we are not slicing a derived class
42     return new TrailObject(*this);
43 }
44 
updateTrail(dms * LST,const dms * lat)45 void TrailObject::updateTrail(dms *LST, const dms *lat)
46 {
47     for (auto & item : Trail)
48         item.EquatorialToHorizontal(LST, lat);
49 }
50 
initPopupMenu(KSPopupMenu * pmenu)51 void TrailObject::initPopupMenu(KSPopupMenu *pmenu)
52 {
53 #ifndef KSTARS_LITE
54     pmenu->createPlanetMenu(this);
55 #else
56     Q_UNUSED(pmenu);
57 #endif
58 }
59 
addToTrail(const QString & label)60 void TrailObject::addToTrail(const QString &label)
61 {
62     Trail.append(SkyPoint(*this));
63     m_TrailLabels.append(label);
64     trailObjects.insert(this);
65 }
66 
clipTrail()67 void TrailObject::clipTrail()
68 {
69     if (Trail.size())
70     {
71         Trail.removeFirst();
72         Q_ASSERT(m_TrailLabels.size());
73         m_TrailLabels.removeFirst();
74     }
75     if (Trail.size()) // Eh? Shouldn't this be if( !Trail.size() ) -- asimha
76         trailObjects.remove(this);
77 }
78 
clearTrail()79 void TrailObject::clearTrail()
80 {
81     Trail.clear();
82     m_TrailLabels.clear();
83     trailObjects.remove(this);
84 }
85 
clearTrailsExcept(SkyObject * o)86 void TrailObject::clearTrailsExcept(SkyObject *o)
87 {
88     TrailObject *keep = nullptr;
89     foreach (TrailObject *tr, trailObjects)
90     {
91         if (tr != o)
92             tr->clearTrail();
93         else
94             keep = tr;
95     }
96 
97     trailObjects = QSet<TrailObject *>();
98     if (keep)
99         trailObjects.insert(keep);
100 }
101 
drawTrail(SkyPainter * skyp) const102 void TrailObject::drawTrail(SkyPainter *skyp) const
103 {
104     Q_UNUSED(skyp)
105 #ifndef KSTARS_LITE
106     if (!Trail.size())
107         return;
108 
109     KStarsData *data = KStarsData::Instance();
110 
111     QColor tcolor = QColor(data->colorScheme()->colorNamed("PlanetTrailColor"));
112     skyp->setPen(QPen(tcolor, 1));
113     SkyLabeler *labeler = SkyLabeler::Instance();
114     labeler->setPen(tcolor);
115     int n = Trail.size();
116     for (int i = 1; i < n; ++i)
117     {
118         if (Options::fadePlanetTrails())
119         {
120             tcolor.setAlphaF(static_cast<qreal>(i) / static_cast<qreal>(n));
121             skyp->setPen(QPen(tcolor, 1));
122         }
123         SkyPoint a = Trail[i - 1];
124         SkyPoint b = Trail[i];
125         skyp->drawSkyLine(&a, &b);
126         if (i % 5 == 1) // TODO: Make drawing of labels configurable, incl. frequency etc.
127         {
128             QPointF pt = SkyMap::Instance()->projector()->toScreen(&a);
129             labeler->drawGuideLabel(pt, m_TrailLabels[i - 1], 0.0);
130         }
131     }
132 #endif
133 }
134