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 #include "group.hpp" 0008 0009 #include <QPainter> 0010 0011 #include "model/document.hpp" 0012 #include "model/shapes/styler.hpp" 0013 0014 GLAXNIMATE_OBJECT_IMPL(glaxnimate::model::Group) 0015 0016 0017 glaxnimate::model::Group::Group(Document* document) 0018 : Ctor(document) 0019 { 0020 connect(transform.get(), &Object::property_changed, 0021 this, &Group::on_transform_matrix_changed); 0022 } 0023 0024 void glaxnimate::model::Group::on_paint(QPainter* painter, glaxnimate::model::FrameTime time, glaxnimate::model::VisualNode::PaintMode, glaxnimate::model::Modifier*) const 0025 { 0026 painter->setOpacity( 0027 painter->opacity() * opacity.get_at(time) 0028 ); 0029 } 0030 0031 void glaxnimate::model::Group::on_transform_matrix_changed() 0032 { 0033 propagate_bounding_rect_changed(); 0034 Q_EMIT local_transform_matrix_changed(local_transform_matrix(time())); 0035 propagate_transform_matrix_changed(transform_matrix(time()), group_transform_matrix(time())); 0036 } 0037 0038 void glaxnimate::model::Group::add_shapes(glaxnimate::model::FrameTime t, math::bezier::MultiBezier & bez, const QTransform& parent_transform) const 0039 { 0040 QTransform trans = transform.get()->transform_matrix(t, auto_orient.get()) * parent_transform; 0041 for ( const auto& ch : utils::Range(shapes.begin(), shapes.past_first_modifier()) ) 0042 { 0043 ch->add_shapes(t, bez, trans); 0044 } 0045 } 0046 0047 QRectF glaxnimate::model::Group::local_bounding_rect(FrameTime t) const 0048 { 0049 if ( shapes.empty() ) 0050 return owner_composition()->rect(); 0051 return shapes.bounding_rect(t); 0052 } 0053 0054 QTransform glaxnimate::model::Group::local_transform_matrix(glaxnimate::model::FrameTime t) const 0055 { 0056 return transform.get()->transform_matrix(t, auto_orient.get()); 0057 } 0058 0059 0060 QPainterPath glaxnimate::model::Group::to_painter_path_impl(glaxnimate::model::FrameTime t) const 0061 { 0062 QPainterPath path; 0063 for ( const auto& ch : utils::Range(shapes.begin(), shapes.past_first_modifier()) ) 0064 { 0065 if ( ch->is_instance<glaxnimate::model::Styler>() || ch->is_instance<glaxnimate::model::Group>() ) 0066 path.addPath(ch->to_clip(t)); 0067 } 0068 0069 return path; 0070 } 0071 0072 0073 QPainterPath glaxnimate::model::Group::to_clip(FrameTime t) const 0074 { 0075 return transform.get()->transform_matrix(t, auto_orient.get()).map(to_painter_path(t)); 0076 } 0077 0078 std::unique_ptr<glaxnimate::model::ShapeElement> glaxnimate::model::Group::to_path() const 0079 { 0080 auto clone = std::make_unique<glaxnimate::model::Group>(document()); 0081 0082 for ( BaseProperty* prop : properties() ) 0083 { 0084 if ( prop != &shapes ) 0085 clone->get_property(prop->name())->assign_from(prop); 0086 } 0087 0088 for ( const auto& shape : shapes ) 0089 { 0090 clone->shapes.insert(shape->to_path()); 0091 if ( shape->is_instance<glaxnimate::model::Modifier>() ) 0092 break; 0093 } 0094 0095 return clone; 0096 } 0097 0098 void glaxnimate::model::Group::on_graphics_changed() 0099 { 0100 ShapeElement::on_graphics_changed(); 0101 0102 for ( const auto& shape : shapes ) 0103 { 0104 if ( shape->is_instance<glaxnimate::model::ShapeOperator>() ) 0105 shape->on_graphics_changed(); 0106 } 0107 0108 } 0109 0110 0111 void glaxnimate::model::Group::on_composition_changed(model::Composition*, model::Composition* new_comp) 0112 { 0113 for ( const auto& shape : shapes ) 0114 { 0115 shape->refresh_owner_composition(new_comp); 0116 } 0117 }