Sun, 04 Oct 2015 16:45:30 +0300
Fixed circle, rectangle and line path modes not working anymore. Add blip coordinates to curve and line path modes. Circle mode for now only can show the coordinates of the initial blip
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
1 | /* |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
2 | * LDForge: LDraw parts authoring CAD |
968 | 3 | * Copyright (C) 2013 - 2015 Teemu Piippo |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
4 | * |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
5 | * This program is free software: you can redistribute it and/or modify |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
6 | * it under the terms of the GNU General Public License as published by |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
7 | * the Free Software Foundation, either version 3 of the License, or |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
8 | * (at your option) any later version. |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
9 | * |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
10 | * This program is distributed in the hope that it will be useful, |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
13 | * GNU General Public License for more details. |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
14 | * |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
15 | * You should have received a copy of the GNU General Public License |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
17 | */ |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
18 | |
946 | 19 | #include <QFile> |
998 | 20 | #include <QMessageBox> |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
21 | #include "main.h" |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
22 | #include "colors.h" |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
23 | #include "ldDocument.h" |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
24 | #include "miscallenous.h" |
962
a4b463a7ee82
Rename MainWindow files
Teemu Piippo <crimsondusk64@gmail.com>
parents:
952
diff
changeset
|
25 | #include "mainwindow.h" |
998 | 26 | #include "documentmanager.h" |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
27 | |
998 | 28 | static ColorData* colorData = nullptr; |
946 | 29 | |
998 | 30 | void initColors() |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
31 | { |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
32 | print ("Initializing color information.\n"); |
998 | 33 | static ColorData colors; |
34 | colorData = &colors; | |
946 | 35 | } |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
36 | |
946 | 37 | bool LDColor::isValid() const |
38 | { | |
998 | 39 | if (isLDConfigColor() and data().name.isEmpty()) |
946 | 40 | return false; // Unknown LDConfig color |
41 | ||
42 | return m_index != -1; | |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
43 | } |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
44 | |
946 | 45 | bool LDColor::isLDConfigColor() const |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
46 | { |
998 | 47 | return colorData->contains (index()); |
48 | } | |
49 | ||
50 | const ColorData::Entry& LDColor::data() const | |
51 | { | |
52 | return colorData->get (index()); | |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
53 | } |
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
54 | |
946 | 55 | QString LDColor::name() const |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
56 | { |
946 | 57 | if (isDirect()) |
58 | return "0x" + QString::number (index(), 16).toUpper(); | |
59 | else if (isLDConfigColor()) | |
998 | 60 | return data().name; |
946 | 61 | else if (index() == -1) |
62 | return "null color"; | |
63 | else | |
64 | return ""; | |
65 | } | |
66 | ||
67 | QString LDColor::hexcode() const | |
68 | { | |
69 | return faceColor().name(); | |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
70 | } |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
71 | |
946 | 72 | QColor LDColor::faceColor() const |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
73 | { |
946 | 74 | if (isDirect()) |
75 | { | |
76 | QColor color; | |
77 | color.setRed ((index() & 0x0FF0000) >> 16); | |
78 | color.setGreen ((index() & 0x000FF00) >> 8); | |
79 | color.setBlue (index() & 0x00000FF); | |
80 | ||
81 | if (index() >= 0x3000000) | |
82 | color.setAlpha (128); | |
83 | ||
84 | return color; | |
85 | } | |
86 | else if (isLDConfigColor()) | |
87 | { | |
998 | 88 | return data().faceColor; |
946 | 89 | } |
90 | else | |
91 | { | |
92 | return Qt::black; | |
93 | } | |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
94 | } |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
95 | |
946 | 96 | QColor LDColor::edgeColor() const |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
97 | { |
946 | 98 | if (isDirect()) |
998 | 99 | return ::luma (faceColor()) < 48 ? Qt::white : Qt::black; |
946 | 100 | else if (isLDConfigColor()) |
998 | 101 | return data().edgeColor; |
946 | 102 | else |
103 | return Qt::black; | |
104 | } | |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
105 | |
946 | 106 | int LDColor::luma() const |
107 | { | |
998 | 108 | return ::luma (faceColor()); |
946 | 109 | } |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
110 | |
946 | 111 | int LDColor::edgeLuma() const |
112 | { | |
998 | 113 | return ::luma (edgeColor()); |
946 | 114 | } |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
115 | |
946 | 116 | qint32 LDColor::index() const |
117 | { | |
118 | return m_index; | |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
119 | } |
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
120 | |
806
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
121 | QString LDColor::indexString() const |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
122 | { |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
123 | if (isDirect()) |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
124 | return "0x" + QString::number (index(), 16).toUpper(); |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
125 | |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
126 | return QString::number (index()); |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
127 | } |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
128 | |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
129 | bool LDColor::isDirect() const |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
130 | { |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
131 | return index() >= 0x02000000; |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
132 | } |
4240f47aa2d4
- moved most of LDColorData API into LDColor
Santeri Piippo <crimsondusk64@gmail.com>
parents:
797
diff
changeset
|
133 | |
998 | 134 | int luma (const QColor& col) |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
135 | { |
946 | 136 | return (0.2126f * col.red()) + (0.7152f * col.green()) + (0.0722f * col.blue()); |
655
b376645315ab
- renamed files to camelCase
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff
changeset
|
137 | } |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
138 | |
998 | 139 | ColorData::ColorData() |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
140 | { |
998 | 141 | if (colorData == nullptr) |
142 | colorData = this; | |
143 | ||
144 | // Initialize main and edge colors, they're special like that. | |
145 | m_data[MainColor].faceColor = | |
146 | m_data[MainColor].hexcode = "#AAAAAA"; | |
147 | m_data[MainColor].edgeColor = Qt::black; | |
148 | m_data[MainColor].name = "Main color"; | |
149 | m_data[EdgeColor].faceColor = | |
150 | m_data[EdgeColor].edgeColor = | |
151 | m_data[EdgeColor].hexcode = "#000000"; | |
152 | m_data[EdgeColor].name = "Edge color"; | |
153 | loadFromLdconfig(); | |
154 | } | |
155 | ||
156 | ColorData::~ColorData() | |
157 | { | |
158 | if (colorData == this) | |
159 | colorData = nullptr; | |
795
195fa1fff9c3
- changed all color usage to use LDColor classes instead of color indices. Added support for direct colors.
Santeri Piippo <crimsondusk64@gmail.com>
parents:
706
diff
changeset
|
160 | } |
946 | 161 | |
998 | 162 | bool ColorData::contains (int code) const |
946 | 163 | { |
998 | 164 | return code >= 0 and code < EntryCount; |
165 | } | |
166 | ||
167 | const ColorData::Entry& ColorData::get (int code) const | |
168 | { | |
169 | if (not contains (code)) | |
170 | throw std::runtime_error ("Attempted to get non-existant color information"); | |
946 | 171 | |
998 | 172 | return m_data[code]; |
173 | } | |
174 | ||
175 | void ColorData::loadFromLdconfig() | |
176 | { | |
177 | if (not g_win) | |
178 | return; | |
179 | ||
180 | QString path = g_win->documents()->findDocumentPath ("LDConfig.ldr", false); | |
181 | QFile fp (path); | |
182 | ||
183 | if (not fp.open (QIODevice::ReadOnly)) | |
946 | 184 | { |
998 | 185 | QMessageBox::critical (nullptr, "Error", "Unable to open LDConfig.ldr for parsing: " + fp.errorString()); |
946 | 186 | return; |
187 | } | |
188 | ||
998 | 189 | // TODO: maybe LDConfig can be loaded as a Document? Or would that be overkill? |
190 | while (not fp.atEnd()) | |
946 | 191 | { |
998 | 192 | QString line = QString::fromUtf8 (fp.readLine()); |
946 | 193 | |
194 | if (line.isEmpty() or line[0] != '0') | |
195 | continue; // empty or illogical | |
196 | ||
197 | line.remove ('\r'); | |
198 | line.remove ('\n'); | |
199 | ||
200 | // Parse the line | |
998 | 201 | LDConfigParser parser (line, ' '); |
202 | QString name; | |
203 | QString facename; | |
204 | QString edgename; | |
205 | QString codestring; | |
946 | 206 | |
207 | // Check 0 !COLOUR, parse the name | |
998 | 208 | if (not parser.compareToken (0, "0") or not parser.compareToken (1, "!COLOUR") or not parser.getToken (name, 2)) |
946 | 209 | continue; |
210 | ||
211 | // Replace underscores in the name with spaces for readability | |
212 | name.replace ("_", " "); | |
213 | ||
998 | 214 | if (not parser.parseTag ("CODE", codestring)) |
946 | 215 | continue; |
216 | ||
217 | bool ok; | |
998 | 218 | int code = codestring.toShort (&ok); |
946 | 219 | |
998 | 220 | if (not ok or not contains (code)) |
946 | 221 | continue; |
222 | ||
998 | 223 | if (not parser.parseTag ("VALUE", facename) or not parser.parseTag ("EDGE", edgename)) |
946 | 224 | continue; |
225 | ||
226 | // Ensure that our colors are correct | |
998 | 227 | QColor faceColor (facename); |
228 | QColor edgeColor (edgename); | |
946 | 229 | |
230 | if (not faceColor.isValid() or not edgeColor.isValid()) | |
231 | continue; | |
232 | ||
998 | 233 | Entry& entry = m_data[code]; |
946 | 234 | entry.name = name; |
235 | entry.faceColor = faceColor; | |
236 | entry.edgeColor = edgeColor; | |
237 | entry.hexcode = facename; | |
998 | 238 | |
239 | if (parser.parseTag ("ALPHA", codestring)) | |
240 | entry.faceColor.setAlpha (qBound (0, codestring.toInt(), 255)); | |
946 | 241 | } |
242 | } | |
243 | ||
244 | // ============================================================================= | |
245 | // | |
246 | LDConfigParser::LDConfigParser (QString inText, char sep) | |
247 | { | |
248 | m_tokens = inText.split (sep, QString::SkipEmptyParts); | |
249 | m_pos = -1; | |
250 | } | |
251 | ||
252 | // ============================================================================= | |
253 | // | |
254 | bool LDConfigParser::getToken (QString& val, const int pos) | |
255 | { | |
256 | if (pos >= m_tokens.size()) | |
257 | return false; | |
258 | ||
259 | val = m_tokens[pos]; | |
260 | return true; | |
261 | } | |
262 | ||
263 | // ============================================================================= | |
264 | // | |
265 | bool LDConfigParser::findToken (int& result, char const* needle, int args) | |
266 | { | |
267 | for (int i = 0; i < (m_tokens.size() - args); ++i) | |
268 | { | |
269 | if (m_tokens[i] == needle) | |
270 | { | |
271 | result = i; | |
272 | return true; | |
273 | } | |
274 | } | |
275 | ||
276 | return false; | |
277 | } | |
278 | ||
279 | // ============================================================================= | |
280 | // | |
281 | bool LDConfigParser::compareToken (int inPos, QString text) | |
282 | { | |
283 | QString tok; | |
284 | ||
285 | if (not getToken (tok, inPos)) | |
286 | return false; | |
287 | ||
288 | return (tok == text); | |
289 | } | |
290 | ||
291 | // ============================================================================= | |
292 | // | |
293 | // Helper function for parseLDConfig | |
294 | // | |
998 | 295 | bool LDConfigParser::parseTag (char const* tag, QString& val) |
946 | 296 | { |
297 | int pos; | |
298 | ||
299 | // Try find the token and get its position | |
300 | if (not findToken (pos, tag, 1)) | |
301 | return false; | |
302 | ||
303 | // Get the token after it and store it into val | |
304 | return getToken (val, pos + 1); | |
305 | } |