diff --git a/common/camera.cpp b/common/camera.cpp index 8134ee5a..a5bfa74b 100644 --- a/common/camera.cpp +++ b/common/camera.cpp @@ -566,7 +566,7 @@ void lcCamera::DrawInterface(lcContext* Context, const lcScene& Scene) const } } -bool lcCamera::GetBoolProperty(lcObjectPropertyId PropertyId) const +QVariant lcCamera::GetPropertyValue(lcObjectPropertyId PropertyId) const { switch (PropertyId) { @@ -617,11 +617,13 @@ bool lcCamera::GetBoolProperty(lcObjectPropertyId PropertyId) const break; } - return false; + return QVariant(); } -bool lcCamera::SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) +bool lcCamera::SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) { + Q_UNUSED(Step); + Q_UNUSED(AddKey); Q_UNUSED(Value); switch (PropertyId) diff --git a/common/camera.h b/common/camera.h index c33330d4..89af7b95 100644 --- a/common/camera.h +++ b/common/camera.h @@ -271,8 +271,8 @@ public: void RayTest(lcObjectRayTest& ObjectRayTest) const override; void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override; void DrawInterface(lcContext* Context, const lcScene& Scene) const override; - bool GetBoolProperty(lcObjectPropertyId PropertyId) const override; - bool SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) override; + QVariant GetPropertyValue(lcObjectPropertyId PropertyId) const override; + bool SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) override; bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override; bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) override; void RemoveKeyFrames() override; diff --git a/common/lc_math.h b/common/lc_math.h index fb89a6b3..4723601d 100644 --- a/common/lc_math.h +++ b/common/lc_math.h @@ -66,6 +66,16 @@ public: int x, y; }; +inline bool operator==(const lcVector2i& a, const lcVector2i& b) +{ + return a.x == b.x && a.y == b.y; +} + +inline bool operator!=(const lcVector2i& a, const lcVector2i& b) +{ + return a.x != b.x || a.y != b.y; +} + class lcVector2 { public: @@ -2381,3 +2391,5 @@ inline lcVector4 lcAlgorithmicEdgeColor(const lcVector3& Value, const float Valu return lcVector4(lcLinearToSRGB(rgbf), 1.0f); } + +Q_DECLARE_METATYPE(lcVector3); diff --git a/common/lc_model.cpp b/common/lc_model.cpp index e0e13947..ede50e46 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -3184,16 +3184,6 @@ void lcModel::SetLightType(lcLight* Light, lcLightType LightType) UpdateAllViews(); } -void lcModel::SetLightColor(lcLight* Light, const lcVector3& Color) -{ - Light->SetColor(Color, mCurrentStep, gMainWindow->GetAddKeys()); - Light->UpdatePosition(mCurrentStep); - - SaveCheckpoint(tr("Changing Light Color")); - gMainWindow->UpdateSelectedObjects(false); - UpdateAllViews(); -} - void lcModel::SetLightAttenuationDistance(lcLight* Light, float Distance) { Light->SetAttenuationDistance(Distance, mCurrentStep, gMainWindow->GetAddKeys()); @@ -3288,13 +3278,13 @@ void lcModel::SetLightPower(lcLight* Light, float Power) UpdateAllViews(); } -void lcModel::SetObjectsBoolProperty(const lcArray& Objects, lcObjectPropertyId PropertyId, bool Value) +void lcModel::SetObjectsProperty(const lcArray& Objects, lcObjectPropertyId PropertyId, QVariant Value) { bool Modified = false; for (lcObject* Object : Objects) { - bool ObjectModified = Object->SetBoolProperty(PropertyId, Value); + bool ObjectModified = Object->SetPropertyValue(PropertyId, mCurrentStep, gMainWindow->GetAddKeys(), Value); if (ObjectModified) { diff --git a/common/lc_model.h b/common/lc_model.h index 38d63218..f1d0b34f 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -365,7 +365,7 @@ public: void SetSelectedPiecesStepShow(lcStep Step); void SetSelectedPiecesStepHide(lcStep Step); - void SetObjectsBoolProperty(const lcArray& Objects, lcObjectPropertyId PropertyId, bool Value); + void SetObjectsProperty(const lcArray& Objects, lcObjectPropertyId PropertyId, QVariant Value); void SetCameraOrthographic(lcCamera* Camera, bool Ortho); void SetCameraFOV(lcCamera* Camera, float FOV); @@ -374,7 +374,6 @@ public: void SetCameraName(lcCamera* Camera, const QString& Name); void SetLightType(lcLight* Light, lcLightType LightType); - void SetLightColor(lcLight* Light, const lcVector3& Color); void SetLightAttenuationDistance(lcLight* Light, float Distance); void SetLightAttenuationPower(lcLight* Light, float Power); void SetSpotLightConeAngle(lcLight* Light, float Angle); diff --git a/common/lc_objectproperty.cpp b/common/lc_objectproperty.cpp index 8966883a..2aaf3711 100644 --- a/common/lc_objectproperty.cpp +++ b/common/lc_objectproperty.cpp @@ -4,7 +4,7 @@ #define LC_OBJECT_PROPERTY(T) \ template void lcObjectProperty::Update(lcStep Step); \ - template void lcObjectProperty::ChangeKey(const T& Value, lcStep Step, bool AddKey); \ + template bool lcObjectProperty::ChangeKey(const T& Value, lcStep Step, bool AddKey); \ template void lcObjectProperty::InsertTime(lcStep Start, lcStep Time); \ template void lcObjectProperty::RemoveTime(lcStep Start, lcStep Time); \ template bool lcObjectProperty::HasKeyFrame(lcStep Time) const; \ @@ -75,13 +75,16 @@ void lcObjectProperty::Update(lcStep Step) } template -void lcObjectProperty::ChangeKey(const T& Value, lcStep Step, bool AddKey) +bool lcObjectProperty::ChangeKey(const T& Value, lcStep Step, bool AddKey) { if (!AddKey && mKeys.empty()) { + if (mValue == Value) + return false; + mValue = Value; - return; + return true; } for (typename std::vector>::iterator KeyIt = mKeys.begin(); KeyIt != mKeys.end(); KeyIt++) @@ -90,24 +93,40 @@ void lcObjectProperty::ChangeKey(const T& Value, lcStep Step, bool AddKey) continue; if (KeyIt->Step == Step) + { + if (KeyIt->Value == Value) + return false; + KeyIt->Value = Value; + } else if (AddKey) mKeys.insert(KeyIt, lcObjectPropertyKey{ Step, Value }); else if (KeyIt == mKeys.begin()) + { + if (KeyIt->Value == Value) + return false; + KeyIt->Value = Value; + } else { KeyIt = KeyIt - 1; + + if (KeyIt->Value == Value) + return false; + KeyIt->Value = Value; } - return; + return true; } if (AddKey || mKeys.empty()) mKeys.emplace_back(lcObjectPropertyKey{ Step, Value }); else mKeys.back().Value = Value; + + return true; } template diff --git a/common/lc_objectproperty.h b/common/lc_objectproperty.h index 944f566d..cf4b27aa 100644 --- a/common/lc_objectproperty.h +++ b/common/lc_objectproperty.h @@ -82,7 +82,7 @@ public: } void Update(lcStep Step); - void ChangeKey(const T& Value, lcStep Step, bool AddKey); + bool ChangeKey(const T& Value, lcStep Step, bool AddKey); void InsertTime(lcStep Start, lcStep Time); void RemoveTime(lcStep Start, lcStep Time); bool HasKeyFrame(lcStep Time) const; diff --git a/common/lc_propertieswidget.cpp b/common/lc_propertieswidget.cpp index 61cbe9d3..007300b0 100644 --- a/common/lc_propertieswidget.cpp +++ b/common/lc_propertieswidget.cpp @@ -169,46 +169,48 @@ void lcPropertiesWidget::BoolChanged() return; const bool Value = Widget->isChecked(); - Model->SetObjectsBoolProperty(mFocusObject ? lcArray{ mFocusObject } : mSelection, PropertyId, Value); + Model->SetObjectsProperty(mFocusObject ? lcArray{ mFocusObject } : mSelection, PropertyId, Value); } void lcPropertiesWidget::UpdateBool(lcObjectPropertyId PropertyId, bool DefaultValue) { - QCheckBox* Widget = qobject_cast(mPropertyWidgets[static_cast(PropertyId)].Editor); + QCheckBox* CheckBox = qobject_cast(mPropertyWidgets[static_cast(PropertyId)].Editor); - if (Widget) + if (!CheckBox) + return; + + QSignalBlocker Blocker(CheckBox); + bool Value = DefaultValue; + bool Partial = false; + + if (mFocusObject) + Value = mFocusObject->GetPropertyValue(PropertyId).toBool(); + else { - QSignalBlocker Blocker(Widget); + bool First = true; - if (mFocusObject) - Widget->setChecked(mFocusObject->GetBoolProperty(PropertyId)); - else + for (const lcObject* Object : mSelection) { - bool First = true, Partial = false, Value = DefaultValue; + const bool ObjectValue = Object->GetPropertyValue(PropertyId).toBool(); - for (const lcObject* Object : mSelection) + if (First) { - const bool ObjectValue = Object->GetBoolProperty(PropertyId); - - if (First) - { - Value = ObjectValue; - First = false; - } - else if (Value != ObjectValue) - { - Partial = true; - break; - } + Value = ObjectValue; + First = false; + } + else if (Value != ObjectValue) + { + Partial = true; + break; } - - if (Partial) - Widget->setCheckState(Qt::PartiallyChecked); - else - Widget->setCheckState(Value ? Qt::Checked : Qt::Unchecked); } } + if (Partial) + CheckBox->setCheckState(Qt::PartiallyChecked); + else + CheckBox->setCheckState(Value ? Qt::Checked : Qt::Unchecked); + UpdateKeyFrameWidget(PropertyId); } @@ -715,33 +717,75 @@ void lcPropertiesWidget::AddStringListProperty(lcObjectPropertyId PropertyId, co void lcPropertiesWidget::ColorButtonClicked() { - lcLight* Light = dynamic_cast(mFocusObject); QToolButton* ColorButton = qobject_cast(sender()); - lcModel* Model = gMainWindow->GetActiveModel(); + lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId(ColorButton); - if (!ColorButton || !Light || !Model) + if (PropertyId == lcObjectPropertyId::Count) return; - QColor Color = QColorDialog::getColor(lcQColorFromVector3(Light->GetColor()), this, tr("Select Light Color")); + lcLight* Light = dynamic_cast(mFocusObject); + lcVector3 InitialValue(0.5f, 0.5f, 0.5f); + + if (Light) + InitialValue = Light->GetColor(); + + QColor Color = QColorDialog::getColor(lcQColorFromVector3(InitialValue), this, tr("Select Light Color")); if (!Color.isValid()) return; - Model->SetLightColor(Light, lcVector3FromQColor(Color)); + lcModel* Model = gMainWindow->GetActiveModel(); + + if (!Model) + return; + + const lcVector3 Value = lcVector3FromQColor(Color); + Model->SetObjectsProperty(mFocusObject ? lcArray{ mFocusObject } : mSelection, PropertyId, QVariant::fromValue(Value)); } -void lcPropertiesWidget::UpdateColor(lcObjectPropertyId PropertyId, QColor Color) +void lcPropertiesWidget::UpdateColor(lcObjectPropertyId PropertyId, const lcVector3& DefaultValue) { QToolButton* ColorButton = qobject_cast(mPropertyWidgets[static_cast(PropertyId)].Editor); if (!ColorButton) return; + QSignalBlocker Blocker(ColorButton); + lcVector3 Value = DefaultValue; + bool Partial = false; + + if (mFocusObject) + Value = mFocusObject->GetPropertyValue(PropertyId).value(); + else + { + bool First = true; + + for (const lcObject* Object : mSelection) + { + const lcVector3 ObjectValue = Object->GetPropertyValue(PropertyId).value(); + + if (First) + { + Value = ObjectValue; + First = false; + } + else if (Value != ObjectValue) + { + Partial = true; + break; + } + } + } + + if (Partial) + Value = lcVector3(0.5f, 0.5f, 0.5f); + + QColor Color = lcQColorFromVector3(Value); QPixmap Pixmap(14, 14); Pixmap.fill(Color); ColorButton->setIcon(Pixmap); - ColorButton->setText(QString(" ") + Color.name()); + ColorButton->setText(Partial ? tr(" Multiple Colors") : QString(" ") + Color.name()); UpdateKeyFrameWidget(PropertyId); } @@ -1223,7 +1267,6 @@ void lcPropertiesWidget::SetLight(const lcArray& Selection, lcObject* QString Name; lcLightType LightType = lcLightType::Point; - QColor Color(Qt::white); lcLightAreaShape LightAreaShape = lcLightAreaShape::Rectangle; lcVector2 LightSize(0.0f, 0.0f); lcVector2i AreaGrid(2, 2); @@ -1238,7 +1281,6 @@ void lcPropertiesWidget::SetLight(const lcArray& Selection, lcObject* { Name = Light->GetName(); LightType = Light->GetLightType(); - Color = lcQColorFromVector3(Light->GetColor()); Position = Light->GetPosition(); Rotation = lcMatrix44ToEulerAngles(Light->GetWorldMatrix()) * LC_RTOD; @@ -1256,7 +1298,7 @@ void lcPropertiesWidget::SetLight(const lcArray& Selection, lcObject* UpdateString(lcObjectPropertyId::LightName, Name); UpdateStringList(lcObjectPropertyId::LightType, static_cast(LightType)); - UpdateColor(lcObjectPropertyId::LightColor, Color); + UpdateColor(lcObjectPropertyId::LightColor, lcVector3(1.0f, 1.0f, 1.0f)); UpdateFloat(lcObjectPropertyId::LightPower, Power); UpdateBool(lcObjectPropertyId::LightCastShadow, true); diff --git a/common/lc_propertieswidget.h b/common/lc_propertieswidget.h index 4a6247e1..b2f6ce71 100644 --- a/common/lc_propertieswidget.h +++ b/common/lc_propertieswidget.h @@ -102,7 +102,7 @@ protected: void UpdateStepNumber(lcObjectPropertyId PropertyId, lcStep Step, lcStep Min, lcStep Max); void UpdateString(lcObjectPropertyId PropertyId, const QString& Text); void UpdateStringList(lcObjectPropertyId PropertyId, int ListIndex); - void UpdateColor(lcObjectPropertyId PropertyId, QColor Color); + void UpdateColor(lcObjectPropertyId PropertyId, const lcVector3& DefaultValue); void UpdatePieceColor(lcObjectPropertyId PropertyId, int ColorIndex); void UpdatePieceId(lcObjectPropertyId PropertyId, const QString& Name); diff --git a/common/light.cpp b/common/light.cpp index f8102bfb..5073bd9a 100644 --- a/common/light.cpp +++ b/common/light.cpp @@ -499,9 +499,9 @@ bool lcLight::SetLightType(lcLightType LightType) return true; } -void lcLight::SetColor(const lcVector3& Color, lcStep Step, bool AddKey) +bool lcLight::SetColor(const lcVector3& Color, lcStep Step, bool AddKey) { - mColor.ChangeKey(Color, Step, AddKey); + return mColor.ChangeKey(Color, Step, AddKey); } void lcLight::SetAttenuationDistance(float Distance, lcStep Step, bool AddKey) @@ -1038,7 +1038,7 @@ void lcLight::DrawCone(lcContext* Context, float TargetDistance) const Context->DrawIndexedPrimitives(GL_LINES, DrawPenumbra ? (ConeEdges * 2 + 4) * 2 : (ConeEdges + 4) * 2, GL_UNSIGNED_SHORT, 0); } -bool lcLight::GetBoolProperty(lcObjectPropertyId PropertyId) const +QVariant lcLight::GetPropertyValue(lcObjectPropertyId PropertyId) const { switch (PropertyId) { @@ -1062,7 +1062,11 @@ bool lcLight::GetBoolProperty(lcObjectPropertyId PropertyId) const case lcObjectPropertyId::CameraUpZ: case lcObjectPropertyId::LightName: case lcObjectPropertyId::LightType: + break; + case lcObjectPropertyId::LightColor: + return QVariant::fromValue(GetColor()); + case lcObjectPropertyId::LightPower: break; @@ -1093,10 +1097,10 @@ bool lcLight::GetBoolProperty(lcObjectPropertyId PropertyId) const break; } - return false; + return QVariant(); } -bool lcLight::SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) +bool lcLight::SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) { switch (PropertyId) { @@ -1120,12 +1124,16 @@ bool lcLight::SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) case lcObjectPropertyId::CameraUpZ: case lcObjectPropertyId::LightName: case lcObjectPropertyId::LightType: + break; + case lcObjectPropertyId::LightColor: + return SetColor(Value.value(), Step, AddKey); + case lcObjectPropertyId::LightPower: break; case lcObjectPropertyId::LightCastShadow: - return SetCastShadow(Value); + return SetCastShadow(Value.toBool()); case lcObjectPropertyId::LightAttenuationDistance: case lcObjectPropertyId::LightAttenuationPower: diff --git a/common/light.h b/common/light.h index 2a3c475a..1524adff 100644 --- a/common/light.h +++ b/common/light.h @@ -213,8 +213,8 @@ public: void RayTest(lcObjectRayTest& ObjectRayTest) const override; void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override; void DrawInterface(lcContext* Context, const lcScene& Scene) const override; - bool GetBoolProperty(lcObjectPropertyId PropertyId) const override; - bool SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) override; + QVariant GetPropertyValue(lcObjectPropertyId PropertyId) const override; + bool SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) override; bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override; bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) override; void RemoveKeyFrames() override; @@ -227,7 +227,7 @@ public: return (mState & LC_LIGHT_HIDDEN) == 0; } - void SetColor(const lcVector3& Color, lcStep Step, bool AddKey); + bool SetColor(const lcVector3& Color, lcStep Step, bool AddKey); lcVector3 GetColor() const { diff --git a/common/object.cpp b/common/object.cpp index 9ddc620f..16174402 100644 --- a/common/object.cpp +++ b/common/object.cpp @@ -34,7 +34,11 @@ QString lcObject::GetCheckpointString(lcObjectPropertyId PropertyId) case lcObjectPropertyId::CameraUpZ: case lcObjectPropertyId::LightName: case lcObjectPropertyId::LightType: + break; + case lcObjectPropertyId::LightColor: + return QT_TRANSLATE_NOOP("Checkpoint", "Changing Light Color"); + case lcObjectPropertyId::LightPower: break; diff --git a/common/object.h b/common/object.h index 1e248cab..7308ca0f 100644 --- a/common/object.h +++ b/common/object.h @@ -103,8 +103,8 @@ public: virtual void RayTest(lcObjectRayTest& ObjectRayTest) const = 0; virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const = 0; virtual void DrawInterface(lcContext* Context, const lcScene& Scene) const = 0; - virtual bool GetBoolProperty(lcObjectPropertyId PropertyId) const = 0; - virtual bool SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) = 0; + virtual QVariant GetPropertyValue(lcObjectPropertyId PropertyId) const = 0; + virtual bool SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) = 0; virtual bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const = 0; virtual bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) = 0; virtual void RemoveKeyFrames() = 0; diff --git a/common/piece.cpp b/common/piece.cpp index f6275d3c..32eaa829 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -646,7 +646,7 @@ void lcPiece::DrawInterface(lcContext* Context, const lcScene& Scene) const } } -bool lcPiece::GetBoolProperty(lcObjectPropertyId PropertyId) const +QVariant lcPiece::GetPropertyValue(lcObjectPropertyId PropertyId) const { switch (PropertyId) { @@ -697,11 +697,13 @@ bool lcPiece::GetBoolProperty(lcObjectPropertyId PropertyId) const break; } - return false; + return QVariant(); } -bool lcPiece::SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) +bool lcPiece::SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) { + Q_UNUSED(Step); + Q_UNUSED(AddKey); Q_UNUSED(Value); switch (PropertyId) diff --git a/common/piece.h b/common/piece.h index 0694a4b1..028765a0 100644 --- a/common/piece.h +++ b/common/piece.h @@ -130,8 +130,8 @@ public: void RayTest(lcObjectRayTest& ObjectRayTest) const override; void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override; void DrawInterface(lcContext* Context, const lcScene& Scene) const override; - bool GetBoolProperty(lcObjectPropertyId PropertyId) const override; - bool SetBoolProperty(lcObjectPropertyId PropertyId, bool Value) override; + QVariant GetPropertyValue(lcObjectPropertyId PropertyId) const override; + bool SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) override; bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override; bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) override; void RemoveKeyFrames() override;