284 lines
9.5 KiB
C++
284 lines
9.5 KiB
C++
#pragma once
|
|
|
|
#include "foundation/result.h"
|
|
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <utility>
|
|
|
|
namespace pp::app {
|
|
|
|
struct DocumentExportFileTarget {
|
|
std::string path;
|
|
std::string suggested_name;
|
|
};
|
|
|
|
struct DocumentExportCollectionTarget {
|
|
std::string directory;
|
|
std::string stem_path;
|
|
};
|
|
|
|
struct DocumentExportStemTarget {
|
|
std::string stem_path;
|
|
};
|
|
|
|
struct DocumentExportSuggestedName {
|
|
std::string name;
|
|
};
|
|
|
|
enum class DocumentExportStartDecision {
|
|
start_now,
|
|
show_license_disabled,
|
|
unavailable_no_canvas,
|
|
};
|
|
|
|
enum class DocumentExportMenuKind {
|
|
jpeg,
|
|
png,
|
|
layers,
|
|
cube_faces,
|
|
depth,
|
|
animation_frames,
|
|
animation_mp4,
|
|
timelapse,
|
|
};
|
|
|
|
enum class DocumentExportMenuAction {
|
|
show_jpeg_dialog,
|
|
show_png_dialog,
|
|
show_layers_dialog,
|
|
show_cube_faces_dialog,
|
|
show_depth_dialog,
|
|
show_animation_frames_dialog,
|
|
show_animation_mp4_dialog,
|
|
show_timelapse_dialog,
|
|
show_license_disabled,
|
|
unavailable_no_canvas,
|
|
};
|
|
|
|
struct DocumentExportMenuPlan {
|
|
DocumentExportMenuKind kind = DocumentExportMenuKind::jpeg;
|
|
DocumentExportMenuAction action = DocumentExportMenuAction::show_jpeg_dialog;
|
|
bool opens_dialog = true;
|
|
};
|
|
|
|
class DocumentExportMenuServices {
|
|
public:
|
|
virtual ~DocumentExportMenuServices() = default;
|
|
|
|
virtual void show_jpeg_dialog() = 0;
|
|
virtual void show_png_dialog() = 0;
|
|
virtual void show_layers_dialog() = 0;
|
|
virtual void show_cube_faces_dialog() = 0;
|
|
virtual void show_depth_dialog() = 0;
|
|
virtual void show_animation_frames_dialog() = 0;
|
|
virtual void show_animation_mp4_dialog() = 0;
|
|
virtual void show_timelapse_dialog() = 0;
|
|
virtual void show_license_disabled() = 0;
|
|
};
|
|
|
|
[[nodiscard]] constexpr DocumentExportStartDecision plan_document_export_start(
|
|
bool requires_license,
|
|
bool license_valid,
|
|
bool has_canvas) noexcept
|
|
{
|
|
if (requires_license && !license_valid) {
|
|
return DocumentExportStartDecision::show_license_disabled;
|
|
}
|
|
|
|
return has_canvas
|
|
? DocumentExportStartDecision::start_now
|
|
: DocumentExportStartDecision::unavailable_no_canvas;
|
|
}
|
|
|
|
[[nodiscard]] constexpr bool document_export_menu_requires_license(
|
|
DocumentExportMenuKind kind) noexcept
|
|
{
|
|
switch (kind) {
|
|
case DocumentExportMenuKind::animation_mp4:
|
|
case DocumentExportMenuKind::timelapse:
|
|
return true;
|
|
case DocumentExportMenuKind::jpeg:
|
|
case DocumentExportMenuKind::png:
|
|
case DocumentExportMenuKind::layers:
|
|
case DocumentExportMenuKind::cube_faces:
|
|
case DocumentExportMenuKind::depth:
|
|
case DocumentExportMenuKind::animation_frames:
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
[[nodiscard]] constexpr DocumentExportMenuAction document_export_menu_dialog_action(
|
|
DocumentExportMenuKind kind) noexcept
|
|
{
|
|
switch (kind) {
|
|
case DocumentExportMenuKind::jpeg:
|
|
return DocumentExportMenuAction::show_jpeg_dialog;
|
|
case DocumentExportMenuKind::png:
|
|
return DocumentExportMenuAction::show_png_dialog;
|
|
case DocumentExportMenuKind::layers:
|
|
return DocumentExportMenuAction::show_layers_dialog;
|
|
case DocumentExportMenuKind::cube_faces:
|
|
return DocumentExportMenuAction::show_cube_faces_dialog;
|
|
case DocumentExportMenuKind::depth:
|
|
return DocumentExportMenuAction::show_depth_dialog;
|
|
case DocumentExportMenuKind::animation_frames:
|
|
return DocumentExportMenuAction::show_animation_frames_dialog;
|
|
case DocumentExportMenuKind::animation_mp4:
|
|
return DocumentExportMenuAction::show_animation_mp4_dialog;
|
|
case DocumentExportMenuKind::timelapse:
|
|
return DocumentExportMenuAction::show_timelapse_dialog;
|
|
}
|
|
|
|
return DocumentExportMenuAction::show_jpeg_dialog;
|
|
}
|
|
|
|
[[nodiscard]] constexpr DocumentExportMenuPlan plan_document_export_menu_action(
|
|
DocumentExportMenuKind kind,
|
|
bool has_canvas,
|
|
bool license_valid) noexcept
|
|
{
|
|
DocumentExportMenuPlan plan;
|
|
plan.kind = kind;
|
|
plan.action = document_export_menu_dialog_action(kind);
|
|
|
|
const auto start = plan_document_export_start(
|
|
document_export_menu_requires_license(kind),
|
|
license_valid,
|
|
has_canvas);
|
|
if (start == DocumentExportStartDecision::show_license_disabled) {
|
|
plan.action = DocumentExportMenuAction::show_license_disabled;
|
|
plan.opens_dialog = false;
|
|
} else if (start == DocumentExportStartDecision::unavailable_no_canvas) {
|
|
plan.action = DocumentExportMenuAction::unavailable_no_canvas;
|
|
plan.opens_dialog = false;
|
|
}
|
|
|
|
return plan;
|
|
}
|
|
|
|
[[nodiscard]] inline pp::foundation::Result<DocumentExportFileTarget> make_document_export_file_target(
|
|
std::string_view work_directory,
|
|
std::string_view document_name,
|
|
std::string_view extension)
|
|
{
|
|
if (document_name.empty()) {
|
|
return pp::foundation::Result<DocumentExportFileTarget>::failure(
|
|
pp::foundation::Status::invalid_argument("document name must not be empty"));
|
|
}
|
|
|
|
if (extension.empty()) {
|
|
return pp::foundation::Result<DocumentExportFileTarget>::failure(
|
|
pp::foundation::Status::invalid_argument("extension must not be empty"));
|
|
}
|
|
|
|
DocumentExportFileTarget target;
|
|
target.suggested_name.reserve(document_name.size() + extension.size());
|
|
target.suggested_name += document_name;
|
|
target.suggested_name += extension;
|
|
target.path.reserve(work_directory.size() + target.suggested_name.size() + 1);
|
|
target.path += work_directory;
|
|
target.path += "/";
|
|
target.path += target.suggested_name;
|
|
return pp::foundation::Result<DocumentExportFileTarget>::success(std::move(target));
|
|
}
|
|
|
|
[[nodiscard]] inline pp::foundation::Result<DocumentExportCollectionTarget> make_document_export_collection_target(
|
|
std::string_view work_directory,
|
|
std::string_view document_name,
|
|
std::string_view suffix)
|
|
{
|
|
if (document_name.empty()) {
|
|
return pp::foundation::Result<DocumentExportCollectionTarget>::failure(
|
|
pp::foundation::Status::invalid_argument("document name must not be empty"));
|
|
}
|
|
|
|
DocumentExportCollectionTarget target;
|
|
target.directory.reserve(work_directory.size() + document_name.size() + suffix.size() + 1);
|
|
target.directory += work_directory;
|
|
target.directory += "/";
|
|
target.directory += document_name;
|
|
target.directory += suffix;
|
|
target.stem_path.reserve(target.directory.size() + document_name.size() + 1);
|
|
target.stem_path += target.directory;
|
|
target.stem_path += "/";
|
|
target.stem_path += document_name;
|
|
return pp::foundation::Result<DocumentExportCollectionTarget>::success(std::move(target));
|
|
}
|
|
|
|
[[nodiscard]] inline pp::foundation::Result<DocumentExportStemTarget> make_document_export_stem_target(
|
|
std::string_view directory,
|
|
std::string_view document_name)
|
|
{
|
|
if (document_name.empty()) {
|
|
return pp::foundation::Result<DocumentExportStemTarget>::failure(
|
|
pp::foundation::Status::invalid_argument("document name must not be empty"));
|
|
}
|
|
|
|
DocumentExportStemTarget target;
|
|
target.stem_path.reserve(directory.size() + document_name.size() + 1);
|
|
target.stem_path += directory;
|
|
target.stem_path += "/";
|
|
target.stem_path += document_name;
|
|
return pp::foundation::Result<DocumentExportStemTarget>::success(std::move(target));
|
|
}
|
|
|
|
[[nodiscard]] inline pp::foundation::Result<DocumentExportSuggestedName> make_document_export_suggested_name(
|
|
std::string_view document_name,
|
|
std::string_view suffix)
|
|
{
|
|
if (document_name.empty()) {
|
|
return pp::foundation::Result<DocumentExportSuggestedName>::failure(
|
|
pp::foundation::Status::invalid_argument("document name must not be empty"));
|
|
}
|
|
|
|
DocumentExportSuggestedName target;
|
|
target.name.reserve(document_name.size() + suffix.size());
|
|
target.name += document_name;
|
|
target.name += suffix;
|
|
return pp::foundation::Result<DocumentExportSuggestedName>::success(std::move(target));
|
|
}
|
|
|
|
[[nodiscard]] inline pp::foundation::Status execute_document_export_menu_plan(
|
|
const DocumentExportMenuPlan& plan,
|
|
DocumentExportMenuServices& services)
|
|
{
|
|
switch (plan.action) {
|
|
case DocumentExportMenuAction::show_jpeg_dialog:
|
|
services.show_jpeg_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_png_dialog:
|
|
services.show_png_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_layers_dialog:
|
|
services.show_layers_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_cube_faces_dialog:
|
|
services.show_cube_faces_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_depth_dialog:
|
|
services.show_depth_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_animation_frames_dialog:
|
|
services.show_animation_frames_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_animation_mp4_dialog:
|
|
services.show_animation_mp4_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_timelapse_dialog:
|
|
services.show_timelapse_dialog();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::show_license_disabled:
|
|
services.show_license_disabled();
|
|
return pp::foundation::Status::success();
|
|
case DocumentExportMenuAction::unavailable_no_canvas:
|
|
return pp::foundation::Status::success();
|
|
}
|
|
|
|
return pp::foundation::Status::invalid_argument("unknown document export menu action");
|
|
}
|
|
|
|
}
|