Extract canvas plane data, brush preset list, and WinMain bridge

This commit is contained in:
2026-06-16 22:29:08 +02:00
parent 2a2f0c7dd6
commit 338f115540
11 changed files with 215 additions and 149 deletions

View File

@@ -267,39 +267,6 @@ std::vector<CanvasMode*> Canvas::modes[] = {
{ new CanvasModeMaskLine, new CanvasModeBasicCamera }, // mask-poly
{ new CanvasModeFloodFill, new CanvasModeBasicCamera }, // flood-fill
};
glm::vec3 Canvas::m_plane_origin[6] = {
{ 0, 0,-1}, // front
{ 1, 0, 0}, // right
{ 0, 0, 1}, // back
{-1, 0, 0}, // left
{ 0, 1, 0}, // top
{ 0,-1, 0}, // bottom
};
glm::vec3 Canvas::m_plane_normal[6] = {
{ 0, 0, 1}, // front
{-1, 0, 0}, // right
{ 0, 0,-1}, // back
{ 1, 0, 0}, // left
{ 0,-1, 0}, // top
{ 0, 1, 0}, // bottom
};
glm::vec3 Canvas::m_plane_tangent[6] = {
{0, 1, 0}, // front
{0, 1, 0}, // right
{0, 1, 0}, // back
{0, 1, 0}, // left
{0, 0,-1}, // top
{0, 0, 1}, // bottom
};
// only rotation
glm::mat4 Canvas::m_plane_transform[6] = {
glm::lookAt(glm::vec3(), { 0, 0,-1}, {0, 1, 0}), // front
glm::lookAt(glm::vec3(), {-1, 0, 0}, {0, 1, 0}), // right
glm::lookAt(glm::vec3(), { 0, 0, 1}, {0, 1, 0}), // back
glm::lookAt(glm::vec3(), { 1, 0, 0}, {0, 1, 0}), // left
glm::lookAt(glm::vec3(), { 0, 1, 0}, {0, 0,-1}), // top
glm::lookAt(glm::vec3(), { 0,-1, 0}, {0, 0, 1}), // bottom
};
void Canvas::stroke_end() { pp::panopainter::legacy_canvas_stroke_end(*this); }
void Canvas::stroke_cancel() { pp::panopainter::legacy_canvas_stroke_cancel(*this); }

View File

@@ -0,0 +1,98 @@
#include "pch.h"
#include "legacy_brush_preset_list_services.h"
#include "canvas.h"
#include "legacy_ui_overlay_services.h"
namespace pp::panopainter {
LegacyBrushPresetListServices::LegacyBrushPresetListServices(NodePanelBrushPreset& owner)
: owner_(owner)
{
}
pp::foundation::Status LegacyBrushPresetListServices::add_current_brush_preset(int target_index)
{
if (target_index < 0) {
return pp::foundation::Status::out_of_range("brush preset add target is invalid");
}
if (!Canvas::I || !Canvas::I->m_current_brush) {
return pp::foundation::Status::invalid_argument("current brush must be available to add a preset");
}
for (auto p : NodePanelBrushPreset::s_panels) {
p->add_brush(std::make_shared<Brush>(*Canvas::I->m_current_brush));
}
return pp::foundation::Status::success();
}
void LegacyBrushPresetListServices::remove_brush_preset(
int current_index,
int target_index,
bool selects_target,
bool clears_selection)
{
for (auto p : NodePanelBrushPreset::s_panels) {
if (current_index < 0 || current_index >= static_cast<int>(p->m_container->m_children.size())) {
continue;
}
const bool new_current = !p->m_current || p->m_container->get_child_index(p->m_current) == current_index;
pp::panopainter::destroy_legacy_node(*p->m_container->m_children[current_index]);
if (clears_selection) {
p->m_current = nullptr;
} else if (new_current && selects_target) {
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->m_children[target_index].get());
p->m_current->m_selected = true;
}
}
}
void LegacyBrushPresetListServices::move_brush_preset(int from_index, int to_index)
{
for (auto p : NodePanelBrushPreset::s_panels) {
if (from_index >= 0 && from_index < static_cast<int>(p->m_container->m_children.size())) {
p->m_container->move_child(p->m_container->m_children[from_index].get(), to_index);
}
}
}
void LegacyBrushPresetListServices::select_brush_preset(int index, bool notify_brush_changed)
{
for (auto p : NodePanelBrushPreset::s_panels) {
if (p->m_current) {
p->m_current->m_selected = false;
}
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->get_child_at(index));
p->m_current->m_selected = true;
p->m_interacted = true;
}
if (notify_brush_changed && owner_.on_brush_changed) {
owner_.on_brush_changed(&owner_, owner_.m_current->m_brush);
}
}
void LegacyBrushPresetListServices::clear_brush_presets(bool clears_selection)
{
for (auto p : NodePanelBrushPreset::s_panels) {
p->m_container->remove_all_children();
if (clears_selection) {
p->m_current = nullptr;
}
}
}
void LegacyBrushPresetListServices::update_preset_empty_notification()
{
for (auto p : NodePanelBrushPreset::s_panels) {
p->m_notification->SetVisibility(p->m_container->m_children.size() == 0);
}
}
void LegacyBrushPresetListServices::save_preset_list()
{
owner_.save();
}
} // namespace pp::panopainter

