Files
panopainter/src/app_dialogs.cpp

627 lines
18 KiB
C++

#include "pch.h"
#include "app.h"
#include "action.h"
#include "node_dialog_open.h"
#include "node_dialog_browse.h"
#include "node_dialog_resize.h"
#include "node_dialog_cloud.h"
#include "node_about.h"
#include "node_changelog.h"
#include "node_usermanual.h"
#ifdef __QUEST__
#include "oculus_vr.h"
#endif
#include "node_dialog_export_ppbr.h"
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title, int total /*= 0*/)
{
auto pb = std::make_shared<NodeProgressBar>();
pb->m_manager = &layout;
pb->init();
pb->create();
pb->loaded();
pb->m_progress->SetWidthP(0);
pb->m_title->set_text(title.c_str());
pb->m_total = total;
pb->m_count = 0;
layout[main_id]->add_child(pb);
return pb;
}
std::shared_ptr<NodeMessageBox> App::message_box(const std::string &title, const std::string& text, bool cancel_button)
{
auto m = std::make_shared<NodeMessageBox>();
m->m_manager = &layout;
m->init();
m->create();
m->loaded();
m->m_title->set_text(title.c_str());
m->m_message->set_text(text.c_str());
m->btn_ok->m_text->set_text("Ok");
if (!cancel_button)
m->btn_cancel->destroy();
layout[main_id]->add_child(m);
return m;
}
std::shared_ptr<NodeInputBox> App::input_box(const std::string& title,
const std::string& field_name, const std::string& ok_caption /*= "Ok"*/)
{
auto m = std::make_shared<NodeInputBox>();
m->m_manager = &layout;
m->init();
m->create();
m->loaded();
m->m_title->set_text(title.c_str());
m->m_field_name->set_text(field_name.c_str());
m->btn_ok->m_text->set_text(ok_caption.c_str());
layout[main_id]->add_child(m);
return m;
}
void App::dialog_usermanual()
{
auto dialog = std::make_shared<NodeUserManual>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
}
void App::dialog_changelog()
{
auto dialog = std::make_shared<NodeChangelog>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
}
void App::dialog_about()
{
auto dialog = std::make_shared<NodeAbout>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
}
void App::dialog_newdoc()
{
auto show_dialog = [this] {
auto dialog = std::make_shared<NodeDialogNewDoc>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
dialog->input->set_text("name");
layout[main_id]->add_child(dialog);
layout[main_id]->update();
App::I->showKeyboard();
dialog->btn_ok->on_click = [this, dialog](Node*)
{
std::string name = dialog->input->m_text;
std::string path = work_path + "/" + name + ".ppi";
if (name.empty())
{
message_box("Warning", "You need to specify a name to file.");
return;
}
auto action = [this, dialog, name, path] {
std::array<int, 6> resolutions{ 512, 1024, 1536, 2048, 4096, 8192 };
int res = resolutions[dialog->m_resolution->m_current_index];
doc_name = name;
doc_path = path;
doc_filename = name + ".ppi";
doc_dir = work_path;
layers->clear();
canvas->m_canvas->m_layers.clear();
canvas->m_canvas->resize(res, res);
canvas->reset_camera();
ActionManager::clear();
layers->add_layer("Default", false, true);
canvas->m_canvas->m_unsaved = true;
canvas->m_canvas->m_newdoc = false;
title_update();
dialog->destroy();
App::I->hideKeyboard();
};
if (Asset::exist(path))
{
// ask confirm is file already exist
auto msgbox = new NodeMessageBox();
msgbox->m_manager = &layout;
msgbox->init();
msgbox->m_title->set_text("Warning");
msgbox->m_message->set_text("A document with this name already exists, continue?");
msgbox->btn_ok->on_click = [this, msgbox, action](Node*) {
action();
msgbox->destroy();
};
layout[main_id]->add_child(msgbox);
}
else
{
action();
}
};
dialog->btn_cancel->on_click = [this, dialog](Node*)
{
dialog->destroy();
App::I->hideKeyboard();
};
};
if (canvas)
{
if (Canvas::I->m_unsaved)
{
auto m = layout[main_id]->add_child<NodeMessageBox>();
m->m_title->set_text("Unsaved document");
m->m_message->set_text("Would you like to save this document before closing?");
m->btn_ok->m_text->set_text("Yes");
m->btn_cancel->m_text->set_text("No");
m->btn_ok->on_click = [this, m, show_dialog](Node*) {
Canvas::I->project_save([this, m, show_dialog](bool success){
if (success)
show_dialog();
else
message_box("Saving Error", "There was a problem saving the document");
});
m->destroy();
};
m->btn_cancel->on_click = [this, m, show_dialog](Node*) {
show_dialog();
m->destroy();
};
}
else
{
show_dialog();
}
}
}
// DEPRECATED
void App::dialog_open()
{
auto show_dialog = [this] {
// load thumbnail test
auto dialog = std::make_shared<NodeDialogOpen>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
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();
};
};
if (canvas)
{
if (Canvas::I->m_unsaved)
{
auto m = layout[main_id]->add_child<NodeMessageBox>();
m->m_title->set_text("Unsaved document");
m->m_message->set_text("Would you like to save this document before closing?");
m->btn_ok->m_text->set_text("Yes");
m->btn_cancel->m_text->set_text("No");
m->btn_ok->on_click = [this,m,show_dialog](Node*){
Canvas::I->project_save([this,m,show_dialog](bool success){
if (success)
show_dialog();
else
message_box("Saving Error", "There was a problem saving the document");
});
m->destroy();
};
m->btn_cancel->on_click = [this,m,show_dialog](Node*) {
show_dialog();
m->destroy();
};
}
else
{
show_dialog();
}
}
}
void App::dialog_browse()
{
auto show_dialog = [this] {
// load thumbnail test
auto dialog = std::make_shared<NodeDialogBrowse>();
dialog->m_manager = &layout;
#ifdef __IOS__
dialog->search_paths = {work_path, data_path + "/Inbox"};
#else
dialog->search_paths = {work_path};
#endif
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
dialog->btn_ok->on_click = [this, dialog](Node*)
{
if (dialog->is_selected())
{
open_document(dialog->selected_path);
dialog->destroy();
}
};
};
if (canvas)
{
if (Canvas::I->m_unsaved)
{
auto m = layout[main_id]->add_child<NodeMessageBox>();
m->m_title->set_text("Unsaved document");
m->m_message->set_text("Would you like to save this document before closing?");
m->btn_ok->m_text->set_text("Yes");
m->btn_cancel->m_text->set_text("No");
m->btn_ok->on_click = [this, m, show_dialog](Node*) {
Canvas::I->project_save([this, m, show_dialog](bool success){
if (success)
show_dialog();
else
message_box("Saving Error", "There was a problem saving the document");
});
m->destroy();
};
m->btn_cancel->on_click = [this, m, show_dialog](Node*) {
show_dialog();
m->destroy();
};
}
else
{
show_dialog();
}
}
}
void App::dialog_save_ver()
{
if (!check_license())
{
message_box("License", "This function is disabled in demo mode.");
return;
}
int current = 0;
std::string next = doc_name + ".01";
std::string base = doc_name;
std::regex r(R"((.*)\.(\w{2})$)");
std::smatch m;
if (std::regex_search(doc_name, m, r))
{
base = m[1].str();
current = atoi(m[2].str().c_str());
}
for (int i = current + 1; i < 99; i++)
{
static char tmp_name[256];
sprintf(tmp_name, "%s.%02d", base.c_str(), i);
next = tmp_name;
if (Asset::exist(doc_dir + "/" + next + ".ppi"))
continue;
break;
}
doc_name = next;
doc_path = doc_dir + "/" + next + ".ppi";
canvas->m_canvas->m_unsaved = true;
title_update();
canvas->m_canvas->project_save(doc_path);
}
void App::dialog_save()
{
if (!check_license())
{
message_box("License", "This function is disabled in demo mode.");
return;
}
if (canvas)
{
auto dialog = std::make_shared<NodeDialogSave>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
dialog->input->set_text(doc_name);
App::I->showKeyboard();
dialog->btn_ok->on_click = [this, dialog](Node*)
{
std::string name = dialog->input->m_text;
std::string path = work_path + "/" + name + ".ppi";
if (name.empty())
{
message_box("Warning", "You need to specify a name to file.");
return;
}
auto action = [this, dialog, name, path] {
canvas->m_canvas->project_save(path);
doc_name = name;
doc_path = path;
doc_dir = work_path;
title_update();
dialog->destroy();
App::I->hideKeyboard();
};
if (Asset::exist(path))
{
// ask confirm is file already exist
auto msgbox = new NodeMessageBox();
msgbox->m_manager = &layout;
msgbox->init();
msgbox->m_title->set_text("Warning");
msgbox->m_message->set_text(("Are you sure you want to overwrite " + name + "?").c_str());
msgbox->btn_ok->on_click = [this, msgbox, action](Node*) {
action();
msgbox->destroy();
};
layout[main_id]->add_child(msgbox);
}
else
{
action();
}
};
dialog->btn_cancel->on_click = [this, dialog](Node*)
{
dialog->destroy();
App::I->hideKeyboard();
};
layout[main_id]->add_child(dialog);
layout[main_id]->update();
}
}
void App::dialog_export(std::string ext)
{
if (!check_license())
{
message_box("License", "This function is disabled in demo mode.");
return;
}
if (canvas)
{
// TODO: use picker
auto path = work_path + "/" + doc_name + ext;
canvas->m_canvas->export_equirectangular(path, [this, path]{
#if defined(__IOS__)
message_box("Export Equirectangular", "Image exported to Photos");
#elif defined(__OSX__)
message_box("Export Equirectangular", "Image exported to Pictures/PanoPainter folder");
#elif defined(_WIN32)
message_box("Export Equirectangular", "Image exported to " + work_path);
#elif defined(__QUEST__)
//auto result = ovr_Media_ShareToFacebook("Sharing from PanoPainter on Oculus Quest", path.c_str(), ovrMediaContentType_Photo);
#endif
});
}
}
void App::dialog_export_layers()
{
if (!check_license())
{
message_box("License", "This function is disabled in demo mode.");
return;
}
if (canvas)
{
// TODO: use picker
canvas->m_canvas->export_layers(doc_name, [this] {
#if defined(__IOS__)
message_box("Export Layers", "Image layers exported to Files/PanoPainter");
#elif defined(__OSX__)
message_box("Export Layers", "Image layers exported to Pictures/PanoPainter folder");
#elif defined(_WIN32)
message_box("Export Layers", "Image layers exported to " + work_path);
#endif
});
}
}
void App::dialog_export_depth()
{
if (!check_license())
{
message_box("License", "This function is disabled in demo mode.");
return;
}
if (canvas)
{
// TODO: use picker
canvas->m_canvas->export_depth(doc_name, [this] {
#if defined(__IOS__)
message_box("Export 3D View + Depth", "Image and depth exported to Files/PanoPainter");
#elif defined(__OSX__)
message_box("Export 3D View + Depth", "Image and depth exported to Pictures/PanoPainter folder");
#elif defined(_WIN32)
message_box("Export 3D View + Depth", "Image and depth exported to " + work_path);
#endif
});
}
}
void App::dialog_resize()
{
auto dialog = std::make_shared<NodeDialogResize>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
dialog->btn_ok->on_click = [this,dialog](Node*)
{
int res = dialog->get_resolution();
if (canvas)
canvas->m_canvas->resize(res, res);
App::I->title_update();
ActionManager::clear();
dialog->destroy();
};
}
void App::dialog_export_cube_faces()
{
if (canvas)
{
canvas->m_canvas->export_cube_faces(doc_name, [this] {
#if defined(__IOS__)
message_box("Export Cube Faces", "Image and depth exported to Files/PanoPainter");
#elif defined(__OSX__)
message_box("Export Cube Faces", "Image and depth exported to Pictures/PanoPainter folder");
#elif defined(_WIN32)
message_box("Export Cube Faces", "Image and depth exported to " + work_path);
#endif
});
}
}
void App::dialog_layer_rename()
{
auto dialog = std::make_shared<NodeDialogLayerRename>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
dialog->input->set_text(layers->m_current_layer->m_label_text);
App::I->showKeyboard();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
dialog->btn_ok->on_click = [this,dialog](Node*)
{
struct ActionLayerRename : public Action
{
std::string m_old_name;
std::string m_new_name;
bool m_unsaved;
Layer* m_layer;
std::shared_ptr<NodeLayer> m_layer_node;
ActionLayerRename(std::string old_name, std::string new_name, std::shared_ptr<NodeLayer> layer_node, Layer* layer) :
m_old_name(old_name), m_new_name(new_name), m_layer_node(layer_node), m_layer(layer) { }
virtual void run() override { }
virtual size_t memory() override { return 0; }
virtual void undo() override
{
m_layer_node->set_name(m_old_name.c_str());
m_layer->m_name = m_old_name;
}
virtual Action* get_redo() override
{
return new ActionLayerRename(m_new_name, m_old_name, m_layer_node, m_layer);
}
};
auto layer_node = std::static_pointer_cast<NodeLayer>(layers->m_current_layer->shared_from_this());
auto* layer = canvas->m_canvas->m_layers[canvas->m_canvas->m_current_layer_idx].get();
ActionManager::add(new ActionLayerRename(layers->m_current_layer->m_label_text, dialog->get_name(), layer_node, layer));
layer_node->set_name(dialog->get_name().c_str());
layer->m_name = dialog->get_name();
dialog->destroy();
App::I->hideKeyboard();
};
dialog->btn_cancel->on_click = [this, dialog](Node*)
{
dialog->destroy();
App::I->hideKeyboard();
};
}
void App::dialog_preset_download()
{
}
void App::dialog_ppbr_export()
{
auto root = layout[main_id];
auto dialog = root->add_child_ref<NodeDialogExportPPBR>();
dialog->btn_ok->on_click = [this, dialog] (Node*) {
NodePanelBrushPreset::PPBRInfo info;
info.author = dialog->txt_author->m_text;
info.url = dialog->txt_url->m_text;
info.email = dialog->txt_email->m_text;
info.descr = dialog->txt_descr->m_text;
info.header_image = dialog->m_header_image;
#if __IOS__
App::I->pick_file_save("ppbr", [this, dialog, info] (std::string path) {
presets->export_ppbr(path, info);
});
#else
App::I->pick_file_save({ "ppbr" }, [this, dialog, info] (std::string path) {
std::thread([this, path, dialog, info] {
BT_SetTerminate();
presets->export_ppbr(path, info);
dialog->destroy();
App::I->message_box("Export PPBR", "Brushes exported to:\n" + path);
}).detach();
});
#endif
};
}