1 /* |
|
2 * LDForge: LDraw parts authoring CAD |
|
3 * Copyright (C) 2013, 2014 Santeri Piippo |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License as published by |
|
7 * the Free Software Foundation, either version 3 of the License, or |
|
8 * (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #pragma once |
|
20 #include <QMainWindow> |
|
21 #include <QAction> |
|
22 #include <QListWidget> |
|
23 #include <QRadioButton> |
|
24 #include "Configuration.h" |
|
25 #include "LDObject.h" |
|
26 #include "ui_ldforge.h" |
|
27 |
|
28 class MessageManager; |
|
29 class MainWindow; |
|
30 class LDColor; |
|
31 class QToolButton; |
|
32 class QDialogButtonBox; |
|
33 class GLRenderer; |
|
34 class QComboBox; |
|
35 class QProgressBar; |
|
36 class Ui_LDForgeUI; |
|
37 |
|
38 // Stuff for dialogs |
|
39 #define IMPLEMENT_DIALOG_BUTTONS \ |
|
40 bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); \ |
|
41 connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); \ |
|
42 connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); \ |
|
43 |
|
44 // ============================================================================= |
|
45 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
46 // ============================================================================= |
|
47 #define DEFINE_ACTION(NAME, DEFSHORTCUT) \ |
|
48 cfg (KeySequence, key_action##NAME, DEFSHORTCUT); \ |
|
49 void MainWindow::slot_action##NAME() |
|
50 |
|
51 // Convenience macros for key sequences. |
|
52 #define KEY(N) (Qt::Key_##N) |
|
53 #define CTRL(N) (Qt::CTRL | Qt::Key_##N) |
|
54 #define SHIFT(N) (Qt::SHIFT | Qt::Key_##N) |
|
55 #define CTRL_SHIFT(N) (Qt::CTRL | Qt::SHIFT | Qt::Key_##N) |
|
56 |
|
57 // ============================================================================= |
|
58 class LDQuickColor |
|
59 { |
|
60 PROPERTY (public, LDColor*, color, setColor, STOCK_WRITE) |
|
61 PROPERTY (public, QToolButton*, toolButton, setToolButton, STOCK_WRITE) |
|
62 |
|
63 public: |
|
64 LDQuickColor (LDColor* color, QToolButton* toolButton); |
|
65 bool isSeparator() const; |
|
66 |
|
67 static LDQuickColor getSeparator(); |
|
68 }; |
|
69 |
|
70 //! |
|
71 //! Object list class for MainWindow |
|
72 //! |
|
73 class ObjectList : public QListWidget |
|
74 { |
|
75 Q_OBJECT |
|
76 |
|
77 protected: |
|
78 void contextMenuEvent (QContextMenuEvent* ev); |
|
79 }; |
|
80 |
|
81 //! |
|
82 //! \brief The main window class. |
|
83 //! |
|
84 //! The MainWindow is LDForge's main GUI. It hosts the renderer, the object list, |
|
85 //! the message log, etc. Contains \c slot_action(), which is what all actions |
|
86 //! connect to. |
|
87 //! |
|
88 class MainWindow : public QMainWindow |
|
89 { |
|
90 Q_OBJECT |
|
91 |
|
92 public: |
|
93 //! Constructs the main window |
|
94 explicit MainWindow (QWidget* parent = null, Qt::WindowFlags flags = 0); |
|
95 |
|
96 //! Rebuilds the object list, located to the right of the GUI. |
|
97 void buildObjList(); |
|
98 |
|
99 //! Updates the window title. |
|
100 void updateTitle(); |
|
101 |
|
102 //! Builds the object list and tells the GL renderer to init a full |
|
103 //! refresh. |
|
104 void doFullRefresh(); |
|
105 |
|
106 //! Builds the object list and tells the GL renderer to do a soft update. |
|
107 void refresh(); |
|
108 |
|
109 //! \returns the suggested position to place a new object at. |
|
110 int getInsertionPoint(); |
|
111 |
|
112 //! Updates the quick color toolbar |
|
113 void updateColorToolbar(); |
|
114 |
|
115 //! Rebuilds the recent files submenu |
|
116 void updateRecentFilesMenu(); |
|
117 |
|
118 //! Sets the selection based on what's selected in the object list. |
|
119 void updateSelection(); |
|
120 |
|
121 //! Updates the grids, selects the selected grid and deselects others. |
|
122 void updateGridToolBar(); |
|
123 |
|
124 //! Updates the edit modes, current one is selected and others are deselected. |
|
125 void updateEditModeActions(); |
|
126 |
|
127 //! Rebuilds the document tab list. |
|
128 void updateDocumentList(); |
|
129 |
|
130 //! Updates the document tab for \c doc. If no such tab exists, the |
|
131 //! document list is rebuilt instead. |
|
132 void updateDocumentListItem (LDDocument* doc); |
|
133 |
|
134 //! \returns the uniform selected color (i.e. 4 if everything selected is |
|
135 //! red), -1 if there is no such consensus. |
|
136 int getSelectedColor(); |
|
137 |
|
138 //! \returns the uniform selected type (i.e. \c LDObject::ELine if everything |
|
139 //! selected is a line), \c LDObject::EUnidentified if there is no such |
|
140 //! consensus. |
|
141 LDObject::Type getUniformSelectedType(); |
|
142 |
|
143 //! Automatically scrolls the object list so that it points to the first |
|
144 //! selected object. |
|
145 void scrollToSelection(); |
|
146 |
|
147 //! Spawns the context menu at the given position. |
|
148 void spawnContextMenu (const QPoint pos); |
|
149 |
|
150 //! Deletes all selected objects. |
|
151 //! \returns the count of deleted objects. |
|
152 int deleteSelection(); |
|
153 |
|
154 //! Deletes all objects by the given color number. |
|
155 void deleteByColor (int colnum); |
|
156 |
|
157 //! Tries to save the given document. |
|
158 //! \param doc the document to save |
|
159 //! \param saveAs if true, always ask for a file path |
|
160 //! \returns whether the save was successful |
|
161 bool save (LDDocument* doc, bool saveAs); |
|
162 |
|
163 //! Updates various actions, undo/redo are set enabled/disabled where |
|
164 //! appropriate, togglable actions are updated based on configuration, |
|
165 //! etc. |
|
166 void updateActions(); |
|
167 |
|
168 //! \returns a pointer to the renderer |
|
169 inline GLRenderer* R() |
|
170 { |
|
171 return m_renderer; |
|
172 } |
|
173 |
|
174 //! Sets the quick color list to the given list of colors. |
|
175 inline void setQuickColors (const QList<LDQuickColor>& colors) |
|
176 { |
|
177 m_quickColors = colors; |
|
178 updateColorToolbar(); |
|
179 } |
|
180 |
|
181 //! Adds a message to the renderer's message manager. |
|
182 void addMessage (QString msg); |
|
183 |
|
184 //! Updates the object list. Right now this just rebuilds it. |
|
185 void refreshObjectList(); |
|
186 |
|
187 //! Updates all actions to ensure they have the correct shortcut as |
|
188 //! defined in the configuration entries. |
|
189 void updateActionShortcuts(); |
|
190 |
|
191 //! Gets the shortcut configuration for the given \c action |
|
192 KeySequenceConfig* shortcutForAction (QAction* action); |
|
193 |
|
194 void endAction(); |
|
195 |
|
196 public slots: |
|
197 void changeCurrentFile(); |
|
198 void slot_action(); |
|
199 void slot_actionNew(); |
|
200 void slot_actionNewFile(); |
|
201 void slot_actionOpen(); |
|
202 void slot_actionDownloadFrom(); |
|
203 void slot_actionSave(); |
|
204 void slot_actionSaveAs(); |
|
205 void slot_actionSaveAll(); |
|
206 void slot_actionClose(); |
|
207 void slot_actionCloseAll(); |
|
208 void slot_actionInsertFrom(); |
|
209 void slot_actionExportTo(); |
|
210 void slot_actionSettings(); |
|
211 void slot_actionSetLDrawPath(); |
|
212 void slot_actionScanPrimitives(); |
|
213 void slot_actionExit(); |
|
214 void slot_actionResetView(); |
|
215 void slot_actionAxes(); |
|
216 void slot_actionWireframe(); |
|
217 void slot_actionBFCView(); |
|
218 void slot_actionSetOverlay(); |
|
219 void slot_actionClearOverlay(); |
|
220 void slot_actionScreenshot(); |
|
221 void slot_actionInsertRaw(); |
|
222 void slot_actionNewSubfile(); |
|
223 void slot_actionNewLine(); |
|
224 void slot_actionNewTriangle(); |
|
225 void slot_actionNewQuad(); |
|
226 void slot_actionNewCLine(); |
|
227 void slot_actionNewComment(); |
|
228 void slot_actionNewBFC(); |
|
229 void slot_actionNewVertex(); |
|
230 void slot_actionUndo(); |
|
231 void slot_actionRedo(); |
|
232 void slot_actionCut(); |
|
233 void slot_actionCopy(); |
|
234 void slot_actionPaste(); |
|
235 void slot_actionDelete(); |
|
236 void slot_actionSelectAll(); |
|
237 void slot_actionSelectByColor(); |
|
238 void slot_actionSelectByType(); |
|
239 void slot_actionModeDraw(); |
|
240 void slot_actionModeSelect(); |
|
241 void slot_actionModeCircle(); |
|
242 void slot_actionSetDrawDepth(); |
|
243 void slot_actionSetColor(); |
|
244 void slot_actionAutocolor(); |
|
245 void slot_actionUncolorize(); |
|
246 void slot_actionInline(); |
|
247 void slot_actionInlineDeep(); |
|
248 void slot_actionInvert(); |
|
249 void slot_actionMakePrimitive(); |
|
250 void slot_actionSplitQuads(); |
|
251 void slot_actionEditRaw(); |
|
252 void slot_actionBorders(); |
|
253 void slot_actionCornerVerts(); |
|
254 void slot_actionRoundCoordinates(); |
|
255 void slot_actionVisibilityHide(); |
|
256 void slot_actionVisibilityReveal(); |
|
257 void slot_actionVisibilityToggle(); |
|
258 void slot_actionReplaceCoords(); |
|
259 void slot_actionFlip(); |
|
260 void slot_actionDemote(); |
|
261 void slot_actionYtruder(); |
|
262 void slot_actionRectifier(); |
|
263 void slot_actionIntersector(); |
|
264 void slot_actionIsecalc(); |
|
265 void slot_actionCoverer(); |
|
266 void slot_actionEdger2(); |
|
267 void slot_actionHelp(); |
|
268 void slot_actionAbout(); |
|
269 void slot_actionAboutQt(); |
|
270 void slot_actionGridCoarse(); |
|
271 void slot_actionGridMedium(); |
|
272 void slot_actionGridFine(); |
|
273 void slot_actionEdit(); |
|
274 void slot_actionMoveUp(); |
|
275 void slot_actionMoveDown(); |
|
276 void slot_actionMoveXNeg(); |
|
277 void slot_actionMoveXPos(); |
|
278 void slot_actionMoveYNeg(); |
|
279 void slot_actionMoveYPos(); |
|
280 void slot_actionMoveZNeg(); |
|
281 void slot_actionMoveZPos(); |
|
282 void slot_actionRotateXNeg(); |
|
283 void slot_actionRotateXPos(); |
|
284 void slot_actionRotateYNeg(); |
|
285 void slot_actionRotateYPos(); |
|
286 void slot_actionRotateZNeg(); |
|
287 void slot_actionRotateZPos(); |
|
288 void slot_actionRotationPoint(); |
|
289 void slot_actionAddHistoryLine(); |
|
290 void slot_actionJumpTo(); |
|
291 void slot_actionSubfileSelection(); |
|
292 void slot_actionDrawAngles(); |
|
293 |
|
294 protected: |
|
295 void closeEvent (QCloseEvent* ev); |
|
296 |
|
297 private: |
|
298 GLRenderer* m_renderer; |
|
299 LDObjectList m_sel; |
|
300 QList<LDQuickColor> m_quickColors; |
|
301 QList<QToolButton*> m_colorButtons; |
|
302 QList<QAction*> m_recentFiles; |
|
303 MessageManager* m_msglog; |
|
304 Ui_LDForgeUI* ui; |
|
305 QTabBar* m_tabs; |
|
306 bool m_updatingTabs; |
|
307 |
|
308 private slots: |
|
309 void slot_selectionChanged(); |
|
310 void slot_recentFile(); |
|
311 void slot_quickColor(); |
|
312 void slot_lastSecondCleanup(); |
|
313 void slot_editObject (QListWidgetItem* listitem); |
|
314 }; |
|
315 |
|
316 //! Pointer to the instance of MainWindow. |
|
317 extern MainWindow* g_win; |
|
318 |
|
319 //! Get an icon by name from the resources directory. |
|
320 QPixmap getIcon (QString iconName); |
|
321 |
|
322 //! \returns a list of quick colors based on the configuration entry. |
|
323 QList<LDQuickColor> quickColorsFromConfig(); |
|
324 |
|
325 //! Asks the user a yes/no question with the given \c message and the given |
|
326 //! window \c title. |
|
327 //! \returns true if the user answered yes, false if no. |
|
328 bool confirm (const QString& title, const QString& message); // Generic confirm prompt |
|
329 |
|
330 //! An overload of \c confirm(), this asks the user a yes/no question with the |
|
331 //! given \c message. |
|
332 //! \returns true if the user answered yes, false if no. |
|
333 bool confirm (const QString& message); |
|
334 |
|
335 //! Displays an error prompt with the given \c message |
|
336 void critical (const QString& message); |
|
337 |
|
338 //! Makes an icon of \c size x \c size pixels to represent \c colinfo |
|
339 QIcon makeColorIcon (LDColor* colinfo, const int size); |
|
340 |
|
341 //! Fills the given combo-box with color information |
|
342 void makeColorComboBox (QComboBox* box); |
|
343 |
|
344 //! \returns a QImage from the given raw GL \c data |
|
345 QImage imageFromScreencap (uchar* data, int w, int h); |
|
346 |
|
347 //! |
|
348 //! Takes in pairs of radio buttons and respective values and finds the first |
|
349 //! selected one. |
|
350 //! \returns returns the value of the first found radio button that was checked |
|
351 //! \returns by the user. |
|
352 //! |
|
353 template<class T> |
|
354 T radioSwitch (const T& defval, QList<Pair<QRadioButton*, T>> haystack) |
|
355 { |
|
356 for (Pair<QRadioButton*, const T&> i : haystack) |
|
357 if (i.first->isChecked()) |
|
358 return i.second; |
|
359 |
|
360 return defval; |
|
361 } |
|
362 |
|
363 //! |
|
364 //! Takes in pairs of radio buttons and respective values and checks the first |
|
365 //! found radio button whose respsective value matches \c expr have the given value. |
|
366 //! |
|
367 template<class T> |
|
368 void radioDefault (const T& expr, QList<Pair<QRadioButton*, T>> haystack) |
|
369 { |
|
370 for (Pair<QRadioButton*, const T&> i : haystack) |
|
371 { |
|
372 if (i.second == expr) |
|
373 { |
|
374 i.first->setChecked (true); |
|
375 return; |
|
376 } |
|
377 } |
|
378 } |
|