20 document{document}, |
20 document{document}, |
21 formContainer{new QWidget{this}}, |
21 formContainer{new QWidget{this}}, |
22 objectTypeNameLabel{new QLabel{this}}, |
22 objectTypeNameLabel{new QLabel{this}}, |
23 objectTypeIconLabel{new QLabel{this}} |
23 objectTypeIconLabel{new QLabel{this}} |
24 { |
24 { |
25 this->polygonEditor.emplace(this->document, id); |
|
26 this->setLayout(new QVBoxLayout{this}); |
25 this->setLayout(new QVBoxLayout{this}); |
27 QWidget* objectTitleLayoutContainer = new QWidget{this}; |
26 QWidget* objectTitleLayoutContainer = new QWidget{this}; |
28 QLayout* objectTitleLayout = new QHBoxLayout{objectTitleLayoutContainer}; |
27 QLayout* objectTitleLayout = new QHBoxLayout{objectTitleLayoutContainer}; |
29 objectTitleLayoutContainer->setLayout(objectTitleLayout); |
28 objectTitleLayoutContainer->setLayout(objectTitleLayout); |
30 objectTitleLayout->addWidget(this->objectTypeIconLabel); |
29 objectTitleLayout->addWidget(this->objectTypeIconLabel); |
31 objectTitleLayout->addWidget(this->objectTypeNameLabel); |
30 objectTitleLayout->addWidget(this->objectTypeNameLabel); |
32 objectTitleLayout->addWidget(new QSplitter{Qt::Horizontal, this}); |
31 objectTitleLayout->addWidget(new QSplitter{Qt::Horizontal, this}); |
33 this->layout()->addWidget(objectTitleLayoutContainer); |
32 this->layout()->addWidget(objectTitleLayoutContainer); |
34 this->layout()->addWidget(&*this->polygonEditor); |
|
35 this->layout()->addWidget(formContainer); |
33 this->layout()->addWidget(formContainer); |
36 this->setObjectId(id); |
34 this->setObjectId(id); |
37 |
35 |
38 QWidget* const parent = this->formContainer; |
36 QWidget* const parent = this->formContainer; |
39 QFormLayout* formLayout = new QFormLayout{parent}; |
37 QFormLayout* formLayout = new QFormLayout{parent}; |
40 this->formContainer->setLayout(formLayout); |
38 this->formContainer->setLayout(formLayout); |
41 QLabel* colorLabel = new QLabel{"Color", parent}; |
39 |
42 ColorIndexInput* colorWidget = new ColorIndexInput{document, {0}, parent}; |
40 for (const ldraw::Property property : ldraw::ALL_PROPERTIES) |
43 formLayout->addRow(colorLabel, colorWidget); |
|
44 connect(colorWidget, &ColorIndexInput::colorChanged, [this](ldraw::Color color) |
|
45 { |
41 { |
46 const QModelIndex index = this->document->getModel().find(this->objectId); |
42 QWidget* editorWidget = this->makeEditorWidgetForProperty(property); |
47 if (index.isValid()) |
43 if (editorWidget != nullptr) |
48 { |
44 { |
49 this->document->editModel()->modifyObjectAt<ldraw::ColoredObject>( |
45 editorWidget->setProperty("_property_id", static_cast<int>(property)); |
50 index.row(), |
46 QLabel* propertyLabel = new QLabel{ldraw::traits(property).name.data()}; |
51 [color](ldraw::ColoredObject* object) |
47 formLayout->addRow(propertyLabel, editorWidget); |
52 { |
48 this->propertyWidgets[property] = {propertyLabel, editorWidget}; |
53 object->colorIndex = color; |
|
54 } |
|
55 ); |
|
56 } |
49 } |
57 }); |
50 } |
58 this->propertyWidgets[ldraw::Property::Color] = {colorLabel, colorWidget}; |
51 |
|
52 this->setObjectId(ldraw::NULL_ID); |
59 } |
53 } |
60 |
54 |
61 QString titleCase(const QString& string) |
55 QString titleCase(const QString& string) |
62 { |
56 { |
63 return string.left(1).toUpper() + string.mid(1); |
57 return string.left(1).toUpper() + string.mid(1); |
64 } |
58 } |
65 |
59 |
|
60 void setValueToWidget(QWidget* widget, const QVariant& value) |
|
61 { |
|
62 ColorIndexInput* colorIndexInput = qobject_cast<ColorIndexInput*>(widget); |
|
63 if (colorIndexInput != nullptr) |
|
64 { |
|
65 colorIndexInput->setSelectedColor(value.value<ldraw::Color>()); |
|
66 } |
|
67 else |
|
68 { |
|
69 Vec3Editor* vec3Editor = qobject_cast<Vec3Editor*>(widget); |
|
70 if (vec3Editor != nullptr) |
|
71 { |
|
72 vec3Editor->setValue(value.value<glm::vec3>()); |
|
73 } |
|
74 } |
|
75 } |
|
76 |
66 void ObjectEditor::setObjectId(const ldraw::id_t id) |
77 void ObjectEditor::setObjectId(const ldraw::id_t id) |
67 { |
78 { |
68 this->objectId = id; |
79 this->objectId = id; |
69 const ldraw::Object* object = this->document->getModel().get(id); |
80 const ldraw::Object* object = this->document->getModel().get(id); |
70 this->clear(); |
|
71 if (object != nullptr) |
81 if (object != nullptr) |
72 { |
82 { |
73 this->objectTypeNameLabel->setText("<b>" + titleCase(object->typeName()) + "</b>"); |
83 this->objectTypeNameLabel->setText("<b>" + titleCase(object->typeName()) + "</b>"); |
74 this->objectTypeIconLabel->setPixmap(QPixmap{object->iconName()}.scaledToWidth(24)); |
84 this->objectTypeIconLabel->setPixmap(QPixmap{object->iconName()}.scaledToWidth(24)); |
75 if (object->numPoints() > 0) |
85 for (const ldraw::Property property : ldraw::ALL_PROPERTIES) |
76 { |
86 { |
77 this->polygonEditor->setObjectId(id); |
87 const QVariant value = object->getProperty(property); |
78 } |
88 const auto it = this->propertyWidgets.find(property); |
79 else |
89 if (it != this->propertyWidgets.end()) |
80 { |
90 { |
81 this->polygonEditor->clear(); |
91 it->first->setVisible(not value.isNull()); |
82 } |
92 it->second->setVisible(not value.isNull()); |
83 constexpr ldraw::Property prop = ldraw::Property::Color; |
93 if (not value.isNull()) |
84 QVariant color = object->getProperty(prop); |
94 { |
85 this->propertyWidgets[prop].first->setVisible(not color.isNull()); |
95 setValueToWidget(it->second, value); |
86 this->propertyWidgets[prop].second->setVisible(not color.isNull()); |
96 } |
87 if (not color.isNull()) |
97 } |
88 { |
|
89 static_cast<ColorIndexInput*>(this->propertyWidgets[prop].second)->setSelectedColor(color.value<ldraw::Color>()); |
|
90 } |
98 } |
91 } |
99 } |
92 else |
100 else |
93 { |
101 { |
|
102 this->objectTypeNameLabel->clear(); |
|
103 this->objectTypeIconLabel->clear(); |
94 for (auto& pair : this->propertyWidgets) |
104 for (auto& pair : this->propertyWidgets) |
95 { |
105 { |
96 pair.first->setVisible(false); |
106 pair.first->setVisible(false); |
97 pair.second->setVisible(false); |
107 pair.second->setVisible(false); |
98 } |
108 } |
99 } |
109 } |
100 } |
110 } |
101 |
111 |
102 void ObjectEditor::clear() |
112 void ObjectEditor::handleColorChange(ldraw::Color value) |
103 { |
113 { |
104 this->objectTypeNameLabel->clear(); |
114 this->handlePropertyChange(this->sender(), QVariant::fromValue(value)); |
105 this->objectTypeIconLabel->clear(); |
|
106 this->polygonEditor->clear(); |
|
107 delete this->formContainer->layout(); |
|
108 } |
115 } |
|
116 |
|
117 void ObjectEditor::handleVec3Change(const glm::vec3 &value) |
|
118 { |
|
119 this->handlePropertyChange(this->sender(), QVariant::fromValue(value)); |
|
120 } |
|
121 |
|
122 QWidget* ObjectEditor::makeEditorWidgetForProperty(ldraw::Property property) |
|
123 { |
|
124 QWidget* const parent = qobject_cast<QWidget*>(this->parent()); |
|
125 if (ldraw::traits(property).type == qMetaTypeId<ldraw::Color>()) |
|
126 { |
|
127 ColorIndexInput* colorWidget = new ColorIndexInput{this->document, {0}, parent}; |
|
128 connect(colorWidget, &ColorIndexInput::colorChanged, this, &ObjectEditor::handleColorChange); |
|
129 return colorWidget; |
|
130 } |
|
131 else if (ldraw::traits(property).type == qMetaTypeId<glm::vec3>()) |
|
132 { |
|
133 Vec3Editor* editor = new Vec3Editor{{}, parent}; |
|
134 connect(editor, &Vec3Editor::valueChanged, this, &ObjectEditor::handleVec3Change); |
|
135 return editor; |
|
136 } |
|
137 else |
|
138 { |
|
139 return nullptr; |
|
140 } |
|
141 } |
|
142 |
|
143 void ObjectEditor::handlePropertyChange(QObject *caller, const QVariant &value) |
|
144 { |
|
145 QVariant propertyVariant = caller->property("_property_id"); |
|
146 if (not propertyVariant.isNull()) |
|
147 { |
|
148 ldraw::Property const property = static_cast<ldraw::Property>(propertyVariant.toInt()); |
|
149 this->document->editModel()->setObjectProperty(this->objectId, property, value); |
|
150 } |
|
151 } |