|         | 
     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 |