diff --git a/include/Clip.h b/include/Clip.h index bd44cda1..72581a74 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -104,7 +104,7 @@ namespace openshot { int adjust_frame_number_minimum(int frame_number); /// Generate JSON for a property - Json::Value add_property_json(string name, float value, string type, string memo, bool contains_point, int number_of_points, float min_value, float max_value, bool readonly); + Json::Value add_property_json(string name, float value, string type, string memo, bool contains_point, int number_of_points, float min_value, float max_value, InterpolationType intepolation, int closest_point_x, bool readonly); /// Get file extension string get_file_extension(string path); diff --git a/include/KeyFrame.h b/include/KeyFrame.h index 10a4bc66..abca5d92 100644 --- a/include/KeyFrame.h +++ b/include/KeyFrame.h @@ -131,6 +131,9 @@ namespace openshot { /// Get a point at a specific index Point& GetPoint(int index) throw(OutOfBoundsPoint); + /// Get current point (or closest point) from the X coordinate (i.e. the frame number) + Point GetClosestPoint(Point p); + // Get the number of values (i.e. coordinates on the X axis) int GetLength(); diff --git a/src/Clip.cpp b/src/Clip.cpp index e902ddef..8c588df1 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -532,26 +532,26 @@ string Clip::PropertiesJSON(int requested_frame) { // Generate JSON properties list Json::Value root; - root["id"] = add_property_json("ID", 0.0, "string", Id(), false, 0, -1, -1, true); - root["position"] = add_property_json("Position", Position(), "int", "", false, 0, 0, 1000 * 60 * 30, false); - root["layer"] = add_property_json("Layer", Layer(), "int", "", false, 0, 0, 1000, false); - root["start"] = add_property_json("Start", Start(), "float", "", false, 0, 0, 1000 * 60 * 30, false); - root["end"] = add_property_json("End", End(), "float", "", false, 0, 0, 1000 * 60 * 30, false); - root["duration"] = add_property_json("Duration", Duration(), "float", "", false, 0, 0, 1000 * 60 * 30, false); - root["gravity"] = add_property_json("Gravity", gravity, "int", "", false, 0, -1, -1, false); - root["scale"] = add_property_json("Scale", scale, "int", "", false, 0, -1, -1, false); - root["anchor"] = add_property_json("Anchor", anchor, "int", "", false, 0, -1, -1, false); - root["waveform"] = add_property_json("Waveform", waveform, "int", "", false, 0, -1, -1, false); + root["id"] = add_property_json("ID", 0.0, "string", Id(), false, 0, -1, -1, CONSTANT, -1, true); + root["position"] = add_property_json("Position", Position(), "int", "", false, 0, 0, 1000 * 60 * 30, CONSTANT, -1, false); + root["layer"] = add_property_json("Layer", Layer(), "int", "", false, 0, 0, 1000, CONSTANT, -1, false); + root["start"] = add_property_json("Start", Start(), "float", "", false, 0, 0, 1000 * 60 * 30, CONSTANT, -1, false); + root["end"] = add_property_json("End", End(), "float", "", false, 0, 0, 1000 * 60 * 30, CONSTANT, -1, false); + root["duration"] = add_property_json("Duration", Duration(), "float", "", false, 0, 0, 1000 * 60 * 30, CONSTANT, -1, false); + root["gravity"] = add_property_json("Gravity", gravity, "int", "", false, 0, -1, -1, CONSTANT, -1, false); + root["scale"] = add_property_json("Scale", scale, "int", "", false, 0, -1, -1, CONSTANT, -1, false); + root["anchor"] = add_property_json("Anchor", anchor, "int", "", false, 0, -1, -1, CONSTANT, -1, false); + root["waveform"] = add_property_json("Waveform", waveform, "int", "", false, 0, -1, -1, CONSTANT, -1, false); // Keyframes - root["location_x"] = add_property_json("Location X", location_x.GetValue(requested_frame), "float", "", location_x.Contains(requested_point), location_x.GetLength(), -10000, 10000, false); - root["location_y"] = add_property_json("Location Y", location_y.GetValue(requested_frame), "float", "", location_y.Contains(requested_point), location_y.GetLength(), -10000, 10000, false); - root["scale_x"] = add_property_json("Scale X", scale_x.GetValue(requested_frame), "float", "", scale_x.Contains(requested_point), scale_x.GetLength(), 0.0, 100.0, false); - root["scale_y"] = add_property_json("Scale Y", scale_y.GetValue(requested_frame), "float", "", scale_y.Contains(requested_point), scale_y.GetLength(), 0.0, 100.0, false); - root["alpha"] = add_property_json("Alpha", alpha.GetValue(requested_frame), "float", "", alpha.Contains(requested_point), alpha.GetLength(), 0.0, 1.0, false); - root["rotation"] = add_property_json("Rotation", rotation.GetValue(requested_frame), "float", "", rotation.Contains(requested_point), rotation.GetLength(), -10000, 10000, false); - root["volume"] = add_property_json("Volume", volume.GetValue(requested_frame), "float", "", volume.Contains(requested_point), volume.GetLength(), 0.0, 1.0, false); - root["time"] = add_property_json("Time", time.GetValue(requested_frame), "float", "", time.Contains(requested_point), time.GetLength(), 0.0, 1000 * 60 * 30, false); + root["location_x"] = add_property_json("Location X", location_x.GetValue(requested_frame), "float", "", location_x.Contains(requested_point), location_x.GetLength(), -10000, 10000, location_x.GetClosestPoint(requested_point).interpolation, location_x.GetClosestPoint(requested_point).co.X, false); + root["location_y"] = add_property_json("Location Y", location_y.GetValue(requested_frame), "float", "", location_y.Contains(requested_point), location_y.GetLength(), -10000, 10000, location_y.GetClosestPoint(requested_point).interpolation, location_y.GetClosestPoint(requested_point).co.X, false); + root["scale_x"] = add_property_json("Scale X", scale_x.GetValue(requested_frame), "float", "", scale_x.Contains(requested_point), scale_x.GetLength(), 0.0, 100.0, scale_x.GetClosestPoint(requested_point).interpolation, scale_x.GetClosestPoint(requested_point).co.X, false); + root["scale_y"] = add_property_json("Scale Y", scale_y.GetValue(requested_frame), "float", "", scale_y.Contains(requested_point), scale_y.GetLength(), 0.0, 100.0, scale_y.GetClosestPoint(requested_point).interpolation, scale_y.GetClosestPoint(requested_point).co.X, false); + root["alpha"] = add_property_json("Alpha", alpha.GetValue(requested_frame), "float", "", alpha.Contains(requested_point), alpha.GetLength(), 0.0, 1.0, alpha.GetClosestPoint(requested_point).interpolation, alpha.GetClosestPoint(requested_point).co.X, false); + root["rotation"] = add_property_json("Rotation", rotation.GetValue(requested_frame), "float", "", rotation.Contains(requested_point), rotation.GetLength(), -10000, 10000, rotation.GetClosestPoint(requested_point).interpolation, rotation.GetClosestPoint(requested_point).co.X, false); + root["volume"] = add_property_json("Volume", volume.GetValue(requested_frame), "float", "", volume.Contains(requested_point), volume.GetLength(), 0.0, 1.0, volume.GetClosestPoint(requested_point).interpolation, volume.GetClosestPoint(requested_point).co.X, false); + root["time"] = add_property_json("Time", time.GetValue(requested_frame), "float", "", time.Contains(requested_point), time.GetLength(), 0.0, 1000 * 60 * 30, time.GetClosestPoint(requested_point).interpolation, time.GetClosestPoint(requested_point).co.X, false); // Keep track of settings string stringstream properties; @@ -568,15 +568,15 @@ string Clip::PropertiesJSON(int requested_frame) { } // Mark JSON as changed - root["changed"] = add_property_json("changed", changed, "bool", "", false, 0, 0, 1, false); - root["hash"] = add_property_json("hash", 0.0, "string", properties.str(), false, 0, 0, 1, false); + root["changed"] = add_property_json("changed", changed, "bool", "", false, 0, 0, 1, CONSTANT, -1, true); + root["hash"] = add_property_json("hash", 0.0, "string", properties.str(), false, 0, 0, 1, CONSTANT, -1, true); // Return formatted string return root.toStyledString(); } // Generate JSON for a property -Json::Value Clip::add_property_json(string name, float value, string type, string memo, bool contains_point, int number_of_points, float min_value, float max_value, bool readonly) { +Json::Value Clip::add_property_json(string name, float value, string type, string memo, bool contains_point, int number_of_points, float min_value, float max_value, InterpolationType intepolation, int closest_point_x, bool readonly) { // Create JSON Object Json::Value prop = Json::Value(Json::objectValue); @@ -589,6 +589,8 @@ Json::Value Clip::add_property_json(string name, float value, string type, strin prop["keyframe"] = contains_point; prop["points"] = number_of_points; prop["readonly"] = max_value; + prop["interpolation"] = intepolation; + prop["closest_point_x"] = closest_point_x; // return JsonValue return prop; diff --git a/src/KeyFrame.cpp b/src/KeyFrame.cpp index b1449d8c..e5c5c2f7 100644 --- a/src/KeyFrame.cpp +++ b/src/KeyFrame.cpp @@ -47,8 +47,6 @@ void Keyframe::ReorderPoints() { // swap items if (smallest_index != compare_index) { - cout << "swap item " << Points[compare_index].co.X << " with " - << Points[smallest_index].co.X << endl; swap(Points[compare_index], Points[smallest_index]); } } @@ -189,6 +187,26 @@ bool Keyframe::Contains(Point p) { return false; } +// Get current point (or closest point) from the X coordinate (i.e. the frame number) +Point Keyframe::GetClosestPoint(Point p) { + Point closest(-1, -1); + + // loop through points, and find a matching coordinate + for (int x = 0; x < Points.size(); x++) { + // Get each point + Point existing_point = Points[x]; + + // find a match + if ((p.co.X <= existing_point.co.X && p.co.X >= closest.co.X) || (closest.co.X == -1)) { + // New closest point found + closest = existing_point; + } + } + + // no matching point found + return closest; +} + // Get the value at a specific index float Keyframe::GetValue(int index) { diff --git a/src/Point.cpp b/src/Point.cpp index f80e4c78..0f0917b8 100644 --- a/src/Point.cpp +++ b/src/Point.cpp @@ -34,7 +34,7 @@ using namespace openshot; Point::Point() : interpolation(BEZIER), handle_type(AUTO) { // set new coorinate - co = Coordinate(0, 0); + co = Coordinate(1, 0); // set handles Initialize_Handles(); @@ -44,7 +44,7 @@ Point::Point() : interpolation(BEZIER), handle_type(AUTO) Point::Point(float y) : interpolation(CONSTANT), handle_type(AUTO) { // set new coorinate - co = Coordinate(0, y); + co = Coordinate(1, y); // set handles Initialize_Handles();