Sat, 01 Feb 2020 17:10:11 +0200
Main color is now configurable
--- a/CMakeLists.txt Sat Feb 01 15:49:28 2020 +0200 +++ b/CMakeLists.txt Sat Feb 01 17:10:11 2020 +0200 @@ -49,6 +49,7 @@ src/settingseditor/librarieseditor.cpp src/settingseditor/settingseditor.cpp src/types/boundingbox.cpp + src/widgets/colorbutton.cpp ) set (LDFORGE_HEADERS src/basics.h @@ -84,6 +85,7 @@ src/settingseditor/librarieseditor.h src/settingseditor/settingseditor.h src/types/boundingbox.h + src/widgets/colorbutton.h ) set (LDFORGE_FORMS src/document.ui @@ -98,18 +100,18 @@ ) set(LDFORGE_RESOURCES ldforge.qrc) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +include_directories("${PROJECT_BINARY_DIR}") +include_directories("${PROJECT_BINARY_DIR}/src") +include_directories("${PROJECT_SOURCE_DIR}/src") # Translations qt5_create_translation(QM_FILES ${LDFORGE_SOURCES} ${LDFORGE_HEADERS} ${LDFORGE_FORMS} ${LDFORGE_LOCALES}) add_custom_target(translations ALL DEPENDS ${QM_FILES}) add_custom_target(resources ALL DEPENDS ${LDFORGE_RESOURCES}) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) -include_directories("${PROJECT_BINARY_DIR}") -include_directories("${PROJECT_BINARY_DIR}/src") -include_directories("${PROJECT_SOURCE_DIR}/src") if (NOT MSVC) if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" OR "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG")
--- a/locale/fi.ts Sat Feb 01 15:49:28 2020 +0200 +++ b/locale/fi.ts Sat Feb 01 17:10:11 2020 +0200 @@ -181,27 +181,27 @@ <translation type="unfinished">Satunnaiset värit</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="88"/> + <location filename="../src/mainwindow.cpp" line="91"/> <source>Open model</source> <translation>Avaa malli</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="90"/> + <location filename="../src/mainwindow.cpp" line="93"/> <source>LDraw models (*.ldr *.dat)</source> <translation>LDraw-mallit (*.ldr *.dat)</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="109"/> + <location filename="../src/mainwindow.cpp" line="112"/> <source>Problem loading references</source> <translation type="unfinished">Ongelma viitteiden lataamisessa</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="119"/> + <location filename="../src/mainwindow.cpp" line="122"/> <source>Problem opening file</source> <translation>Ongelma tiedoston avaamisessa</translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="121"/> + <location filename="../src/mainwindow.cpp" line="124"/> <source>Could not open %1: %2</source> <translation>Ei voitu avata %1: %2</translation> </message> @@ -228,27 +228,42 @@ </message> <message> <location filename="../src/settingseditor/settingseditor.ui" line="30"/> + <source>Interface</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/settingseditor/settingseditor.ui" line="36"/> <source>Language:</source> <translation>Kieli:</translation> </message> <message> - <location filename="../src/settingseditor/settingseditor.ui" line="38"/> - <location filename="../src/settingseditor/settingseditor.cpp" line="54"/> + <location filename="../src/settingseditor/settingseditor.ui" line="46"/> + <location filename="../src/settingseditor/settingseditor.cpp" line="55"/> <source>System language</source> <translation>Järjestelmän kieli</translation> </message> <message> - <location filename="../src/settingseditor/settingseditor.ui" line="43"/> + <location filename="../src/settingseditor/settingseditor.ui" line="51"/> <source>English</source> <translation>Englanti</translation> </message> <message> - <location filename="../src/settingseditor/settingseditor.ui" line="52"/> + <location filename="../src/settingseditor/settingseditor.ui" line="77"/> + <source>Rendering</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/settingseditor/settingseditor.ui" line="83"/> + <source>Main color:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/settingseditor/settingseditor.ui" line="131"/> <source>LDraw parts libraries</source> <translation>LDraw-osakirjastot</translation> </message> <message> - <location filename="../src/settingseditor/settingseditor.ui" line="57"/> + <location filename="../src/settingseditor/settingseditor.ui" line="136"/> <source>Keyboard shortcuts</source> <translation>Näppäinyhdistelmät</translation> </message>
--- a/locale/sv.ts Sat Feb 01 15:49:28 2020 +0200 +++ b/locale/sv.ts Sat Feb 01 17:10:11 2020 +0200 @@ -266,6 +266,18 @@ <source>Keyboard shortcuts</source> <translation>Tangentbordsgenvägar</translation> </message> + <message> + <source>Interface</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Rendering</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Main color:</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>gl::Compiler</name>
--- a/src/document.cpp Sat Feb 01 15:49:28 2020 +0200 +++ b/src/document.cpp Sat Feb 01 17:10:11 2020 +0200 @@ -55,7 +55,7 @@ this->ui.splitter->restoreState(state); } -void Document::setRenderStyle(gl::RenderStyle newRenderStyle) +void Document::setRenderPreferences(const gl::RenderPreferences& newPreferences) { - this->renderer->setRenderStyle(newRenderStyle); + this->renderer->setRenderPreferences(newPreferences); }
--- a/src/document.h Sat Feb 01 15:49:28 2020 +0200 +++ b/src/document.h Sat Feb 01 17:10:11 2020 +0200 @@ -40,7 +40,7 @@ ~Document(); QByteArray saveSplitterState() const; void restoreSplitterState(const QByteArray& state); - void setRenderStyle(gl::RenderStyle newRenderStyle); + void setRenderPreferences(const gl::RenderPreferences& newPreferences); signals: void splitterChanged(); private:
--- a/src/gl/common.h Sat Feb 01 15:49:28 2020 +0200 +++ b/src/gl/common.h Sat Feb 01 17:10:11 2020 +0200 @@ -150,4 +150,12 @@ BfcRed = 2, RandomColors = 3, }; + + // User options for rendering + struct RenderPreferences + { + gl::RenderStyle style = gl::RenderStyle::Normal; + QColor mainColor{255, 255, 64}; + float lineThickness = 2.0f; + }; }
--- a/src/gl/compiler.cpp Sat Feb 01 15:49:28 2020 +0200 +++ b/src/gl/compiler.cpp Sat Feb 01 17:10:11 2020 +0200 @@ -143,14 +143,14 @@ } } -void gl::Compiler::build(Model* model, DocumentManager* context) +void gl::Compiler::build(Model* model, DocumentManager* context, const gl::RenderPreferences& preferences) { this->boundingBox = {}; std::vector<gl::Vertex> vboData[gl::NUM_ARRAY_CLASSES]; const std::vector<gl::Polygon> polygons = model->getPolygons(context); for (const gl::Polygon& polygon : polygons) { - this->buildPolygon(polygon, vboData); + this->buildPolygon(polygon, vboData, preferences); } for (int arrayId = 0; arrayId < gl::NUM_ARRAY_CLASSES; arrayId += 1) { @@ -190,13 +190,16 @@ return {r, g, b}; } -void gl::Compiler::buildPolygon(gl::Polygon polygon, std::vector<gl::Vertex>* vboData) +void gl::Compiler::buildPolygon( + gl::Polygon polygon, + std::vector<gl::Vertex>* vboData, + const gl::RenderPreferences& preferences) { const gl::ArrayClass vboClass = classifyPolygon(polygon); std::vector<gl::Vertex>& vertexBuffer = vboData[static_cast<int>(vboClass)]; auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices()); reserveMore(vertexBuffer, polygon.numPolygonVertices()); - const QColor color = this->getColorForPolygon(polygon); + const QColor color = this->getColorForPolygon(polygon, preferences); for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) { const glm::vec3& v1 = vertexRing[i - 1]; @@ -210,13 +213,13 @@ } } -QColor gl::Compiler::getColorForPolygon(const gl::Polygon& polygon) +QColor gl::Compiler::getColorForPolygon(const gl::Polygon& polygon, const gl::RenderPreferences& preferences) { QColor color; // For normal colors, use the polygon's color. if (polygon.color == ldraw::mainColor) { - color = {255, 255, 64}; // mainColorRepresentation(); + color = preferences.mainColor; } else if (polygon.color == ldraw::edgeColor) {
--- a/src/gl/compiler.h Sat Feb 01 15:49:28 2020 +0200 +++ b/src/gl/compiler.h Sat Feb 01 17:10:11 2020 +0200 @@ -48,10 +48,10 @@ public: Compiler(const ldraw::ColorTable& colorTable, QObject* parent); ~Compiler(); - void build(Model* model, DocumentManager* context); - void buildPolygon(Polygon polygon, std::vector<Vertex>* vboData); + void build(Model* model, DocumentManager* context, const RenderPreferences& preferences); + void buildPolygon(Polygon polygon, std::vector<Vertex>* vboData, const gl::RenderPreferences& preferences); std::size_t vertexCount(gl::ArrayClass arrayClass) const; - QColor getColorForPolygon(const gl::Polygon& polygon); + QColor getColorForPolygon(const gl::Polygon& polygon, const RenderPreferences& preferences); glm::vec3 modelCenter() const; double modelDistance() const; void initialize();
--- a/src/gl/partrenderer.cpp Sat Feb 01 15:49:28 2020 +0200 +++ b/src/gl/partrenderer.cpp Sat Feb 01 17:10:11 2020 +0200 @@ -49,7 +49,7 @@ abort(); } this->compiler->initialize(); - this->compiler->build(this->model, this->documents); + this->compiler->build(this->model, this->documents, this->renderPreferences); this->initialized = true; this->modelQuaternion = glm::angleAxis(glm::radians(30.0f), glm::vec3{-1, 0, 0}); this->modelQuaternion *= glm::angleAxis(glm::radians(225.0f), glm::vec3{-0, 1, 0}); @@ -105,7 +105,7 @@ glEnable(GL_DEPTH_TEST); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0f, 1.0f); - switch (this->renderStyle) + switch (this->renderPreferences.style) { case gl::RenderStyle::Normal: this->setFragmentStyle(gl::FragmentStyle::Normal); @@ -224,9 +224,14 @@ * @brief Changes the way the scene is rendered * @param newStyle new render style to use */ -void PartRenderer::setRenderStyle(const gl::RenderStyle newStyle) +void PartRenderer::setRenderPreferences(const gl::RenderPreferences& newPreferences) { - this->renderStyle = newStyle; + bool mainColorChanged = this->renderPreferences.mainColor != newPreferences.mainColor; + this->renderPreferences = newPreferences; + if (mainColorChanged) + { + this->compiler->build(this->model, this->documents, this->renderPreferences); + } this->update(); }
--- a/src/gl/partrenderer.h Sat Feb 01 15:49:28 2020 +0200 +++ b/src/gl/partrenderer.h Sat Feb 01 17:10:11 2020 +0200 @@ -21,7 +21,7 @@ const ldraw::ColorTable& colorTable, QWidget* parent = nullptr); ~PartRenderer() override; - void setRenderStyle(const gl::RenderStyle newStyle); + void setRenderPreferences(const gl::RenderPreferences& newPreferences); protected: void initializeGL() override; void resizeGL(int width, int height) override; @@ -38,7 +38,7 @@ const ldraw::ColorTable& colorTable; QPointF lastMousePosition; gl::Compiler* compiler; - gl::RenderStyle renderStyle = gl::RenderStyle::Normal; + gl::RenderPreferences renderPreferences; glm::mat4 projectionMatrix; glm::mat4 viewMatrix; glm::quat modelQuaternion;
--- a/src/mainwindow.cpp Sat Feb 01 15:49:28 2020 +0200 +++ b/src/mainwindow.cpp Sat Feb 01 17:10:11 2020 +0200 @@ -68,10 +68,13 @@ } this->updateTitle(); this->restoreSettings(); - this->updateRenderStyles(); + this->updateRenderPreferences(); this->newModel(); } +// MainWindow needs a destructor even if it is empty because otherwise the destructor of the +// std::unique_ptr is resolved in the header file, where it will complain about Ui_MainWindow +// being incomplete. MainWindow::~MainWindow() { } @@ -162,7 +165,7 @@ void MainWindow::openModelForEditing(const QString& modelName) { Document* document = new Document{this->documents.findModelByName(modelName), &this->documents, this->colorTable}; - document->setRenderStyle(this->renderStyle); + document->setRenderPreferences(this->renderPreferences); this->ui->tabs->addTab(document, modelName); this->ui->tabs->setCurrentWidget(document); document->restoreSplitterState(this->documentSplitterState); @@ -221,9 +224,9 @@ void MainWindow::setRenderStyle(gl::RenderStyle renderStyle) { - this->renderStyle = renderStyle; + this->renderPreferences.style = renderStyle; this->saveSettings(); - this->updateRenderStyles(); + this->updateRenderPreferences(); } void MainWindow::changeEvent(QEvent* event) @@ -264,20 +267,20 @@ setWindowTitle(title); } -void MainWindow::updateRenderStyles() +void MainWindow::updateRenderPreferences() { for (int i = 0; i < this->ui->tabs->count(); i += 1) { Document* document = qobject_cast<Document*>(this->ui->tabs->widget(i)); if (document != nullptr) { - document->setRenderStyle(renderStyle); + document->setRenderPreferences(this->renderPreferences); } } for (auto data : ::renderStyleButtons) { QAction* action = data.memberInstance(this->ui.get()); - action->setChecked(this->renderStyle == data.payload); + action->setChecked(this->renderPreferences.style == data.payload); } } @@ -289,7 +292,7 @@ this->settings.setValue("MainWindow/Geometry", this->saveGeometry()); this->settings.setValue("MainWindow/RecentlyOpened", this->recentlyOpenedFiles); this->settings.setValue("MainWindow/DocumentSplitterState", this->documentSplitterState); - this->settings.setValue("MainWindow/RenderStyle", static_cast<int>(this->renderStyle)); + this->settings.setValue("MainWindow/RenderStyle", static_cast<int>(this->renderPreferences.style)); this->libraries.storeToSettings(&this->settings); } @@ -301,13 +304,15 @@ this->restoreGeometry(this->settings.value("MainWindow/Geometry").toByteArray()); this->recentlyOpenedFiles = this->settings.value("MainWindow/RecentlyOpened").toStringList(); this->documentSplitterState = this->settings.value("MainWindow/DocumentSplitterState").toByteArray(); - this->renderStyle = static_cast<gl::RenderStyle>(this->settings.value("MainWindow/RenderStyle").toInt()); + this->renderPreferences.style = static_cast<gl::RenderStyle>(this->settings.value("Render/Style").toInt()); + this->renderPreferences.mainColor = this->settings.value("Render/MainColor").toString(); const QString systemLocale = QLocale::system().name(); const QVariant defaultLocale = this->settings.value("locale", systemLocale); changeLanguage(defaultLocale.toString()); this->libraries.restoreFromSettings(&this->settings); this->updateRecentlyOpenedDocumentsMenu(); this->loadColors(); + this->updateRenderPreferences(); } QString MainWindow::pathToTranslation(const QString& localeCode)
--- a/src/mainwindow.h Sat Feb 01 15:49:28 2020 +0200 +++ b/src/mainwindow.h Sat Feb 01 17:10:11 2020 +0200 @@ -30,7 +30,7 @@ Q_OBJECT public: MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + ~MainWindow() override; private slots: void newModel(); void openModel(); @@ -56,9 +56,9 @@ static constexpr int maxRecentlyOpenedFiles = 10; QStringList recentlyOpenedFiles; ldraw::ColorTable colorTable; - gl::RenderStyle renderStyle; + gl::RenderPreferences renderPreferences; void updateTitle(); - void updateRenderStyles(); + void updateRenderPreferences(); void saveSettings(); void restoreSettings(); void changeLanguage(QString localeCode);
--- a/src/settingseditor/settingseditor.cpp Sat Feb 01 15:49:28 2020 +0200 +++ b/src/settingseditor/settingseditor.cpp Sat Feb 01 17:10:11 2020 +0200 @@ -37,6 +37,7 @@ void SettingsEditor::handleAccepted() { this->settings->setValue("locale", this->ui.language->currentData().toString()); + this->settings->setValue("Render/MainColor", this->ui.mainColorButton->selectedColor().name()); this->librariesEditor.saveSettings(this->settings); } @@ -65,6 +66,7 @@ void SettingsEditor::setDefaults() { this->setCurrentLanguage(this->settings->value("locale", QLocale::system().name()).toString()); + this->ui.mainColorButton->setSelectedColor(this->settings->value("Render/MainColor").toString()); } void SettingsEditor::setCurrentLanguage(const QString& localeCode)
--- a/src/settingseditor/settingseditor.ui Sat Feb 01 15:49:28 2020 +0200 +++ b/src/settingseditor/settingseditor.ui Sat Feb 01 17:10:11 2020 +0200 @@ -17,34 +17,113 @@ <item> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> - <number>2</number> + <number>0</number> </property> <widget class="QWidget" name="tabGeneral"> <attribute name="title"> <string>General</string> </attribute> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Language:</string> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Interface</string> </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Language:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QComboBox" name="language"> + <item> + <property name="text"> + <string>System language</string> + </property> + </item> + <item> + <property name="text"> + <string>English</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> </widget> </item> - <item row="0" column="1"> - <widget class="QComboBox" name="language"> - <item> - <property name="text"> - <string>System language</string> - </property> - </item> - <item> - <property name="text"> - <string>English</string> - </property> - </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Rendering</string> + </property> + <layout class="QFormLayout" name="formLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Main color:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="ColorButton" name="mainColorButton"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> </widget> </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <widget class="QWidget" name="tabLdrawLibraries"> @@ -76,6 +155,13 @@ </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>ColorButton</class> + <extends>QPushButton</extends> + <header>widgets/colorbutton.h</header> + </customwidget> + </customwidgets> <resources/> <connections> <connection>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/colorbutton.cpp Sat Feb 01 17:10:11 2020 +0200 @@ -0,0 +1,34 @@ +#include <QColorDialog> +#include "colorbutton.h" + +ColorButton::ColorButton(const QColor& color, QWidget* parent) : + ColorButton{parent} +{ + this->setSelectedColor(color); +} + +ColorButton::ColorButton(QWidget* parent) : + QPushButton{parent} +{ + connect(this, &QPushButton::clicked, [&]() + { + const QColor color = QColorDialog::getColor(this->storedSelectedColor, this->parentWidget()); + if (color.isValid()) + { + this->setSelectedColor(color); + } + }); +} + +QColor ColorButton::selectedColor() const +{ + return this->storedSelectedColor; +} + +void ColorButton::setSelectedColor(const QColor& newSelectedColor) +{ + this->storedSelectedColor = newSelectedColor; + this->setStyleSheet(QString{"background-color: %1"}.arg(newSelectedColor.name())); + this->setText(newSelectedColor.name()); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/colorbutton.h Sat Feb 01 17:10:11 2020 +0200 @@ -0,0 +1,16 @@ +#pragma once +#include <QPushButton> + +/** + * @brief A button that can be used to select a color + */ +class ColorButton : public QPushButton +{ +public: + ColorButton(const QColor& color = {}, QWidget* parent = nullptr); + ColorButton(QWidget* parent = nullptr); + QColor selectedColor() const; + void setSelectedColor(const QColor& newSelectedColor); +private: + QColor storedSelectedColor; +};