From 584e075f678efa1fbbabccc32f7df7da70d707e6 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Fri, 2 Jul 2021 21:03:26 -0400 Subject: [PATCH] Point: Rethink stream formatting --- src/Point.h | 196 ++++++++++++++++++++++++------------------------ tests/Point.cpp | 24 +++--- 2 files changed, 108 insertions(+), 112 deletions(-) diff --git a/src/Point.h b/src/Point.h index 2602fb9f..48ebea45 100644 --- a/src/Point.h +++ b/src/Point.h @@ -37,120 +37,118 @@ namespace openshot { - /** - * @brief This controls how a Keyframe uses this point to interpolate between two points. - * - * Bezier is a smooth curve. Linear is a straight line. Constant is a jump from the - * previous point to this one. - */ - enum InterpolationType { - BEZIER, ///< Bezier curves are quadratic curves, which create a smooth curve. - LINEAR, ///< Linear curves are angular, straight lines between two points. - CONSTANT ///< Constant curves jump from their previous position to a new one (with no interpolation). - }; +/** + * @brief This controls how a Keyframe uses this point to interpolate between two points. + * + * Bezier is a smooth curve. Linear is a straight line. Constant is a jump from the + * previous point to this one. + */ +enum InterpolationType { + BEZIER, ///< Bezier curves are quadratic curves, which create a smooth curve. + LINEAR, ///< Linear curves are angular, straight lines between two points. + CONSTANT ///< Constant curves jump from their previous position to a new one (with no interpolation). +}; - /** - * @brief When BEZIER interpolation is used, the point's left and right handles are used - * to influence the direction of the curve. - * - * AUTO will try and adjust the handles automatically, to achieve the smoothest curves. - * MANUAL will leave the handles alone, making it the responsibility of the user to set them. - */ - enum HandleType { - AUTO, ///< Automatically adjust the handles to achieve the smoothest curve - MANUAL ///< Do not automatically adjust handles (set them manually) - }; +/** + * @brief When BEZIER interpolation is used, the point's left and right handles are used + * to influence the direction of the curve. + * + * AUTO will try and adjust the handles automatically, to achieve the smoothest curves. + * MANUAL will leave the handles alone, making it the responsibility of the user to set them. + */ +enum HandleType { + AUTO, ///< Automatically adjust the handles to achieve the smoothest curve + MANUAL ///< Do not automatically adjust handles (set them manually) +}; - /** - * @brief A Point is the basic building block of a key-frame curve. - * - * Points have a primary coordinate and a left and right handle coordinate. - * The handles are used to influence the direction of the curve as it - * moves between the primary coordinate and the next primary coordinate when the - * interpolation mode is BEZIER. When using LINEAR or CONSTANT, the handles are - * ignored. - * - * Please see the following Example Code: - * \code - * Coordinate c1(3,9); - * Point p1(c1, BEZIER); - * assert(c1.X == 3); - * assert(c1.Y == 9); - * - * \endcode - */ - class Point { - public: - Coordinate co; ///< This is the primary coordinate - Coordinate handle_left; ///< This is the left handle coordinate (in percentages from 0 to 1) - Coordinate handle_right; ///< This is the right handle coordinate (in percentages from 0 to 1) - InterpolationType interpolation; ///< This is the interpolation mode - HandleType handle_type; ///< This is the handle mode +/** + * @brief A Point is the basic building block of a key-frame curve. + * + * Points have a primary coordinate and a left and right handle coordinate. + * The handles are used to influence the direction of the curve as it + * moves between the primary coordinate and the next primary coordinate when the + * interpolation mode is BEZIER. When using LINEAR or CONSTANT, the handles are + * ignored. + * + * Please see the following Example Code: + * \code + * Coordinate c1(3,9); + * Point p1(c1, BEZIER); + * assert(c1.X == 3); + * assert(c1.Y == 9); + * + * \endcode + */ +class Point { +public: + Coordinate co; ///< This is the primary coordinate + Coordinate handle_left; ///< This is the left handle coordinate (in percentages from 0 to 1) + Coordinate handle_right; ///< This is the right handle coordinate (in percentages from 0 to 1) + InterpolationType interpolation; ///< This is the interpolation mode + HandleType handle_type; ///< This is the handle mode - /// Default constructor (defaults to 1,0) - Point(); + /// Default constructor (defaults to 1,0) + Point(); - /// Constructor which creates a single coordinate at X=1 - Point(float y); + /// Constructor which creates a single coordinate at X=1 + Point(float y); - /// Constructor which also creates a Point and sets the X and Y of the Point. - Point(float x, float y); + /// Constructor which also creates a Point and sets the X and Y of the Point. + Point(float x, float y); - /// Constructor which also creates a Point and sets the X,Y, and interpolation of the Point. - Point(float x, float y, InterpolationType interpolation); + /// Constructor which also creates a Point and sets the X,Y, and interpolation of the Point. + Point(float x, float y, InterpolationType interpolation); - /// Constructor which takes a coordinate - Point(const Coordinate& co); + /// Constructor which takes a coordinate + Point(const Coordinate& co); - /// Constructor which takes a coordinate and interpolation mode - Point(const Coordinate& co, InterpolationType interpolation); + /// Constructor which takes a coordinate and interpolation mode + Point(const Coordinate& co, InterpolationType interpolation); - /// Constructor which takes a coordinate, interpolation mode, and handle type - Point(const Coordinate& co, InterpolationType interpolation, HandleType handle_type); + /// Constructor which takes a coordinate, interpolation mode, and handle type + Point(const Coordinate& co, InterpolationType interpolation, HandleType handle_type); - /// Set the left and right handles to a percent of the primary coordinate (0 to 1) - /// Defaults to a smooth curve (Ease in and out) - void Initialize_Handles(); + /// Set the left and right handles to a percent of the primary coordinate (0 to 1) + /// Defaults to a smooth curve (Ease in and out) + void Initialize_Handles(); - /// Set the left handle to a percent of the primary coordinate (0 to 1) - void Initialize_LeftHandle(float x, float y); + /// Set the left handle to a percent of the primary coordinate (0 to 1) + void Initialize_LeftHandle(float x, float y); - /// Set the right handle to a percent of the primary coordinate (0 to 1) - void Initialize_RightHandle(float x, float y); + /// Set the right handle to a percent of the primary coordinate (0 to 1) + void Initialize_RightHandle(float x, float y); - // Get and Set JSON methods - std::string Json() const; ///< Generate JSON string of this object - Json::Value JsonValue() const; ///< Generate Json::Value for this object - void SetJson(const std::string value); ///< Load JSON string into this object - void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object + // Get and Set JSON methods + std::string Json() const; ///< Generate JSON string of this object + Json::Value JsonValue() const; ///< Generate Json::Value for this object + void SetJson(const std::string value); ///< Load JSON string into this object + void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object - }; +}; - // Stream output operator for openshot::Point - template - std::basic_ostream& - operator<<(std::basic_ostream& o, const openshot::Point& p) { - std::basic_ostringstream s; - s.flags(o.flags()); - s.imbue(o.getloc()); - s.precision(o.precision()); - s << "co" << p.co; - switch(p.interpolation) { - case(openshot::LINEAR): - s << " interpolation(LINEAR)"; - break; - case(openshot::CONSTANT): - s << " interpolation(CONSTANT)"; - break; - case(openshot::BEZIER): - s << " interpolation(BEZIER)" - << " handle_left" << p.handle_left - << " handle_right" << p.handle_right; - break; - } - return o << s.str(); - }; +// Stream output operator for openshot::Point +template +std::basic_ostream& +operator<<(std::basic_ostream& o, const openshot::Point& p) { + std::basic_ostringstream s; + s.flags(o.flags()); + s.imbue(o.getloc()); + s.precision(o.precision()); + s << "co" << p.co; + switch(p.interpolation) { + case(InterpolationType::LINEAR): + s << " LINEAR"; + break; + case(InterpolationType::CONSTANT): + s << " CONSTANT"; + break; + case(InterpolationType::BEZIER): + s << " BEZIER[L" << p.handle_left << ",R" << p.handle_right << ']'; + break; + } + return o << s.str(); +}; -} +} // namespace openshot #endif diff --git a/tests/Point.cpp b/tests/Point.cpp index f4e7792b..57cff7c7 100644 --- a/tests/Point.cpp +++ b/tests/Point.cpp @@ -52,7 +52,7 @@ TEST_CASE( "default constructor", "[libopenshot][point]" ) CHECK(p.interpolation == openshot::InterpolationType::BEZIER); CHECK(p.handle_type == openshot::HandleType::AUTO); } -TEST_CASE( "XY constructor", "[libopenshot][point]" ) +TEST_CASE( "x,y ctor", "[libopenshot][point]" ) { // Create a point with X and Y values openshot::Point p1(2,9); @@ -62,7 +62,7 @@ TEST_CASE( "XY constructor", "[libopenshot][point]" ) CHECK(p1.interpolation == openshot::InterpolationType::BEZIER); } -TEST_CASE( "std::pair constructor", "[libopenshot][point]" ) +TEST_CASE( "std::pair ctor", "[libopenshot][point]" ) { // Create a point from a std::pair std::pair coordinates(22, 5); @@ -72,7 +72,7 @@ TEST_CASE( "std::pair constructor", "[libopenshot][point]" ) CHECK(p1.co.Y == Approx(5.0f).margin(0.00001)); } -TEST_CASE( "constructor from Coordinate", "[libopenshot][point]" ) +TEST_CASE( "Coordinate ctor", "[libopenshot][point]" ) { // Create a point with a coordinate openshot::Coordinate c1(3,7); @@ -83,7 +83,7 @@ TEST_CASE( "constructor from Coordinate", "[libopenshot][point]" ) CHECK(p1.interpolation == openshot::InterpolationType::BEZIER); } -TEST_CASE( "constructor from Coordinate, LINEAR", "[libopenshot][point]" ) +TEST_CASE( "Coordinate ctor, LINEAR", "[libopenshot][point]" ) { // Create a point with a coordinate and interpolation openshot::Coordinate c1(3,9); @@ -95,7 +95,7 @@ TEST_CASE( "constructor from Coordinate, LINEAR", "[libopenshot][point]" ) CHECK(p1.interpolation == openshot::InterpolationType::LINEAR); } -TEST_CASE( "constructor from Coordinate, BEZIER", "[libopenshot][point]" ) +TEST_CASE( "Coordinate ctor, BEZIER", "[libopenshot][point]" ) { // Create a point with a coordinate and interpolation openshot::Coordinate c1(3,9); @@ -107,7 +107,7 @@ TEST_CASE( "constructor from Coordinate, BEZIER", "[libopenshot][point]" ) CHECK(p1.interpolation == openshot::InterpolationType::BEZIER); } -TEST_CASE( "constructor from Coordinate, CONSTANT", "[libopenshot][point]" ) +TEST_CASE( "Coordinate ctor, CONSTANT", "[libopenshot][point]" ) { // Create a point with a coordinate and interpolation openshot::Coordinate c1(2,8); @@ -119,7 +119,7 @@ TEST_CASE( "constructor from Coordinate, CONSTANT", "[libopenshot][point]" ) CHECK(p1.interpolation == openshot::InterpolationType::CONSTANT); } -TEST_CASE( "constructor from Coordinate, BEZIER+AUTO", "[libopenshot][point]" ) +TEST_CASE( "Coordinate ctor, BEZIER+AUTO", "[libopenshot][point]" ) { // Create a point with a coordinate and interpolation openshot::Coordinate c1(3,9); @@ -133,7 +133,7 @@ TEST_CASE( "constructor from Coordinate, BEZIER+AUTO", "[libopenshot][point]" ) CHECK(p1.handle_type == openshot::HandleType::AUTO); } -TEST_CASE( "constructor from Coordinate, BEZIER+MANUAL", "[libopenshot][point]" ) +TEST_CASE( "Coordinate ctor, BEZIER+MANUAL", "[libopenshot][point]" ) { // Create a point with a coordinate and interpolation openshot::Coordinate c1(3,9); @@ -197,17 +197,15 @@ TEST_CASE( "Operator ostream", "[libopenshot][point]" ) std::stringstream output1; openshot::Point p1(c1, openshot::InterpolationType::LINEAR); output1 << p1; - CHECK(output1.str() == "co(10, 5) interpolation(LINEAR)"); + CHECK(output1.str() == "co(10, 5) LINEAR"); std::stringstream output2; openshot::Point p2(c1, openshot::InterpolationType::CONSTANT); output2 << p2; - CHECK(output2.str() == "co(10, 5) interpolation(CONSTANT)"); + CHECK(output2.str() == "co(10, 5) CONSTANT"); std::stringstream output3; openshot::Point p3(c1, openshot::InterpolationType::BEZIER); output3 << p3; - CHECK( - output3.str() == - "co(10, 5) interpolation(BEZIER) handle_left(0.5, 1) handle_right(0.5, 0)"); + CHECK(output3.str() == "co(10, 5) BEZIER[L(0.5, 1),R(0.5, 0)]"); }