Extract UI state and Win32 window shell
This commit is contained in:
@@ -97,6 +97,7 @@ set(PP_PANOPAINTER_APP_SOURCES
|
|||||||
src/app_dialogs_info_openers.cpp
|
src/app_dialogs_info_openers.cpp
|
||||||
src/app_events.cpp
|
src/app_events.cpp
|
||||||
src/app_layout.cpp
|
src/app_layout.cpp
|
||||||
|
src/app_layout_ui_state.cpp
|
||||||
src/app_layout_sidebar.cpp
|
src/app_layout_sidebar.cpp
|
||||||
src/app_layout_main_toolbar.cpp
|
src/app_layout_main_toolbar.cpp
|
||||||
src/app_layout_edit_menu.cpp
|
src/app_layout_edit_menu.cpp
|
||||||
@@ -177,6 +178,8 @@ set(PP_WINDOWS_PLATFORM_SOURCES
|
|||||||
src/platform_windows/windows_splash.h
|
src/platform_windows/windows_splash.h
|
||||||
src/platform_windows/windows_stylus_input.cpp
|
src/platform_windows/windows_stylus_input.cpp
|
||||||
src/platform_windows/windows_stylus_input.h
|
src/platform_windows/windows_stylus_input.h
|
||||||
|
src/platform_windows/windows_window_shell.cpp
|
||||||
|
src/platform_windows/windows_window_shell.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PP_WINDOWS_APP_SOURCES
|
set(PP_WINDOWS_APP_SOURCES
|
||||||
|
|||||||
@@ -80,12 +80,12 @@ What is still carrying too much live ownership:
|
|||||||
Current hotspot files:
|
Current hotspot files:
|
||||||
|
|
||||||
- `src/canvas.cpp`: 2645 lines
|
- `src/canvas.cpp`: 2645 lines
|
||||||
- `src/app_layout.cpp`: 717 lines
|
- `src/app_layout.cpp`: 353 lines
|
||||||
- `src/canvas_modes.cpp`: 1798 lines
|
- `src/canvas_modes.cpp`: 1798 lines
|
||||||
- `src/node.cpp`: 1594 lines
|
- `src/node.cpp`: 1594 lines
|
||||||
- `src/main.cpp`: 847 lines
|
- `src/main.cpp`: 487 lines
|
||||||
- `src/node_panel_brush.cpp`: 1197 lines
|
- `src/node_panel_brush.cpp`: 1197 lines
|
||||||
- `src/node_stroke_preview.cpp`: 948 lines
|
- `src/node_stroke_preview.cpp`: 890 lines
|
||||||
- `src/node_canvas.cpp`: 910 lines
|
- `src/node_canvas.cpp`: 910 lines
|
||||||
- `src/app.cpp`: 502 lines
|
- `src/app.cpp`: 502 lines
|
||||||
- `src/app_dialogs.cpp`: 142 lines
|
- `src/app_dialogs.cpp`: 142 lines
|
||||||
@@ -144,7 +144,10 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
now also lives in `src/app_layout_main_toolbar.cpp` and
|
now also lives in `src/app_layout_main_toolbar.cpp` and
|
||||||
`App::init_toolbar_main()` is now a thin call-through, while edit-menu
|
`App::init_toolbar_main()` is now a thin call-through, while edit-menu
|
||||||
binding now also lives in `src/app_layout_edit_menu.cpp` and
|
binding now also lives in `src/app_layout_edit_menu.cpp` and
|
||||||
`App::init_menu_edit()` is now a thin call-through, while the
|
`App::init_menu_edit()` is now a thin call-through, while UI-direction and
|
||||||
|
persisted floating/docked panel-state ownership now also live in
|
||||||
|
`src/app_layout_ui_state.cpp`, and `src/app_layout.cpp` is now mostly
|
||||||
|
layout/bootstrap composition, while the
|
||||||
informational overlay opener family now also lives in
|
informational overlay opener family now also lives in
|
||||||
`src/app_dialogs_info_openers.cpp` and the corresponding `App::dialog_*`
|
`src/app_dialogs_info_openers.cpp` and the corresponding `App::dialog_*`
|
||||||
entrypoints are thinner, while the export/video/PPBR dialog family now also
|
entrypoints are thinner, while the export/video/PPBR dialog family now also
|
||||||
@@ -192,8 +195,10 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
`src/platform_windows/windows_bootstrap_helpers.*` for runtime-data
|
`src/platform_windows/windows_bootstrap_helpers.*` for runtime-data
|
||||||
discovery, startup-state initialization, window creation, pixel-format
|
discovery, startup-state initialization, window creation, pixel-format
|
||||||
setup, GL loader init, runtime-info logging, and core-context upgrade
|
setup, GL loader init, runtime-info logging, and core-context upgrade
|
||||||
sequencing, which materially thins `src/main.cpp` even though broader window
|
sequencing, while the Win32 window procedure and retained message-handling
|
||||||
procedure and retained shell flow still remain there,
|
shell now also live in `src/platform_windows/windows_window_shell.*`
|
||||||
|
instead of `src/main.cpp`, which materially thins `src/main.cpp` even
|
||||||
|
though broader entrypoint/runtime composition still remains there,
|
||||||
while `App::rec_loop()` now delegates worker-iteration orchestration into
|
while `App::rec_loop()` now delegates worker-iteration orchestration into
|
||||||
the retained recording bridge, `App::update_rec_frames()` now delegates
|
the retained recording bridge, `App::update_rec_frames()` now delegates
|
||||||
recording label refresh through that same retained recording path, and the
|
recording label refresh through that same retained recording path, and the
|
||||||
@@ -212,7 +217,10 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
still owns worker-side readback flow and encoder-state label reads, while the
|
still owns worker-side readback flow and encoder-state label reads, while the
|
||||||
main live-pass request assembly and framebuffer-copy setup now also route
|
main live-pass request assembly and framebuffer-copy setup now also route
|
||||||
through `src/legacy_node_stroke_preview_execution_services.h`, even though
|
through `src/legacy_node_stroke_preview_execution_services.h`, even though
|
||||||
broader preview-pass orchestration still lives in `src/node_stroke_preview.cpp`, while
|
broader preview-pass orchestration still lives in
|
||||||
|
`src/node_stroke_preview.cpp`, while the immediate preview pass-sequencing
|
||||||
|
family inside `draw_stroke_immediate()` now also routes through
|
||||||
|
`NodeStrokePreview::execute_stroke_draw_immediate_pass_sequence(...)`, while
|
||||||
`Node` child attach/detach/reorder operations now route through named local
|
`Node` child attach/detach/reorder operations now route through named local
|
||||||
helpers in `src/node.cpp`, which makes the scene-graph mutation paths easier
|
helpers in `src/node.cpp`, which makes the scene-graph mutation paths easier
|
||||||
to reason about without yet reducing the file or moving ownership into
|
to reason about without yet reducing the file or moving ownership into
|
||||||
|
|||||||
@@ -153,6 +153,11 @@ Current slice:
|
|||||||
`legacy_node_stroke_preview_execution_services.h`, which trims another
|
`legacy_node_stroke_preview_execution_services.h`, which trims another
|
||||||
coherent pass-setup block from `src/node_stroke_preview.cpp`, but broader
|
coherent pass-setup block from `src/node_stroke_preview.cpp`, but broader
|
||||||
preview-pass orchestration is still inline.
|
preview-pass orchestration is still inline.
|
||||||
|
- `NodeStrokePreview::draw_stroke_immediate()` immediate preview pass
|
||||||
|
sequencing now also routes through the private
|
||||||
|
`execute_stroke_draw_immediate_pass_sequence(...)` helper, which removes
|
||||||
|
another live orchestration block from the node even though worker/readback
|
||||||
|
flow still remains in the file.
|
||||||
- `NodeCanvas` merged-path per-plane merged-texture draw execution now also
|
- `NodeCanvas` merged-path per-plane merged-texture draw execution now also
|
||||||
routes through `execute_legacy_canvas_draw_merge_layer_texture(...)`.
|
routes through `execute_legacy_canvas_draw_merge_layer_texture(...)`.
|
||||||
- `NodeCanvas` merged-path and non-blend checkerboard background setup now also
|
- `NodeCanvas` merged-path and non-blend checkerboard background setup now also
|
||||||
@@ -298,7 +303,7 @@ targets look like helpers under one old monolith.
|
|||||||
Status: In Progress
|
Status: In Progress
|
||||||
|
|
||||||
Why now:
|
Why now:
|
||||||
`src/app_layout.cpp` is still a 717-line mixed file that builds menus,
|
`src/app_layout.cpp` is still a 353-line mixed file that builds menus,
|
||||||
attaches callbacks, computes planner inputs, and mutates UI state directly.
|
attaches callbacks, computes planner inputs, and mutates UI state directly.
|
||||||
|
|
||||||
Current slice:
|
Current slice:
|
||||||
@@ -325,6 +330,9 @@ Current slice:
|
|||||||
`App::init_menu_edit()` is now a thin call-through, but draw-toolbar,
|
`App::init_menu_edit()` is now a thin call-through, but draw-toolbar,
|
||||||
brush-refresh, and broader layout composition are still inline in
|
brush-refresh, and broader layout composition are still inline in
|
||||||
`src/app_layout.cpp`.
|
`src/app_layout.cpp`.
|
||||||
|
- UI-direction plus persisted floating/docked panel-state ownership now also
|
||||||
|
lives in `src/app_layout_ui_state.cpp`, and `src/app_layout.cpp` is down to
|
||||||
|
the remaining draw-toolbar, brush-refresh, and layout/bootstrap composition.
|
||||||
|
|
||||||
Write scope:
|
Write scope:
|
||||||
- `src/app_layout.cpp`
|
- `src/app_layout.cpp`
|
||||||
@@ -489,8 +497,11 @@ Current slice:
|
|||||||
`src/platform_windows/windows_bootstrap_helpers.*` for runtime-data
|
`src/platform_windows/windows_bootstrap_helpers.*` for runtime-data
|
||||||
discovery, startup-state initialization, window creation, pixel-format
|
discovery, startup-state initialization, window creation, pixel-format
|
||||||
setup, GL loader init, runtime-info logging, and core-context upgrade
|
setup, GL loader init, runtime-info logging, and core-context upgrade
|
||||||
sequencing, which materially thins `src/main.cpp`, but the retained Win32
|
sequencing
|
||||||
window procedure and broader shell flow are still open
|
- the Win32 window procedure and retained message-handling shell now also live
|
||||||
|
in `src/platform_windows/windows_window_shell.*` instead of `src/main.cpp`,
|
||||||
|
which materially thins the entry file even though broader runtime/entrypoint
|
||||||
|
composition is still open
|
||||||
- prepared-file background work now runs through an `AppRuntime`-owned worker
|
- prepared-file background work now runs through an `AppRuntime`-owned worker
|
||||||
queue instead of a retained static worker in `src/app_events.cpp`
|
queue instead of a retained static worker in `src/app_events.cpp`
|
||||||
- canvas async import/export/save/open background work now also runs through an
|
- canvas async import/export/save/open background work now also runs through an
|
||||||
|
|||||||
@@ -21,8 +21,6 @@
|
|||||||
#include "legacy_canvas_tool_services.h"
|
#include "legacy_canvas_tool_services.h"
|
||||||
#include "legacy_document_layer_services.h"
|
#include "legacy_document_layer_services.h"
|
||||||
#include "legacy_preference_storage.h"
|
#include "legacy_preference_storage.h"
|
||||||
#include "legacy_ui_overlay_services.h"
|
|
||||||
#include "serializer.h"
|
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "node_remote_page.h"
|
#include "node_remote_page.h"
|
||||||
#include "node_shorcuts.h"
|
#include "node_shorcuts.h"
|
||||||
@@ -398,320 +396,3 @@ void App::set_ui_scale(float scale)
|
|||||||
pp::panopainter::save_legacy_ui_scale_preference(plan.scale);
|
pp::panopainter::save_legacy_ui_scale_preference(plan.scale);
|
||||||
App::I->title_update();
|
App::I->title_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::set_ui_rtl(bool rtl)
|
|
||||||
{
|
|
||||||
const auto plan = pp::app::plan_interface_direction(rtl);
|
|
||||||
ui_rtl = plan.direction == pp::app::InterfaceDirection::right_to_left;
|
|
||||||
layout[main_id]->find("central-row")->SetRTL(
|
|
||||||
ui_rtl ? YGDirectionRTL : YGDirectionLTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool App::get_ui_rtl() const
|
|
||||||
{
|
|
||||||
return ui_rtl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::ui_save()
|
|
||||||
{
|
|
||||||
Serializer::Descriptor d;
|
|
||||||
d.class_id = "ui-state";
|
|
||||||
|
|
||||||
Serializer::List list_floatings;
|
|
||||||
for (auto const& c : layout[main_id]->find("floatings")->m_children)
|
|
||||||
{
|
|
||||||
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(c))
|
|
||||||
{
|
|
||||||
auto fd = list_floatings.add<Serializer::Descriptor>();
|
|
||||||
fd->class_id = "ui-flt";
|
|
||||||
fd->set("pos", Serializer::Vec2(f->GetPosition()));
|
|
||||||
fd->set("size", Serializer::Vec2(f->m_size));
|
|
||||||
fd->set("class", Serializer::Integer((int)f->m_class));
|
|
||||||
fd->set("title", Serializer::CString(f->m_title->m_text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.set("floatings", list_floatings);
|
|
||||||
|
|
||||||
Serializer::List list_drop_left;
|
|
||||||
for (auto const& c : layout[main_id]->find("drop-left")->m_children)
|
|
||||||
{
|
|
||||||
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(c))
|
|
||||||
{
|
|
||||||
auto fd = list_drop_left.add<Serializer::Descriptor>();
|
|
||||||
fd->class_id = "ui-dpl";
|
|
||||||
fd->set("size", Serializer::Vec2(f->m_size));
|
|
||||||
fd->set("class", Serializer::Integer((int)f->m_class));
|
|
||||||
fd->set("title", Serializer::CString(f->m_title->m_text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.set("drop-left", list_drop_left);
|
|
||||||
|
|
||||||
Serializer::List list_drop_right;
|
|
||||||
for (auto const& c : layout[main_id]->find("drop-right")->m_children)
|
|
||||||
{
|
|
||||||
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(c))
|
|
||||||
{
|
|
||||||
auto fd = list_drop_right.add<Serializer::Descriptor>();
|
|
||||||
fd->class_id = "ui-dpr";
|
|
||||||
fd->set("size", Serializer::Vec2(f->m_size));
|
|
||||||
fd->set("class", Serializer::Integer((int)f->m_class));
|
|
||||||
fd->set("title", Serializer::CString(f->m_title->m_text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.set("drop-right", list_drop_right);
|
|
||||||
|
|
||||||
pp::panopainter::set_legacy_ui_state_preferences(d, ui_rtl);
|
|
||||||
save_platform_ui_state();
|
|
||||||
|
|
||||||
pp::panopainter::save_legacy_preferences();
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::ui_restore()
|
|
||||||
{
|
|
||||||
const auto preferences = pp::panopainter::read_legacy_ui_preferences();
|
|
||||||
if (preferences.has_rtl)
|
|
||||||
set_ui_rtl(preferences.rtl);
|
|
||||||
|
|
||||||
if (!preferences.state)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto floatings = layout[main_id]->find_ref("floatings");
|
|
||||||
auto drop_left = layout[main_id]->find_ref("drop-left");
|
|
||||||
auto drop_right = layout[main_id]->find_ref("drop-right");
|
|
||||||
auto d = preferences.state;
|
|
||||||
for (auto const& l : d->get<Serializer::List>("floatings")->items)
|
|
||||||
{
|
|
||||||
auto ld = std::static_pointer_cast<Serializer::Descriptor>(l);
|
|
||||||
auto pos = ld->value<Serializer::Vec2>("pos");
|
|
||||||
auto size = ld->value<Serializer::Vec2>("size");
|
|
||||||
auto cls = static_cast<NodePanelFloating::kClass>(ld->value<Serializer::Integer>("class"));
|
|
||||||
auto f = floatings->add_child<NodePanelFloating>();
|
|
||||||
std::string title = "Floating Panel";
|
|
||||||
ld->value<Serializer::CString>("title", title);
|
|
||||||
f->m_title->set_text(title.c_str());
|
|
||||||
switch (cls)
|
|
||||||
{
|
|
||||||
case NodePanelFloating::kClass::Presets:
|
|
||||||
{
|
|
||||||
floating_presets = f->m_container->add_child_ref<NodePanelBrushPreset>();
|
|
||||||
floating_presets->SetHeightP(100);
|
|
||||||
//floating_presets->find("toolbar")->destroy();
|
|
||||||
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
|
||||||
apply_brush_preset_plan(*this, b);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::Color:
|
|
||||||
{
|
|
||||||
floating_color = f->m_container->add_child_ref<NodePanelColor>();
|
|
||||||
floating_color->SetHeightP(100);
|
|
||||||
floating_color->find("title")->SetVisibility(false);
|
|
||||||
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
||||||
apply_brush_color_plan(*this, color, false, false);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::ColorAdv:
|
|
||||||
{
|
|
||||||
floating_picker = f->m_container->add_child_ref<NodeColorPicker>();
|
|
||||||
floating_picker->m_autohide = false;
|
|
||||||
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
|
||||||
apply_brush_color_plan(*this, glm::vec4(color, 1.f), false, false);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::Layers:
|
|
||||||
f->m_container->add_child(layers);
|
|
||||||
f->SetMinHeight(100);
|
|
||||||
f->SetHeight(300);
|
|
||||||
layers->find("title")->SetVisibility(false);
|
|
||||||
layers->SetPositioning(YGPositionTypeRelative);
|
|
||||||
layers->SetPosition(0, 0);
|
|
||||||
layers->SetWidthP(100);
|
|
||||||
layers->SetHeightP(100);
|
|
||||||
layers->SetFlexShrink(0);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Brush:
|
|
||||||
f->m_container->add_child(stroke);
|
|
||||||
stroke->find("title")->SetVisibility(false);
|
|
||||||
stroke->SetPositioning(YGPositionTypeRelative);
|
|
||||||
stroke->SetPosition(0, 0);
|
|
||||||
stroke->SetWidthP(100);
|
|
||||||
stroke->SetHeightP(100);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Grids:
|
|
||||||
f->m_container->add_child(grid);
|
|
||||||
grid->find("title")->SetVisibility(false);
|
|
||||||
grid->SetPositioning(YGPositionTypeRelative);
|
|
||||||
grid->SetPosition(0, 0);
|
|
||||||
grid->SetWidthP(100);
|
|
||||||
grid->SetHeightP(100);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Animation:
|
|
||||||
f->m_container->add_child(animation);
|
|
||||||
f->m_droppable = false;
|
|
||||||
//grid->find("title")->SetVisibility(false);
|
|
||||||
animation->SetPositioning(YGPositionTypeRelative);
|
|
||||||
animation->SetPosition(0, 0);
|
|
||||||
animation->SetWidthP(100);
|
|
||||||
animation->SetHeightP(100);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Generic:
|
|
||||||
default:
|
|
||||||
f->m_container->add_child<Node>();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
f->m_class = cls;
|
|
||||||
f->SetSize(size);
|
|
||||||
f->SetPosition(pos);
|
|
||||||
f->SetPositioning(YGPositionTypeAbsolute);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto const& l : d->get<Serializer::List>("drop-left")->items)
|
|
||||||
{
|
|
||||||
auto ld = std::static_pointer_cast<Serializer::Descriptor>(l);
|
|
||||||
auto size = ld->value<Serializer::Vec2>("size");
|
|
||||||
auto cls = static_cast<NodePanelFloating::kClass>(ld->value<Serializer::Integer>("class"));
|
|
||||||
auto f = drop_left->add_child<NodePanelFloating>();
|
|
||||||
std::string title = "Floating Panel";
|
|
||||||
ld->value<Serializer::CString>("title", title);
|
|
||||||
f->m_title->set_text(title.c_str());
|
|
||||||
switch (cls)
|
|
||||||
{
|
|
||||||
case NodePanelFloating::kClass::Presets:
|
|
||||||
{
|
|
||||||
auto floating_presets = f->m_container->add_child<NodePanelBrushPreset>();
|
|
||||||
floating_presets->SetHeightP(100);
|
|
||||||
//floating_presets->find("toolbar")->destroy();
|
|
||||||
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
|
||||||
apply_brush_preset_plan(*this, b);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::Color:
|
|
||||||
{
|
|
||||||
auto floating_color = f->m_container->add_child<NodePanelColor>();
|
|
||||||
floating_color->SetHeightP(100);
|
|
||||||
pp::panopainter::destroy_legacy_node(*floating_color->find("title"));
|
|
||||||
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
||||||
apply_brush_color_plan(*this, color, false, false);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::ColorAdv:
|
|
||||||
{
|
|
||||||
floating_picker = f->m_container->add_child_ref<NodeColorPicker>();
|
|
||||||
floating_picker->m_autohide = false;
|
|
||||||
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
|
||||||
apply_brush_color_plan(*this, glm::vec4(color, 1.f), false, false);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::Layers:
|
|
||||||
f->m_container->add_child(layers);
|
|
||||||
layers->SetPositioning(YGPositionTypeRelative);
|
|
||||||
layers->SetPosition(0, 0);
|
|
||||||
layers->SetWidthP(100);
|
|
||||||
layers->SetHeightP(100);
|
|
||||||
layers->SetFlexShrink(0);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Brush:
|
|
||||||
f->m_container->add_child(stroke);
|
|
||||||
stroke->SetPositioning(YGPositionTypeRelative);
|
|
||||||
stroke->SetPosition(0, 0);
|
|
||||||
stroke->SetWidthP(100);
|
|
||||||
stroke->SetHeightP(100);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Grids:
|
|
||||||
f->m_container->add_child(grid);
|
|
||||||
grid->SetPositioning(YGPositionTypeRelative);
|
|
||||||
grid->SetPosition(0, 0);
|
|
||||||
grid->SetWidthP(100);
|
|
||||||
grid->SetHeightP(100);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Generic:
|
|
||||||
default:
|
|
||||||
f->m_container->add_child<Node>();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
f->m_class = cls;
|
|
||||||
f->m_dock = drop_left;
|
|
||||||
f->SetPositioning(YGPositionTypeRelative);
|
|
||||||
f->SetPosition(0, 0);
|
|
||||||
f->SetSize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto const& l : d->get<Serializer::List>("drop-right")->items)
|
|
||||||
{
|
|
||||||
auto ld = std::static_pointer_cast<Serializer::Descriptor>(l);
|
|
||||||
auto size = ld->value<Serializer::Vec2>("size");
|
|
||||||
auto cls = static_cast<NodePanelFloating::kClass>(ld->value<Serializer::Integer>("class"));
|
|
||||||
auto f = drop_right->add_child<NodePanelFloating>();
|
|
||||||
std::string title = "Floating Panel";
|
|
||||||
ld->value<Serializer::CString>("title", title);
|
|
||||||
f->m_title->set_text(title.c_str());
|
|
||||||
switch (cls)
|
|
||||||
{
|
|
||||||
case NodePanelFloating::kClass::Presets:
|
|
||||||
{
|
|
||||||
auto floating_presets = f->m_container->add_child<NodePanelBrushPreset>();
|
|
||||||
floating_presets->SetHeightP(100);
|
|
||||||
//floating_presets->find("toolbar")->destroy();
|
|
||||||
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
|
||||||
apply_brush_preset_plan(*this, b);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::Color:
|
|
||||||
{
|
|
||||||
auto floating_color = f->m_container->add_child<NodePanelColor>();
|
|
||||||
floating_color->SetHeightP(100);
|
|
||||||
pp::panopainter::destroy_legacy_node(*floating_color->find("title"));
|
|
||||||
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
||||||
apply_brush_color_plan(*this, color, false, false);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::ColorAdv:
|
|
||||||
{
|
|
||||||
floating_picker = f->m_container->add_child_ref<NodeColorPicker>();
|
|
||||||
floating_picker->m_autohide = false;
|
|
||||||
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
|
||||||
apply_brush_color_plan(*this, glm::vec4(color, 1.f), false, false);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NodePanelFloating::kClass::Layers:
|
|
||||||
f->m_container->add_child(layers);
|
|
||||||
layers->SetPositioning(YGPositionTypeRelative);
|
|
||||||
layers->SetPosition(0, 0);
|
|
||||||
layers->SetWidthP(100);
|
|
||||||
layers->SetHeightP(100);
|
|
||||||
layers->SetFlexShrink(0);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Brush:
|
|
||||||
f->m_container->add_child(stroke);
|
|
||||||
stroke->SetPositioning(YGPositionTypeRelative);
|
|
||||||
stroke->SetPosition(0, 0);
|
|
||||||
stroke->SetWidthP(100);
|
|
||||||
stroke->SetHeightP(100);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Grids:
|
|
||||||
f->m_container->add_child(grid);
|
|
||||||
grid->SetPositioning(YGPositionTypeRelative);
|
|
||||||
grid->SetPosition(0, 0);
|
|
||||||
grid->SetWidthP(100);
|
|
||||||
grid->SetHeightP(100);
|
|
||||||
break;
|
|
||||||
case NodePanelFloating::kClass::Generic:
|
|
||||||
default:
|
|
||||||
f->m_container->add_child<Node>();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
f->m_class = cls;
|
|
||||||
f->m_dock = drop_right;
|
|
||||||
f->SetPositioning(YGPositionTypeRelative);
|
|
||||||
f->SetPosition(0, 0);
|
|
||||||
f->SetSize(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
216
src/app_layout_ui_state.cpp
Normal file
216
src/app_layout_ui_state.cpp
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "app.h"
|
||||||
|
#include "app_core/app_preferences.h"
|
||||||
|
#include "legacy_brush_ui_services.h"
|
||||||
|
#include "legacy_ui_overlay_services.h"
|
||||||
|
#include "legacy_preference_storage.h"
|
||||||
|
#include "node_dialog_picker.h"
|
||||||
|
#include "node_panel_brush.h"
|
||||||
|
#include "node_panel_color.h"
|
||||||
|
#include "node_panel_grid.h"
|
||||||
|
#include "node_panel_floating.h"
|
||||||
|
#include "serializer.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool apply_brush_color_plan(App& app, glm::vec4 color, bool update_quick, bool update_color_panel)
|
||||||
|
{
|
||||||
|
return pp::panopainter::apply_legacy_brush_color_plan(app, color, update_quick, update_color_panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool apply_brush_preset_plan(App& app, const std::shared_ptr<Brush>& brush)
|
||||||
|
{
|
||||||
|
return pp::panopainter::apply_legacy_brush_preset_plan(app, brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_floating_panel_state(Serializer::List& list, const std::shared_ptr<Node>& child)
|
||||||
|
{
|
||||||
|
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(child))
|
||||||
|
{
|
||||||
|
auto fd = list.add<Serializer::Descriptor>();
|
||||||
|
fd->class_id = "ui-flt";
|
||||||
|
fd->set("pos", Serializer::Vec2(f->GetPosition()));
|
||||||
|
fd->set("size", Serializer::Vec2(f->m_size));
|
||||||
|
fd->set("class", Serializer::Integer((int)f->m_class));
|
||||||
|
fd->set("title", Serializer::CString(f->m_title->m_text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_docked_panel_state(Serializer::List& list, const std::shared_ptr<Node>& child, const char* class_id)
|
||||||
|
{
|
||||||
|
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(child))
|
||||||
|
{
|
||||||
|
auto fd = list.add<Serializer::Descriptor>();
|
||||||
|
fd->class_id = class_id;
|
||||||
|
fd->set("size", Serializer::Vec2(f->m_size));
|
||||||
|
fd->set("class", Serializer::Integer((int)f->m_class));
|
||||||
|
fd->set("title", Serializer::CString(f->m_title->m_text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class TList>
|
||||||
|
void restore_panel_children(
|
||||||
|
App& app,
|
||||||
|
std::shared_ptr<Node> container,
|
||||||
|
const TList& items,
|
||||||
|
bool docked)
|
||||||
|
{
|
||||||
|
for (auto const& l : items)
|
||||||
|
{
|
||||||
|
auto ld = std::static_pointer_cast<Serializer::Descriptor>(l);
|
||||||
|
auto size = ld->value<Serializer::Vec2>("size");
|
||||||
|
auto cls = static_cast<NodePanelFloating::kClass>(ld->value<Serializer::Integer>("class"));
|
||||||
|
auto f = container->add_child<NodePanelFloating>();
|
||||||
|
std::string title = "Floating Panel";
|
||||||
|
ld->value<Serializer::CString>("title", title);
|
||||||
|
f->m_title->set_text(title.c_str());
|
||||||
|
switch (cls)
|
||||||
|
{
|
||||||
|
case NodePanelFloating::kClass::Presets:
|
||||||
|
{
|
||||||
|
auto floating_presets = f->m_container->add_child_ref<NodePanelBrushPreset>();
|
||||||
|
if (!docked)
|
||||||
|
app.floating_presets = floating_presets;
|
||||||
|
floating_presets->SetHeightP(100);
|
||||||
|
floating_presets->on_brush_changed = [&app](Node*, std::shared_ptr<Brush>& b) {
|
||||||
|
apply_brush_preset_plan(app, b);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NodePanelFloating::kClass::Color:
|
||||||
|
{
|
||||||
|
auto floating_color = f->m_container->add_child_ref<NodePanelColor>();
|
||||||
|
if (!docked)
|
||||||
|
app.floating_color = floating_color;
|
||||||
|
floating_color->SetHeightP(100);
|
||||||
|
if (docked)
|
||||||
|
pp::panopainter::destroy_legacy_node(*floating_color->find("title"));
|
||||||
|
else
|
||||||
|
floating_color->find("title")->SetVisibility(false);
|
||||||
|
floating_color->on_color_changed = [&app](Node*, glm::vec4 color) {
|
||||||
|
apply_brush_color_plan(app, color, false, false);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NodePanelFloating::kClass::ColorAdv:
|
||||||
|
{
|
||||||
|
app.floating_picker = f->m_container->add_child_ref<NodeColorPicker>();
|
||||||
|
app.floating_picker->m_autohide = false;
|
||||||
|
app.floating_picker->on_color_change = [&app](Node*, glm::vec3 color) {
|
||||||
|
apply_brush_color_plan(app, glm::vec4(color, 1.f), false, false);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NodePanelFloating::kClass::Layers:
|
||||||
|
f->m_container->add_child(app.layers);
|
||||||
|
if (!docked)
|
||||||
|
f->SetMinHeight(100);
|
||||||
|
if (!docked)
|
||||||
|
f->SetHeight(300);
|
||||||
|
if (!docked)
|
||||||
|
app.layers->find("title")->SetVisibility(false);
|
||||||
|
app.layers->SetPositioning(YGPositionTypeRelative);
|
||||||
|
app.layers->SetPosition(0, 0);
|
||||||
|
app.layers->SetWidthP(100);
|
||||||
|
app.layers->SetHeightP(100);
|
||||||
|
app.layers->SetFlexShrink(0);
|
||||||
|
break;
|
||||||
|
case NodePanelFloating::kClass::Brush:
|
||||||
|
f->m_container->add_child(app.stroke);
|
||||||
|
if (!docked)
|
||||||
|
app.stroke->find("title")->SetVisibility(false);
|
||||||
|
app.stroke->SetPositioning(YGPositionTypeRelative);
|
||||||
|
app.stroke->SetPosition(0, 0);
|
||||||
|
app.stroke->SetWidthP(100);
|
||||||
|
app.stroke->SetHeightP(100);
|
||||||
|
break;
|
||||||
|
case NodePanelFloating::kClass::Grids:
|
||||||
|
f->m_container->add_child(app.grid);
|
||||||
|
if (!docked)
|
||||||
|
app.grid->find("title")->SetVisibility(false);
|
||||||
|
app.grid->SetPositioning(YGPositionTypeRelative);
|
||||||
|
app.grid->SetPosition(0, 0);
|
||||||
|
app.grid->SetWidthP(100);
|
||||||
|
app.grid->SetHeightP(100);
|
||||||
|
break;
|
||||||
|
case NodePanelFloating::kClass::Animation:
|
||||||
|
f->m_container->add_child(app.animation);
|
||||||
|
f->m_droppable = false;
|
||||||
|
app.animation->SetPositioning(YGPositionTypeRelative);
|
||||||
|
app.animation->SetPosition(0, 0);
|
||||||
|
app.animation->SetWidthP(100);
|
||||||
|
app.animation->SetHeightP(100);
|
||||||
|
break;
|
||||||
|
case NodePanelFloating::kClass::Generic:
|
||||||
|
default:
|
||||||
|
f->m_container->add_child<Node>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
f->m_class = cls;
|
||||||
|
if (docked)
|
||||||
|
f->m_dock = container;
|
||||||
|
f->SetPositioning(docked ? YGPositionTypeRelative : YGPositionTypeAbsolute);
|
||||||
|
f->SetPosition(0, 0);
|
||||||
|
f->SetSize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void App::set_ui_rtl(bool rtl)
|
||||||
|
{
|
||||||
|
const auto plan = pp::app::plan_interface_direction(rtl);
|
||||||
|
ui_rtl = plan.direction == pp::app::InterfaceDirection::right_to_left;
|
||||||
|
layout[main_id]->find("central-row")->SetRTL(
|
||||||
|
ui_rtl ? YGDirectionRTL : YGDirectionLTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool App::get_ui_rtl() const
|
||||||
|
{
|
||||||
|
return ui_rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::ui_save()
|
||||||
|
{
|
||||||
|
Serializer::Descriptor d;
|
||||||
|
d.class_id = "ui-state";
|
||||||
|
|
||||||
|
Serializer::List list_floatings;
|
||||||
|
for (auto const& c : layout[main_id]->find("floatings")->m_children)
|
||||||
|
save_floating_panel_state(list_floatings, c);
|
||||||
|
d.set("floatings", list_floatings);
|
||||||
|
|
||||||
|
Serializer::List list_drop_left;
|
||||||
|
for (auto const& c : layout[main_id]->find("drop-left")->m_children)
|
||||||
|
save_docked_panel_state(list_drop_left, c, "ui-dpl");
|
||||||
|
d.set("drop-left", list_drop_left);
|
||||||
|
|
||||||
|
Serializer::List list_drop_right;
|
||||||
|
for (auto const& c : layout[main_id]->find("drop-right")->m_children)
|
||||||
|
save_docked_panel_state(list_drop_right, c, "ui-dpr");
|
||||||
|
d.set("drop-right", list_drop_right);
|
||||||
|
|
||||||
|
pp::panopainter::set_legacy_ui_state_preferences(d, ui_rtl);
|
||||||
|
save_platform_ui_state();
|
||||||
|
|
||||||
|
pp::panopainter::save_legacy_preferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::ui_restore()
|
||||||
|
{
|
||||||
|
const auto preferences = pp::panopainter::read_legacy_ui_preferences();
|
||||||
|
if (preferences.has_rtl)
|
||||||
|
set_ui_rtl(preferences.rtl);
|
||||||
|
|
||||||
|
if (!preferences.state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto floatings = layout[main_id]->find_ref("floatings");
|
||||||
|
auto drop_left = layout[main_id]->find_ref("drop-left");
|
||||||
|
auto drop_right = layout[main_id]->find_ref("drop-right");
|
||||||
|
auto d = preferences.state;
|
||||||
|
|
||||||
|
restore_panel_children(*this, floatings, d->get<Serializer::List>("floatings")->items, false);
|
||||||
|
restore_panel_children(*this, drop_left, d->get<Serializer::List>("drop-left")->items, true);
|
||||||
|
restore_panel_children(*this, drop_right, d->get<Serializer::List>("drop-right")->items, true);
|
||||||
|
}
|
||||||
@@ -119,7 +119,7 @@ enum {
|
|||||||
kVK_UpArrow = 0x7E
|
kVK_UpArrow = 0x7E
|
||||||
};
|
};
|
||||||
|
|
||||||
kKey convert_key(int key)
|
inline kKey convert_key(int key)
|
||||||
{
|
{
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
@@ -240,7 +240,7 @@ kKey convert_key(int key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif __WIN__
|
#elif __WIN__
|
||||||
kKey convert_key(int key)
|
inline kKey convert_key(int key)
|
||||||
{
|
{
|
||||||
static auto KL = GetKeyboardLayout(0);
|
static auto KL = GetKeyboardLayout(0);
|
||||||
if (key == (VkKeyScanA('[') & 0xFF))
|
if (key == (VkKeyScanA('[') & 0xFF))
|
||||||
@@ -450,7 +450,7 @@ kKey convert_key(int key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
kKey convert_key(int key)
|
inline kKey convert_key(int key)
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
@@ -682,7 +682,7 @@ kKey convert_key(int key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif __WEB__
|
#elif __WEB__
|
||||||
kKey convert_key(int key)
|
inline kKey convert_key(int key)
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
|
|||||||
276
src/main.cpp
276
src/main.cpp
@@ -12,6 +12,7 @@
|
|||||||
#include "platform_windows/windows_lifecycle_shell.h"
|
#include "platform_windows/windows_lifecycle_shell.h"
|
||||||
#include "platform_windows/windows_splash.h"
|
#include "platform_windows/windows_splash.h"
|
||||||
#include "platform_windows/windows_stylus_input.h"
|
#include "platform_windows/windows_stylus_input.h"
|
||||||
|
#include "platform_windows/windows_window_shell.h"
|
||||||
#include "platform_windows/windows_vr_shell.h"
|
#include "platform_windows/windows_vr_shell.h"
|
||||||
#include "../resource.h"
|
#include "../resource.h"
|
||||||
|
|
||||||
@@ -30,24 +31,9 @@ namespace pp::platform::windows {
|
|||||||
bool try_lock_async_render_context();
|
bool try_lock_async_render_context();
|
||||||
void unlock_async_render_context();
|
void unlock_async_render_context();
|
||||||
void swap_async_render_context();
|
void swap_async_render_context();
|
||||||
|
RetainedState& retained_state();
|
||||||
}
|
}
|
||||||
struct RetainedState
|
using pp::platform::windows::retained_state;
|
||||||
{
|
|
||||||
HINSTANCE hInst{};
|
|
||||||
HWND hWnd{};
|
|
||||||
bool keys[256]{};
|
|
||||||
std::map<kKey, int> vkey_map;
|
|
||||||
wchar_t window_title[512]{};
|
|
||||||
bool sandboxed = false;
|
|
||||||
pp::platform::windows::VrShellState vr;
|
|
||||||
};
|
|
||||||
|
|
||||||
RetainedState& retained_state()
|
|
||||||
{
|
|
||||||
static RetainedState state;
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct RetainedMainTaskQueue final
|
struct RetainedMainTaskQueue final
|
||||||
@@ -571,262 +557,6 @@ int main(int argc, char** argv)
|
|||||||
LogRemote::I.stop();
|
LogRemote::I.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|
||||||
{
|
|
||||||
auto& state = retained_state();
|
|
||||||
static bool leftDown = false;
|
|
||||||
static DWORD lastTime;
|
|
||||||
static glm::vec2 lastPoint;
|
|
||||||
|
|
||||||
auto extra = GetMessageExtraInfo();
|
|
||||||
// if ((extra & 0xFFFFFF00) == 0xFF515700)
|
|
||||||
// LOG("source %s", extra & 0x80 ? "touch" : "pen");
|
|
||||||
|
|
||||||
switch (msg)
|
|
||||||
{
|
|
||||||
case pp::platform::windows::kUserCloseMessage:
|
|
||||||
pp::platform::windows::handle_window_close_message(state.vr);
|
|
||||||
return 0;
|
|
||||||
case WM_PAINT:
|
|
||||||
App::I->redraw = true;
|
|
||||||
break;
|
|
||||||
case WM_CREATE:
|
|
||||||
BT_SetTerminate();
|
|
||||||
break;
|
|
||||||
case WM_CLOSE:
|
|
||||||
{
|
|
||||||
App::I->ui_task_async([] {
|
|
||||||
if (App::I->request_close())
|
|
||||||
{
|
|
||||||
destroy_window();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_SIZE:
|
|
||||||
{
|
|
||||||
auto w = (float)LOWORD(lp);
|
|
||||||
auto h = (float)HIWORD(lp);
|
|
||||||
if (h != 0 && pp::platform::windows::lifecycle_is_running())
|
|
||||||
{
|
|
||||||
App::I->ui_task_async([=]
|
|
||||||
{
|
|
||||||
App::I->resize(w, h);
|
|
||||||
App::I->redraw = true;
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_ACTIVATE:
|
|
||||||
{
|
|
||||||
pp::platform::windows::platform_services().set_cursor_visible(true);
|
|
||||||
App::I->ui_task_async([&state, wp, lp] {
|
|
||||||
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
|
||||||
WacomTablet::I.set_focus(active);
|
|
||||||
static BYTE keys[256];
|
|
||||||
if (GetKeyboardState(keys))
|
|
||||||
{
|
|
||||||
bool alt = keys[VK_MENU] & 0x80;
|
|
||||||
for (auto k : state.vkey_map)
|
|
||||||
{
|
|
||||||
// ignore alt + tab
|
|
||||||
if (alt && k.first == kKey::KeyTab)
|
|
||||||
continue;
|
|
||||||
bool down = keys[k.second] & 0x80;
|
|
||||||
if (App::I->keys[(int)k.first] && !down)
|
|
||||||
App::I->key_up(k.first);
|
|
||||||
else if(!App::I->keys[(int)k.first] && down)
|
|
||||||
App::I->key_down(k.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// case WM_TOUCH:
|
|
||||||
// {
|
|
||||||
// App::I->ui_task_async([=] {
|
|
||||||
// //LOG("touch");
|
|
||||||
// });
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
case WT_PACKET:
|
|
||||||
{
|
|
||||||
pp::platform::windows::note_wintab_packet();
|
|
||||||
App::I->ui_task_async([=] {
|
|
||||||
WacomTablet::I.handle_message(hWnd, msg, wp, lp);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_SYSKEYDOWN:
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
if ((lp >> 30 & 1) == 0 && // ignore repeated
|
|
||||||
!(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt])) // ignore alt+tab
|
|
||||||
{
|
|
||||||
App::I->ui_task_async([wp] {
|
|
||||||
App::I->key_down(convert_key((int)wp));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_SYSKEYUP:
|
|
||||||
case WM_KEYUP:
|
|
||||||
if (!(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt])) // ignore alt+tab
|
|
||||||
{
|
|
||||||
App::I->ui_task_async([wp] {
|
|
||||||
App::I->key_up(convert_key((int)wp));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_CHAR:
|
|
||||||
{
|
|
||||||
App::I->ui_task_async([wp]{
|
|
||||||
App::I->key_char((int)wp);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
RECT r;
|
|
||||||
POINT curpos;
|
|
||||||
GetWindowRect(hWnd, &r);
|
|
||||||
glm::vec2 center = { r.left + (r.right - r.left) / 2, r.top + (r.bottom - r.top) / 2 };
|
|
||||||
GetCursorPos(&curpos);
|
|
||||||
SetCursorPos(center.x, center.y);
|
|
||||||
|
|
||||||
//glm::vec2 cur = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
|
||||||
glm::vec2 sz = { App::I->width, App::I->height };
|
|
||||||
glm::vec2 diff = { curpos.x - center.x, curpos.y - center.y };
|
|
||||||
lastPoint = glm::clamp(lastPoint + diff, { 0, 0 }, sz);
|
|
||||||
|
|
||||||
*/
|
|
||||||
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
|
||||||
|
|
||||||
auto pt = lastPoint;
|
|
||||||
App::I->ui_task_async([pt, extra, p = WacomTablet::I.get_pressure()]{
|
|
||||||
kEventSource pointer_source;
|
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
|
||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
|
||||||
pointer_source = kEventSource::Touch;
|
|
||||||
}
|
|
||||||
App::I->mouse_move((float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_LBUTTONDOWN:
|
|
||||||
{
|
|
||||||
SetCapture(hWnd);
|
|
||||||
auto pt = lastPoint;
|
|
||||||
App::I->ui_task_async([pt, extra, hWnd, p = WacomTablet::I.get_pressure()]{
|
|
||||||
kEventSource pointer_source;
|
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
|
||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
|
||||||
pointer_source = kEventSource::Touch;
|
|
||||||
}
|
|
||||||
App::I->mouse_down(0, (float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
{
|
|
||||||
ReleaseCapture();
|
|
||||||
auto pt = lastPoint;
|
|
||||||
App::I->ui_task_async([pt, extra] {
|
|
||||||
WacomTablet::I.reset_pressure();
|
|
||||||
kEventSource pointer_source;
|
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
|
||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
|
||||||
pointer_source = kEventSource::Touch;
|
|
||||||
}
|
|
||||||
App::I->mouse_up(0, (float)pt.x, (float)pt.y, pointer_source, WacomTablet::I.m_eraser);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
{
|
|
||||||
SetCapture(hWnd);
|
|
||||||
auto pt = lastPoint;
|
|
||||||
App::I->ui_task_async([pt, extra, hWnd] {
|
|
||||||
kEventSource pointer_source;
|
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
|
||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
|
||||||
pointer_source = kEventSource::Touch;
|
|
||||||
}
|
|
||||||
App::I->mouse_down(1, (float)pt.x, (float)pt.y, 1.f, pointer_source, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_RBUTTONUP:
|
|
||||||
{
|
|
||||||
ReleaseCapture();
|
|
||||||
auto pt = lastPoint;
|
|
||||||
App::I->ui_task_async([pt, extra] {
|
|
||||||
kEventSource pointer_source;
|
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
|
||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
|
||||||
pointer_source = kEventSource::Touch;
|
|
||||||
}
|
|
||||||
App::I->mouse_up(1, (float)pt.x, (float)pt.y, pointer_source, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_MOUSEWHEEL:
|
|
||||||
{
|
|
||||||
POINT pt;
|
|
||||||
pt.x = GET_X_LPARAM(lp);
|
|
||||||
pt.y = GET_Y_LPARAM(lp);
|
|
||||||
ScreenToClient(hWnd, &pt);
|
|
||||||
{
|
|
||||||
App::I->ui_task_async([pt, wp] {
|
|
||||||
App::I->mouse_scroll((float)pt.x, (float)pt.y,
|
|
||||||
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_POINTERUPDATE:
|
|
||||||
{
|
|
||||||
pp::platform::windows::handle_pointer_update_message(wp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// avoid annoying alt system menu
|
|
||||||
if (wp == SC_KEYMENU && (lp >> 16) <= 0) return 0;
|
|
||||||
|
|
||||||
return DefWindowProc(hWnd, msg, wp, lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||||
{
|
{
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
|
|||||||
@@ -656,68 +656,16 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
.mvp = ortho_proj,
|
.mvp = ortho_proj,
|
||||||
});
|
});
|
||||||
const bool copy_stroke_destination = pass_orchestration.copy_stroke_destination;
|
const bool copy_stroke_destination = pass_orchestration.copy_stroke_destination;
|
||||||
const auto& material = pass_orchestration.material;
|
|
||||||
pp::panopainter::setup_legacy_stroke_shader(pass_orchestration.stroke_shader);
|
pp::panopainter::setup_legacy_stroke_shader(pass_orchestration.stroke_shader);
|
||||||
|
execute_stroke_draw_immediate_pass_sequence(
|
||||||
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_pass_sequence(
|
m_stroke,
|
||||||
pp::panopainter::LegacyNodeStrokePreviewImmediatePassSequenceRequest {
|
m_dual_stroke,
|
||||||
.execute_dual_pass = [&] {
|
*b,
|
||||||
if (!pass_orchestration.material.dual_pass.enabled) {
|
std::move(dual_brush),
|
||||||
return;
|
pass_orchestration,
|
||||||
}
|
copy_stroke_destination,
|
||||||
|
zoom,
|
||||||
pp::panopainter::setup_legacy_stroke_dual_shader(
|
size);
|
||||||
pass_orchestration.material.dual_pass.uses_pattern);
|
|
||||||
bind_stroke_preview_dual_pass_textures(*dual_brush);
|
|
||||||
execute_stroke_draw_immediate_dual_pass(
|
|
||||||
m_dual_stroke,
|
|
||||||
*b,
|
|
||||||
pass_orchestration,
|
|
||||||
std::move(dual_brush),
|
|
||||||
copy_stroke_destination,
|
|
||||||
zoom,
|
|
||||||
size);
|
|
||||||
},
|
|
||||||
.capture_background = [&] {
|
|
||||||
execute_stroke_preview_background_capture_pass(
|
|
||||||
size,
|
|
||||||
pass_orchestration.background_colorize,
|
|
||||||
m_tex_background,
|
|
||||||
[&] {
|
|
||||||
m_plane.draw_fill();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
.execute_main_live_pass = [&]() -> bool {
|
|
||||||
return pp::panopainter::execute_legacy_node_stroke_preview_main_live_pass(
|
|
||||||
make_stroke_draw_immediate_main_live_pass_request(
|
|
||||||
m_stroke,
|
|
||||||
*b,
|
|
||||||
pass_orchestration,
|
|
||||||
copy_stroke_destination,
|
|
||||||
zoom,
|
|
||||||
size));
|
|
||||||
},
|
|
||||||
.execute_final_composite = [&]() -> bool {
|
|
||||||
return pp::panopainter::execute_legacy_node_stroke_preview_final_composite(
|
|
||||||
size,
|
|
||||||
glm::vec2(b->m_pattern_scale),
|
|
||||||
*b,
|
|
||||||
material.composite_pass,
|
|
||||||
m_tex_background,
|
|
||||||
m_tex,
|
|
||||||
m_tex_dual,
|
|
||||||
m_tex_preview,
|
|
||||||
m_sampler_linear,
|
|
||||||
m_sampler_linear_repeat,
|
|
||||||
[&] {
|
|
||||||
b->m_pattern_texture ? b->m_pattern_texture->bind() : unbind_texture_2d();
|
|
||||||
},
|
|
||||||
[&] {
|
|
||||||
m_plane.draw_fill();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
assert(sequence_ok);
|
|
||||||
|
|
||||||
m_rtt.unbindFramebuffer();
|
m_rtt.unbindFramebuffer();
|
||||||
|
|
||||||
@@ -811,6 +759,78 @@ void NodeStrokePreview::execute_stroke_draw_immediate_dual_pass(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeStrokePreview::execute_stroke_draw_immediate_pass_sequence(
|
||||||
|
Stroke& stroke,
|
||||||
|
Stroke& dual_stroke,
|
||||||
|
const Brush& brush,
|
||||||
|
std::shared_ptr<Brush> dual_brush,
|
||||||
|
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||||
|
bool copy_stroke_destination,
|
||||||
|
float zoom,
|
||||||
|
const glm::vec2& size)
|
||||||
|
{
|
||||||
|
const auto& material = pass_orchestration.material;
|
||||||
|
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_pass_sequence(
|
||||||
|
pp::panopainter::LegacyNodeStrokePreviewImmediatePassSequenceRequest {
|
||||||
|
.execute_dual_pass = [&] {
|
||||||
|
if (!material.dual_pass.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::panopainter::setup_legacy_stroke_dual_shader(
|
||||||
|
material.dual_pass.uses_pattern);
|
||||||
|
bind_stroke_preview_dual_pass_textures(*dual_brush);
|
||||||
|
execute_stroke_draw_immediate_dual_pass(
|
||||||
|
dual_stroke,
|
||||||
|
brush,
|
||||||
|
pass_orchestration,
|
||||||
|
std::move(dual_brush),
|
||||||
|
copy_stroke_destination,
|
||||||
|
zoom,
|
||||||
|
size);
|
||||||
|
},
|
||||||
|
.capture_background = [&] {
|
||||||
|
execute_stroke_preview_background_capture_pass(
|
||||||
|
size,
|
||||||
|
pass_orchestration.background_colorize,
|
||||||
|
m_tex_background,
|
||||||
|
[&] {
|
||||||
|
m_plane.draw_fill();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.execute_main_live_pass = [&]() -> bool {
|
||||||
|
return pp::panopainter::execute_legacy_node_stroke_preview_main_live_pass(
|
||||||
|
make_stroke_draw_immediate_main_live_pass_request(
|
||||||
|
stroke,
|
||||||
|
brush,
|
||||||
|
pass_orchestration,
|
||||||
|
copy_stroke_destination,
|
||||||
|
zoom,
|
||||||
|
size));
|
||||||
|
},
|
||||||
|
.execute_final_composite = [&]() -> bool {
|
||||||
|
return pp::panopainter::execute_legacy_node_stroke_preview_final_composite(
|
||||||
|
size,
|
||||||
|
glm::vec2(brush.m_pattern_scale),
|
||||||
|
brush,
|
||||||
|
material.composite_pass,
|
||||||
|
m_tex_background,
|
||||||
|
m_tex,
|
||||||
|
m_tex_dual,
|
||||||
|
m_tex_preview,
|
||||||
|
m_sampler_linear,
|
||||||
|
m_sampler_linear_repeat,
|
||||||
|
[&] {
|
||||||
|
brush.m_pattern_texture ? brush.m_pattern_texture->bind() : unbind_texture_2d();
|
||||||
|
},
|
||||||
|
[&] {
|
||||||
|
m_plane.draw_fill();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
assert(sequence_ok);
|
||||||
|
}
|
||||||
|
|
||||||
void NodeStrokePreview::execute_stroke_draw_immediate_main_live_sample_pass(
|
void NodeStrokePreview::execute_stroke_draw_immediate_main_live_sample_pass(
|
||||||
const Brush& brush,
|
const Brush& brush,
|
||||||
bool copy_stroke_destination,
|
bool copy_stroke_destination,
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ class NodeStrokePreview : public NodeBorder
|
|||||||
static Sampler m_sampler_mipmap;
|
static Sampler m_sampler_mipmap;
|
||||||
static DynamicShape m_brush_shape;
|
static DynamicShape m_brush_shape;
|
||||||
Texture2D m_tex_preview;
|
Texture2D m_tex_preview;
|
||||||
|
void execute_stroke_draw_immediate_pass_sequence(
|
||||||
|
Stroke& stroke,
|
||||||
|
Stroke& dual_stroke,
|
||||||
|
const Brush& brush,
|
||||||
|
std::shared_ptr<Brush> dual_brush,
|
||||||
|
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||||
|
bool copy_stroke_destination,
|
||||||
|
float zoom,
|
||||||
|
const glm::vec2& size);
|
||||||
public:
|
public:
|
||||||
using parent = NodeBorder;
|
using parent = NodeBorder;
|
||||||
static std::atomic_int s_instances;
|
static std::atomic_int s_instances;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#include "platform_windows/windows_bootstrap_helpers.h"
|
#include "platform_windows/windows_bootstrap_helpers.h"
|
||||||
|
#include "platform_windows/windows_window_shell.h"
|
||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "legacy_gl_runtime_dispatch.h"
|
#include "legacy_gl_runtime_dispatch.h"
|
||||||
@@ -15,8 +16,6 @@
|
|||||||
#define USE_RENDERDOC
|
#define USE_RENDERDOC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
|
|
||||||
|
|
||||||
namespace pp::platform::windows {
|
namespace pp::platform::windows {
|
||||||
void set_async_render_context(HDC hdc, HGLRC hrc);
|
void set_async_render_context(HDC hdc, HGLRC hrc);
|
||||||
}
|
}
|
||||||
@@ -113,7 +112,7 @@ MainWindowStartupState initialize_main_window_startup_state()
|
|||||||
const auto className = L"EngineMain";
|
const auto className = L"EngineMain";
|
||||||
|
|
||||||
startup.window_class.hInstance = hInst;
|
startup.window_class.hInstance = hInst;
|
||||||
startup.window_class.lpfnWndProc = (WNDPROC)WndProc;
|
startup.window_class.lpfnWndProc = (WNDPROC)main_window_proc;
|
||||||
startup.window_class.lpszClassName = className;
|
startup.window_class.lpszClassName = className;
|
||||||
startup.window_class.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
startup.window_class.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||||
startup.window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
|
startup.window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
|||||||
247
src/platform_windows/windows_window_shell.cpp
Normal file
247
src/platform_windows/windows_window_shell.cpp
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "platform_windows/windows_window_shell.h"
|
||||||
|
|
||||||
|
#include "app.h"
|
||||||
|
#include "platform_windows/windows_lifecycle_shell.h"
|
||||||
|
#include "platform_windows/windows_platform_services.h"
|
||||||
|
#include "platform_windows/windows_stylus_input.h"
|
||||||
|
#include "keymap.h"
|
||||||
|
#include "wacom.h"
|
||||||
|
|
||||||
|
void destroy_window();
|
||||||
|
|
||||||
|
namespace pp::platform::windows {
|
||||||
|
|
||||||
|
RetainedState& retained_state()
|
||||||
|
{
|
||||||
|
static RetainedState state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||||
|
{
|
||||||
|
auto& state = retained_state();
|
||||||
|
static glm::vec2 lastPoint;
|
||||||
|
|
||||||
|
auto extra = GetMessageExtraInfo();
|
||||||
|
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case kUserCloseMessage:
|
||||||
|
handle_window_close_message(state.vr);
|
||||||
|
return 0;
|
||||||
|
case WM_PAINT:
|
||||||
|
App::I->redraw = true;
|
||||||
|
break;
|
||||||
|
case WM_CREATE:
|
||||||
|
BT_SetTerminate();
|
||||||
|
break;
|
||||||
|
case WM_CLOSE:
|
||||||
|
{
|
||||||
|
App::I->ui_task_async([] {
|
||||||
|
if (App::I->request_close())
|
||||||
|
{
|
||||||
|
destroy_window();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_SIZE:
|
||||||
|
{
|
||||||
|
auto w = (float)LOWORD(lp);
|
||||||
|
auto h = (float)HIWORD(lp);
|
||||||
|
if (h != 0 && lifecycle_is_running())
|
||||||
|
{
|
||||||
|
App::I->ui_task_async([=]
|
||||||
|
{
|
||||||
|
App::I->resize(w, h);
|
||||||
|
App::I->redraw = true;
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_ACTIVATE:
|
||||||
|
{
|
||||||
|
platform_services().set_cursor_visible(true);
|
||||||
|
App::I->ui_task_async([&state, wp, lp] {
|
||||||
|
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
||||||
|
WacomTablet::I.set_focus(active);
|
||||||
|
static BYTE keys[256];
|
||||||
|
if (GetKeyboardState(keys))
|
||||||
|
{
|
||||||
|
bool alt = keys[VK_MENU] & 0x80;
|
||||||
|
for (auto k : state.vkey_map)
|
||||||
|
{
|
||||||
|
if (alt && k.first == kKey::KeyTab)
|
||||||
|
continue;
|
||||||
|
bool down = keys[k.second] & 0x80;
|
||||||
|
if (App::I->keys[(int)k.first] && !down)
|
||||||
|
App::I->key_up(k.first);
|
||||||
|
else if (!App::I->keys[(int)k.first] && down)
|
||||||
|
App::I->key_down(k.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WT_PACKET:
|
||||||
|
{
|
||||||
|
note_wintab_packet();
|
||||||
|
App::I->ui_task_async([=] {
|
||||||
|
WacomTablet::I.handle_message(hWnd, msg, wp, lp);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_SYSKEYDOWN:
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
if ((lp >> 30 & 1) == 0 &&
|
||||||
|
!(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt]))
|
||||||
|
{
|
||||||
|
App::I->ui_task_async([wp] {
|
||||||
|
App::I->key_down(convert_key((int)wp));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
case WM_KEYUP:
|
||||||
|
if (!(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt]))
|
||||||
|
{
|
||||||
|
App::I->ui_task_async([wp] {
|
||||||
|
App::I->key_up(convert_key((int)wp));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_CHAR:
|
||||||
|
App::I->ui_task_async([wp] {
|
||||||
|
App::I->key_char((int)wp);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
||||||
|
{
|
||||||
|
auto pt = lastPoint;
|
||||||
|
App::I->ui_task_async([pt, extra, p = WacomTablet::I.get_pressure()] {
|
||||||
|
kEventSource pointer_source;
|
||||||
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
||||||
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
|
pointer_source = kEventSource::Touch;
|
||||||
|
}
|
||||||
|
App::I->mouse_move((float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
{
|
||||||
|
SetCapture(hWnd);
|
||||||
|
auto pt = lastPoint;
|
||||||
|
App::I->ui_task_async([pt, extra, hWnd, p = WacomTablet::I.get_pressure()] {
|
||||||
|
kEventSource pointer_source;
|
||||||
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
||||||
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
|
pointer_source = kEventSource::Touch;
|
||||||
|
}
|
||||||
|
App::I->mouse_down(0, (float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
{
|
||||||
|
ReleaseCapture();
|
||||||
|
auto pt = lastPoint;
|
||||||
|
App::I->ui_task_async([pt, extra] {
|
||||||
|
WacomTablet::I.reset_pressure();
|
||||||
|
kEventSource pointer_source;
|
||||||
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
||||||
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
|
pointer_source = kEventSource::Touch;
|
||||||
|
}
|
||||||
|
App::I->mouse_up(0, (float)pt.x, (float)pt.y, pointer_source, WacomTablet::I.m_eraser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
|
{
|
||||||
|
SetCapture(hWnd);
|
||||||
|
auto pt = lastPoint;
|
||||||
|
App::I->ui_task_async([pt, extra, hWnd] {
|
||||||
|
kEventSource pointer_source;
|
||||||
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
||||||
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
|
pointer_source = kEventSource::Touch;
|
||||||
|
}
|
||||||
|
App::I->mouse_down(1, (float)pt.x, (float)pt.y, 1.f, pointer_source, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
{
|
||||||
|
ReleaseCapture();
|
||||||
|
auto pt = lastPoint;
|
||||||
|
App::I->ui_task_async([pt, extra] {
|
||||||
|
kEventSource pointer_source;
|
||||||
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_ink_pen ? kEventSource::Stylus : kEventSource::Touch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointer_source = WacomTablet::I.m_stylus ? kEventSource::Stylus : kEventSource::Mouse;
|
||||||
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
|
pointer_source = kEventSource::Touch;
|
||||||
|
}
|
||||||
|
App::I->mouse_up(1, (float)pt.x, (float)pt.y, pointer_source, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
{
|
||||||
|
POINT pt;
|
||||||
|
pt.x = GET_X_LPARAM(lp);
|
||||||
|
pt.y = GET_Y_LPARAM(lp);
|
||||||
|
ScreenToClient(hWnd, &pt);
|
||||||
|
App::I->ui_task_async([pt, wp] {
|
||||||
|
App::I->mouse_scroll((float)pt.x, (float)pt.y,
|
||||||
|
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_POINTERUPDATE:
|
||||||
|
{
|
||||||
|
handle_pointer_update_message(wp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wp == SC_KEYMENU && (lp >> 16) <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return DefWindowProc(hWnd, msg, wp, lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
src/platform_windows/windows_window_shell.h
Normal file
25
src/platform_windows/windows_window_shell.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "event.h"
|
||||||
|
#include "platform_windows/windows_vr_shell.h"
|
||||||
|
|
||||||
|
struct RetainedState
|
||||||
|
{
|
||||||
|
HINSTANCE hInst{};
|
||||||
|
HWND hWnd{};
|
||||||
|
bool keys[256]{};
|
||||||
|
std::map<kKey, int> vkey_map;
|
||||||
|
wchar_t window_title[512]{};
|
||||||
|
bool sandboxed = false;
|
||||||
|
pp::platform::windows::VrShellState vr;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace pp::platform::windows {
|
||||||
|
|
||||||
|
RetainedState& retained_state();
|
||||||
|
LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user