Point: Rethink stream formatting

This commit is contained in:
FeRD (Frank Dana)
2021-07-02 21:03:26 -04:00
parent b3c43166fa
commit 584e075f67
2 changed files with 108 additions and 112 deletions

View File

@@ -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 <b>Example Code</b>:
* \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 <b>Example Code</b>:
* \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<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& o, const openshot::Point& p) {
std::basic_ostringstream<charT, traits> 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<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& o, const openshot::Point& p) {
std::basic_ostringstream<charT, traits> 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

View File

@@ -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<double, double> 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)]");
}