Sun, 10 Jan 2021 15:28:44 +0200
added tool base code
--- a/CMakeLists.txt Thu Nov 05 14:29:58 2020 +0200 +++ b/CMakeLists.txt Sun Jan 10 15:28:44 2021 +0200 @@ -25,6 +25,7 @@ source_group("3.1 Settings editor" REGULAR_EXPRESSION "src/settingseditor/.+\\.(cpp|h|ui)") source_group("3 User interface" REGULAR_EXPRESSION "src/(mainwindow|document|documentmanager|uiutilities)\\.(cpp|h|ui)") source_group("2 Model handling" REGULAR_EXPRESSION "src/(model|modeleditcontext|libraries|colors|parser)\\.(cpp|h|ui)") +source_group("6 Editing tools" REGULAR_EXPRESSION "src/tools/.+\\.(cpp|h|ui)") set (LDFORGE_SOURCES src/colors.cpp @@ -67,6 +68,9 @@ src/widgets/doublespinbox.cpp src/widgets/matrixeditor.cpp src/widgets/vec3editor.cpp + src/tools/basetool.cpp + src/tools/selecttool.cpp + src/tools/drawtool.cpp ) set (LDFORGE_HEADERS src/basics.h @@ -118,6 +122,9 @@ src/widgets/doublespinbox.h src/widgets/matrixeditor.h src/widgets/vec3editor.h + src/tools/selecttool.h + src/tools/basetool.h + src/tools/drawtool.h ) set (LDFORGE_FORMS src/document.ui
--- a/locale/fi.ts Thu Nov 05 14:29:58 2020 +0200 +++ b/locale/fi.ts Sun Jan 10 15:28:44 2021 +0200 @@ -2,6 +2,34 @@ <!DOCTYPE TS> <TS version="2.1" language="fi"> <context> + <name>ColorSelectDialog</name> + <message> + <location filename="../src/widgets/colorselectdialog.ui" line="20"/> + <source>Choose colour</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/widgets/colorselectdialog.ui" line="64"/> + <source>Search...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/widgets/colorselectdialog.ui" line="71"/> + <source>TextLabel</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/widgets/colorselectdialog.ui" line="98"/> + <source>Colour index:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/widgets/colorselectdialog.ui" line="112"/> + <source>Direct colour...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Document</name> <message> <location filename="../src/document.ui" line="14"/> @@ -10,6 +38,19 @@ </message> </context> <context> + <name>DrawTool</name> + <message> + <location filename="../src/tools/drawtool.cpp" line="8"/> + <source>Draw</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/tools/drawtool.cpp" line="14"/> + <source>Draw new elements into the model.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>KeyboardShortcutsEditor</name> <message> <location filename="../src/settingseditor/keyboardshortcutseditor.cpp" line="51"/> @@ -137,76 +178,91 @@ </message> <message> <location filename="../src/mainwindow.ui" line="64"/> + <source>toolBar</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/mainwindow.ui" line="75"/> <source>Quit</source> <translation>Lopeta</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="69"/> + <location filename="../src/mainwindow.ui" line="80"/> <source>Open…</source> <translation>Avaa...</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="72"/> + <location filename="../src/mainwindow.ui" line="83"/> <source>Ctrl+O</source> <translation>Ctrl+O</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="77"/> + <location filename="../src/mainwindow.ui" line="88"/> <source>New</source> <translation>Uusi</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="80"/> + <location filename="../src/mainwindow.ui" line="91"/> <source>Ctrl+N</source> <translation>Ctrl+N</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="85"/> + <location filename="../src/mainwindow.ui" line="96"/> <source>Preferences…</source> <translation>Asetukset...</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="93"/> + <location filename="../src/mainwindow.ui" line="104"/> <source>Normal colours</source> <translation type="unfinished">Perusvärit</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="101"/> + <location filename="../src/mainwindow.ui" line="112"/> <source>BFC color coding</source> <translation type="unfinished">BFC-värikoodaus</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="109"/> + <location filename="../src/mainwindow.ui" line="120"/> <source>Random colours</source> <translation type="unfinished">Satunnaiset värit</translation> </message> <message> - <location filename="../src/mainwindow.ui" line="117"/> + <location filename="../src/mainwindow.ui" line="128"/> <source>Pick scene colours</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="98"/> + <location filename="../src/mainwindow.cpp" line="102"/> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/mainwindow.cpp" line="102"/> + <source>Unable to construct %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/mainwindow.cpp" line="123"/> <source>Open model</source> <translation>Avaa malli</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="100"/> + <location filename="../src/mainwindow.cpp" line="125"/> <source>LDraw models (*.ldr *.dat)</source> <translation>LDraw-mallit (*.ldr *.dat)</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="119"/> + <location filename="../src/mainwindow.cpp" line="144"/> <source>Problem loading references</source> <translation type="unfinished">Ongelma viitteiden lataamisessa</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="129"/> + <location filename="../src/mainwindow.cpp" line="154"/> <source>Problem opening file</source> <translation>Ongelma tiedoston avaamisessa</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="131"/> + <location filename="../src/mainwindow.cpp" line="156"/> <source>Could not open %1: %2</source> <translation>Ei voitu avata %1: %2</translation> </message> @@ -299,6 +355,19 @@ </message> </context> <context> + <name>SelectTool</name> + <message> + <location filename="../src/tools/selecttool.cpp" line="8"/> + <source>Select</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/tools/selecttool.cpp" line="14"/> + <source>Select elements from the model.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>SettingsEditor</name> <message> <location filename="../src/settingseditor/settingseditor.ui" line="14"/>
--- a/locale/sv.ts Thu Nov 05 14:29:58 2020 +0200 +++ b/locale/sv.ts Sun Jan 10 15:28:44 2021 +0200 @@ -2,6 +2,29 @@ <!DOCTYPE TS> <TS version="2.1" language="sv_FI"> <context> + <name>ColorSelectDialog</name> + <message> + <source>Choose colour</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Search...</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>TextLabel</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Colour index:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Direct colour...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Dialog</name> <message> <source>System language</source> @@ -16,6 +39,17 @@ </message> </context> <context> + <name>DrawTool</name> + <message> + <source>Draw</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Draw new elements into the model.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>KeyboardShortcutsEditor</name> <message> <source>Action</source> @@ -228,6 +262,18 @@ <source>Pick scene colours</source> <translation type="unfinished"></translation> </message> + <message> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to construct %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>toolBar</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>MatrixEditor</name> @@ -306,6 +352,17 @@ </message> </context> <context> + <name>SelectTool</name> + <message> + <source>Select</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select elements from the model.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>SettingsEditor</name> <message> <source>Dialog</source>
--- a/src/basics.h Thu Nov 05 14:29:58 2020 +0200 +++ b/src/basics.h Sun Jan 10 15:28:44 2021 +0200 @@ -23,6 +23,7 @@ #include <cstring> #include <cmath> #include <optional> +#include <type_traits> #include <QMatrix4x4> #include <QObject> #include <QPointF> @@ -162,9 +163,26 @@ return {point.x(), point.y()}; } -constexpr float PIf = static_cast<float>(M_PI); -constexpr double PI = M_PI; -constexpr long double PIl = M_PIl; +/* + * coalesce(arg1, arg2, ..., argn) + * Returns the first of the given arguments that evaluates to true. + */ +template<typename T> +T coalesce(T&& arg) +{ + // recursion base: 1 argument + return arg; +} + +template<typename T, typename... Rest> +std::common_type_t<T, Rest...> coalesce(T&& arg, Rest&&... rest) +{ + // general case: n arguments + return arg ? arg : coalesce(rest...); +} + +template<typename T = double> +constexpr std::enable_if_t<std::is_floating_point_v<T>, T> PI = static_cast<T>(M_PIl); Q_DECLARE_METATYPE(glm::vec3) Q_DECLARE_METATYPE(glm::mat4)
--- a/src/main.h Thu Nov 05 14:29:58 2020 +0200 +++ b/src/main.h Sun Jan 10 15:28:44 2021 +0200 @@ -20,6 +20,7 @@ #include <QString> #include <QVector> #include <QSet> +#include <QDebug> #include <memory> #include "basics.h" #include "utility.h"
--- a/src/mainwindow.cpp Thu Nov 05 14:29:58 2020 +0200 +++ b/src/mainwindow.cpp Sun Jan 10 15:28:44 2021 +0200 @@ -28,6 +28,14 @@ #include "document.h" #include "uiutilities.h" #include "widgets/colorselectdialog.h" +#include "tools/basetool.h" +#include "tools/drawtool.h" +#include "tools/selecttool.h" + +static const QMetaObject* const toolMetaObjects[] = { + &SelectTool::staticMetaObject, + &DrawTool::staticMetaObject, +}; template<typename BaseType, typename MemberType, typename DataType> struct MemberData @@ -78,6 +86,22 @@ this->restoreSettings(); this->updateRenderPreferences(); this->newModel(); + + for (const QMetaObject* const metaObject : ::toolMetaObjects) + { + QObject* const objectInstance = metaObject->newInstance(Q_ARG(QObject*, this)); + BaseTool* const toolInstance = qobject_cast<BaseTool*>(objectInstance); + if (toolInstance) + { + this->selectedTool = coalesce(this->selectedTool, toolInstance); + this->tools.append(toolInstance); + qInfo() << toolInstance->name(); + } + else + { + QMessageBox::critical(this, tr("Error"), tr("Unable to construct %1").arg(metaObject->className())); + } + } } // MainWindow needs a destructor even if it is empty because otherwise the destructor of the
--- a/src/mainwindow.h Thu Nov 05 14:29:58 2020 +0200 +++ b/src/mainwindow.h Sun Jan 10 15:28:44 2021 +0200 @@ -58,6 +58,8 @@ QStringList recentlyOpenedFiles; ldraw::ColorTable colorTable; gl::RenderPreferences renderPreferences; + QVector<class BaseTool*> tools; + BaseTool* selectedTool = nullptr; void updateTitle(); void updateRenderPreferences(); void saveSettings();
--- a/src/mainwindow.ui Thu Nov 05 14:29:58 2020 +0200 +++ b/src/mainwindow.ui Sun Jan 10 15:28:44 2021 +0200 @@ -26,7 +26,7 @@ <x>0</x> <y>0</y> <width>800</width> - <height>24</height> + <height>26</height> </rect> </property> <widget class="QMenu" name="menuFile"> @@ -59,6 +59,17 @@ <addaction name="menuView"/> </widget> <widget class="QStatusBar" name="statusbar"/> + <widget class="QToolBar" name="toolsBar"> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <attribute name="toolBarArea"> + <enum>LeftToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + </widget> <action name="actionQuit"> <property name="text"> <string>Quit</string>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/basetool.cpp Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,4 @@ +#include "basetool.h" + +BaseTool::BaseTool(QObject* parent) : + QObject{parent} {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/basetool.h Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,26 @@ +#pragma once +#include "../main.h" + +class BaseTool : public QObject +{ + Q_OBJECT + +public: + struct MouseEventData + { + QMouseEvent* ev; + Qt::KeyboardModifiers keymods; + bool mouseMoved; + Qt::MouseButtons releasedButtons; + }; + + BaseTool(QObject* parent = nullptr); + + virtual QString name() const = 0; + virtual QString toolTip() const = 0; + virtual bool mousePressed(QMouseEvent*) { return false; } + virtual bool mouseReleased(MouseEventData const&) { return false; } + virtual bool mouseDoubleClicked(QMouseEvent*) { return false; } + virtual bool mouseMoved(QMouseEvent*) { return false; } + virtual bool keyReleased(QKeyEvent*) { return false; } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/drawtool.cpp Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,16 @@ +#include "drawtool.h" + +DrawTool::DrawTool(QObject* parent) : + BaseTool{parent} {} + +QString DrawTool::name() const +{ + static const QString result = tr("Draw"); + return result; +} + +QString DrawTool::toolTip() const +{ + static const QString result = tr("Draw new elements into the model."); + return result; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/drawtool.h Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,13 @@ +#pragma once +#include "basetool.h" + +class DrawTool : public BaseTool +{ + Q_OBJECT + +public: + Q_INVOKABLE DrawTool(QObject* parent = nullptr); + + QString name() const; + QString toolTip() const; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/selecttool.cpp Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,16 @@ +#include "selecttool.h" + +SelectTool::SelectTool(QObject* parent) : + BaseTool{parent} {} + +QString SelectTool::name() const +{ + static const QString result = tr("Select"); + return result; +} + +QString SelectTool::toolTip() const +{ + static const QString result = tr("Select elements from the model."); + return result; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/selecttool.h Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,13 @@ +#pragma once +#include "basetool.h" + +class SelectTool : public BaseTool +{ + Q_OBJECT + +public: + Q_INVOKABLE SelectTool(QObject* parent = nullptr); + + QString name() const; + QString toolTip() const; +};
--- a/src/ui/canvas.cpp Thu Nov 05 14:29:58 2020 +0200 +++ b/src/ui/canvas.cpp Sun Jan 10 15:28:44 2021 +0200 @@ -69,12 +69,12 @@ if (angle_x < angle_y) { this->newStatusText("rotate by X axis"); - this->gridMatrix = glm::rotate(this->gridMatrix, PIf / 2, glm::vec3{1, 0, 0}); + this->gridMatrix = glm::rotate(this->gridMatrix, PI<float> / 2, glm::vec3{1, 0, 0}); } else { this->newStatusText("rotate by Y axis"); - this->gridMatrix = glm::rotate(this->gridMatrix, PIf / 2, glm::vec3{0, 1, 0}); + this->gridMatrix = glm::rotate(this->gridMatrix, PI<float> / 2, glm::vec3{0, 1, 0}); } this->updateGridMatrix(); this->update();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/colorinput.cpp Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,14 @@ +#include "colorinput.h" +#include "ui_colorinput.h" + +ColorInput::ColorInput(QWidget *parent) : + QWidget(parent), + ui(new Ui::ColorInput) +{ + ui->setupUi(this); +} + +ColorInput::~ColorInput() +{ + delete ui; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/colorinput.h Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,22 @@ +#ifndef COLORINPUT_H +#define COLORINPUT_H + +#include <QWidget> + +namespace Ui { +class ColorInput; +} + +class ColorInput : public QWidget +{ + Q_OBJECT + +public: + explicit ColorInput(QWidget *parent = nullptr); + ~ColorInput(); + +private: + Ui::ColorInput *ui; +}; + +#endif // COLORINPUT_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/colorinput.ui Sun Jan 10 15:28:44 2021 +0200 @@ -0,0 +1,21 @@ +<ui version="4.0"> + <author/> + <comment/> + <exportmacro/> + <class>ColorInput</class> + <widget class="QWidget" name="ColorInput"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + </widget> + <pixmapfunction/> + <connections/> +</ui>