diff --git a/data/layout.xml b/data/layout.xml
index 41e58d2..da48052 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -1483,6 +1483,9 @@ Here's a list of what's available in this release.
+
diff --git a/src/app.h b/src/app.h
index 82caa10..997d282 100644
--- a/src/app.h
+++ b/src/app.h
@@ -205,7 +205,7 @@ public:
bool key_char(char key);
void toggle_ui();
void set_stylus();
- NodeMessageBox* message_box(const std::string& title, const std::string& text, bool cancel_button = false);
+ std::shared_ptr message_box(const std::string& title, const std::string& text, bool cancel_button = false);
void rec_clear();
void rec_loop();
@@ -243,7 +243,7 @@ public:
void download(std::string url, std::string dest_filepath, std::function progress = nullptr);
bool check_license();
- std::shared_ptr show_progress(const std::string& title);
+ std::shared_ptr show_progress(const std::string& title, int total = 0);
void brush_update(bool update_color, bool update_brush);
void title_update();
@@ -253,6 +253,7 @@ public:
int res_to_index(int res);
std::string res_to_string(int res);
void crash_test();
+ void stacktrace();
void ui_save();
void ui_restore();
@@ -394,7 +395,7 @@ public:
}
ui_cv.notify_all();
}
- return ui_running ? f.get() : R();
+ return ui_running ? f.get(), redraw = true : R();
}
void ui_sync()
diff --git a/src/app_cloud.cpp b/src/app_cloud.cpp
index aadf262..d79e45c 100644
--- a/src/app_cloud.cpp
+++ b/src/app_cloud.cpp
@@ -31,7 +31,7 @@ void App::cloud_upload()
auto pb = show_progress("Uploading");
upload(doc_path, doc_filename, [this,pb](float p){
- pb->m_progress->SetWidthP(p * 100.f);
+ pb->set_progress(p);
});
pb->destroy();
@@ -70,32 +70,20 @@ void App::cloud_upload_all()
gl_state gl;
std::shared_ptr pb;
if (layout.m_loaded)
- {
- pb = show_progress("Export Pano Image");
- }
-
- int progress = 0;
- int total = (int)names.size();
+ pb = show_progress("Export Pano Image", names.size());
for (const auto& n : names)
{
std::string path = data_path + "/" + n;
upload(path);
- progress++;
- float p = (float)progress / total * 100.f;
- LOG("progress: %f", p);
-
if (layout.m_loaded)
- {
- pb->m_progress->SetWidthP(p);
- }
+ pb->increment();
}
if (layout.m_loaded)
- {
pb->destroy();
- }
+
}).detach();
}
diff --git a/src/app_dialogs.cpp b/src/app_dialogs.cpp
index def5f1a..810dfb8 100644
--- a/src/app_dialogs.cpp
+++ b/src/app_dialogs.cpp
@@ -13,7 +13,7 @@
#include "oculus_vr.h"
#endif
-std::shared_ptr App::show_progress(const std::string& title)
+std::shared_ptr App::show_progress(const std::string& title, int total /*= 0*/)
{
auto pb = std::make_shared();
pb->m_manager = &layout;
@@ -22,18 +22,25 @@ std::shared_ptr App::show_progress(const std::string& title)
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;
}
-NodeMessageBox* App::message_box(const std::string &title, const std::string& text, bool cancel_button)
+std::shared_ptr App::message_box(const std::string &title, const std::string& text, bool cancel_button)
{
- auto* m = layout[main_id]->add_child();
+ auto m = std::make_shared();
+ 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;
}
diff --git a/src/canvas.cpp b/src/canvas.cpp
index 9beb7d2..962d75f 100644
--- a/src/canvas.cpp
+++ b/src/canvas.cpp
@@ -1921,113 +1921,16 @@ void Canvas::export_layers(std::string file_name, std::function on_compl
void Canvas::export_layers_thread(std::string file_name)
{
- std::shared_ptr pb;
- if (App::I->layout.m_loaded)
+ static std::array plane_names { "front", "right", "back", "left", "top", "bottom" };
+ auto pb = App::I->show_progress("Export Layers", m_layers.size());
+ for (int i = 0; i < m_layers.size(); i++)
{
- pb = std::make_shared();
- pb->m_manager = &App::I->layout;
- pb->init();
- pb->create();
- pb->loaded();
- pb->m_progress->SetWidthP(0);
- pb->m_title->set_text("Export Pano Layers");
- App::I->layout[App::I->main_id]->add_child(pb);
- }
- int progress = 0;
- int total = (int)(m_layers.size() + 1) * 6;
-
- RTT m_latlong;
- m_latlong.create(m_width * 4, m_height * 2); // NOTE: w and h must be equal to make sense
-
- GLuint cube_id;
- int faces[]{
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // front
- GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // right
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // back
- GL_TEXTURE_CUBE_MAP_POSITIVE_X, // left
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // top
- GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom
- };
- App::I->render_task([&]
- {
- glGenTextures(1, &cube_id);
- glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
- for (GLuint i = 0; i < 6; i++)
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- });
-
- int seq = 0;
- for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
- {
- for (int i = 0; i < 6; i++)
- {
- App::I->render_task([&]
- {
- // copy layer to cubemap
- m_layers[layer_index]->m_rtt[i].bindFramebuffer();
- glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
- glCopyTexImage2D(faces[i], 0, GL_RGBA8, 0, 0, m_width, m_height, 0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
- m_layers[layer_index]->m_rtt[i].unbindFramebuffer();
- });
-
- progress++;
- float p = (float)progress / total * 100.f;
- LOG("progress: %f", p);
-
- if (App::I->layout.m_loaded)
- {
- pb->m_progress->SetWidthP(p);
- }
- }
-
- App::I->render_task([&]
- {
- glViewport(0, 0, m_latlong.getWidth(), m_latlong.getHeight());
- glActiveTexture(GL_TEXTURE0);
- m_latlong.bindFramebuffer();
- m_latlong.clear({ 1, 1, 1, 0 });
- ShaderManager::use(kShader::Equirect);
- ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
- ShaderManager::u_int(kShaderUniform::Tex, 0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
- glDisable(GL_BLEND);
- m_sampler_linear.bind(0);
- m_plane.draw_fill();
- glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
- m_latlong.unbindFramebuffer();
- });
-
- {
- auto latlong_data = std::make_unique(m_latlong.bytes());
- m_latlong.readTextureData(latlong_data.get());
- static char name[128];
- sprintf(name, "%s/%s-layer-%02d.png", App::I->work_path.c_str(), file_name.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());
- }
-
- progress++;
- float p = (float)progress / total * 100.f;
- LOG("progress: %f", p);
-
- if (App::I->layout.m_loaded)
- {
- pb->m_progress->SetWidthP(p);
- }
- }
-
- App::I->render_task([&]
- {
- glDeleteTextures(1, &cube_id);
- m_latlong.destroy();
- });
-
- if (App::I->layout.m_loaded)
- {
- pb->destroy();
+ 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));
+ pb->increment();
}
+ pb->destroy();
}
void Canvas::export_cubes()
diff --git a/src/layout.cpp b/src/layout.cpp
index a5c89b9..0bcb361 100644
--- a/src/layout.cpp
+++ b/src/layout.cpp
@@ -9,7 +9,7 @@
void LayoutManager::unload()
{
for (auto& l : m_layouts)
- l.second->destroy_immediate();
+ l.second->destroy();
m_layouts.clear();
}
diff --git a/src/node.cpp b/src/node.cpp
index 02984fa..93e1dc8 100644
--- a/src/node.cpp
+++ b/src/node.cpp
@@ -41,6 +41,7 @@ void Node::app_redraw()
{
App::I->redraw = true;
App::I->ui_cv.notify_all();
+ App::I->render_cv.notify_all();
}
void Node::watch(std::function observer)
@@ -58,20 +59,17 @@ void Node::watch(std::function observer)
void Node::destroy()
{
- m_destroyed = true;
+ auto children_copy = m_children;
+ for (auto c : children_copy)
+ c->destroy();
mouse_release();
key_release();
-}
-
-void Node::destroy_immediate()
-{
- for (auto c : m_children)
- c->destroy_immediate();
+ remove_from_parent();
+ app_redraw();
}
Node* Node::root()
{
-
Node* ret = this;
while (ret->m_parent)
ret = ret->m_parent;
@@ -657,7 +655,6 @@ Node::Node(Node&& o)
m_flood_events = o.m_flood_events;
m_force_mouse_capture = o.m_force_mouse_capture;
m_capture_children = o.m_capture_children;
- m_destroyed = false;// o.m_destroyed;
m_scale = o.m_scale;
m_pos_origin = o.m_pos_origin;
@@ -1007,16 +1004,6 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj, float
m_mvp = proj * pos * scale * pivot * prescale;
m_proj = proj;
- for (int i = 0; i < m_children.size(); i++)
- {
- if (m_children[i]->m_destroyed)
- {
- m_children[i]->destroy_immediate();
- remove_child(m_children[i].get());
- i--;
- }
- }
-
if (m_size != old_size || m_zoom != zoom)
{
m_zoom = zoom;
@@ -1370,14 +1357,11 @@ void Node::clone_copy(Node* dest) const
dest->m_mvp = m_mvp;
dest->m_mouse_inside = m_mouse_inside;
dest->m_capture_children = m_capture_children;
- dest->m_destroyed = false;// m_destroyed;
dest->m_scale = m_scale;
dest->m_pos_origin = m_pos_origin;
dest->m_pos_offset = m_pos_offset;
dest->m_pos_offset_childred = m_pos_offset_childred;
dest->m_clip_uncut = m_clip_uncut;
-
-
}
void Node::clone_children(Node* dest) const
diff --git a/src/node.h b/src/node.h
index 1d9b3bb..720a086 100644
--- a/src/node.h
+++ b/src/node.h
@@ -116,7 +116,6 @@ public:
bool m_flood_events = false;
bool m_force_mouse_capture = false;
bool m_capture_children = true; // wether to capture children events when xx_capture() is used
- bool m_destroyed = false;
std::vector m_capture_stack;
bool m_mouse_ignore = true;
@@ -201,8 +200,7 @@ public:
virtual void clone_children(Node* dest) const;
virtual void clone_finalize(Node* dest) const;;
void watch(std::function observer);
- void destroy();
- virtual void destroy_immediate();
+ virtual void destroy();
Node* root();
template T* find(const char* ids)
diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp
index bacff9b..b24bb6a 100644
--- a/src/node_canvas.cpp
+++ b/src/node_canvas.cpp
@@ -643,9 +643,8 @@ void NodeCanvas::on_tick(float dt)
m_outline_pan = glm::fract(m_outline_pan + dt * 0.01f);
}
-void NodeCanvas::destroy_immediate()
+void NodeCanvas::destroy()
{
- Node::destroy_immediate();
m_blender_rtt.destroy();
m_cache_rtt.destroy();
m_rtt.destroy();
@@ -653,4 +652,5 @@ void NodeCanvas::destroy_immediate()
m_face_plane.destroy();
m_line.destroy();
m_grid.destroy();
+ Node::destroy();
}
diff --git a/src/node_canvas.h b/src/node_canvas.h
index 9c45c6c..a067e40 100644
--- a/src/node_canvas.h
+++ b/src/node_canvas.h
@@ -27,7 +27,7 @@ public:
virtual void draw() override;
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom) override;
virtual kEventResult handle_event(Event* e) override;
- virtual void destroy_immediate() override;
+ virtual void destroy() override;
virtual void on_tick(float dt) override;
void reset_camera();
void create_buffers();
diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp
index ea5f4eb..ea51c91 100644
--- a/src/node_panel_brush.cpp
+++ b/src/node_panel_brush.cpp
@@ -442,8 +442,7 @@ void NodePanelBrushPreset::init()
if (!m_current)
return;
int index = m_container->get_child_index(m_current);
- m_current->destroy_immediate();
- m_container->remove_child(m_current);
+ m_current->destroy();
if (m_container->m_children.empty())
{
m_current = nullptr;
diff --git a/src/node_panel_grid.cpp b/src/node_panel_grid.cpp
index eb1ae31..69e3dd1 100644
--- a/src/node_panel_grid.cpp
+++ b/src/node_panel_grid.cpp
@@ -467,7 +467,7 @@ void NodePanelGrid::bake_uvs()
);
while (pb_value < fb.getHeight())
{
- pb->m_progress->SetWidthP((float)pb_value / (float)fb.getHeight() * 100.f);
+ pb->set_progress((float)pb_value / (float)fb.getHeight());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
worker.join();
diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp
index 4f14009..8fb93f4 100644
--- a/src/node_panel_stroke.cpp
+++ b/src/node_panel_stroke.cpp
@@ -76,8 +76,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
brush->m_user_brush = true;
brush->on_click = std::bind(&NodePanelBrush::handle_click, m_brush_popup, std::placeholders::_1);
count++;
- float prog = (float)count / (float)tot;
- pb->m_progress->SetWidthP(prog * 100.f);
+ pb->set_progress((float)count / (float)tot);
});
m_brush_popup->save();
@@ -105,8 +104,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
brush->m_user_brush = true;
brush->on_click = std::bind(&NodePanelBrush::handle_click, m_pattern_popup, std::placeholders::_1);
count++;
- float prog = (float)count / (float)tot;
- pb->m_progress->SetWidthP(prog * 100.f);
+ pb->set_progress((float)count / (float)tot);
});
m_pattern_popup->save();
@@ -119,8 +117,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
App::I->presets->add_brush(pr);
}
count++;
- float prog = (float)count / (float)tot;
- pb->m_progress->SetWidthP(prog * 100.f);
+ pb->set_progress((float)count / (float)tot);
}
App::I->presets->save();
diff --git a/src/node_progress_bar.cpp b/src/node_progress_bar.cpp
index 32e98d9..f3a5501 100644
--- a/src/node_progress_bar.cpp
+++ b/src/node_progress_bar.cpp
@@ -20,5 +20,17 @@ void NodeProgressBar::init()
btn_cancel->on_click = [&](Node*) { destroy(); };
m_progress = find("progress");
- m_progress->SetWidthP(10);
+ m_progress->SetWidthP(0);
+}
+
+void NodeProgressBar::increment() noexcept
+{
+ m_count++;
+ if (m_total != 0)
+ m_progress->SetWidthP(((float)m_count / m_total) * 100.f);
+}
+
+void NodeProgressBar::set_progress(float p) noexcept
+{
+ m_progress->SetWidthP(p * 100.f);
}
diff --git a/src/node_progress_bar.h b/src/node_progress_bar.h
index f5133e3..f8436e1 100644
--- a/src/node_progress_bar.h
+++ b/src/node_progress_bar.h
@@ -11,6 +11,11 @@ public:
NodeButton* btn_cancel;
NodeText* m_title;
NodeBorder* m_progress;
+ int m_total = 0;
+ int m_count = 0;
virtual Node* clone_instantiate() const override;
virtual void init() override;
+ void increment() noexcept;
+ // set progress where p [0, 1]
+ void set_progress(float p) noexcept;
};
diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp
index 0a14701..3923d33 100644
--- a/src/node_stroke_preview.cpp
+++ b/src/node_stroke_preview.cpp
@@ -589,10 +589,10 @@ void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size, fl
draw_stroke();
}
-void NodeStrokePreview::destroy_immediate()
+void NodeStrokePreview::destroy()
{
- Node::destroy_immediate();
m_tex_preview.destroy();
+ Node::destroy();
}
void NodeStrokePreview::handle_on_screen(bool old_visibility, bool new_visibility)
diff --git a/src/node_stroke_preview.h b/src/node_stroke_preview.h
index 85be498..43def90 100644
--- a/src/node_stroke_preview.h
+++ b/src/node_stroke_preview.h
@@ -54,6 +54,6 @@ public:
void draw_stroke_immediate();
virtual void draw() override;
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom) override;
- virtual void destroy_immediate() override;
+ virtual void destroy() override;
virtual void handle_on_screen(bool old_visibility, bool new_visibility) override;
};