1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, The Regents of the University of California
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 //   list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 //   this list of conditions and the following disclaimer in the documentation
15 //   and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 //   contributors may be used to endorse or promote products derived from
19 //   this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 
33 #pragma once
34 
35 #include <QColorDialog>
36 #include <QDialog>
37 #include <QDockWidget>
38 #include <QGridLayout>
39 #include <QGroupBox>
40 #include <QLineEdit>
41 #include <QModelIndex>
42 #include <QRadioButton>
43 #include <QSettings>
44 #include <QStandardItemModel>
45 #include <QStringList>
46 #include <QTextEdit>
47 #include <QTreeView>
48 #include <QVBoxLayout>
49 #include <functional>
50 #include <vector>
51 
52 #include "congestionSetupDialog.h"
53 #include "options.h"
54 
55 namespace odb {
56 class dbDatabase;
57 class dbBlock;
58 class dbNet;
59 }  // namespace odb
60 
61 namespace gui {
62 
63 struct Callback
64 {
65   std::function<void(bool)> action;
66 };
67 
68 class PatternButton : public QRadioButton
69 {
70   Q_OBJECT
71  public:
72   PatternButton(Qt::BrushStyle pattern, QWidget* parent = nullptr);
~PatternButton()73   ~PatternButton() {}
74 
75   void paintEvent(QPaintEvent* event);
pattern()76   Qt::BrushStyle pattern() const { return pattern_; }
77 
78  private:
79   Qt::BrushStyle pattern_;
80 };
81 
82 class DisplayColorDialog : public QDialog
83 {
84   Q_OBJECT
85  public:
86   DisplayColorDialog(QColor color,
87                      Qt::BrushStyle pattern = Qt::SolidPattern,
88                      QWidget* parent = nullptr);
89   ~DisplayColorDialog();
90 
getSelectedColor()91   QColor getSelectedColor() const { return color_; }
92   Qt::BrushStyle getSelectedPattern() const;
93 
94  public slots:
95   void acceptDialog();
96   void rejectDialog();
97 
98  private:
99   QColor color_;
100   Qt::BrushStyle pattern_;
101 
102   QGroupBox* pattern_group_box_;
103   QGridLayout* grid_layout_;
104   QVBoxLayout* main_layout_;
105 
106   std::vector<PatternButton*> pattern_buttons_;
107   QColorDialog* color_dialog_;
108 
109   void buildUI();
110 
111   static inline std::vector<std::vector<Qt::BrushStyle>> brush_patterns_{
112       {Qt::NoBrush, Qt::SolidPattern},
113       {Qt::HorPattern, Qt::VerPattern},
114       {Qt::CrossPattern, Qt::DiagCrossPattern},
115       {Qt::FDiagPattern, Qt::BDiagPattern}};
116 };
117 
118 // This class shows the user the set of layers & objects that
119 // they can control the visibility and selectablity of.  The
120 // controls are show in a tree view to provide grouping of
121 // related options.
122 //
123 // It also implements the Options interface so that other clients can
124 // access the data.
125 class DisplayControls : public QDockWidget, public Options
126 {
127   Q_OBJECT
128 
129  public:
130   DisplayControls(QWidget* parent = nullptr);
131 
132   void setDb(odb::dbDatabase* db);
133 
134   void readSettings(QSettings* settings);
135   void writeSettings(QSettings* settings);
136 
137   // From the Options API
138   QColor color(const odb::dbTechLayer* layer) override;
139   Qt::BrushStyle pattern(const odb::dbTechLayer* layer) override;
140   bool isVisible(const odb::dbTechLayer* layer) override;
141   bool isSelectable(const odb::dbTechLayer* layer) override;
142   bool isNetVisible(odb::dbNet* net) override;
143   bool areFillsVisible() override;
144   bool areRowsVisible() override;
145   bool arePrefTracksVisible() override;
146   bool areNonPrefTracksVisible() override;
147 
148   void addCustomVisibilityControl(const std::string& name,
149                                   bool initially_visible = false);
150   bool checkCustomVisibilityControl(const std::string& name);
151 
152   bool isGridGraphVisible();
153   bool areRouteGuidesVisible();
154   bool areRoutingObjsVisible();
155 
156   bool isCongestionVisible() const override;
157   bool arePinMarkersVisible() const override;
158   bool showHorizontalCongestion() const override;
159   bool showVerticalCongestion() const override;
160   float getMinCongestionToShow() const override;
161   float getMaxCongestionToShow() const override;
162   QColor getCongestionColor(float congestion) const override;
163 
164  signals:
165   // The display options have changed and clients need to update
166   void changed();
167 
168  public slots:
169   // Tells this widget that a new design is loaded and the
170   // options displayed need to match
171   void designLoaded(odb::dbBlock* block);
172 
173   // This is called by the check boxes to update the state
174   void itemChanged(QStandardItem* item);
175   void displayItemDblClicked(const QModelIndex& index);
176 
177   void showCongestionSetup();
178 
179  private:
180   // The columns in the tree view
181   enum Column
182   {
183     Name,
184     Swatch,
185     Visible,
186     Selectable
187   };
188 
189   // One leaf (non-group) row in the model
190   struct ModelRow
191   {
192     QStandardItem* name = nullptr;
193     QStandardItem* swatch = nullptr;
194     QStandardItem* visible = nullptr;
195     QStandardItem* selectable = nullptr;  // may be null
196   };
197 
198   // The *Models are groups in the tree
199   struct NetModels
200   {
201     ModelRow signal;
202     ModelRow power;
203     ModelRow ground;
204     ModelRow clock;
205   };
206 
207   struct TrackModels
208   {
209     ModelRow pref;
210     ModelRow non_pref;
211   };
212 
213   struct MiscModels
214   {
215     ModelRow fills;
216   };
217 
218   void techInit();
219 
220   template <typename T>
221   QStandardItem* makeItem(ModelRow& row,
222                           const QString& text,
223                           T* parent,
224                           Qt::CheckState checked,
225                           const std::function<void(bool)>& visibility_action
226                           = std::function<void(bool)>(),
227                           const std::function<void(bool)>& select_action
228                           = std::function<void(bool)>(),
229                           const QColor& color = Qt::transparent,
230                           odb::dbTechLayer* tech_layer = nullptr);
231 
232   void toggleAllChildren(bool checked, QStandardItem* parent, Column column);
233 
234   QTreeView* view_;
235   QStandardItemModel* model_;
236 
237   // Categories in the model
238   ModelRow layers_group_;
239   ModelRow routing_group_;
240   ModelRow tracks_group_;
241   ModelRow nets_group_;
242   ModelRow misc_group_;
243 
244   // Object controls
245   NetModels nets_;
246   ModelRow rows_;
247   ModelRow congestion_map_;
248   ModelRow pin_markers_;
249   TrackModels tracks_;
250   MiscModels misc_;
251 
252   std::map<const odb::dbTechLayer*, ModelRow> layer_controls_;
253   std::map<std::string, ModelRow> custom_controls_;
254 
255   odb::dbDatabase* db_;
256   bool tech_inited_;
257 
258   std::map<const odb::dbTechLayer*, QColor> layer_color_;
259   std::map<const odb::dbTechLayer*, Qt::BrushStyle> layer_pattern_;
260 
261   CongestionSetupDialog* congestion_dialog_;
262 };
263 
264 }  // namespace gui
265 
266 Q_DECLARE_METATYPE(gui::Callback);
267