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:
@@ -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"/>
|
||||
|
||||
24
src/app.cpp
24
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<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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
55
src/main.cpp
55
src/main.cpp
@@ -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)
|
||||
{
|
||||
|
||||
256
src/node.cpp
256
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<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()
|
||||
|
||||
@@ -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) {
|
||||
|
||||
10
src/util.cpp
10
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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user