1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LIBREPCB_GRAPHICSLAYER_H
21 #define LIBREPCB_GRAPHICSLAYER_H
22 
23 /*******************************************************************************
24  *  Includes
25  ******************************************************************************/
26 #include "../signalslot.h"
27 #include "graphicslayername.h"
28 
29 #include <QtCore>
30 #include <QtWidgets>
31 
32 #include <memory>
33 
34 /*******************************************************************************
35  *  Namespace / Forward Declarations
36  ******************************************************************************/
37 namespace librepcb {
38 
39 /*******************************************************************************
40  *  Class GraphicsLayer
41  ******************************************************************************/
42 
43 /**
44  * @brief The GraphicsLayer class represents a graphical layer used in
45  * schematics and boards
46  *
47  * These layers are used in graphics items (QGraphicsItem) to determine their
48  * visibility and colors.
49  */
50 class GraphicsLayer : public QObject {
51   Q_OBJECT
52 
53 public:
54   // clang-format off
55 
56   // schematic layers
57   //static constexpr const char* sSchematicBackground     = "sch_background";         ///< Primary: background | Secondary: grid
58   //static constexpr const char* sSchematicSelection      = "sch_selection";          ///< Primary: outline    | Secondary: area
59   static constexpr const char* sSchematicReferences     = "sch_references";         ///< origin crosses of symbols, texts, ...
60   static constexpr const char* sSchematicSheetFrames    = "sch_scheet_frames";      ///< e.g. A4 sheet frame + text boxes
61   static constexpr const char* sSchematicNetLines       = "sch_net_lines";          ///< librepcb::project::SI_NetLine
62   static constexpr const char* sSchematicNetLabels      = "sch_net_labels";         ///< librepcb::project::SI_NetLabel
63   static constexpr const char* sSchematicNetLabelAnchors= "sch_net_label_anchors";  ///< anchor line of librepcb::project::SI_NetLabel
64   static constexpr const char* sSchematicDocumentation  = "sch_documentation";      ///< for documentation purposes, e.g. text
65   static constexpr const char* sSchematicComments       = "sch_comments";           ///< for personal comments, e.g. text
66   static constexpr const char* sSchematicGuide          = "sch_guide";              ///< e.g. for boxes around circuits
67 
68   // symbol layers
69   static constexpr const char* sSymbolOutlines          = "sym_outlines";           ///< dark red lines of symbols
70   static constexpr const char* sSymbolGrabAreas         = "sym_grab_areas";         ///< optional yellow area of symbols
71   static constexpr const char* sSymbolHiddenGrabAreas   = "sym_hidden_grab_areas";  ///< hidden grab areas of symbols
72   static constexpr const char* sSymbolNames             = "sym_names";              ///< text {{NAME}}
73   static constexpr const char* sSymbolValues            = "sym_values";             ///< text {{VALUE}}
74   static constexpr const char* sSymbolPinCirclesOpt     = "sym_pin_circles_opt";    ///< green circle of unconnected pins
75   static constexpr const char* sSymbolPinCirclesReq     = "sym_pin_circles_req";    ///< red circle of unconnected pins
76   static constexpr const char* sSymbolPinNames          = "sym_pin_names";          ///< name of the connected component signal
77   static constexpr const char* sSymbolPinNumbers        = "sym_pin_numbers";        ///< number of the connected footprint pad
78 
79   // asymmetric board layers
80   //static constexpr const char* sBoardBackground         = "brd_background";         ///< Primary: background | Secondary: grid
81   //static constexpr const char* sBoardSelection          = "brd_selection";          ///< Primary: outline    | Secondary: area
82   //static constexpr const char* sBoardReferences         = "brd_references";         ///< origin crosses of footprints, holes, ...
83   static constexpr const char* sBoardSheetFrames        = "brd_sheet_frames";       ///< e.g. A4 sheet frame + text boxes
84   static constexpr const char* sBoardOutlines           = "brd_outlines";           ///< incl. non-plated through hole milling
85   static constexpr const char* sBoardMillingPth         = "brd_milling_pth";        ///< plated through hole milling
86   static constexpr const char* sBoardDrillsNpth         = "brd_drills_npth";        ///< non-plated through hole drills
87   static constexpr const char* sBoardPadsTht            = "brd_pads_tht";           ///< plated through hole pads
88   static constexpr const char* sBoardViasTht            = "brd_vias_tht";           ///< plated through hole vias
89   static constexpr const char* sBoardAirWires           = "brd_airwires";           ///< air wires (unconnected)
90   static constexpr const char* sBoardMeasures           = "brd_measures";           ///< measurements documentation
91   static constexpr const char* sBoardAlignment          = "brd_alignment";          ///< alignment helpers in devices
92   static constexpr const char* sBoardDocumentation      = "brd_documentation";      ///< for documentation purposes, e.g. text
93   static constexpr const char* sBoardComments           = "brd_comments";           ///< for personal comments, e.g. text
94   static constexpr const char* sBoardGuide              = "brd_guide";              ///< e.g. for boxes around circuits
95 
96   // symmetric board layers
97   static constexpr const char* sTopPlacement            = "top_placement";          ///< placement information (e.g. outline) of devices
98   static constexpr const char* sBotPlacement            = "bot_placement";          ///< placement information (e.g. outline) of devices
99   static constexpr const char* sTopDocumentation        = "top_documentation";      ///< like placement layers, but not for silk screen
100   static constexpr const char* sBotDocumentation        = "bot_documentation";      ///< like placement layers, but not for silk screen
101   static constexpr const char* sTopGrabAreas            = "top_grab_areas";         ///< area where devices can be dragged
102   static constexpr const char* sBotGrabAreas            = "bot_grab_areas";         ///< area where devices can be dragged
103   static constexpr const char* sTopHiddenGrabAreas      = "top_hidden_grab_areas";  ///< hidden area where devices can be dragged
104   static constexpr const char* sBotHiddenGrabAreas      = "bot_hidden_grab_areas";  ///< hidden area where devices can be dragged
105   static constexpr const char* sTopReferences           = "top_references";         ///< origin crosses of devices
106   static constexpr const char* sBotReferences           = "bot_references";         ///< origin crosses of devices
107   static constexpr const char* sTopNames                = "top_names";              ///< text, may be used for silk screen
108   static constexpr const char* sBotNames                = "bot_names";              ///< text, may be used for silk screen
109   static constexpr const char* sTopValues               = "top_values";             ///< text, may be used for silk screen
110   static constexpr const char* sBotValues               = "bot_values";             ///< text, may be used for silk screen
111   static constexpr const char* sTopCourtyard            = "top_courtyard";          ///< area required to mount devices
112   static constexpr const char* sBotCourtyard            = "bot_courtyard";          ///< area required to mount devices
113   static constexpr const char* sTopStopMask             = "top_stop_mask";          ///< areas over smt pads
114   static constexpr const char* sBotStopMask             = "bot_stop_mask";          ///< areas over smt pads
115   static constexpr const char* sTopSolderPaste          = "top_solder_paste";       ///< areas over smt pads
116   static constexpr const char* sBotSolderPaste          = "bot_solder_paste";       ///< areas over smt pads
117   static constexpr const char* sTopFinish               = "top_finish";             ///< areas of special surface treatments
118   static constexpr const char* sBotFinish               = "bot_finish";             ///< areas of special surface treatments
119   static constexpr const char* sTopGlue                 = "top_glue";               ///< adhesive for fixing devices
120   static constexpr const char* sBotGlue                 = "bot_glue";               ///< adhesive for fixing devices
121 
122   // copper layers
123   static constexpr const char* sTopCopper               = "top_cu";
124   //static constexpr const char* sInnerCopper#            = "in#_cu";
125   static constexpr const char* sBotCopper               = "bot_cu";
126 
127 #ifdef QT_DEBUG
128   // debug layers
129   static constexpr const char* sDebugGraphicsItemsBoundingRects       = "dbg_GraphicsItemsBoundingRects";
130   static constexpr const char* sDebugGraphicsItemsTextsBoundingRects  = "dbg_GraphicsItemsTextsBoundingRects";
131   static constexpr const char* sDebugSymbolPinNetSignalNames          = "dbg_SymbolPinNetSignalNames";
132   static constexpr const char* sDebugNetLinesNetSignalNames           = "dbg_NetLinesNetSignalNames";
133   static constexpr const char* sDebugInvisibleNetPoints               = "dbg_InvisibleNetPoints";
134   static constexpr const char* sDebugComponentSymbolsCounts           = "dbg_ComponentSymbolsCounts";
135 #endif
136 
137   // clang-format on
138 
139   // Signals
140   enum class Event {
141     ColorChanged,
142     HighlightColorChanged,
143     VisibleChanged,
144     EnabledChanged,
145     Destroyed,
146   };
147   Signal<GraphicsLayer, Event> onEdited;
148   typedef Slot<GraphicsLayer, Event> OnEditedSlot;
149 
150   // Constructors / Destructor
151   GraphicsLayer() = delete;
152   GraphicsLayer(const GraphicsLayer& other) noexcept;
153   explicit GraphicsLayer(const QString& name) noexcept;
154   virtual ~GraphicsLayer() noexcept;
155 
156   // Getters
getName()157   const QString& getName() const noexcept { return mName; }
getNameTr()158   const QString& getNameTr() const noexcept { return mNameTr; }
159   const QColor& getColor(bool highlighted = false) const noexcept {
160     return highlighted ? mColorHighlighted : mColor;
161   }
getVisible()162   bool getVisible() const noexcept { return mIsVisible; }
isEnabled()163   bool isEnabled() const noexcept { return mIsEnabled; }
isVisible()164   bool isVisible() const noexcept { return mIsEnabled && mIsVisible; }
isTopLayer()165   bool isTopLayer() const noexcept { return isTopLayer(mName); }
isBottomLayer()166   bool isBottomLayer() const noexcept { return isBottomLayer(mName); }
isInnerLayer()167   bool isInnerLayer() const noexcept { return isInnerLayer(mName); }
isCopperLayer()168   bool isCopperLayer() const noexcept { return isCopperLayer(mName); }
getInnerLayerNumber()169   int getInnerLayerNumber() const noexcept {
170     return getInnerLayerNumber(mName);
171   }
getMirroredLayerName()172   QString getMirroredLayerName() const noexcept {
173     return getMirroredLayerName(mName);
174   }
getGrabAreaLayerName()175   QString getGrabAreaLayerName() const noexcept {
176     return getGrabAreaLayerName(mName);
177   }
178 
179   // Setters
180   void setColor(const QColor& color) noexcept;
181   void setColorHighlighted(const QColor& color) noexcept;
182   void setVisible(bool visible) noexcept;
183   void setEnabled(bool enable) noexcept;
184 
185   // Operator Overloadings
186   GraphicsLayer& operator=(const GraphicsLayer& rhs) = delete;
187 
188   // Static Methods
getInnerLayerCount()189   static int getInnerLayerCount() noexcept {
190     return 62;
191   }  // some random number... ;)
192   static bool isTopLayer(const QString& name) noexcept;
193   static bool isBottomLayer(const QString& name) noexcept;
194   static bool isInnerLayer(const QString& name) noexcept;
195   static bool isCopperLayer(const QString& name) noexcept;
196   static QString getInnerLayerName(int number) noexcept;
197   static int getInnerLayerNumber(const QString& name) noexcept;
198   static QString getMirroredLayerName(const QString& name) noexcept;
199   static QString getGrabAreaLayerName(const QString& outlineLayerName) noexcept;
200   static void getDefaultValues(const QString& name, QString& nameTr,
201                                QColor& color, QColor& colorHl,
202                                bool& visible) noexcept;
203 
204 signals:
205   void attributesChanged();
206 
207 protected:  // Data
208   QString mName;  ///< Unique name which is used for serialization
209   QString mNameTr;  ///< Layer name (translated into the user's language)
210   QColor mColor;  ///< Color of graphics items on that layer
211   QColor mColorHighlighted;  ///< Color of highlighted graphics items on that
212                              ///< layer
213   bool mIsVisible;  ///< Visibility of graphics items on that layer
214   bool mIsEnabled;  ///< Visibility/availability of the layer itself
215 };
216 
217 /*******************************************************************************
218  *  Interface IF_GraphicsLayerProvider
219  ******************************************************************************/
220 
221 /**
222  * @brief The IF_GraphicsLayerProvider class defines an interface for classes
223  * which provide layers
224  */
225 class IF_GraphicsLayerProvider {
226 public:
~IF_GraphicsLayerProvider()227   virtual ~IF_GraphicsLayerProvider() {}
228 
229   virtual GraphicsLayer* getLayer(const QString& name) const noexcept = 0;
230   virtual QList<GraphicsLayer*> getAllLayers() const noexcept = 0;
231 
getGrabAreaLayer(const QString outlineLayerName)232   GraphicsLayer* getGrabAreaLayer(const QString outlineLayerName) const
233       noexcept {
234     return getLayer(GraphicsLayer::getGrabAreaLayerName(outlineLayerName));
235   }
236 
getLayers(const QStringList & layerNames)237   QList<GraphicsLayer*> getLayers(const QStringList& layerNames) const
238       noexcept {
239     QList<GraphicsLayer*> layers;
240     foreach (const QString& name, layerNames) {
241       GraphicsLayer* layer = getLayer(name);
242       if (layer) layers.append(layer);
243     }
244     return layers;
245   }
246 };
247 
248 /*******************************************************************************
249  *  End of File
250  ******************************************************************************/
251 
252 }  // namespace librepcb
253 
254 #endif  // LIBREPCB_GRAPHICSLAYER_H
255