Files
panopainter/src/app_dialogs_export.cpp

317 lines
10 KiB
C++

#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