Compare commits

...

5 commits

6 changed files with 26 additions and 7 deletions

View file

@ -21,7 +21,7 @@ std::string getProgramDataDir() {
homedir = getpwuid(getuid())->pw_dir; homedir = getpwuid(getuid())->pw_dir;
} }
return std::string(homedir) + "/openblocks"; return std::string(homedir) + "/.local/share/openblocks";
} }
void displayErrorMessage(std::string message) { void displayErrorMessage(std::string message) {

View file

@ -16,8 +16,9 @@ Texture::Texture(const char* texturePath, unsigned int format, bool noMipMaps) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Interpolation // Interpolation
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if (!noMipMaps) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (noMipMaps) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// stbi_set_flip_vertically_on_load(true); // stbi_set_flip_vertically_on_load(true);
int width, height, nrChannels; int width, height, nrChannels;

View file

@ -17,8 +17,8 @@ Texture3D::Texture3D(const char* texturePath, unsigned int tileWidth, unsigned i
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_REPEAT);
// Interpolation // Interpolation
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// stbi_set_flip_vertically_on_load(true); // stbi_set_flip_vertically_on_load(true);
int width, height, nrChannels; int width, height, nrChannels;
@ -32,6 +32,7 @@ Texture3D::Texture3D(const char* texturePath, unsigned int tileWidth, unsigned i
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format, tileWidth, tileHeight, /* no of layers= */ tileCount, 0, format, glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format, tileWidth, tileHeight, /* no of layers= */ tileCount, 0, format,
GL_UNSIGNED_BYTE, data); GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
stbi_image_free(data); stbi_image_free(data);
} }

View file

@ -391,14 +391,16 @@ void MainWindow::connectActionHandlers() {
auto model = Model::New(); auto model = Model::New();
std::shared_ptr<Instance> firstParent; std::shared_ptr<Instance> firstParent;
bool done = false;
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (auto object : selection->Get()) { for (auto object : selection->Get()) {
if (firstParent == nullptr && object->GetParent().has_value()) firstParent = object->GetParent().value(); if (firstParent == nullptr && object->GetParent().has_value()) firstParent = object->GetParent().value();
historyState.push_back(UndoStateInstanceReparented { object, object->GetParent().value(), model }); historyState.push_back(UndoStateInstanceReparented { object, object->GetParent().value(), model });
object->SetParent(model); object->SetParent(model);
done = true;
} }
if (model->GetChildren().size() == 0) if (!done)
return; return;
// Technically not how it works in the actual studio, but it's not an API-breaking change // Technically not how it works in the actual studio, but it's not an API-breaking change
@ -408,6 +410,7 @@ void MainWindow::connectActionHandlers() {
model->SetParent(firstParent); model->SetParent(firstParent);
historyState.push_back(UndoStateSelectionChanged { selection->Get(), { model } }); historyState.push_back(UndoStateSelectionChanged { selection->Get(), { model } });
undoManager.PushState(historyState);
selection->Set({ model }); selection->Set({ model });
playSound("./assets/excluded/electronicpingshort.wav"); playSound("./assets/excluded/electronicpingshort.wav");
}); });
@ -416,10 +419,12 @@ void MainWindow::connectActionHandlers() {
UndoState historyState; UndoState historyState;
std::vector<std::shared_ptr<Instance>> newSelection; std::vector<std::shared_ptr<Instance>> newSelection;
bool done = false;
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (auto model : selection->Get()) { for (auto model : selection->Get()) {
// Not a model, skip // Not a model, skip
if (!model->IsA<Model>()) { newSelection.push_back(model); continue; } if (!model->IsA<Model>()) { newSelection.push_back(model); continue; }
done = true;
for (auto object : model->GetChildren()) { for (auto object : model->GetChildren()) {
historyState.push_back(UndoStateInstanceReparented { object, object->GetParent().value(), model->GetParent().value() }); historyState.push_back(UndoStateInstanceReparented { object, object->GetParent().value(), model->GetParent().value() });
@ -431,7 +436,11 @@ void MainWindow::connectActionHandlers() {
model->SetParent(std::nullopt); model->SetParent(std::nullopt);
} }
if (!done)
return;
historyState.push_back(UndoStateSelectionChanged { selection->Get(), newSelection }); historyState.push_back(UndoStateSelectionChanged { selection->Get(), newSelection });
undoManager.PushState(historyState);
selection->Set(newSelection); selection->Set(newSelection);
playSound("./assets/excluded/electronicpingshort.wav"); playSound("./assets/excluded/electronicpingshort.wav");
}); });

View file

@ -1,11 +1,15 @@
#include "explorermodel.h" #include "explorermodel.h"
#include "common.h" #include "common.h"
#include "mainwindow.h"
#include "objects/base/instance.h" #include "objects/base/instance.h"
#include "objects/base/member.h" #include "objects/base/member.h"
#include "undohistory.h"
#include <qicon.h> #include <qicon.h>
#include <qmimedata.h> #include <qmimedata.h>
#include <QWidget> #include <QWidget>
#define M_mainWindow dynamic_cast<MainWindow*>(dynamic_cast<QWidget*>(dynamic_cast<QObject*>(this)->parent())->window())
// https://doc.qt.io/qt-6/qtwidgets-itemviews-simpletreemodel-example.html#testing-the-model // https://doc.qt.io/qt-6/qtwidgets-itemviews-simpletreemodel-example.html#testing-the-model
std::map<std::string, QIcon> instanceIconCache; std::map<std::string, QIcon> instanceIconCache;
@ -216,11 +220,15 @@ bool ExplorerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, i
return true; return true;
} }
UndoState historyState;
std::shared_ptr<Instance> parentInst = fromIndex(parent); std::shared_ptr<Instance> parentInst = fromIndex(parent);
for (std::shared_ptr<Instance> instance : slot->instances) { for (std::shared_ptr<Instance> instance : slot->instances) {
historyState.push_back(UndoStateInstanceReparented { instance, instance->GetParent().value_or(nullptr), parentInst });
instance->SetParent(parentInst); instance->SetParent(parentInst);
} }
M_mainWindow->undoManager.PushState(historyState);
delete slot; delete slot;
return true; return true;
} }

View file

@ -15,7 +15,7 @@
ExplorerView::ExplorerView(QWidget* parent): ExplorerView::ExplorerView(QWidget* parent):
QTreeView(parent), QTreeView(parent),
model(ExplorerModel(std::dynamic_pointer_cast<Instance>(gDataModel))), model(ExplorerModel(std::dynamic_pointer_cast<Instance>(gDataModel), this)),
contextMenu(this) { contextMenu(this) {
this->setModel(&model); this->setModel(&model);