24 #include "file.h" |
24 #include "file.h" |
25 #include "config.h" |
25 #include "config.h" |
26 #include "misc.h" |
26 #include "misc.h" |
27 #include "colors.h" |
27 #include "colors.h" |
28 #include "config.h" |
28 #include "config.h" |
29 #include "zz_addObjectDialog.h" |
29 |
30 #include "zz_colorSelectDialog.h" |
30 EXTERN_ACTION (newFile) |
31 #include "zz_configDialog.h" |
31 EXTERN_ACTION (open) |
32 #include "zz_newPartDialog.h" |
32 EXTERN_ACTION (save) |
33 #include "zz_setContentsDialog.h" |
33 EXTERN_ACTION (saveAs) |
34 |
34 EXTERN_ACTION (settings) |
35 // ============================================================================= |
35 EXTERN_ACTION (exit) |
36 // ACTION ARMADA |
36 EXTERN_ACTION (cut) |
37 namespace Actions { |
37 EXTERN_ACTION (copy) |
38 QAction* newFile, *open, *save, *saveAs, *exit; |
38 EXTERN_ACTION (paste) |
39 QAction* cut, *copy, *paste, *del; |
39 EXTERN_ACTION (del) |
40 QAction* newSubfile, *newLine, *newTriangle, *newQuad; |
40 EXTERN_ACTION (setColor) |
41 QAction* newCondLine, *newComment, *newVertex; |
41 EXTERN_ACTION (inlineContents) |
42 QAction* splitQuads, *setContents, *setColor; |
42 EXTERN_ACTION (deepInline) |
43 QAction* inlineContents, *deepInline, *makeBorders; |
43 EXTERN_ACTION (splitQuads) |
44 QAction* settings; |
44 EXTERN_ACTION (setContents) |
45 QAction* help, *about, *aboutQt; |
45 EXTERN_ACTION (makeBorders) |
46 }; |
46 EXTERN_ACTION (newSubfile) |
47 |
47 EXTERN_ACTION (newLine) |
48 // Key-binding configurations |
48 EXTERN_ACTION (newCondLine) |
49 cfg (keyseq, key_newFile, (Qt::CTRL | Qt::Key_N)); |
49 EXTERN_ACTION (newTriangle) |
50 cfg (keyseq, key_open, (Qt::CTRL | Qt::Key_O)); |
50 EXTERN_ACTION (newQuad) |
51 cfg (keyseq, key_save, (Qt::CTRL | Qt::Key_S)); |
51 EXTERN_ACTION (newVertex) |
52 cfg (keyseq, key_saveAs, (Qt::CTRL | Qt::SHIFT | Qt::Key_S)); |
52 EXTERN_ACTION (newComment) |
53 cfg (keyseq, key_exit, (Qt::CTRL | Qt::Key_Q)); |
53 EXTERN_ACTION (help) |
54 cfg (keyseq, key_cut, (Qt::CTRL | Qt::Key_X)); |
54 EXTERN_ACTION (about) |
55 cfg (keyseq, key_copy, (Qt::CTRL | Qt::Key_C)); |
55 EXTERN_ACTION (aboutQt) |
56 cfg (keyseq, key_paste, (Qt::CTRL | Qt::Key_V)); |
56 |
57 cfg (keyseq, key_del, (Qt::Key_Delete)); |
|
58 cfg (keyseq, key_newSubfile, 0); |
|
59 cfg (keyseq, key_newLine, 0); |
|
60 cfg (keyseq, key_newTriangle, 0); |
|
61 cfg (keyseq, key_newQuad, 0); |
|
62 cfg (keyseq, key_newCondLine, 0); |
|
63 cfg (keyseq, key_newComment, 0); |
|
64 cfg (keyseq, key_newVertex, 0); |
|
65 cfg (keyseq, key_splitQuads, 0); |
|
66 cfg (keyseq, key_setContents, 0); |
|
67 cfg (keyseq, key_inlineContents, (Qt::CTRL | Qt::Key_I)); |
|
68 cfg (keyseq, key_deepInline, (Qt::CTRL | Qt::SHIFT | Qt::Key_I)); |
|
69 cfg (keyseq, key_makeBorders, (Qt::CTRL | Qt::SHIFT | Qt::Key_B)); |
|
70 cfg (keyseq, key_settings, 0); |
|
71 cfg (keyseq, key_help, (Qt::Key_F1)); |
|
72 cfg (keyseq, key_about, 0); |
|
73 cfg (keyseq, key_aboutQt, 0); |
|
74 cfg (keyseq, key_setColor, 0); |
|
75 |
|
76 vector<LDObject*> g_Clipboard; |
|
77 vector<actionmeta> g_ActionMeta; |
57 vector<actionmeta> g_ActionMeta; |
78 |
|
79 cfg (bool, lv_colorize, true); |
58 cfg (bool, lv_colorize, true); |
80 |
59 |
81 // ============================================================================= |
60 // ============================================================================= |
82 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
61 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
83 // ============================================================================= |
62 // ============================================================================= |
117 } |
96 } |
118 |
97 |
119 // ============================================================================= |
98 // ============================================================================= |
120 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
99 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
121 // ============================================================================= |
100 // ============================================================================= |
122 #define ACTION(N) (Actions::N) |
|
123 #define MAKE_ACTION(OBJECT, DISPLAYNAME, IMAGENAME, DESCR) \ |
|
124 ACTION (OBJECT) = new QAction (QIcon ("./icons/" IMAGENAME ".png"), tr (DISPLAYNAME), this); \ |
|
125 ACTION (OBJECT)->setStatusTip (tr (DESCR)); \ |
|
126 connect (ACTION (OBJECT), SIGNAL (triggered ()), this, SLOT (slot_##OBJECT ())); \ |
|
127 { \ |
|
128 actionmeta meta = {&ACTION (OBJECT), &key_##OBJECT}; \ |
|
129 g_ActionMeta.push_back (meta); \ |
|
130 } |
|
131 |
|
132 void ForgeWindow::createMenuActions () { |
101 void ForgeWindow::createMenuActions () { |
133 // Long menu names go here so my cool action definition table doesn't get out of proportions |
102 // Create the actions based on stored meta. |
134 char const* sNewCdLineText = "New Conditional Line", |
103 for (actionmeta meta : g_ActionMeta) { |
135 *sNewQuadText = "New Quadrilateral", |
104 QAction*& qAct = *meta.qAct; |
136 *sAboutText = "About " APPNAME_DISPLAY; |
105 qAct = new QAction (getIcon (meta.sIconName), meta.sDisplayName, this); |
137 |
106 qAct->setStatusTip (meta.sDescription); |
138 MAKE_ACTION (newFile, "&New", "brick", "Create a new part model.") |
107 qAct->setShortcut (*meta.conf); |
139 MAKE_ACTION (open, "&Open", "file-open", "Load a part model from a file.") |
108 |
140 MAKE_ACTION (save, "&Save", "file-save", "Save the part model.") |
109 connect (qAct, SIGNAL (triggered ()), this, SLOT (slot_action ())); |
141 MAKE_ACTION (saveAs, "Save &As", "file-save-as", "Save the part to a specific file.") |
110 } |
142 MAKE_ACTION (exit, "&Exit", "exit", "Close " APPNAME_DISPLAY ".") |
|
143 |
|
144 MAKE_ACTION (cut, "Cut", "cut", "Cut the current selection to clipboard.") |
|
145 MAKE_ACTION (copy, "Copy", "copy", "Copy the current selection to clipboard.") |
|
146 MAKE_ACTION (paste, "Paste", "paste", "Paste clipboard contents.") |
|
147 MAKE_ACTION (del, "Delete", "delete", "Delete the selection") |
|
148 |
|
149 MAKE_ACTION (setColor, "Set Color", "palette", "Set the color on given objects.") |
|
150 MAKE_ACTION (inlineContents,"Inline", "inline", "Inline selected subfiles.") |
|
151 MAKE_ACTION (deepInline, "Deep Inline", "inline-deep", "Recursively inline selected subfiles down to polygons only.") |
|
152 MAKE_ACTION (splitQuads, "Split Quads", "quad-split", "Split quads into triangles.") |
|
153 MAKE_ACTION (setContents, "Set Contents", "set-contents", "Set the raw code of this object.") |
|
154 MAKE_ACTION (makeBorders, "Make Borders", "make-borders", "Add borders around given polygons.") |
|
155 |
|
156 MAKE_ACTION (newSubfile, "New Subfile", "add-subfile", "Creates a new subfile reference.") |
|
157 MAKE_ACTION (newLine, "New Line", "add-line", "Creates a new line.") |
|
158 MAKE_ACTION (newTriangle, "New Triangle", "add-triangle", "Creates a new triangle.") |
|
159 MAKE_ACTION (newQuad, sNewQuadText, "add-quad", "Creates a new quadrilateral.") |
|
160 MAKE_ACTION (newCondLine, sNewCdLineText, "add-condline", "Creates a new conditional line.") |
|
161 MAKE_ACTION (newComment, "New Comment", "add-comment", "Creates a new comment.") |
|
162 MAKE_ACTION (newVertex, "New Vertex", "add-vertex", "Creates a new vertex.") |
|
163 |
|
164 MAKE_ACTION (settings, "Settings", "settings", "Edit the settings of " APPNAME_DISPLAY ".") |
|
165 |
|
166 MAKE_ACTION (help, "Help", "help", "Shows the " APPNAME_DISPLAY " help manual.") |
|
167 MAKE_ACTION (about, sAboutText, "ldforge", "Shows information about " APPNAME_DISPLAY ".") |
|
168 MAKE_ACTION (aboutQt, "About Qt", "aboutQt", "Shows information about Qt.") |
|
169 |
|
170 // Apply the shortcuts now |
|
171 for (actionmeta meta : g_ActionMeta) |
|
172 (*meta.qAct)->setShortcut (*meta.conf); |
|
173 |
111 |
174 // things not implemented yet |
112 // things not implemented yet |
175 QAction* const qaDisabledActions[] = { |
113 QAction* const qaDisabledActions[] = { |
176 ACTION (newSubfile), |
114 ACTION_NAME (newSubfile), |
177 ACTION (about), |
115 ACTION_NAME (about), |
178 ACTION (help), |
116 ACTION_NAME (help), |
179 }; |
117 }; |
180 |
118 |
181 for (QAction* act : qaDisabledActions) |
119 for (QAction* act : qaDisabledActions) |
182 act->setEnabled (false); |
120 act->setEnabled (false); |
183 } |
121 } |
184 |
122 |
185 // ============================================================================= |
123 // ============================================================================= |
186 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
124 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
187 // ============================================================================= |
125 // ============================================================================= |
188 #define ADD_MENU_ITEM(MENU, ACT) q##MENU##Menu->addAction (ACTION (ACT)); |
126 #define ADD_MENU_ITEM(MENU, ACT) q##MENU##Menu->addAction (ACTION_NAME (ACT)); |
189 |
127 |
190 void ForgeWindow::createMenus () { |
128 void ForgeWindow::createMenus () { |
191 // File menu |
129 // File menu |
192 qFileMenu = menuBar ()->addMenu (tr ("&File")); |
130 qFileMenu = menuBar ()->addMenu (tr ("&File")); |
193 ADD_MENU_ITEM (File, newFile) // New |
131 ADD_MENU_ITEM (File, newFile) // New |
197 qFileMenu->addSeparator (); // ------- |
135 qFileMenu->addSeparator (); // ------- |
198 ADD_MENU_ITEM (File, settings) // Settings |
136 ADD_MENU_ITEM (File, settings) // Settings |
199 qFileMenu->addSeparator (); // ------- |
137 qFileMenu->addSeparator (); // ------- |
200 ADD_MENU_ITEM (File, exit) // Exit |
138 ADD_MENU_ITEM (File, exit) // Exit |
201 |
139 |
202 // Edit menu |
140 // Insert menu |
203 qInsertMenu = menuBar ()->addMenu (tr ("&Insert")); |
141 qInsertMenu = menuBar ()->addMenu (tr ("&Insert")); |
204 ADD_MENU_ITEM (Insert, newSubfile) // New Subfile |
142 ADD_MENU_ITEM (Insert, newSubfile) // New Subfile |
205 ADD_MENU_ITEM (Insert, newLine) // New Line |
143 ADD_MENU_ITEM (Insert, newLine) // New Line |
206 ADD_MENU_ITEM (Insert, newTriangle) // New Triangle |
144 ADD_MENU_ITEM (Insert, newTriangle) // New Triangle |
207 ADD_MENU_ITEM (Insert, newQuad) // New Quad |
145 ADD_MENU_ITEM (Insert, newQuad) // New Quad |
208 ADD_MENU_ITEM (Insert, newCondLine) // New Conditional Line |
146 ADD_MENU_ITEM (Insert, newCondLine) // New Conditional Line |
209 ADD_MENU_ITEM (Insert, newComment) // New Comment |
147 ADD_MENU_ITEM (Insert, newComment) // New Comment |
210 ADD_MENU_ITEM (Insert, newVertex) // New Vertex |
148 ADD_MENU_ITEM (Insert, newVertex) // New Vertex |
211 |
149 |
|
150 // Edit menu |
212 qEditMenu = menuBar ()->addMenu (tr ("&Edit")); |
151 qEditMenu = menuBar ()->addMenu (tr ("&Edit")); |
213 ADD_MENU_ITEM (Edit, cut) // Cut |
152 ADD_MENU_ITEM (Edit, cut) // Cut |
214 ADD_MENU_ITEM (Edit, copy) // Copy |
153 ADD_MENU_ITEM (Edit, copy) // Copy |
215 ADD_MENU_ITEM (Edit, paste) // Paste |
154 ADD_MENU_ITEM (Edit, paste) // Paste |
216 ADD_MENU_ITEM (Edit, del) // Delete |
155 ADD_MENU_ITEM (Edit, del) // Delete |
290 } |
229 } |
291 |
230 |
292 // ============================================================================= |
231 // ============================================================================= |
293 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
232 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
294 // ============================================================================= |
233 // ============================================================================= |
295 void ForgeWindow::slot_newFile () { |
234 void ForgeWindow::slot_action () { |
296 // newFile (); |
235 // Get the action that triggered this slot. |
297 NewPartDialog::StaticDialog (); |
236 QAction* qAct = static_cast<QAction*> (sender ()); |
298 } |
237 |
299 |
238 // Find the meta for the action. |
300 void ForgeWindow::slot_open () { |
239 actionmeta* pMeta = nullptr; |
301 str zName; |
240 |
302 zName += QFileDialog::getOpenFileName (this, "Open File", |
241 for (actionmeta meta : g_ActionMeta) { |
303 "", "LDraw files (*.dat *.ldr)"); |
242 if (*meta.qAct == qAct) { |
304 |
243 pMeta = &meta; |
305 if (~zName) |
244 break; |
306 openMainFile (zName); |
245 } |
307 } |
246 } |
308 |
247 |
309 void ForgeWindow::slot_save () { |
248 if (!pMeta) { |
310 if (!~g_CurrentFile->zFileName) { |
249 fprintf (stderr, "unknown signal sender %p!\n", qAct); |
311 // If we don't have a file name, this is an anonymous file created |
|
312 // with the new file command. We cannot save without a name so ask |
|
313 // the user for one. |
|
314 slot_saveAs (); |
|
315 return; |
250 return; |
316 } |
251 } |
317 |
252 |
318 g_CurrentFile->save (); |
253 // We have the meta, now call the handler. |
319 } |
254 (*pMeta->handler) (); |
320 |
|
321 void ForgeWindow::slot_saveAs () { |
|
322 str zName; |
|
323 zName += QFileDialog::getSaveFileName (this, "Save As", |
|
324 "", "LDraw files (*.dat *.ldr)"); |
|
325 |
|
326 if (~zName && g_CurrentFile->save (zName)) |
|
327 g_CurrentFile->zFileName = zName; |
|
328 } |
|
329 |
|
330 void ForgeWindow::slot_settings () { |
|
331 ConfigDialog::staticDialog (this); |
|
332 } |
|
333 |
|
334 void ForgeWindow::slot_exit () { |
|
335 exit (0); |
|
336 } |
|
337 |
|
338 void ForgeWindow::slot_newSubfile () { |
|
339 |
|
340 } |
|
341 |
|
342 void ForgeWindow::slot_newLine () { |
|
343 AddObjectDialog::staticDialog (OBJ_Line, this); |
|
344 } |
|
345 |
|
346 void ForgeWindow::slot_newTriangle () { |
|
347 AddObjectDialog::staticDialog (OBJ_Triangle, this); |
|
348 } |
|
349 |
|
350 void ForgeWindow::slot_newQuad () { |
|
351 AddObjectDialog::staticDialog (OBJ_Quad, this); |
|
352 } |
|
353 |
|
354 void ForgeWindow::slot_newCondLine () { |
|
355 AddObjectDialog::staticDialog (OBJ_CondLine, this); |
|
356 } |
|
357 |
|
358 void ForgeWindow::slot_newComment () { |
|
359 AddObjectDialog::staticDialog (OBJ_Comment, this); |
|
360 } |
|
361 |
|
362 void ForgeWindow::slot_help () { |
|
363 |
|
364 } |
|
365 |
|
366 void ForgeWindow::slot_about () { |
|
367 |
|
368 } |
|
369 |
|
370 void ForgeWindow::slot_aboutQt () { |
|
371 QMessageBox::aboutQt (this); |
|
372 } |
|
373 |
|
374 // ============================================================================= |
|
375 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
376 // ============================================================================= |
|
377 bool ForgeWindow::copyToClipboard () { |
|
378 vector<LDObject*> objs = getSelectedObjects (); |
|
379 |
|
380 if (objs.size() == 0) |
|
381 return false; |
|
382 |
|
383 // Clear the clipboard first. |
|
384 for (LDObject* obj : g_Clipboard) |
|
385 delete obj; |
|
386 |
|
387 g_Clipboard.clear (); |
|
388 |
|
389 // Now, copy the contents into the clipboard. The objects should be |
|
390 // separate objects so that modifying the existing ones does not affect |
|
391 // the clipboard. Thus, we add clones of the objects to the clipboard, not |
|
392 // the objects themselves. |
|
393 for (ulong i = 0; i < objs.size(); ++i) |
|
394 g_Clipboard.push_back (objs[i]->clone ()); |
|
395 |
|
396 return true; |
|
397 } |
|
398 |
|
399 // ============================================================================= |
|
400 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
401 // ============================================================================= |
|
402 void ForgeWindow::slot_cut () { |
|
403 if (!copyToClipboard ()) |
|
404 return; |
|
405 |
|
406 deleteSelection (); |
|
407 |
|
408 ACTION (paste)->setEnabled (true); |
|
409 refresh (); |
|
410 } |
|
411 |
|
412 // ============================================================================= |
|
413 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
414 // ============================================================================= |
|
415 void ForgeWindow::slot_copy () { |
|
416 if (copyToClipboard ()) |
|
417 ACTION (paste)->setEnabled (true); |
|
418 } |
|
419 |
|
420 // ============================================================================= |
|
421 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
422 // ============================================================================= |
|
423 void ForgeWindow::slot_paste () { |
|
424 for (LDObject* obj : g_Clipboard) |
|
425 g_CurrentFile->addObject (obj->clone ()); |
|
426 |
|
427 refresh (); |
|
428 } |
|
429 |
|
430 // ============================================================================= |
|
431 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
432 // ============================================================================= |
|
433 void ForgeWindow::slot_del () { |
|
434 deleteSelection (); |
|
435 refresh (); |
|
436 } |
|
437 |
|
438 // ============================================================================= |
|
439 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
440 // ============================================================================= |
|
441 void ForgeWindow::slot_newVertex () { |
|
442 AddObjectDialog::staticDialog (OBJ_Vertex, this); |
|
443 } |
|
444 |
|
445 // ============================================================================= |
|
446 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
447 // ============================================================================= |
|
448 void ForgeWindow::doInline (bool bDeep) { |
|
449 vector<LDObject*> sel = getSelectedObjects (); |
|
450 |
|
451 for (LDObject* obj : sel) { |
|
452 // Obviously, only subfiles can be inlined. |
|
453 if (obj->getType() != OBJ_Subfile) |
|
454 continue; |
|
455 |
|
456 // Get the index of the subfile so we know where to insert the |
|
457 // inlined contents. |
|
458 long idx = obj->getIndex (g_CurrentFile); |
|
459 if (idx == -1) |
|
460 continue; |
|
461 |
|
462 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
|
463 |
|
464 // Get the inlined objects. These are clones of the subfile's contents. |
|
465 vector<LDObject*> objs = ref->inlineContents (bDeep, true); |
|
466 |
|
467 // Merge in the inlined objects |
|
468 for (LDObject* inlineobj : objs) |
|
469 g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + idx++, inlineobj); |
|
470 |
|
471 // Delete the subfile now as it's been inlined. |
|
472 g_CurrentFile->forgetObject (ref); |
|
473 delete ref; |
|
474 } |
|
475 |
|
476 refresh (); |
|
477 } |
|
478 |
|
479 void ForgeWindow::slot_inlineContents () { |
|
480 doInline (false); |
|
481 } |
|
482 |
|
483 void ForgeWindow::slot_deepInline () { |
|
484 doInline (true); |
|
485 } |
|
486 |
|
487 // ============================================================================= |
|
488 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
489 // ============================================================================= |
|
490 void ForgeWindow::slot_splitQuads () { |
|
491 vector<LDObject*> objs = getSelectedObjects (); |
|
492 |
|
493 for (LDObject* obj : objs) { |
|
494 if (obj->getType() != OBJ_Quad) |
|
495 continue; |
|
496 |
|
497 // Find the index of this quad |
|
498 long lIndex = obj->getIndex (g_CurrentFile); |
|
499 |
|
500 if (lIndex == -1) { |
|
501 // couldn't find it? |
|
502 logf (LOG_Error, "Couldn't find quad %p in " |
|
503 "current object list!!\n", this); |
|
504 return; |
|
505 } |
|
506 |
|
507 std::vector<LDTriangle*> triangles = static_cast<LDQuad*> (obj)->splitToTriangles (); |
|
508 |
|
509 // Replace the quad with the first triangle and add the second triangle |
|
510 // after the first one. |
|
511 g_CurrentFile->objects[lIndex] = triangles[0]; |
|
512 g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + lIndex + 1, triangles[1]); |
|
513 |
|
514 // Delete this quad now, it has been split. |
|
515 delete this; |
|
516 } |
|
517 |
|
518 refresh (); |
|
519 } |
|
520 |
|
521 // ============================================================================= |
|
522 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
523 // ============================================================================= |
|
524 void ForgeWindow::slot_setContents () { |
|
525 if (qObjList->selectedItems().size() != 1) |
|
526 return; |
|
527 |
|
528 LDObject* obj = getSelectedObjects ()[0]; |
|
529 SetContentsDialog::staticDialog (obj, this); |
|
530 } |
|
531 |
|
532 // ============================================================================= |
|
533 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
534 // ============================================================================= |
|
535 void ForgeWindow::slot_setColor () { |
|
536 if (qObjList->selectedItems().size() <= 0) |
|
537 return; |
|
538 |
|
539 short dColor; |
|
540 short dDefault = -1; |
|
541 |
|
542 std::vector<LDObject*> objs = getSelectedObjects (); |
|
543 |
|
544 // If all selected objects have the same color, said color is our default |
|
545 // value to the color selection dialog. |
|
546 for (LDObject* obj : objs) { |
|
547 if (obj->dColor == -1) |
|
548 continue; // doesn't use color |
|
549 |
|
550 if (dDefault != -1 && obj->dColor != dDefault) { |
|
551 // No consensus in object color, therefore we don't have a |
|
552 // proper default value to use. |
|
553 dDefault = -1; |
|
554 break; |
|
555 } |
|
556 |
|
557 if (dDefault == -1) |
|
558 dDefault = obj->dColor; |
|
559 } |
|
560 |
|
561 // Show the dialog to the user now and ask for a color. |
|
562 if (ColorSelectDialog::staticDialog (dColor, dDefault, this)) { |
|
563 for (LDObject* obj : objs) |
|
564 if (obj->dColor != -1) |
|
565 obj->dColor = dColor; |
|
566 |
|
567 refresh (); |
|
568 } |
|
569 } |
|
570 |
|
571 // ============================================================================= |
|
572 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
573 // ============================================================================= |
|
574 void ForgeWindow::slot_makeBorders () { |
|
575 vector<LDObject*> objs = getSelectedObjects (); |
|
576 |
|
577 for (LDObject* obj : objs) { |
|
578 if (obj->getType() != OBJ_Quad && obj->getType() != OBJ_Triangle) |
|
579 continue; |
|
580 |
|
581 short dNumLines; |
|
582 LDLine* lines[4]; |
|
583 |
|
584 if (obj->getType() == OBJ_Quad) { |
|
585 dNumLines = 4; |
|
586 |
|
587 LDQuad* quad = static_cast<LDQuad*> (obj); |
|
588 lines[0] = new LDLine (quad->vaCoords[0], quad->vaCoords[1]); |
|
589 lines[1] = new LDLine (quad->vaCoords[1], quad->vaCoords[2]); |
|
590 lines[2] = new LDLine (quad->vaCoords[2], quad->vaCoords[3]); |
|
591 lines[3] = new LDLine (quad->vaCoords[3], quad->vaCoords[0]); |
|
592 } else { |
|
593 dNumLines = 3; |
|
594 |
|
595 LDTriangle* tri = static_cast<LDTriangle*> (obj); |
|
596 lines[0] = new LDLine (tri->vaCoords[0], tri->vaCoords[1]); |
|
597 lines[1] = new LDLine (tri->vaCoords[1], tri->vaCoords[2]); |
|
598 lines[2] = new LDLine (tri->vaCoords[2], tri->vaCoords[0]); |
|
599 } |
|
600 |
|
601 for (short i = 0; i < dNumLines; ++i) { |
|
602 lines[i]->dColor = dEdgeColor; |
|
603 g_CurrentFile->addObject (lines[i]); |
|
604 } |
|
605 } |
|
606 |
|
607 refresh (); |
|
608 } |
255 } |
609 |
256 |
610 // ============================================================================= |
257 // ============================================================================= |
611 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
258 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
612 // ============================================================================= |
259 // ============================================================================= |