Extract draw toolbar and thin NodeCanvas and Win32 shell
This commit is contained in:
@@ -10,15 +10,12 @@
|
||||
#include "app_core/about_menu.h"
|
||||
#include "app_core/app_preferences.h"
|
||||
#include "app_core/brush_ui.h"
|
||||
#include "app_core/canvas_tool_ui.h"
|
||||
#include "app_core/document_layer.h"
|
||||
#include "app_core/document_canvas.h"
|
||||
#include "app_core/app_status.h"
|
||||
#include "app_core/tools_menu.h"
|
||||
#include "legacy_app_preference_services.h"
|
||||
#include "legacy_app_shell_services.h"
|
||||
#include "legacy_brush_ui_services.h"
|
||||
#include "legacy_canvas_tool_services.h"
|
||||
#include "legacy_document_layer_services.h"
|
||||
#include "legacy_preference_storage.h"
|
||||
#include "font.h"
|
||||
@@ -38,21 +35,6 @@ void bind_legacy_tools_menu(App& app);
|
||||
|
||||
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_texture_plan(App& app, pp::app::BrushUiTextureSlot slot, const std::string& path, const std::string& thumb)
|
||||
{
|
||||
return pp::panopainter::apply_legacy_brush_texture_plan(app, slot, path, thumb);
|
||||
}
|
||||
|
||||
bool apply_brush_preset_plan(App& app, const std::shared_ptr<Brush>& brush)
|
||||
{
|
||||
return pp::panopainter::apply_legacy_brush_preset_plan(app, brush);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool should_open_tools_panel(const pp::app::ToolsPanelPlan& plan) noexcept
|
||||
{
|
||||
return plan.action == pp::app::ToolsPanelAction::open_floating_panel;
|
||||
@@ -112,64 +94,6 @@ void App::init_toolbar_main()
|
||||
pp::panopainter::bind_legacy_main_toolbar(*this);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool current_canvas_mode_is_draw(App& app) noexcept
|
||||
{
|
||||
return app.canvas && app.canvas->m_canvas && app.canvas->m_canvas->m_current_mode == kCanvasMode::Draw;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void execute_canvas_tool_toolbar_binding(
|
||||
App& app,
|
||||
const pp::app::CanvasToolToolbarBinding& binding,
|
||||
T* button)
|
||||
{
|
||||
const auto plan = pp::app::plan_canvas_tool_toolbar_binding_action(
|
||||
binding,
|
||||
current_canvas_mode_is_draw(app));
|
||||
const auto status = binding.action == pp::app::CanvasToolToolbarAction::select_mode
|
||||
? pp::panopainter::execute_legacy_canvas_tool_plan(app, plan, button)
|
||||
: pp::panopainter::execute_legacy_canvas_tool_plan(app, plan);
|
||||
if (!status.ok())
|
||||
LOG("Canvas toolbar action failed: %s", status.message);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void bind_canvas_tool_toolbar_button(
|
||||
App& app,
|
||||
const pp::app::CanvasToolToolbarBinding& binding,
|
||||
T* button)
|
||||
{
|
||||
button->on_click = [&app, binding, button](Node*) {
|
||||
execute_canvas_tool_toolbar_binding(app, binding, button);
|
||||
};
|
||||
}
|
||||
|
||||
void App::init_toolbar_draw()
|
||||
{
|
||||
const auto toolbar = pp::app::plan_canvas_tool_toolbar();
|
||||
bool apply_default_tool = false;
|
||||
for (const auto& binding : toolbar.bindings) {
|
||||
if (binding.custom_button) {
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>(binding.button_id.data())) {
|
||||
bind_canvas_tool_toolbar_button(*this, binding, button);
|
||||
apply_default_tool = apply_default_tool || binding.applies_default_on_init;
|
||||
}
|
||||
} else {
|
||||
if (auto* button = layout[main_id]->find<NodeButton>(binding.button_id.data())) {
|
||||
bind_canvas_tool_toolbar_button(*this, binding, button);
|
||||
apply_default_tool = apply_default_tool || binding.applies_default_on_init;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_default_tool) {
|
||||
const auto default_plan = pp::app::plan_canvas_tool_select(toolbar.default_mode);
|
||||
const auto status = pp::panopainter::execute_legacy_canvas_tool_plan(*this, default_plan);
|
||||
if (!status.ok())
|
||||
LOG("Canvas default tool action failed: %s", status.message);
|
||||
}
|
||||
}
|
||||
|
||||
void App::init_menu_file()
|
||||
{
|
||||
pp::panopainter::bind_legacy_file_menu(*this);
|
||||
|
||||
68
src/app_layout_draw_toolbar.cpp
Normal file
68
src/app_layout_draw_toolbar.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "app_core/canvas_tool_ui.h"
|
||||
#include "legacy_canvas_tool_services.h"
|
||||
#include "node_button.h"
|
||||
#include "node_button_custom.h"
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] bool current_canvas_mode_is_draw(App& app) noexcept
|
||||
{
|
||||
return app.canvas && app.canvas->m_canvas && app.canvas->m_canvas->m_current_mode == kCanvasMode::Draw;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void execute_canvas_tool_toolbar_binding(
|
||||
App& app,
|
||||
const pp::app::CanvasToolToolbarBinding& binding,
|
||||
T* button)
|
||||
{
|
||||
const auto plan = pp::app::plan_canvas_tool_toolbar_binding_action(
|
||||
binding,
|
||||
current_canvas_mode_is_draw(app));
|
||||
const auto status = binding.action == pp::app::CanvasToolToolbarAction::select_mode
|
||||
? pp::panopainter::execute_legacy_canvas_tool_plan(app, plan, button)
|
||||
: pp::panopainter::execute_legacy_canvas_tool_plan(app, plan);
|
||||
if (!status.ok())
|
||||
LOG("Canvas toolbar action failed: %s", status.message);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void bind_canvas_tool_toolbar_button(
|
||||
App& app,
|
||||
const pp::app::CanvasToolToolbarBinding& binding,
|
||||
T* button)
|
||||
{
|
||||
button->on_click = [&app, binding, button](Node*) {
|
||||
execute_canvas_tool_toolbar_binding(app, binding, button);
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void App::init_toolbar_draw()
|
||||
{
|
||||
const auto toolbar = pp::app::plan_canvas_tool_toolbar();
|
||||
bool apply_default_tool = false;
|
||||
for (const auto& binding : toolbar.bindings) {
|
||||
if (binding.custom_button) {
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>(binding.button_id.data())) {
|
||||
bind_canvas_tool_toolbar_button(*this, binding, button);
|
||||
apply_default_tool = apply_default_tool || binding.applies_default_on_init;
|
||||
}
|
||||
} else {
|
||||
if (auto* button = layout[main_id]->find<NodeButton>(binding.button_id.data())) {
|
||||
bind_canvas_tool_toolbar_button(*this, binding, button);
|
||||
apply_default_tool = apply_default_tool || binding.applies_default_on_init;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_default_tool) {
|
||||
const auto default_plan = pp::app::plan_canvas_tool_select(toolbar.default_mode);
|
||||
const auto status = pp::panopainter::execute_legacy_canvas_tool_plan(*this, default_plan);
|
||||
if (!status.ok())
|
||||
LOG("Canvas default tool action failed: %s", status.message);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "app.h"
|
||||
#include "app_core/document_animation.h"
|
||||
#include "legacy_canvas_stroke_composite_services.h"
|
||||
#include "legacy_canvas_stroke_erase_services.h"
|
||||
#include "shader.h"
|
||||
@@ -988,6 +990,128 @@ inline void execute_legacy_canvas_draw_unmerged_shell(
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename MakeLayerPathExecution,
|
||||
typename ShouldDrawTemporaryErase,
|
||||
typename ShouldDrawTemporaryPaint,
|
||||
typename FrameAlpha>
|
||||
inline void execute_legacy_canvas_draw_unmerged_layer_path(
|
||||
const LegacyCanvasDrawLayerVisit& visit,
|
||||
const auto& onion_range,
|
||||
bool use_blend,
|
||||
const glm::mat4& proj,
|
||||
const glm::mat4& camera,
|
||||
const glm::mat4& orientation,
|
||||
const auto& plane_transform,
|
||||
MakeLayerPathExecution&& make_layer_path_execution,
|
||||
ShouldDrawTemporaryErase&& should_draw_temporary_erase,
|
||||
ShouldDrawTemporaryPaint&& should_draw_temporary_paint,
|
||||
FrameAlpha&& frame_alpha)
|
||||
{
|
||||
const auto plane_index = visit.plane_index;
|
||||
const auto plane_mvp_z = proj * camera *
|
||||
glm::scale(glm::vec3(visit.z + 1)) *
|
||||
orientation *
|
||||
plane_transform[plane_index] *
|
||||
glm::translate(glm::vec3(0, 0, -1));
|
||||
const auto layer_path_execution = make_layer_path_execution(visit.layer_index, plane_index, plane_mvp_z);
|
||||
|
||||
execute_legacy_canvas_draw_merge_layer_path(
|
||||
should_draw_temporary_erase(visit),
|
||||
should_draw_temporary_paint(visit),
|
||||
use_blend,
|
||||
visit.first_frame,
|
||||
visit.last_frame,
|
||||
[&](int frame) {
|
||||
return frame_alpha(onion_range, frame);
|
||||
},
|
||||
layer_path_execution);
|
||||
}
|
||||
|
||||
template <
|
||||
typename NodeCanvasT,
|
||||
typename PrepareBlendCache,
|
||||
typename DrawBackground,
|
||||
typename ConfigureBlendState,
|
||||
typename DisableDepthTest,
|
||||
typename MakeLayerPathExecution,
|
||||
typename LogOnionRangeFailure,
|
||||
typename CompositeBlendCache>
|
||||
inline void execute_legacy_canvas_draw_unmerged_node_canvas_shell(
|
||||
NodeCanvasT& node_canvas,
|
||||
bool use_blend,
|
||||
const glm::mat4& proj,
|
||||
const glm::mat4& camera,
|
||||
const glm::mat4& orientation,
|
||||
PrepareBlendCache&& prepare_blend_cache,
|
||||
DrawBackground&& draw_background,
|
||||
ConfigureBlendState&& configure_blend_state,
|
||||
DisableDepthTest&& disable_depth_test,
|
||||
MakeLayerPathExecution&& make_layer_path_execution,
|
||||
LogOnionRangeFailure&& log_onion_range_failure,
|
||||
CompositeBlendCache&& composite_blend_cache)
|
||||
{
|
||||
if (use_blend) {
|
||||
prepare_blend_cache();
|
||||
}
|
||||
|
||||
draw_background();
|
||||
configure_blend_state(use_blend);
|
||||
disable_depth_test();
|
||||
|
||||
const auto plan_onion_range = [&](size_t layer_index) {
|
||||
return pp::app::plan_animation_onion_frame_range(
|
||||
node_canvas.m_canvas->m_layers[layer_index]->frames_count(),
|
||||
node_canvas.m_canvas->m_layers[layer_index]->m_frame_index,
|
||||
App::I->animation->get_onion_size());
|
||||
};
|
||||
|
||||
const auto should_draw_plane = [&](size_t layer_index, int plane_index, int first_frame, int last_frame) {
|
||||
bool faces = false;
|
||||
for (int frame = first_frame; frame <= last_frame; ++frame) {
|
||||
faces |= node_canvas.m_canvas->m_layers[layer_index]->face(plane_index, frame);
|
||||
}
|
||||
|
||||
if (node_canvas.m_canvas->m_show_tmp && node_canvas.m_canvas->m_current_layer_idx == layer_index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return node_canvas.m_canvas->m_layers[layer_index]->m_visible &&
|
||||
node_canvas.m_canvas->m_layers[layer_index]->m_opacity != .0f &&
|
||||
faces;
|
||||
};
|
||||
|
||||
execute_legacy_canvas_draw_layer_traversal(
|
||||
node_canvas.m_canvas->m_layers.size(),
|
||||
plan_onion_range,
|
||||
should_draw_plane,
|
||||
[&](const LegacyCanvasDrawLayerVisit& visit, const auto& onion_range) {
|
||||
execute_legacy_canvas_draw_unmerged_layer_path(
|
||||
visit,
|
||||
onion_range,
|
||||
use_blend,
|
||||
proj,
|
||||
camera,
|
||||
orientation,
|
||||
node_canvas.m_canvas->m_plane_transform,
|
||||
make_layer_path_execution,
|
||||
[&](const LegacyCanvasDrawLayerVisit& visit) {
|
||||
return node_canvas.m_canvas->m_current_stroke && node_canvas.m_canvas->m_current_mode == kCanvasMode::Erase && node_canvas.m_canvas->m_show_tmp && node_canvas.m_canvas->m_current_layer_idx == visit.layer_index;
|
||||
},
|
||||
[&](const LegacyCanvasDrawLayerVisit& visit) {
|
||||
return node_canvas.m_canvas->m_current_stroke && node_canvas.m_canvas->m_show_tmp && node_canvas.m_canvas->m_current_layer_idx == visit.layer_index;
|
||||
},
|
||||
[&](const auto& onion_range, int frame) {
|
||||
return pp::app::animation_onion_frame_alpha(onion_range, frame);
|
||||
});
|
||||
},
|
||||
std::forward<LogOnionRangeFailure>(log_onion_range_failure));
|
||||
|
||||
if (use_blend) {
|
||||
composite_blend_cache();
|
||||
}
|
||||
}
|
||||
|
||||
inline void execute_legacy_canvas_draw_merge_plane_setup(
|
||||
const LegacyCanvasDrawMergePlaneSetupUniforms& uniforms,
|
||||
const LegacyCanvasDrawMergePlaneSetupExecution& execution)
|
||||
|
||||
63
src/main.cpp
63
src/main.cpp
@@ -21,10 +21,6 @@
|
||||
#include "wacom.h"
|
||||
#include "abr.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
|
||||
namespace pp::platform::windows {
|
||||
void set_async_render_context(HDC hdc, HGLRC hrc);
|
||||
void lock_async_render_context();
|
||||
@@ -323,62 +319,6 @@ int read_WMI_info()
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT_PTR g_iLogHandle = -1;
|
||||
static void SetupExceptionHandler()
|
||||
{
|
||||
// Setup exception handler
|
||||
BT_SetAppName(_T("PanoPainter"));
|
||||
BT_SetAppVersion(g_version_w);
|
||||
//BT_SetSupportEMail(_T("your@email.com"));
|
||||
BT_SetFlags(BTF_DETAILEDMODE | BTF_ATTACHREPORT | BTF_SCREENCAPTURE);
|
||||
|
||||
// = BugTrapServer ===========================================
|
||||
//BT_SetSupportServer(_T("omigamedev.ddns.net"), 8088);
|
||||
BT_SetSupportEMail(_T("info@panopainter.com"));
|
||||
// - or -
|
||||
//BT_SetSupportServer(_T("127.0.0.1"), 9999);
|
||||
|
||||
// = BugTrapWebServer ========================================
|
||||
//BT_SetSupportServer(_T("http://localhost/BugTrapWebServer/RequestHandler.aspx"), BUGTRAP_HTTP_PORT);
|
||||
//BT_SetSupportServer(_T("http://omigamedev.ddns.net:8088/source/Server/BugTrapWebServer/RequestHandler.aspx"), BUGTRAP_HTTP_PORT);
|
||||
BT_SetSupportServer(_T("http://panopainter.com/bug/"), BUGTRAP_HTTP_PORT);
|
||||
|
||||
// required for VS 2005 & 2008
|
||||
BT_InstallSehFilter();
|
||||
|
||||
// Add custom log file using default name
|
||||
// g_iLogHandle = BT_OpenLogFile(NULL, BTLF_TEXT);
|
||||
// BT_SetLogSizeInEntries(g_iLogHandle, 100);
|
||||
// BT_SetLogFlags(g_iLogHandle, BTLF_SHOWTIMESTAMP);
|
||||
// BT_SetLogEchoMode(g_iLogHandle, BTLE_STDERR | BTLE_DBGOUT);
|
||||
//
|
||||
// PCTSTR pszLogFileName = BT_GetLogFileName(g_iLogHandle);
|
||||
TCHAR wpath[MAX_PATH];
|
||||
//GetFullPathNameW(L"panopainter-log.txt", 1024, wpath, nullptr);
|
||||
auto log_file = App::I->data_path + "/panopainter-log.txt";
|
||||
std::mbstowcs(wpath, log_file.c_str(), log_file.size());
|
||||
BT_AddLogFile(wpath);
|
||||
|
||||
BT_SetPreErrHandler([](INT_PTR){
|
||||
if (Canvas::I && Canvas::I->m_unsaved)
|
||||
{
|
||||
auto t = std::time(nullptr);
|
||||
auto tm = *std::localtime(&t);
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S");
|
||||
|
||||
auto path = App::I->data_path + "/" + App::I->doc_name + "-recovery (" + oss.str() + ").ppi";
|
||||
Canvas::I->project_save_thread(path, false);
|
||||
static char abspath[MAX_PATH];
|
||||
GetFullPathNameA(path.c_str(), MAX_PATH, abspath, NULL);
|
||||
static char message[4096];
|
||||
snprintf(message, sizeof(message), "File recovered in: %s", abspath);
|
||||
MessageBoxA(retained_state().hWnd, message, "File Recovery", MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
LogRemote::I.file_close();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
// create a reverse map from kKey to VK_XXX
|
||||
void init_vk_map()
|
||||
{
|
||||
@@ -439,8 +379,7 @@ int main(int argc, char** argv)
|
||||
|
||||
init_vk_map();
|
||||
|
||||
SetupExceptionHandler();
|
||||
BT_SetTerminate();
|
||||
pp::platform::windows::setup_exception_handler();
|
||||
|
||||
read_WMI_info();
|
||||
|
||||
|
||||
@@ -667,11 +667,15 @@ void NodeCanvas::draw()
|
||||
m_canvas->m_current_stroke ? m_canvas->m_current_stroke->m_brush.get() : nullptr);
|
||||
const bool use_blend = blend_gate.shader_blend;
|
||||
const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color;
|
||||
const auto layer_orientation = glm::eulerAngleYXZ(yaw, pitch, roll);
|
||||
|
||||
const auto& b = m_canvas->m_current_stroke->m_brush;
|
||||
pp::panopainter::execute_legacy_canvas_draw_unmerged_shell(
|
||||
pp::panopainter::execute_legacy_canvas_draw_unmerged_node_canvas_shell(
|
||||
*this,
|
||||
use_blend,
|
||||
m_canvas->m_layers.size(),
|
||||
proj,
|
||||
camera,
|
||||
layer_orientation,
|
||||
[&] {
|
||||
apply_node_canvas_viewport(0, 0, m_cache_rtt.getWidth(), m_cache_rtt.getHeight());
|
||||
m_cache_rtt.bindFramebuffer();
|
||||
@@ -703,33 +707,8 @@ void NodeCanvas::draw()
|
||||
[&] {
|
||||
apply_node_canvas_capability(pp::renderer::gl::depth_test_state(), false);
|
||||
},
|
||||
[&](size_t layer_index) {
|
||||
return pp::app::plan_animation_onion_frame_range(
|
||||
m_canvas->m_layers[layer_index]->frames_count(),
|
||||
m_canvas->m_layers[layer_index]->m_frame_index,
|
||||
App::I->animation->get_onion_size());
|
||||
},
|
||||
[&](size_t layer_index, int plane_index, int first_frame, int last_frame) {
|
||||
bool faces = false;
|
||||
for (int frame = first_frame; frame <= last_frame; ++frame)
|
||||
faces |= m_canvas->m_layers[layer_index]->face(plane_index, frame);
|
||||
|
||||
if (m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||
return true;
|
||||
|
||||
return m_canvas->m_layers[layer_index]->m_visible &&
|
||||
m_canvas->m_layers[layer_index]->m_opacity != .0f &&
|
||||
faces;
|
||||
},
|
||||
[&](const pp::panopainter::LegacyCanvasDrawLayerVisit& visit, const auto& onion_range) {
|
||||
const auto layer_index = visit.layer_index;
|
||||
const auto plane_index = visit.plane_index;
|
||||
const auto plane_mvp_z = proj * camera *
|
||||
glm::scale(glm::vec3(visit.z + 1)) *
|
||||
glm::eulerAngleYXZ(yaw, pitch, roll) *
|
||||
m_canvas->m_plane_transform[plane_index] *
|
||||
glm::translate(glm::vec3(0, 0, -1));
|
||||
const auto layer_path_execution = make_node_canvas_layer_path_execution(
|
||||
[&](size_t layer_index, int plane_index, const glm::mat4& plane_mvp_z) {
|
||||
return make_node_canvas_layer_path_execution(
|
||||
*this,
|
||||
layer_index,
|
||||
plane_index,
|
||||
@@ -737,17 +716,6 @@ void NodeCanvas::draw()
|
||||
b.get(),
|
||||
copy_blend_destination,
|
||||
m_canvas->m_cam_fov < 20.f);
|
||||
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_layer_path(
|
||||
m_canvas->m_current_stroke && m_canvas->m_current_mode == kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index,
|
||||
m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index,
|
||||
use_blend,
|
||||
visit.first_frame,
|
||||
visit.last_frame,
|
||||
[&](int frame) {
|
||||
return pp::app::animation_onion_frame_alpha(onion_range, frame);
|
||||
},
|
||||
layer_path_execution);
|
||||
},
|
||||
[&](const char* message) {
|
||||
LOG("NodeCanvas onion frame range failed: %s", message);
|
||||
|
||||
@@ -4,10 +4,16 @@
|
||||
#include "platform_windows/windows_window_shell.h"
|
||||
|
||||
#include "app.h"
|
||||
#include "canvas.h"
|
||||
#include "legacy_gl_runtime_dispatch.h"
|
||||
#include "legacy_preference_storage.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <shellscalingapi.h>
|
||||
#include <string>
|
||||
|
||||
@@ -105,6 +111,57 @@ void ensure_runtime_data_directory()
|
||||
LOG("data files ok");
|
||||
}
|
||||
|
||||
void setup_exception_handler()
|
||||
{
|
||||
// Setup exception handler
|
||||
BT_SetAppName(_T("PanoPainter"));
|
||||
BT_SetAppVersion(g_version_w);
|
||||
//BT_SetSupportEMail(_T("your@email.com"));
|
||||
BT_SetFlags(BTF_DETAILEDMODE | BTF_ATTACHREPORT | BTF_SCREENCAPTURE);
|
||||
|
||||
// = BugTrapServer ===========================================
|
||||
//BT_SetSupportServer(_T("omigamedev.ddns.net"), 8088);
|
||||
BT_SetSupportEMail(_T("info@panopainter.com"));
|
||||
// - or -
|
||||
//BT_SetSupportServer(_T("127.0.0.1"), 9999);
|
||||
|
||||
// = BugTrapWebServer ========================================
|
||||
//BT_SetSupportServer(_T("http://localhost/BugTrapWebServer/RequestHandler.aspx"), BUGTRAP_HTTP_PORT);
|
||||
//BT_SetSupportServer(_T("http://omigamedev.ddns.net:8088/source/Server/BugTrapWebServer/RequestHandler.aspx"), BUGTRAP_HTTP_PORT);
|
||||
BT_SetSupportServer(_T("http://panopainter.com/bug/"), BUGTRAP_HTTP_PORT);
|
||||
|
||||
// required for VS 2005 & 2008
|
||||
BT_InstallSehFilter();
|
||||
|
||||
// Add custom log file using default name
|
||||
TCHAR wpath[MAX_PATH];
|
||||
//GetFullPathNameW(L"panopainter-log.txt", 1024, wpath, nullptr);
|
||||
auto log_file = App::I->data_path + "/panopainter-log.txt";
|
||||
std::mbstowcs(wpath, log_file.c_str(), log_file.size());
|
||||
BT_AddLogFile(wpath);
|
||||
|
||||
BT_SetPreErrHandler([](INT_PTR){
|
||||
if (Canvas::I && Canvas::I->m_unsaved)
|
||||
{
|
||||
auto t = std::time(nullptr);
|
||||
auto tm = *std::localtime(&t);
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S");
|
||||
|
||||
auto path = App::I->data_path + "/" + App::I->doc_name + "-recovery (" + oss.str() + ").ppi";
|
||||
Canvas::I->project_save_thread(path, false);
|
||||
static char abspath[MAX_PATH];
|
||||
GetFullPathNameA(path.c_str(), MAX_PATH, abspath, NULL);
|
||||
static char message[4096];
|
||||
snprintf(message, sizeof(message), "File recovered in: %s", abspath);
|
||||
MessageBoxA(retained_state().hWnd, message, "File Recovery", MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
LogRemote::I.file_close();
|
||||
}, 0);
|
||||
|
||||
BT_SetTerminate();
|
||||
}
|
||||
|
||||
MainWindowStartupState initialize_main_window_startup_state()
|
||||
{
|
||||
auto startup = MainWindowStartupState {};
|
||||
|
||||
@@ -46,6 +46,7 @@ enum class MainStartupResult
|
||||
};
|
||||
|
||||
void ensure_runtime_data_directory();
|
||||
void setup_exception_handler();
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user