diff --git a/docs/tutorials/otio-serialized-schema-only-fields.md b/docs/tutorials/otio-serialized-schema-only-fields.md index 09a4c2b25..72ba593ce 100644 --- a/docs/tutorials/otio-serialized-schema-only-fields.md +++ b/docs/tutorials/otio-serialized-schema-only-fields.md @@ -289,6 +289,7 @@ parameters: ### Transition.1 parameters: +- *enabled* - *in_offset* - *metadata* - *name* diff --git a/docs/tutorials/otio-serialized-schema.md b/docs/tutorials/otio-serialized-schema.md index 73919a094..4fdb4e600 100644 --- a/docs/tutorials/otio-serialized-schema.md +++ b/docs/tutorials/otio-serialized-schema.md @@ -665,6 +665,7 @@ dissolve or wipe. ``` parameters: +- *enabled*: If true, a Transition contributes to compositions. For example, when a transition is ``enabled=false`` the transition is ignored and the adjacent clips are cut together with no transition. - *in_offset*: Amount of the previous clip this transition overlaps, exclusive. - *metadata*: - *name*: diff --git a/src/opentimelineio/transition.cpp b/src/opentimelineio/transition.cpp index 8a41c5096..a29cb4d5b 100644 --- a/src/opentimelineio/transition.cpp +++ b/src/opentimelineio/transition.cpp @@ -11,11 +11,13 @@ Transition::Transition( std::string const& transition_type, RationalTime in_offset, RationalTime out_offset, - AnyDictionary const& metadata) + AnyDictionary const& metadata, + bool enabled) : Parent(name, metadata) , _transition_type(transition_type) , _in_offset(in_offset) , _out_offset(out_offset) + , _enabled(enabled) {} Transition::~Transition() @@ -33,6 +35,7 @@ Transition::read_from(Reader& reader) return reader.read("in_offset", &_in_offset) && reader.read("out_offset", &_out_offset) && reader.read("transition_type", &_transition_type) + && reader.read_if_present("enabled", &_enabled) && Parent::read_from(reader); } @@ -43,6 +46,7 @@ Transition::write_to(Writer& writer) const writer.write("in_offset", _in_offset); writer.write("out_offset", _out_offset); writer.write("transition_type", _transition_type); + writer.write("enabled", _enabled); } RationalTime diff --git a/src/opentimelineio/transition.h b/src/opentimelineio/transition.h index c5c5d52fb..2dd75cf15 100644 --- a/src/opentimelineio/transition.h +++ b/src/opentimelineio/transition.h @@ -41,7 +41,8 @@ class OTIO_API_TYPE Transition : public Composable std::string const& transition_type = std::string(), RationalTime in_offset = RationalTime(), RationalTime out_offset = RationalTime(), - AnyDictionary const& metadata = AnyDictionary()); + AnyDictionary const& metadata = AnyDictionary(), + bool enabled = true); bool overlapping() const override; @@ -72,6 +73,12 @@ class OTIO_API_TYPE Transition : public Composable _out_offset = out_offset; } + /// @brief Return whether the transition is enabled. + bool enabled() const { return _enabled; } + + /// @brief Set whether the transition is enabled. + void set_enabled(bool enabled) { _enabled = enabled; } + RationalTime duration(ErrorStatus* error_status = nullptr) const override; /// @brief Return the range in the parent's time. @@ -91,6 +98,7 @@ class OTIO_API_TYPE Transition : public Composable private: std::string _transition_type; RationalTime _in_offset, _out_offset; + bool _enabled; }; }} // namespace opentimelineio::OPENTIMELINEIO_VERSION_NS diff --git a/src/py-opentimelineio/opentimelineio-bindings/otio_serializableObjects.cpp b/src/py-opentimelineio/opentimelineio-bindings/otio_serializableObjects.cpp index 4268a4cf6..d2c837f60 100644 --- a/src/py-opentimelineio/opentimelineio-bindings/otio_serializableObjects.cpp +++ b/src/py-opentimelineio/opentimelineio-bindings/otio_serializableObjects.cpp @@ -721,19 +721,22 @@ An object that can be composed within a :class:`~Composition` (such as :class:`~ std::string const& transition_type, RationalTime in_offset, RationalTime out_offset, - py::object metadata) { + py::object metadata, + py::bool_ enabled) { return new Transition( name, transition_type, in_offset, out_offset, - py_to_any_dictionary(metadata)); + py_to_any_dictionary(metadata), + enabled); }), py::arg_v("name"_a = std::string()), "transition_type"_a = std::string(), "in_offset"_a = RationalTime(), "out_offset"_a = RationalTime(), - py::arg_v("metadata"_a = py::none())) + py::arg_v("metadata"_a = py::none()), + "enabled"_a = true) .def_property( "transition_type", &Transition::transition_type, @@ -749,6 +752,11 @@ An object that can be composed within a :class:`~Composition` (such as :class:`~ &Transition::out_offset, &Transition::set_out_offset, "Amount of the next clip this transition overlaps, exclusive.") + .def_property( + "enabled", + &Transition::enabled, + &Transition::set_enabled, + "If true, a Transition contributes to compositions. For example, when a transition is ``enabled=false`` the transition is ignored and the adjacent clips are cut together with no transition.") .def( "duration", [](Transition* t) { return t->duration(ErrorStatusHandler()); }) diff --git a/src/py-opentimelineio/opentimelineio/schema/transition.py b/src/py-opentimelineio/opentimelineio/schema/transition.py index a344b61ae..8e9d7b3a0 100644 --- a/src/py-opentimelineio/opentimelineio/schema/transition.py +++ b/src/py-opentimelineio/opentimelineio/schema/transition.py @@ -7,12 +7,13 @@ @add_method(_otio.Transition) def __str__(self): - return 'Transition("{}", "{}", {}, {}, {})'.format( + return 'Transition("{}", "{}", {}, {}, {}, {})'.format( self.name, self.transition_type, self.in_offset, self.out_offset, - self.metadata + self.metadata, + self.enabled ) @@ -24,12 +25,14 @@ def __repr__(self): 'transition_type={}, ' 'in_offset={}, ' 'out_offset={}, ' - 'metadata={}' + 'metadata={}, ' + 'enabled={}' ')'.format( repr(self.name), repr(self.transition_type), repr(self.in_offset), repr(self.out_offset), repr(self.metadata), + repr(self.enabled) ) ) diff --git a/tests/baselines/empty_transition.json b/tests/baselines/empty_transition.json index 6858ac758..a4656754d 100644 --- a/tests/baselines/empty_transition.json +++ b/tests/baselines/empty_transition.json @@ -1,5 +1,6 @@ { "OTIO_SCHEMA": "Transition.1", + "enabled": true, "metadata": {}, "name": "", "transition_type": "", diff --git a/tests/test_transition.py b/tests/test_transition.py index fdf78c1c1..1c00ee9b4 100644 --- a/tests/test_transition.py +++ b/tests/test_transition.py @@ -16,11 +16,13 @@ def test_constructor(self): transition_type="SMPTE.Dissolve", metadata={ "foo": "bar" - } + }, + enabled=False ) self.assertEqual(trx.transition_type, "SMPTE.Dissolve") self.assertEqual(trx.name, "AtoB") self.assertEqual(trx.metadata, {"foo": "bar"}) + self.assertEqual(trx.enabled, False) def test_serialize(self): trx = otio.schema.Transition( @@ -28,7 +30,8 @@ def test_serialize(self): transition_type="SMPTE.Dissolve", metadata={ "foo": "bar" - } + }, + enabled=False ) encoded = otio.adapters.otio_json.write_to_string(trx) decoded = otio.adapters.otio_json.read_from_string(encoded) @@ -47,6 +50,7 @@ def test_stringify(self): '"{}", ' '{}, ' "{}, " + "{}, " "{}" ")".format( str(trx.name), @@ -54,6 +58,7 @@ def test_stringify(self): str(trx.in_offset), str(trx.out_offset), str(trx.metadata), + str(trx.enabled) ) ) @@ -64,13 +69,15 @@ def test_stringify(self): "transition_type={}, " "in_offset={}, " "out_offset={}, " - "metadata={}" + "metadata={}, " + "enabled={}" ")".format( repr(trx.name), repr(trx.transition_type), repr(trx.in_offset), repr(trx.out_offset), repr(trx.metadata), + repr(trx.enabled) ) ) @@ -85,6 +92,9 @@ def test_setters(self): self.assertEqual(trx.transition_type, "SMPTE.Dissolve") trx.transition_type = "EdgeWipe" self.assertEqual(trx.transition_type, "EdgeWipe") + self.assertTrue(trx.enabled) + trx.enabled = False + self.assertFalse(trx.enabled) def test_parent_range(self): timeline = otio.schema.Timeline(