View File

@@ -0,0 +1,28 @@
#pragma once
#include "app_core/brush_ui.h"
#include "node_panel_brush.h"
namespace pp::panopainter {
class LegacyBrushPresetListServices final : public pp::app::BrushPresetListServices {
public:
explicit LegacyBrushPresetListServices(NodePanelBrushPreset& owner);
pp::foundation::Status add_current_brush_preset(int target_index) override;
void remove_brush_preset(
int current_index,
int target_index,
bool selects_target,
bool clears_selection) override;
void move_brush_preset(int from_index, int to_index) override;
void select_brush_preset(int index, bool notify_brush_changed) override;
void clear_brush_presets(bool clears_selection) override;
void update_preset_empty_notification() override;
void save_preset_list() override;
private:
NodePanelBrushPreset& owner_;
};
} // namespace pp::panopainter

View File

@@ -0,0 +1,39 @@
#include "pch.h"
#include "canvas.h"
glm::vec3 Canvas::m_plane_origin[6] = {
{ 0, 0,-1}, // front
{ 1, 0, 0}, // right
{ 0, 0, 1}, // back
{-1, 0, 0}, // left
{ 0, 1, 0}, // top
{ 0,-1, 0}, // bottom
};
glm::vec3 Canvas::m_plane_normal[6] = {
{ 0, 0, 1}, // front
{-1, 0, 0}, // right
{ 0, 0,-1}, // back
{ 1, 0, 0}, // left
{ 0,-1, 0}, // top
{ 0, 1, 0}, // bottom
};
glm::vec3 Canvas::m_plane_tangent[6] = {
{0, 1, 0}, // front
{0, 1, 0}, // right
{0, 1, 0}, // back
{0, 1, 0}, // left
{0, 0,-1}, // top
{0, 0, 1}, // bottom
};
// only rotation
glm::mat4 Canvas::m_plane_transform[6] = {
glm::lookAt(glm::vec3(), { 0, 0,-1}, {0, 1, 0}), // front
glm::lookAt(glm::vec3(), {-1, 0, 0}, {0, 1, 0}), // right
glm::lookAt(glm::vec3(), { 0, 0, 1}, {0, 1, 0}), // back
glm::lookAt(glm::vec3(), { 1, 0, 0}, {0, 1, 0}), // left
glm::lookAt(glm::vec3(), { 0, 1, 0}, {0, 0,-1}), // top
glm::lookAt(glm::vec3(), { 0,-1, 0}, {0, 0, 1}), // bottom
};

View File

@@ -152,19 +152,5 @@ int main(int argc, char** argv)
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
int argc = 0;
// convert args from char to wchar
auto wargs = CommandLineToArgvW(GetCommandLine(), &argc);
auto argv = new char*[argc + 1];
for (int i = 0; i < argc; i++)
{
auto len = wcslen(wargs[i]) + 1;
argv[i] = new char[len];
wcstombs_s(nullptr, argv[i], len, wargs[i], len);
}
LocalFree(wargs);
return main(argc, argv);
return pp::platform::windows::run_winmain_entry(main);
}

View File

