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

This commit is contained in:
2019-07-10 21:08:14 +02:00
parent 4cbf0c47b4
commit 48c39c4ef2
10 changed files with 293 additions and 131 deletions

View File

@@ -919,8 +919,11 @@
<!-- DIALOG BROWSE -->
<layout id="dialog-browse-item">
<border dir="col" color=".4 .4 .4 .8" pad="4" height="120" width="100" margin="1 1 1 1" grow="1" align="center">
<image-texture id="thumb-tex" width="100%" grow="1" height="1" aspect-ratio="1"/>
<text id="title" text="File Name" margin="5 0 0 0"/>
<image-texture id="thumb-tex" width="100%" grow="1" height="1" aspect-ratio="1">
<border positioning="absolute" color="0 0 0 .5" pad="2">
<text id="title" text="File Name" margin="5 0 0 0" text-wrap-width="90"/>
</border>
</image-texture>
</border>
</layout>
<layout id="dialog-browse">
@@ -1581,12 +1584,10 @@ Here's a list of what's available in this release.
<icon icon="bug" width="20"/>
<text id="menu-label" text="What's new?" margin="0 0 0 5"/>
</button-custom>
<!--
<button-custom id="about-crash" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="bug" width="20"/>
<text id="menu-label" text="Induce crash" margin="0 0 0 5"/>
</button-custom>
-->
<button-custom id="about-perf" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="bug" width="20"/>
<text id="menu-label" text="Performance test" margin="0 0 0 5"/>

View File

@@ -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<std::mutex> 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<float>(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);

View File

@@ -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<std::chrono::milliseconds>(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<std::chrono::milliseconds>(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();

View File

@@ -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<Layer>();
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<glm::vec4, 6> * dirty_box /*= nullptr*/, std::array<bool, 6> * 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];

View File

@@ -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<uint8_t[]>(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);
}
}

View File

@@ -18,6 +18,10 @@
#include "abr.h"
#include "settings.h"
#include <iomanip>
#include <ctime>
#include <sstream>
#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<kKey, int> 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<std::mutex> lock(main_task_mutex);
main_tasklist.emplace_back([] {
SetWindowText(hWnd, title_fps);
});
}
void win32_show_cursor(bool visible)
{
std::lock_guard<std::mutex> 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)
{

View File

@@ -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<bool(Node*)> 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<Node*>(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<Node*>(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<Node> 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<Node> 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<Node>& 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<Node>& 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<int>(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<int>(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()

View File

@@ -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) {

View File

@@ -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)
{

View File

@@ -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