Route canvas cursor visibility through app core

This commit is contained in:
2026-06-05 01:39:36 +02:00
parent e95861e9b7
commit f42a6540be
8 changed files with 447 additions and 23 deletions

View File

@@ -515,6 +515,18 @@ struct PlanCanvasToolStateArgs {
bool touch_lock = false;
};
struct PlanCanvasCursorArgs {
std::string mode = "draw";
std::string visibility = "small-brush";
bool has_brush = true;
float brush_size = 9.5F;
bool drawing = false;
bool alt = false;
bool resizing = false;
bool picking = false;
bool bad_size = false;
};
struct PlanQuickOperationArgs {
std::string kind = "brush";
int current_index = 0;
@@ -1456,6 +1468,22 @@ const char* canvas_tool_transform_action_name(pp::app::CanvasToolTransformAction
return "none";
}
const char* canvas_cursor_visibility_mode_name(pp::app::CanvasCursorVisibilityMode mode) noexcept
{
switch (mode) {
case pp::app::CanvasCursorVisibilityMode::never:
return "never";
case pp::app::CanvasCursorVisibilityMode::small_brush:
return "small-brush";
case pp::app::CanvasCursorVisibilityMode::not_painting:
return "not-painting";
case pp::app::CanvasCursorVisibilityMode::always:
return "always";
}
return "never";
}
const char* canvas_hotkey_event_name(pp::app::CanvasHotkeyEvent event) noexcept
{
switch (event) {
@@ -2003,6 +2031,7 @@ void print_help()
<< " 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"
<< " plan-canvas-tool --kind draw|erase|line|camera|grid|copy|cut|fill|mask-free|mask-line|bucket|pick|touch-lock [--current-mode-draw]\n"
<< " plan-canvas-tool-state [--mode draw|erase|line|camera|grid|copy|cut|fill|mask-free|mask-line|bucket] [--picking] [--touch-lock]\n"
<< " plan-canvas-cursor [--mode draw|erase|line|camera|grid|copy|cut|fill|mask-free|mask-line|bucket] [--visibility never|small-brush|not-painting|always] [--brush-size N] [--no-brush] [--drawing] [--alt] [--resizing] [--picking] [--bad-size]\n"
<< " plan-grid-operation --kind pick|load|reload|clear|render|commit [--path FILE] [--no-heightmap] [--no-canvas] [--float32] [--float16] [--texture-resolution N] [--samples N]\n"
<< " plan-history-operation --kind undo|redo|clear [--undo-count N] [--redo-count N] [--memory-bytes N]\n"
<< " plan-main-toolbar --command open|save|undo|redo|clear-history|clear-canvas|message-box|settings [--undo-count N] [--redo-count N] [--memory-bytes N] [--no-canvas]\n"
@@ -6436,6 +6465,30 @@ pp::foundation::Result<pp::app::CanvasToolMode> parse_canvas_tool_mode(std::stri
pp::foundation::Status::invalid_argument("unknown canvas tool mode"));
}
pp::foundation::Result<pp::app::CanvasCursorVisibilityMode> parse_canvas_cursor_visibility_mode(
std::string_view mode)
{
if (mode == "never") {
return pp::foundation::Result<pp::app::CanvasCursorVisibilityMode>::success(
pp::app::CanvasCursorVisibilityMode::never);
}
if (mode == "small-brush") {
return pp::foundation::Result<pp::app::CanvasCursorVisibilityMode>::success(
pp::app::CanvasCursorVisibilityMode::small_brush);
}
if (mode == "not-painting") {
return pp::foundation::Result<pp::app::CanvasCursorVisibilityMode>::success(
pp::app::CanvasCursorVisibilityMode::not_painting);
}
if (mode == "always") {
return pp::foundation::Result<pp::app::CanvasCursorVisibilityMode>::success(
pp::app::CanvasCursorVisibilityMode::always);
}
return pp::foundation::Result<pp::app::CanvasCursorVisibilityMode>::failure(
pp::foundation::Status::invalid_argument("unknown canvas cursor visibility mode"));
}
int plan_canvas_tool(int argc, char** argv)
{
PlanCanvasToolArgs args;
@@ -6693,6 +6746,105 @@ int plan_canvas_tool_state(int argc, char** argv)
return 0;
}
pp::foundation::Status parse_plan_canvas_cursor_args(
int argc,
char** argv,
PlanCanvasCursorArgs& args)
{
for (int i = 2; i < argc; ++i) {
const std::string_view key(argv[i]);
if (key == "--mode" || key == "--visibility") {
if (i + 1 >= argc) {
return pp::foundation::Status::invalid_argument("missing value for option");
}
if (key == "--mode") {
args.mode = argv[++i];
} else {
args.visibility = argv[++i];
}
} else if (key == "--brush-size") {
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();
}
args.brush_size = value.value();
} else if (key == "--no-brush") {
args.has_brush = false;
} else if (key == "--drawing") {
args.drawing = true;
} else if (key == "--alt") {
args.alt = true;
} else if (key == "--resizing") {
args.resizing = true;
} else if (key == "--picking") {
args.picking = true;
} else if (key == "--bad-size") {
args.bad_size = true;
} else {
return pp::foundation::Status::invalid_argument("unknown option");
}
}
return pp::foundation::Status::success();
}
int plan_canvas_cursor(int argc, char** argv)
{
PlanCanvasCursorArgs args;
const auto status = parse_plan_canvas_cursor_args(argc, argv, args);
if (!status.ok()) {
print_error("plan-canvas-cursor", status.message);
return 2;
}
const auto mode = parse_canvas_tool_mode(args.mode);
if (!mode) {
print_error("plan-canvas-cursor", mode.status().message);
return 2;
}
const auto visibility = parse_canvas_cursor_visibility_mode(args.visibility);
if (!visibility) {
print_error("plan-canvas-cursor", visibility.status().message);
return 2;
}
const auto plan = pp::app::plan_canvas_cursor_visibility(pp::app::CanvasCursorVisibilityInput {
.mode = mode.value(),
.visibility_mode = visibility.value(),
.has_current_brush = args.has_brush,
.brush_tip_size = args.bad_size ? std::nanf("") : args.brush_size,
.pen_is_drawing = args.drawing,
.alt_down = args.alt,
.pen_is_resizing = args.resizing,
.pen_is_picking = args.picking,
});
if (!plan) {
print_error("plan-canvas-cursor", plan.status().message);
return 2;
}
const auto& value = plan.value();
std::cout << "{\"ok\":true,\"command\":\"plan-canvas-cursor\""
<< ",\"state\":{\"mode\":\"" << canvas_tool_mode_name(mode.value())
<< "\",\"visibility\":\"" << canvas_cursor_visibility_mode_name(visibility.value())
<< "\",\"hasBrush\":" << json_bool(args.has_brush)
<< ",\"brushSize\":" << args.brush_size
<< ",\"drawing\":" << json_bool(args.drawing)
<< ",\"alt\":" << json_bool(args.alt)
<< ",\"resizing\":" << json_bool(args.resizing)
<< ",\"picking\":" << json_bool(args.picking)
<< "},\"plan\":{\"visible\":" << json_bool(value.visible)
<< ",\"paintMode\":" << json_bool(value.paint_mode)
<< ",\"usesBrushSize\":" << json_bool(value.uses_brush_size)
<< ",\"usesPenState\":" << json_bool(value.uses_pen_state)
<< ",\"forcedVisibleByModifierOrTool\":" << json_bool(value.forced_visible_by_modifier_or_tool)
<< "}}\n";
return 0;
}
pp::foundation::Status parse_plan_grid_operation_args(
int argc,
char** argv,
@@ -9753,6 +9905,10 @@ int main(int argc, char** argv)
return plan_canvas_tool_state(argc, argv);
}
if (command == "plan-canvas-cursor") {
return plan_canvas_cursor(argc, argv);
}
if (command == "plan-grid-operation") {
return plan_grid_operation(argc, argv);
}