@@ -3,6 +3,7 @@
#include "node_panel_brush.h"
#include "legacy_brush_panel_ui.h"
#include "legacy_brush_preset_panel_ui.h"
#include "legacy_brush_preset_list_services.h"
#include "legacy_brush_panel_services.h"
#include "app_core/brush_ui.h"
#include "legacy_brush_ui_services.h"
@@ -194,101 +195,6 @@ Node* NodePanelBrushPreset::clone_instantiate() const
}
namespace pp::panopainter {
class LegacyBrushPresetListServices final : public pp::app::BrushPresetListServices {
public:
explicit LegacyBrushPresetListServices(NodePanelBrushPreset& owner)
: owner_(owner)
{
}
pp::foundation::Status add_current_brush_preset(int target_index) override
{
if (target_index < 0) {
return pp::foundation::Status::out_of_range("brush preset add target is invalid");
}
if (!Canvas::I || !Canvas::I->m_current_brush) {
return pp::foundation::Status::invalid_argument("current brush must be available to add a preset");
}
for (auto p : NodePanelBrushPreset::s_panels) {
p->add_brush(std::make_shared<Brush>(*Canvas::I->m_current_brush));
}
return pp::foundation::Status::success();
}
void remove_brush_preset(
int current_index,
int target_index,
bool selects_target,
bool clears_selection) override
{
for (auto p : NodePanelBrushPreset::s_panels) {
if (current_index < 0 || current_index >= static_cast<int>(p->m_container->m_children.size())) {
continue;
}
const bool new_current = !p->m_current || p->m_container->get_child_index(p->m_current) == current_index;
pp::panopainter::destroy_legacy_node(*p->m_container->m_children[current_index]);
if (clears_selection) {
p->m_current = nullptr;
} else if (new_current && selects_target) {
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->m_children[target_index].get());
p->m_current->m_selected = true;
}
}
}
void move_brush_preset(int from_index, int to_index) override
{
for (auto p : NodePanelBrushPreset::s_panels) {
if (from_index >= 0 && from_index < static_cast<int>(p->m_container->m_children.size())) {
p->m_container->move_child(p->m_container->m_children[from_index].get(), to_index);
}
}
}
void select_brush_preset(int index, bool notify_brush_changed) override
{
for (auto p : NodePanelBrushPreset::s_panels) {
if (p->m_current) {
p->m_current->m_selected = false;
}
p->m_current = static_cast<NodeBrushPresetItem*>(p->m_container->get_child_at(index));
p->m_current->m_selected = true;
p->m_interacted = true;
}
if (notify_brush_changed && owner_.on_brush_changed) {
owner_.on_brush_changed(&owner_, owner_.m_current->m_brush);
}
}
void clear_brush_presets(bool clears_selection) override
{
for (auto p : NodePanelBrushPreset::s_panels) {
p->m_container->remove_all_children();
if (clears_selection) {
p->m_current = nullptr;
}
}
}
void update_preset_empty_notification() override
{
for (auto p : NodePanelBrushPreset::s_panels) {
p->m_notification->SetVisibility(p->m_container->m_children.size() == 0);
}
}
void save_preset_list() override
{
owner_.save();
}
private:
NodePanelBrushPreset& owner_;
};
} // namespace pp::panopainter
void NodePanelBrushPreset::execute_preset_list_plan(const pp::app::BrushPresetListPlan& plan)

View File

@@ -112,6 +112,24 @@ void ensure_runtime_data_directory()
LOG("data files ok");
}
int run_winmain_entry(int (*entry_point)(int, char**))
{
int argc = 0;
auto wargs = CommandLineToArgvW(GetCommandLine(), &argc);
auto argv = new char*[argc + 1];
for (int i = 0; i < argc; i++)
{
auto len = wcslen(wargs[i]) + 1;
argv[i] = new char[len];
wcstombs_s(nullptr, argv[i], len, wargs[i], len);
}
LocalFree(wargs);
return entry_point(argc, argv);
}
void setup_exception_handler()
{
// Setup exception handler

View File

@@ -48,6 +48,7 @@ enum class MainStartupResult
void ensure_runtime_data_directory();
void setup_exception_handler();
int run_winmain_entry(int (*entry_point)(int, char**));
MainWindowStartupState initialize_main_window_startup_state();
void create_main_window(const MainWindowStartupState& startup, HWND& hWnd, HINSTANCE hInst, const wchar_t* window_title);
void initialize_pixel_format_descriptor(PIXELFORMATDESCRIPTOR& pixel_format);