Extract app frame and export dialog helpers
This commit is contained in:
316
src/app_dialogs_export.cpp
Normal file
316
src/app_dialogs_export.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "app_core/app_dialog.h"
|
||||
#include "app_core/document_export.h"
|
||||
#include "legacy_brush_package_export_services.h"
|
||||
#include "legacy_document_export_services.h"
|
||||
#include "legacy_ui_overlay_services.h"
|
||||
#include "node_dialog_export_ppbr.h"
|
||||
|
||||
#include <codec_api.h>
|
||||
#define MP4V2_NO_STDINT_DEFS
|
||||
#include <mp4v2/mp4v2.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] bool can_start_document_export(App& app, bool requires_license)
|
||||
{
|
||||
const auto decision = pp::app::plan_document_export_start(
|
||||
requires_license,
|
||||
!requires_license || app.check_license(),
|
||||
app.canvas != nullptr);
|
||||
|
||||
switch (decision) {
|
||||
case pp::app::DocumentExportStartDecision::start_now:
|
||||
return true;
|
||||
case pp::app::DocumentExportStartDecision::show_license_disabled:
|
||||
{
|
||||
const auto plan = pp::app::plan_document_export_license_disabled_dialog();
|
||||
app.message_box(plan.title, plan.message, plan.show_cancel);
|
||||
return false;
|
||||
}
|
||||
case pp::app::DocumentExportStartDecision::unavailable_no_canvas:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void start_document_export_collection(
|
||||
App& app,
|
||||
pp::app::DocumentExportCollectionKind kind)
|
||||
{
|
||||
const auto plan = pp::app::plan_document_export_collection_target(
|
||||
kind,
|
||||
app.uses_work_directory_document_export_collections());
|
||||
const auto success_kind = pp::app::document_export_collection_success_kind(kind);
|
||||
|
||||
if (plan.destination == pp::app::DocumentExportCollectionDestination::work_directory_collection) {
|
||||
const auto target = pp::app::make_document_export_collection_target(
|
||||
app.work_path,
|
||||
app.doc_name,
|
||||
plan.suffix);
|
||||
if (!target) {
|
||||
const auto dialog = pp::app::plan_document_export_failure_dialog(success_kind, target.status().message);
|
||||
app.message_box(dialog.title, dialog.message, dialog.show_cancel);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_document_export_collection(
|
||||
app,
|
||||
plan.kind,
|
||||
target.value());
|
||||
if (!status.ok())
|
||||
LOG(
|
||||
"%s: %s",
|
||||
pp::app::document_export_execution_log_message(
|
||||
kind == pp::app::DocumentExportCollectionKind::layers
|
||||
? pp::app::DocumentExportExecutionKind::layers_collection
|
||||
: pp::app::DocumentExportExecutionKind::animation_frames_collection),
|
||||
status.message);
|
||||
return;
|
||||
}
|
||||
|
||||
app.pick_dir([
|
||||
&app,
|
||||
kind = plan.kind,
|
||||
success_kind
|
||||
](std::string path) {
|
||||
const auto target = pp::app::make_document_export_stem_target(path, app.doc_name);
|
||||
if (!target) {
|
||||
const auto dialog = pp::app::plan_document_export_failure_dialog(success_kind, target.status().message);
|
||||
app.message_box(dialog.title, dialog.message, dialog.show_cancel);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_document_export_stem(
|
||||
app,
|
||||
kind,
|
||||
target.value());
|
||||
if (!status.ok())
|
||||
LOG(
|
||||
"%s: %s",
|
||||
pp::app::document_export_execution_log_message(
|
||||
kind == pp::app::DocumentExportCollectionKind::layers
|
||||
? pp::app::DocumentExportExecutionKind::layers_stem
|
||||
: pp::app::DocumentExportExecutionKind::animation_frames_stem),
|
||||
status.message);
|
||||
});
|
||||
}
|
||||
|
||||
void start_document_video_export(
|
||||
App& app,
|
||||
pp::app::DocumentVideoExportKind kind,
|
||||
pp::app::DocumentExportSuccessKind success_kind,
|
||||
const char* suffix,
|
||||
pp::app::DocumentExportExecutionKind execution_kind)
|
||||
{
|
||||
if (!can_start_document_export(app, false))
|
||||
return;
|
||||
|
||||
if (app.uses_prepared_file_writes())
|
||||
{
|
||||
const auto target = pp::app::make_document_export_suggested_name(app.doc_name, suffix);
|
||||
if (!target) {
|
||||
const auto dialog = pp::app::plan_document_export_failure_dialog(
|
||||
success_kind,
|
||||
target.status().message);
|
||||
app.message_box(dialog.title, dialog.message, dialog.show_cancel);
|
||||
return;
|
||||
}
|
||||
|
||||
app.pick_file_save("mp4", target.value().name,
|
||||
[&app, kind, execution_kind](std::string path) {
|
||||
const auto status = pp::panopainter::execute_legacy_document_video_export(
|
||||
app,
|
||||
kind,
|
||||
path,
|
||||
false);
|
||||
if (!status.ok())
|
||||
LOG(
|
||||
"%s: %s",
|
||||
pp::app::document_export_execution_log_message(execution_kind),
|
||||
status.message);
|
||||
},
|
||||
[](const std::string& path, bool saved) {
|
||||
(void)path;
|
||||
(void)saved;
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
app.pick_file_save({ "mp4" }, [&app, kind, execution_kind](std::string path) {
|
||||
const auto status = pp::panopainter::execute_legacy_document_video_export(
|
||||
app,
|
||||
kind,
|
||||
path,
|
||||
true);
|
||||
if (!status.ok())
|
||||
LOG(
|
||||
"%s: %s",
|
||||
pp::app::document_export_execution_log_message(execution_kind),
|
||||
status.message);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void open_document_export_dialog(App& app, std::string ext)
|
||||
{
|
||||
if (!can_start_document_export(app, true))
|
||||
return;
|
||||
|
||||
// TODO: use picker
|
||||
const auto target = pp::app::make_document_export_file_target(app.work_path, app.doc_name, ext);
|
||||
if (!target) {
|
||||
const auto dialog = pp::app::plan_document_export_failure_dialog(
|
||||
pp::app::DocumentExportSuccessKind::equirectangular,
|
||||
target.status().message);
|
||||
app.message_box(dialog.title, dialog.message, dialog.show_cancel);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_document_export_file(app, target.value());
|
||||
if (!status.ok())
|
||||
LOG(
|
||||
"%s: %s",
|
||||
pp::app::document_export_execution_log_message(
|
||||
pp::app::DocumentExportExecutionKind::equirectangular_file),
|
||||
status.message);
|
||||
}
|
||||
|
||||
void open_document_export_layers_dialog(App& app)
|
||||
{
|
||||
if (!can_start_document_export(app, true))
|
||||
return;
|
||||
|
||||
start_document_export_collection(
|
||||
app,
|
||||
pp::app::DocumentExportCollectionKind::layers);
|
||||
}
|
||||
|
||||
void open_document_export_anim_frames_dialog(App& app)
|
||||
{
|
||||
if (!can_start_document_export(app, true))
|
||||
return;
|
||||
|
||||
start_document_export_collection(
|
||||
app,
|
||||
pp::app::DocumentExportCollectionKind::animation_frames);
|
||||
}
|
||||
|
||||
void open_document_export_depth_dialog(App& app)
|
||||
{
|
||||
if (!can_start_document_export(app, true))
|
||||
return;
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_document_export_depth(app, app.doc_name);
|
||||
if (!status.ok())
|
||||
LOG(
|
||||
"%s: %s",
|
||||
pp::app::document_export_execution_log_message(pp::app::DocumentExportExecutionKind::depth),
|
||||
status.message);
|
||||
}
|
||||
|
||||
void open_document_export_cube_faces_dialog(App& app)
|
||||
{
|
||||
if (!can_start_document_export(app, false))
|
||||
return;
|
||||
|
||||
const auto status = pp::panopainter::execute_legacy_document_export_cube_faces(app, app.doc_name);
|
||||
if (!status.ok())
|
||||
LOG(
|
||||
"%s: %s",
|
||||
pp::app::document_export_execution_log_message(pp::app::DocumentExportExecutionKind::cube_faces),
|
||||
status.message);
|
||||
}
|
||||
|
||||
void open_document_timelapse_export_dialog(App& app)
|
||||
{
|
||||
start_document_video_export(
|
||||
app,
|
||||
pp::app::DocumentVideoExportKind::timelapse,
|
||||
pp::app::DocumentExportSuccessKind::timelapse,
|
||||
"-timelapse",
|
||||
pp::app::DocumentExportExecutionKind::timelapse);
|
||||
}
|
||||
|
||||
void open_document_export_mp4_dialog(App& app)
|
||||
{
|
||||
start_document_video_export(
|
||||
app,
|
||||
pp::app::DocumentVideoExportKind::animation_mp4,
|
||||
pp::app::DocumentExportSuccessKind::animation_mp4,
|
||||
"-animation",
|
||||
pp::app::DocumentExportExecutionKind::animation_mp4);
|
||||
}
|
||||
|
||||
void open_ppbr_export_dialog(App& app)
|
||||
{
|
||||
auto* overlay_anchor = app.layout[app.main_id];
|
||||
if (!overlay_anchor) {
|
||||
LOG("PPBR export dialog open failed: main layout anchor is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
auto dialog = pp::panopainter::make_legacy_overlay_node<NodeDialogExportPPBR>(app);
|
||||
|
||||
const auto overlay = pp::panopainter::open_legacy_overlay_node_with_handle(*overlay_anchor, dialog);
|
||||
if (!overlay) {
|
||||
LOG("PPBR export 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 = [&app, dialog] (Node*) {
|
||||
const auto request = pp::panopainter::make_legacy_brush_package_export_request(*dialog);
|
||||
|
||||
if (app.uses_prepared_file_writes())
|
||||
{
|
||||
app.pick_file_save("ppbr", "exported-brushes",
|
||||
[&app, dialog, request] (std::string path) {
|
||||
const auto status = pp::panopainter::execute_legacy_brush_package_export(
|
||||
app,
|
||||
*dialog,
|
||||
request,
|
||||
path,
|
||||
pp::panopainter::LegacyBrushPackageExportMode::inline_export_only);
|
||||
if (!status.ok())
|
||||
LOG("PPBR export failed: %s", status.message);
|
||||
},
|
||||
[dialog] (const std::string& path, bool saved) {
|
||||
(void)path;
|
||||
pp::panopainter::complete_legacy_brush_package_export(*dialog, saved);
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
app.pick_file_save({ "ppbr" }, [&app, dialog, request] (std::string path) {
|
||||
const auto status = pp::panopainter::execute_legacy_brush_package_export(
|
||||
app,
|
||||
*dialog,
|
||||
request,
|
||||
path,
|
||||
pp::panopainter::LegacyBrushPackageExportMode::desktop_async_close_and_message);
|
||||
if (!status.ok())
|
||||
LOG("PPBR export failed: %s", status.message);
|
||||
});
|
||||
};
|
||||
dialog->btn_cancel->on_click = [close_dialog](Node*)
|
||||
{
|
||||
close_dialog();
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace pp::panopainter
|
||||
Reference in New Issue
Block a user