|
1 /* |
|
2 * LDForge: LDraw parts authoring CAD |
|
3 * Copyright (C) 2013 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 #ifndef GUI_H |
|
20 #define GUI_H |
|
21 |
|
22 #include <QMainWindow> |
|
23 #include <QMenu> |
|
24 #include <QToolBar> |
|
25 #include <QAction> |
|
26 #include <QToolBar> |
|
27 #include <QTextEdit> |
|
28 #include <qpushbutton.h> |
|
29 #include <qlistwidget.h> |
|
30 #include <qlabel.h> |
|
31 #include <qboxlayout.h> |
|
32 #include "gldraw.h" |
|
33 #include "config.h" |
|
34 |
|
35 class QComboBox; |
|
36 class ForgeWindow; |
|
37 class color; |
|
38 class QSplitter; |
|
39 class DelHistory; |
|
40 |
|
41 // Stuff for dialogs |
|
42 #define IMPLEMENT_DIALOG_BUTTONS \ |
|
43 bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); \ |
|
44 connect (bbx_buttons, SIGNAL (accepted ()), this, SLOT (accept ())); \ |
|
45 connect (bbx_buttons, SIGNAL (rejected ()), this, SLOT (reject ())); \ |
|
46 |
|
47 // ============================================================================= |
|
48 // Metadata for actions |
|
49 typedef struct { |
|
50 QAction** const qAct; |
|
51 keyseqconfig* const conf; |
|
52 const char* const name, *sDisplayName, *sIconName, *sDescription; |
|
53 void (*const handler) (); |
|
54 } actionmeta; |
|
55 |
|
56 extern vector<actionmeta> g_ActionMeta; |
|
57 |
|
58 // ============================================================================= |
|
59 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
60 // ============================================================================= |
|
61 #define MAKE_ACTION(NAME, DISPLAYNAME, ICONNAME, DESCR, DEFSHORTCUT) \ |
|
62 QAction* ACTION (NAME); \ |
|
63 cfg (keyseq, key_##NAME, DEFSHORTCUT); \ |
|
64 static void actionHandler_##NAME (); \ |
|
65 static ActionAdder ActionAdderInstance_##NAME (&ACTION(NAME), DISPLAYNAME, \ |
|
66 ICONNAME, DESCR, &key_##NAME, actionHandler_##NAME, #NAME); \ |
|
67 static void actionHandler_##NAME () |
|
68 |
|
69 #define EXTERN_ACTION(NAME) extern QAction* ACTION (NAME); |
|
70 #define ACTION(N) LDForgeAction_##N |
|
71 |
|
72 // Convenience macros for key sequences. |
|
73 #define KEY(N) (Qt::Key_##N) |
|
74 #define CTRL(N) (Qt::CTRL | Qt::Key_##N) |
|
75 #define SHIFT(N) (Qt::SHIFT | Qt::Key_##N) |
|
76 #define CTRL_SHIFT(N) (Qt::CTRL | Qt::SHIFT | Qt::Key_##N) |
|
77 |
|
78 // ============================================================================= |
|
79 typedef struct { |
|
80 color* col; |
|
81 QPushButton* btn; |
|
82 bool bSeparator; |
|
83 } quickColorMetaEntry; |
|
84 |
|
85 // ============================================================================= |
|
86 // ActionAdder |
|
87 // |
|
88 // The ACTION macro expands into - among other stuff - into an instance of this. |
|
89 // This class' constructor creates meta for the newly defined action and stores |
|
90 // it in g_ActionMeta. It is not supposed to be used directly! |
|
91 // ============================================================================= |
|
92 class ActionAdder { |
|
93 public: |
|
94 ActionAdder (QAction** qAct, const char* sDisplayName, const char* sIconName, |
|
95 const char* sDescription, keyseqconfig* conf, void (*const handler) (), |
|
96 const char* name) |
|
97 { |
|
98 actionmeta meta = {qAct, conf, name, sDisplayName, sIconName, sDescription, handler}; |
|
99 g_ActionMeta.push_back (meta); |
|
100 } |
|
101 }; |
|
102 |
|
103 // ============================================================================= |
|
104 // ObjectList |
|
105 // |
|
106 // Object list class for ForgeWindow |
|
107 // ============================================================================= |
|
108 class ObjectList : public QListWidget { |
|
109 Q_OBJECT |
|
110 |
|
111 protected: |
|
112 void contextMenuEvent (QContextMenuEvent* ev); |
|
113 }; |
|
114 |
|
115 // ============================================================================= |
|
116 // ForgeWindow |
|
117 // |
|
118 // The one main GUI class. Hosts the renderer, object list, message log. Contains |
|
119 // slot_action, which is what all actions connect to. Manages menus and toolbars. |
|
120 // Large and in charge. |
|
121 // ============================================================================= |
|
122 class ForgeWindow : public QMainWindow { |
|
123 Q_OBJECT |
|
124 |
|
125 public: |
|
126 ForgeWindow (); |
|
127 void buildObjList (); |
|
128 void setTitle (); |
|
129 void refresh (); |
|
130 ulong getInsertionPoint (); |
|
131 void deleteSelection (vector<ulong>* ulapIndices, std::vector<LDObject*>* papObjects); |
|
132 void updateToolBars (); |
|
133 void updateRecentFilesMenu (); |
|
134 void updateSelection (); |
|
135 void updateGridToolBar (); |
|
136 bool isSelected (LDObject* obj); |
|
137 short getSelectedColor(); |
|
138 LDObject::Type uniformSelectedType (); |
|
139 void scrollToSelection (); |
|
140 void spawnContextMenu (const QPoint pos); |
|
141 DelHistory* deleteObjVector (const std::vector<LDObject*> objs); |
|
142 DelHistory* deleteSelection (); |
|
143 DelHistory* deleteByColor (const short colnum); |
|
144 GLRenderer* R () { return m_renderer; } |
|
145 std::vector<LDObject*>& sel () { return m_sel; } |
|
146 void setQuickColorMeta (std::vector<quickColorMetaEntry>& quickColorMeta) { |
|
147 m_colorMeta = quickColorMeta; |
|
148 } |
|
149 |
|
150 protected: |
|
151 void closeEvent (QCloseEvent* ev); |
|
152 void logVA (LogType eType, const char* fmtstr, va_list va); |
|
153 |
|
154 friend void logf (const char* fmt, ...); |
|
155 friend void logf (LogType eType, const char* fmt, ...); |
|
156 friend void warnf (const char* fmt, ...); |
|
157 friend void infof (const char* fmt, ...); |
|
158 friend void succf (const char* fmt, ...); |
|
159 friend void errf (const char* fmt, ...); |
|
160 friend void devf (const char* fmt, ...); |
|
161 |
|
162 private: |
|
163 GLRenderer* m_renderer; |
|
164 ObjectList* m_objList; |
|
165 QMenu* m_recentFilesMenu; |
|
166 QSplitter* m_splitter; |
|
167 str m_msglogHTML; |
|
168 QToolBar* m_colorToolBar; |
|
169 std::vector<QToolBar*> m_toolBars; |
|
170 std::vector<LDObject*> m_sel; |
|
171 std::vector<quickColorMetaEntry> m_colorMeta; |
|
172 std::vector<QPushButton*> m_colorButtons; |
|
173 std::vector<QAction*> m_recentFiles; |
|
174 |
|
175 void createMenuActions (); |
|
176 void createMenus (); |
|
177 void createToolbars (); |
|
178 void initSingleToolBar (const char* name); |
|
179 void addToolBarAction (const char* name); |
|
180 |
|
181 QMenu* initMenu (const char* name); |
|
182 void addMenuAction (const char* name); |
|
183 |
|
184 private slots: |
|
185 void slot_selectionChanged (); |
|
186 void slot_action (); |
|
187 void slot_recentFile (); |
|
188 void slot_quickColor (); |
|
189 void slot_lastSecondCleanup (); |
|
190 }; |
|
191 |
|
192 // ============================================================================= |
|
193 // LabeledWidget |
|
194 // |
|
195 // Convenience class for a widget with a label beside it. |
|
196 // ============================================================================= |
|
197 template<class R> class LabeledWidget : public QWidget { |
|
198 public: |
|
199 explicit LabeledWidget (const char* labelstr, QWidget* parent = null) : QWidget (parent) { |
|
200 m_widget = new R (this); |
|
201 commonInit (labelstr); |
|
202 } |
|
203 |
|
204 explicit LabeledWidget (const char* labelstr, R* widget, QWidget* parent = null) : |
|
205 QWidget (parent), m_widget (widget) |
|
206 { |
|
207 commonInit (labelstr); |
|
208 } |
|
209 |
|
210 explicit LabeledWidget (QWidget* parent = 0, Qt::WindowFlags f = 0) { |
|
211 m_widget = new R (this); |
|
212 commonInit (""); |
|
213 } |
|
214 |
|
215 R* widget () const { return m_widget; } |
|
216 R* w () const { return m_widget; } |
|
217 QLabel* label () const { return m_label; } |
|
218 QLabel* l () const { return m_label; } |
|
219 void setWidget (R* widget) { m_widget = widget; } |
|
220 void setLabel (QLabel* label) { m_label = label; } |
|
221 operator R* () { return m_widget; } |
|
222 |
|
223 private: |
|
224 Q_DISABLE_COPY (LabeledWidget<R>) |
|
225 |
|
226 void commonInit (const char* labelstr) { |
|
227 m_label = new QLabel (labelstr, this); |
|
228 m_layout = new QHBoxLayout; |
|
229 m_layout->addWidget (m_label); |
|
230 m_layout->addWidget (m_widget); |
|
231 setLayout (m_layout); |
|
232 } |
|
233 |
|
234 R* m_widget; |
|
235 QLabel* m_label; |
|
236 QHBoxLayout* m_layout; |
|
237 }; |
|
238 |
|
239 // ----------------------------------------------------------------------------- |
|
240 // Other GUI-related stuff not directly part of ForgeWindow: |
|
241 QPixmap getIcon (const char* sIconName); |
|
242 std::vector<quickColorMetaEntry> parseQuickColorMeta (); |
|
243 bool confirm (str title, str msg); |
|
244 bool confirm (str msg); |
|
245 void critical (str msg); |
|
246 QAction* findAction (str name); |
|
247 void makeColorSelector (QComboBox* box); |
|
248 |
|
249 // ----------------------------------------------------------------------------- |
|
250 // Pointer to the instance of ForgeWindow. |
|
251 extern ForgeWindow* g_win; |
|
252 |
|
253 #endif // GUI_H |