Mon, 20 Jun 2022 17:27:30 +0300
Add a basic message log
26 | 1 | #include "colors.h" |
2 | ||
205 | 3 | const ColorDefinition unknownColor{{}, {}, "Unknown", "???"}; |
26 | 4 | |
205 | 5 | template<typename... Args> |
6 | static QString replaced(QString text, Args&&... args) | |
26 | 7 | { |
205 | 8 | text.replace(args...); |
9 | return text; | |
139
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
10 | } |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
11 | |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
12 | /** |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
13 | * @brief Parses an LDConfig.ldr line from a string |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
14 | * @param string LDConfig.ldr line to parse |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
15 | */ |
205 | 16 | static auto loadColorFromString(const QString& string) |
26 | 17 | { |
205 | 18 | std::optional<std::pair<ColorIndex, ColorDefinition>> result; |
19 | static const QRegExp pattern{QStringLiteral( | |
20 | R"(^\s*0 \!COLOUR\s+([^\s]+)\s+)" | |
21 | R"(CODE\s+(\d+)\s+)" | |
22 | R"(VALUE\s+(\#[0-9a-fA-F]{3,6})\s+)" | |
23 | R"(EDGE\s+(\#[0-9a-fA-F]{3,6}))" | |
24 | R"((?:\s+ALPHA\s+(\d+))?)" | |
25 | )}; | |
26 | 26 | if (pattern.indexIn(string) != -1) |
27 | { | |
28 | const int code = pattern.cap(2).toInt(); | |
205 | 29 | const QString name = pattern.cap(1); |
30 | ColorDefinition definition = { | |
31 | .faceColor = pattern.cap(3), | |
32 | .edgeColor = pattern.cap(4), | |
33 | .name = name, | |
34 | .displayName = replaced(name, "_", " "), | |
35 | }; | |
26 | 36 | if (not pattern.cap(5).isEmpty()) |
37 | { | |
38 | const int alpha = pattern.cap(5).toInt(); | |
39 | definition.faceColor.setAlpha(alpha); | |
40 | } | |
205 | 41 | result = std::make_pair(ColorIndex{code}, definition); |
26 | 42 | } |
205 | 43 | return result; |
44 | } | |
45 | ||
46 | /** | |
47 | * @brief Loads colors from LDConfig.ldr | |
48 | */ | |
49 | std::optional<ColorTable> loadColorTable(QIODevice &device, QTextStream &errors) | |
50 | { | |
51 | std::optional<ColorTable> result; | |
52 | if (device.isReadable()) | |
53 | { | |
54 | result.emplace(); | |
55 | QTextStream stream{&device}; | |
56 | QString line; | |
57 | while (stream.readLineInto(&line)) | |
58 | { | |
59 | const auto pair = loadColorFromString(line); | |
60 | if (pair.has_value()) { | |
61 | (*result)[pair->first] = pair->second; | |
62 | } | |
63 | } | |
64 | } | |
65 | else | |
66 | { | |
67 | errors << "could not read colors"; | |
68 | } | |
69 | return result; | |
26 | 70 | } |
43
08dc62e03a6d
made edges white in dark backgrounds
Teemu Piippo <teemu@hecknology.net>
parents:
35
diff
changeset
|
71 | |
139
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
72 | /** |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
73 | * @brief Calculates the luma-value for the given color. |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
74 | * @details c.f. https://en.wikipedia.org/wiki/Luma_(video) |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
75 | * @param color |
72098474d362
Document and refactor colors.cpp and colors.h
Teemu Piippo <teemu@hecknology.net>
parents:
132
diff
changeset
|
76 | * @returns luma value [0, 1] |
43
08dc62e03a6d
made edges white in dark backgrounds
Teemu Piippo <teemu@hecknology.net>
parents:
35
diff
changeset
|
77 | */ |
205 | 78 | qreal luma(const QColor& color) |
43
08dc62e03a6d
made edges white in dark backgrounds
Teemu Piippo <teemu@hecknology.net>
parents:
35
diff
changeset
|
79 | { |
205 | 80 | return luma(color.redF(), color.greenF(), color.blueF()); |
43
08dc62e03a6d
made edges white in dark backgrounds
Teemu Piippo <teemu@hecknology.net>
parents:
35
diff
changeset
|
81 | } |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
82 | |
205 | 83 | //! @brief Returns a direct color index that codes the specified color value |
84 | ColorIndex directColor(const QColor& color) | |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
85 | { |
205 | 86 | return directColor(color.red(), color.green(), color.blue()); |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
87 | } |
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
88 | |
205 | 89 | //! @brief Returns a face color for @param color, taking direct colors into account |
90 | std::optional<QColor> colorFace(ColorIndex color, const ColorTable& colorTable) | |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
91 | { |
205 | 92 | std::optional<QColor> result; |
93 | if (isDirectColor(color)) { | |
94 | const std::array<int, 3> rgb = directColorRgb(color); | |
95 | result = QColor{rgb[0], rgb[1], rgb[2]}; | |
96 | } | |
97 | else { | |
98 | const ColorDefinition* def = findInMap(colorTable, color); | |
99 | if (def != nullptr) { | |
100 | result = def->faceColor; | |
101 | } | |
102 | } | |
103 | return result; | |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
104 | } |
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
105 | |
205 | 106 | //! @brief Returns an edge color for @param color, taking direct colors into account |
107 | std::optional<QColor> colorEdge(ColorIndex color, const ColorTable& colorTable) | |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
108 | { |
205 | 109 | if (isDirectColor(color)) { |
110 | const std::array<int, 3> rgb = directColorRgb(color); | |
111 | return (luma(rgb[0], rgb[1], rgb[2]) < 0.4) ? Qt::white : Qt::black; | |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
112 | } |
205 | 113 | else { |
114 | return colorFace(color, colorTable); | |
94
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
115 | } |
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
116 | } |
164f53fb5921
added a color select dialog
Teemu Piippo <teemu@hecknology.net>
parents:
43
diff
changeset
|
117 | |
205 | 118 | QDataStream& operator<<(QDataStream& stream, ColorIndex color) |
132
488d0ba6070b
Begin work with serialization
Teemu Piippo <teemu@hecknology.net>
parents:
94
diff
changeset
|
119 | { |
488d0ba6070b
Begin work with serialization
Teemu Piippo <teemu@hecknology.net>
parents:
94
diff
changeset
|
120 | return stream << color.index; |
488d0ba6070b
Begin work with serialization
Teemu Piippo <teemu@hecknology.net>
parents:
94
diff
changeset
|
121 | } |
488d0ba6070b
Begin work with serialization
Teemu Piippo <teemu@hecknology.net>
parents:
94
diff
changeset
|
122 | |
205 | 123 | QDataStream& operator>>(QDataStream& stream, ColorIndex& color) |
132
488d0ba6070b
Begin work with serialization
Teemu Piippo <teemu@hecknology.net>
parents:
94
diff
changeset
|
124 | { |
488d0ba6070b
Begin work with serialization
Teemu Piippo <teemu@hecknology.net>
parents:
94
diff
changeset
|
125 | return stream >> color.index; |
488d0ba6070b
Begin work with serialization
Teemu Piippo <teemu@hecknology.net>
parents:
94
diff
changeset
|
126 | } |
178 | 127 | |
205 | 128 | std::optional<QString> colorDisplayName(ColorIndex color, const ColorTable &colorTable) |
178 | 129 | { |
205 | 130 | std::optional<QString> result; |
131 | if (isDirectColor(color)) { | |
132 | result = colorFace(color, colorTable).value_or(QColor{}).name(); | |
178 | 133 | } |
205 | 134 | else { |
135 | const ColorDefinition* def = findInMap(colorTable, color); | |
136 | if (def != nullptr) { | |
137 | result = def->displayName; | |
138 | } | |
178 | 139 | } |
205 | 140 | return result; |
178 | 141 | } |