Compare commits
2 commits
b80eb03f9d
...
186d64f28e
Author | SHA1 | Date | |
---|---|---|---|
|
186d64f28e | ||
|
940109b0b9 |
|
@ -73,7 +73,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 studPx = texture(studs, vec3(vTexCoords, vSurfaceZ));
|
vec4 studPx = texture(studs, vec3(vTexCoords, vSurfaceZ));
|
||||||
FragColor = vec4(mix(result, vec3(studPx), studPx.w), 1-transparency);
|
FragColor = vec4(mix(result, vec3(studPx), studPx.w), 1) * (1-transparency);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 calculateDirectionalLight(DirLight light) {
|
vec3 calculateDirectionalLight(DirLight light) {
|
||||||
|
|
|
@ -233,6 +233,8 @@ void renderHandles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2d square overlay
|
// 2d square overlay
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
identityShader->use();
|
identityShader->use();
|
||||||
identityShader->set("aColor", glm::vec3(0.f, 1.f, 1.f));
|
identityShader->set("aColor", glm::vec3(0.f, 1.f, 1.f));
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include <QAbstractItemView>
|
#include <QAbstractItemView>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <qglobal.h>
|
||||||
|
#include <qwindowdefs.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "editorcommon.h"
|
#include "editorcommon.h"
|
||||||
|
@ -21,7 +24,8 @@
|
||||||
#include "physics/simulation.h"
|
#include "physics/simulation.h"
|
||||||
#include "objects/part.h"
|
#include "objects/part.h"
|
||||||
#include "qfiledialog.h"
|
#include "qfiledialog.h"
|
||||||
#include "qitemselectionmodel.h"
|
#include "qclipboard.h"
|
||||||
|
#include "qmimedata.h"
|
||||||
#include "qobject.h"
|
#include "qobject.h"
|
||||||
#include "qsysinfo.h"
|
#include "qsysinfo.h"
|
||||||
|
|
||||||
|
@ -37,7 +41,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
timer.start(33, this);
|
timer.start(33, this);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
ConnectSelectionChangeHandler();
|
ui->explorerView->buildContextMenu();
|
||||||
|
|
||||||
connect(ui->actionToolSelect, &QAction::triggered, this, [&]() { selectedTool = SelectedTool::SELECT; updateToolbars(); });
|
connect(ui->actionToolSelect, &QAction::triggered, this, [&]() { selectedTool = SelectedTool::SELECT; updateToolbars(); });
|
||||||
connect(ui->actionToolMove, &QAction::triggered, this, [&](bool state) { selectedTool = state ? SelectedTool::MOVE : SelectedTool::SELECT; updateToolbars(); });
|
connect(ui->actionToolMove, &QAction::triggered, this, [&](bool state) { selectedTool = state ? SelectedTool::MOVE : SelectedTool::SELECT; updateToolbars(); });
|
||||||
|
@ -82,7 +86,78 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
delete ui->explorerView->selectionModel();
|
delete ui->explorerView->selectionModel();
|
||||||
ui->explorerView->reset();
|
ui->explorerView->reset();
|
||||||
ui->explorerView->setModel(new ExplorerModel(dataModel));
|
ui->explorerView->setModel(new ExplorerModel(dataModel));
|
||||||
ConnectSelectionChangeHandler();
|
});
|
||||||
|
|
||||||
|
connect(ui->actionDelete, &QAction::triggered, this, [&]() {
|
||||||
|
for (InstanceRefWeak inst : getSelection()) {
|
||||||
|
if (inst.expired()) continue;
|
||||||
|
inst.lock()->SetParent(std::nullopt);
|
||||||
|
}
|
||||||
|
setSelection(std::vector<InstanceRefWeak> {});
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->actionCopy, &QAction::triggered, this, [&]() {
|
||||||
|
pugi::xml_document rootDoc;
|
||||||
|
for (InstanceRefWeak inst : getSelection()) {
|
||||||
|
if (inst.expired()) continue;
|
||||||
|
inst.lock()->Serialize(&rootDoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream encoded;
|
||||||
|
rootDoc.save(encoded);
|
||||||
|
|
||||||
|
QMimeData* mimeData = new QMimeData;
|
||||||
|
mimeData->setData("application/xml", QByteArray::fromStdString(encoded.str()));
|
||||||
|
QApplication::clipboard()->setMimeData(mimeData);
|
||||||
|
});
|
||||||
|
connect(ui->actionCut, &QAction::triggered, this, [&]() {
|
||||||
|
pugi::xml_document rootDoc;
|
||||||
|
for (InstanceRefWeak inst : getSelection()) {
|
||||||
|
if (inst.expired()) continue;
|
||||||
|
inst.lock()->Serialize(&rootDoc);
|
||||||
|
inst.lock()->SetParent(std::nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream encoded;
|
||||||
|
rootDoc.save(encoded);
|
||||||
|
|
||||||
|
QMimeData* mimeData = new QMimeData;
|
||||||
|
mimeData->setData("application/xml", QByteArray::fromStdString(encoded.str()));
|
||||||
|
QApplication::clipboard()->setMimeData(mimeData);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->actionPaste, &QAction::triggered, this, [&]() {
|
||||||
|
const QMimeData* mimeData = QApplication::clipboard()->mimeData();
|
||||||
|
if (!mimeData || !mimeData->hasFormat("application/xml")) return;
|
||||||
|
QByteArray bytes = mimeData->data("application/xml");
|
||||||
|
std::string encoded = bytes.toStdString();
|
||||||
|
|
||||||
|
pugi::xml_document rootDoc;
|
||||||
|
rootDoc.load_string(encoded.c_str());
|
||||||
|
|
||||||
|
for (pugi::xml_node instNode : rootDoc.children()) {
|
||||||
|
InstanceRef inst = Instance::Deserialize(&instNode);
|
||||||
|
workspace()->AddChild(inst);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->actionPasteInto, &QAction::triggered, this, [&]() {
|
||||||
|
if (getSelection().size() != 1 || getSelection()[0].expired()) return;
|
||||||
|
|
||||||
|
InstanceRef selectedParent = getSelection()[0].lock();
|
||||||
|
|
||||||
|
const QMimeData* mimeData = QApplication::clipboard()->mimeData();
|
||||||
|
if (!mimeData || !mimeData->hasFormat("application/xml")) return;
|
||||||
|
QByteArray bytes = mimeData->data("application/xml");
|
||||||
|
std::string encoded = bytes.toStdString();
|
||||||
|
|
||||||
|
pugi::xml_document rootDoc;
|
||||||
|
rootDoc.load_string(encoded.c_str());
|
||||||
|
|
||||||
|
for (pugi::xml_node instNode : rootDoc.children()) {
|
||||||
|
InstanceRef inst = Instance::Deserialize(&instNode);
|
||||||
|
selectedParent->AddChild(inst);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update handles
|
// Update handles
|
||||||
|
@ -127,17 +202,6 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
syncPartPhysics(ui->mainWidget->lastPart);
|
syncPartPhysics(ui->mainWidget->lastPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::ConnectSelectionChangeHandler() {
|
|
||||||
// connect(ui->explorerView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [&](const QItemSelection &selected, const QItemSelection &deselected) {
|
|
||||||
// if (selected.count() == 0) return;
|
|
||||||
|
|
||||||
// std::optional<InstanceRef> inst = selected.count() == 0 ? std::nullopt
|
|
||||||
// : std::make_optional(((Instance*)selected.indexes()[0].internalPointer())->shared_from_this());
|
|
||||||
|
|
||||||
// ui->propertiesView->setSelected(inst);
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::chrono::time_point lastTime = std::chrono::steady_clock::now();
|
static std::chrono::time_point lastTime = std::chrono::steady_clock::now();
|
||||||
void MainWindow::timerEvent(QTimerEvent* evt) {
|
void MainWindow::timerEvent(QTimerEvent* evt) {
|
||||||
if (evt->timerId() != timer.timerId()) {
|
if (evt->timerId() != timer.timerId()) {
|
||||||
|
|
|
@ -44,6 +44,5 @@ private:
|
||||||
|
|
||||||
void updateToolbars();
|
void updateToolbars();
|
||||||
void timerEvent(QTimerEvent*) override;
|
void timerEvent(QTimerEvent*) override;
|
||||||
void ConnectSelectionChangeHandler();
|
|
||||||
};
|
};
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
|
@ -115,6 +115,12 @@
|
||||||
<addaction name="actionToolScale"/>
|
<addaction name="actionToolScale"/>
|
||||||
<addaction name="actionToolRotate"/>
|
<addaction name="actionToolRotate"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionDelete"/>
|
||||||
|
<addaction name="actionCopy"/>
|
||||||
|
<addaction name="actionCut"/>
|
||||||
|
<addaction name="actionPaste"/>
|
||||||
|
<addaction name="actionPasteInto"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionGridSnap1"/>
|
<addaction name="actionGridSnap1"/>
|
||||||
<addaction name="actionGridSnap05"/>
|
<addaction name="actionGridSnap05"/>
|
||||||
<addaction name="actionGridSnapOff"/>
|
<addaction name="actionGridSnapOff"/>
|
||||||
|
@ -315,6 +321,91 @@
|
||||||
<enum>QAction::MenuRole::NoRole</enum>
|
<enum>QAction::MenuRole::NoRole</enum>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionCopy">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-copy"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy objects to clipboard</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+C</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuRole">
|
||||||
|
<enum>QAction::MenuRole::NoRole</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCut">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-cut"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cut</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Cut objects into clipboard</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+X</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuRole">
|
||||||
|
<enum>QAction::MenuRole::NoRole</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPaste">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-paste"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Paste</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Paste objects from clipboard</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+V</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuRole">
|
||||||
|
<enum>QAction::MenuRole::NoRole</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPasteInto">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-paste"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Paste Into</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Paste objects from clipboard into selected object</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Shift+V</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuRole">
|
||||||
|
<enum>QAction::MenuRole::NoRole</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDelete">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-delete"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete Object</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Delete selected objects</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Del</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuRole">
|
||||||
|
<enum>QAction::MenuRole::NoRole</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
#include "explorerview.h"
|
#include "explorerview.h"
|
||||||
#include "explorermodel.h"
|
#include "explorermodel.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "../ui_mainwindow.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "objects/base/instance.h"
|
#include "objects/base/instance.h"
|
||||||
#include "objects/workspace.h"
|
|
||||||
#include "qabstractitemmodel.h"
|
#include "qabstractitemmodel.h"
|
||||||
#include "qaction.h"
|
#include <qaction.h>
|
||||||
#include "qnamespace.h"
|
#include <qnamespace.h>
|
||||||
#include <qitemselectionmodel.h>
|
#include <qitemselectionmodel.h>
|
||||||
|
|
||||||
|
#define M_mainWindow dynamic_cast<MainWindow*>(window())
|
||||||
|
|
||||||
ExplorerView::ExplorerView(QWidget* parent):
|
ExplorerView::ExplorerView(QWidget* parent):
|
||||||
QTreeView(parent),
|
QTreeView(parent),
|
||||||
model(ExplorerModel(std::dynamic_pointer_cast<Instance>(dataModel))) {
|
model(ExplorerModel(std::dynamic_pointer_cast<Instance>(dataModel))) {
|
||||||
|
@ -57,8 +60,6 @@ ExplorerView::ExplorerView(QWidget* parent):
|
||||||
this->selectionModel()->select(index, QItemSelectionModel::SelectionFlag::Select);
|
this->selectionModel()->select(index, QItemSelectionModel::SelectionFlag::Select);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
buildContextMenu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExplorerView::~ExplorerView() {
|
ExplorerView::~ExplorerView() {
|
||||||
|
@ -67,19 +68,17 @@ ExplorerView::~ExplorerView() {
|
||||||
void ExplorerView::keyPressEvent(QKeyEvent* event) {
|
void ExplorerView::keyPressEvent(QKeyEvent* event) {
|
||||||
switch (event->key()) {
|
switch (event->key()) {
|
||||||
case Qt::Key_Delete:
|
case Qt::Key_Delete:
|
||||||
actionDelete->trigger();
|
M_mainWindow->ui->actionDelete->trigger();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExplorerView::buildContextMenu() {
|
|
||||||
// This will leak memory. Anyway...
|
|
||||||
contextMenu.addAction(this->actionDelete = new QAction(QIcon("assets/icons/editor/delete"), "Delete"));
|
|
||||||
|
|
||||||
connect(actionDelete, &QAction::triggered, this, [&]() {
|
void ExplorerView::buildContextMenu() {
|
||||||
QModelIndexList selectedIndexes = this->selectionModel()->selectedIndexes();
|
contextMenu.addAction(M_mainWindow->ui->actionDelete);
|
||||||
for (QModelIndex index : selectedIndexes) {
|
contextMenu.addSeparator();
|
||||||
model.fromIndex(index)->SetParent(std::nullopt);
|
contextMenu.addAction(M_mainWindow->ui->actionCopy);
|
||||||
}
|
contextMenu.addAction(M_mainWindow->ui->actionCut);
|
||||||
});
|
contextMenu.addAction(M_mainWindow->ui->actionPaste);
|
||||||
|
contextMenu.addAction(M_mainWindow->ui->actionPasteInto);
|
||||||
}
|
}
|
|
@ -20,18 +20,9 @@ public:
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent*) override;
|
void keyPressEvent(QKeyEvent*) override;
|
||||||
// void dropEvent(QDropEvent*) override;
|
// void dropEvent(QDropEvent*) override;
|
||||||
|
|
||||||
|
void buildContextMenu();
|
||||||
private:
|
private:
|
||||||
ExplorerModel model;
|
ExplorerModel model;
|
||||||
QMenu contextMenu;
|
QMenu contextMenu;
|
||||||
|
|
||||||
// TODO: Move these to a separate top-level namespace so these can be
|
|
||||||
// accessed from multiple locations
|
|
||||||
QAction* actionDelete;
|
|
||||||
QAction* actionCopy;
|
|
||||||
QAction* actionCut;
|
|
||||||
QAction* actionPaste;
|
|
||||||
QAction* actionPasteInto;
|
|
||||||
QAction* actionSelectChildren;
|
|
||||||
|
|
||||||
void buildContextMenu();
|
|
||||||
};
|
};
|
Loading…
Reference in a new issue