1 /*
2     SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com>
3     SPDX-License-Identifier: GPL-2.0-or-later
4 */
5 
6 #pragma once
7 
8 #include "skylabeler.h"
9 #include "typedef.h"
10 #include "typedeflite.h"
11 
12 #include "skyopacitynode.h"
13 
14 class StarItem;
15 class LabelNode;
16 class GuideLabelNode;
17 class RootNode;
18 class TrixelNode;
19 
20 class SkyObject;
21 
22 typedef SkyOpacityNode LabelTypeNode;
23 
24 /**
25  * @class LabelsItem
26  *
27  * This class is in charge of labels in SkyMapLite. Labels can be instantiated by calling addLabel with
28  * either SkyObject or plain QString as a name. There are two types of label nodes available - LabelNode
29  * that can't be rotated and GuideLabelNode that supports rotation (but it is not used anywhere yet).
30  *
31  * To prevent labels from overlapping this class uses SkyLabeler. We check LabelNode for overlapping by
32  * calling SkyLabeler::markText() (SkyLabeler::markRegion() for GuideLabelNode) and update().
33  *
34  * Each of SkyItems that uses labels has its own label type in enum label_t (copied from SkyLabeler but
35  * was extended). Labels of particular type are reparented to LabelTypeNode(QSGOpacityNode) so
36  * to hide all labels of some type you just need to set opacity of LabelTypeNode that corresponds to
37  * this type to 0.
38  *
39  * Order of drawing can be changed in LabelsItem's constructor. Order of labels update can be changed in
40  * update().
41  *
42  * This class is not derived from SkyItem as it doesn't have label type and SkyItem's header needs an
43  * inclusion of this header to allow use of label_t enum. (Might be a good idea to fix this)
44  *
45  * @note font size is set in SkyLabeler::SkyLabeler() by initializing m_stdFont with default font
46  *
47  * @short Handles labels in SkyMapLite
48  * @author Artem Fedoskin
49  * @version 1.0
50  */
51 
52 class LabelsItem : public SkyOpacityNode
53 {
54   public:
55     /**
56      * @brief Constructor
57      */
58     LabelsItem();
59 
60     /** @short The label_t enum. Holds types of labels */
61     enum label_t
62     {
63         STAR_LABEL,
64         ASTEROID_LABEL,
65         COMET_LABEL,
66         PLANET_LABEL,
67         JUPITER_MOON_LABEL,
68         SATURN_MOON_LABEL,
69         DEEP_SKY_LABEL,
70         DSO_MESSIER_LABEL,
71         DSO_OTHER_LABEL,
72         CONSTEL_NAME_LABEL,
73         SATELLITE_LABEL,
74         RUDE_LABEL, ///Rude labels block other labels FIXME: find a better solution
75         NUM_LABEL_TYPES,
76         HORIZON_LABEL,
77         EQUATOR_LABEL,
78         ECLIPTIC_LABEL,
79         TELESCOPE_SYMBOL,
80         CATALOG_STAR_LABEL,
81         CATALOG_DSO_LABEL,
82         NO_LABEL //used in LinesItem
83     };
84 
85     /**
86      * Create LabelNode with given skyObject and append it to LabelTypeNode that corresponds
87      * to type
88      * @param skyObject for which the label is created
89      * @param labelType type of LabelTypeNode to which this label has to be reparented
90      * @return pointer to newly created LabelNode
91      */
92     LabelNode *addLabel(SkyObject *skyObject, label_t labelType);
93 
94     /**
95      * Create LabelNode and append it to corresponding TrixelNode so that all labels
96      * can be hidden whenever Trixel is not displayed. Use for sky objects that are indexed by SkyMesh
97      * @param skyObject for which the label is created
98      * @param labelType type of LabelTypeNode to which this label has to be reparented
99      * @param trixel id of trixel
100      **/
101     LabelNode *addLabel(SkyObject *skyObject, label_t labelType, Trixel trixel);
102 
103     /** @short does the same as above but with QString instead of SkyObject */
104     LabelNode *addLabel(QString name, label_t labelType);
105 
106     /**
107      * @short does the same as above but instead creates GuideLabelNode
108      * @note currently GuideLabelNode is not used anywhere so it is not fully supported yet
109      */
110     GuideLabelNode *addGuideLabel(QString name, label_t labelType);
111 
112     /**
113      * The order of labels update can be changed here.
114      * @short updates all child labels
115      */
116     void update();
117 
118     /**
119      * @short updates child labels of LabelTypeNode that corresponds to type in m_labelsLists
120      * Labels for stars and DSOs we update labels only if corresponding TrixelNode is visible.
121      * @param labelType type of LabelTypeNode (see m_labelsLists)
122      */
123     void updateChildLabels(label_t labelType);
124 
125     /** @return LabelTypeNode that holds labels of labelType */
getLabelNode(label_t labelType)126     LabelTypeNode *getLabelNode(label_t labelType) { return m_labelsLists.value(labelType); }
127 
128     /** @short deletes all labels of type labelType */
129     void deleteLabels(label_t labelType);
130 
131     /** @short deletes particular label */
132     void deleteLabel(LabelNode *label);
133 
134     /** @short hides all labels of type labelType */
135     void hideLabels(label_t labelType);
136 
137     /**
138          * @short shows all labels of type labelType
139          */
140 
141     void showLabels(label_t labelType);
142 
143     /** @short adds trixel to the node corresponding to labelType */
144     TrixelNode *addTrixel(label_t labelType, Trixel trixel);
145 
146     /**
147      * @short sets m_rootNode and appends to it this node
148      * @param rootNode parent RootNode that instantiates this object
149      */
150     void setRootNode(RootNode *rootNode);
151 
152     /** @return pointer to RootNode that instantiated this object */
rootNode()153     RootNode *rootNode() { return m_rootNode; }
154 
155   private:
156     QMap<label_t, LabelTypeNode *> m_labelsLists;
157 
158     /** @short because this class is not derived from SkyItem it has to store pointer to RootNode */
159     RootNode *m_rootNode { nullptr };
160     SkyLabeler *skyLabeler { nullptr };
161 };
162