Route app input dispatch through app core

This commit is contained in:
2026-06-05 06:38:48 +02:00
parent 1df93c23f7
commit b825d920d2
11 changed files with 695 additions and 46 deletions

View File

@@ -1,6 +1,7 @@
#include "pch.h"
#include "app.h"
#include "app_core/app_frame.h"
#include "app_core/app_input.h"
#include "app_core/document_platform_io.h"
#include "app_core/document_sharing.h"
#include "platform_api/platform_services.h"
@@ -411,164 +412,249 @@ void App::save_prepared_file(
bool App::mouse_down(int button, float x, float y, float pressure, kEventSource source, bool eraser)
{
redraw = true;
const auto plan = pp::app::plan_app_pointer_dispatch(
x,
y,
zoom,
layout_designer.get(main_id) != nullptr,
layout.get(main_id) != nullptr);
if (!plan) {
LOG("Mouse down dispatch plan failed: %s", plan.status().message);
return false;
}
redraw = plan.value().request_redraw;
MouseEvent e;
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
e.m_pos = { x / zoom, y / zoom };
e.m_pos = { plan.value().normalized_x, plan.value().normalized_y };
e.m_pressure = pressure;
e.m_source = source;
e.m_eraser = eraser;
kEventResult ret = kEventResult::Available;
if (auto* main = layout_designer[main_id])
if (auto* main = layout_designer[main_id]; plan.value().dispatch_designer_first && main)
return main->on_event(&e) == kEventResult::Consumed;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.value().dispatch_main_if_not_consumed && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::mouse_move(float x, float y, float pressure, kEventSource source, bool eraser)
{
cursor = { x / zoom, y / zoom };
redraw = true;
const auto plan = pp::app::plan_app_pointer_dispatch(
x,
y,
zoom,
layout_designer.get(main_id) != nullptr,
layout.get(main_id) != nullptr);
if (!plan) {
LOG("Mouse move dispatch plan failed: %s", plan.status().message);
return false;
}
cursor = { plan.value().normalized_x, plan.value().normalized_y };
redraw = plan.value().request_redraw;
MouseEvent e;
e.m_type = kEventType::MouseMove;
e.m_pos = { x / zoom, y / zoom };
e.m_pos = { plan.value().normalized_x, plan.value().normalized_y };
e.m_pressure = pressure;
e.m_source = source;
e.m_eraser = eraser;
kEventResult ret = kEventResult::Available;
if (auto* main = layout_designer[main_id])
if (auto* main = layout_designer[main_id]; plan.value().dispatch_designer_first && main)
return main->on_event(&e) == kEventResult::Consumed;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.value().dispatch_main_if_not_consumed && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::mouse_up(int button, float x, float y, kEventSource source, bool eraser)
{
redraw = true;
const auto plan = pp::app::plan_app_pointer_dispatch(
x,
y,
zoom,
layout_designer.get(main_id) != nullptr,
layout.get(main_id) != nullptr);
if (!plan) {
LOG("Mouse up dispatch plan failed: %s", plan.status().message);
return false;
}
redraw = plan.value().request_redraw;
MouseEvent e;
e.m_type = button ? kEventType::MouseUpR : kEventType::MouseUpL;
e.m_pos = { x / zoom, y / zoom };
e.m_pos = { plan.value().normalized_x, plan.value().normalized_y };
e.m_source = source;
e.m_eraser = eraser;
kEventResult ret = kEventResult::Available;
if (auto* main = layout_designer[main_id])
if (auto* main = layout_designer[main_id]; plan.value().dispatch_designer_first && main)
return main->on_event(&e) == kEventResult::Consumed;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.value().dispatch_main_if_not_consumed && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::mouse_scroll(float x, float y, float delta)
{
redraw = true;
const auto plan = pp::app::plan_app_pointer_dispatch(
x,
y,
zoom,
layout_designer.get(main_id) != nullptr,
layout.get(main_id) != nullptr);
if (!plan) {
LOG("Mouse scroll dispatch plan failed: %s", plan.status().message);
return false;
}
redraw = plan.value().request_redraw;
MouseEvent e;
e.m_type = kEventType::MouseScroll;
e.m_pos = { x / zoom, y / zoom };
e.m_pos = { plan.value().normalized_x, plan.value().normalized_y };
e.m_scroll_delta = delta;
kEventResult ret = kEventResult::Available;
if (auto* main = layout_designer[main_id])
if (auto* main = layout_designer[main_id]; plan.value().dispatch_designer_first && main)
return main->on_event(&e) == kEventResult::Consumed;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.value().dispatch_main_if_not_consumed && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::mouse_cancel(int button)
{
redraw = true;
const auto plan = pp::app::plan_app_mouse_cancel_dispatch(
layout_designer.get(main_id) != nullptr,
layout.get(main_id) != nullptr);
redraw = plan.request_redraw;
MouseEvent e;
e.m_type = kEventType::MouseCancel;
kEventResult ret = kEventResult::Available;
if (auto* main = layout_designer[main_id])
if (auto* main = layout_designer[main_id]; plan.dispatch_designer_first && main)
return main->on_event(&e) == kEventResult::Consumed;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.dispatch_main_if_not_consumed && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::gesture_start(const glm::vec2& p0, const glm::vec2& p1)
{
redraw = true;
const auto plan = pp::app::plan_app_gesture_dispatch(
p0.x,
p0.y,
p1.x,
p1.y,
p0.x,
p0.y,
p1.x,
p1.y,
zoom,
layout.get(main_id) != nullptr);
if (!plan) {
LOG("Gesture start dispatch plan failed: %s", plan.status().message);
return false;
}
redraw = plan.value().request_redraw;
GestureEvent e;
glm::vec2 p = glm::lerp(p0, p1, 0.5f);
e.m_type = kEventType::GestureStart;
e.m_pos = p / glm::vec2(zoom);
e.m_distance = glm::distance(p0, p1);
e.m_pos = { plan.value().normalized_x, plan.value().normalized_y };
e.m_distance = plan.value().distance;
gesture_p0 = p0;
gesture_p1 = p1;
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.value().dispatch_main && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::gesture_move(const glm::vec2& p0, const glm::vec2& p1)
{
redraw = true;
const auto plan = pp::app::plan_app_gesture_dispatch(
p0.x,
p0.y,
p1.x,
p1.y,
gesture_p0.x,
gesture_p0.y,
gesture_p1.x,
gesture_p1.y,
zoom,
layout.get(main_id) != nullptr);
if (!plan) {
LOG("Gesture move dispatch plan failed: %s", plan.status().message);
return false;
}
redraw = plan.value().request_redraw;
GestureEvent e;
glm::vec2 p = glm::lerp(p0, p1, 0.5f);
e.m_type = kEventType::GestureMove;
e.m_pos = p / glm::vec2(zoom);
e.m_distance = glm::distance(p0, p1);
e.m_distance_delta = e.m_distance - glm::distance(gesture_p0, gesture_p1);
e.m_pos_delta = p - glm::lerp(gesture_p0, gesture_p1, 0.5f);
e.m_pos = { plan.value().normalized_x, plan.value().normalized_y };
e.m_distance = plan.value().distance;
e.m_distance_delta = plan.value().distance_delta;
e.m_pos_delta = { plan.value().position_delta_x, plan.value().position_delta_y };
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.value().dispatch_main && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::gesture_end()
{
redraw = true;
const auto plan = pp::app::plan_app_main_input_dispatch(layout.get(main_id) != nullptr);
redraw = plan.request_redraw;
GestureEvent e;
e.m_type = kEventType::GestureEnd;
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.dispatch_main && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::touch_tap(const glm::vec2& pos, int fingers, int tap_count)
{
redraw = true;
const auto plan = pp::app::plan_app_main_input_dispatch(layout.get(main_id) != nullptr);
redraw = plan.request_redraw;
TouchEvent e;
e.m_type = kEventType::TouchTap;
e.m_finger_count = fingers;
e.m_tap_count = tap_count;
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.dispatch_main && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::key_down(kKey key)
{
if (key == kKey::KeySpacebar && vr_active)
const auto plan = pp::app::plan_app_key_down_dispatch(
layout.get(main_id) != nullptr,
key == kKey::KeySpacebar,
vr_active);
if (plan.sync_vr_camera_rotation)
canvas->m_canvas->m_cam_rot = vr_rot;
redraw = true;
keys[(int)key] = true;
redraw = plan.request_redraw;
keys[(int)key] = plan.set_key_down;
KeyEvent e;
e.m_type = kEventType::KeyDown;
e.m_key = key;
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.dispatch_main && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::key_up(kKey key)
{
redraw = true;
keys[(int)key] = false;
const auto plan = pp::app::plan_app_key_up_dispatch(layout.get(main_id) != nullptr);
redraw = plan.request_redraw;
keys[(int)key] = plan.set_key_down;
KeyEvent e;
e.m_type = kEventType::KeyUp;
e.m_key = key;
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.dispatch_main && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}
bool App::key_char(char key)
{
redraw = true;
const auto plan = pp::app::plan_app_main_input_dispatch(layout.get(main_id) != nullptr);
redraw = plan.request_redraw;
KeyEvent e;
e.m_type = kEventType::KeyChar;
e.m_char = key;
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
if (auto* main = layout[main_id]; plan.dispatch_main && main)
ret = main->on_event(&e);
return ret == kEventResult::Consumed;
}