diff --git a/data/layout.xml b/data/layout.xml
index 3432262..815e929 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -1632,6 +1632,9 @@ Here's a list of what's available in this release.
+
@@ -1694,6 +1697,10 @@ Here's a list of what's available in this release.
+
+
+
+
@@ -1963,9 +1970,12 @@ Here's a list of what's available in this release.
-
+
+
+
+
diff --git a/src/app.h b/src/app.h
index db1d85e..a0fb369 100644
--- a/src/app.h
+++ b/src/app.h
@@ -104,6 +104,7 @@ public:
std::shared_ptr stroke;
std::shared_ptr grid;
std::shared_ptr presets;
+ std::shared_ptr timeline;
NodePanelQuick* quick;
std::map quick_mode_state;
Node* floatings_container;
diff --git a/src/app_dialogs.cpp b/src/app_dialogs.cpp
index ed29cea..1ed14da 100644
--- a/src/app_dialogs.cpp
+++ b/src/app_dialogs.cpp
@@ -466,16 +466,23 @@ void App::dialog_export_layers()
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
+ auto dir = work_path + "/" + doc_name + "_layers";
+ if (Asset::create_dir(dir))
+ {
+ auto p = dir + "/" + doc_name;
+ canvas->m_canvas->export_layers(p, [this, p] {
+ message_box("Export Layers", "Image layers exported to Files/PanoPainter");
+ });
+ }
+#else
+ pick_dir([this](std::string path) {
+ auto p = path + "/" + doc_name;
+ canvas->m_canvas->export_layers(p, [this, p] {
+ message_box("Export Layers", "Layers exported to: " + p);
+ });
});
+#endif
}
}
diff --git a/src/app_layout.cpp b/src/app_layout.cpp
index c21c40a..1c2e7ce 100644
--- a/src/app_layout.cpp
+++ b/src/app_layout.cpp
@@ -638,6 +638,13 @@ void App::init_menu_file()
popup->mouse_release();
popup->destroy();
};
+ subpopup->find("file-submenu-export-anim")->on_click = [this, subpopup, popup](Node*) {
+ dialog_export_layers();
+ subpopup->mouse_release();
+ subpopup->destroy();
+ popup->mouse_release();
+ popup->destroy();
+ };
};
if (auto b = popup->find("file-share"))
b->on_click = [this, popup](Node*) {
@@ -987,6 +994,23 @@ void App::init_menu_tools()
};
}
+ if (auto vr_btn = popup_exp->find("tools-timeline"))
+ {
+ NodeCheckBox* cb = vr_btn->find("tools-timeline-check");
+ cb->set_value(timeline->GetVisibility());
+
+ vr_btn->on_click = [this, popup_exp, vr_btn](Node* b)
+ {
+ NodeCheckBox* cb = vr_btn->find("tools-timeline-check");
+ cb->set_value(!cb->checked, true);
+ };
+
+ vr_btn->find("tools-timeline-check")->on_value_changed = [this, main](Node* target, bool checked)
+ {
+ timeline->SetVisibility(checked);
+ };
+ }
+
popup_exp->find("clear-grids")->on_click = [this, popup_exp](Node*) {
CanvasModeGrid* mode = (CanvasModeGrid*)Canvas::modes[(int)kCanvasMode::Grid][0];
mode->clear();
@@ -1297,7 +1321,8 @@ void App::initLayout()
toggle_ui();
};
- if (auto* timeline = layout[main_id]->find("timeline"))
+ timeline = layout[main_id]->find_ref("timeline");
+ if (timeline)
{
if (auto * slider = layout[main_id]->find("frames-slider"))
{
@@ -1337,7 +1362,12 @@ void App::initLayout()
}
};
}
- timeline->destroy();
+ if (auto btn_add = timeline->find("btn-add"))
+ {
+ btn_add->on_click = [this] (Node*) {
+ layers->add_layer(true, true);
+ };
+ }
}
/*
@@ -1459,6 +1489,7 @@ void App::ui_save()
Settings::set("ui", d);
Settings::set("ui-rtl", Serializer::Boolean(ui_rtl));
+ Settings::set("timeline-visible", Serializer::Boolean(timeline->GetVisibility()));
#if _WIN32
extern void win32_save_window_state();
@@ -1477,6 +1508,9 @@ void App::ui_restore()
if (!Settings::has("ui"))
return;
+
+ timeline->SetVisibility(Settings::value_or("timeline-visible", false));
+
auto floatings = layout[main_id]->find_ref("floatings");
auto drop_left = layout[main_id]->find_ref("drop-left");
auto drop_right = layout[main_id]->find_ref("drop-right");
diff --git a/src/canvas.cpp b/src/canvas.cpp
index 4f57e70..c417e64 100644
--- a/src/canvas.cpp
+++ b/src/canvas.cpp
@@ -1908,13 +1908,13 @@ void Canvas::export_depth_thread(std::string file_name)
rtt.destroy();
}
-void Canvas::export_layers(std::string file_name, std::function on_complete)
+void Canvas::export_layers(std::string path, std::function on_complete)
{
if (App::I->check_license())
{
std::thread t([=] {
BT_SetTerminate();
- export_layers_thread(file_name);
+ export_layers_thread(path);
if (on_complete)
on_complete();
});
@@ -1922,14 +1922,14 @@ void Canvas::export_layers(std::string file_name, std::function on_compl
}
}
-void Canvas::export_layers_thread(std::string file_name)
+void Canvas::export_layers_thread(std::string path)
{
auto pb = App::I->show_progress("Export Layers", m_layers.size());
for (int i = 0; i < m_layers.size(); i++)
{
auto l = m_layers[i];
Image img = l->gen_equirect().get_image();
- img.save_png(fmt::format("{}/{}-layer{:02d}-{}.png", App::I->work_path, file_name, i, l->m_name));
+ img.save_png(fmt::format("{}-layer{:02d}-{}.png", path, i, l->m_name));
pb->increment();
}
pb->destroy();
diff --git a/src/canvas.h b/src/canvas.h
index 9d54f61..45c6095 100644
--- a/src/canvas.h
+++ b/src/canvas.h
@@ -203,8 +203,8 @@ public:
void import_equirectangular_thread(std::string file_path, std::shared_ptr layer = nullptr);
void export_equirectangular(std::string file_path, std::function on_complete = nullptr);
void export_equirectangular_thread(std::string file_path);
- void export_layers(std::string file_name, std::function on_complete = nullptr);
- void export_layers_thread(std::string file_name);
+ void export_layers(std::string path, std::function on_complete = nullptr);
+ void export_layers_thread(std::string path);
void export_depth(std::string file_name, std::function on_complete = nullptr);
void export_depth_thread(std::string file_name);
void export_cube_faces(std::string file_name, std::function on_complete);
diff --git a/src/node.cpp b/src/node.cpp
index 0fc32fd..23bb39e 100644
--- a/src/node.cpp
+++ b/src/node.cpp
@@ -907,6 +907,11 @@ void Node::SetRTL(YGDirection dir)
app_redraw();
}
+bool Node::GetVisibility()
+{
+ return m_display;
+}
+
void Node::SetVisibility(bool visible)
{
App::I->ui_task([&]
diff --git a/src/node.h b/src/node.h
index 52e55d9..22001d6 100644
--- a/src/node.h
+++ b/src/node.h
@@ -181,6 +181,7 @@ public:
// used in visibility switch
YGNodeRef y_placeholder = nullptr;
+ bool GetVisibility();
void SetVisibility(bool visible);
void ToggleVisibility();