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

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 
0009 #include "group.hpp"
0010 #include "model/property/reference_property.hpp"
0011 #include "model/animation_container.hpp"
0012 #include "model/mask_settings.hpp"
0013 
0014 namespace glaxnimate::model {
0015 
0016 class Layer : public StaticOverrides<Layer, Group>
0017 {
0018     GLAXNIMATE_OBJECT(Layer)
0019     GLAXNIMATE_SUBOBJECT(AnimationContainer, animation)
0020     GLAXNIMATE_PROPERTY_REFERENCE(Layer, parent, &Layer::valid_parents, &Layer::is_valid_parent, &Layer::docnode_on_update_group)
0021     /**
0022      * \brief Whether the layer will be rendered / exported in other formats
0023      */
0024     GLAXNIMATE_PROPERTY(bool, render, true)
0025     GLAXNIMATE_SUBOBJECT(MaskSettings, mask)
0026 
0027 public:
0028     class ChildLayerIterator
0029     {
0030     public:
0031         using value_type = VisualNode;
0032         using reference = value_type&;
0033         using pointer = value_type*;
0034         using difference_type = int;
0035         using iterator_category = std::forward_iterator_tag;
0036 
0037         ChildLayerIterator& operator++()
0038         {
0039             ++index;
0040             find_first();
0041             return *this;
0042         }
0043 
0044         pointer operator*() const;
0045         pointer operator->() const;
0046 
0047         bool operator==(const ChildLayerIterator& other) const
0048         {
0049             return comp == other.comp && parent == other.parent && index == other.index;
0050         }
0051 
0052         bool operator!=(const ChildLayerIterator& other) const
0053         {
0054             return !(*this == other);
0055         }
0056 
0057     private:
0058         ChildLayerIterator(const ShapeListProperty* comp, const Layer* parent, int index)
0059         : comp(comp),
0060           parent(parent),
0061           index(index)
0062         {
0063             find_first();
0064         }
0065 
0066         void find_first();
0067         friend Layer;
0068         friend Composition;
0069         const ShapeListProperty* comp;
0070         const Layer* parent;
0071         int index;
0072     };
0073 
0074     using Ctor::Ctor;
0075 
0076     VisualNode* docnode_group_parent() const override;
0077     int docnode_group_child_count() const override;
0078     VisualNode* docnode_group_child(int index) const override;
0079     QIcon tree_icon() const override;
0080     static QIcon static_tree_icon();
0081     static QString static_type_name_human() { return i18n("Layer"); }
0082     void set_time(FrameTime t) override;
0083 
0084     /**
0085      * \brief Returns the (frame) time relative to this layer
0086      *
0087      * Useful for stretching / remapping etc.
0088      * Always use this to get animated property values,
0089      * even if currently it doesn't do anything
0090      */
0091     FrameTime relative_time(FrameTime time) const { return time; }
0092 
0093     bool is_ancestor_of(const Layer* other) const;
0094 
0095     bool is_top_level() const;
0096 
0097     void paint(QPainter*, FrameTime, PaintMode, model::Modifier* modifier) const override;
0098 
0099     QPainterPath to_clip(model::FrameTime t) const override;
0100 
0101     std::unique_ptr<ShapeElement> to_path() const override;
0102 
0103     bool is_valid_parent(DocumentNode* node) const;
0104 
0105 protected:
0106     QPainterPath to_painter_path_impl(model::FrameTime t) const override;
0107 
0108 private:
0109     std::vector<DocumentNode*> valid_parents() const;
0110 };
0111 
0112 } // namespace glaxnimate::model