From 4ae75d1d20e6b3ef1de43cab5f9f29d281865af5 Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Sun, 15 Apr 2018 14:47:31 +0300 Subject: [PATCH] Terrain texture brush frame --- apps/opencs/CMakeLists.txt | 2 +- .../view/render/pagedworldspacewidget.cpp | 3 +- .../opencs/view/render/terraintexturemode.cpp | 214 ++++++++++++++++++ .../opencs/view/render/terraintexturemode.hpp | 108 +++++++++ apps/opencs/view/render/worldspacewidget.cpp | 3 + apps/opencs/view/widget/scenetoolmode.cpp | 9 + apps/opencs/view/widget/scenetoolmode.hpp | 4 + files/opencs/resources.qrc | 8 +- 8 files changed, 347 insertions(+), 4 deletions(-) create mode 100644 apps/opencs/view/render/terraintexturemode.cpp create mode 100644 apps/opencs/view/render/terraintexturemode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index f07b518a9..f8dd1fe2d 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -88,7 +88,7 @@ opencs_units (view/render scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget previewwidget editmode instancemode instanceselectionmode instancemovemode orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller - cellwater + cellwater terraintexturemode ) opencs_units_noqt (view/render diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 4a745195b..1d1a7cd17 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -21,6 +21,7 @@ #include "mask.hpp" #include "cameracontroller.hpp" #include "cellarrow.hpp" +#include "terraintexturemode.hpp" bool CSVRender::PagedWorldspaceWidget::adjustCells() { @@ -136,7 +137,7 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons ( new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain shape editing"), "terrain-shape"); tool->addButton ( - new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain texture editing"), + new TerrainTextureMode (this, tool), "terrain-texture"); tool->addButton ( new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain vertex paint editing"), diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp new file mode 100644 index 000000000..346ba3136 --- /dev/null +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -0,0 +1,214 @@ +// To-do: Getting Texture Id and Texture Filenames to base class Terraintexturemode +// To-do: Better data handling options for mBrushTexture +// To-do: loading texture bitmaps from virtual file system (vfs) for texture overlay icon + +#include "terraintexturemode.hpp" +#include "editmode.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../widget/modebutton.hpp" +#include "../widget/scenetoolbar.hpp" + +#include "../../model/world/universalid.hpp" +#include "../../model/world/tablemimedata.hpp" + +#include "pagedworldspacewidget.hpp" + + +CSVRender::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *parent) + : QGroupBox(title, parent) +{ + brushSizeSlider = new QSlider(Qt::Horizontal); + brushSizeSlider->setTickPosition(QSlider::TicksBothSides); + brushSizeSlider->setTickInterval(10); + brushSizeSlider->setSingleStep(1); + + brushSizeSpinBox = new QSpinBox; + brushSizeSpinBox->setRange(1, 100); + brushSizeSpinBox->setSingleStep(1); + + layoutSliderSize = new QHBoxLayout; + layoutSliderSize->addWidget(brushSizeSlider); + layoutSliderSize->addWidget(brushSizeSpinBox); + + connect(brushSizeSlider, SIGNAL(valueChanged(int)), brushSizeSpinBox, SLOT(setValue(int))); + connect(brushSizeSpinBox, SIGNAL(valueChanged(int)), brushSizeSlider, SLOT(setValue(int))); + + setLayout(layoutSliderSize); +} + +CSVRender::TextureBrushButton::TextureBrushButton (const QIcon & icon, const QString & text, QWidget * parent) + : QPushButton(icon, text, parent) +{ +} + +CSVRender::TextureBrushWindow::TextureBrushWindow(WorldspaceWidget *worldspaceWidget, QWidget *parent) + : QFrame(parent, Qt::Popup), mWorldspaceWidget (worldspaceWidget) +{ + mBrushTextureLabel = "Brush: " + mBrushTexture; + selectedBrush = new QLabel(QString::fromUtf8(mBrushTextureLabel.c_str()), this); + + const std::string& iconPoint = ":scenetoolbar/brush-point"; + const std::string& iconSquare = ":scenetoolbar/brush-square"; + const std::string& iconCircle = ":scenetoolbar/brush-circle"; + const std::string& iconCustom = ":scenetoolbar/brush-custom"; + + TextureBrushButton *buttonPoint = new TextureBrushButton(QIcon (QPixmap (iconPoint.c_str())), "", this); + TextureBrushButton *buttonSquare = new TextureBrushButton(QIcon (QPixmap (iconSquare.c_str())), "", this); + TextureBrushButton *buttonCircle = new TextureBrushButton(QIcon (QPixmap (iconCircle.c_str())), "", this); + TextureBrushButton *buttonCustom = new TextureBrushButton(QIcon (QPixmap (iconCustom.c_str())), "", this); + + QVBoxLayout *layoutMain = new QVBoxLayout; + layoutMain->setSpacing(0); + + QHBoxLayout *layoutHorizontal = new QHBoxLayout; + layoutHorizontal->setContentsMargins (QMargins (0, 0, 0, 0)); + layoutHorizontal->setSpacing(0); + + configureButtonInitialSettings(buttonPoint); + configureButtonInitialSettings(buttonSquare); + configureButtonInitialSettings(buttonCircle); + configureButtonInitialSettings(buttonCustom); + + QButtonGroup* brushButtonGroup = new QButtonGroup(this); + brushButtonGroup->addButton(buttonPoint); + brushButtonGroup->addButton(buttonSquare); + brushButtonGroup->addButton(buttonCircle); + brushButtonGroup->addButton(buttonCustom); + + brushButtonGroup->setExclusive(true); + + layoutHorizontal->addWidget(buttonPoint); + layoutHorizontal->addWidget(buttonSquare); + layoutHorizontal->addWidget(buttonCircle); + layoutHorizontal->addWidget(buttonCustom); + + horizontalGroupBox = new QGroupBox(tr("")); + horizontalGroupBox->setLayout(layoutHorizontal); + + BrushSizeControls* sizeSliders = new BrushSizeControls(tr(""), this); + + layoutMain->addWidget(horizontalGroupBox); + layoutMain->addWidget(sizeSliders); + layoutMain->addWidget(selectedBrush); + + setLayout(layoutMain); + + connect(parent, SIGNAL(passBrushTexture(std::string)), this, SLOT(getBrushTexture(std::string))); +} + +void CSVRender::TextureBrushWindow::configureButtonInitialSettings(TextureBrushButton *button) +{ + button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setContentsMargins (QMargins (0, 0, 0, 0)); + button->setIconSize (QSize (48-6, 48-6)); + button->setFixedSize (48, 48); + button->setAcceptDrops(true); + button->setCheckable(true); +} + +void CSVRender::TextureBrushWindow::getBrushTexture(std::string brushTexture) +{ + mBrushTexture = brushTexture; + mBrushTextureLabel = "Brush:" + mBrushTexture; + selectedBrush->setText(QString::fromUtf8(mBrushTextureLabel.c_str())); +} + +CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) +: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, Mask_Terrain | Mask_Reference, "Terrain texture editing", parent) +, textureBrushWindow(new TextureBrushWindow(worldspaceWidget, this)) +{ + connect(parent, SIGNAL(passEvent(QDragEnterEvent*)), this, SLOT(handleDragEnterEvent(QDragEnterEvent*))); + connect(parent, SIGNAL(passEvent(QDropEvent*)), this, SLOT(handleDropEvent(QDropEvent*))); +} + +void CSVRender::TerrainTextureMode::activate(CSVWidget::SceneToolbar* toolbar) +{ + EditMode::activate(toolbar); +} + +void CSVRender::TerrainTextureMode::deactivate(CSVWidget::SceneToolbar* toolbar) +{ + EditMode::deactivate(toolbar); +} + +void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResult& hit) +{ + QPoint position = QCursor::pos(); + textureBrushWindow->move (position); + textureBrushWindow->show(); +} + +void CSVRender::TerrainTextureMode::secondarySelectPressed(const WorldspaceHitResult& hit) +{ +} + +bool CSVRender::TerrainTextureMode::primaryEditStartDrag (const QPoint& pos) +{ + return false; +} + +bool CSVRender::TerrainTextureMode::secondaryEditStartDrag (const QPoint& pos) +{ + return false; +} + +bool CSVRender::TerrainTextureMode::primarySelectStartDrag (const QPoint& pos) +{ + return false; +} + +bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos) +{ + return false; +} + +void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) { +} + +void CSVRender::TerrainTextureMode::dragCompleted(const QPoint& pos) { +} + +void CSVRender::TerrainTextureMode::dragAborted() { +} + +void CSVRender::TerrainTextureMode::dragWheel (int diff, double speedFactor) {} + +void CSVRender::TerrainTextureMode::handleDragEnterEvent (QDragEnterEvent *event) { + event->accept(); +} + +void CSVRender::TerrainTextureMode::handleDropEvent (QDropEvent *event) { + const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + + if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped + return; + + if (mime->holdsType (CSMWorld::UniversalId::Type_LandTexture)) + { + const std::vector ids = mime->getData(); + + for (const CSMWorld::UniversalId& uid : ids) + { + mBrushTexture = uid.getId(); + emit passBrushTexture(mBrushTexture); + } + } +} + +void CSVRender::TerrainTextureMode::dragMoveEvent (QDragMoveEvent *event) { +} diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp new file mode 100644 index 000000000..809816047 --- /dev/null +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -0,0 +1,108 @@ +#ifndef CSV_RENDER_TERRAINTEXTUREMODE_H +#define CSV_RENDER_TERRAINTEXTUREMODE_H + +#include "editmode.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CSVWidget +{ + class SceneToolMode; +} + +namespace CSVRender +{ + class BrushSizeControls : public QGroupBox + { + Q_OBJECT + + public: + BrushSizeControls(const QString &title, QWidget *parent); + + private: + QSlider *brushSizeSlider; + QSpinBox *brushSizeSpinBox; + QHBoxLayout *layoutSliderSize; + }; + + class TextureBrushButton : public QPushButton + { + Q_OBJECT + + public: + TextureBrushButton (const QIcon& icon, const QString& tooltip = "", + QWidget *parent = 0); + }; + + class TextureBrushWindow : public QFrame + { + Q_OBJECT + + public: + TextureBrushWindow(WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); + void configureButtonInitialSettings(TextureBrushButton *button); + + private: + QLabel *selectedBrush; + QGroupBox *horizontalGroupBox; + int mButtonSize; + int mIconSize; + WorldspaceWidget *mWorldspaceWidget; + std::string mBrushTexture; + std::string mBrushTextureLabel; + + public slots: + void getBrushTexture(std::string brushTexture); + }; + + class TerrainTextureMode : public EditMode + { + Q_OBJECT + + public: + std::string mBrushTexture; + + TerrainTextureMode(WorldspaceWidget*, QWidget* parent = nullptr); + + void primarySelectPressed(const WorldspaceHitResult&); + void secondarySelectPressed(const WorldspaceHitResult&); + + void activate(CSVWidget::SceneToolbar*); + void deactivate(CSVWidget::SceneToolbar*); + + virtual bool primaryEditStartDrag (const QPoint& pos); + virtual bool secondaryEditStartDrag (const QPoint& pos); + virtual bool primarySelectStartDrag (const QPoint& pos); + virtual bool secondarySelectStartDrag (const QPoint& pos); + virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor); + virtual void dragCompleted(const QPoint& pos); + virtual void dragAborted(); + virtual void dragWheel (int diff, double speedFactor); + virtual void dragMoveEvent (QDragMoveEvent *event); + + private: + TextureBrushWindow *textureBrushWindow; + + signals: + + void passBrushTexture(std::string brushTexture); + + public slots: + void handleDragEnterEvent (QDragEnterEvent *event); + void handleDropEvent(QDropEvent *event); + }; +} + + +#endif diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index af53c86f0..f3b781080 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -577,6 +577,9 @@ void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelInde void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id) { dynamic_cast (*mEditMode->getCurrent()).setEditLock (mLocked); + if (mEditMode->getCurrentId() == "terrain-texture") mEditMode->setAcceptDrops(true); + else mEditMode->setAcceptDrops(false); + mDragging = false; mDragMode = InteractionType_None; } diff --git a/apps/opencs/view/widget/scenetoolmode.cpp b/apps/opencs/view/widget/scenetoolmode.cpp index 7b2ff64db..80104515b 100644 --- a/apps/opencs/view/widget/scenetoolmode.cpp +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -144,6 +144,15 @@ bool CSVWidget::SceneToolMode::event(QEvent* event) return SceneTool::event(event); } +void CSVWidget::SceneToolMode::dragEnterEvent (QDragEnterEvent *event) +{ + emit passEvent(event); +} +void CSVWidget::SceneToolMode::dropEvent (QDropEvent *event) +{ + emit passEvent(event); +} + void CSVWidget::SceneToolMode::selected() { std::map::iterator iter = diff --git a/apps/opencs/view/widget/scenetoolmode.hpp b/apps/opencs/view/widget/scenetoolmode.hpp index 90f1dc419..84fcf59a7 100644 --- a/apps/opencs/view/widget/scenetoolmode.hpp +++ b/apps/opencs/view/widget/scenetoolmode.hpp @@ -47,6 +47,8 @@ namespace CSVWidget protected: bool event(QEvent* event); + void dragEnterEvent (QDragEnterEvent *event); + void dropEvent (QDropEvent *event); public: @@ -72,6 +74,8 @@ namespace CSVWidget signals: void modeChanged (const std::string& id); + void passEvent (QDragEnterEvent *event); + void passEvent (QDropEvent *event); private slots: diff --git a/files/opencs/resources.qrc b/files/opencs/resources.qrc index bfa256faf..0afd855f9 100644 --- a/files/opencs/resources.qrc +++ b/files/opencs/resources.qrc @@ -68,7 +68,7 @@ record-preview.png record-clone.png record-add.png - resources-icon.png + resources-icon.png resources-mesh.png resources-music.png resources-sound.png @@ -149,6 +149,10 @@ transform-scale.png selection-mode-cube.png selection-mode-cube-corner.png - selection-mode-cube-sphere.png + selection-mode-cube-sphere.png + brush-point.png + brush-square.png + brush-circle.png + brush-custom.png