feat(editor): spinbox for floats
This commit is contained in:
parent
c19b428830
commit
7e14e3f968
4 changed files with 86 additions and 14 deletions
|
@ -47,6 +47,7 @@ std::function<void(std::string name)> memberFunctionOf(void(T::*func)(std::strin
|
||||||
enum PropertyFlags {
|
enum PropertyFlags {
|
||||||
PROP_HIDDEN = 1 << 0, // Hidden from the editor
|
PROP_HIDDEN = 1 << 0, // Hidden from the editor
|
||||||
PROP_NOSAVE = 1 << 1, // Do not serialize
|
PROP_NOSAVE = 1 << 1, // Do not serialize
|
||||||
|
PROP_UNIT_FLOAT = 1 << 2, // Float between 0 and 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PropertyCategory {
|
enum PropertyCategory {
|
||||||
|
|
|
@ -109,6 +109,7 @@ Part::Part(PartConstructParams params): Instance(&TYPE), cframe(Data::CFrame(par
|
||||||
.backingField = &transparency,
|
.backingField = &transparency,
|
||||||
.type = &Data::Float::TYPE,
|
.type = &Data::Float::TYPE,
|
||||||
.codec = fieldCodecOf<Data::Float, float>(),
|
.codec = fieldCodecOf<Data::Float, float>(),
|
||||||
|
.flags = PROP_UNIT_FLOAT,
|
||||||
.category = PROP_CATEGORY_APPEARENCE,
|
.category = PROP_CATEGORY_APPEARENCE,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <qabstractitemdelegate.h>
|
#include <qabstractitemdelegate.h>
|
||||||
#include <qbrush.h>
|
#include <qbrush.h>
|
||||||
|
#include <qlineedit.h>
|
||||||
#include <qnamespace.h>
|
#include <qnamespace.h>
|
||||||
#include <qpalette.h>
|
#include <qpalette.h>
|
||||||
|
#include <qspinbox.h>
|
||||||
#include <qstyle.h>
|
#include <qstyle.h>
|
||||||
#include <qstyleditemdelegate.h>
|
#include <qstyleditemdelegate.h>
|
||||||
#include <qstyleoption.h>
|
#include <qstyleoption.h>
|
||||||
|
@ -14,10 +16,12 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <private/qtreeview_p.h>
|
#include <private/qtreeview_p.h>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
|
||||||
class CustomItemDelegate : public QStyledItemDelegate {
|
class CustomItemDelegate : public QStyledItemDelegate {
|
||||||
|
PropertiesView* view;
|
||||||
public:
|
public:
|
||||||
CustomItemDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {}
|
CustomItemDelegate(PropertiesView* parent) : view(parent), QStyledItemDelegate(parent) {}
|
||||||
|
|
||||||
void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override {
|
void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override {
|
||||||
// https://stackoverflow.com/a/76645757/16255372
|
// https://stackoverflow.com/a/76645757/16255372
|
||||||
|
@ -32,10 +36,72 @@ public:
|
||||||
} else {
|
} else {
|
||||||
option->state &= ~QStyle::State_Selected;
|
option->state &= ~QStyle::State_Selected;
|
||||||
|
|
||||||
QWidget* parentWidget = dynamic_cast<QWidget*>(parent());
|
option->backgroundBrush = view->palette().dark();
|
||||||
option->backgroundBrush = parentWidget->palette().dark();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
|
||||||
|
if (index.column() == 0) return nullptr;
|
||||||
|
|
||||||
|
if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return nullptr;
|
||||||
|
InstanceRef inst = view->currentInstance->lock();
|
||||||
|
|
||||||
|
std::string propertyName = view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString();
|
||||||
|
PropertyMeta meta = inst->GetPropertyMeta(propertyName).value();
|
||||||
|
Data::Variant currentValue = inst->GetPropertyValue(propertyName).value();
|
||||||
|
|
||||||
|
if (meta.type == &Data::Float::TYPE) {
|
||||||
|
QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
|
||||||
|
spinBox->setValue(currentValue.get<Data::Float>());
|
||||||
|
|
||||||
|
if (meta.flags & PROP_UNIT_FLOAT) {
|
||||||
|
spinBox->setMinimum(0);
|
||||||
|
spinBox->setMaximum(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spinBox;
|
||||||
|
} else if (meta.type == &Data::Int::TYPE) {
|
||||||
|
QSpinBox* spinBox = new QSpinBox(parent);
|
||||||
|
spinBox->setValue(currentValue.get<Data::Int>());
|
||||||
|
|
||||||
|
return spinBox;
|
||||||
|
} else if (meta.type == &Data::String::TYPE) {
|
||||||
|
QLineEdit* lineEdit = new QLineEdit(parent);
|
||||||
|
lineEdit->setText(QString::fromStdString(currentValue.get<Data::String>()));
|
||||||
|
|
||||||
|
return lineEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const override {
|
||||||
|
editor->setGeometry(option.rect.adjusted(-view->indentation(), 0, -view->indentation(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override {
|
||||||
|
if (index.column() == 0) return;
|
||||||
|
|
||||||
|
if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return;
|
||||||
|
InstanceRef inst = view->currentInstance->lock();
|
||||||
|
|
||||||
|
std::string propertyName = view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString();
|
||||||
|
PropertyMeta meta = inst->GetPropertyMeta(propertyName).value();
|
||||||
|
|
||||||
|
if (meta.type == &Data::Float::TYPE) {
|
||||||
|
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
|
||||||
|
|
||||||
|
inst->SetPropertyValue(propertyName, Data::Float((float)spinBox->value()));
|
||||||
|
} else if (meta.type == &Data::Int::TYPE) {
|
||||||
|
QSpinBox* spinBox = dynamic_cast<QSpinBox*>(editor);
|
||||||
|
|
||||||
|
inst->SetPropertyValue(propertyName, Data::Int((float)spinBox->value()));
|
||||||
|
} else if (meta.type == &Data::String::TYPE) {
|
||||||
|
QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(editor);
|
||||||
|
|
||||||
|
inst->SetPropertyValue(propertyName, Data::String(lineEdit->text().toStdString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PropertiesView::PropertiesView(QWidget* parent):
|
PropertiesView::PropertiesView(QWidget* parent):
|
||||||
|
@ -68,7 +134,6 @@ QStringList PROPERTY_CATEGORY_NAMES {
|
||||||
"Surface"
|
"Surface"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
QModelIndex PropertiesView::indexAt(const QPoint &point) const {
|
QModelIndex PropertiesView::indexAt(const QPoint &point) const {
|
||||||
return QTreeWidget::indexAt(point + QPoint(indentation(), 0));
|
return QTreeWidget::indexAt(point + QPoint(indentation(), 0));
|
||||||
}
|
}
|
||||||
|
@ -163,16 +228,16 @@ void PropertiesView::propertyChanged(QTreeWidgetItem *item, int column) {
|
||||||
if (!item->parent() || !currentInstance || currentInstance->expired()) return;
|
if (!item->parent() || !currentInstance || currentInstance->expired()) return;
|
||||||
InstanceRef inst = currentInstance->lock();
|
InstanceRef inst = currentInstance->lock();
|
||||||
|
|
||||||
std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString();
|
// std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString();
|
||||||
PropertyMeta meta = inst->GetPropertyMeta(propertyName).value();
|
// PropertyMeta meta = inst->GetPropertyMeta(propertyName).value();
|
||||||
|
|
||||||
if (meta.type == &Data::String::TYPE) {
|
// if (meta.type == &Data::String::TYPE) {
|
||||||
inst->SetPropertyValue(propertyName, Data::String(item->data(1, Qt::EditRole).toString().toStdString()));
|
// inst->SetPropertyValue(propertyName, Data::String(item->data(1, Qt::EditRole).toString().toStdString()));
|
||||||
} else if (meta.type == &Data::Bool::TYPE) {
|
// } else if (meta.type == &Data::Bool::TYPE) {
|
||||||
inst->SetPropertyValue(propertyName, Data::Bool(item->checkState(1)));
|
// inst->SetPropertyValue(propertyName, Data::Bool(item->checkState(1)));
|
||||||
} else {
|
// } else {
|
||||||
inst->SetPropertyValue(propertyName, meta.type->fromString(item->data(1, Qt::EditRole).toString().toStdString()));
|
// inst->SetPropertyValue(propertyName, meta.type->fromString(item->data(1, Qt::EditRole).toString().toStdString()));
|
||||||
}
|
// }
|
||||||
|
|
||||||
update(indexFromItem(item, column));
|
// update(indexFromItem(item, column));
|
||||||
}
|
}
|
|
@ -5,11 +5,16 @@
|
||||||
|
|
||||||
class Ui_MainWindow;
|
class Ui_MainWindow;
|
||||||
|
|
||||||
|
class CustomItemDelegate;
|
||||||
|
|
||||||
class PropertiesView : public QTreeWidget {
|
class PropertiesView : public QTreeWidget {
|
||||||
Q_DECLARE_PRIVATE(QTreeView)
|
Q_DECLARE_PRIVATE(QTreeView)
|
||||||
|
|
||||||
std::optional<InstanceRefWeak> currentInstance;
|
std::optional<InstanceRefWeak> currentInstance;
|
||||||
void propertyChanged(QTreeWidgetItem *item, int column);
|
void propertyChanged(QTreeWidgetItem *item, int column);
|
||||||
|
void activateProperty(QTreeWidgetItem *item, int column);
|
||||||
|
|
||||||
|
friend CustomItemDelegate;
|
||||||
protected:
|
protected:
|
||||||
void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override;
|
void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override;
|
||||||
QModelIndex indexAt(const QPoint &point) const override;
|
QModelIndex indexAt(const QPoint &point) const override;
|
||||||
|
|
Loading…
Add table
Reference in a new issue