Extract animation operation planning
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "app_core/app_preferences.h"
|
||||
#include "app_core/app_status.h"
|
||||
#include "app_core/document_animation.h"
|
||||
#include "app_core/document_export.h"
|
||||
#include "app_core/document_cloud.h"
|
||||
#include "app_core/document_layer.h"
|
||||
@@ -238,6 +239,18 @@ struct PlanLayerOperationArgs {
|
||||
int blend_mode = 0;
|
||||
};
|
||||
|
||||
struct PlanAnimationOperationArgs {
|
||||
std::string kind = "goto";
|
||||
int frame_count = 1;
|
||||
int total_duration = 1;
|
||||
int current_frame = 0;
|
||||
int selected_frame = 0;
|
||||
int current_duration = 1;
|
||||
int delta = 1;
|
||||
int offset = 1;
|
||||
int onion_size = 1;
|
||||
};
|
||||
|
||||
struct SimulateAppSessionArgs {
|
||||
bool has_canvas = true;
|
||||
bool new_document = false;
|
||||
@@ -511,6 +524,32 @@ const char* document_layer_operation_name(pp::app::DocumentLayerOperation operat
|
||||
return "select";
|
||||
}
|
||||
|
||||
const char* document_animation_operation_name(pp::app::DocumentAnimationOperation operation) noexcept
|
||||
{
|
||||
switch (operation) {
|
||||
case pp::app::DocumentAnimationOperation::add_frame:
|
||||
return "add-frame";
|
||||
case pp::app::DocumentAnimationOperation::duplicate_frame:
|
||||
return "duplicate-frame";
|
||||
case pp::app::DocumentAnimationOperation::remove_frame:
|
||||
return "remove-frame";
|
||||
case pp::app::DocumentAnimationOperation::adjust_duration:
|
||||
return "adjust-duration";
|
||||
case pp::app::DocumentAnimationOperation::move_frame:
|
||||
return "move-frame";
|
||||
case pp::app::DocumentAnimationOperation::goto_frame:
|
||||
return "goto-frame";
|
||||
case pp::app::DocumentAnimationOperation::goto_next:
|
||||
return "goto-next";
|
||||
case pp::app::DocumentAnimationOperation::goto_previous:
|
||||
return "goto-previous";
|
||||
case pp::app::DocumentAnimationOperation::set_onion_size:
|
||||
return "set-onion-size";
|
||||
}
|
||||
|
||||
return "goto-frame";
|
||||
}
|
||||
|
||||
const char* document_file_write_decision_name(pp::app::DocumentFileWriteDecision decision) noexcept
|
||||
{
|
||||
switch (decision) {
|
||||
@@ -724,6 +763,20 @@ pp::foundation::Result<float> parse_float_arg(std::string_view text)
|
||||
return pp::foundation::Result<float>::success(value);
|
||||
}
|
||||
|
||||
pp::foundation::Result<int> parse_i32_arg(std::string_view text)
|
||||
{
|
||||
int value = 0;
|
||||
const auto* begin = text.data();
|
||||
const auto* end = begin + text.size();
|
||||
const auto [ptr, ec] = std::from_chars(begin, end, value);
|
||||
if (ec != std::errc {} || ptr != end) {
|
||||
return pp::foundation::Result<int>::failure(
|
||||
pp::foundation::Status::invalid_argument("invalid signed integer value"));
|
||||
}
|
||||
|
||||
return pp::foundation::Result<int>::success(value);
|
||||
}
|
||||
|
||||
void print_help()
|
||||
{
|
||||
std::cout
|
||||
@@ -750,6 +803,7 @@ void print_help()
|
||||
<< " plan-document-resize [--current-resolution N] [--selected-resolution-index N]\n"
|
||||
<< " plan-layer-rename --old-name NAME --new-name NAME\n"
|
||||
<< " plan-layer-operation --kind add|duplicate|select|reorder|remove|opacity|visibility|alpha-lock|blend-mode|highlight [--layer-count N] [--index N] [--from-index N] [--to-index N] [--source-index N] [--name NAME] [--opacity N] [--blend-mode N] [--enabled]\n"
|
||||
<< " plan-animation-operation --kind add|duplicate|remove|duration|move|goto|next|prev|onion [--frame-count N] [--total-duration N] [--current-frame N] [--selected-frame N] [--current-duration N] [--delta N] [--offset N] [--onion-size N]\n"
|
||||
<< " plan-share-file [--path FILE]\n"
|
||||
<< " plan-picked-path [--path FILE]\n"
|
||||
<< " plan-display-file [--path FILE]\n"
|
||||
@@ -2535,6 +2589,136 @@ int plan_layer_operation(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_animation_operation_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
PlanAnimationOperationArgs& args)
|
||||
{
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
const std::string_view key(argv[i]);
|
||||
if (key == "--kind") {
|
||||
if (i + 1 >= argc) {
|
||||
return pp::foundation::Status::invalid_argument("missing value for option");
|
||||
}
|
||||
args.kind = argv[++i];
|
||||
} else if (key == "--frame-count" || key == "--total-duration" || key == "--current-frame"
|
||||
|| key == "--selected-frame" || key == "--current-duration" || key == "--delta"
|
||||
|| key == "--offset" || key == "--onion-size") {
|
||||
if (i + 1 >= argc) {
|
||||
return pp::foundation::Status::invalid_argument("missing value for option");
|
||||
}
|
||||
const auto value = parse_i32_arg(argv[++i]);
|
||||
if (!value) {
|
||||
return value.status();
|
||||
}
|
||||
if (key == "--frame-count") {
|
||||
args.frame_count = value.value();
|
||||
} else if (key == "--total-duration") {
|
||||
args.total_duration = value.value();
|
||||
} else if (key == "--current-frame") {
|
||||
args.current_frame = value.value();
|
||||
} else if (key == "--selected-frame") {
|
||||
args.selected_frame = value.value();
|
||||
} else if (key == "--current-duration") {
|
||||
args.current_duration = value.value();
|
||||
} else if (key == "--delta") {
|
||||
args.delta = value.value();
|
||||
} else if (key == "--offset") {
|
||||
args.offset = value.value();
|
||||
} else {
|
||||
args.onion_size = value.value();
|
||||
}
|
||||
} else {
|
||||
return pp::foundation::Status::invalid_argument("unknown option");
|
||||
}
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<pp::app::DocumentAnimationOperationPlan> make_animation_operation_plan(
|
||||
const PlanAnimationOperationArgs& args)
|
||||
{
|
||||
if (args.kind == "add") {
|
||||
return pp::app::plan_animation_add_frame(args.frame_count, args.current_frame);
|
||||
}
|
||||
if (args.kind == "duplicate") {
|
||||
return pp::app::plan_animation_duplicate_frame(args.frame_count, args.selected_frame);
|
||||
}
|
||||
if (args.kind == "remove") {
|
||||
return pp::app::plan_animation_remove_frame(args.frame_count, args.selected_frame);
|
||||
}
|
||||
if (args.kind == "duration") {
|
||||
return pp::app::plan_animation_adjust_duration(
|
||||
args.frame_count,
|
||||
args.selected_frame,
|
||||
args.current_duration,
|
||||
args.delta);
|
||||
}
|
||||
if (args.kind == "move") {
|
||||
return pp::app::plan_animation_move_frame(args.frame_count, args.selected_frame, args.offset);
|
||||
}
|
||||
if (args.kind == "goto") {
|
||||
return pp::app::plan_animation_goto_frame(args.total_duration, args.current_frame);
|
||||
}
|
||||
if (args.kind == "next") {
|
||||
return pp::app::plan_animation_step_frame(args.total_duration, args.current_frame, 1);
|
||||
}
|
||||
if (args.kind == "prev") {
|
||||
return pp::app::plan_animation_step_frame(args.total_duration, args.current_frame, -1);
|
||||
}
|
||||
if (args.kind == "onion") {
|
||||
return pp::app::plan_animation_onion_size(args.onion_size);
|
||||
}
|
||||
|
||||
return pp::foundation::Result<pp::app::DocumentAnimationOperationPlan>::failure(
|
||||
pp::foundation::Status::invalid_argument("unknown animation operation kind"));
|
||||
}
|
||||
|
||||
int plan_animation_operation(int argc, char** argv)
|
||||
{
|
||||
PlanAnimationOperationArgs args;
|
||||
const auto status = parse_plan_animation_operation_args(argc, argv, args);
|
||||
if (!status.ok()) {
|
||||
print_error("plan-animation-operation", status.message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto plan = make_animation_operation_plan(args);
|
||||
if (!plan) {
|
||||
print_error("plan-animation-operation", plan.status().message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto& value = plan.value();
|
||||
std::cout << "{\"ok\":true,\"command\":\"plan-animation-operation\""
|
||||
<< ",\"state\":{\"kind\":\"" << json_escape(args.kind)
|
||||
<< "\",\"frameCount\":" << args.frame_count
|
||||
<< ",\"totalDuration\":" << args.total_duration
|
||||
<< ",\"currentFrame\":" << args.current_frame
|
||||
<< ",\"selectedFrame\":" << args.selected_frame
|
||||
<< ",\"currentDuration\":" << args.current_duration
|
||||
<< ",\"delta\":" << args.delta
|
||||
<< ",\"offset\":" << args.offset
|
||||
<< ",\"onionSize\":" << args.onion_size
|
||||
<< "},\"plan\":{\"operation\":\"" << document_animation_operation_name(value.operation)
|
||||
<< "\",\"frameCount\":" << value.frame_count
|
||||
<< ",\"currentFrame\":" << value.current_frame
|
||||
<< ",\"selectedFrame\":" << value.selected_frame
|
||||
<< ",\"targetFrame\":" << value.target_frame
|
||||
<< ",\"frameDuration\":" << value.frame_duration
|
||||
<< ",\"durationDelta\":" << value.duration_delta
|
||||
<< ",\"moveOffset\":" << value.move_offset
|
||||
<< ",\"onionSize\":" << value.onion_size
|
||||
<< ",\"requiresSelectedFrame\":" << json_bool(value.requires_selected_frame)
|
||||
<< ",\"mutatesDocument\":" << json_bool(value.mutates_document)
|
||||
<< ",\"reloadsAnimationLayers\":" << json_bool(value.reloads_animation_layers)
|
||||
<< ",\"updatesCanvasAnimation\":" << json_bool(value.updates_canvas_animation)
|
||||
<< ",\"marksUnsaved\":" << json_bool(value.marks_unsaved)
|
||||
<< "}}\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_share_file_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
@@ -4947,6 +5131,10 @@ int main(int argc, char** argv)
|
||||
return plan_layer_operation(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-animation-operation") {
|
||||
return plan_animation_operation(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-share-file") {
|
||||
return plan_share_file(argc, argv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user