File indexing completed on 2025-02-02 04:11:05

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #pragma once
0008 #include "model/object.hpp"
0009 #include "model/property/property.hpp"
0010 
0011 #define GLAXNIMATE_SUBOBJECT(type, name)                    \
0012 public:                                                     \
0013     SubObjectProperty<type> name{this, kli18n(#name)};      \
0014     type* get_##name() { return name.get(); }               \
0015 private:                                                    \
0016     Q_PROPERTY(type* name READ get_##name)                  \
0017     // macro end
0018 
0019 namespace glaxnimate::model {
0020 
0021 class SubObjectPropertyBase : public BaseProperty
0022 {
0023 public:
0024     SubObjectPropertyBase(Object* obj, const KLazyLocalizedString& name)
0025         : BaseProperty(obj, name, {PropertyTraits::Object})
0026     {}
0027 
0028     virtual const model::Object* sub_object() const = 0;
0029     virtual model::Object* sub_object() = 0;
0030 };
0031 
0032 template<class Type>
0033 class SubObjectProperty : public SubObjectPropertyBase
0034 {
0035 public:
0036     SubObjectProperty(Object* obj, const KLazyLocalizedString& name)
0037         : SubObjectPropertyBase(obj, name),
0038         sub_obj(obj->document())
0039     {}
0040 
0041     const Type* operator->() const
0042     {
0043         return &sub_obj;
0044     }
0045 
0046     Type* operator->()
0047     {
0048         return &sub_obj;
0049     }
0050 
0051     QVariant value() const override
0052     {
0053         return QVariant::fromValue(const_cast<Type*>(&sub_obj));
0054     }
0055 
0056     bool valid_value(const QVariant & v) const override
0057     {
0058         return v.value<Type*>();
0059     }
0060 
0061     bool set_value(const QVariant& val) override
0062     {
0063         if ( !val.canConvert<Type*>() )
0064             return false;
0065 
0066         if ( Type* t = val.value<Type*>() )
0067             return set_clone(t);
0068 
0069         return false;
0070     }
0071 
0072     Type* set_clone(Type* object)
0073     {
0074         if ( !object )
0075             return nullptr;
0076 
0077         sub_obj.assign_from(object);
0078         return &sub_obj;
0079     }
0080 
0081     Type* get() { return &sub_obj; }
0082     const Type* get() const { return &sub_obj; }
0083 
0084     model::Object * sub_object() override { return &sub_obj; }
0085     const model::Object * sub_object() const override { return &sub_obj; }
0086 
0087 
0088     void set_time(FrameTime t) override
0089     {
0090         sub_obj.set_time(t);
0091     }
0092 
0093     void transfer(Document* doc) override
0094     {
0095         sub_obj.transfer(doc);
0096     }
0097 
0098     void stretch_time(qreal multiplier) override
0099     {
0100         sub_obj.stretch_time(multiplier);
0101     }
0102 
0103 private:
0104     Type sub_obj;
0105 };
0106 
0107 } // namespace glaxnimate::model