Extract dialog workflow, bootstrap, and canvas tail helpers
This commit is contained in:
@@ -2,100 +2,29 @@
|
||||
#include "app.h"
|
||||
#include "app_core/app_dialog.h"
|
||||
#include "app_core/document_layer.h"
|
||||
#include "app_core/document_resize.h"
|
||||
#include "app_core/document_export.h"
|
||||
#include "app_core/document_session.h"
|
||||
#include "legacy_document_canvas_services.h"
|
||||
#include "legacy_app_dialog_services.h"
|
||||
#include "legacy_brush_package_export_services.h"
|
||||
#include "legacy_document_export_services.h"
|
||||
#include "legacy_document_layer_services.h"
|
||||
#include "legacy_document_session_services.h"
|
||||
#include "legacy_ui_overlay_services.h"
|
||||
#include "node_dialog_open.h"
|
||||
#include "node_dialog_browse.h"
|
||||
#include "node_dialog_resize.h"
|
||||
#include "node_dialog_cloud.h"
|
||||
#include "node_dialog_layer_rename.h"
|
||||
|
||||
#ifdef __QUEST__
|
||||
#include "oculus_vr.h"
|
||||
#endif
|
||||
|
||||
namespace pp::panopainter {
|
||||
void open_usermanual_dialog(App& app);
|
||||
void open_changelog_dialog(App& app);
|
||||
void open_about_dialog(App& app);
|
||||
void open_whatsnew_dialog(App& app, bool force_show);
|
||||
void open_shortcuts_dialog(App& app);
|
||||
void open_document_export_dialog(App& app, std::string ext);
|
||||
void open_document_export_layers_dialog(App& app);
|
||||
void open_document_export_anim_frames_dialog(App& app);
|
||||
void open_document_export_depth_dialog(App& app);
|
||||
void open_document_export_cube_faces_dialog(App& app);
|
||||
void open_ppbr_export_dialog(App& app);
|
||||
void open_document_timelapse_export_dialog(App& app);
|
||||
void open_document_export_mp4_dialog(App& app);
|
||||
void open_ppbr_export_dialog(App& app);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void wire_document_browse_dialog_actions(
|
||||
App& app,
|
||||
const std::shared_ptr<NodeDialogBrowse>& dialog,
|
||||
Node& overlay_anchor,
|
||||
pp::ui::NodeHandle overlay_handle)
|
||||
{
|
||||
const auto close_dialog = [&overlay_anchor, overlay_handle]() {
|
||||
const auto close_status =
|
||||
pp::panopainter::close_legacy_overlay_node(overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [&app, dialog, close_dialog](Node*)
|
||||
{
|
||||
if (dialog->is_selected())
|
||||
{
|
||||
app.open_document(dialog->selected_path);
|
||||
close_dialog();
|
||||
}
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
}
|
||||
|
||||
void wire_document_save_dialog_buttons(
|
||||
App& app,
|
||||
const std::shared_ptr<NodeDialogSave>& dialog,
|
||||
std::function<void()> close_dialog)
|
||||
{
|
||||
dialog->btn_ok->on_click = [&app, dialog](Node*)
|
||||
{
|
||||
std::string name = dialog->input->m_text;
|
||||
const auto plan = pp::app::plan_document_file_save(
|
||||
app.work_path,
|
||||
name,
|
||||
[](const std::string& path) {
|
||||
return Asset::exist(path);
|
||||
});
|
||||
if (!plan)
|
||||
{
|
||||
app.message_box("Warning", "You need to specify a name to file.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status =
|
||||
pp::panopainter::execute_legacy_document_file_save_plan(app, plan.value(), dialog);
|
||||
if (!status.ok())
|
||||
LOG("Document file save action failed: %s", status.message);
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
}
|
||||
|
||||
void open_usermanual_dialog(App& app);
|
||||
void open_changelog_dialog(App& app);
|
||||
void open_about_dialog(App& app);
|
||||
void open_whatsnew_dialog(App& app, bool force_show);
|
||||
void open_shortcuts_dialog(App& app);
|
||||
}
|
||||
|
||||
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title, int total /*= 0*/)
|
||||
@@ -139,234 +68,6 @@ void App::dialog_about()
|
||||
pp::panopainter::open_about_dialog(*this);
|
||||
}
|
||||
|
||||
void App::continue_document_workflow_after_optional_save(std::function<void()> action)
|
||||
{
|
||||
const bool has_canvas = canvas != nullptr;
|
||||
const bool has_unsaved_changes = has_canvas && Canvas::I->m_unsaved;
|
||||
const auto decision = pp::app::plan_document_workflow(has_canvas, has_unsaved_changes);
|
||||
const auto status = pp::panopainter::execute_legacy_document_workflow_decision(
|
||||
*this,
|
||||
decision,
|
||||
std::move(action));
|
||||
if (!status.ok())
|
||||
LOG("Document workflow action failed: %s", status.message);
|
||||
}
|
||||
|
||||
void App::dialog_newdoc()
|
||||
{
|
||||
auto show_dialog = [this] {
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("New document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogNewDoc>(*this);
|
||||
dialog->input->set_text("name");
|
||||
|
||||
App::I->showKeyboard();
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
App::I->hideKeyboard();
|
||||
LOG("New document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [this, overlay_anchor, overlay_handle]() {
|
||||
const auto close_status = pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
App::I->hideKeyboard();
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||
{
|
||||
std::string name = dialog->input->m_text;
|
||||
const auto plan = pp::app::plan_new_document(
|
||||
work_path,
|
||||
name,
|
||||
dialog->m_resolution->m_current_index,
|
||||
[](const std::string& path) {
|
||||
return Asset::exist(path);
|
||||
});
|
||||
if (!plan)
|
||||
{
|
||||
const bool missing_name =
|
||||
plan.status().code == pp::foundation::StatusCode::invalid_argument;
|
||||
message_box(
|
||||
"Warning",
|
||||
missing_name ? "You need to specify a name to file." : plan.status().message);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_new_document_plan(*this, plan.value(), dialog);
|
||||
if (!status.ok())
|
||||
LOG("New document action failed: %s", status.message);
|
||||
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
};
|
||||
|
||||
continue_document_workflow_after_optional_save(show_dialog);
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
void App::dialog_open()
|
||||
{
|
||||
auto show_dialog = [this] {
|
||||
// load thumbnail test
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Open document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogOpen>(*this);
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
LOG("Open document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [overlay_anchor, overlay_handle]() {
|
||||
const auto close_status = pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||
{
|
||||
// canvas->reset_camera();
|
||||
// layers->clear();
|
||||
// doc_name = dialog->selected_name;
|
||||
// canvas->m_canvas->project_open(dialog->selected_path, [this](bool success) {
|
||||
// // on complete
|
||||
// async_start();
|
||||
// title_update();
|
||||
// for (auto& i : canvas->m_canvas->m_order)
|
||||
// layers->add_layer(canvas->m_canvas->m_layers[i]->m_name.c_str());
|
||||
// async_end();
|
||||
// });
|
||||
// dialog->destroy();
|
||||
// ActionManager::clear();
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
};
|
||||
|
||||
continue_document_workflow_after_optional_save(show_dialog);
|
||||
}
|
||||
|
||||
void App::dialog_browse()
|
||||
{
|
||||
auto show_dialog = [this] {
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Browse document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogBrowse>(*this);
|
||||
dialog->search_paths = document_browse_roots();
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
LOG("Browse document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
wire_document_browse_dialog_actions(*this, dialog, *overlay_anchor, overlay_handle);
|
||||
};
|
||||
|
||||
continue_document_workflow_after_optional_save(show_dialog);
|
||||
}
|
||||
|
||||
void save_document_version(App& app)
|
||||
{
|
||||
const auto target = pp::app::find_next_document_version_target(
|
||||
app.doc_dir,
|
||||
app.doc_name,
|
||||
[](const std::string& path) {
|
||||
return Asset::exist(path);
|
||||
});
|
||||
if (!target) {
|
||||
app.message_box("Saving Error", target.status().message);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_document_version_save(app, target.value());
|
||||
if (!status.ok())
|
||||
LOG("Document version save action failed: %s", status.message);
|
||||
}
|
||||
|
||||
void App::dialog_save_ver()
|
||||
{
|
||||
if (!check_license())
|
||||
{
|
||||
message_box("License", "This function is disabled in demo mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
save_document_version(*this);
|
||||
}
|
||||
|
||||
void App::save_document(pp::app::DocumentSaveIntent intent)
|
||||
{
|
||||
const auto decision = pp::app::plan_document_save(
|
||||
Canvas::I->m_newdoc,
|
||||
Canvas::I->m_unsaved,
|
||||
intent);
|
||||
const auto status = pp::panopainter::execute_legacy_document_save_decision(*this, decision);
|
||||
if (!status.ok())
|
||||
LOG("Document save action failed: %s", status.message);
|
||||
}
|
||||
|
||||
void App::dialog_save()
|
||||
{
|
||||
if (!check_license())
|
||||
{
|
||||
message_box("License", "This function is disabled in demo mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (canvas)
|
||||
{
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Save document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogSave>(*this);
|
||||
dialog->input->set_text(doc_name);
|
||||
|
||||
App::I->showKeyboard();
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
App::I->hideKeyboard();
|
||||
LOG("Save document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [this, overlay_anchor, overlay_handle]() {
|
||||
const auto close_status = pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
App::I->hideKeyboard();
|
||||
};
|
||||
|
||||
wire_document_save_dialog_buttons(*this, dialog, close_dialog);
|
||||
}
|
||||
}
|
||||
|
||||
void App::dialog_export(std::string ext)
|
||||
{
|
||||
pp::panopainter::open_document_export_dialog(*this, ext);
|
||||
@@ -387,47 +88,6 @@ void App::dialog_export_depth()
|
||||
pp::panopainter::open_document_export_depth_dialog(*this);
|
||||
}
|
||||
|
||||
void App::dialog_resize()
|
||||
{
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Resize dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogResize>(*this);
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
LOG("Resize dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [overlay_anchor, overlay_handle]() {
|
||||
const auto close_status =
|
||||
pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [this, dialog, close_dialog](Node*)
|
||||
{
|
||||
const auto plan = pp::app::plan_document_resize(
|
||||
dialog->combo ? dialog->combo->m_current_index : 0);
|
||||
if (!plan)
|
||||
{
|
||||
close_dialog();
|
||||
return;
|
||||
}
|
||||
const auto status = pp::panopainter::execute_legacy_document_resize_plan(*this, plan.value());
|
||||
if (!status.ok())
|
||||
LOG("Document resize failed: %s", status.message);
|
||||
close_dialog();
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*) {
|
||||
close_dialog();
|
||||
};
|
||||
}
|
||||
|
||||
void App::dialog_export_cube_faces()
|
||||
{
|
||||
pp::panopainter::open_document_export_cube_faces_dialog(*this);
|
||||
|
||||
343
src/app_dialogs_workflow.cpp
Normal file
343
src/app_dialogs_workflow.cpp
Normal file
@@ -0,0 +1,343 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "app_core/document_resize.h"
|
||||
#include "legacy_document_canvas_services.h"
|
||||
#include "legacy_document_session_services.h"
|
||||
#include "legacy_ui_overlay_services.h"
|
||||
#include "node_dialog_browse.h"
|
||||
#include "node_dialog_open.h"
|
||||
#include "node_dialog_resize.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void wire_document_browse_dialog_actions(
|
||||
App& app,
|
||||
const std::shared_ptr<NodeDialogBrowse>& dialog,
|
||||
Node& overlay_anchor,
|
||||
pp::ui::NodeHandle overlay_handle)
|
||||
{
|
||||
const auto close_dialog = [&overlay_anchor, overlay_handle]() {
|
||||
const auto close_status =
|
||||
pp::panopainter::close_legacy_overlay_node(overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [&app, dialog, close_dialog](Node*)
|
||||
{
|
||||
if (dialog->is_selected())
|
||||
{
|
||||
app.open_document(dialog->selected_path);
|
||||
close_dialog();
|
||||
}
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
}
|
||||
|
||||
void wire_document_save_dialog_buttons(
|
||||
App& app,
|
||||
const std::shared_ptr<NodeDialogSave>& dialog,
|
||||
std::function<void()> close_dialog)
|
||||
{
|
||||
dialog->btn_ok->on_click = [&app, dialog](Node*)
|
||||
{
|
||||
std::string name = dialog->input->m_text;
|
||||
const auto plan = pp::app::plan_document_file_save(
|
||||
app.work_path,
|
||||
name,
|
||||
[](const std::string& path) {
|
||||
return Asset::exist(path);
|
||||
});
|
||||
if (!plan)
|
||||
{
|
||||
app.message_box("Warning", "You need to specify a name to file.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status =
|
||||
pp::panopainter::execute_legacy_document_file_save_plan(app, plan.value(), dialog);
|
||||
if (!status.ok())
|
||||
LOG("Document file save action failed: %s", status.message);
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
}
|
||||
|
||||
void save_document_version(App& app)
|
||||
{
|
||||
const auto target = pp::app::find_next_document_version_target(
|
||||
app.doc_dir,
|
||||
app.doc_name,
|
||||
[](const std::string& path) {
|
||||
return Asset::exist(path);
|
||||
});
|
||||
if (!target) {
|
||||
app.message_box("Saving Error", target.status().message);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_document_version_save(app, target.value());
|
||||
if (!status.ok())
|
||||
LOG("Document version save action failed: %s", status.message);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void App::continue_document_workflow_after_optional_save(std::function<void()> action)
|
||||
{
|
||||
const bool has_canvas = canvas != nullptr;
|
||||
const bool has_unsaved_changes = has_canvas && Canvas::I->m_unsaved;
|
||||
const auto decision = pp::app::plan_document_workflow(has_canvas, has_unsaved_changes);
|
||||
const auto status = pp::panopainter::execute_legacy_document_workflow_decision(
|
||||
*this,
|
||||
decision,
|
||||
std::move(action));
|
||||
if (!status.ok())
|
||||
LOG("Document workflow action failed: %s", status.message);
|
||||
}
|
||||
|
||||
void App::dialog_newdoc()
|
||||
{
|
||||
auto show_dialog = [this] {
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("New document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogNewDoc>(*this);
|
||||
dialog->input->set_text("name");
|
||||
|
||||
App::I->showKeyboard();
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
App::I->hideKeyboard();
|
||||
LOG("New document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [this, overlay_anchor, overlay_handle]() {
|
||||
const auto close_status =
|
||||
pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
App::I->hideKeyboard();
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||
{
|
||||
std::string name = dialog->input->m_text;
|
||||
const auto plan = pp::app::plan_new_document(
|
||||
work_path,
|
||||
name,
|
||||
dialog->m_resolution->m_current_index,
|
||||
[](const std::string& path) {
|
||||
return Asset::exist(path);
|
||||
});
|
||||
if (!plan)
|
||||
{
|
||||
const bool missing_name =
|
||||
plan.status().code == pp::foundation::StatusCode::invalid_argument;
|
||||
message_box(
|
||||
"Warning",
|
||||
missing_name ? "You need to specify a name to file." : plan.status().message);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status =
|
||||
pp::panopainter::execute_legacy_new_document_plan(*this, plan.value(), dialog);
|
||||
if (!status.ok())
|
||||
LOG("New document action failed: %s", status.message);
|
||||
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
};
|
||||
|
||||
continue_document_workflow_after_optional_save(show_dialog);
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
void App::dialog_open()
|
||||
{
|
||||
auto show_dialog = [this] {
|
||||
// load thumbnail test
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Open document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogOpen>(*this);
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
LOG("Open document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [overlay_anchor, overlay_handle]() {
|
||||
const auto close_status =
|
||||
pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||
{
|
||||
// canvas->reset_camera();
|
||||
// layers->clear();
|
||||
// doc_name = dialog->selected_name;
|
||||
// canvas->m_canvas->project_open(dialog->selected_path, [this](bool success) {
|
||||
// // on complete
|
||||
// async_start();
|
||||
// title_update();
|
||||
// for (auto& i : canvas->m_canvas->m_order)
|
||||
// layers->add_layer(canvas->m_canvas->m_layers[i]->m_name.c_str());
|
||||
// async_end();
|
||||
// });
|
||||
// dialog->destroy();
|
||||
// ActionManager::clear();
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
};
|
||||
|
||||
continue_document_workflow_after_optional_save(show_dialog);
|
||||
}
|
||||
|
||||
void App::dialog_browse()
|
||||
{
|
||||
auto show_dialog = [this] {
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Browse document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogBrowse>(*this);
|
||||
dialog->search_paths = document_browse_roots();
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
LOG("Browse document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
wire_document_browse_dialog_actions(*this, dialog, *overlay_anchor, overlay_handle);
|
||||
};
|
||||
|
||||
continue_document_workflow_after_optional_save(show_dialog);
|
||||
}
|
||||
|
||||
void App::dialog_save_ver()
|
||||
{
|
||||
if (!check_license())
|
||||
{
|
||||
message_box("License", "This function is disabled in demo mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
save_document_version(*this);
|
||||
}
|
||||
|
||||
void App::save_document(pp::app::DocumentSaveIntent intent)
|
||||
{
|
||||
const auto decision = pp::app::plan_document_save(
|
||||
Canvas::I->m_newdoc,
|
||||
Canvas::I->m_unsaved,
|
||||
intent);
|
||||
const auto status = pp::panopainter::execute_legacy_document_save_decision(*this, decision);
|
||||
if (!status.ok())
|
||||
LOG("Document save action failed: %s", status.message);
|
||||
}
|
||||
|
||||
void App::dialog_save()
|
||||
{
|
||||
if (!check_license())
|
||||
{
|
||||
message_box("License", "This function is disabled in demo mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (canvas)
|
||||
{
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Save document dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogSave>(*this);
|
||||
dialog->input->set_text(doc_name);
|
||||
|
||||
App::I->showKeyboard();
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
App::I->hideKeyboard();
|
||||
LOG("Save document dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [this, overlay_anchor, overlay_handle]() {
|
||||
const auto close_status =
|
||||
pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
App::I->hideKeyboard();
|
||||
};
|
||||
|
||||
wire_document_save_dialog_buttons(*this, dialog, close_dialog);
|
||||
}
|
||||
}
|
||||
|
||||
void App::dialog_resize()
|
||||
{
|
||||
auto* overlay_anchor = layout[main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("Resize dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogResize>(*this);
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
LOG("Resize dialog open failed: %s", overlay.status().message);
|
||||
return;
|
||||
}
|
||||
const auto overlay_handle = overlay.value();
|
||||
|
||||
const auto close_dialog = [overlay_anchor, overlay_handle]() {
|
||||
const auto close_status =
|
||||
pp::panopainter::close_legacy_overlay_node(*overlay_anchor, overlay_handle);
|
||||
(void)close_status;
|
||||
};
|
||||
|
||||
dialog->btn_ok->on_click = [this, dialog, close_dialog](Node*)
|
||||
{
|
||||
const auto plan = pp::app::plan_document_resize(
|
||||
dialog->combo ? dialog->combo->m_current_index : 0);
|
||||
if (!plan)
|
||||
{
|
||||
close_dialog();
|
||||
return;
|
||||
}
|
||||
const auto status = pp::panopainter::execute_legacy_document_resize_plan(*this, plan.value());
|
||||
if (!status.ok())
|
||||
LOG("Document resize failed: %s", status.message);
|
||||
close_dialog();
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*) {
|
||||
close_dialog();
|
||||
};
|
||||
}
|
||||
104
src/main.cpp
104
src/main.cpp
@@ -43,6 +43,15 @@ namespace pp::platform::windows {
|
||||
void unlock_async_render_context();
|
||||
void swap_async_render_context();
|
||||
}
|
||||
extern HRESULT(*GetDpiForMonitor_fn)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT* dpiX, UINT* dpiY);
|
||||
extern HRESULT(*SetProcessDpiAwareness_fn)(PROCESS_DPI_AWARENESS value);
|
||||
bool win32_renderdoc_init();
|
||||
void win32_renderdoc_frame_start();
|
||||
void win32_renderdoc_frame_end();
|
||||
void init_shcore_API();
|
||||
std::string GetLastErrorAsString();
|
||||
void _pre_call_callback(const char* name, void* funcptr, int len_args, ...);
|
||||
void _post_call_callback(const char* name, void* funcptr, int len_args, ...);
|
||||
struct RetainedState
|
||||
{
|
||||
HINSTANCE hInst{};
|
||||
@@ -120,71 +129,6 @@ void pp_windows_enqueue_main_task(std::packaged_task<void()> task)
|
||||
|
||||
std::atomic<int> running{-1};
|
||||
|
||||
#ifdef USE_RENDERDOC
|
||||
RENDERDOC_API_1_4_0* rdoc_api = NULL;
|
||||
bool win32_renderdoc_init()
|
||||
{
|
||||
// At init, on windows
|
||||
if (HMODULE mod = GetModuleHandleA("renderdoc.dll"))
|
||||
{
|
||||
pRENDERDOC_GetAPI RENDERDOC_GetAPI =
|
||||
(pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
|
||||
return RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&rdoc_api);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void win32_renderdoc_frame_start()
|
||||
{
|
||||
if (rdoc_api)
|
||||
rdoc_api->StartFrameCapture(NULL, NULL);
|
||||
}
|
||||
|
||||
void win32_renderdoc_frame_end()
|
||||
{
|
||||
if (rdoc_api)
|
||||
rdoc_api->EndFrameCapture(NULL, NULL);
|
||||
}
|
||||
#else
|
||||
void win32_renderdoc_frame_start() { }
|
||||
void win32_renderdoc_frame_end() { }
|
||||
#endif
|
||||
|
||||
HRESULT(*GetDpiForMonitor_fn)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT* dpiX, UINT* dpiY);
|
||||
HRESULT(*SetProcessDpiAwareness_fn)(PROCESS_DPI_AWARENESS value);
|
||||
void init_shcore_API()
|
||||
{
|
||||
HMODULE dll = LoadLibrary(L"Shcore.dll");
|
||||
if (!dll)
|
||||
{
|
||||
LOG("cannot load Shcore.dll");
|
||||
return;
|
||||
}
|
||||
LOG("loaded Shcore.dll");
|
||||
GetDpiForMonitor_fn = (decltype(GetDpiForMonitor_fn))GetProcAddress(dll, "GetDpiForMonitor");
|
||||
SetProcessDpiAwareness_fn = (decltype(SetProcessDpiAwareness_fn))GetProcAddress(dll, "SetProcessDpiAwareness");
|
||||
}
|
||||
|
||||
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
|
||||
std::string GetLastErrorAsString()
|
||||
{
|
||||
//Get the error message, if any.
|
||||
DWORD errorMessageID = ::GetLastError();
|
||||
if (errorMessageID == 0)
|
||||
return std::string(); //No error message has been recorded
|
||||
|
||||
LPSTR messageBuffer = nullptr;
|
||||
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||
|
||||
std::string message(messageBuffer, size);
|
||||
|
||||
//Free the buffer.
|
||||
LocalFree(messageBuffer);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
void destroy_window()
|
||||
{
|
||||
auto& state = retained_state();
|
||||
@@ -531,36 +475,6 @@ void win32_save_window_state()
|
||||
p.rcNormalPosition.right,
|
||||
p.rcNormalPosition.bottom });
|
||||
}
|
||||
BOOL UnadjustWindowRectEx(LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle)
|
||||
{
|
||||
RECT rc;
|
||||
SetRectEmpty(&rc);
|
||||
BOOL fRc = AdjustWindowRectEx(&rc, dwStyle, fMenu, dwExStyle);
|
||||
if (fRc) {
|
||||
prc->left -= rc.left;
|
||||
prc->top -= rc.top;
|
||||
prc->right -= rc.right;
|
||||
prc->bottom -= rc.bottom;
|
||||
}
|
||||
return fRc;
|
||||
}
|
||||
|
||||
void _pre_call_callback(const char* name, void* funcptr, int len_args, ...)
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
}
|
||||
|
||||
void _post_call_callback(const char* name, void* funcptr, int len_args, ...)
|
||||
{
|
||||
GLenum error_code;
|
||||
error_code = glad_glGetError();
|
||||
|
||||
if (error_code != pp::renderer::gl::no_error_code())
|
||||
{
|
||||
LOG("ERROR %d in %s\n", error_code, name);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
auto& state = retained_state();
|
||||
|
||||
@@ -395,6 +395,101 @@ pp::panopainter::LegacyCanvasDrawMergeLayerPathExecution make_node_canvas_layer_
|
||||
draw_layer_frame);
|
||||
}
|
||||
|
||||
void execute_node_canvas_draw_merge_tail(
|
||||
NodeCanvas& node_canvas,
|
||||
const glm::mat4& ortho_proj,
|
||||
const glm::mat4& proj,
|
||||
const glm::mat4& camera,
|
||||
const glm::ivec4& c)
|
||||
{
|
||||
apply_node_canvas_capability(pp::renderer::gl::depth_test_state(), false);
|
||||
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_post_draw_callbacks(
|
||||
node_canvas.m_canvas->m_smask_active,
|
||||
node_canvas.m_canvas->m_current_mode == kCanvasMode::Copy || node_canvas.m_canvas->m_current_mode == kCanvasMode::Cut,
|
||||
node_canvas.m_canvas->m_smask_mode,
|
||||
node_canvas.m_canvas->m_current_mode != kCanvasMode::Grid,
|
||||
[&] {
|
||||
node_canvas.m_canvas->modes[(int)kCanvasMode::MaskFree][0]->on_Draw(ortho_proj, proj, camera);
|
||||
},
|
||||
[&] {
|
||||
node_canvas.m_canvas->modes[(int)kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera);
|
||||
},
|
||||
[&] {
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_smask_faces(
|
||||
pp::panopainter::LegacyCanvasDrawMergeTextureMaskUniforms {
|
||||
.texture_slot = 0,
|
||||
.pattern_offset = node_canvas.m_outline_pan,
|
||||
},
|
||||
proj,
|
||||
camera,
|
||||
node_canvas.m_canvas->m_layers.size() + 500.f,
|
||||
std::to_array(node_canvas.m_canvas->m_plane_transform),
|
||||
{
|
||||
.set_active_texture_unit = [&] {
|
||||
set_active_texture_unit(0);
|
||||
},
|
||||
.enable_blend = [&] {
|
||||
apply_node_canvas_capability(pp::renderer::gl::blend_state(), true);
|
||||
},
|
||||
.bind_face_texture = [&](int plane_index) {
|
||||
node_canvas.m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
},
|
||||
.draw_face = [&] {
|
||||
node_canvas.m_face_plane.draw_fill();
|
||||
},
|
||||
.unbind_face_texture = [&](int plane_index) {
|
||||
node_canvas.m_canvas->m_smask.rtt(plane_index).unbindTexture();
|
||||
},
|
||||
});
|
||||
},
|
||||
pp::panopainter::make_legacy_canvas_draw_merge_grid_modes_draw(
|
||||
&Canvas::modes[(int)kCanvasMode::Grid],
|
||||
ortho_proj,
|
||||
proj,
|
||||
camera),
|
||||
pp::panopainter::make_legacy_canvas_draw_merge_heightmap_draw(App::I->grid.get(), proj, camera),
|
||||
pp::panopainter::make_legacy_canvas_draw_merge_current_modes_draw(
|
||||
node_canvas.m_canvas->m_mode,
|
||||
ortho_proj,
|
||||
proj,
|
||||
camera));
|
||||
|
||||
if (node_canvas.m_density != 1.f) {
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_display_resolve(
|
||||
pp::panopainter::LegacyCanvasDrawMergeDisplayResolveUniforms {
|
||||
.texture = {
|
||||
.mvp = glm::ortho<float>(-1, 1, -1, 1),
|
||||
.texture_slot = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.unbind_resolve_framebuffer = [&] {
|
||||
node_canvas.m_rtt.unbindFramebuffer();
|
||||
},
|
||||
.clear_color_buffer = [&] {
|
||||
clear_node_canvas_color_buffer({ 1.f, 1.f, 1.f, 0.f });
|
||||
},
|
||||
.apply_viewport = [&] {
|
||||
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
|
||||
},
|
||||
.bind_sampler = [&] {
|
||||
node_canvas.m_sampler_nearest.bind(0);
|
||||
},
|
||||
.bind_resolve_texture = [&] {
|
||||
set_active_texture_unit(0);
|
||||
node_canvas.m_rtt.bindTexture();
|
||||
},
|
||||
.draw = [&] {
|
||||
node_canvas.m_face_plane.draw_fill();
|
||||
},
|
||||
.unbind_resolve_texture = [&] {
|
||||
node_canvas.m_rtt.unbindTexture();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Node* NodeCanvas::clone_instantiate() const
|
||||
@@ -700,93 +795,7 @@ void NodeCanvas::draw()
|
||||
}
|
||||
}
|
||||
|
||||
apply_node_canvas_capability(pp::renderer::gl::depth_test_state(), false);
|
||||
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_post_draw_callbacks(
|
||||
m_canvas->m_smask_active,
|
||||
m_canvas->m_current_mode == kCanvasMode::Copy || m_canvas->m_current_mode == kCanvasMode::Cut,
|
||||
m_canvas->m_smask_mode,
|
||||
m_canvas->m_current_mode != kCanvasMode::Grid,
|
||||
[&] {
|
||||
m_canvas->modes[(int)kCanvasMode::MaskFree][0]->on_Draw(ortho_proj, proj, camera);
|
||||
},
|
||||
[&] {
|
||||
m_canvas->modes[(int)kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera);
|
||||
},
|
||||
[&] {
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_smask_faces(
|
||||
pp::panopainter::LegacyCanvasDrawMergeTextureMaskUniforms {
|
||||
.texture_slot = 0,
|
||||
.pattern_offset = m_outline_pan,
|
||||
},
|
||||
proj,
|
||||
camera,
|
||||
m_canvas->m_layers.size() + 500.f,
|
||||
std::to_array(m_canvas->m_plane_transform),
|
||||
{
|
||||
.set_active_texture_unit = [&] {
|
||||
set_active_texture_unit(0);
|
||||
},
|
||||
.enable_blend = [&] {
|
||||
apply_node_canvas_capability(pp::renderer::gl::blend_state(), true);
|
||||
},
|
||||
.bind_face_texture = [&](int plane_index) {
|
||||
m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
},
|
||||
.draw_face = [&] {
|
||||
m_face_plane.draw_fill();
|
||||
},
|
||||
.unbind_face_texture = [&](int plane_index) {
|
||||
m_canvas->m_smask.rtt(plane_index).unbindTexture();
|
||||
},
|
||||
});
|
||||
},
|
||||
pp::panopainter::make_legacy_canvas_draw_merge_grid_modes_draw(
|
||||
&Canvas::modes[(int)kCanvasMode::Grid],
|
||||
ortho_proj,
|
||||
proj,
|
||||
camera),
|
||||
pp::panopainter::make_legacy_canvas_draw_merge_heightmap_draw(App::I->grid.get(), proj, camera),
|
||||
pp::panopainter::make_legacy_canvas_draw_merge_current_modes_draw(
|
||||
m_canvas->m_mode,
|
||||
ortho_proj,
|
||||
proj,
|
||||
camera));
|
||||
|
||||
if (m_density != 1.f)
|
||||
{
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_display_resolve(
|
||||
pp::panopainter::LegacyCanvasDrawMergeDisplayResolveUniforms {
|
||||
.texture = {
|
||||
.mvp = glm::ortho<float>(-1, 1, -1, 1),
|
||||
.texture_slot = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.unbind_resolve_framebuffer = [&] {
|
||||
m_rtt.unbindFramebuffer();
|
||||
},
|
||||
.clear_color_buffer = [&] {
|
||||
clear_node_canvas_color_buffer({ 1.f, 1.f, 1.f, 0.f });
|
||||
},
|
||||
.apply_viewport = [&] {
|
||||
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
|
||||
},
|
||||
.bind_sampler = [&] {
|
||||
m_sampler_nearest.bind(0);
|
||||
},
|
||||
.bind_resolve_texture = [&] {
|
||||
set_active_texture_unit(0);
|
||||
m_rtt.bindTexture();
|
||||
},
|
||||
.draw = [&] {
|
||||
m_face_plane.draw_fill();
|
||||
},
|
||||
.unbind_resolve_texture = [&] {
|
||||
m_rtt.unbindTexture();
|
||||
},
|
||||
});
|
||||
}
|
||||
execute_node_canvas_draw_merge_tail(*this, ortho_proj, proj, camera, c);
|
||||
|
||||
scissor ? apply_node_canvas_capability(pp::renderer::gl::scissor_test_state(), true) : apply_node_canvas_capability(pp::renderer::gl::scissor_test_state(), false);
|
||||
blend ? apply_node_canvas_capability(pp::renderer::gl::blend_state(), true) : apply_node_canvas_capability(pp::renderer::gl::blend_state(), false);
|
||||
|
||||
106
src/platform_windows/windows_bootstrap_helpers.cpp
Normal file
106
src/platform_windows/windows_bootstrap_helpers.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "log.h"
|
||||
#include "renderer_gl/opengl_capabilities.h"
|
||||
|
||||
#include <shellscalingapi.h>
|
||||
#include <string>
|
||||
|
||||
#if __has_include(<renderdoc_app.h>)
|
||||
#include <renderdoc_app.h>
|
||||
#define USE_RENDERDOC
|
||||
#endif
|
||||
|
||||
#ifdef USE_RENDERDOC
|
||||
RENDERDOC_API_1_4_0* rdoc_api = NULL;
|
||||
|
||||
bool win32_renderdoc_init()
|
||||
{
|
||||
// At init, on windows
|
||||
if (HMODULE mod = GetModuleHandleA("renderdoc.dll"))
|
||||
{
|
||||
pRENDERDOC_GetAPI RENDERDOC_GetAPI =
|
||||
(pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
|
||||
return RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&rdoc_api);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void win32_renderdoc_frame_start()
|
||||
{
|
||||
if (rdoc_api)
|
||||
rdoc_api->StartFrameCapture(NULL, NULL);
|
||||
}
|
||||
|
||||
void win32_renderdoc_frame_end()
|
||||
{
|
||||
if (rdoc_api)
|
||||
rdoc_api->EndFrameCapture(NULL, NULL);
|
||||
}
|
||||
#else
|
||||
void win32_renderdoc_frame_start() { }
|
||||
void win32_renderdoc_frame_end() { }
|
||||
#endif
|
||||
|
||||
HRESULT(*GetDpiForMonitor_fn)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT* dpiX, UINT* dpiY);
|
||||
HRESULT(*SetProcessDpiAwareness_fn)(PROCESS_DPI_AWARENESS value);
|
||||
|
||||
void init_shcore_API()
|
||||
{
|
||||
HMODULE dll = LoadLibrary(L"Shcore.dll");
|
||||
if (!dll)
|
||||
{
|
||||
LOG("cannot load Shcore.dll");
|
||||
return;
|
||||
}
|
||||
LOG("loaded Shcore.dll");
|
||||
GetDpiForMonitor_fn = (decltype(GetDpiForMonitor_fn))GetProcAddress(dll, "GetDpiForMonitor");
|
||||
SetProcessDpiAwareness_fn = (decltype(SetProcessDpiAwareness_fn))GetProcAddress(dll, "SetProcessDpiAwareness");
|
||||
}
|
||||
|
||||
// Returns the last Win32 error, in string format. Returns an empty string if there is no error.
|
||||
std::string GetLastErrorAsString()
|
||||
{
|
||||
DWORD errorMessageID = ::GetLastError();
|
||||
if (errorMessageID == 0)
|
||||
return std::string();
|
||||
|
||||
LPSTR messageBuffer = nullptr;
|
||||
size_t size = FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||
|
||||
std::string message(messageBuffer, size);
|
||||
LocalFree(messageBuffer);
|
||||
return message;
|
||||
}
|
||||
|
||||
BOOL UnadjustWindowRectEx(LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle)
|
||||
{
|
||||
RECT rc;
|
||||
SetRectEmpty(&rc);
|
||||
BOOL fRc = AdjustWindowRectEx(&rc, dwStyle, fMenu, dwExStyle);
|
||||
if (fRc) {
|
||||
prc->left -= rc.left;
|
||||
prc->top -= rc.top;
|
||||
prc->right -= rc.right;
|
||||
prc->bottom -= rc.bottom;
|
||||
}
|
||||
return fRc;
|
||||
}
|
||||
|
||||
void _pre_call_callback(const char* name, void* funcptr, int len_args, ...)
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
}
|
||||
|
||||
void _post_call_callback(const char* name, void* funcptr, int len_args, ...)
|
||||
{
|
||||
GLenum error_code;
|
||||
error_code = glad_glGetError();
|
||||
|
||||
if (error_code != pp::renderer::gl::no_error_code())
|
||||
{
|
||||
LOG("ERROR %d in %s\n", error_code, name);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user