Implemented World Editor Link/Unlink actions
This commit is contained in:
parent
93d6e8dd14
commit
0b5c7c8e90
|
@ -148,7 +148,8 @@ HEADERS += \
|
||||||
WorldEditor/CSelectInstanceDialog.h \
|
WorldEditor/CSelectInstanceDialog.h \
|
||||||
Undo/CAddLinkCommand.h \
|
Undo/CAddLinkCommand.h \
|
||||||
Undo/CDeleteLinksCommand.h \
|
Undo/CDeleteLinksCommand.h \
|
||||||
Undo/CEditLinkCommand.h
|
Undo/CEditLinkCommand.h \
|
||||||
|
WorldEditor/CConfirmUnlinkDialog.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
#ifndef CCONFIRMUNLINKDIALOG_H
|
||||||
|
#define CCONFIRMUNLINKDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
// This class is basically a workaround for the fact that QMessageBox doesn't allow directly controlling button placement
|
||||||
|
class CConfirmUnlinkDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum EChoice
|
||||||
|
{
|
||||||
|
eAll,
|
||||||
|
eIncomingOnly,
|
||||||
|
eOutgoingOnly,
|
||||||
|
eCancel
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLabel *mpLabel;
|
||||||
|
QPushButton *mpAllButton;
|
||||||
|
QPushButton *mpIncomingButton;
|
||||||
|
QPushButton *mpOutgoingButton;
|
||||||
|
QPushButton *mpCancelButton;
|
||||||
|
QHBoxLayout *mpButtonLayout;
|
||||||
|
QVBoxLayout *mpDialogLayout;
|
||||||
|
|
||||||
|
EChoice mChoice;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CConfirmUnlinkDialog(QWidget *pParent = 0)
|
||||||
|
: QDialog(pParent)
|
||||||
|
{
|
||||||
|
mpLabel = new QLabel("Which links should be removed from the selected instances?");
|
||||||
|
mpAllButton = new QPushButton("All");
|
||||||
|
mpIncomingButton = new QPushButton("Incoming Links");
|
||||||
|
mpOutgoingButton = new QPushButton("Outgoing Links");
|
||||||
|
mpCancelButton = new QPushButton("Cancel");
|
||||||
|
|
||||||
|
mpButtonLayout = new QHBoxLayout();
|
||||||
|
mpButtonLayout->addWidget(mpAllButton);
|
||||||
|
mpButtonLayout->addWidget(mpIncomingButton);
|
||||||
|
mpButtonLayout->addWidget(mpOutgoingButton);
|
||||||
|
mpButtonLayout->addWidget(mpCancelButton);
|
||||||
|
|
||||||
|
mpDialogLayout = new QVBoxLayout();
|
||||||
|
mpDialogLayout->addWidget(mpLabel);
|
||||||
|
mpDialogLayout->addLayout(mpButtonLayout);
|
||||||
|
setLayout(mpDialogLayout);
|
||||||
|
|
||||||
|
connect(mpAllButton, SIGNAL(clicked()), this, SLOT(OnAllClicked()));
|
||||||
|
connect(mpIncomingButton, SIGNAL(clicked()), this, SLOT(OnIncomingClicked()));
|
||||||
|
connect(mpOutgoingButton, SIGNAL(clicked()), this, SLOT(OnOutgoingClicked()));
|
||||||
|
connect(mpCancelButton, SIGNAL(clicked()), this, SLOT(OnCancelClicked()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EChoice UserChoice() const { return mChoice; }
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void OnAllClicked()
|
||||||
|
{
|
||||||
|
mChoice = eAll;
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnIncomingClicked()
|
||||||
|
{
|
||||||
|
mChoice = eIncomingOnly;
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnOutgoingClicked()
|
||||||
|
{
|
||||||
|
mChoice = eOutgoingOnly;
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCancelClicked()
|
||||||
|
{
|
||||||
|
mChoice = eCancel;
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CCONFIRMUNLINKDIALOG_H
|
|
@ -1,5 +1,7 @@
|
||||||
#include "CWorldEditor.h"
|
#include "CWorldEditor.h"
|
||||||
#include "ui_CWorldEditor.h"
|
#include "ui_CWorldEditor.h"
|
||||||
|
|
||||||
|
#include "CConfirmUnlinkDialog.h"
|
||||||
#include "CLayerEditor.h"
|
#include "CLayerEditor.h"
|
||||||
#include "WModifyTab.h"
|
#include "WModifyTab.h"
|
||||||
#include "WInstancesTab.h"
|
#include "WInstancesTab.h"
|
||||||
|
@ -22,19 +24,20 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
|
|
||||||
CWorldEditor::CWorldEditor(QWidget *parent) :
|
CWorldEditor::CWorldEditor(QWidget *parent)
|
||||||
INodeEditor(parent),
|
: INodeEditor(parent)
|
||||||
ui(new Ui::CWorldEditor)
|
, ui(new Ui::CWorldEditor)
|
||||||
|
, mpArea(nullptr)
|
||||||
|
, mpWorld(nullptr)
|
||||||
|
, mpLinkDialog(new CLinkDialog(this, this))
|
||||||
|
, mpPoiDialog(nullptr)
|
||||||
|
, mIsMakingLink(false)
|
||||||
|
, mpNewLinkSender(nullptr)
|
||||||
|
, mpNewLinkReceiver(nullptr)
|
||||||
{
|
{
|
||||||
Log::Write("Creating World Editor");
|
Log::Write("Creating World Editor");
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
mpArea = nullptr;
|
|
||||||
mpWorld = nullptr;
|
|
||||||
mpLinkDialog = new CLinkDialog(this, this);
|
|
||||||
mpPoiDialog = nullptr;
|
|
||||||
mGizmoHovering = false;
|
|
||||||
mGizmoTransforming = false;
|
|
||||||
mSelectionNodeFlags = eScriptNode | eLightNode;
|
mSelectionNodeFlags = eScriptNode | eLightNode;
|
||||||
|
|
||||||
// Start refresh timer
|
// Start refresh timer
|
||||||
|
@ -88,6 +91,8 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
||||||
connect(ui->TransformSpinBox, SIGNAL(ValueChanged(CVector3f)), this, SLOT(OnTransformSpinBoxModified(CVector3f)));
|
connect(ui->TransformSpinBox, SIGNAL(ValueChanged(CVector3f)), this, SLOT(OnTransformSpinBoxModified(CVector3f)));
|
||||||
connect(ui->TransformSpinBox, SIGNAL(EditingDone(CVector3f)), this, SLOT(OnTransformSpinBoxEdited(CVector3f)));
|
connect(ui->TransformSpinBox, SIGNAL(EditingDone(CVector3f)), this, SLOT(OnTransformSpinBoxEdited(CVector3f)));
|
||||||
connect(ui->CamSpeedSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnCameraSpeedChange(double)));
|
connect(ui->CamSpeedSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnCameraSpeedChange(double)));
|
||||||
|
connect(ui->ActionLink, SIGNAL(toggled(bool)), this, SLOT(OnLinkButtonToggled(bool)));
|
||||||
|
connect(ui->ActionUnlink, SIGNAL(triggered()), this, SLOT(OnUnlinkClicked()));
|
||||||
connect(&mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
connect(&mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
||||||
|
|
||||||
connect(ui->ActionSave, SIGNAL(triggered()), this, SLOT(Save()));
|
connect(ui->ActionSave, SIGNAL(triggered()), this, SLOT(Save()));
|
||||||
|
@ -488,6 +493,102 @@ void CWorldEditor::GizmoModeChanged(CGizmo::EGizmoMode mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ PRIVATE SLOTS ************
|
// ************ PRIVATE SLOTS ************
|
||||||
|
void CWorldEditor::OnLinkButtonToggled(bool Enabled)
|
||||||
|
{
|
||||||
|
if (Enabled)
|
||||||
|
{
|
||||||
|
EnterPickMode(eScriptNode, true, false, false);
|
||||||
|
connect(this, SIGNAL(PickModeClick(SRayIntersection,QMouseEvent*)), this, SLOT(OnLinkClick(SRayIntersection)));
|
||||||
|
connect(this, SIGNAL(PickModeExited()), this, SLOT(OnLinkEnd()));
|
||||||
|
mIsMakingLink = true;
|
||||||
|
mpNewLinkSender = nullptr;
|
||||||
|
mpNewLinkReceiver = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mIsMakingLink)
|
||||||
|
ExitPickMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldEditor::OnLinkClick(const SRayIntersection& rkIntersect)
|
||||||
|
{
|
||||||
|
if (!mpNewLinkSender)
|
||||||
|
{
|
||||||
|
mpNewLinkSender = static_cast<CScriptNode*>(rkIntersect.pNode)->Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mpNewLinkReceiver = static_cast<CScriptNode*>(rkIntersect.pNode)->Object();
|
||||||
|
mpLinkDialog->NewLink(mpNewLinkSender, mpNewLinkReceiver);
|
||||||
|
mpLinkDialog->show();
|
||||||
|
ExitPickMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldEditor::OnLinkEnd()
|
||||||
|
{
|
||||||
|
disconnect(this, SIGNAL(PickModeClick(SRayIntersection,QMouseEvent*)), this, SLOT(OnLinkClick(SRayIntersection)));
|
||||||
|
disconnect(this, SIGNAL(PickModeExited()), this, SLOT(OnLinkEnd()));
|
||||||
|
ui->ActionLink->setChecked(false);
|
||||||
|
mIsMakingLink = false;
|
||||||
|
mpNewLinkSender = nullptr;
|
||||||
|
mpNewLinkReceiver = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldEditor::OnUnlinkClicked()
|
||||||
|
{
|
||||||
|
QList<CScriptNode*> SelectedScriptNodes;
|
||||||
|
|
||||||
|
foreach (CSceneNode *pNode, mSelection)
|
||||||
|
{
|
||||||
|
if (pNode->NodeType() == eScriptNode)
|
||||||
|
SelectedScriptNodes << static_cast<CScriptNode*>(pNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SelectedScriptNodes.isEmpty())
|
||||||
|
{
|
||||||
|
CConfirmUnlinkDialog Dialog(this);
|
||||||
|
Dialog.exec();
|
||||||
|
|
||||||
|
if (Dialog.UserChoice() != CConfirmUnlinkDialog::eCancel)
|
||||||
|
{
|
||||||
|
mUndoStack.beginMacro("Unlink");
|
||||||
|
bool UnlinkIncoming = (Dialog.UserChoice() != CConfirmUnlinkDialog::eOutgoingOnly);
|
||||||
|
bool UnlinkOutgoing = (Dialog.UserChoice() != CConfirmUnlinkDialog::eIncomingOnly);
|
||||||
|
|
||||||
|
foreach (CScriptNode *pNode, SelectedScriptNodes)
|
||||||
|
{
|
||||||
|
CScriptObject *pInst = pNode->Object();
|
||||||
|
|
||||||
|
if (UnlinkIncoming)
|
||||||
|
{
|
||||||
|
QVector<u32> LinkIndices;
|
||||||
|
for (u32 iLink = 0; iLink < pInst->NumLinks(eIncoming); iLink++)
|
||||||
|
LinkIndices << iLink;
|
||||||
|
|
||||||
|
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(this, pInst, eIncoming, LinkIndices);
|
||||||
|
mUndoStack.push(pCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UnlinkOutgoing)
|
||||||
|
{
|
||||||
|
QVector<u32> LinkIndices;
|
||||||
|
for (u32 iLink = 0; iLink < pInst->NumLinks(eOutgoing); iLink++)
|
||||||
|
LinkIndices << iLink;
|
||||||
|
|
||||||
|
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(this, pInst, eOutgoing, LinkIndices);
|
||||||
|
mUndoStack.push(pCmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mUndoStack.endMacro();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CWorldEditor::OnUndoStackIndexChanged()
|
void CWorldEditor::OnUndoStackIndexChanged()
|
||||||
{
|
{
|
||||||
// Check the commands that have been executed on the undo stack and find out whether any of them affect the clean state.
|
// Check the commands that have been executed on the undo stack and find out whether any of them affect the clean state.
|
||||||
|
|
|
@ -39,6 +39,10 @@ class CWorldEditor : public INodeEditor
|
||||||
CLinkDialog *mpLinkDialog;
|
CLinkDialog *mpLinkDialog;
|
||||||
CPoiMapEditDialog *mpPoiDialog;
|
CPoiMapEditDialog *mpPoiDialog;
|
||||||
|
|
||||||
|
bool mIsMakingLink;
|
||||||
|
CScriptObject *mpNewLinkSender;
|
||||||
|
CScriptObject *mpNewLinkReceiver;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CWorldEditor(QWidget *parent = 0);
|
explicit CWorldEditor(QWidget *parent = 0);
|
||||||
~CWorldEditor();
|
~CWorldEditor();
|
||||||
|
@ -68,6 +72,11 @@ protected:
|
||||||
void GizmoModeChanged(CGizmo::EGizmoMode mode);
|
void GizmoModeChanged(CGizmo::EGizmoMode mode);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void OnLinkButtonToggled(bool Enabled);
|
||||||
|
void OnLinkClick(const SRayIntersection& rkIntersect);
|
||||||
|
void OnLinkEnd();
|
||||||
|
void OnUnlinkClicked();
|
||||||
|
|
||||||
void OnUndoStackIndexChanged();
|
void OnUndoStackIndexChanged();
|
||||||
void OnPickModeEnter(QCursor Cursor);
|
void OnPickModeEnter(QCursor Cursor);
|
||||||
void OnPickModeExit();
|
void OnPickModeExit();
|
||||||
|
|
|
@ -494,6 +494,9 @@
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionLink">
|
<action name="ActionLink">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../Icons.qrc">
|
<iconset resource="../Icons.qrc">
|
||||||
<normaloff>:/icons/Link.png</normaloff>:/icons/Link.png</iconset>
|
<normaloff>:/icons/Link.png</normaloff>:/icons/Link.png</iconset>
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="ConnectionsTab">
|
<widget class="QWidget" name="ConnectionsTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Connections</string>
|
<string>Links</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="ConnectionsLayout">
|
<layout class="QVBoxLayout" name="ConnectionsLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
|
@ -169,7 +169,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../Icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/Plus.png</normaloff>:/icons/Plus.png</iconset>
|
<normaloff>:/icons/Plus.png</normaloff>:/icons/Plus.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="popupMode">
|
<property name="popupMode">
|
||||||
|
@ -221,7 +221,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../Icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/Minus v2.png</normaloff>:/icons/Minus v2.png</iconset>
|
<normaloff>:/icons/Minus v2.png</normaloff>:/icons/Minus v2.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -282,7 +282,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../Icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/Plus.png</normaloff>:/icons/Plus.png</iconset>
|
<normaloff>:/icons/Plus.png</normaloff>:/icons/Plus.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="popupMode">
|
<property name="popupMode">
|
||||||
|
@ -325,7 +325,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../Icons.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/Minus v2.png</normaloff>:/icons/Minus v2.png</iconset>
|
<normaloff>:/icons/Minus v2.png</normaloff>:/icons/Minus v2.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -359,8 +359,6 @@
|
||||||
<header>Editor/PropertyEdit/CPropertyView.h</header>
|
<header>Editor/PropertyEdit/CPropertyView.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources/>
|
||||||
<include location="../Icons.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
Loading…
Reference in New Issue