Extract canvas toolbar state planning
This commit is contained in:
@@ -44,7 +44,7 @@ agent or engineer to remove them without reconstructing context from chat.
|
||||
| DEBT-0024 | Open | Modernization | Grid/heightmap/lightmap UI planning now consumes pure `pp_app_core` through `NodePanelGrid` and `pano_cli plan-grid-operation`, but live execution still performs legacy image loading, OpenGL texture updates, nanort lightmap baking, progress UI, and `Canvas::draw_objects` commit directly | Preserve grid/lightmap behavior while moving renderable grid commands toward app/renderer/document boundaries | `pp_app_core_grid_ui_tests`; `pano_cli plan-grid-operation --kind render --float32 --texture-resolution 1024 --samples 32`; `ctest --preset desktop-fast --build-config Debug` | Grid heightmap/lightmap execution is owned by app/renderer/document services with `NodePanelGrid` acting only as UI adapter |
|
||||
| DEBT-0025 | Open | Modernization | Quick brush/color slot and mini-state planning now consumes pure `pp_app_core` through `NodePanelQuick` and `pano_cli plan-quick-operation`, but live execution still mutates legacy quick UI widgets, `Brush` previews, color picker popup state, and preset popup state directly | Preserve quick-panel behavior while quick brush/color commands move toward a brush/app command boundary with safer automation coverage | `pp_app_core_quick_ui_tests`; `pano_cli plan-quick-operation --kind brush --current-index 0 --slot-index 2`; `pano_cli plan-quick-operation --kind restore --brush-index 2 --color-index 1 --fire-event`; `ctest --preset desktop-fast --build-config Debug` | Quick-panel selection, popup, restore, reset, brush preview, and color execution are owned by app/brush/UI services with `NodePanelQuick` acting only as UI adapter |
|
||||
| DEBT-0026 | Open | Modernization | Toolbar and canvas history command planning now consumes pure `pp_app_core` through `App::init_toolbar_main`, `NodeCanvas`, and `pano_cli plan-history-operation`, but live execution still mutates legacy `ActionManager` stacks and `Canvas::I` unsaved state directly | Preserve undo/redo/clear behavior while moving action history toward document/app command services | `pp_app_core_history_ui_tests`; `pano_cli plan-history-operation --kind undo --undo-count 2`; `pano_cli plan-history-operation --kind clear --undo-count 2 --redo-count 1 --memory-bytes 4096`; `ctest --preset desktop-fast --build-config Debug` | Undo/redo/clear execution is owned by document/app history services with toolbar and canvas input acting only as adapters |
|
||||
| DEBT-0027 | Open | Modernization | Canvas draw-tool toolbar planning now consumes pure `pp_app_core` through `App::init_toolbar_draw` and `pano_cli plan-canvas-tool`, but live execution still mutates legacy `Canvas` mode state, pen picking state, touch-lock state, and transform copy/cut action objects directly | Preserve current toolbar behavior while canvas input/tools move toward an app/document command boundary | `pp_app_core_canvas_tool_ui_tests`; `pano_cli plan-canvas-tool --kind copy`; `pano_cli plan-canvas-tool --kind pick`; `ctest --preset desktop-fast --build-config Debug` | Canvas tool selection, picking, touch lock, and transform action execution are owned by app/document/canvas services with toolbar callbacks acting only as adapters |
|
||||
| DEBT-0027 | Open | Modernization | Canvas draw-tool toolbar command and active-state planning now consume pure `pp_app_core` through `App::init_toolbar_draw`, `App::update`, `pano_cli plan-canvas-tool`, and `pano_cli plan-canvas-tool-state`, but live execution/state storage still mutates or reads legacy `Canvas` mode state, pen picking state, touch-lock state, and transform copy/cut action objects directly | Preserve current toolbar behavior while canvas input/tools move toward an app/document command boundary | `pp_app_core_canvas_tool_ui_tests`; `pano_cli plan-canvas-tool --kind copy`; `pano_cli plan-canvas-tool-state --mode draw --picking --touch-lock`; `ctest --preset desktop-fast --build-config Debug` | Canvas tool selection, toolbar state refresh, picking, touch lock, and transform action execution are owned by app/document/canvas services with toolbar callbacks acting only as adapters |
|
||||
|
||||
## Closed Debt
|
||||
|
||||
|
||||
@@ -502,7 +502,9 @@ callbacks before legacy `Brush` mutation and resource loading continue.
|
||||
`pano_cli plan-canvas-tool` exposes app-core planning for draw/erase/line,
|
||||
camera, grid, copy, cut, fill, mask, flood-fill, pick, and touch-lock toolbar
|
||||
commands before legacy `Canvas` mode, pen picking, touch-lock, and transform
|
||||
state mutation continue.
|
||||
state mutation continue. `pano_cli plan-canvas-tool-state` exposes the matching
|
||||
toolbar active-state refresh used by `App::update` before legacy `Canvas` mode
|
||||
state remains the source of truth.
|
||||
`pano_cli plan-grid-operation` exposes app-core planning for grid heightmap
|
||||
pick/load/reload/clear, lightmap render capability/limit checks, and heightmap
|
||||
commit used by the live grid panel before legacy image loading, OpenGL texture
|
||||
@@ -1164,13 +1166,18 @@ Results:
|
||||
grid/heightmap/lightmap planning as JSON automation.
|
||||
- `pp_app_core_canvas_tool_ui_tests` passed, covering toolbar mode selection,
|
||||
copy/cut transform action planning, pick no-op outside draw mode, and
|
||||
touch-lock toggling.
|
||||
touch-lock toggling, plus toolbar active-state derivation for draw, copy, and
|
||||
bucket modes.
|
||||
- `pano_cli_plan_canvas_tool_draw_smoke`,
|
||||
`pano_cli_plan_canvas_tool_copy_smoke`,
|
||||
`pano_cli_plan_canvas_tool_pick_noop_smoke`,
|
||||
`pano_cli_plan_canvas_tool_touch_lock_smoke`, and
|
||||
`pano_cli_plan_canvas_tool_rejects_unknown` passed and expose live draw
|
||||
toolbar planning as JSON automation.
|
||||
- `pano_cli_plan_canvas_tool_state_draw_smoke`,
|
||||
`pano_cli_plan_canvas_tool_state_copy_smoke`, and
|
||||
`pano_cli_plan_canvas_tool_state_rejects_unknown` passed and expose draw
|
||||
toolbar active-state refresh as JSON automation.
|
||||
- `pp_app_core_history_ui_tests` passed, covering undo/redo availability,
|
||||
no-op history commands, clear-history stack/memory state, memory-only clear,
|
||||
and negative metric rejection.
|
||||
|
||||
62
src/app.cpp
62
src/app.cpp
@@ -6,6 +6,7 @@
|
||||
#include "node_progress_bar.h"
|
||||
#include "mp4enc.h"
|
||||
#include "app_core/app_status.h"
|
||||
#include "app_core/canvas_tool_ui.h"
|
||||
#include "app_core/document_recording.h"
|
||||
#include "app_core/document_route.h"
|
||||
#include "app_core/document_session.h"
|
||||
@@ -36,6 +37,36 @@ void enable_opengl_state(std::uint32_t state) noexcept
|
||||
glEnable(static_cast<GLenum>(state));
|
||||
}
|
||||
|
||||
pp::app::CanvasToolMode canvas_tool_mode_from_canvas_mode(kCanvasMode mode) noexcept
|
||||
{
|
||||
switch (mode) {
|
||||
case kCanvasMode::Draw:
|
||||
return pp::app::CanvasToolMode::draw;
|
||||
case kCanvasMode::Erase:
|
||||
return pp::app::CanvasToolMode::erase;
|
||||
case kCanvasMode::Line:
|
||||
return pp::app::CanvasToolMode::line;
|
||||
case kCanvasMode::Camera:
|
||||
return pp::app::CanvasToolMode::camera;
|
||||
case kCanvasMode::Grid:
|
||||
return pp::app::CanvasToolMode::grid;
|
||||
case kCanvasMode::Copy:
|
||||
return pp::app::CanvasToolMode::copy;
|
||||
case kCanvasMode::Cut:
|
||||
return pp::app::CanvasToolMode::cut;
|
||||
case kCanvasMode::Fill:
|
||||
return pp::app::CanvasToolMode::fill;
|
||||
case kCanvasMode::MaskFree:
|
||||
return pp::app::CanvasToolMode::mask_free;
|
||||
case kCanvasMode::MaskLine:
|
||||
return pp::app::CanvasToolMode::mask_line;
|
||||
case kCanvasMode::FloodFill:
|
||||
return pp::app::CanvasToolMode::flood_fill;
|
||||
default:
|
||||
return pp::app::CanvasToolMode::draw;
|
||||
}
|
||||
}
|
||||
|
||||
void disable_opengl_state(std::uint32_t state) noexcept
|
||||
{
|
||||
glDisable(static_cast<GLenum>(state));
|
||||
@@ -631,25 +662,26 @@ void App::update(float dt)
|
||||
main->update(width, height, zoom);
|
||||
|
||||
{
|
||||
static glm::vec4 color_button_normal{ .1, .1, .1, 1 };
|
||||
static glm::vec4 color_button_hlight{ 1, .0, .0, 1 };
|
||||
|
||||
auto mode = Canvas::I->m_current_mode;
|
||||
|
||||
CanvasModePen* pm = (CanvasModePen*)canvas->m_canvas->modes[(int)kCanvasMode::Draw][0];
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-pick")->set_active(mode == kCanvasMode::Draw && pm->m_picking);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-touchlock")->set_active(canvas->m_canvas->m_touch_lock);
|
||||
const auto toolbar = pp::app::plan_canvas_tool_button_state(
|
||||
canvas_tool_mode_from_canvas_mode(mode),
|
||||
pm && pm->m_picking,
|
||||
canvas->m_canvas->m_touch_lock);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-pick")->set_active(toolbar.pick_active);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-touchlock")->set_active(toolbar.touch_lock_active);
|
||||
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-pen")->set_active(mode == kCanvasMode::Draw);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-erase")->set_active(mode == kCanvasMode::Erase);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_active(mode == kCanvasMode::Camera);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-line")->set_active(mode == kCanvasMode::Line);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_active(mode == kCanvasMode::Grid);
|
||||
layout[main_id]->find<NodeButton>("btn-copy")->set_active(mode == kCanvasMode::Copy);
|
||||
layout[main_id]->find<NodeButton>("btn-cut")->set_active(mode == kCanvasMode::Cut);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-mask-free")->set_active(mode == kCanvasMode::MaskFree);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-mask-line")->set_active(mode == kCanvasMode::MaskLine);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-bucket")->set_active(mode == kCanvasMode::FloodFill);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-pen")->set_active(toolbar.pen_active);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-erase")->set_active(toolbar.erase_active);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_active(toolbar.camera_active);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-line")->set_active(toolbar.line_active);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_active(toolbar.grid_active);
|
||||
layout[main_id]->find<NodeButton>("btn-copy")->set_active(toolbar.copy_active);
|
||||
layout[main_id]->find<NodeButton>("btn-cut")->set_active(toolbar.cut_active);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-mask-free")->set_active(toolbar.mask_free_active);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-mask-line")->set_active(toolbar.mask_line_active);
|
||||
layout[main_id]->find<NodeButtonCustom>("btn-bucket")->set_active(toolbar.flood_fill_active);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,23 @@ struct CanvasToolPlan {
|
||||
bool no_op = false;
|
||||
};
|
||||
|
||||
struct CanvasToolButtonState {
|
||||
CanvasToolMode mode = CanvasToolMode::draw;
|
||||
bool pick_active = false;
|
||||
bool touch_lock_active = false;
|
||||
bool pen_active = false;
|
||||
bool erase_active = false;
|
||||
bool line_active = false;
|
||||
bool camera_active = false;
|
||||
bool grid_active = false;
|
||||
bool copy_active = false;
|
||||
bool cut_active = false;
|
||||
bool fill_active = false;
|
||||
bool mask_free_active = false;
|
||||
bool mask_line_active = false;
|
||||
bool flood_fill_active = false;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline constexpr CanvasToolTransformAction transform_action_for_mode(CanvasToolMode mode) noexcept
|
||||
{
|
||||
if (mode == CanvasToolMode::copy) {
|
||||
@@ -83,4 +100,27 @@ struct CanvasToolPlan {
|
||||
return plan;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr CanvasToolButtonState plan_canvas_tool_button_state(
|
||||
CanvasToolMode mode,
|
||||
bool picking,
|
||||
bool touch_lock) noexcept
|
||||
{
|
||||
CanvasToolButtonState state;
|
||||
state.mode = mode;
|
||||
state.pick_active = mode == CanvasToolMode::draw && picking;
|
||||
state.touch_lock_active = touch_lock;
|
||||
state.pen_active = mode == CanvasToolMode::draw;
|
||||
state.erase_active = mode == CanvasToolMode::erase;
|
||||
state.line_active = mode == CanvasToolMode::line;
|
||||
state.camera_active = mode == CanvasToolMode::camera;
|
||||
state.grid_active = mode == CanvasToolMode::grid;
|
||||
state.copy_active = mode == CanvasToolMode::copy;
|
||||
state.cut_active = mode == CanvasToolMode::cut;
|
||||
state.fill_active = mode == CanvasToolMode::fill;
|
||||
state.mask_free_active = mode == CanvasToolMode::mask_free;
|
||||
state.mask_line_active = mode == CanvasToolMode::mask_line;
|
||||
state.flood_fill_active = mode == CanvasToolMode::flood_fill;
|
||||
return state;
|
||||
}
|
||||
|
||||
} // namespace pp::app
|
||||
|
||||
@@ -886,6 +886,24 @@ if(TARGET pano_cli)
|
||||
LABELS "app;ui;integration;desktop-fast;fuzz"
|
||||
WILL_FAIL TRUE)
|
||||
|
||||
add_test(NAME pano_cli_plan_canvas_tool_state_draw_smoke
|
||||
COMMAND pano_cli plan-canvas-tool-state --mode draw --picking --touch-lock)
|
||||
set_tests_properties(pano_cli_plan_canvas_tool_state_draw_smoke PROPERTIES
|
||||
LABELS "app;ui;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool-state\".*\"mode\":\"draw\".*\"pickActive\":true.*\"touchLockActive\":true.*\"penActive\":true")
|
||||
|
||||
add_test(NAME pano_cli_plan_canvas_tool_state_copy_smoke
|
||||
COMMAND pano_cli plan-canvas-tool-state --mode copy --picking)
|
||||
set_tests_properties(pano_cli_plan_canvas_tool_state_copy_smoke PROPERTIES
|
||||
LABELS "app;ui;integration;desktop-fast;fuzz"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-tool-state\".*\"mode\":\"copy\".*\"pickActive\":false.*\"penActive\":false.*\"copyActive\":true")
|
||||
|
||||
add_test(NAME pano_cli_plan_canvas_tool_state_rejects_unknown
|
||||
COMMAND pano_cli plan-canvas-tool-state --mode warp)
|
||||
set_tests_properties(pano_cli_plan_canvas_tool_state_rejects_unknown PROPERTIES
|
||||
LABELS "app;ui;integration;desktop-fast;fuzz"
|
||||
WILL_FAIL TRUE)
|
||||
|
||||
add_test(NAME pano_cli_plan_grid_operation_pick_smoke
|
||||
COMMAND pano_cli plan-grid-operation --kind pick)
|
||||
set_tests_properties(pano_cli_plan_grid_operation_pick_smoke PROPERTIES
|
||||
|
||||
@@ -50,6 +50,37 @@ void pick_and_touch_lock_toggle_state(pp::tests::Harness& harness)
|
||||
PP_EXPECT(harness, !touch_lock.no_op);
|
||||
}
|
||||
|
||||
void button_state_tracks_active_mode_and_toggles(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto draw = pp::app::plan_canvas_tool_button_state(
|
||||
pp::app::CanvasToolMode::draw,
|
||||
true,
|
||||
true);
|
||||
PP_EXPECT(harness, draw.mode == pp::app::CanvasToolMode::draw);
|
||||
PP_EXPECT(harness, draw.pick_active);
|
||||
PP_EXPECT(harness, draw.touch_lock_active);
|
||||
PP_EXPECT(harness, draw.pen_active);
|
||||
PP_EXPECT(harness, !draw.erase_active);
|
||||
PP_EXPECT(harness, !draw.copy_active);
|
||||
PP_EXPECT(harness, !draw.flood_fill_active);
|
||||
|
||||
const auto copy = pp::app::plan_canvas_tool_button_state(
|
||||
pp::app::CanvasToolMode::copy,
|
||||
true,
|
||||
false);
|
||||
PP_EXPECT(harness, copy.copy_active);
|
||||
PP_EXPECT(harness, !copy.pick_active);
|
||||
PP_EXPECT(harness, !copy.touch_lock_active);
|
||||
PP_EXPECT(harness, !copy.pen_active);
|
||||
|
||||
const auto bucket = pp::app::plan_canvas_tool_button_state(
|
||||
pp::app::CanvasToolMode::flood_fill,
|
||||
false,
|
||||
false);
|
||||
PP_EXPECT(harness, bucket.flood_fill_active);
|
||||
PP_EXPECT(harness, !bucket.mask_line_active);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
@@ -58,5 +89,6 @@ int main()
|
||||
harness.run("selection plans canvas modes", selection_plans_canvas_modes);
|
||||
harness.run("transform tools plan copy and cut actions", transform_tools_plan_copy_and_cut_actions);
|
||||
harness.run("pick and touch lock toggle state", pick_and_touch_lock_toggle_state);
|
||||
harness.run("button state tracks active mode and toggles", button_state_tracks_active_mode_and_toggles);
|
||||
return harness.finish();
|
||||
}
|
||||
|
||||
@@ -290,6 +290,12 @@ struct PlanCanvasToolArgs {
|
||||
bool current_mode_draw = false;
|
||||
};
|
||||
|
||||
struct PlanCanvasToolStateArgs {
|
||||
std::string mode = "draw";
|
||||
bool picking = false;
|
||||
bool touch_lock = false;
|
||||
};
|
||||
|
||||
struct PlanQuickOperationArgs {
|
||||
std::string kind = "brush";
|
||||
int current_index = 0;
|
||||
@@ -1005,6 +1011,7 @@ void print_help()
|
||||
<< " 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-brush-operation --kind color|tip|pattern|dual|preset|settings [--path FILE] [--thumb FILE] [--r N] [--g N] [--b N] [--a N] [--no-brush]\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-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-quick-operation --kind brush|color|restore|reset [--current-index N] [--slot-index N] [--brush-index N] [--color-index N] [--slot-count N] [--fire-event]\n"
|
||||
@@ -3127,6 +3134,46 @@ pp::foundation::Result<pp::app::CanvasToolPlan> make_canvas_tool_plan(const Plan
|
||||
pp::foundation::Status::invalid_argument("unknown canvas tool kind"));
|
||||
}
|
||||
|
||||
pp::foundation::Result<pp::app::CanvasToolMode> parse_canvas_tool_mode(std::string_view mode)
|
||||
{
|
||||
if (mode == "draw") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::draw);
|
||||
}
|
||||
if (mode == "erase") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::erase);
|
||||
}
|
||||
if (mode == "line") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::line);
|
||||
}
|
||||
if (mode == "camera") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::camera);
|
||||
}
|
||||
if (mode == "grid") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::grid);
|
||||
}
|
||||
if (mode == "copy") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::copy);
|
||||
}
|
||||
if (mode == "cut") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::cut);
|
||||
}
|
||||
if (mode == "fill") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::fill);
|
||||
}
|
||||
if (mode == "mask-free") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::mask_free);
|
||||
}
|
||||
if (mode == "mask-line") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::mask_line);
|
||||
}
|
||||
if (mode == "bucket") {
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::success(pp::app::CanvasToolMode::flood_fill);
|
||||
}
|
||||
|
||||
return pp::foundation::Result<pp::app::CanvasToolMode>::failure(
|
||||
pp::foundation::Status::invalid_argument("unknown canvas tool mode"));
|
||||
}
|
||||
|
||||
int plan_canvas_tool(int argc, char** argv)
|
||||
{
|
||||
PlanCanvasToolArgs args;
|
||||
@@ -3159,6 +3206,71 @@ int plan_canvas_tool(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_canvas_tool_state_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
PlanCanvasToolStateArgs& args)
|
||||
{
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
const std::string_view key(argv[i]);
|
||||
if (key == "--mode") {
|
||||
if (i + 1 >= argc) {
|
||||
return pp::foundation::Status::invalid_argument("missing value for option");
|
||||
}
|
||||
args.mode = argv[++i];
|
||||
} else if (key == "--picking") {
|
||||
args.picking = true;
|
||||
} else if (key == "--touch-lock") {
|
||||
args.touch_lock = true;
|
||||
} else {
|
||||
return pp::foundation::Status::invalid_argument("unknown option");
|
||||
}
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
int plan_canvas_tool_state(int argc, char** argv)
|
||||
{
|
||||
PlanCanvasToolStateArgs args;
|
||||
const auto status = parse_plan_canvas_tool_state_args(argc, argv, args);
|
||||
if (!status.ok()) {
|
||||
print_error("plan-canvas-tool-state", status.message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto mode = parse_canvas_tool_mode(args.mode);
|
||||
if (!mode) {
|
||||
print_error("plan-canvas-tool-state", mode.status().message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto state = pp::app::plan_canvas_tool_button_state(
|
||||
mode.value(),
|
||||
args.picking,
|
||||
args.touch_lock);
|
||||
std::cout << "{\"ok\":true,\"command\":\"plan-canvas-tool-state\""
|
||||
<< ",\"state\":{\"mode\":\"" << json_escape(args.mode)
|
||||
<< "\",\"picking\":" << json_bool(args.picking)
|
||||
<< ",\"touchLock\":" << json_bool(args.touch_lock)
|
||||
<< "},\"toolbar\":{\"mode\":\"" << canvas_tool_mode_name(state.mode)
|
||||
<< "\",\"pickActive\":" << json_bool(state.pick_active)
|
||||
<< ",\"touchLockActive\":" << json_bool(state.touch_lock_active)
|
||||
<< ",\"penActive\":" << json_bool(state.pen_active)
|
||||
<< ",\"eraseActive\":" << json_bool(state.erase_active)
|
||||
<< ",\"lineActive\":" << json_bool(state.line_active)
|
||||
<< ",\"cameraActive\":" << json_bool(state.camera_active)
|
||||
<< ",\"gridActive\":" << json_bool(state.grid_active)
|
||||
<< ",\"copyActive\":" << json_bool(state.copy_active)
|
||||
<< ",\"cutActive\":" << json_bool(state.cut_active)
|
||||
<< ",\"fillActive\":" << json_bool(state.fill_active)
|
||||
<< ",\"maskFreeActive\":" << json_bool(state.mask_free_active)
|
||||
<< ",\"maskLineActive\":" << json_bool(state.mask_line_active)
|
||||
<< ",\"bucketActive\":" << json_bool(state.flood_fill_active)
|
||||
<< "}}\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_grid_operation_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
@@ -5907,6 +6019,10 @@ int main(int argc, char** argv)
|
||||
return plan_canvas_tool(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-canvas-tool-state") {
|
||||
return plan_canvas_tool_state(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-grid-operation") {
|
||||
return plan_grid_operation(argc, argv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user