479 lines
14 KiB
C++
479 lines
14 KiB
C++
#include "WPropertyEditor.h"
|
|
#include "UICommon.h"
|
|
#include "WDraggableSpinBox.h"
|
|
#include "WIntegralSpinBox.h"
|
|
#include "WResourceSelector.h"
|
|
#include "WColorPicker.h"
|
|
#include "WVectorEditor.h"
|
|
#include "WAnimParamsEditor.h"
|
|
#include <Resource/CAnimSet.h>
|
|
|
|
#include <QCheckBox>
|
|
#include <QComboBox>
|
|
#include <QDoubleSpinBox>
|
|
#include <QFontMetrics>
|
|
#include <QGroupBox>
|
|
#include <QLineEdit>
|
|
#include <QSpinBox>
|
|
|
|
static const QString gskNullProperty = "[NULL]";
|
|
static const QString gskUnsupportedType = "Invalid property type";
|
|
|
|
WPropertyEditor::WPropertyEditor(QWidget *pParent, CPropertyBase *pProperty)
|
|
: QWidget(pParent)
|
|
{
|
|
mUI.PropertyName = new QLabel(gskNullProperty, this);
|
|
mUI.EditorWidget = nullptr;
|
|
mUI.Layout = new QHBoxLayout(this);
|
|
mUI.Layout->addWidget(mUI.PropertyName);
|
|
mUI.Layout->setContentsMargins(0,0,0,0);
|
|
setLayout(mUI.Layout);
|
|
|
|
mpProperty = nullptr;
|
|
SetProperty(pProperty);
|
|
}
|
|
|
|
WPropertyEditor::~WPropertyEditor()
|
|
{
|
|
|
|
}
|
|
|
|
void WPropertyEditor::resizeEvent(QResizeEvent *pEvent)
|
|
{
|
|
CreateLabelText();
|
|
}
|
|
|
|
void WPropertyEditor::SetProperty(CPropertyBase *pProperty)
|
|
{
|
|
if (pProperty)
|
|
{
|
|
bool IsNewProperty = ((!mpProperty) || (pProperty->Template() != mpProperty->Template()));
|
|
mpProperty = pProperty;
|
|
|
|
if (IsNewProperty)
|
|
CreateEditor();
|
|
else
|
|
UpdateEditor();
|
|
}
|
|
|
|
else
|
|
{
|
|
delete mUI.EditorWidget;
|
|
mUI.EditorWidget = nullptr;
|
|
|
|
mpProperty = pProperty;
|
|
mUI.PropertyName->setText(gskNullProperty);
|
|
}
|
|
}
|
|
|
|
void WPropertyEditor::CreateEditor()
|
|
{
|
|
// Clear existing edit widget (if any)
|
|
delete mUI.EditorWidget;
|
|
|
|
// Set name
|
|
mUI.PropertyName->setText(TO_QSTRING(mpProperty->Name()));
|
|
mUI.PropertyName->setToolTip(TO_QSTRING(mpProperty->Name()));
|
|
|
|
// Set editor widget
|
|
switch (mpProperty->Type())
|
|
{
|
|
|
|
// Bool - QCheckBox
|
|
case eBoolProperty:
|
|
{
|
|
CBoolProperty *pBoolCast = static_cast<CBoolProperty*>(mpProperty);
|
|
QCheckBox *pCheckBox = new QCheckBox(this);
|
|
|
|
pCheckBox->setChecked(pBoolCast->Get());
|
|
|
|
mUI.EditorWidget = pCheckBox;
|
|
break;
|
|
}
|
|
|
|
// Byte - WIntegralSpinBox
|
|
case eByteProperty:
|
|
{
|
|
CByteProperty *pByteCast = static_cast<CByteProperty*>(mpProperty);
|
|
QSpinBox *pSpinBox = new WIntegralSpinBox(this);
|
|
|
|
pSpinBox->setRange(-128, 128);
|
|
pSpinBox->setFocusPolicy(Qt::StrongFocus);
|
|
pSpinBox->setContextMenuPolicy(Qt::NoContextMenu);
|
|
pSpinBox->setValue(pByteCast->Get());
|
|
|
|
mUI.EditorWidget = pSpinBox;
|
|
break;
|
|
}
|
|
|
|
// Short - WIntegralSpinBox
|
|
case eShortProperty:
|
|
{
|
|
CShortProperty *pShortCast = static_cast<CShortProperty*>(mpProperty);
|
|
QSpinBox *pSpinBox = new WIntegralSpinBox(this);
|
|
|
|
pSpinBox->setRange(-32768, 32767);
|
|
pSpinBox->setFocusPolicy(Qt::StrongFocus);
|
|
pSpinBox->setContextMenuPolicy(Qt::NoContextMenu);
|
|
pSpinBox->setValue(pShortCast->Get());
|
|
|
|
mUI.EditorWidget = pSpinBox;
|
|
break;
|
|
}
|
|
|
|
// Long - WIntegralSpinBox
|
|
case eLongProperty:
|
|
{
|
|
CLongProperty *pLongCast = static_cast<CLongProperty*>(mpProperty);
|
|
QSpinBox *pSpinBox = new WIntegralSpinBox(this);
|
|
|
|
pSpinBox->setRange(-2147483648, 2147483647);
|
|
pSpinBox->setFocusPolicy(Qt::StrongFocus);
|
|
pSpinBox->setContextMenuPolicy(Qt::NoContextMenu);
|
|
pSpinBox->setValue(pLongCast->Get());
|
|
|
|
mUI.EditorWidget = pSpinBox;
|
|
break;
|
|
}
|
|
|
|
// Enum - QComboBox
|
|
case eEnumProperty:
|
|
{
|
|
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(mpProperty);
|
|
CEnumTemplate *pTemplate = static_cast<CEnumTemplate*>(pEnumCast->Template());
|
|
QComboBox *pComboBox = new QComboBox(this);
|
|
|
|
for (u32 iEnum = 0; iEnum < pTemplate->NumEnumerators(); iEnum++)
|
|
{
|
|
TString name = pTemplate->EnumeratorName(iEnum);
|
|
pComboBox->addItem(TO_QSTRING(name));
|
|
}
|
|
|
|
u32 index = pEnumCast->Get();
|
|
if (index < pTemplate->NumEnumerators()) pComboBox->setCurrentIndex(index);
|
|
pComboBox->setFocusPolicy(Qt::StrongFocus);
|
|
pComboBox->setContextMenuPolicy(Qt::NoContextMenu);
|
|
|
|
mUI.EditorWidget = pComboBox;
|
|
break;
|
|
}
|
|
|
|
// Bitfield - QGroupBox containing QCheckBoxes
|
|
case eBitfieldProperty:
|
|
{
|
|
CBitfieldProperty *pBitfieldCast = static_cast<CBitfieldProperty*>(mpProperty);
|
|
CBitfieldTemplate *pTemplate = static_cast<CBitfieldTemplate*>(pBitfieldCast->Template());
|
|
long value = pBitfieldCast->Get();
|
|
|
|
QGroupBox *pGroupBox = new QGroupBox(this);
|
|
QVBoxLayout *pBitfieldLayout = new QVBoxLayout(pGroupBox);
|
|
pBitfieldLayout->setContentsMargins(5,5,5,5);
|
|
pGroupBox->setLayout(pBitfieldLayout);
|
|
pGroupBox->setTitle(TO_QSTRING(pBitfieldCast->Name()));
|
|
mUI.PropertyName->hide();
|
|
|
|
for (u32 iFlag = 0; iFlag < pTemplate->NumFlags(); iFlag++)
|
|
{
|
|
TString flagName = pTemplate->FlagName(iFlag);
|
|
long mask = pTemplate->FlagMask(iFlag);
|
|
|
|
QCheckBox *pCheckBox = new QCheckBox(TO_QSTRING(flagName), pGroupBox);
|
|
pCheckBox->setChecked((value & mask) != 0);
|
|
pBitfieldLayout->addWidget(pCheckBox);
|
|
}
|
|
|
|
mUI.EditorWidget = pGroupBox;
|
|
break;
|
|
}
|
|
|
|
// Float - WDraggableSpinBox
|
|
case eFloatProperty:
|
|
{
|
|
CFloatProperty *pFloatCast = static_cast<CFloatProperty*>(mpProperty);
|
|
WDraggableSpinBox *pDraggableSpinBox = new WDraggableSpinBox(this);
|
|
|
|
pDraggableSpinBox->setDecimals(4);
|
|
pDraggableSpinBox->setFocusPolicy(Qt::StrongFocus);
|
|
pDraggableSpinBox->setContextMenuPolicy(Qt::NoContextMenu);
|
|
pDraggableSpinBox->setValue(pFloatCast->Get());
|
|
|
|
mUI.EditorWidget = pDraggableSpinBox;
|
|
break;
|
|
}
|
|
|
|
// String - QLineEdit
|
|
case eStringProperty:
|
|
{
|
|
CStringProperty *pStringCast = static_cast<CStringProperty*>(mpProperty);
|
|
QLineEdit *pLineEdit = new QLineEdit(this);
|
|
|
|
pLineEdit->setText(TO_QSTRING(pStringCast->Get()));
|
|
pLineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
//pLineEdit->setCursorPosition(0);
|
|
|
|
mUI.EditorWidget = pLineEdit;
|
|
break;
|
|
}
|
|
|
|
// Vector3 - WVectorEditor (inside QGroupBox)
|
|
case eVector3Property:
|
|
{
|
|
CVector3Property *pVector3Cast = static_cast<CVector3Property*>(mpProperty);
|
|
QGroupBox *pGroupBox = new QGroupBox(this);
|
|
WVectorEditor *pVectorEditor = new WVectorEditor(pGroupBox);
|
|
|
|
QVBoxLayout *pGroupLayout = new QVBoxLayout(pGroupBox);
|
|
pGroupLayout->addWidget(pVectorEditor);
|
|
pGroupLayout->setContentsMargins(0,0,0,0);
|
|
pGroupBox->setLayout(pGroupLayout);
|
|
|
|
pGroupBox->setTitle(TO_QSTRING(mpProperty->Name()));
|
|
pVectorEditor->SetValue(pVector3Cast->Get());
|
|
pVectorEditor->SetOrientation(Qt::Vertical);
|
|
mUI.PropertyName->hide();
|
|
|
|
mUI.EditorWidget = pGroupBox;
|
|
break;
|
|
}
|
|
|
|
// Color - WColorPicker
|
|
case eColorProperty:
|
|
{
|
|
CColorProperty *pColorCast = static_cast<CColorProperty*>(mpProperty);
|
|
WColorPicker *pColorPicker = new WColorPicker(this);
|
|
|
|
CColor color = pColorCast->Get();
|
|
QColor qcolor = QColor(color.r, color.g, color.b, color.a);
|
|
pColorPicker->setColor(qcolor);
|
|
|
|
mUI.EditorWidget = pColorPicker;
|
|
break;
|
|
}
|
|
|
|
// File - WResourceSelector
|
|
case eFileProperty:
|
|
{
|
|
CFileProperty *pFileCast = static_cast<CFileProperty*>(mpProperty);
|
|
WResourceSelector *pResourceSelector = new WResourceSelector(this);
|
|
|
|
pResourceSelector->AdjustPreviewToParent(true);
|
|
pResourceSelector->SetAllowedExtensions(pFileCast->AllowedExtensions());
|
|
pResourceSelector->SetResource(pFileCast->Get());
|
|
|
|
mUI.EditorWidget = pResourceSelector;
|
|
break;
|
|
}
|
|
|
|
// Struct - QGroupBox
|
|
case eStructProperty:
|
|
{
|
|
CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(mpProperty);
|
|
|
|
QGroupBox *pGroupBox = new QGroupBox(this);
|
|
QVBoxLayout *pStructLayout = new QVBoxLayout(pGroupBox);
|
|
pStructLayout->setContentsMargins(5,5,5,5);
|
|
pGroupBox->setLayout(pStructLayout);
|
|
pGroupBox->setTitle(TO_QSTRING(pStructCast->Name()));
|
|
mUI.PropertyName->hide();
|
|
|
|
for (u32 p = 0; p < pStructCast->Count(); p++)
|
|
{
|
|
WPropertyEditor *pEditor = new WPropertyEditor(pGroupBox, pStructCast->PropertyByIndex(p));
|
|
pStructLayout->addWidget(pEditor);
|
|
}
|
|
|
|
mUI.EditorWidget = pGroupBox;
|
|
break;
|
|
}
|
|
|
|
// AnimParams - WAnimParamsEditor
|
|
case eAnimParamsProperty:
|
|
{
|
|
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(mpProperty);
|
|
CAnimationParameters params = pAnimCast->Get();
|
|
|
|
WAnimParamsEditor *pEditor = new WAnimParamsEditor(params, this);
|
|
pEditor->SetTitle(TO_QSTRING(pAnimCast->Name()));
|
|
|
|
mUI.PropertyName->hide();
|
|
mUI.EditorWidget = pEditor;
|
|
break;
|
|
}
|
|
|
|
// Invalid
|
|
case eInvalidProperty:
|
|
default:
|
|
mUI.EditorWidget = new QLabel(gskUnsupportedType, this);
|
|
break;
|
|
}
|
|
|
|
// For some reason setting a minimum size on group boxes flattens it...
|
|
if ((mpProperty->Type() != eStructProperty) &&
|
|
(mpProperty->Type() != eBitfieldProperty) &&
|
|
(mpProperty->Type() != eVector3Property) &&
|
|
(mpProperty->Type() != eAnimParamsProperty))
|
|
{
|
|
mUI.EditorWidget->setMinimumHeight(21);
|
|
mUI.EditorWidget->setMaximumHeight(21);
|
|
}
|
|
|
|
mUI.Layout->addWidget(mUI.EditorWidget, 0);
|
|
CreateLabelText();
|
|
}
|
|
|
|
void WPropertyEditor::UpdateEditor()
|
|
{
|
|
switch (mpProperty->Type())
|
|
{
|
|
|
|
case eBoolProperty:
|
|
{
|
|
CBoolProperty *pBoolCast = static_cast<CBoolProperty*>(mpProperty);
|
|
QCheckBox *pCheckBox = static_cast<QCheckBox*>(mUI.EditorWidget);
|
|
pCheckBox->setChecked(pBoolCast->Get());
|
|
break;
|
|
}
|
|
|
|
case eByteProperty:
|
|
{
|
|
CByteProperty *pByteCast = static_cast<CByteProperty*>(mpProperty);
|
|
QSpinBox *pSpinBox = static_cast<QSpinBox*>(mUI.EditorWidget);
|
|
pSpinBox->setValue(pByteCast->Get());
|
|
break;
|
|
}
|
|
|
|
case eShortProperty:
|
|
{
|
|
CShortProperty *pShortCast = static_cast<CShortProperty*>(mpProperty);
|
|
QSpinBox *pSpinBox = static_cast<QSpinBox*>(mUI.EditorWidget);
|
|
pSpinBox->setValue(pShortCast->Get());
|
|
break;
|
|
}
|
|
|
|
case eLongProperty:
|
|
{
|
|
CLongProperty *pLongCast = static_cast<CLongProperty*>(mpProperty);
|
|
QSpinBox *pSpinBox = static_cast<QSpinBox*>(mUI.EditorWidget);
|
|
pSpinBox->setValue(pLongCast->Get());
|
|
break;
|
|
}
|
|
|
|
case eEnumProperty:
|
|
{
|
|
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(mpProperty);
|
|
QComboBox *pComboBox = static_cast<QComboBox*>(mUI.EditorWidget);
|
|
pComboBox->setCurrentIndex(pEnumCast->Get());
|
|
break;
|
|
}
|
|
|
|
case eBitfieldProperty:
|
|
{
|
|
CBitfieldProperty *pBitfieldCast = static_cast<CBitfieldProperty*>(mpProperty);
|
|
CBitfieldTemplate *pTemplate = static_cast<CBitfieldTemplate*>(pBitfieldCast->Template());
|
|
QGroupBox *pGroupBox = static_cast<QGroupBox*>(mUI.EditorWidget);
|
|
|
|
QObjectList ChildList = pGroupBox->children();
|
|
long value = pBitfieldCast->Get();
|
|
u32 propNum = 0;
|
|
|
|
foreach (QObject *pObj, ChildList)
|
|
{
|
|
if (pObj != pGroupBox->layout())
|
|
{
|
|
u32 mask = pTemplate->FlagMask(propNum);
|
|
QCheckBox *pCheckBox = static_cast<QCheckBox*>(pObj);
|
|
pCheckBox->setChecked((value & mask) != 0);
|
|
propNum++;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case eFloatProperty:
|
|
{
|
|
CFloatProperty *pFloatCast = static_cast<CFloatProperty*>(mpProperty);
|
|
WDraggableSpinBox *pDraggableSpinBox = static_cast<WDraggableSpinBox*>(mUI.EditorWidget);
|
|
pDraggableSpinBox->setValue(pFloatCast->Get());
|
|
break;
|
|
}
|
|
|
|
case eStringProperty:
|
|
{
|
|
CStringProperty *pStringCast = static_cast<CStringProperty*>(mpProperty);
|
|
QLineEdit *pLineEdit = static_cast<QLineEdit*>(mUI.EditorWidget);
|
|
pLineEdit->setText(TO_QSTRING(pStringCast->Get()));
|
|
pLineEdit->setCursorPosition(0);
|
|
break;
|
|
}
|
|
|
|
case eVector3Property:
|
|
{
|
|
CVector3Property *pVector3Cast = static_cast<CVector3Property*>(mpProperty);
|
|
QGroupBox *pGroupBox = static_cast<QGroupBox*>(mUI.EditorWidget);
|
|
|
|
WVectorEditor *pVectorEditor = static_cast<WVectorEditor*>(pGroupBox->children().first());
|
|
pVectorEditor->SetValue(pVector3Cast->Get());
|
|
break;
|
|
}
|
|
|
|
case eColorProperty:
|
|
{
|
|
CColorProperty *pColorCast = static_cast<CColorProperty*>(mpProperty);
|
|
WColorPicker *pColorPicker = static_cast<WColorPicker*>(mUI.EditorWidget);
|
|
|
|
CColor color = pColorCast->Get();
|
|
QColor qcolor = QColor(color.r, color.g, color.b, color.a);
|
|
pColorPicker->setColor(qcolor);
|
|
|
|
break;
|
|
}
|
|
|
|
case eFileProperty:
|
|
{
|
|
CFileProperty *pFileCast = static_cast<CFileProperty*>(mpProperty);
|
|
WResourceSelector *pResourceSelector = static_cast<WResourceSelector*>(mUI.EditorWidget);
|
|
pResourceSelector->SetAllowedExtensions(pFileCast->AllowedExtensions());
|
|
pResourceSelector->SetResource(pFileCast->Get());
|
|
break;
|
|
}
|
|
|
|
case eStructProperty:
|
|
{
|
|
CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(mpProperty);
|
|
QGroupBox *pGroupBox = static_cast<QGroupBox*>(mUI.EditorWidget);
|
|
|
|
QObjectList ChildList = pGroupBox->children();
|
|
u32 PropNum = 0;
|
|
|
|
foreach (QObject *pObj, ChildList)
|
|
{
|
|
if (pObj != pGroupBox->layout())
|
|
{
|
|
CPropertyBase *pProp = pStructCast->PropertyByIndex(PropNum);
|
|
static_cast<WPropertyEditor*>(pObj)->SetProperty(pProp);
|
|
PropNum++;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case eAnimParamsProperty:
|
|
{
|
|
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(mpProperty);
|
|
WAnimParamsEditor *pEditor = static_cast<WAnimParamsEditor*>(mUI.EditorWidget);
|
|
pEditor->SetParameters(pAnimCast->Get());
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void WPropertyEditor::CreateLabelText()
|
|
{
|
|
mUI.PropertyName->setText(TO_QSTRING(mpProperty->Name()));
|
|
QFontMetrics metrics(mUI.PropertyName->font());
|
|
QString text = metrics.elidedText(TO_QSTRING(mpProperty->Name()), Qt::ElideRight, mUI.PropertyName->width());
|
|
mUI.PropertyName->setText(text);
|
|
}
|