src/ui/objecteditor.cpp

changeset 200
ca23936b455b
parent 183
97b591813c8b
child 232
8efa3a33172e
equal deleted inserted replaced
199:6988973515d2 200:ca23936b455b
1 #include <QCheckBox> 1 #include <QCheckBox>
2 #include <QLineEdit> 2 #include <QLineEdit>
3 #include <QFormLayout> 3 #include <QFormLayout>
4 #include "objecteditor.h" 4 #include "objecteditor.h"
5 #include "document.h" 5 #include "document.h"
6 #include "modeleditor.h"
7 #include "widgets/colorbutton.h" 6 #include "widgets/colorbutton.h"
8 #include "widgets/colorindexinput.h" 7 #include "widgets/colorindexinput.h"
9 #include "widgets/vec3editor.h" 8 #include "widgets/vec3editor.h"
10 #include "ui_objecteditor.h" 9 #include "ui_objecteditor.h"
11 10
12 ObjectEditor::ObjectEditor(Document* document, const ldraw::id_t id) : 11 using PropertyValue = std::variant<
13 QWidget{document}, 12 const glm::vec3*,
14 ui{*new Ui_ObjectEditor}, 13 const glm::mat4*,
15 document{document} 14 const QString*,
15 ldraw::Color>;
16
17 enum PropertyKey
16 { 18 {
17 this->ui.setupUi(this); 19 Point1,
18 this->setObjectId(id); 20 Point2,
19 QFormLayout* formLayout = new QFormLayout{ui.properties}; 21 Point3,
20 this->ui.properties->setLayout(formLayout); 22 Point4,
21 for (const ldraw::Property property : ldraw::ALL_PROPERTIES) 23 Control1,
22 { 24 Control2,
23 QWidget* editorWidget = this->makeEditorWidgetForProperty(property); 25 Color,
24 if (editorWidget != nullptr) 26 Transformation,
25 { 27 Name,
26 editorWidget->setProperty("_property_id", static_cast<int>(property)); 28 Text,
27 QLabel* propertyLabel = new QLabel{ldraw::traits(property).name.data()}; 29 Code,
28 formLayout->addRow(propertyLabel, editorWidget); 30 };
29 this->propertyWidgets[property] = {propertyLabel, editorWidget}; 31
30 } 32 std::map<PropertyKey, PropertyValue> getProperties(const ModelElement& element)
31 } 33 {
32 this->setObjectId(ldraw::NULL_ID); 34 std::map<PropertyKey, PropertyValue> result;
35 std::visit<void>(overloaded{
36 [&](const Colored<LineSegment>& edge) {
37 result[Point1] = &edge.p1;
38 result[Point2] = &edge.p2;
39 result[Color] = edge.color;
40 },
41 [&](const Colored<Triangle>& tri) {
42 result[Point1] = &tri.p1;
43 result[Point2] = &tri.p2;
44 result[Point3] = &tri.p3;
45 result[Color] = tri.color;
46 },
47 [&](const Colored<Quadrilateral>& quad) {
48 result[Point1] = &quad.p1;
49 result[Point2] = &quad.p2;
50 result[Point3] = &quad.p3;
51 result[Point4] = &quad.p4;
52 result[Color] = quad.color;
53 },
54 [&](const Colored<ConditionalEdge>& cedge) {
55 result[Point1] = &cedge.p1;
56 result[Point2] = &cedge.p2;
57 result[Control1] = &cedge.c1;
58 result[Control2] = &cedge.c2;
59 result[Color] = cedge.color;
60 },
61 [&](const Colored<SubfileReference>& ref) {
62 result[Transformation] = &ref.transformation;
63 result[Name] = &ref.name;
64 result[Color] = ref.color;
65 },
66 [&](Empty) {},
67 [&](const Comment& comment) {
68 result[Text] = &comment.text;
69 },
70 [&](const ParseError& parseError) {
71 result[Code] = &parseError.code;
72 },
73 }, element);
74 return result;
33 } 75 }
34
35 ObjectEditor::~ObjectEditor()
36 {
37 delete &this->ui;
38 }
39
40 QString titleCase(const QString& string)
41 {
42 return string.left(1).toUpper() + string.mid(1);
43 }
44
45 void setValueToWidget(QWidget* widget, const QVariant& value)
46 {
47 ColorIndexInput* colorIndexInput = qobject_cast<ColorIndexInput*>(widget);
48 if (colorIndexInput != nullptr)
49 {
50 colorIndexInput->setSelectedColor(value.value<ldraw::Color>());
51 }
52 else
53 {
54 Vec3Editor* vec3Editor = qobject_cast<Vec3Editor*>(widget);
55 if (vec3Editor != nullptr)
56 {
57 vec3Editor->setValue(value.value<glm::vec3>());
58 }
59 else
60 {
61 QCheckBox* checkBox = qobject_cast<QCheckBox*>(widget);
62 if (checkBox != nullptr)
63 {
64 checkBox->setChecked(value.toBool());
65 }
66 else
67 {
68 QLineEdit* lineEdit = qobject_cast<QLineEdit*>(widget);
69 if (lineEdit != nullptr)
70 {
71 lineEdit->setText(value.toString());
72 }
73 }
74 }
75 }
76 }
77
78 void ObjectEditor::setObjectId(const ldraw::id_t id)
79 {
80 this->objectId = id;
81 const ldraw::Object* object = this->document->getModel().get(id);
82 this->ui.properties->setEnabled(object != nullptr);
83 if (object != nullptr)
84 {
85 this->ui.typeNameLabel->setText("<b>" + titleCase(object->typeName()) + "</b>");
86 this->ui.typeIconLabel->setPixmap(QPixmap{object->iconName()}.scaledToWidth(24));
87 for (const ldraw::Property property : ldraw::ALL_PROPERTIES)
88 {
89 const QVariant value = object->getProperty(property);
90 const auto it = this->propertyWidgets.find(property);
91 if (it != this->propertyWidgets.end())
92 {
93 it->first->setEnabled(not value.isNull());
94 it->second->setEnabled(not value.isNull());
95 if (not value.isNull())
96 {
97 setValueToWidget(it->second, value);
98 }
99 }
100 }
101 }
102 else
103 {
104 this->ui.typeNameLabel->setText(tr("No object selected"));
105 this->ui.typeIconLabel->clear();
106 }
107 }
108
109 void ObjectEditor::handleColorChange(ldraw::Color value)
110 {
111 this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
112 }
113
114 void ObjectEditor::handleVec3Change(const glm::vec3 &value)
115 {
116 this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
117 }
118
119 void ObjectEditor::handleBoolChange(bool value)
120 {
121 this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
122 }
123
124 void ObjectEditor::handleStringChange(const QString &value)
125 {
126 this->handlePropertyChange(this->sender(), QVariant::fromValue(value));
127 }
128
129 QWidget* ObjectEditor::makeEditorWidgetForProperty(ldraw::Property property)
130 {
131 QWidget* const parent = qobject_cast<QWidget*>(this->parent());
132 if (ldraw::traits(property).type == qMetaTypeId<ldraw::Color>())
133 {
134 ColorIndexInput* colorWidget = new ColorIndexInput{this->document, {0}, parent};
135 connect(colorWidget, &ColorIndexInput::colorChanged, this, &ObjectEditor::handleColorChange);
136 return colorWidget;
137 }
138 else if (ldraw::traits(property).type == qMetaTypeId<glm::vec3>())
139 {
140 Vec3Editor* editor = new Vec3Editor{{}, parent};
141 connect(editor, &Vec3Editor::valueChanged, this, &ObjectEditor::handleVec3Change);
142 return editor;
143 }
144 else if (ldraw::traits(property).type == qMetaTypeId<bool>())
145 {
146 QCheckBox* editor = new QCheckBox{{}, parent};
147 connect(editor, &QCheckBox::clicked, this, &ObjectEditor::handleBoolChange);
148 return editor;
149 }
150 else if (ldraw::traits(property).type == qMetaTypeId<QString>())
151 {
152 QLineEdit* editor = new QLineEdit{{}, parent};
153 connect(editor, &QLineEdit::textChanged, this, &ObjectEditor::handleStringChange);
154 return editor;
155 }
156 else
157 {
158 return nullptr;
159 }
160 }
161
162 void ObjectEditor::handlePropertyChange(QObject *caller, const QVariant &value)
163 {
164 QVariant propertyVariant = caller->property("_property_id");
165 if (not propertyVariant.isNull())
166 {
167 ldraw::Property const property = static_cast<ldraw::Property>(propertyVariant.toInt());
168 this->document->editModel()->setObjectProperty(this->objectId, property, value);
169 }
170 }

mercurial