diff --git a/src/app.cpp b/src/app.cpp index b204524..360cd55 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -33,8 +33,10 @@ void App::create() void App::open_document(std::string path) { - auto start = path.rfind("/") + 1; + auto start = path.rfind('/') + 1; doc_name = path.substr(start, path.length() - start - strlen(".ppi")); + doc_dir = path.substr(0, start - 1); + doc_path = path; canvas->reset_camera(); layers->clear(); canvas->m_canvas->project_open(path, [this](bool success){ @@ -168,7 +170,7 @@ void App::initLog() std::string path = std::string(my_documents) + "\\PanoPainter"; if (!PathFileExistsA(path.c_str())) CreateDirectoryA(path.c_str(), NULL); - App::I.data_path = path; + data_path = path; } else { diff --git a/src/app.h b/src/app.h index e5c750a..14b72f8 100644 --- a/src/app.h +++ b/src/app.h @@ -66,6 +66,9 @@ public: NodeScroll* panels; const uint16_t main_id = const_hash("main"); std::string doc_name = "no-name"; + std::string doc_path; + std::string doc_dir; + std::string doc_filename; float width; float height; bool keys[256]; diff --git a/src/app_cloud.cpp b/src/app_cloud.cpp index 9c2933d..7e23d95 100644 --- a/src/app_cloud.cpp +++ b/src/app_cloud.cpp @@ -23,10 +23,9 @@ void App::cloud_upload() else { auto upload_thread = [this] { - std::string path = data_path + "/" + doc_name + ".ppi"; if (ui::Canvas::I->m_unsaved) { - Canvas::I->project_save_thread(path); + Canvas::I->project_save_thread(doc_path); } async_start(); @@ -34,7 +33,7 @@ void App::cloud_upload() async_redraw(); async_end(); - upload(path, doc_name + ".ppi", [this,pb](float p){ + upload(doc_path, doc_filename, [this,pb](float p){ async_start(); pb->m_progress->SetWidthP(p * 100.f); async_redraw(); @@ -90,7 +89,7 @@ void App::cloud_upload_all() } int progress = 0; - int total = names.size(); + int total = (int)names.size(); for (const auto& n : names) { @@ -130,7 +129,6 @@ void App::cloud_browse() // load thumbnail test auto dialog = std::make_shared(); dialog->m_manager = &layout; - dialog->data_path = data_path; dialog->init(); dialog->create(); dialog->loaded(); @@ -148,8 +146,7 @@ void App::cloud_browse() m->m_message->set_text("Download in progress"); async_redraw(); async_end(); - - download(dialog->selected_file, [this,m](float p){ + download(dialog->selected_path, [this,m](float p){ static char progress[256]; sprintf(progress, "Download in progress %.2f%%", p * 100.f); async_start(); diff --git a/src/app_dialogs.cpp b/src/app_dialogs.cpp index 52c03fa..6c671b7 100644 --- a/src/app_dialogs.cpp +++ b/src/app_dialogs.cpp @@ -90,12 +90,15 @@ void App::dialog_newdoc() dialog->btn_ok->on_click = [this, dialog](Node*) { std::string name = dialog->input->m_string; - std::string path = data_path + "/" + name + ".ppi"; + std::string path = work_path + "/" + name + ".ppi"; - auto action = [this, dialog, name] { + auto action = [this, dialog, name, path] { std::array resolutions{ 512, 1024, 1536, 2048 }; 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(); @@ -176,7 +179,6 @@ void App::dialog_open() // load thumbnail test auto dialog = std::make_shared(); dialog->m_manager = &layout; - dialog->data_path = data_path; dialog->init(); dialog->create(); dialog->loaded(); @@ -237,7 +239,7 @@ void App::dialog_browse() // load thumbnail test auto dialog = std::make_shared(); dialog->m_manager = &layout; - dialog->data_path = data_path; + dialog->search_path = work_path; dialog->init(); dialog->create(); dialog->loaded(); @@ -302,14 +304,15 @@ void App::dialog_save_ver() static char tmp_name[256]; sprintf(tmp_name, "%s.%02d", base.c_str(), i); next = tmp_name; - if (Asset::exist(data_path + "/" + next + ".ppi", false)) + if (Asset::exist(doc_dir + "/" + next + ".ppi", false)) continue; break; } doc_name = next; + doc_path = doc_dir + "/" + next + ".ppi"; title_update(); - canvas->m_canvas->project_save(data_path + "/" + next + ".ppi"); + canvas->m_canvas->project_save(doc_path); } void App::dialog_save() @@ -328,7 +331,7 @@ void App::dialog_save() dialog->btn_ok->on_click = [this, dialog](Node*) { std::string name = dialog->input->m_string; - std::string path = data_path + "/" + name + ".ppi"; + std::string path = work_path + "/" + name + ".ppi"; if (name.empty()) { @@ -343,6 +346,8 @@ void App::dialog_save() auto action = [this, dialog, name, path] { doc_name = name; + doc_path = path; + doc_dir = work_path; title_update(); canvas->m_canvas->project_save(path); dialog->destroy(); @@ -383,7 +388,8 @@ void App::dialog_export() { if (canvas) { - canvas->m_canvas->export_equirectangular(data_path + "/" + doc_name + ".jpg", [this]{ + // TODO: use picker + canvas->m_canvas->export_equirectangular(work_path + "/" + doc_name + ".jpg", [this]{ #if defined(__IOS__) message_box("Export JPG", "Image exported to Photos"); #elif defined(__OSX__) @@ -424,7 +430,7 @@ void App::dialog_export_cubes() { if (canvas) { - canvas->m_canvas->export_cubes(data_path + "/" + doc_name); + canvas->m_canvas->export_cubes(); } } @@ -432,7 +438,6 @@ void App::dialog_layer_rename() { auto dialog = std::make_shared(); dialog->m_manager = &layout; - dialog->data_path = data_path; dialog->init(); dialog->create(); dialog->loaded(); diff --git a/src/app_layout.cpp b/src/app_layout.cpp index fdf260f..c1aa2b5 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -21,24 +21,12 @@ void App::title_update() void App::init_toolbar_main() { - - if (auto* button = layout[main_id]->find("btn-export")) - { - button->on_click = [this, button](Node*) { - if (canvas) - { - canvas->m_canvas->export_equirectangular(data_path, [this]{ - message_box("Export", "blabl"); - }); - } - }; - } if (auto* button = layout[main_id]->find("btn-anim")) { button->on_click = [this, button](Node*) { if (canvas) { - canvas->m_canvas->export_anim(data_path); + canvas->m_canvas->export_anim(); } }; } @@ -107,7 +95,6 @@ void App::init_sidebar() sidebar = layout[main_id]->find("sidebar"); panels = layout[main_id]->find("panels"); canvas = layout[main_id]->find("paint-canvas"); - canvas->data_path = data_path; //brushes = layout[main_id]->find("panel-brush"); //layers = layout[main_id]->find("panel-layer"); diff --git a/src/canvas.cpp b/src/canvas.cpp index 2fb4505..b9b2e39 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -953,13 +953,13 @@ bool ui::Canvas::create(int width, int height) return true; } -void ui::Canvas::snapshot_save(std::string data_path) +void ui::Canvas::snapshot_save() { LOG("SAVE SNAPSHOT"); m_layers_snapshot.clear(); m_layers_snapshot.resize(m_layers.size()); for (int i = 0; i < m_layers.size(); i++) - m_layers_snapshot[i] = m_layers[i].snapshot(data_path); + m_layers_snapshot[i] = m_layers[i].snapshot(); } void ui::Canvas::snapshot_restore() @@ -968,7 +968,6 @@ void ui::Canvas::snapshot_restore() for (int i = 0; i < m_layers.size(); i++) m_layers[i].restore(m_layers_snapshot[i]); m_layers_snapshot.clear(); - LOG("RESTORE SNAPSHOT complete"); } void ui::Canvas::clear_context() @@ -1303,7 +1302,7 @@ void ui::Canvas::inject_xmp(std::string jpg_path) } -void ui::Canvas::export_anim(std::string data_path) +void ui::Canvas::export_anim() { if (!App::I.check_license()) return; @@ -1396,7 +1395,7 @@ void ui::Canvas::export_anim(std::string data_path) auto latlong_data = std::make_unique(m_latlong.bytes()); m_latlong.readTextureData(latlong_data.get()); static char name[128]; - sprintf(name, "%s/latlong-frame%02d.png", data_path.c_str(), seq); + sprintf(name, "%s/latlong-frame%02d.png", App::I.work_path.c_str(), seq); seq++; LOG("writing %s", name); int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride()); @@ -1416,7 +1415,7 @@ void ui::Canvas::export_anim(std::string data_path) glActiveTexture(GL_TEXTURE0); } -void ui::Canvas::export_cubes(std::string data_path) +void ui::Canvas::export_cubes() { if (!App::I.check_license()) return; @@ -1465,7 +1464,7 @@ void ui::Canvas::export_cubes(std::string data_path) } static char name[128]; - sprintf(name, "%s-%02d-%d.png", data_path.c_str(), layer, plane); + sprintf(name, "%s-%02d-%d.png", App::I.work_path.c_str(), layer, plane); int ret = stbi_write_png(name, m_width, m_height, 4, buffer.get(), 0); @@ -1490,7 +1489,7 @@ void ui::Canvas::export_cubes(std::string data_path) } #ifdef __OBJC__ static char name[128]; - sprintf(name, "%s.zip", data_path.c_str()); + sprintf(name, "%s.zip", App::I.work_path.c_str()); auto zip_path = [NSString stringWithUTF8String : name]; //[SSZipArchive createZipFileAtPath:zip_path withFilesAtPaths:files]; for (NSString* f : files) @@ -1503,7 +1502,7 @@ void ui::Canvas::project_save(std::function on_complete) if (App::I.check_license()) { std::thread t([=] { - project_save_thread(App::I.data_path + "/" + App::I.doc_name + ".ppi"); + project_save_thread(App::I.doc_path); if (on_complete) on_complete(); }); @@ -1536,7 +1535,10 @@ void ui::Canvas::project_save_thread(std::string file_path) // sprintf(name, "%s/latlong.ppi", data_path.c_str()); FILE* fp; - std::string tmp_path = file_path.substr(0, file_path.size() - strlen(".ppi")) + ".tmp.ppi"; + auto start = file_path.rfind('/') + 1; + std::string file_name = file_path.substr(start, file_path.length() - start - strlen(".ppi")); + std::string tmp_path = App::I.data_path + '/' + file_name + ".tmp.ppi"; + bool use_tmp = false; // check if file already exists if ((fp = fopen(file_path.c_str(), "rb"))) @@ -1546,11 +1548,13 @@ void ui::Canvas::project_save_thread(std::string file_path) use_tmp = true; if (!(fp = fopen(tmp_path.c_str(), "wb"))) { - LOG("cannot write project to %s", file_path.c_str()); - return; + LOG("cannot write tmp project to %s", tmp_path.c_str()); + //return; + use_tmp = false; } } - else + + if (!fp) { // write directly to the new file if (!(fp = fopen(file_path.c_str(), "wb"))) @@ -1558,6 +1562,7 @@ void ui::Canvas::project_save_thread(std::string file_path) LOG("cannot write project to %s", file_path.c_str()); return; } + LOG("unsafe mode saving directly to %s", file_path.c_str()); } PPIHeader ppi_header; @@ -1602,7 +1607,7 @@ void ui::Canvas::project_save_thread(std::string file_path) fwrite(m_layers[i].m_name.data(), name_len, 1, fp); App::I.async_start(); - auto snap = m_layers[i].snapshot(file_path); + auto snap = m_layers[i].snapshot(); App::I.async_update(); App::I.async_end(); for (int plane_index = 0; plane_index < 6; plane_index++) @@ -1901,14 +1906,14 @@ ui::Image ui::Canvas::thumbnail_generate(int w, int h) return image; } -ui::Image ui::Canvas::thumbnail_read(std::string data_path) +ui::Image ui::Canvas::thumbnail_read(std::string file_path) { // static char name[128]; // sprintf(name, "%s/latlong.ppi", data_path.c_str()); - FILE* fp = fopen(data_path.c_str(), "rb"); + FILE* fp = fopen(file_path.c_str(), "rb"); if (!fp) { - LOG("cannot read project %s", data_path.c_str()); + LOG("cannot read project %s", file_path.c_str()); return {}; // return empty image } PPIHeader ppi_header; @@ -1924,7 +1929,7 @@ ui::Image ui::Canvas::thumbnail_read(std::string data_path) thumb.create(); fread((uint8_t*)thumb.data(), thumb.size(), 1, fp); fclose(fp); - LOG("project thumbnail read from %s", data_path.c_str()); + LOG("project thumbnail read from %s", file_path.c_str()); return thumb; } @@ -2134,7 +2139,7 @@ void ui::Layer::restore(const Snapshot& snap) } } -ui::Layer::Snapshot ui::Layer::snapshot(std::string data_path) +ui::Layer::Snapshot ui::Layer::snapshot() { Snapshot snap; static int counter = 0; @@ -2156,11 +2161,6 @@ ui::Layer::Snapshot ui::Layer::snapshot(std::string data_path) glReadPixels(m_dirty_box[i].x, m_dirty_box[i].y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get()); m_rtt[i].unbindFramebuffer(); //glReadBuffer(GL_NONE); - - LOG("snapshot face %d - %d bytes (%dx%d)", i, (int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y); - static char name[128]; - sprintf(name, "%s/Layer%d-%d.png", data_path.c_str(), counter, i); - //int ret = stbi_write_png(name, m_rtt[i].getWidth(), m_rtt[i].getHeight(), 4, snap.image[i].get(), m_rtt[i].stride()); } counter++; return snap; diff --git a/src/canvas.h b/src/canvas.h index 36573de..cd3e902 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -52,7 +52,7 @@ public: void resize(int width, int height); bool create(int width, int height, std::string name); void clear(const glm::vec4& c); - Snapshot snapshot(std::string data_path); + Snapshot snapshot(); void restore(const Snapshot& snap); void destroy(); }; @@ -202,7 +202,7 @@ public: void pick_update(int plane); glm::vec4 pick_get(glm::vec2 canvas_loc); void pick_end(); - void snapshot_save(std::string data_path); + void snapshot_save(); void snapshot_restore(); void snap_history(const std::vector& planes); class ActionStroke* create_action(int layer); @@ -211,8 +211,8 @@ public: void import_equirectangular_thread(std::string file_path); void export_equirectangular(std::string file_path, std::function on_complete = nullptr); void export_equirectangular_thread(std::string file_path); - void export_anim(std::string data_path); - void export_cubes(std::string data_path); + void export_anim(); + void export_cubes(); void project_save(std::function on_complete = nullptr); void project_save(std::string file_path, std::function on_complete = nullptr); void project_save_thread(std::string file_path); @@ -220,7 +220,7 @@ public: bool project_open_thread(std::string file_path); void inject_xmp(std::string jpg_path); ui::Image thumbnail_generate(int w, int h); - ui::Image thumbnail_read(std::string data_path); + ui::Image thumbnail_read(std::string file_path); void draw_objects(std::function); void draw_objects(std::function, Layer& layer); bool ray_intersect(glm::vec3 ray_origin, glm::vec3 ray_dir, glm::vec3 plane_origin, diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 528c4b9..9661392 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -53,7 +53,7 @@ void NodeCanvas::restore_context() void NodeCanvas::clear_context() { Node::clear_context(); - m_canvas->snapshot_save(data_path); + m_canvas->snapshot_save(); m_canvas->clear_context(); // TODO: clear CanvasMode objects } diff --git a/src/node_canvas.h b/src/node_canvas.h index 3e4bfbf..1f57b9c 100644 --- a/src/node_canvas.h +++ b/src/node_canvas.h @@ -5,7 +5,6 @@ class NodeCanvas : public Node { public: - std::string data_path; std::unique_ptr m_canvas; Sampler m_sampler; Sampler m_sampler_linear; diff --git a/src/node_dialog_browse.cpp b/src/node_dialog_browse.cpp index fa74191..0d48d94 100644 --- a/src/node_dialog_browse.cpp +++ b/src/node_dialog_browse.cpp @@ -72,10 +72,10 @@ void NodeDialogBrowse::init_controls() root()->update(); }; container = find("files-list"); - auto names = Asset::list_files(data_path, false, ".*\\.ppi"); + auto names = Asset::list_files(search_path, false, ".*\\.ppi"); for (const auto& n : names) { - ui::Image thumb = ui::Canvas::I->thumbnail_read(data_path + "/" + n); + ui::Image thumb = ui::Canvas::I->thumbnail_read(search_path + "/" + n); if (thumb.width == 0 || thumb.height == 0) continue; @@ -83,7 +83,7 @@ void NodeDialogBrowse::init_controls() node->m_manager = m_manager; node->init(); node->m_text->set_text(n.c_str()); - node->m_path = data_path + "/" + n; + node->m_path = search_path + "/" + n; node->m_file_name = n; node->on_selected = [&](NodeDialogBrowseItem* target) { if (target == current) diff --git a/src/node_dialog_browse.h b/src/node_dialog_browse.h index 23dcf90..8deae07 100644 --- a/src/node_dialog_browse.h +++ b/src/node_dialog_browse.h @@ -37,7 +37,7 @@ public: std::string selected_path; std::string selected_file; std::string selected_name; - std::string data_path; + std::string search_path; virtual Node* clone_instantiate() const override; virtual void clone_finalize(Node* dest) const override; virtual void init() override; diff --git a/src/node_dialog_cloud.cpp b/src/node_dialog_cloud.cpp index b9d784c..fa6c85f 100644 --- a/src/node_dialog_cloud.cpp +++ b/src/node_dialog_cloud.cpp @@ -101,7 +101,7 @@ void NodeDialogCloud::load_thumbs_thread() node->m_manager = m_manager; node->init(); node->m_text->set_text(n.c_str()); - node->m_path = data_path + "/" + n; + node->m_path = App::I.work_path + "/" + n; node->m_file_name = n; container->add_child(node); node->on_selected = [&](NodeDialogCloudItem* target) { diff --git a/src/node_dialog_cloud.h b/src/node_dialog_cloud.h index 61b93e3..d94c887 100644 --- a/src/node_dialog_cloud.h +++ b/src/node_dialog_cloud.h @@ -38,7 +38,6 @@ public: std::string selected_path; std::string selected_file; std::string selected_name; - std::string data_path; virtual Node* clone_instantiate() const override; virtual void clone_finalize(Node* dest) const override; virtual void init() override; diff --git a/src/node_dialog_layer_rename.h b/src/node_dialog_layer_rename.h index bb43628..955e2b3 100644 --- a/src/node_dialog_layer_rename.h +++ b/src/node_dialog_layer_rename.h @@ -9,7 +9,6 @@ public: NodeButton* btn_cancel; NodeButton* btn_ok; NodeTextInput* input; - std::string data_path; virtual Node* clone_instantiate() const override; virtual void clone_finalize(Node* dest) const override; virtual void init() override; diff --git a/src/node_dialog_open.cpp b/src/node_dialog_open.cpp index d42ee95..050756b 100644 --- a/src/node_dialog_open.cpp +++ b/src/node_dialog_open.cpp @@ -69,14 +69,14 @@ void NodeDialogOpen::init_controls() root()->update(); }; container = find("files-list"); - auto names = Asset::list_files(data_path, false, ".*\\.ppi"); + auto names = Asset::list_files(App::I.work_path, false, ".*\\.ppi"); for (const auto& n : names) { auto node = new NodeDialogOpenItem; node->m_manager = m_manager; node->init(); node->m_text->set_text(n.c_str()); - node->m_path = data_path + "/" + n; + node->m_path = App::I.work_path + "/" + n; node->m_file_name = n; node->on_selected = [&](NodeDialogOpenItem* target) { if (target == current) diff --git a/src/node_dialog_open.h b/src/node_dialog_open.h index 468fb2f..bf5b359 100644 --- a/src/node_dialog_open.h +++ b/src/node_dialog_open.h @@ -38,7 +38,6 @@ public: std::string selected_path; std::string selected_file; std::string selected_name; - std::string data_path; virtual Node* clone_instantiate() const override; virtual void clone_finalize(Node* dest) const override; virtual void init() override;