Compare commits
No commits in common. "153fbba2d2ed39b798cb29e7f6b1526cbba13c40" and "375d6c89b99a9c2b62579b9bf0340516f550d663" have entirely different histories.
153fbba2d2
...
375d6c89b9
9 changed files with 28 additions and 116 deletions
|
@ -3,7 +3,6 @@
|
||||||
#include "physics/util.h"
|
#include "physics/util.h"
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
#include <glm/gtc/matrix_inverse.hpp>
|
#include <glm/gtc/matrix_inverse.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
|
||||||
#include <glm/matrix.hpp>
|
#include <glm/matrix.hpp>
|
||||||
#include <reactphysics3d/mathematics/Transform.h>
|
#include <reactphysics3d/mathematics/Transform.h>
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
@ -84,7 +83,7 @@ Data::Vector3 Data::CFrame::ToEulerAnglesXYZ() {
|
||||||
|
|
||||||
Data::CFrame Data::CFrame::FromEulerAnglesXYZ(Data::Vector3 vector) {
|
Data::CFrame Data::CFrame::FromEulerAnglesXYZ(Data::Vector3 vector) {
|
||||||
glm::mat3 mat = glm::eulerAngleXYZ(vector.X(), vector.Y(), vector.Z());
|
glm::mat3 mat = glm::eulerAngleXYZ(vector.X(), vector.Y(), vector.Z());
|
||||||
return Data::CFrame((glm::vec3)Data::Vector3::ZERO, mat);
|
return Data::CFrame(Data::Vector3::ZERO, glm::column(mat, 2), (Data::Vector3)glm::column(mat, 1)); // Getting LookAt (3rd) and Up (2nd) vectors
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::CFrame Data::CFrame::Inverse() const {
|
Data::CFrame Data::CFrame::Inverse() const {
|
||||||
|
|
|
@ -51,7 +51,3 @@ namespace Data {
|
||||||
bool operator ==(Data::Vector3) const;
|
bool operator ==(Data::Vector3) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void printVec(Data::Vector3 vec) {
|
|
||||||
printf("(%f, %f, %f)\n", vec.X(), vec.Y(), vec.Z());
|
|
||||||
}
|
|
|
@ -62,7 +62,7 @@ void DataModel::SaveToFile(std::optional<std::string> path) {
|
||||||
doc.save(outStream);
|
doc.save(outStream);
|
||||||
currentFile = target;
|
currentFile = target;
|
||||||
name = target;
|
name = target;
|
||||||
Logger::info("Place saved successfully");
|
Logger::info("Place saved succesfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataModel::DeserializeService(pugi::xml_node* node) {
|
void DataModel::DeserializeService(pugi::xml_node* node) {
|
||||||
|
|
|
@ -16,8 +16,6 @@ HandleFace HandleFace::ZPos(4, glm::vec3(0,0,1));
|
||||||
HandleFace HandleFace::ZNeg(5, glm::vec3(0,0,-1));
|
HandleFace HandleFace::ZNeg(5, glm::vec3(0,0,-1));
|
||||||
std::array<HandleFace, 6> HandleFace::Faces { HandleFace::XPos, HandleFace::XNeg, HandleFace::YPos, HandleFace::YNeg, HandleFace::ZPos, HandleFace::ZNeg };
|
std::array<HandleFace, 6> HandleFace::Faces { HandleFace::XPos, HandleFace::XNeg, HandleFace::YPos, HandleFace::YNeg, HandleFace::ZPos, HandleFace::ZNeg };
|
||||||
|
|
||||||
static Data::CFrame XYZToZXY(glm::vec3(0, 0, 0), -glm::vec3(1, 0, 0), glm::vec3(0, 0, 1));
|
|
||||||
|
|
||||||
// Shitty solution
|
// Shitty solution
|
||||||
static rp3d::PhysicsCommon common;
|
static rp3d::PhysicsCommon common;
|
||||||
static rp3d::PhysicsWorld* world = common.createPhysicsWorld();
|
static rp3d::PhysicsWorld* world = common.createPhysicsWorld();
|
||||||
|
@ -41,18 +39,14 @@ Data::CFrame Handles::GetCFrameOfHandle(HandleFace face) {
|
||||||
|
|
||||||
Data::CFrame localFrame = worldMode ? Data::CFrame::IDENTITY + adornee->lock()->position() : adornee->lock()->cframe;
|
Data::CFrame localFrame = worldMode ? Data::CFrame::IDENTITY + adornee->lock()->position() : adornee->lock()->cframe;
|
||||||
|
|
||||||
Data::Vector3 handleNormal = face.normal;
|
|
||||||
if (nixAxes)
|
|
||||||
handleNormal = XYZToZXY * face.normal;
|
|
||||||
|
|
||||||
// We don't want this to align with local * face.normal, or else we have problems.
|
// We don't want this to align with local * face.normal, or else we have problems.
|
||||||
glm::vec3 upAxis(0, 0, 1);
|
glm::vec3 upAxis(0, 0, 1);
|
||||||
if (glm::abs(glm::dot(glm::vec3(localFrame.Rotation() * handleNormal), upAxis)) > 0.9999f)
|
if (glm::abs(glm::dot(glm::vec3(localFrame.Rotation() * face.normal), upAxis)) > 0.9999f)
|
||||||
upAxis = glm::vec3(0, 1, 0);
|
upAxis = glm::vec3(0, 1, 0);
|
||||||
|
|
||||||
Data::Vector3 handleOffset = this->worldMode ? ((Data::Vector3::ONE * 2.f) + adornee->lock()->GetAABB() * 0.5f) : Data::Vector3(2.f + adornee->lock()->size * 0.5f);
|
Data::Vector3 handleOffset = this->worldMode ? ((Data::Vector3::ONE * 2.f) + adornee->lock()->GetAABB() * 0.5f) : Data::Vector3(2.f + adornee->lock()->size * 0.5f);
|
||||||
Data::Vector3 handlePos = localFrame * (handleOffset * handleNormal);
|
Data::Vector3 handlePos = localFrame * (handleOffset * face.normal);
|
||||||
Data::CFrame cframe(handlePos, handlePos + localFrame.Rotation() * -handleNormal, upAxis);
|
Data::CFrame cframe(handlePos, handlePos + localFrame.Rotation() * -face.normal, upAxis);
|
||||||
|
|
||||||
return cframe;
|
return cframe;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ class Handles : public Instance {
|
||||||
public:
|
public:
|
||||||
const static InstanceType TYPE;
|
const static InstanceType TYPE;
|
||||||
|
|
||||||
bool nixAxes = false; // XYZ -> ZXY, used with rotation
|
|
||||||
bool active;
|
bool active;
|
||||||
std::optional<std::weak_ptr<Part>> adornee;
|
std::optional<std::weak_ptr<Part>> adornee;
|
||||||
HandlesType handlesType;
|
HandlesType handlesType;
|
||||||
|
|
|
@ -10,14 +10,12 @@
|
||||||
#include <glm/geometric.hpp>
|
#include <glm/geometric.hpp>
|
||||||
#include <glm/gtc/round.hpp>
|
#include <glm/gtc/round.hpp>
|
||||||
#include <glm/matrix.hpp>
|
#include <glm/matrix.hpp>
|
||||||
#include <glm/trigonometric.hpp>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <reactphysics3d/collision/RaycastInfo.h>
|
#include <reactphysics3d/collision/RaycastInfo.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "datatypes/cframe.h"
|
#include "datatypes/cframe.h"
|
||||||
#include "datatypes/vector.h"
|
|
||||||
#include "editorcommon.h"
|
#include "editorcommon.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
@ -35,10 +33,9 @@
|
||||||
#include "rendering/shader.h"
|
#include "rendering/shader.h"
|
||||||
|
|
||||||
#include "mainglwidget.h"
|
#include "mainglwidget.h"
|
||||||
|
#include "../core/src/rendering/defaultmeshes.h"
|
||||||
#include "math_helper.h"
|
#include "math_helper.h"
|
||||||
|
|
||||||
static Data::CFrame XYZToZXY(glm::vec3(0, 0, 0), -glm::vec3(1, 0, 0), glm::vec3(0, 0, 1));
|
|
||||||
|
|
||||||
MainGLWidget::MainGLWidget(QWidget* parent): QOpenGLWidget(parent) {
|
MainGLWidget::MainGLWidget(QWidget* parent): QOpenGLWidget(parent) {
|
||||||
setFocusPolicy(Qt::FocusPolicy::ClickFocus);
|
setFocusPolicy(Qt::FocusPolicy::ClickFocus);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
@ -144,18 +141,17 @@ void MainGLWidget::handleObjectDrag(QMouseEvent* evt) {
|
||||||
Data::CFrame targetFrame = partFromBody(rayHit->body)->cframe;
|
Data::CFrame targetFrame = partFromBody(rayHit->body)->cframe;
|
||||||
Data::Vector3 surfaceNormal = targetFrame.Inverse().Rotation() * rayHit->worldNormal;
|
Data::Vector3 surfaceNormal = targetFrame.Inverse().Rotation() * rayHit->worldNormal;
|
||||||
// The part being dragged's frame local to the hit target's frame, but without its position component
|
// The part being dragged's frame local to the hit target's frame, but without its position component
|
||||||
// To find a world vector local to the new frame, use newFrame, not localFrame, as localFrame is localFrame is local to targetFrame in itself
|
Data::CFrame localFrame = (targetFrame.Inverse() * draggingObject->lock()->cframe).Rotation();
|
||||||
Data::CFrame localFrame = (targetFrame.Inverse() * (draggingObject->lock()->cframe.Rotation() + vec));
|
|
||||||
|
|
||||||
// Snap axis
|
// Snap axis
|
||||||
localFrame = snapCFrame(localFrame);
|
localFrame = snapCFrame(localFrame);
|
||||||
Data::CFrame newFrame = targetFrame * localFrame;
|
|
||||||
|
|
||||||
// Unsink the object
|
// Unsink the object
|
||||||
// Get the normal of the surface relative to the part's frame, and get the size along that vector
|
// Get the normal of the surface relative to the part's frame, and get the size along that vector
|
||||||
Data::Vector3 unsinkOffset = newFrame.Rotation() * ((newFrame.Rotation().Inverse() * rayHit->worldNormal) * draggingObject->lock()->size / 2);
|
Data::Vector3 partOffset = localFrame * ((localFrame.Inverse() * rayHit->worldNormal) * draggingObject->lock()->size / 2);
|
||||||
|
|
||||||
draggingObject->lock()->cframe = newFrame + unsinkOffset;
|
Data::CFrame newFrame = targetFrame.Rotation() * localFrame;
|
||||||
|
draggingObject->lock()->cframe = newFrame + vec + partOffset;
|
||||||
|
|
||||||
syncPartPhysics(draggingObject->lock());
|
syncPartPhysics(draggingObject->lock());
|
||||||
}
|
}
|
||||||
|
@ -164,8 +160,11 @@ inline glm::vec3 vec3fy(glm::vec4 vec) {
|
||||||
return vec / vec.w;
|
return vec / vec.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taken from Godot's implementation of moving handles (godot/editor/plugins/gizmos/gizmo_3d_helper.cpp)
|
QPoint lastPoint;
|
||||||
void MainGLWidget::handleLinearTransform(QMouseEvent* evt) {
|
void MainGLWidget::handleHandleDrag(QMouseEvent* evt) {
|
||||||
|
QPoint cLastPoint = lastPoint;
|
||||||
|
lastPoint = evt->pos();
|
||||||
|
|
||||||
if (!isMouseDragging || !draggingHandle || !editorToolHandles->adornee || !editorToolHandles->active) return;
|
if (!isMouseDragging || !draggingHandle || !editorToolHandles->adornee || !editorToolHandles->active) return;
|
||||||
|
|
||||||
QPoint position = evt->pos();
|
QPoint position = evt->pos();
|
||||||
|
@ -204,6 +203,7 @@ void MainGLWidget::handleLinearTransform(QMouseEvent* evt) {
|
||||||
// printf("Post-snap: (%f, %f, %f)\n", diff.x, diff.y, diff.z);
|
// printf("Post-snap: (%f, %f, %f)\n", diff.x, diff.y, diff.z);
|
||||||
|
|
||||||
switch (mainWindow()->selectedTool) {
|
switch (mainWindow()->selectedTool) {
|
||||||
|
case SelectedTool::SELECT: break;
|
||||||
case SelectedTool::MOVE: {
|
case SelectedTool::MOVE: {
|
||||||
// Add difference
|
// Add difference
|
||||||
editorToolHandles->adornee->lock()->cframe = editorToolHandles->adornee->lock()->cframe + diff;
|
editorToolHandles->adornee->lock()->cframe = editorToolHandles->adornee->lock()->cframe + diff;
|
||||||
|
@ -227,58 +227,14 @@ void MainGLWidget::handleLinearTransform(QMouseEvent* evt) {
|
||||||
part->cframe = part->cframe + diff * 0.5f;
|
part->cframe = part->cframe + diff * 0.5f;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
case SelectedTool::ROTATE: {
|
||||||
Logger::error("Invalid tool was set to be handled by handleLinearTransform\n");
|
// TODO: Implement rotation
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
syncPartPhysics(std::dynamic_pointer_cast<Part>(editorToolHandles->adornee->lock()));
|
syncPartPhysics(std::dynamic_pointer_cast<Part>(editorToolHandles->adornee->lock()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also implemented based on Godot: [c7ea8614](godot/editor/plugins/canvas_item_editor_plugin.cpp#L1490)
|
|
||||||
glm::vec2 startPoint;
|
|
||||||
QPoint _lastPoint;
|
|
||||||
void MainGLWidget::handleRotationalTransform(QMouseEvent* evt) {
|
|
||||||
QPoint lastPoint = _lastPoint;
|
|
||||||
_lastPoint = evt->pos();
|
|
||||||
|
|
||||||
glm::vec2 startPoint(lastPoint.x(), lastPoint.y());
|
|
||||||
|
|
||||||
if (!isMouseDragging || !draggingHandle || !editorToolHandles->adornee || !editorToolHandles->active) return;
|
|
||||||
|
|
||||||
glm::vec2 destPoint = glm::vec2(evt->pos().x(), evt->pos().y());
|
|
||||||
auto part = editorToolHandles->adornee->lock();
|
|
||||||
|
|
||||||
// Calculate part pos as screen point
|
|
||||||
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)width() / (float)height(), 0.1f, 1000.0f);
|
|
||||||
glm::mat4 view = camera.getLookAt();
|
|
||||||
glm::vec4 screenPos = projection * view * glm::vec4((glm::vec3)part->cframe.Position(), 1.f);
|
|
||||||
screenPos /= screenPos.w * 2;
|
|
||||||
screenPos += 0.5f;
|
|
||||||
screenPos = glm::vec4(screenPos.x, 1-screenPos.y, 0, 0);
|
|
||||||
screenPos *= glm::vec4(width(), height(), 0, 0);
|
|
||||||
|
|
||||||
// https://wumbo.net/formulas/angle-between-two-vectors-2d/
|
|
||||||
glm::vec2 initVec = glm::normalize(startPoint - (glm::vec2)screenPos);
|
|
||||||
glm::vec2 destVec = glm::normalize(destPoint - (glm::vec2)screenPos);
|
|
||||||
float angle = atan2f(initVec.x * destVec.y - initVec.y * destVec.x, initVec.x * destVec.x + initVec.y * destVec.y);
|
|
||||||
|
|
||||||
// Yes, it's messy. But it works so I don't wanna hear it.
|
|
||||||
// Maybe I'll clean it up next week.
|
|
||||||
// TODO: ?
|
|
||||||
glm::vec4 pos1 = projection * view * glm::vec4((glm::vec3)part->cframe.Position(), 1.f);
|
|
||||||
pos1 /= pos1.w;
|
|
||||||
glm::vec4 otherVec = projection * view * glm::vec4((glm::vec3)(part->cframe * glm::abs(draggingHandle->normal)), 1.f);
|
|
||||||
otherVec /= otherVec.w;
|
|
||||||
glm::vec4 signVec = glm::normalize(otherVec - pos1);
|
|
||||||
float sign = glm::sign(signVec.z);
|
|
||||||
|
|
||||||
glm::vec3 angles = glm::abs(draggingHandle->normal) * -sign * glm::vec3(angle);
|
|
||||||
|
|
||||||
part->cframe = part->cframe * Data::CFrame::FromEulerAnglesXYZ(-angles);
|
|
||||||
|
|
||||||
syncPartPhysics(std::dynamic_pointer_cast<Part>(editorToolHandles->adornee->lock()));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<HandleFace> MainGLWidget::raycastHandle(glm::vec3 pointDir) {
|
std::optional<HandleFace> MainGLWidget::raycastHandle(glm::vec3 pointDir) {
|
||||||
if (!editorToolHandles->adornee.has_value() || !editorToolHandles->active) return std::nullopt;
|
if (!editorToolHandles->adornee.has_value() || !editorToolHandles->active) return std::nullopt;
|
||||||
return editorToolHandles->RaycastHandle(rp3d::Ray(glmToRp(camera.cameraPos), glmToRp(glm::normalize(pointDir)) * 50000));
|
return editorToolHandles->RaycastHandle(rp3d::Ray(glmToRp(camera.cameraPos), glmToRp(glm::normalize(pointDir)) * 50000));
|
||||||
|
@ -306,19 +262,8 @@ void MainGLWidget::handleCursorChange(QMouseEvent* evt) {
|
||||||
void MainGLWidget::mouseMoveEvent(QMouseEvent* evt) {
|
void MainGLWidget::mouseMoveEvent(QMouseEvent* evt) {
|
||||||
handleCameraRotate(evt);
|
handleCameraRotate(evt);
|
||||||
handleObjectDrag(evt);
|
handleObjectDrag(evt);
|
||||||
|
handleHandleDrag(evt);
|
||||||
handleCursorChange(evt);
|
handleCursorChange(evt);
|
||||||
|
|
||||||
switch (mainWindow()->selectedTool) {
|
|
||||||
case SelectedTool::MOVE:
|
|
||||||
case SelectedTool::SCALE:
|
|
||||||
handleLinearTransform(evt);
|
|
||||||
break;
|
|
||||||
case SelectedTool::ROTATE:
|
|
||||||
handleRotationalTransform(evt);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
||||||
|
@ -336,7 +281,6 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
||||||
// raycast handles
|
// raycast handles
|
||||||
auto handle = raycastHandle(pointDir);
|
auto handle = raycastHandle(pointDir);
|
||||||
if (handle.has_value()) {
|
if (handle.has_value()) {
|
||||||
startPoint = glm::vec2(evt->pos().x(), evt->pos().y());
|
|
||||||
isMouseDragging = true;
|
isMouseDragging = true;
|
||||||
draggingHandle = handle;
|
draggingHandle = handle;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -23,8 +23,7 @@ protected:
|
||||||
|
|
||||||
void handleCameraRotate(QMouseEvent* evt);
|
void handleCameraRotate(QMouseEvent* evt);
|
||||||
void handleObjectDrag(QMouseEvent* evt);
|
void handleObjectDrag(QMouseEvent* evt);
|
||||||
void handleLinearTransform(QMouseEvent* evt);
|
void handleHandleDrag(QMouseEvent* evt);
|
||||||
void handleRotationalTransform(QMouseEvent* evt);
|
|
||||||
void handleCursorChange(QMouseEvent* evt);
|
void handleCursorChange(QMouseEvent* evt);
|
||||||
std::optional<HandleFace> raycastHandle(glm::vec3 pointDir);
|
std::optional<HandleFace> raycastHandle(glm::vec3 pointDir);
|
||||||
|
|
||||||
|
|
|
@ -118,21 +118,14 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
std::optional<std::string> path;
|
std::optional<std::string> path;
|
||||||
if (!dataModel->HasFile())
|
if (!dataModel->HasFile())
|
||||||
path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save " + dataModel->name));
|
path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save " + dataModel->name));
|
||||||
if (!path || path == "") return;
|
if (path == "") return;
|
||||||
|
|
||||||
dataModel->SaveToFile(path);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(ui->actionSaveAs, &QAction::triggered, this, [&]() {
|
|
||||||
std::optional<std::string> path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save as " + dataModel->name));
|
|
||||||
if (!path || path == "") return;
|
|
||||||
|
|
||||||
dataModel->SaveToFile(path);
|
dataModel->SaveToFile(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->actionOpen, &QAction::triggered, this, [&]() {
|
connect(ui->actionOpen, &QAction::triggered, this, [&]() {
|
||||||
std::optional<std::string> path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptOpen);
|
std::optional<std::string> path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptOpen);
|
||||||
if (!path || path == "") return;
|
if (!path) return;
|
||||||
std::shared_ptr<DataModel> newModel = DataModel::LoadFromFile(path.value());
|
std::shared_ptr<DataModel> newModel = DataModel::LoadFromFile(path.value());
|
||||||
dataModel = newModel;
|
dataModel = newModel;
|
||||||
ui->explorerView->updateRoot(newModel);
|
ui->explorerView->updateRoot(newModel);
|
||||||
|
@ -323,8 +316,11 @@ void MainWindow::updateToolbars() {
|
||||||
ui->actionGridSnap05->setChecked(snappingMode == GridSnappingMode::SNAP_05_STUDS);
|
ui->actionGridSnap05->setChecked(snappingMode == GridSnappingMode::SNAP_05_STUDS);
|
||||||
ui->actionGridSnapOff->setChecked(snappingMode == GridSnappingMode::SNAP_OFF);
|
ui->actionGridSnapOff->setChecked(snappingMode == GridSnappingMode::SNAP_OFF);
|
||||||
|
|
||||||
editorToolHandles->worldMode = selectedTool == SelectedTool::SCALE ? false : worldSpaceTransforms;
|
// editorToolHandles->worldMode = false;
|
||||||
editorToolHandles->nixAxes = selectedTool == SelectedTool::ROTATE;
|
if (selectedTool == SelectedTool::SCALE)
|
||||||
|
editorToolHandles->worldMode = false;
|
||||||
|
else
|
||||||
|
editorToolHandles->worldMode = worldSpaceTransforms;
|
||||||
|
|
||||||
editorToolHandles->active = selectedTool != SelectedTool::SELECT;
|
editorToolHandles->active = selectedTool != SelectedTool::SELECT;
|
||||||
editorToolHandles->handlesType =
|
editorToolHandles->handlesType =
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
<addaction name="actionNew"/>
|
<addaction name="actionNew"/>
|
||||||
<addaction name="actionOpen"/>
|
<addaction name="actionOpen"/>
|
||||||
<addaction name="actionSave"/>
|
<addaction name="actionSave"/>
|
||||||
<addaction name="actionSaveAs"/>
|
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionQuit"/>
|
<addaction name="actionQuit"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -481,20 +480,6 @@
|
||||||
<enum>QAction::MenuRole::NoRole</enum>
|
<enum>QAction::MenuRole::NoRole</enum>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionSaveAs">
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="document-save-as"/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Save As...</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Shift+S</string>
|
|
||||||
</property>
|
|
||||||
<property name="menuRole">
|
|
||||||
<enum>QAction::MenuRole::NoRole</enum>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
Loading…
Add table
Reference in a new issue