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

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 "asset.hpp"
0010 #include "model/property/object_list_property.hpp"
0011 #include "model/shapes/layer.hpp"
0012 
0013 namespace glaxnimate::model {
0014 
0015 
0016 class Composition : public VisualNode, public AssetBase
0017 {
0018     GLAXNIMATE_OBJECT(Composition)
0019 
0020     GLAXNIMATE_PROPERTY_LIST(model::ShapeElement, shapes)
0021 
0022     GLAXNIMATE_SUBOBJECT(AnimationContainer, animation)
0023 
0024     //                  type    name    default  notify                       validate
0025     GLAXNIMATE_PROPERTY(float,  fps,         60, &Composition::fps_changed,     &Composition::validate_fps)
0026     GLAXNIMATE_PROPERTY(int,    width,      512, &Composition::width_changed,   &Composition::validate_nonzero, PropertyTraits::Visual)
0027     GLAXNIMATE_PROPERTY(int,    height,     512, &Composition::height_changed,  &Composition::validate_nonzero, PropertyTraits::Visual)
0028 
0029     Q_PROPERTY(QSize size READ size)
0030     Q_PROPERTY(QRectF rect READ rect)
0031 
0032 public:
0033     using VisualNode::VisualNode;
0034 
0035     utils::Range<Layer::ChildLayerIterator> top_level() const
0036     {
0037         return {
0038             Layer::ChildLayerIterator(&shapes, nullptr, 0),
0039             Layer::ChildLayerIterator(&shapes, nullptr, shapes.size())
0040         };
0041     }
0042 
0043     DocumentNode* docnode_child(int index) const override
0044     {
0045         return shapes[index];
0046     }
0047 
0048     int docnode_child_count() const override
0049     {
0050         return shapes.size();
0051     }
0052 
0053     int docnode_child_index(DocumentNode* dn) const override;
0054 
0055     QRectF local_bounding_rect(FrameTime t) const override;
0056 
0057     QIcon tree_icon() const override;
0058     QString type_name_human() const override;
0059     bool remove_if_unused(bool clean_lists) override;
0060     DocumentNode* docnode_parent() const override;
0061     QSize size() const { return {width.get(), height.get()}; }
0062     QRectF rect() const { return QRectF(QPointF(0, 0), size()); }
0063 
0064     Q_INVOKABLE QImage render_image(float time, QSize size = {}, const QColor& background = {}) const;
0065     Q_INVOKABLE QImage render_image() const;
0066 
0067 Q_SIGNALS:
0068     void fps_changed(float fps);
0069     void width_changed(int);
0070     void height_changed(int);
0071 
0072 private:
0073     bool validate_nonzero(int size) const
0074     {
0075         return size > 0;
0076     }
0077 
0078     bool validate_out_point(int p) const
0079     {
0080         return p > 0;
0081     }
0082 
0083     bool validate_fps(float v) const
0084     {
0085         return v > 0;
0086     }
0087 };
0088 
0089 
0090 } // namespace glaxnimate::model
0091