From 48c39c4ef27e7c50c71b43e01626bd7f2f1fab53 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Wed, 10 Jul 2019 21:08:14 +0200 Subject: [PATCH] improve dialog browse, wrap ui task for every Node method that modifies the children list, update the ui every time the scene tree changes, restore fps and stylus state on win, fix bucket tool, fix snapshop restore, init in ui thread --- data/layout.xml | 9 +- src/app.cpp | 24 +++- src/app_layout.cpp | 46 ++++--- src/canvas.cpp | 13 +- src/canvas_layer.cpp | 6 +- src/main.cpp | 55 +++++++- src/node.cpp | 256 +++++++++++++++++++++++-------------- src/node_dialog_browse.cpp | 2 +- src/util.cpp | 10 ++ src/util.h | 3 + 10 files changed, 293 insertions(+), 131 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index 27eb92e..da3a449 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -919,8 +919,11 @@ - - + + + + + @@ -1581,12 +1584,10 @@ Here's a list of what's available in this release. - diff --git a/src/app.cpp b/src/app.cpp index 56d2364..e1ee65a 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -718,7 +718,6 @@ void App::update_memory_usage(size_t bytes) static char buffer[128]; sprintf(buffer, "History memory: %.2f Mb", bytes / 1024.f / 1024.f); txt->set_text(buffer); - layout[main_id]->update(); } } @@ -1021,6 +1020,8 @@ void App::rec_loop() void App::render_thread_main() { + BT_SetTerminate(); + uint32_t count = 0; render_thread_id = std::this_thread::get_id(); render_running = true; @@ -1053,9 +1054,14 @@ void App::render_thread_main() void App::ui_thread_main() { + BT_SetTerminate(); + uint32_t count = 0; ui_thread_id = std::this_thread::get_id(); ui_running = true; + + init(); + auto t_start = std::chrono::high_resolution_clock::now(); float t_frame = 0; float t_fps_counter = 0; @@ -1067,7 +1073,8 @@ void App::ui_thread_main() // move the task list locally to free the queue for other threads { std::unique_lock lock(ui_task_mutex); - ui_cv.wait(lock, [this] { return ui_tasklist.empty() && ui_running ? false : true; }); + ui_cv.wait_for(lock, std::chrono::milliseconds(100), + [this] { return ui_tasklist.empty() && ui_running ? false : true; }); working_list = std::move(ui_tasklist); } @@ -1085,6 +1092,12 @@ void App::ui_thread_main() auto t_now = std::chrono::high_resolution_clock::now(); float dt = std::chrono::duration(t_now - t_start).count(); + t_start = t_now; + +#ifdef _WIN32 + extern void win32_update_stylus(float dt); + win32_update_stylus(dt); +#endif // increment timers t_frame += dt; @@ -1092,7 +1105,12 @@ void App::ui_thread_main() if (t_fps_counter > 1.f) { - +#ifdef _WIN32 + extern void win32_update_fps(int frames); + win32_update_fps(rendered_frames); +#endif + t_fps_counter = 0; + rendered_frames = 0; } tick(dt); diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 9ea389c..e3db4dc 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -1064,28 +1064,31 @@ void App::init_menu_about() { b->on_click = [this, popup](Node*) { LOG("perf"); - auto start = std::chrono::high_resolution_clock::now(); - Canvas::I->stroke_start({ 0, 0, 0 }, 0.9f); - for (int i = 0; i < 100; i++) - { - Canvas::I->stroke_update({ 100, 100, 0 }, 0.9f); - Canvas::I->stroke_update({ 200, 200, 0 }, 0.9f); - Canvas::I->stroke_update({ 200, 100, 0 }, 0.9f); - Canvas::I->stroke_update({ 100, 200, 0 }, 0.9f); - Canvas::I->stroke_update({ 300, 300, 0 }, 0.9f); - Canvas::I->stroke_update({ 200, 500, 0 }, 0.9f); - Canvas::I->stroke_update({ 500, 500, 0 }, 0.9f); - Canvas::I->stroke_update({ 400, 400, 0 }, 0.9f); - Canvas::I->stroke_update({ 0, 200, 0 }, 0.9f); - Canvas::I->stroke_update({ 200, 0, 0 }, 0.9f); - Canvas::I->stroke_draw(); - } - Canvas::I->stroke_end(); - auto diff = std::chrono::high_resolution_clock::now() - start; - auto ms = std::chrono::duration_cast(diff).count(); - LOG("%lld ms", ms); static char str[256]; - sprintf(str, "Time %lld ms", ms); + render_task([&] + { + auto start = std::chrono::high_resolution_clock::now(); + Canvas::I->stroke_start({ 0, 0, 0 }, 0.9f); + for (int i = 0; i < 100; i++) + { + Canvas::I->stroke_update({ 100, 100, 0 }, 0.9f); + Canvas::I->stroke_update({ 200, 200, 0 }, 0.9f); + Canvas::I->stroke_update({ 200, 100, 0 }, 0.9f); + Canvas::I->stroke_update({ 100, 200, 0 }, 0.9f); + Canvas::I->stroke_update({ 300, 300, 0 }, 0.9f); + Canvas::I->stroke_update({ 200, 500, 0 }, 0.9f); + Canvas::I->stroke_update({ 500, 500, 0 }, 0.9f); + Canvas::I->stroke_update({ 400, 400, 0 }, 0.9f); + Canvas::I->stroke_update({ 0, 200, 0 }, 0.9f); + Canvas::I->stroke_update({ 200, 0, 0 }, 0.9f); + Canvas::I->stroke_draw(); + } + Canvas::I->stroke_end(); + auto diff = std::chrono::high_resolution_clock::now() - start; + auto ms = std::chrono::duration_cast(diff).count(); + LOG("%lld ms", ms); + sprintf(str, "Time %lld ms", ms); + }); message_box("Performance test", str); popup->mouse_release(); popup->destroy(); @@ -1215,6 +1218,7 @@ void App::initLayout() init_sidebar(); layers->add_layer("Default", false, true); + Canvas::I->m_unsaved = false; init_toolbar_draw(); init_toolbar_main(); diff --git a/src/canvas.cpp b/src/canvas.cpp index 849f839..1701df3 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -1446,6 +1446,7 @@ void Canvas::FloodData::apply() rtt.unbindTexture(); }); layer->m_dirty_face[plane] = true; + layer->m_dirty_box[plane] = box_union(layer->m_dirty_box[plane], bb[plane]); } } @@ -2413,6 +2414,7 @@ bool Canvas::project_save_thread(std::string file_path) fwrite(&m_layers[i]->m_visible, sizeof(bool), 1, fp); } + m_layers[i]->optimize(); auto snap = m_layers[i]->snapshot(); for (int plane_index = 0; plane_index < 6; plane_index++) { @@ -2562,6 +2564,9 @@ bool Canvas::project_open_thread(std::string file_path) int n_order; fread(&n_order, sizeof(int), 1, fp); + //if (ppi_header.doc_version.minor > 1) + // n_order = i; + tmp_layers[n_order] = std::make_unique(); auto& layer = tmp_layers[n_order]; @@ -3085,8 +3090,12 @@ void Layer::restore(const Snapshot& snap) clear({ 0, 0, 0, 0 }); for (int i = 0; i < 6; i++) { - if (snap.image[i] == nullptr) + if (snap.image[i] == nullptr || snap.m_dirty_face[i] == false || box_area(snap.m_dirty_box[i]) <= 0) + { + m_dirty_box[i] = glm::vec4(snap.width, snap.height, 0, 0); + m_dirty_face[i] = false; continue; + } m_dirty_box[i] = snap.m_dirty_box[i]; m_dirty_face[i] = snap.m_dirty_face[i]; @@ -3115,6 +3124,8 @@ void Layer::restore(const Snapshot& snap) Layer::Snapshot Layer::snapshot(std::array * dirty_box /*= nullptr*/, std::array * dirty_face /*= nullptr*/) { Snapshot snap; + snap.width = w; + snap.height = h; for (int i = 0; i < 6; i++) { snap.m_dirty_box[i] = dirty_box ? dirty_box->at(i) : m_dirty_box[i]; diff --git a/src/canvas_layer.cpp b/src/canvas_layer.cpp index 40a1c54..d88a5ce 100644 --- a/src/canvas_layer.cpp +++ b/src/canvas_layer.cpp @@ -5,8 +5,12 @@ uint32_t Layer::s_count = 0; void Layer::Snapshot::create(int w, int h) { + width = w; + height = h; for (int i = 0; i < 6; i++) { + m_dirty_face[i] = false; + m_dirty_box[i] = glm::vec4(width, height, 0, 0); image[i] = std::make_unique(w * h * 4); std::fill_n(image[i].get(), w * h * 4, 0); } @@ -17,7 +21,7 @@ void Layer::Snapshot::clear() for (int i = 0; i < 6; i++) { m_dirty_face[i] = false; - m_dirty_box[i] = glm::vec4(0); + m_dirty_box[i] = glm::vec4(width, height, 0, 0); std::fill_n(image[i].get(), width * height * 4, 0); } } diff --git a/src/main.cpp b/src/main.cpp index 3bee26a..7070a0e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,10 @@ #include "abr.h" #include "settings.h" +#include +#include +#include + #define WM_USER_CLOSE (WM_USER + 1) LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); @@ -31,6 +35,7 @@ std::mutex gl_mutex; std::mutex async_mutex; std::thread::id gl_thread; std::map vkey_map; +static wchar_t window_title[512]; std::thread hmd_renderer; int vr_frames = 0; @@ -159,6 +164,44 @@ void async_unlock() } } +void win32_update_stylus(float dt) +{ + timer_stylus += dt; + timer_ink_touch += dt; + timer_ink_pen += dt; + + if (timer_stylus > 0.1 && (WacomTablet::I.m_stylus || WacomTablet::I.m_eraser)) + { + WacomTablet::I.m_stylus = false; + WacomTablet::I.m_eraser = false; + App::I.redraw = true; + } + if (timer_ink_pen > 0.1 && WacomTablet::I.m_ink_pen) + { + WacomTablet::I.m_ink_pen = false; + App::I.redraw = true; + } + if (timer_ink_touch > 0.1 && WacomTablet::I.m_ink_touch) + { + WacomTablet::I.m_ink_touch = false; + App::I.redraw = true; + } +} + +void win32_update_fps(int frames) +{ + static wchar_t title_fps[512]; + if (App::I.vr_active) + swprintf_s(title_fps, L"%s - %d fps - %d vr fps", window_title, frames, vr_frames); + else + swprintf_s(title_fps, L"%s - %d fps", window_title, frames); + + std::lock_guard lock(main_task_mutex); + main_tasklist.emplace_back([] { + SetWindowText(hWnd, title_fps); + }); +} + void win32_show_cursor(bool visible) { std::lock_guard lock(main_task_mutex); @@ -476,9 +519,14 @@ static void SetupExceptionHandler() BT_AddLogFile(wpath); BT_SetPreErrHandler([](INT_PTR){ - if (Canvas::I) + if (Canvas::I && Canvas::I->m_unsaved) { - auto path = App::I.data_path + "/recovery.ppi"; + auto t = std::time(nullptr); + auto tm = *std::localtime(&t); + std::ostringstream oss; + oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S"); + + auto path = App::I.data_path + "/" + App::I.doc_name + "-recovery (" + oss.str() + ").ppi"; Canvas::I->project_save_thread(path); static char abspath[MAX_PATH]; GetFullPathNameA(path.c_str(), MAX_PATH, abspath, NULL); @@ -845,7 +893,6 @@ int main(int argc, char** argv) LOG("GL vendor: %s", glGetString(GL_VENDOR)); LOG("GL renderer: %s", glGetString(GL_RENDERER)); - static wchar_t window_title[512]; swprintf_s(window_title, L"PanoPainter %s (%s)", g_version_number_w, str2wstr((char*)glGetString(GL_RENDERER)).c_str()); @@ -934,7 +981,7 @@ int main(int argc, char** argv) #endif LOG("init app"); - App::I.init(); + // App::I.init(); if (!sandboxed) { diff --git a/src/node.cpp b/src/node.cpp index 8b5024c..f548436 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -39,7 +39,8 @@ void Node::app_redraw() { - App::I.ui_task([] { App::I.redraw = true; }); + App::I.redraw = true; + App::I.ui_cv.notify_all(); } void Node::watch(std::function observer) @@ -301,68 +302,84 @@ void Node::removed(Node* parent) const Node* Node::init_template(const char* id) { - auto hid = const_hash(id); - Node* top = m_manager->get(hid); - Node* m_template = static_cast(top->m_children[0].get()); - for (auto& c : m_template->m_children) + Node* m_template = nullptr; + App::I.ui_task([&] { - auto node = c->clone(); - add_child(node); - //node->init(); - //node->create(); - //node->loaded(); - } - YGNodeCopyStyle(y_node, m_template->y_node); - m_template->clone_copy(this); + auto hid = const_hash(id); + Node* top = m_manager->get(hid); + m_template = static_cast(top->m_children[0].get()); + for (auto& c : m_template->m_children) + { + auto node = c->clone(); + add_child(node); + //node->init(); + //node->create(); + //node->loaded(); + } + YGNodeCopyStyle(y_node, m_template->y_node); + m_template->clone_copy(this); + }); return m_template; } void Node::add_child(Node* n) { - if (n->m_parent) - n->m_parent->remove_child(n); - m_children.emplace_back(n); - n->m_parent = this; - n->m_manager = m_manager; - YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node)); - n->added(this); - on_child_added(n); + App::I.ui_task([&] + { + if (n->m_parent) + n->m_parent->remove_child(n); + m_children.emplace_back(n); + n->m_parent = this; + n->m_manager = m_manager; + YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node)); + n->added(this); + on_child_added(n); + }); } void Node::add_child(Node* n, int index) { - if (n->m_parent) - n->m_parent->remove_child(n); - m_children.emplace_back(n); - n->m_parent = this; - n->m_manager = m_manager; - YGNodeInsertChild(y_node, n->y_node, index); - n->added(this); - on_child_added(n); + App::I.ui_task([&] + { + if (n->m_parent) + n->m_parent->remove_child(n); + m_children.emplace_back(n); + n->m_parent = this; + n->m_manager = m_manager; + YGNodeInsertChild(y_node, n->y_node, index); + n->added(this); + on_child_added(n); + }); } void Node::add_child(std::shared_ptr n) { - if (n->m_parent) - n->m_parent->remove_child(n.get()); - m_children.push_back(n); - n->m_parent = this; - n->m_manager = m_manager; - YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node)); - n->added(this); - on_child_added(n.get()); + App::I.ui_task([&] + { + if (n->m_parent) + n->m_parent->remove_child(n.get()); + m_children.push_back(n); + n->m_parent = this; + n->m_manager = m_manager; + YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node)); + n->added(this); + on_child_added(n.get()); + }); } void Node::add_child(std::shared_ptr n, int index) { - if (n->m_parent) - n->m_parent->remove_child(n.get()); - m_children.insert(m_children.begin() + index, n); - n->m_parent = this; - n->m_manager = m_manager; - YGNodeInsertChild(y_node, n->y_node, index); - n->added(this); - on_child_added(n.get()); + App::I.ui_task([&] + { + if (n->m_parent) + n->m_parent->remove_child(n.get()); + m_children.insert(m_children.begin() + index, n); + n->m_parent = this; + n->m_manager = m_manager; + YGNodeInsertChild(y_node, n->y_node, index); + n->added(this); + on_child_added(n.get()); + }); } void Node::remove_from_parent() @@ -376,59 +393,74 @@ void Node::remove_child(Node* n) auto i = std::find_if(m_children.begin(), m_children.end(), [=](auto& ptr) { return ptr.get() == n; }); if (i != m_children.end()) { - n->removed(this); - n->m_parent = nullptr; - YGNodeRemoveChild(y_node, n->y_node); - on_child_removed(n); - m_children.erase(i); - if (child_mouse_focus == n) - child_mouse_focus = nullptr; + App::I.ui_task([&] + { + n->removed(this); + n->m_parent = nullptr; + YGNodeRemoveChild(y_node, n->y_node); + on_child_removed(n); + m_children.erase(i); + if (child_mouse_focus == n) + child_mouse_focus = nullptr; + }); } } void Node::remove_all_children() { - for (auto& n : m_children) + App::I.ui_task([&] { - n->removed(this); - n->m_parent = nullptr; - YGNodeRemoveChild(y_node, n->y_node); - on_child_removed(n.get()); - } - m_children.clear(); - child_mouse_focus = nullptr; + for (auto& n : m_children) + { + n->removed(this); + n->m_parent = nullptr; + YGNodeRemoveChild(y_node, n->y_node); + on_child_removed(n.get()); + } + m_children.clear(); + child_mouse_focus = nullptr; + }); } void Node::move_child(Node* n, int index) { - YGNodeRemoveChild(y_node, n->y_node); - YGNodeInsertChild(y_node, n->y_node, index); - auto it = std::find_if(m_children.begin(), m_children.end(), - [n](const std::shared_ptr& o) { return o.get() == n; }); - auto tmp = *it; // copy the ptr before removing it - m_children.erase(it); - m_children.insert(m_children.begin() + index, tmp); + App::I.ui_task([&] + { + YGNodeRemoveChild(y_node, n->y_node); + YGNodeInsertChild(y_node, n->y_node, index); + auto it = std::find_if(m_children.begin(), m_children.end(), + [n](const std::shared_ptr& o) { return o.get() == n; }); + auto tmp = *it; // copy the ptr before removing it + m_children.erase(it); + m_children.insert(m_children.begin() + index, tmp); + }); } void Node::move_child_front(Node* n) { - int count = YGNodeGetChildCount(y_node); - move_child(n, count - 1); + App::I.ui_task([&] + { + int count = YGNodeGetChildCount(y_node); + move_child(n, count - 1); + }); } void Node::move_child_offset(Node* n, int offset) { - int count = YGNodeGetChildCount(y_node); - for (int i = 0; i < count; i++) + App::I.ui_task([&] { - if (YGNodeGetChild(y_node, i) == n->y_node) + int count = YGNodeGetChildCount(y_node); + for (int i = 0; i < count; i++) { - int new_index = glm::clamp(i + offset, 0, count - 1); - YGNodeRemoveChild(y_node, n->y_node); - YGNodeInsertChild(y_node, n->y_node, new_index); - break; + if (YGNodeGetChild(y_node, i) == n->y_node) + { + int new_index = glm::clamp(i + offset, 0, count - 1); + YGNodeRemoveChild(y_node, n->y_node); + YGNodeInsertChild(y_node, n->y_node, new_index); + break; + } } - } + }); } int Node::get_child_index(Node* n) @@ -647,74 +679,88 @@ void Node::SetWidth(float value) { YGNodeStyleSetWidth(y_node, value); m_size.x = value; + app_redraw(); } void Node::SetWidthP(float value) { YGNodeStyleSetWidthPercent(y_node, value); + app_redraw(); } void Node::SetHeight(float value) { YGNodeStyleSetHeight(y_node, value); m_size.y = value; + app_redraw(); } void Node::SetHeightP(float value) { YGNodeStyleSetHeightPercent(y_node, value); + app_redraw(); } void Node::SetSize(float w, float h) { SetWidth(w); SetHeight(h); m_size = {w, h}; + app_redraw(); } void Node::SetSize(glm::vec2 value) { SetWidth(value.x); SetHeight(value.y); m_size = value; + app_redraw(); } void Node::SetMaxWidth(float value) { YGNodeStyleSetMaxWidth(y_node, value); + app_redraw(); } void Node::SetMaxWidthP(float value) { YGNodeStyleSetMaxWidthPercent(y_node, value); + app_redraw(); } void Node::SetMaxHeight(float value) { YGNodeStyleSetMaxHeight(y_node, value); + app_redraw(); } void Node::SetMaxHeightP(float value) { YGNodeStyleSetMaxHeightPercent(y_node, value); + app_redraw(); } void Node::SetMinWidth(float value) { YGNodeStyleSetMinWidth(y_node, value); + app_redraw(); } void Node::SetMinWidthP(float value) { YGNodeStyleSetMinWidthPercent(y_node, value); + app_redraw(); } void Node::SetMinHeight(float value) { YGNodeStyleSetMinHeight(y_node, value); + app_redraw(); } void Node::SetMinHeightP(float value) { YGNodeStyleSetMinHeightPercent(y_node, value); + app_redraw(); } void Node::SetPadding(float t, float r, float b, float l) @@ -723,6 +769,7 @@ void Node::SetPadding(float t, float r, float b, float l) YGNodeStyleSetPadding(y_node, YGEdgeRight, r); YGNodeStyleSetPadding(y_node, YGEdgeBottom, b); YGNodeStyleSetPadding(y_node, YGEdgeLeft, l); + app_redraw(); } glm::vec4 Node::GetPadding() const @@ -740,6 +787,7 @@ void Node::SetMargin(float t, float r, float b, float l) YGNodeStyleSetMargin(y_node, YGEdgeRight, r); YGNodeStyleSetMargin(y_node, YGEdgeBottom, b); YGNodeStyleSetMargin(y_node, YGEdgeLeft, l); + app_redraw(); } glm::vec4 Node::GetMargin() const @@ -755,6 +803,7 @@ void Node::SetPosition(const glm::vec2 pos) { SetPosition(pos.x, pos.y); m_pos = pos; + app_redraw(); } void Node::SetPosition(float l, float t) @@ -762,6 +811,7 @@ void Node::SetPosition(float l, float t) YGNodeStyleSetPosition(y_node, YGEdgeTop, t); YGNodeStyleSetPosition(y_node, YGEdgeLeft, l); m_pos = {l, t}; + app_redraw(); } void Node::SetPosition(float l, float t, float r, float b) @@ -770,79 +820,93 @@ void Node::SetPosition(float l, float t, float r, float b) YGNodeStyleSetPosition(y_node, YGEdgeRight, r); YGNodeStyleSetPosition(y_node, YGEdgeBottom, b); YGNodeStyleSetPosition(y_node, YGEdgeLeft, l); + app_redraw(); } void Node::SetFlexGrow(float value) { YGNodeStyleSetFlexGrow(y_node, value); + app_redraw(); } void Node::SetFlexShrink(float value) { YGNodeStyleSetFlexShrink(y_node, value); + app_redraw(); } void Node::SetFlexDir(YGFlexDirection value) { YGNodeStyleSetFlexDirection(y_node, value); + app_redraw(); } void Node::SetFlexWrap(YGWrap value) { YGNodeStyleSetFlexWrap(y_node, value); + app_redraw(); } void Node::SetJustify(YGJustify value) { YGNodeStyleSetJustifyContent(y_node, value); + app_redraw(); } void Node::SetAlign(YGAlign value) { YGNodeStyleSetAlignItems(y_node, value); + app_redraw(); } void Node::SetPositioning(YGPositionType value) { YGNodeStyleSetPositionType(y_node, value); + app_redraw(); } void Node::SetAspectRatio(float ar) { YGNodeStyleSetAspectRatio(y_node, ar); + app_redraw(); } void Node::SetRTL(YGDirection dir) { YGNodeStyleSetDirection(y_node, dir); + app_redraw(); } void Node::SetVisibility(bool visible) { - if (m_display && !visible) + App::I.ui_task([&] { - // hide - int idx = m_parent->get_child_index(this); - YGNodeRemoveChild(m_parent->y_node, y_node); - y_placeholder = YGNodeNew(); - YGNodeInsertChild(m_parent->y_node, y_placeholder, idx); - } - else if (!m_display && visible) - { - int count = YGNodeGetChildCount(m_parent->y_node); - for (int i = 0; i < count; i++) + if (m_display && !visible) { - if (YGNodeGetChild(m_parent->y_node, i) == y_placeholder) + // hide + int idx = m_parent->get_child_index(this); + YGNodeRemoveChild(m_parent->y_node, y_node); + y_placeholder = YGNodeNew(); + YGNodeInsertChild(m_parent->y_node, y_placeholder, idx); + } + else if (!m_display && visible) + { + int count = YGNodeGetChildCount(m_parent->y_node); + for (int i = 0; i < count; i++) { - YGNodeRemoveChild(m_parent->y_node, y_placeholder); - YGNodeInsertChild(m_parent->y_node, y_node, i); - YGNodeFree(y_placeholder); - y_placeholder = nullptr; - break; + if (YGNodeGetChild(m_parent->y_node, i) == y_placeholder) + { + YGNodeRemoveChild(m_parent->y_node, y_placeholder); + YGNodeInsertChild(m_parent->y_node, y_node, i); + YGNodeFree(y_placeholder); + y_placeholder = nullptr; + break; + } } } - } + }); m_display = visible; + app_redraw(); } void Node::ToggleVisibility() @@ -852,7 +916,7 @@ void Node::ToggleVisibility() glm::vec2 Node::GetPosition() { - return{ YGNodeLayoutGetLeft(y_node), YGNodeLayoutGetTop(y_node) }; + return { YGNodeLayoutGetLeft(y_node), YGNodeLayoutGetTop(y_node) }; } float Node::GetWidth() diff --git a/src/node_dialog_browse.cpp b/src/node_dialog_browse.cpp index 8dbeee9..bb58f68 100644 --- a/src/node_dialog_browse.cpp +++ b/src/node_dialog_browse.cpp @@ -139,7 +139,7 @@ void NodeDialogBrowse::init_list() auto node = new NodeDialogBrowseItem; node->m_manager = m_manager; node->init(); - node->m_text->set_text(f_name.c_str()); + node->m_text->set_text(f_name.substr(0, f_name.length() - strlen(".ppi")).c_str()); node->m_path = f_path; node->m_file_name = f_name; node->on_selected = [&](NodeDialogBrowseItem* target) { diff --git a/src/util.cpp b/src/util.cpp index dec3afa..b738f2e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -48,6 +48,16 @@ glm::vec4 rect_union(glm::vec4 a, glm::vec4 b) return o; } +float box_area(glm::vec4 b) +{ + return glm::compMul(box_size(b)); +} + +glm::vec2 box_size(glm::vec4 b) +{ + return zw(b) - xy(b); +} + // params and returns {min, max} form glm::vec4 box_union(glm::vec4 a, glm::vec4 b) { diff --git a/src/util.h b/src/util.h index a6c8fc0..cd08239 100644 --- a/src/util.h +++ b/src/util.h @@ -51,6 +51,9 @@ bool point_in_rect(const glm::vec2& point, const glm::vec4& rect); glm::vec4 rect_intersection(glm::vec4 a, glm::vec4 b); // params and returns {origin, size} form glm::vec4 rect_union(glm::vec4 a, glm::vec4 b); +// return the are of the box {min, max} +float box_area(glm::vec4 b); +glm::vec2 box_size(glm::vec4 b); // params and returns {min, max} form glm::vec4 box_union(glm::vec4 a, glm::vec4 b); // params and returns {min, max} form