Implemented World Editor Link/Unlink actions
This commit is contained in:
parent
93d6e8dd14
commit
0b5c7c8e90
|
@ -148,7 +148,8 @@ HEADERS += \
|
|||
WorldEditor/CSelectInstanceDialog.h \
|
||||
Undo/CAddLinkCommand.h \
|
||||
Undo/CDeleteLinksCommand.h \
|
||||
Undo/CEditLinkCommand.h
|
||||
Undo/CEditLinkCommand.h \
|
||||
WorldEditor/CConfirmUnlinkDialog.h
|
||||
|
||||
# Source Files
|
||||
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 "ui_CWorldEditor.h"
|
||||
|
||||
#include "CConfirmUnlinkDialog.h"
|
||||
#include "CLayerEditor.h"
|
||||
#include "WModifyTab.h"
|
||||
#include "WInstancesTab.h"
|
||||
|
@ -22,19 +24,20 @@
|
|||
#include <QMessageBox>
|
||||
#include <QOpenGLContext>
|
||||
|
||||
CWorldEditor::CWorldEditor(QWidget *parent) :
|
||||
INodeEditor(parent),
|
||||
ui(new Ui::CWorldEditor)
|
||||
CWorldEditor::CWorldEditor(QWidget *parent)
|
||||
: INodeEditor(parent)
|
||||
, 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");
|
||||
ui->setupUi(this);
|
||||
|
||||
mpArea = nullptr;
|
||||
mpWorld = nullptr;
|
||||
mpLinkDialog = new CLinkDialog(this, this);
|
||||
mpPoiDialog = nullptr;
|
||||
mGizmoHovering = false;
|
||||
mGizmoTransforming = false;
|
||||
mSelectionNodeFlags = eScriptNode | eLightNode;
|
||||
|
||||
// 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(EditingDone(CVector3f)), this, SLOT(OnTransformSpinBoxEdited(CVector3f)));
|
||||
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(ui->ActionSave, SIGNAL(triggered()), this, SLOT(Save()));
|
||||
|
@ -488,6 +493,102 @@ void CWorldEditor::GizmoModeChanged(CGizmo::EGizmoMode mode)
|
|||
}
|
||||
|
||||
// ************ 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()
|
||||
{
|
||||
// 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;
|
||||
CPoiMapEditDialog *mpPoiDialog;
|
||||
|
||||
bool mIsMakingLink;
|
||||
CScriptObject *mpNewLinkSender;
|
||||
CScriptObject *mpNewLinkReceiver;
|
||||
|
||||
public:
|
||||
explicit CWorldEditor(QWidget *parent = 0);
|
||||
~CWorldEditor();
|
||||
|
@ -68,6 +72,11 @@ protected:
|
|||
void GizmoModeChanged(CGizmo::EGizmoMode mode);
|
||||
|
||||
private slots:
|
||||
void OnLinkButtonToggled(bool Enabled);
|
||||
void OnLinkClick(const SRayIntersection& rkIntersect);
|
||||
void OnLinkEnd();
|
||||
void OnUnlinkClicked();
|
||||
|
||||
void OnUndoStackIndexChanged();
|
||||
void OnPickModeEnter(QCursor Cursor);
|
||||
void OnPickModeExit();
|
||||
|
|
|
@ -494,6 +494,9 @@
|
|||
</property>
|
||||
</action>
|
||||
<action name="ActionLink">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<normaloff>:/icons/Link.png</normaloff>:/icons/Link.png</iconset>
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
</widget>
|
||||
<widget class="QWidget" name="ConnectionsTab">
|
||||
<attribute name="title">
|
||||
<string>Connections</string>
|
||||
<string>Links</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="ConnectionsLayout">
|
||||
<property name="leftMargin">
|
||||
|
@ -169,7 +169,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/Plus.png</normaloff>:/icons/Plus.png</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
|
@ -221,7 +221,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/Minus v2.png</normaloff>:/icons/Minus v2.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
@ -282,7 +282,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/Plus.png</normaloff>:/icons/Plus.png</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
|
@ -325,7 +325,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/Minus v2.png</normaloff>:/icons/Minus v2.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
@ -359,8 +359,6 @@
|
|||
<header>Editor/PropertyEdit/CPropertyView.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../Icons.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
Loading…
Reference in New Issue