WIP string editor UI
This commit is contained in:
parent
0ae7b8686e
commit
76bc2b50f8
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef CCUSTOMDELEGATE_H
|
||||||
|
#define CCUSTOMDELEGATE_H
|
||||||
|
|
||||||
|
#include <QFont>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QPen>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
/** Font parameters for rendering text */
|
||||||
|
struct SDelegateFontInfo
|
||||||
|
{
|
||||||
|
QFont NameFont;
|
||||||
|
QFont InfoFont;
|
||||||
|
QFontMetrics NameFontMetrics;
|
||||||
|
QFontMetrics InfoFontMetrics;
|
||||||
|
QPen NamePen;
|
||||||
|
QPen InfoPen;
|
||||||
|
int Margin;
|
||||||
|
int Spacing;
|
||||||
|
|
||||||
|
SDelegateFontInfo()
|
||||||
|
: NameFontMetrics(NameFont), InfoFontMetrics(InfoFont) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Common base class of custom item delegate implementations */
|
||||||
|
class CCustomDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CCustomDelegate(QObject* pParent = 0)
|
||||||
|
: QStyledItemDelegate(pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual SDelegateFontInfo GetFontInfo(const QStyleOptionViewItem& rkOption) const
|
||||||
|
{
|
||||||
|
SDelegateFontInfo Info;
|
||||||
|
|
||||||
|
Info.NameFont = rkOption.font;
|
||||||
|
Info.NameFont.setPointSize( rkOption.font.pointSize() + 1 );
|
||||||
|
Info.NameFontMetrics = QFontMetrics(Info.NameFont);
|
||||||
|
|
||||||
|
Info.InfoFont = rkOption.font;
|
||||||
|
Info.InfoFont.setPointSize( rkOption.font.pointSize() - 1 );
|
||||||
|
Info.InfoFontMetrics = QFontMetrics(Info.InfoFont);
|
||||||
|
|
||||||
|
Info.NamePen = QPen(rkOption.palette.text(), 1.f);
|
||||||
|
|
||||||
|
Info.InfoPen = QPen(rkOption.palette.text(), 1.f);
|
||||||
|
Info.InfoPen.setColor( Info.InfoPen.color().darker(140) );
|
||||||
|
|
||||||
|
Info.Margin = 3;
|
||||||
|
Info.Spacing = 3;
|
||||||
|
|
||||||
|
return Info;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CCUSTOMDELEGATE_H
|
|
@ -5,6 +5,7 @@
|
||||||
#include "CProjectSettingsDialog.h"
|
#include "CProjectSettingsDialog.h"
|
||||||
#include "Editor/CharacterEditor/CCharacterEditor.h"
|
#include "Editor/CharacterEditor/CCharacterEditor.h"
|
||||||
#include "Editor/ModelEditor/CModelEditorWindow.h"
|
#include "Editor/ModelEditor/CModelEditorWindow.h"
|
||||||
|
#include "Editor/StringEditor/CStringEditor.h"
|
||||||
#include "Editor/ResourceBrowser/CResourceBrowser.h"
|
#include "Editor/ResourceBrowser/CResourceBrowser.h"
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
#include <Common/Macros.h>
|
#include <Common/Macros.h>
|
||||||
|
@ -152,6 +153,10 @@ void CEditorApplication::EditResource(CResourceEntry *pEntry)
|
||||||
case EResourceType::AnimSet:
|
case EResourceType::AnimSet:
|
||||||
pEd = new CCharacterEditor((CAnimSet*) pRes, mpWorldEditor);
|
pEd = new CCharacterEditor((CAnimSet*) pRes, mpWorldEditor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EResourceType::StringTable:
|
||||||
|
pEd = new CStringEditor((CStringTable*) pRes, mpWorldEditor);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pEd)
|
if (pEd)
|
||||||
|
|
|
@ -199,7 +199,11 @@ HEADERS += \
|
||||||
Widgets/CCheckableTreeWidgetItem.h \
|
Widgets/CCheckableTreeWidgetItem.h \
|
||||||
Widgets/CCheckableTreeWidget.h \
|
Widgets/CCheckableTreeWidget.h \
|
||||||
Undo/IEditPropertyCommand.h \
|
Undo/IEditPropertyCommand.h \
|
||||||
Widgets/TEnumComboBox.h
|
Widgets/TEnumComboBox.h \
|
||||||
|
StringEditor/CStringEditor.h \
|
||||||
|
StringEditor/CStringListModel.h \
|
||||||
|
StringEditor/CStringDelegate.h \
|
||||||
|
CCustomDelegate.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -274,7 +278,11 @@ SOURCES += \
|
||||||
ResourceBrowser/CVirtualDirectoryTreeView.cpp \
|
ResourceBrowser/CVirtualDirectoryTreeView.cpp \
|
||||||
CPropertyNameValidator.cpp \
|
CPropertyNameValidator.cpp \
|
||||||
CGeneratePropertyNamesDialog.cpp \
|
CGeneratePropertyNamesDialog.cpp \
|
||||||
Undo/IEditPropertyCommand.cpp
|
Undo/IEditPropertyCommand.cpp \
|
||||||
|
StringEditor/CStringEditor.cpp \
|
||||||
|
StringEditor/CStringListModel.cpp \
|
||||||
|
IEditor.cpp \
|
||||||
|
StringEditor/CStringDelegate.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
@ -301,7 +309,8 @@ FORMS += \
|
||||||
WorldEditor/CPoiMapSidebar.ui \
|
WorldEditor/CPoiMapSidebar.ui \
|
||||||
CProgressDialog.ui \
|
CProgressDialog.ui \
|
||||||
Widgets/CSelectResourcePanel.ui \
|
Widgets/CSelectResourcePanel.ui \
|
||||||
CGeneratePropertyNamesDialog.ui
|
CGeneratePropertyNamesDialog.ui \
|
||||||
|
StringEditor/CStringEditor.ui
|
||||||
|
|
||||||
# Codegen
|
# Codegen
|
||||||
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "IEditor.h"
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QToolBar>
|
||||||
|
|
||||||
|
IEditor::IEditor(QWidget* pParent)
|
||||||
|
: QMainWindow(pParent)
|
||||||
|
{
|
||||||
|
// Register the editor window
|
||||||
|
gpEdApp->AddEditor(this);
|
||||||
|
|
||||||
|
// Create undo actions
|
||||||
|
QAction *pUndoAction = mUndoStack.createUndoAction(this);
|
||||||
|
QAction *pRedoAction = mUndoStack.createRedoAction(this);
|
||||||
|
pUndoAction->setShortcut(QKeySequence::Undo);
|
||||||
|
pRedoAction->setShortcut(QKeySequence::Redo);
|
||||||
|
pUndoAction->setIcon(QIcon(":/icons/Undo.png"));
|
||||||
|
pRedoAction->setIcon(QIcon(":/icons/Redo.png"));
|
||||||
|
mUndoActions.push_back(pUndoAction);
|
||||||
|
mUndoActions.push_back(pRedoAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUndoStack& IEditor::UndoStack()
|
||||||
|
{
|
||||||
|
return mUndoStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IEditor::AddUndoActions(QToolBar* pToolBar, QAction* pBefore)
|
||||||
|
{
|
||||||
|
pToolBar->insertActions(pBefore, mUndoActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IEditor::AddUndoActions(QMenu* pMenu, QAction* pBefore)
|
||||||
|
{
|
||||||
|
pMenu->insertActions(pBefore, mUndoActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IEditor::CheckUnsavedChanges()
|
||||||
|
{
|
||||||
|
// Check whether the user has unsaved changes, return whether it's okay to clear the scene
|
||||||
|
bool OkToClear = !isWindowModified();
|
||||||
|
|
||||||
|
if (!OkToClear)
|
||||||
|
{
|
||||||
|
int Result = QMessageBox::warning(this, "Save", "You have unsaved changes. Save?", QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel);
|
||||||
|
|
||||||
|
if (Result == QMessageBox::Yes)
|
||||||
|
OkToClear = Save();
|
||||||
|
|
||||||
|
else if (Result == QMessageBox::No)
|
||||||
|
OkToClear = true;
|
||||||
|
|
||||||
|
else if (Result == QMessageBox::Cancel)
|
||||||
|
OkToClear = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OkToClear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** QMainWindow overrides */
|
||||||
|
void IEditor::closeEvent(QCloseEvent* pEvent)
|
||||||
|
{
|
||||||
|
if (CheckUnsavedChanges())
|
||||||
|
{
|
||||||
|
mUndoStack.clear();
|
||||||
|
pEvent->accept();
|
||||||
|
emit Closed();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pEvent->ignore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Non-virtual slots */
|
||||||
|
bool IEditor::SaveAndRepack()
|
||||||
|
{
|
||||||
|
if (Save())
|
||||||
|
{
|
||||||
|
gpEdApp->CookAllDirtyPackages();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
}
|
|
@ -2,23 +2,50 @@
|
||||||
#define IEDITOR
|
#define IEDITOR
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QList>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
#include "CEditorApplication.h"
|
#include "CEditorApplication.h"
|
||||||
|
|
||||||
|
/** Base class of all editor windows */
|
||||||
class IEditor : public QMainWindow
|
class IEditor : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
IEditor(QWidget *pParent)
|
// Undo stack
|
||||||
: QMainWindow(pParent)
|
QUndoStack mUndoStack;
|
||||||
{
|
QList<QAction*> mUndoActions;
|
||||||
gpEdApp->AddEditor(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void closeEvent(QCloseEvent*) { emit Closed(); }
|
public:
|
||||||
|
IEditor(QWidget* pParent);
|
||||||
|
QUndoStack& UndoStack();
|
||||||
|
void AddUndoActions(QToolBar* pToolBar, QAction* pBefore);
|
||||||
|
void AddUndoActions(QMenu* pMenu, QAction* pBefore);
|
||||||
|
bool CheckUnsavedChanges();
|
||||||
|
|
||||||
|
/** QMainWindow overrides */
|
||||||
|
virtual void closeEvent(QCloseEvent*);
|
||||||
|
|
||||||
|
/** Interface */
|
||||||
virtual void EditorTick(float /*DeltaTime*/) { }
|
virtual void EditorTick(float /*DeltaTime*/) { }
|
||||||
virtual CBasicViewport* Viewport() const { return nullptr; }
|
virtual CBasicViewport* Viewport() const { return nullptr; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/** Virtual slots */
|
||||||
|
virtual bool Save()
|
||||||
|
{
|
||||||
|
// Default implementation for editor windows that do not support resaving assets.
|
||||||
|
// This should not be called.
|
||||||
|
warnf("Base IEditor::Save() implementation called. Changes will not be saved.");
|
||||||
|
ASSERT(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Non-virtual slots */
|
||||||
|
bool SaveAndRepack();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void Closed();
|
void Closed();
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,14 +15,6 @@ INodeEditor::INodeEditor(QWidget *pParent)
|
||||||
, mRotateSpace(ETransformSpace::World)
|
, mRotateSpace(ETransformSpace::World)
|
||||||
, mCloneState(eNotCloning)
|
, mCloneState(eNotCloning)
|
||||||
{
|
{
|
||||||
// Create undo actions
|
|
||||||
QAction *pUndoAction = mUndoStack.createUndoAction(this);
|
|
||||||
QAction *pRedoAction = mUndoStack.createRedoAction(this);
|
|
||||||
pUndoAction->setShortcut(QKeySequence::Undo);
|
|
||||||
pRedoAction->setShortcut(QKeySequence::Redo);
|
|
||||||
mUndoActions.push_back(pUndoAction);
|
|
||||||
mUndoActions.push_back(pRedoAction);
|
|
||||||
|
|
||||||
// Create gizmo actions
|
// Create gizmo actions
|
||||||
mGizmoActions.append(new QAction(QIcon(":/icons/SelectMode.png"), "Select Objects", this));
|
mGizmoActions.append(new QAction(QIcon(":/icons/SelectMode.png"), "Select Objects", this));
|
||||||
mGizmoActions.append(new QAction(QIcon(":/icons/Translate.png"), "Translate", this));
|
mGizmoActions.append(new QAction(QIcon(":/icons/Translate.png"), "Translate", this));
|
||||||
|
@ -63,11 +55,6 @@ INodeEditor::~INodeEditor()
|
||||||
delete mpSelection;
|
delete mpSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUndoStack* INodeEditor::UndoStack()
|
|
||||||
{
|
|
||||||
return &mUndoStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
CScene* INodeEditor::Scene()
|
CScene* INodeEditor::Scene()
|
||||||
{
|
{
|
||||||
return &mScene;
|
return &mScene;
|
||||||
|
|
|
@ -12,17 +12,12 @@
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QUndoStack>
|
|
||||||
|
|
||||||
class INodeEditor : public IEditor
|
class INodeEditor : public IEditor
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Undo stack
|
|
||||||
QUndoStack mUndoStack;
|
|
||||||
QList<QAction*> mUndoActions;
|
|
||||||
|
|
||||||
// Node management
|
// Node management
|
||||||
CScene mScene;
|
CScene mScene;
|
||||||
CNodeSelection *mpSelection;
|
CNodeSelection *mpSelection;
|
||||||
|
@ -55,7 +50,6 @@ protected:
|
||||||
public:
|
public:
|
||||||
explicit INodeEditor(QWidget *pParent = 0);
|
explicit INodeEditor(QWidget *pParent = 0);
|
||||||
virtual ~INodeEditor();
|
virtual ~INodeEditor();
|
||||||
QUndoStack* UndoStack();
|
|
||||||
CScene* Scene();
|
CScene* Scene();
|
||||||
CGizmo* Gizmo();
|
CGizmo* Gizmo();
|
||||||
bool IsGizmoVisible();
|
bool IsGizmoVisible();
|
||||||
|
|
|
@ -151,6 +151,17 @@ CModelEditorWindow::~CModelEditorWindow()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CModelEditorWindow::Save()
|
||||||
|
{
|
||||||
|
if (!mpCurrentModel) return true;
|
||||||
|
bool SaveSuccess = mpCurrentModel->Entry()->Save();
|
||||||
|
|
||||||
|
if (SaveSuccess)
|
||||||
|
gpEdApp->NotifyAssetsModified();
|
||||||
|
|
||||||
|
return SaveSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
void CModelEditorWindow::RefreshViewport()
|
void CModelEditorWindow::RefreshViewport()
|
||||||
{
|
{
|
||||||
ui->Viewport->ProcessInput();
|
ui->Viewport->ProcessInput();
|
||||||
|
@ -749,15 +760,6 @@ void CModelEditorWindow::Import()
|
||||||
gpResourceStore->DestroyUnreferencedResources();
|
gpResourceStore->DestroyUnreferencedResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelEditorWindow::Save()
|
|
||||||
{
|
|
||||||
if (!mpCurrentModel) return;
|
|
||||||
bool SaveSuccess = mpCurrentModel->Entry()->Save();
|
|
||||||
|
|
||||||
if (SaveSuccess)
|
|
||||||
gpEdApp->NotifyAssetsModified();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModelEditorWindow::ConvertToDDS()
|
void CModelEditorWindow::ConvertToDDS()
|
||||||
{
|
{
|
||||||
QString Input = QFileDialog::getOpenFileName(this, "Retro Texture (*.TXTR)", "", "*.TXTR");
|
QString Input = QFileDialog::getOpenFileName(this, "Retro Texture (*.TXTR)", "", "*.TXTR");
|
||||||
|
|
|
@ -34,6 +34,7 @@ class CModelEditorWindow : public IEditor
|
||||||
public:
|
public:
|
||||||
explicit CModelEditorWindow(CModel *pModel, QWidget *pParent = 0);
|
explicit CModelEditorWindow(CModel *pModel, QWidget *pParent = 0);
|
||||||
~CModelEditorWindow();
|
~CModelEditorWindow();
|
||||||
|
bool Save();
|
||||||
void SetActiveModel(CModel *pModel);
|
void SetActiveModel(CModel *pModel);
|
||||||
CModelEditorViewport* Viewport() const;
|
CModelEditorViewport* Viewport() const;
|
||||||
|
|
||||||
|
@ -100,7 +101,6 @@ private:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void Import();
|
void Import();
|
||||||
void Save();
|
|
||||||
void ConvertToDDS();
|
void ConvertToDDS();
|
||||||
void ConvertToTXTR();
|
void ConvertToTXTR();
|
||||||
void SetMeshPreview();
|
void SetMeshPreview();
|
||||||
|
|
|
@ -525,7 +525,7 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
{
|
{
|
||||||
// Always consider the edit done for bool properties
|
// Always consider the edit done for bool properties
|
||||||
pCommand->SetEditComplete(!mEditInProgress || pProp->Type() == EPropertyType::Bool);
|
pCommand->SetEditComplete(!mEditInProgress || pProp->Type() == EPropertyType::Bool);
|
||||||
mpEditor->UndoStack()->push(pCommand);
|
mpEditor->UndoStack().push(pCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
|
@ -9,44 +9,6 @@
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
// Font Info
|
|
||||||
struct SResDelegateFontInfo
|
|
||||||
{
|
|
||||||
QFont NameFont;
|
|
||||||
QFont InfoFont;
|
|
||||||
QFontMetrics NameFontMetrics;
|
|
||||||
QFontMetrics InfoFontMetrics;
|
|
||||||
QPen NamePen;
|
|
||||||
QPen InfoPen;
|
|
||||||
int Margin;
|
|
||||||
int Spacing;
|
|
||||||
|
|
||||||
SResDelegateFontInfo()
|
|
||||||
: NameFontMetrics(NameFont), InfoFontMetrics(InfoFont) {}
|
|
||||||
};
|
|
||||||
SResDelegateFontInfo GetFontInfo(const QStyleOptionViewItem& rkOption)
|
|
||||||
{
|
|
||||||
SResDelegateFontInfo Info;
|
|
||||||
|
|
||||||
Info.NameFont = rkOption.font;
|
|
||||||
Info.NameFont.setPointSize( rkOption.font.pointSize() + 1 );
|
|
||||||
Info.NameFontMetrics = QFontMetrics(Info.NameFont);
|
|
||||||
|
|
||||||
Info.InfoFont = rkOption.font;
|
|
||||||
Info.InfoFont.setPointSize( rkOption.font.pointSize() - 1 );
|
|
||||||
Info.InfoFontMetrics = QFontMetrics(Info.InfoFont);
|
|
||||||
|
|
||||||
Info.NamePen = QPen(rkOption.palette.text(), 1.f);
|
|
||||||
|
|
||||||
Info.InfoPen = QPen(rkOption.palette.text(), 1.f);
|
|
||||||
Info.InfoPen.setColor( Info.InfoPen.color().darker(140) );
|
|
||||||
|
|
||||||
Info.Margin = 3;
|
|
||||||
Info.Spacing = 3;
|
|
||||||
|
|
||||||
return Info;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Geometry Info
|
// Geometry Info
|
||||||
struct SResDelegateGeometryInfo
|
struct SResDelegateGeometryInfo
|
||||||
{
|
{
|
||||||
|
@ -55,7 +17,7 @@ struct SResDelegateGeometryInfo
|
||||||
QRect NameStringRect;
|
QRect NameStringRect;
|
||||||
QRect InfoStringRect;
|
QRect InfoStringRect;
|
||||||
};
|
};
|
||||||
SResDelegateGeometryInfo GetGeometryInfo(const SResDelegateFontInfo& rkFontInfo, const QStyleOptionViewItem& rkOption, bool IsDirectory)
|
SResDelegateGeometryInfo GetGeometryInfo(const SDelegateFontInfo& rkFontInfo, const QStyleOptionViewItem& rkOption, bool IsDirectory)
|
||||||
{
|
{
|
||||||
SResDelegateGeometryInfo Info;
|
SResDelegateGeometryInfo Info;
|
||||||
|
|
||||||
|
@ -101,7 +63,7 @@ SResDelegateGeometryInfo GetGeometryInfo(const SResDelegateFontInfo& rkFontInfo,
|
||||||
QSize CResourceBrowserDelegate::sizeHint(const QStyleOptionViewItem& rkOption, const QModelIndex&) const
|
QSize CResourceBrowserDelegate::sizeHint(const QStyleOptionViewItem& rkOption, const QModelIndex&) const
|
||||||
{
|
{
|
||||||
// Get string info
|
// Get string info
|
||||||
SResDelegateFontInfo Info = GetFontInfo(rkOption);
|
SDelegateFontInfo Info = GetFontInfo(rkOption);
|
||||||
|
|
||||||
// Calculate height
|
// Calculate height
|
||||||
int Height = (Info.Margin * 2) + Info.NameFontMetrics.height() + Info.Spacing + Info.InfoFontMetrics.height();
|
int Height = (Info.Margin * 2) + Info.NameFontMetrics.height() + Info.Spacing + Info.InfoFontMetrics.height();
|
||||||
|
@ -114,7 +76,7 @@ void CResourceBrowserDelegate::paint(QPainter *pPainter, const QStyleOptionViewI
|
||||||
CResourceEntry *pEntry = GetIndexEntry(rkIndex);
|
CResourceEntry *pEntry = GetIndexEntry(rkIndex);
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
SResDelegateFontInfo FontInfo = GetFontInfo(rkOption);
|
SDelegateFontInfo FontInfo = GetFontInfo(rkOption);
|
||||||
SResDelegateGeometryInfo GeomInfo = GetGeometryInfo(FontInfo, rkOption, pEntry == nullptr);
|
SResDelegateGeometryInfo GeomInfo = GetGeometryInfo(FontInfo, rkOption, pEntry == nullptr);
|
||||||
|
|
||||||
// Draw icon
|
// Draw icon
|
||||||
|
@ -200,7 +162,7 @@ void CResourceBrowserDelegate::updateEditorGeometry(QWidget *pEditor, const QSty
|
||||||
bool IsDir = GetIndexEntry(rkIndex) == nullptr;
|
bool IsDir = GetIndexEntry(rkIndex) == nullptr;
|
||||||
|
|
||||||
// Get rect
|
// Get rect
|
||||||
SResDelegateFontInfo FontInfo = GetFontInfo(rkOption);
|
SDelegateFontInfo FontInfo = GetFontInfo(rkOption);
|
||||||
SResDelegateGeometryInfo GeomInfo = GetGeometryInfo(FontInfo, rkOption, IsDir);
|
SResDelegateGeometryInfo GeomInfo = GetGeometryInfo(FontInfo, rkOption, IsDir);
|
||||||
|
|
||||||
// Set geometry; make it a little bit better than the name string rect to give the user more space
|
// Set geometry; make it a little bit better than the name string rect to give the user more space
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
#ifndef CRESOURCEBROWSERDELEGATE_H
|
#ifndef CRESOURCEBROWSERDELEGATE_H
|
||||||
#define CRESOURCEBROWSERDELEGATE_H
|
#define CRESOURCEBROWSERDELEGATE_H
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include "Editor/CCustomDelegate.h"
|
||||||
|
|
||||||
|
class CResourceBrowserDelegate : public CCustomDelegate
|
||||||
class CResourceBrowserDelegate : public QStyledItemDelegate
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const int skIconSize = 32;
|
static const int skIconSize = 32;
|
||||||
|
@ -14,7 +13,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CResourceBrowserDelegate(QObject *pParent = 0)
|
CResourceBrowserDelegate(QObject *pParent = 0)
|
||||||
: QStyledItemDelegate(pParent)
|
: CCustomDelegate(pParent)
|
||||||
, mDisplayAssetIDs(false)
|
, mDisplayAssetIDs(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include "CStringDelegate.h"
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
/** Constants */
|
||||||
|
static constexpr int gkMargin = 3;
|
||||||
|
static constexpr int gkSpacing = 3;
|
||||||
|
|
||||||
|
CStringDelegate::CStringDelegate(QObject* pParent /*= 0*/)
|
||||||
|
: CCustomDelegate(pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
SDelegateFontInfo CStringDelegate::GetFontInfo(const QStyleOptionViewItem& rkOption) const
|
||||||
|
{
|
||||||
|
SDelegateFontInfo Info = CCustomDelegate::GetFontInfo(rkOption);
|
||||||
|
Info.NameFont.setPointSize( rkOption.font.pointSize() );
|
||||||
|
Info.NameFontMetrics = QFontMetrics(Info.NameFont);
|
||||||
|
Info.NamePen.setColor( Info.NamePen.color().darker(120.f) );
|
||||||
|
Info.InfoFont.setPointSize( rkOption.font.pointSize() );
|
||||||
|
Info.InfoFont.setItalic(true);
|
||||||
|
Info.InfoFontMetrics = QFontMetrics(Info.InfoFont);
|
||||||
|
Info.InfoPen = QPen(rkOption.palette.text(), 1.f);
|
||||||
|
return Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize CStringDelegate::sizeHint(const QStyleOptionViewItem& kOption, const QModelIndex& kIndex) const
|
||||||
|
{
|
||||||
|
QSize BaseSize = CCustomDelegate::sizeHint(kOption, kIndex);
|
||||||
|
|
||||||
|
SDelegateFontInfo FontInfo = GetFontInfo(kOption);
|
||||||
|
int Height = (gkMargin * 2) + gkSpacing + (FontInfo.NameFontMetrics.height() * 2);
|
||||||
|
return QSize(BaseSize.rwidth(), Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringDelegate::paint(QPainter* pPainter, const QStyleOptionViewItem& kOption, const QModelIndex& kIndex) const
|
||||||
|
{
|
||||||
|
SDelegateFontInfo FontInfo = GetFontInfo(kOption);
|
||||||
|
QString StringName = kIndex.model()->data(kIndex, Qt::DisplayRole).toString();
|
||||||
|
QString StringText = kIndex.model()->data(kIndex, Qt::UserRole).toString();
|
||||||
|
|
||||||
|
// Calculate rects
|
||||||
|
int X = kOption.rect.left() + gkMargin;
|
||||||
|
int Width = kOption.rect.width() - (gkMargin * 2);
|
||||||
|
int NameHeight = FontInfo.NameFontMetrics.height();
|
||||||
|
int TextHeight = FontInfo.InfoFontMetrics.height();
|
||||||
|
int NameY = kOption.rect.top() + gkMargin;
|
||||||
|
int TextY = NameY + NameHeight + gkSpacing;
|
||||||
|
QRect NameRect(X, NameY, Width, NameHeight);
|
||||||
|
QRect TextRect(X, TextY, Width, TextHeight);
|
||||||
|
|
||||||
|
// Elide name/text
|
||||||
|
StringName = FontInfo.NameFontMetrics.elidedText(StringName, Qt::ElideRight, Width);
|
||||||
|
StringText = FontInfo.InfoFontMetrics.elidedText(StringText, Qt::ElideRight, Width);
|
||||||
|
|
||||||
|
// Draw selection rect
|
||||||
|
if (kOption.state & QStyle::State_Selected)
|
||||||
|
{
|
||||||
|
pPainter->fillRect( kOption.rect, kOption.palette.highlight() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw string info
|
||||||
|
pPainter->setFont(FontInfo.NameFont);
|
||||||
|
pPainter->setPen(FontInfo.NamePen);
|
||||||
|
pPainter->drawText(NameRect, Qt::AlignLeft, StringName);
|
||||||
|
|
||||||
|
pPainter->setFont(FontInfo.InfoFont);
|
||||||
|
pPainter->setPen(FontInfo.InfoPen);
|
||||||
|
pPainter->drawText(TextRect, Qt::AlignLeft, StringText);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef CSTRINGDELEGATE_H
|
||||||
|
#define CSTRINGDELEGATE_H
|
||||||
|
|
||||||
|
#include "Editor/CCustomDelegate.h"
|
||||||
|
|
||||||
|
/** Delegate for rendering string entries in the string editor list view */
|
||||||
|
class CStringDelegate : public CCustomDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CStringDelegate(QObject* pParent = 0);
|
||||||
|
|
||||||
|
SDelegateFontInfo GetFontInfo(const QStyleOptionViewItem& rkOption) const;
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem& kOption, const QModelIndex& kIndex) const;
|
||||||
|
void paint(QPainter* pPainter, const QStyleOptionViewItem& kOption, const QModelIndex& kIndex) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSTRINGDELEGATE_H
|
|
@ -0,0 +1,132 @@
|
||||||
|
#include "CStringEditor.h"
|
||||||
|
#include "ui_CStringEditor.h"
|
||||||
|
|
||||||
|
#include "CStringDelegate.h"
|
||||||
|
#include "Editor/UICommon.h"
|
||||||
|
#include "Editor/Widgets/CSizeableTabBar.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
/** Settings strings */
|
||||||
|
const char* gkpLanguageSetting = "StringEditor/EditLanguage";
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
CStringEditor::CStringEditor(CStringTable* pStringTable, QWidget* pParent)
|
||||||
|
: IEditor(pParent)
|
||||||
|
, mpUI(new Ui::CStringEditor)
|
||||||
|
, mpStringTable(pStringTable)
|
||||||
|
, mCurrentLanguage(ELanguage::English)
|
||||||
|
, mCurrentStringIndex(0)
|
||||||
|
{
|
||||||
|
mpListModel = new CStringListModel(pStringTable, this);
|
||||||
|
mpUI->setupUi(this);
|
||||||
|
|
||||||
|
InitUI();
|
||||||
|
LoadSettings();
|
||||||
|
UpdateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
CStringEditor::~CStringEditor()
|
||||||
|
{
|
||||||
|
delete mpUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringEditor::InitUI()
|
||||||
|
{
|
||||||
|
mpUI->StringNameListView->setModel(mpListModel);
|
||||||
|
mpUI->StringNameListView->setItemDelegate( new CStringDelegate(this) );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Set up language combo box
|
||||||
|
for (uint LanguageIdx = 0; LanguageIdx < mpStringTable->NumLanguages(); LanguageIdx++)
|
||||||
|
{
|
||||||
|
ELanguage Language = mpStringTable->LanguageByIndex(LanguageIdx);
|
||||||
|
const char* pkLanguageName = TEnumReflection<ELanguage>::ConvertValueToString(Language);
|
||||||
|
mpUI->LanguageComboBox->addItem(pkLanguageName);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
QTabBar* pTabBar = new QTabBar(this);
|
||||||
|
pTabBar->setExpanding(false);
|
||||||
|
|
||||||
|
// Set up language combo box
|
||||||
|
for (uint LanguageIdx = 0; LanguageIdx < mpStringTable->NumLanguages(); LanguageIdx++)
|
||||||
|
{
|
||||||
|
ELanguage Language = mpStringTable->LanguageByIndex(LanguageIdx);
|
||||||
|
const char* pkLanguageName = TEnumReflection<ELanguage>::ConvertValueToString(Language);
|
||||||
|
pTabBar->addTab(pkLanguageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVBoxLayout* pTabLayout = new QVBoxLayout(mpUI->TabsContainerWidget);
|
||||||
|
pTabLayout->setContentsMargins(0,0,0,0);
|
||||||
|
pTabLayout->addWidget(pTabBar);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Connect signals & slots
|
||||||
|
connect( mpUI->StringNameListView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||||
|
this, SLOT(OnStringSelected(QModelIndex)) );
|
||||||
|
|
||||||
|
// connect( mpUI->LanguageComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnLanguageChanged(int)) );
|
||||||
|
connect( pTabBar, SIGNAL(currentChanged(int)), this, SLOT(OnLanguageChanged(int)) );
|
||||||
|
|
||||||
|
// Update window title
|
||||||
|
QString WindowTitle = "%APP_FULL_NAME% - String Editor - %1[*]";
|
||||||
|
WindowTitle = WindowTitle.arg( TO_QSTRING(mpStringTable->Entry()->CookedAssetPath(true).GetFileName()) );
|
||||||
|
SET_WINDOWTITLE_APPVARS(WindowTitle);
|
||||||
|
|
||||||
|
// Update status bar
|
||||||
|
QString StatusText = QString("%1 languages, %2 strings")
|
||||||
|
.arg(mpStringTable->NumLanguages())
|
||||||
|
.arg(mpStringTable->NumStrings());
|
||||||
|
|
||||||
|
mpUI->StatusBar->setStatusTip(StatusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringEditor::UpdateUI()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringEditor::SetActiveLanguage(ELanguage Language)
|
||||||
|
{
|
||||||
|
if (mCurrentLanguage != Language)
|
||||||
|
{
|
||||||
|
mCurrentLanguage = Language;
|
||||||
|
|
||||||
|
// Force UI to update with the correct string for the new language
|
||||||
|
SetActiveString( mCurrentStringIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringEditor::SetActiveString(int StringIndex)
|
||||||
|
{
|
||||||
|
mCurrentStringIndex = StringIndex;
|
||||||
|
TString StringName = mpStringTable->StringNameByIndex(mCurrentStringIndex);
|
||||||
|
TString StringData = mpStringTable->GetString(mCurrentLanguage, mCurrentStringIndex);
|
||||||
|
mpUI->StringNameLineEdit->setText( TO_QSTRING(StringName) );
|
||||||
|
mpUI->StringTextEdit->setPlainText( TO_QSTRING(StringData) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringEditor::LoadSettings()
|
||||||
|
{
|
||||||
|
QSettings Settings;
|
||||||
|
mCurrentLanguage = (ELanguage) Settings.value(gkpLanguageSetting, (int) ELanguage::English).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringEditor::SaveSettings()
|
||||||
|
{
|
||||||
|
QSettings Settings;
|
||||||
|
Settings.setValue(gkpLanguageSetting, (int) mCurrentLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Slots */
|
||||||
|
void CStringEditor::OnStringSelected(const QModelIndex& kIndex)
|
||||||
|
{
|
||||||
|
SetActiveString( kIndex.row() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringEditor::OnLanguageChanged(int LanguageIndex)
|
||||||
|
{
|
||||||
|
ASSERT( LanguageIndex >= 0 && LanguageIndex < (int) mpStringTable->NumLanguages() );
|
||||||
|
ELanguage Language = mpStringTable->LanguageByIndex(LanguageIndex);
|
||||||
|
SetActiveLanguage(Language);
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef CSTRINGEDITOR_H
|
||||||
|
#define CSTRINGEDITOR_H
|
||||||
|
|
||||||
|
#include "IEditor.h"
|
||||||
|
|
||||||
|
#include "CStringListModel.h"
|
||||||
|
#include <Core/Resource/StringTable/CStringTable.h>
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CStringEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Editor window for string tables (STRG assets) */
|
||||||
|
class CStringEditor : public IEditor
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/** Qt UI */
|
||||||
|
Ui::CStringEditor* mpUI;
|
||||||
|
|
||||||
|
/** String table asset being edited */
|
||||||
|
TResPtr<CStringTable> mpStringTable;
|
||||||
|
|
||||||
|
/** Language being edited */
|
||||||
|
ELanguage mCurrentLanguage;
|
||||||
|
|
||||||
|
/** Index of the string being edited */
|
||||||
|
uint mCurrentStringIndex;
|
||||||
|
|
||||||
|
/** Model for the string list view */
|
||||||
|
CStringListModel* mpListModel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CStringEditor(CStringTable* pStringTable, QWidget* pParent = 0);
|
||||||
|
~CStringEditor();
|
||||||
|
void InitUI();
|
||||||
|
void UpdateUI();
|
||||||
|
void SetActiveLanguage(ELanguage Language);
|
||||||
|
void SetActiveString(int StringIndex);
|
||||||
|
|
||||||
|
void LoadSettings();
|
||||||
|
void SaveSettings();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void OnStringSelected(const QModelIndex& kIndex);
|
||||||
|
void OnLanguageChanged(int LanguageIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSTRINGEDITOR_H
|
|
@ -0,0 +1,209 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CStringEditor</class>
|
||||||
|
<widget class="QMainWindow" name="CStringEditor">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>609</width>
|
||||||
|
<height>444</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0">
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QGroupBox" name="StringsGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Strings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="StringNameListView">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="NameLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="StringNameLineEdit">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="AddStringButton">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../Icons.qrc">
|
||||||
|
<normaloff>:/icons/Plus.png</normaloff>:/icons/Plus.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="AddStringButton_2">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../Icons.qrc">
|
||||||
|
<normaloff>:/icons/Minus v2.png</normaloff>:/icons/Minus v2.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="EditGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="TabsContainerWidget" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="StringTextEdit">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="ToolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="ActionSave"/>
|
||||||
|
<addaction name="ActionSaveAndCook"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="StatusBar"/>
|
||||||
|
<action name="ActionSave">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../Icons.qrc">
|
||||||
|
<normaloff>:/icons/Save.png</normaloff>:/icons/Save.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+S</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="ActionSaveAndCook">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../Icons.qrc">
|
||||||
|
<normaloff>:/icons/SaveAndRepack_32px.png</normaloff>:/icons/SaveAndRepack_32px.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save and Cook</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save and Cook</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../Icons.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "CStringListModel.h"
|
||||||
|
#include "Editor/UICommon.h"
|
||||||
|
|
||||||
|
CStringListModel::CStringListModel(CStringTable* pInStrings, QObject* pParent /*= 0*/)
|
||||||
|
: QAbstractListModel(pParent)
|
||||||
|
, mpStringTable(pInStrings)
|
||||||
|
, mStringPreviewLanguage(ELanguage::English)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Change the preview language display */
|
||||||
|
void CStringListModel::SetPreviewLanguage(ELanguage InLanguage)
|
||||||
|
{
|
||||||
|
if (mStringPreviewLanguage != InLanguage)
|
||||||
|
{
|
||||||
|
mStringPreviewLanguage = InLanguage;
|
||||||
|
|
||||||
|
// Emit data changed for user role for the full range of strings
|
||||||
|
int NumStrings = mpStringTable ? mpStringTable->NumStrings() : 0;
|
||||||
|
|
||||||
|
if (NumStrings)
|
||||||
|
{
|
||||||
|
QVector<int> Roles;
|
||||||
|
Roles << Qt::UserRole;
|
||||||
|
emit dataChanged( index(0), index(NumStrings-1), Roles );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** QAbstractListModel interface */
|
||||||
|
int CStringListModel::rowCount(const QModelIndex& kParent) const
|
||||||
|
{
|
||||||
|
return mpStringTable ? mpStringTable->NumStrings() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant CStringListModel::data(const QModelIndex& kIndex, int Role) const
|
||||||
|
{
|
||||||
|
if (!kIndex.isValid() || !mpStringTable)
|
||||||
|
{
|
||||||
|
return QVariant::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringIndex = kIndex.row();
|
||||||
|
|
||||||
|
// display/tooltip role: return the string name
|
||||||
|
if (Role == Qt::DisplayRole || Role == Qt::ToolTipRole)
|
||||||
|
{
|
||||||
|
TString StringName = mpStringTable->StringNameByIndex(StringIndex);
|
||||||
|
|
||||||
|
if (StringName.IsEmpty())
|
||||||
|
{
|
||||||
|
StringName = TString::Format("<String #%d>", kIndex.row()+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TO_QSTRING(StringName);
|
||||||
|
}
|
||||||
|
// user role: used for string preview, return the string contents
|
||||||
|
else if (Role == Qt::UserRole)
|
||||||
|
{
|
||||||
|
TString StringData = mpStringTable->GetString(mStringPreviewLanguage, StringIndex);
|
||||||
|
StringData.Replace("\n", " ");
|
||||||
|
return TO_QSTRING(StringData);
|
||||||
|
}
|
||||||
|
// other roles: invalid
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QVariant::Invalid;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef CSTRINGLISTMODEL_H
|
||||||
|
#define CSTRINGLISTMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <Core/Resource/TResPtr.h>
|
||||||
|
#include <Core/Resource/StringTable/CStringTable.h>
|
||||||
|
|
||||||
|
/** Model for listing available strings in a string table */
|
||||||
|
class CStringListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
/** Asset to pull the strings from */
|
||||||
|
TResPtr<CStringTable> mpStringTable;
|
||||||
|
|
||||||
|
/** Language to use for the string preview for modes that support it */
|
||||||
|
ELanguage mStringPreviewLanguage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CStringListModel(CStringTable* pInStrings, QObject* pParent = 0);
|
||||||
|
|
||||||
|
/** Change the preview language display */
|
||||||
|
void SetPreviewLanguage(ELanguage InLanguage);
|
||||||
|
|
||||||
|
/** QAbstractListModel interface */
|
||||||
|
virtual int rowCount(const QModelIndex& kParent) const override;
|
||||||
|
virtual QVariant data(const QModelIndex& kIndex, int Role) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSTRINGLISTMODEL_H
|
|
@ -174,13 +174,13 @@ void CLinkDialog::accept()
|
||||||
if (!mpEditLink)
|
if (!mpEditLink)
|
||||||
{
|
{
|
||||||
CAddLinkCommand *pCmd = new CAddLinkCommand(mpEditor, Link);
|
CAddLinkCommand *pCmd = new CAddLinkCommand(mpEditor, Link);
|
||||||
mpEditor->UndoStack()->push(pCmd);
|
mpEditor->UndoStack().push(pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Link != *mpEditLink)
|
else if (Link != *mpEditLink)
|
||||||
{
|
{
|
||||||
CEditLinkCommand *pCmd = new CEditLinkCommand(mpEditor, mpEditLink, Link);
|
CEditLinkCommand *pCmd = new CEditLinkCommand(mpEditor, mpEditLink, Link);
|
||||||
mpEditor->UndoStack()->push(pCmd);
|
mpEditor->UndoStack().push(pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
|
|
|
@ -75,7 +75,7 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
||||||
mpTransformCombo->setMinimumWidth(75);
|
mpTransformCombo->setMinimumWidth(75);
|
||||||
ui->MainToolBar->addActions(mGizmoActions);
|
ui->MainToolBar->addActions(mGizmoActions);
|
||||||
ui->MainToolBar->addWidget(mpTransformCombo);
|
ui->MainToolBar->addWidget(mpTransformCombo);
|
||||||
ui->menuEdit->insertActions(ui->ActionCut, mUndoActions);
|
AddUndoActions(ui->menuEdit, ui->ActionCut);
|
||||||
ui->menuEdit->insertSeparator(ui->ActionCut);
|
ui->menuEdit->insertSeparator(ui->ActionCut);
|
||||||
|
|
||||||
// Initialize sidebar
|
// Initialize sidebar
|
||||||
|
@ -103,13 +103,7 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
||||||
addAction(ui->ActionIncrementGizmo);
|
addAction(ui->ActionIncrementGizmo);
|
||||||
addAction(ui->ActionDecrementGizmo);
|
addAction(ui->ActionDecrementGizmo);
|
||||||
|
|
||||||
QAction *pToolBarUndo = mUndoStack.createUndoAction(this);
|
AddUndoActions(ui->MainToolBar, ui->ActionLink);
|
||||||
pToolBarUndo->setIcon(QIcon(":/icons/Undo.png"));
|
|
||||||
ui->MainToolBar->insertAction(ui->ActionLink, pToolBarUndo);
|
|
||||||
|
|
||||||
QAction *pToolBarRedo = mUndoStack.createRedoAction(this);
|
|
||||||
pToolBarRedo->setIcon(QIcon(":/icons/Redo.png"));
|
|
||||||
ui->MainToolBar->insertAction(ui->ActionLink, pToolBarRedo);
|
|
||||||
ui->MainToolBar->insertSeparator(ui->ActionLink);
|
ui->MainToolBar->insertSeparator(ui->ActionLink);
|
||||||
|
|
||||||
ui->ActionCut->setAutoRepeat(false);
|
ui->ActionCut->setAutoRepeat(false);
|
||||||
|
@ -157,7 +151,7 @@ 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(&mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
connect(&UndoStack(), SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
||||||
|
|
||||||
connect(ui->ActionOpenProject, SIGNAL(triggered()), this, SLOT(OpenProject()));
|
connect(ui->ActionOpenProject, SIGNAL(triggered()), this, SLOT(OpenProject()));
|
||||||
connect(ui->ActionSave, SIGNAL(triggered()) , this, SLOT(Save()));
|
connect(ui->ActionSave, SIGNAL(triggered()) , this, SLOT(Save()));
|
||||||
|
@ -207,22 +201,11 @@ CWorldEditor::~CWorldEditor()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::closeEvent(QCloseEvent *pEvent)
|
/*void CWorldEditor::closeEvent(QCloseEvent *pEvent)
|
||||||
{
|
{
|
||||||
bool ShouldClose = CheckUnsavedChanges();
|
mpCollisionDialog->close();
|
||||||
|
mpLinkDialog->close();
|
||||||
if (ShouldClose)
|
}*/
|
||||||
{
|
|
||||||
mUndoStack.clear();
|
|
||||||
mpCollisionDialog->close();
|
|
||||||
mpLinkDialog->close();
|
|
||||||
IEditor::closeEvent(pEvent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pEvent->ignore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CWorldEditor::CloseWorld()
|
bool CWorldEditor::CloseWorld()
|
||||||
{
|
{
|
||||||
|
@ -233,7 +216,7 @@ bool CWorldEditor::CloseWorld()
|
||||||
ui->MainViewport->ResetHover();
|
ui->MainViewport->ResetHover();
|
||||||
mScene.ClearScene();
|
mScene.ClearScene();
|
||||||
|
|
||||||
mUndoStack.clear();
|
UndoStack().clear();
|
||||||
mpCollisionDialog->close();
|
mpCollisionDialog->close();
|
||||||
mpLinkDialog->close();
|
mpLinkDialog->close();
|
||||||
|
|
||||||
|
@ -258,7 +241,7 @@ bool CWorldEditor::SetArea(CWorld *pWorld, int AreaIndex)
|
||||||
ExitPickMode();
|
ExitPickMode();
|
||||||
ui->MainViewport->ResetHover();
|
ui->MainViewport->ResetHover();
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
mUndoStack.clear();
|
UndoStack().clear();
|
||||||
|
|
||||||
// Load new area
|
// Load new area
|
||||||
mpWorld = pWorld;
|
mpWorld = pWorld;
|
||||||
|
@ -310,28 +293,6 @@ bool CWorldEditor::SetArea(CWorld *pWorld, int AreaIndex)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWorldEditor::CheckUnsavedChanges()
|
|
||||||
{
|
|
||||||
// Check whether the user has unsaved changes, return whether it's okay to clear the scene
|
|
||||||
bool OkToClear = !isWindowModified();
|
|
||||||
|
|
||||||
if (!OkToClear)
|
|
||||||
{
|
|
||||||
int Result = QMessageBox::warning(this, "Save", "You have unsaved changes. Save?", QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel);
|
|
||||||
|
|
||||||
if (Result == QMessageBox::Yes)
|
|
||||||
OkToClear = Save();
|
|
||||||
|
|
||||||
else if (Result == QMessageBox::No)
|
|
||||||
OkToClear = true;
|
|
||||||
|
|
||||||
else if (Result == QMessageBox::Cancel)
|
|
||||||
OkToClear = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return OkToClear;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWorldEditor::ResetCamera()
|
void CWorldEditor::ResetCamera()
|
||||||
{
|
{
|
||||||
ui->MainViewport->Camera().Snap(CVector3f(0.f, 5.f, 1.f));
|
ui->MainViewport->Camera().Snap(CVector3f(0.f, 5.f, 1.f));
|
||||||
|
@ -368,12 +329,40 @@ void CWorldEditor::NotifyNodeAboutToBeDeleted(CSceneNode *pNode)
|
||||||
ui->MainViewport->ResetHover();
|
ui->MainViewport->ResetHover();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CWorldEditor::Save()
|
||||||
|
{
|
||||||
|
if (!mpArea)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool SaveAreaSuccess = mpArea->Entry()->Save();
|
||||||
|
bool SaveEGMCSuccess = mpArea->PoiToWorldMap() ? mpArea->PoiToWorldMap()->Entry()->Save() : true;
|
||||||
|
bool SaveWorldSuccess = mpWorld->Entry()->Save();
|
||||||
|
|
||||||
|
if (SaveAreaSuccess)
|
||||||
|
mpArea->ClearExtraDependencies();
|
||||||
|
|
||||||
|
if (SaveAreaSuccess || SaveEGMCSuccess || SaveWorldSuccess)
|
||||||
|
gpEdApp->NotifyAssetsModified();
|
||||||
|
|
||||||
|
if (SaveAreaSuccess && SaveEGMCSuccess && SaveWorldSuccess)
|
||||||
|
{
|
||||||
|
UndoStack().setClean();
|
||||||
|
setWindowModified(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UICommon::ErrorMsg(this, "Area failed to save!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CWorldEditor::Cut()
|
void CWorldEditor::Cut()
|
||||||
{
|
{
|
||||||
if (!mpSelection->IsEmpty())
|
if (!mpSelection->IsEmpty())
|
||||||
{
|
{
|
||||||
Copy();
|
Copy();
|
||||||
mUndoStack.push(new CDeleteSelectionCommand(this, "Cut"));
|
UndoStack().push(new CDeleteSelectionCommand(this, "Cut"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +399,7 @@ void CWorldEditor::Paste()
|
||||||
}
|
}
|
||||||
|
|
||||||
CPasteNodesCommand *pCmd = new CPasteNodesCommand(this, mpScriptSidebar->CreateTab()->SpawnLayer(), PastePoint);
|
CPasteNodesCommand *pCmd = new CPasteNodesCommand(this, mpScriptSidebar->CreateTab()->SpawnLayer(), PastePoint);
|
||||||
mUndoStack.push(pCmd);
|
UndoStack().push(pCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -436,41 +425,6 @@ void CWorldEditor::OpenRecentProject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWorldEditor::Save()
|
|
||||||
{
|
|
||||||
if (!mpArea)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
bool SaveAreaSuccess = mpArea->Entry()->Save();
|
|
||||||
bool SaveEGMCSuccess = mpArea->PoiToWorldMap() ? mpArea->PoiToWorldMap()->Entry()->Save() : true;
|
|
||||||
bool SaveWorldSuccess = mpWorld->Entry()->Save();
|
|
||||||
|
|
||||||
if (SaveAreaSuccess)
|
|
||||||
mpArea->ClearExtraDependencies();
|
|
||||||
|
|
||||||
if (SaveAreaSuccess || SaveEGMCSuccess || SaveWorldSuccess)
|
|
||||||
gpEdApp->NotifyAssetsModified();
|
|
||||||
|
|
||||||
if (SaveAreaSuccess && SaveEGMCSuccess && SaveWorldSuccess)
|
|
||||||
{
|
|
||||||
mUndoStack.setClean();
|
|
||||||
setWindowModified(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UICommon::ErrorMsg(this, "Area failed to save!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CWorldEditor::SaveAndRepack()
|
|
||||||
{
|
|
||||||
if (!Save()) return false;
|
|
||||||
gpEdApp->CookAllDirtyPackages();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWorldEditor::ExportGame()
|
void CWorldEditor::ExportGame()
|
||||||
{
|
{
|
||||||
QString IsoPath = UICommon::OpenFileDialog(this, "Select ISO", "*.iso *.gcm *.tgc *.wbfs");
|
QString IsoPath = UICommon::OpenFileDialog(this, "Select ISO", "*.iso *.gcm *.tgc *.wbfs");
|
||||||
|
@ -634,7 +588,7 @@ void CWorldEditor::SetSelectionActive(bool Active)
|
||||||
|
|
||||||
if (!Objects.isEmpty())
|
if (!Objects.isEmpty())
|
||||||
{
|
{
|
||||||
mUndoStack.beginMacro("Toggle Active");
|
UndoStack().beginMacro("Toggle Active");
|
||||||
|
|
||||||
while (!Objects.isEmpty())
|
while (!Objects.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -667,11 +621,11 @@ void CWorldEditor::SetSelectionActive(bool Active)
|
||||||
|
|
||||||
pCommand->SaveNewData();
|
pCommand->SaveNewData();
|
||||||
|
|
||||||
mUndoStack.push(pCommand);
|
UndoStack().push(pCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mUndoStack.endMacro();
|
UndoStack().endMacro();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,7 +643,7 @@ void CWorldEditor::SetSelectionInstanceNames(const QString& rkNewName, bool IsDo
|
||||||
TString NewName = TO_TSTRING(rkNewName);
|
TString NewName = TO_TSTRING(rkNewName);
|
||||||
IPropertyValue *pOld = pName->RawValue()->Clone();
|
IPropertyValue *pOld = pName->RawValue()->Clone();
|
||||||
pInst->SetName(NewName);
|
pInst->SetName(NewName);
|
||||||
mUndoStack.push(new CEditScriptPropertyCommand(pName, this, pOld, IsDone, "Edit Instance Name"));
|
UndoStack().push(new CEditScriptPropertyCommand(pName, this, pOld, IsDone, "Edit Instance Name"));
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -705,7 +659,7 @@ void CWorldEditor::SetSelectionLayer(CScriptLayer *pLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ScriptNodes.isEmpty())
|
if (!ScriptNodes.isEmpty())
|
||||||
mUndoStack.push(new CChangeLayerCommand(this, ScriptNodes, pLayer));
|
UndoStack().push(new CChangeLayerCommand(this, ScriptNodes, pLayer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::DeleteSelection()
|
void CWorldEditor::DeleteSelection()
|
||||||
|
@ -713,7 +667,7 @@ void CWorldEditor::DeleteSelection()
|
||||||
if (HasAnyScriptNodesSelected())
|
if (HasAnyScriptNodesSelected())
|
||||||
{
|
{
|
||||||
CDeleteSelectionCommand *pCmd = new CDeleteSelectionCommand(this);
|
CDeleteSelectionCommand *pCmd = new CDeleteSelectionCommand(this);
|
||||||
mUndoStack.push(pCmd);
|
UndoStack().push(pCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1031,7 @@ void CWorldEditor::OnUnlinkClicked()
|
||||||
|
|
||||||
if (Dialog.UserChoice() != CConfirmUnlinkDialog::EChoice::Cancel)
|
if (Dialog.UserChoice() != CConfirmUnlinkDialog::EChoice::Cancel)
|
||||||
{
|
{
|
||||||
mUndoStack.beginMacro("Unlink");
|
UndoStack().beginMacro("Unlink");
|
||||||
bool UnlinkIncoming = (Dialog.UserChoice() != CConfirmUnlinkDialog::EChoice::OutgoingOnly);
|
bool UnlinkIncoming = (Dialog.UserChoice() != CConfirmUnlinkDialog::EChoice::OutgoingOnly);
|
||||||
bool UnlinkOutgoing = (Dialog.UserChoice() != CConfirmUnlinkDialog::EChoice::IncomingOnly);
|
bool UnlinkOutgoing = (Dialog.UserChoice() != CConfirmUnlinkDialog::EChoice::IncomingOnly);
|
||||||
|
|
||||||
|
@ -1092,7 +1046,7 @@ void CWorldEditor::OnUnlinkClicked()
|
||||||
LinkIndices << iLink;
|
LinkIndices << iLink;
|
||||||
|
|
||||||
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(this, pInst, ELinkType::Incoming, LinkIndices);
|
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(this, pInst, ELinkType::Incoming, LinkIndices);
|
||||||
mUndoStack.push(pCmd);
|
UndoStack().push(pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UnlinkOutgoing)
|
if (UnlinkOutgoing)
|
||||||
|
@ -1102,11 +1056,11 @@ void CWorldEditor::OnUnlinkClicked()
|
||||||
LinkIndices << iLink;
|
LinkIndices << iLink;
|
||||||
|
|
||||||
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(this, pInst, ELinkType::Outgoing, LinkIndices);
|
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(this, pInst, ELinkType::Outgoing, LinkIndices);
|
||||||
mUndoStack.push(pCmd);
|
UndoStack().push(pCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mUndoStack.endMacro();
|
UndoStack().endMacro();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1115,13 +1069,13 @@ 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.
|
||||||
// This is to prevent commands like select/deselect from altering the clean state.
|
// This is to prevent commands like select/deselect from altering the clean state.
|
||||||
int CurrentIndex = mUndoStack.index();
|
int CurrentIndex = UndoStack().index();
|
||||||
int CleanIndex = mUndoStack.cleanIndex();
|
int CleanIndex = UndoStack().cleanIndex();
|
||||||
|
|
||||||
if (CleanIndex == -1)
|
if (CleanIndex == -1)
|
||||||
{
|
{
|
||||||
if (!isWindowModified())
|
if (!isWindowModified())
|
||||||
mUndoStack.setClean();
|
UndoStack().setClean();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1137,7 +1091,7 @@ void CWorldEditor::OnUndoStackIndexChanged()
|
||||||
|
|
||||||
for (int iIdx = LowIndex; iIdx <= HighIndex; iIdx++)
|
for (int iIdx = LowIndex; iIdx <= HighIndex; iIdx++)
|
||||||
{
|
{
|
||||||
const QUndoCommand *pkQCmd = mUndoStack.command(iIdx);
|
const QUndoCommand *pkQCmd = UndoStack().command(iIdx);
|
||||||
|
|
||||||
if (const IUndoCommand *pkCmd = dynamic_cast<const IUndoCommand*>(pkQCmd))
|
if (const IUndoCommand *pkCmd = dynamic_cast<const IUndoCommand*>(pkQCmd))
|
||||||
{
|
{
|
||||||
|
@ -1208,21 +1162,21 @@ void CWorldEditor::OnTransformSpinBoxModified(CVector3f Value)
|
||||||
case CGizmo::EGizmoMode::Translate:
|
case CGizmo::EGizmoMode::Translate:
|
||||||
{
|
{
|
||||||
CVector3f Delta = Value - mpSelection->Front()->AbsolutePosition();
|
CVector3f Delta = Value - mpSelection->Front()->AbsolutePosition();
|
||||||
mUndoStack.push(new CTranslateNodeCommand(this, mpSelection->SelectedNodeList(), Delta, mTranslateSpace));
|
UndoStack().push(new CTranslateNodeCommand(this, mpSelection->SelectedNodeList(), Delta, mTranslateSpace));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CGizmo::EGizmoMode::Rotate:
|
case CGizmo::EGizmoMode::Rotate:
|
||||||
{
|
{
|
||||||
CQuaternion Delta = CQuaternion::FromEuler(Value) * mpSelection->Front()->AbsoluteRotation().Inverse();
|
CQuaternion Delta = CQuaternion::FromEuler(Value) * mpSelection->Front()->AbsoluteRotation().Inverse();
|
||||||
mUndoStack.push(new CRotateNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), mGizmo.Rotation(), Delta, mRotateSpace));
|
UndoStack().push(new CRotateNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), mGizmo.Rotation(), Delta, mRotateSpace));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CGizmo::EGizmoMode::Scale:
|
case CGizmo::EGizmoMode::Scale:
|
||||||
{
|
{
|
||||||
CVector3f Delta = Value / mpSelection->Front()->AbsoluteScale();
|
CVector3f Delta = Value / mpSelection->Front()->AbsoluteScale();
|
||||||
mUndoStack.push(new CScaleNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), Delta));
|
UndoStack().push(new CScaleNodeCommand(this, mpSelection->SelectedNodeList(), true, mGizmo.Position(), Delta));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1234,9 +1188,9 @@ void CWorldEditor::OnTransformSpinBoxEdited(CVector3f)
|
||||||
{
|
{
|
||||||
if (mpSelection->IsEmpty()) return;
|
if (mpSelection->IsEmpty()) return;
|
||||||
|
|
||||||
if (mGizmo.Mode() == CGizmo::EGizmoMode::Translate) mUndoStack.push(CTranslateNodeCommand::End());
|
if (mGizmo.Mode() == CGizmo::EGizmoMode::Translate) UndoStack().push(CTranslateNodeCommand::End());
|
||||||
else if (mGizmo.Mode() == CGizmo::EGizmoMode::Rotate) mUndoStack.push(CRotateNodeCommand::End());
|
else if (mGizmo.Mode() == CGizmo::EGizmoMode::Rotate) UndoStack().push(CRotateNodeCommand::End());
|
||||||
else if (mGizmo.Mode() == CGizmo::EGizmoMode::Scale) mUndoStack.push(CScaleNodeCommand::End());
|
else if (mGizmo.Mode() == CGizmo::EGizmoMode::Scale) UndoStack().push(CScaleNodeCommand::End());
|
||||||
|
|
||||||
UpdateGizmoUI();
|
UpdateGizmoUI();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,6 @@ class CWorldEditor : public INodeEditor
|
||||||
CScriptObject *mpNewLinkSender;
|
CScriptObject *mpNewLinkSender;
|
||||||
CScriptObject *mpNewLinkReceiver;
|
CScriptObject *mpNewLinkReceiver;
|
||||||
|
|
||||||
QString mWorldDir;
|
|
||||||
QString mPakFileList;
|
|
||||||
QString mPakTarget;
|
|
||||||
|
|
||||||
// Sidebars
|
// Sidebars
|
||||||
QVBoxLayout *mpRightSidebarLayout;
|
QVBoxLayout *mpRightSidebarLayout;
|
||||||
CWorldEditorSidebar *mpCurSidebar;
|
CWorldEditorSidebar *mpCurSidebar;
|
||||||
|
@ -80,10 +76,8 @@ class CWorldEditor : public INodeEditor
|
||||||
public:
|
public:
|
||||||
explicit CWorldEditor(QWidget *parent = 0);
|
explicit CWorldEditor(QWidget *parent = 0);
|
||||||
~CWorldEditor();
|
~CWorldEditor();
|
||||||
void closeEvent(QCloseEvent *pEvent);
|
|
||||||
bool CloseWorld();
|
bool CloseWorld();
|
||||||
bool SetArea(CWorld *pWorld, int AreaIndex);
|
bool SetArea(CWorld *pWorld, int AreaIndex);
|
||||||
bool CheckUnsavedChanges();
|
|
||||||
void ResetCamera();
|
void ResetCamera();
|
||||||
bool HasAnyScriptNodesSelected() const;
|
bool HasAnyScriptNodesSelected() const;
|
||||||
|
|
||||||
|
@ -95,15 +89,10 @@ public:
|
||||||
CResourceBrowser* ResourceBrowser() const;
|
CResourceBrowser* ResourceBrowser() const;
|
||||||
CSceneViewport* Viewport() const;
|
CSceneViewport* Viewport() const;
|
||||||
|
|
||||||
inline void SetWorldDir(QString WorldDir) { mWorldDir = (QDir(WorldDir).exists() ? WorldDir : ""); }
|
|
||||||
inline void SetPakFileList(QString FileList) { mPakFileList = (QFile::exists(FileList) ? FileList : ""); }
|
|
||||||
inline void SetPakTarget(QString PakTarget) { mPakTarget = (QFile::exists(PakTarget) ? PakTarget : ""); }
|
|
||||||
|
|
||||||
inline bool CanRepack() const { return !mWorldDir.isEmpty() && !mPakFileList.isEmpty() && !mPakTarget.isEmpty(); }
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void EditorTick(float);
|
virtual void EditorTick(float);
|
||||||
virtual void NotifyNodeAboutToBeDeleted(CSceneNode *pNode);
|
virtual void NotifyNodeAboutToBeDeleted(CSceneNode *pNode);
|
||||||
|
virtual bool Save() override;
|
||||||
|
|
||||||
void Cut();
|
void Cut();
|
||||||
void Copy();
|
void Copy();
|
||||||
|
@ -111,8 +100,6 @@ public slots:
|
||||||
|
|
||||||
void OpenProject();
|
void OpenProject();
|
||||||
void OpenRecentProject();
|
void OpenRecentProject();
|
||||||
bool Save();
|
|
||||||
bool SaveAndRepack();
|
|
||||||
void ExportGame();
|
void ExportGame();
|
||||||
void CloseProject();
|
void CloseProject();
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ bool WCreateTab::eventFilter(QObject *pObj, QEvent *pEvent)
|
||||||
{
|
{
|
||||||
CVector3f SpawnPoint = mpEditor->Viewport()->HoverPoint();
|
CVector3f SpawnPoint = mpEditor->Viewport()->HoverPoint();
|
||||||
CCreateInstanceCommand *pCmd = new CCreateInstanceCommand(mpEditor, pMimeData->Template(), mpSpawnLayer, SpawnPoint);
|
CCreateInstanceCommand *pCmd = new CCreateInstanceCommand(mpEditor, pMimeData->Template(), mpSpawnLayer, SpawnPoint);
|
||||||
mpEditor->UndoStack()->push(pCmd);
|
mpEditor->UndoStack().push(pCmd);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ void WModifyTab::OnDeleteLinksClicked()
|
||||||
|
|
||||||
CScriptObject *pInst = static_cast<CScriptNode*>(mpSelectedNode)->Instance();
|
CScriptObject *pInst = static_cast<CScriptNode*>(mpSelectedNode)->Instance();
|
||||||
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(mpWorldEditor, pInst, Type, Indices);
|
CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(mpWorldEditor, pInst, Type, Indices);
|
||||||
mpWorldEditor->UndoStack()->push(pCmd);
|
mpWorldEditor->UndoStack().push(pCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue