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; };