Route stroke panel view through app core

This commit is contained in:
2026-06-05 01:01:56 +02:00
parent 75fd7faeb0
commit d5403f082c
8 changed files with 556 additions and 80 deletions

View File

@@ -412,6 +412,19 @@ struct PlanBrushStrokeControlArgs {
int blend_mode = 0;
};
struct PlanBrushStrokePanelViewArgs {
float tip_size = 42.5F;
float jitter_scatter = 0.75F;
bool dual_enabled = true;
int tip_blend_mode = 4;
int pattern_blend_mode = 8;
std::string tip_thumbnail_path = "data/brushes/thumbs/soft.png";
std::string dual_thumbnail_path = "data/brushes/thumbs/hard.png";
std::string pattern_thumbnail_path = "data/patterns/thumbs/noise.png";
bool bad_float = false;
bool bad_blend = false;
};
struct PlanPaintFeedbackArgs {
int width = 64;
int height = 32;
@@ -1957,6 +1970,7 @@ void print_help()
<< " plan-brush-texture-list --kind add|remove|move [--dir NAME] [--data-path DIR] [--source FILE] [--item-count N] [--current-index N] [--offset N] [--user-texture]\n"
<< " plan-brush-preset-list --kind add|remove|move|up|down|select|clear [--item-count N] [--current-index N] [--offset N] [--no-current-brush]\n"
<< " plan-brush-stroke-control --kind float|bool|blend|tip-aspect-reset|default-reset [--setting NAME] [--value N] [--enabled|--disabled] [--blend-mode N]\n"
<< " plan-brush-stroke-panel-view [--tip-size N] [--jitter-scatter N] [--dual-enabled|--dual-disabled] [--tip-blend-mode N] [--pattern-blend-mode N] [--tip-thumb FILE] [--dual-thumb FILE] [--pattern-thumb FILE] [--bad-float] [--bad-blend]\n"
<< " plan-paint-feedback [--width N] [--height N] [--simple|--complex] [--framebuffer-fetch] [--texture-copy] [--blit] [--explicit-transitions] [--render-only] [--depth]\n"
<< " plan-stroke-composite [--width N] [--height N] [--layer-blend N] [--stroke-blend N] [--dual-blend] [--pattern-blend] [--framebuffer-fetch] [--texture-copy] [--blit] [--explicit-transitions] [--render-only] [--depth]\n"
<< " plan-canvas-hotkey --event key-down|key-up|touch-tap --key e|z|s|tab|alt|android-back|bracket-left|bracket-right [--ctrl] [--shift] [--mouse-focus] [--undo-count N] [--redo-count N] [--touch-fingers N]\n"
@@ -5773,6 +5787,154 @@ int plan_brush_stroke_control(int argc, char** argv)
return 0;
}
pp::foundation::Status parse_plan_brush_stroke_panel_view_args(
int argc,
char** argv,
PlanBrushStrokePanelViewArgs& args)
{
for (int i = 2; i < argc; ++i) {
const std::string_view key(argv[i]);
if (key == "--tip-size" || key == "--jitter-scatter") {
if (i + 1 >= argc) {
return pp::foundation::Status::invalid_argument("missing value for option");
}
const auto value = parse_float_arg(argv[++i]);
if (!value) {
return value.status();
}
if (key == "--tip-size") {
args.tip_size = value.value();
} else {
args.jitter_scatter = value.value();
}
} else if (key == "--tip-blend-mode" || key == "--pattern-blend-mode") {
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 == "--tip-blend-mode") {
args.tip_blend_mode = value.value();
} else {
args.pattern_blend_mode = value.value();
}
} else if (key == "--tip-thumb" || key == "--dual-thumb" || key == "--pattern-thumb") {
if (i + 1 >= argc) {
return pp::foundation::Status::invalid_argument("missing value for option");
}
if (key == "--tip-thumb") {
args.tip_thumbnail_path = argv[++i];
} else if (key == "--dual-thumb") {
args.dual_thumbnail_path = argv[++i];
} else {
args.pattern_thumbnail_path = argv[++i];
}
} else if (key == "--dual-enabled") {
args.dual_enabled = true;
} else if (key == "--dual-disabled") {
args.dual_enabled = false;
} else if (key == "--bad-float") {
args.bad_float = true;
} else if (key == "--bad-blend") {
args.bad_blend = true;
} else {
return pp::foundation::Status::invalid_argument("unknown option");
}
}
return pp::foundation::Status::success();
}
int plan_brush_stroke_panel_view(int argc, char** argv)
{
PlanBrushStrokePanelViewArgs args;
const auto status = parse_plan_brush_stroke_panel_view_args(argc, argv, args);
if (!status.ok()) {
print_error("plan-brush-stroke-panel-view", status.message);
return 2;
}
pp::app::BrushStrokePanelInput input;
input.float_values.push_back(pp::app::BrushStrokeFloatValue {
.setting = pp::app::BrushStrokeFloatSetting::tip_size,
.value = args.bad_float ? std::nanf("") : args.tip_size,
});
input.float_values.push_back(pp::app::BrushStrokeFloatValue {
.setting = pp::app::BrushStrokeFloatSetting::jitter_scatter,
.value = args.jitter_scatter,
});
input.bool_values.push_back(pp::app::BrushStrokeBoolValue {
.setting = pp::app::BrushStrokeBoolSetting::dual_enabled,
.value = args.dual_enabled,
});
input.blend_values.push_back(pp::app::BrushStrokeBlendValue {
.setting = pp::app::BrushStrokeBlendSetting::tip,
.blend_mode = args.tip_blend_mode,
});
input.blend_values.push_back(pp::app::BrushStrokeBlendValue {
.setting = pp::app::BrushStrokeBlendSetting::pattern,
.blend_mode = args.bad_blend ? 64 : args.pattern_blend_mode,
});
input.tip_thumbnail_path = args.tip_thumbnail_path;
input.dual_thumbnail_path = args.dual_thumbnail_path;
input.pattern_thumbnail_path = args.pattern_thumbnail_path;
const auto view = pp::app::plan_brush_stroke_panel_view(std::move(input));
if (!view) {
print_error("plan-brush-stroke-panel-view", view.status().message);
return 2;
}
float tip_size = 0.0F;
float jitter_scatter = 0.0F;
bool dual_enabled = false;
int tip_blend_mode = 0;
int pattern_blend_mode = 0;
for (const auto& value : view.value().float_values) {
if (value.setting == pp::app::BrushStrokeFloatSetting::tip_size) {
tip_size = value.value;
} else if (value.setting == pp::app::BrushStrokeFloatSetting::jitter_scatter) {
jitter_scatter = value.value;
}
}
for (const auto& value : view.value().bool_values) {
if (value.setting == pp::app::BrushStrokeBoolSetting::dual_enabled) {
dual_enabled = value.value;
}
}
for (const auto& value : view.value().blend_values) {
if (value.setting == pp::app::BrushStrokeBlendSetting::tip) {
tip_blend_mode = value.blend_mode;
} else if (value.setting == pp::app::BrushStrokeBlendSetting::pattern) {
pattern_blend_mode = value.blend_mode;
}
}
std::cout << "{\"ok\":true,\"command\":\"plan-brush-stroke-panel-view\""
<< ",\"state\":{\"tipSize\":" << args.tip_size
<< ",\"jitterScatter\":" << args.jitter_scatter
<< ",\"dualEnabled\":" << json_bool(args.dual_enabled)
<< ",\"tipBlendMode\":" << args.tip_blend_mode
<< ",\"patternBlendMode\":" << args.pattern_blend_mode
<< "},\"view\":{\"floatValues\":" << view.value().float_values.size()
<< ",\"boolValues\":" << view.value().bool_values.size()
<< ",\"blendValues\":" << view.value().blend_values.size()
<< ",\"tipSize\":" << tip_size
<< ",\"jitterScatter\":" << jitter_scatter
<< ",\"dualEnabled\":" << json_bool(dual_enabled)
<< ",\"tipBlendMode\":" << tip_blend_mode
<< ",\"patternBlendMode\":" << pattern_blend_mode
<< ",\"tipThumb\":\"" << json_escape(view.value().tip_thumbnail_path)
<< "\",\"dualThumb\":\"" << json_escape(view.value().dual_thumbnail_path)
<< "\",\"patternThumb\":\"" << json_escape(view.value().pattern_thumbnail_path)
<< "\",\"updatesPreview\":" << json_bool(view.value().updates_preview)
<< ",\"updatesThumbnails\":" << json_bool(view.value().updates_thumbnails)
<< "}}\n";
return 0;
}
pp::foundation::Status parse_plan_paint_feedback_args(
int argc,
char** argv,
@@ -9337,6 +9499,10 @@ int main(int argc, char** argv)
return plan_brush_stroke_control(argc, argv);
}
if (command == "plan-brush-stroke-panel-view") {
return plan_brush_stroke_panel_view(argc, argv);
}
if (command == "plan-paint-feedback") {
return plan_paint_feedback(argc, argv);
}