Merge branch 'master'
This commit is contained in:
@@ -1483,6 +1483,9 @@ Here's a list of what's available in this release.
|
||||
<button-custom id="file-submenu-export-layers" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||
<text text="Separate Layers" grow="1" margin="0 0 0 5"/>
|
||||
</button-custom>
|
||||
<button-custom id="file-submenu-export-cube" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||
<text text="Cube Faces" grow="1" margin="0 0 0 5"/>
|
||||
</button-custom>
|
||||
<button-custom id="file-submenu-export-depth" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||
<text text="3D View + Depth" grow="1" margin="0 0 0 5"/>
|
||||
</button-custom>
|
||||
|
||||
@@ -495,7 +495,7 @@ bool App::update_ui_observer(Node *n)
|
||||
n->handle_on_screen(false, true);
|
||||
n->m_on_screen = true;
|
||||
}
|
||||
glm::ivec4 c = glm::vec4(box.x, (height / zoom - box.y - box.w), box.z, box.w) * zoom;
|
||||
glm::ivec4 c = glm::vec4(box.x - 1, (height / zoom - box.y - box.w - 1), box.z + 2, box.w + 2) * zoom;
|
||||
glScissor(floorf(c.x + off_x), floorf(c.y + off_y), ceilf(c.z), ceilf(c.w));
|
||||
n->draw();
|
||||
return true;
|
||||
@@ -532,7 +532,7 @@ void App::draw(float dt)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
glViewport(off_x, off_y, (GLsizei)width, (GLsizei)height);
|
||||
//glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
for (int i = 0; i < layout[main_id]->m_children.size(); i++)
|
||||
layout[main_id]->m_children[i]->watch(observer);
|
||||
//msgbox->watch(observer);
|
||||
|
||||
29
src/app.h
29
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<NodeMessageBox> message_box(const std::string& title, const std::string& text, bool cancel_button = false);
|
||||
|
||||
void rec_clear();
|
||||
void rec_loop();
|
||||
@@ -232,7 +232,7 @@ public:
|
||||
void dialog_export(std::string ext);
|
||||
void dialog_export_layers();
|
||||
void dialog_export_depth();
|
||||
void dialog_export_cubes();
|
||||
void dialog_export_cube_faces();
|
||||
void dialog_layer_rename();
|
||||
void dialog_resize();
|
||||
|
||||
@@ -243,7 +243,7 @@ public:
|
||||
void download(std::string url, std::string dest_filepath, std::function<void(float)> progress = nullptr);
|
||||
bool check_license();
|
||||
|
||||
std::shared_ptr<NodeProgressBar> show_progress(const std::string& title);
|
||||
std::shared_ptr<NodeProgressBar> show_progress(const std::string& title, int total = 0);
|
||||
|
||||
void brush_update(bool update_color, bool update_brush);
|
||||
void title_update();
|
||||
@@ -284,8 +284,8 @@ public:
|
||||
|
||||
// don't capture a reference to this ptr as the object may be destroyed
|
||||
// by the time the task is executed
|
||||
template<typename T, typename R = void>
|
||||
std::future<R> render_task_async(T task, bool unique = false)
|
||||
template<typename T>
|
||||
std::future<void> render_task_async(T task, bool unique = false)
|
||||
{
|
||||
AppTask pt(task);
|
||||
auto f = pt.get_future();
|
||||
@@ -308,8 +308,8 @@ public:
|
||||
return f;
|
||||
}
|
||||
|
||||
template<typename T, typename R = void>
|
||||
R render_task(T task)
|
||||
template<typename T>
|
||||
void render_task(T task)
|
||||
{
|
||||
AppTask pt(task);
|
||||
auto f = pt.get_future();
|
||||
@@ -325,7 +325,8 @@ public:
|
||||
}
|
||||
render_cv.notify_all();
|
||||
}
|
||||
return render_running ? f.get() : R();
|
||||
if (render_running)
|
||||
f.get();
|
||||
}
|
||||
|
||||
void render_sync()
|
||||
@@ -354,8 +355,8 @@ public:
|
||||
|
||||
// don't capture a reference to this ptr as the object may be destroyed
|
||||
// by the time the task is executed
|
||||
template<typename T, typename R = void>
|
||||
std::future<R> ui_task_async(T task, bool unique = false)
|
||||
template<typename T>
|
||||
std::future<void> ui_task_async(T task, bool unique = false)
|
||||
{
|
||||
AppTask pt(task);
|
||||
auto f = pt.get_future();
|
||||
@@ -378,8 +379,8 @@ public:
|
||||
return f;
|
||||
}
|
||||
|
||||
template<typename T, typename R = void>
|
||||
R ui_task(T task)
|
||||
template<typename T>
|
||||
void ui_task(T task)
|
||||
{
|
||||
AppTask pt(task);
|
||||
auto f = pt.get_future();
|
||||
@@ -395,7 +396,9 @@ public:
|
||||
}
|
||||
ui_cv.notify_all();
|
||||
}
|
||||
return ui_running ? f.get() : R();
|
||||
if (ui_running)
|
||||
f.get();
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
void ui_sync()
|
||||
|
||||
@@ -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<NodeProgressBar> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "oculus_vr.h"
|
||||
#endif
|
||||
|
||||
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title)
|
||||
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title, int total /*= 0*/)
|
||||
{
|
||||
auto pb = std::make_shared<NodeProgressBar>();
|
||||
pb->m_manager = &layout;
|
||||
@@ -22,18 +22,25 @@ std::shared_ptr<NodeProgressBar> 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<NodeMessageBox> App::message_box(const std::string &title, const std::string& text, bool cancel_button)
|
||||
{
|
||||
auto* m = layout[main_id]->add_child<NodeMessageBox>();
|
||||
auto m = std::make_shared<NodeMessageBox>();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -501,12 +508,20 @@ void App::dialog_resize()
|
||||
};
|
||||
}
|
||||
|
||||
void App::dialog_export_cubes()
|
||||
void App::dialog_export_cube_faces()
|
||||
{
|
||||
if (canvas)
|
||||
{
|
||||
canvas->m_canvas->export_cubes();
|
||||
}
|
||||
canvas->m_canvas->export_cube_faces(doc_name, [this] {
|
||||
#if defined(__IOS__)
|
||||
message_box("Export Cube Faces", "Image and depth exported to Files/PanoPainter");
|
||||
#elif defined(__OSX__)
|
||||
message_box("Export Cube Faces", "Image and depth exported to Pictures/PanoPainter folder");
|
||||
#elif defined(_WIN32)
|
||||
message_box("Export Cube Faces", "Image and depth exported to " + work_path);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void App::dialog_layer_rename()
|
||||
|
||||
@@ -636,6 +636,13 @@ void App::init_menu_file()
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
subpopup->find<NodeButtonCustom>("file-submenu-export-cube")->on_click = [this, subpopup, popup](Node*) {
|
||||
dialog_export_cube_faces();
|
||||
subpopup->mouse_release();
|
||||
subpopup->destroy();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
subpopup->find<NodeButtonCustom>("file-submenu-export-depth")->on_click = [this, subpopup, popup](Node*) {
|
||||
dialog_export_depth();
|
||||
subpopup->mouse_release();
|
||||
@@ -656,13 +663,7 @@ void App::init_menu_file()
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (auto b = popup->find<NodeButtonCustom>("file-export-cubes"))
|
||||
b->on_click = [this, popup](Node*) {
|
||||
dialog_export_cubes();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (auto b = popup->find<NodeButtonCustom>("file-cloud-upload"))
|
||||
if (auto b = popup->find<NodeButtonCustom>("file-cloud-upload"))
|
||||
b->on_click = [this, popup](Node*) {
|
||||
cloud_upload();
|
||||
popup->mouse_release();
|
||||
|
||||
196
src/canvas.cpp
196
src/canvas.cpp
@@ -1921,183 +1921,69 @@ void Canvas::export_layers(std::string file_name, std::function<void()> on_compl
|
||||
|
||||
void Canvas::export_layers_thread(std::string file_name)
|
||||
{
|
||||
std::shared_ptr<NodeProgressBar> pb;
|
||||
if (App::I->layout.m_loaded)
|
||||
auto pb = App::I->show_progress("Export Layers", m_layers.size());
|
||||
for (int i = 0; i < m_layers.size(); i++)
|
||||
{
|
||||
pb = std::make_shared<NodeProgressBar>();
|
||||
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);
|
||||
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();
|
||||
}
|
||||
int progress = 0;
|
||||
int total = (int)(m_layers.size() + 1) * 6;
|
||||
pb->destroy();
|
||||
}
|
||||
|
||||
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([&]
|
||||
void Canvas::export_cube_faces(std::string file_name, std::function<void()> on_complete)
|
||||
{
|
||||
if (App::I->check_license())
|
||||
{
|
||||
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();
|
||||
std::thread t([=] {
|
||||
BT_SetTerminate();
|
||||
export_cube_faces_thread(file_name);
|
||||
if (on_complete)
|
||||
on_complete();
|
||||
});
|
||||
|
||||
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<uint8_t[]>(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();
|
||||
t.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::export_cubes()
|
||||
void Canvas::export_cube_faces_thread(std::string file_name)
|
||||
{
|
||||
if (!App::I->check_license())
|
||||
return;
|
||||
#ifdef __OBJC__
|
||||
NSMutableArray* files = [NSMutableArray array];
|
||||
#endif
|
||||
std::array<std::string, 6> names {
|
||||
"pz", "px", "nz", "nx",
|
||||
"py", "ny"
|
||||
};
|
||||
const int stride = m_width * 4;
|
||||
auto buffer = std::make_unique<uint8_t[]>(m_width * m_height * 4);
|
||||
auto flipped = std::make_unique<uint8_t[]>(m_width * m_height * 4);
|
||||
for (int layer = 0; layer < m_layers.size(); layer++)
|
||||
static std::array<const char*, 6> plane_names{ "front", "right", "back", "left", "top", "bottom" };
|
||||
|
||||
auto pb = App::I->show_progress("Export Cube Faces", 7);
|
||||
|
||||
App::I->render_task([this] {
|
||||
draw_merge(false);
|
||||
});
|
||||
pb->increment();
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
for (int plane = 0; plane < 6; plane++)
|
||||
{
|
||||
auto& l = m_layers[layer];
|
||||
l->m_rtt[plane].bindFramebuffer();
|
||||
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
||||
l->m_rtt[plane].unbindFramebuffer();
|
||||
|
||||
if (plane < 4)
|
||||
{
|
||||
for (int y = 0; y < m_height; y++)
|
||||
{
|
||||
int y_rev = m_height - y - 1;
|
||||
std::copy_n(buffer.get() + y * stride, stride, flipped.get() + y_rev * stride);
|
||||
}
|
||||
std::swap(buffer, flipped);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int y = 0; y < m_height; y++)
|
||||
{
|
||||
auto src = (glm::u8vec4*)(buffer.get() + y * stride);
|
||||
auto dst = (glm::u8vec4*)(flipped.get() + y * stride);
|
||||
for (int x = 0; x < m_width; x++)
|
||||
{
|
||||
int x_rev = m_width - x - 1;
|
||||
dst[x_rev] = src[x];
|
||||
}
|
||||
//std::copy_backward(src + stride, src, dst + stride);
|
||||
}
|
||||
std::swap(buffer, flipped);
|
||||
}
|
||||
|
||||
static char name[128];
|
||||
sprintf(name, "%s-%02d-%d.png", App::I->work_path.c_str(), layer, plane);
|
||||
int ret = stbi_write_png(name, m_width, m_height, 4, buffer.get(), 0);
|
||||
|
||||
Image face = m_layers_merge.m_rtt[i].get_image();
|
||||
std::string path = fmt::format("{}/{}-{}.png", App::I->work_path, file_name, plane_names[i]);
|
||||
face.save_png(path);
|
||||
pb->increment();
|
||||
|
||||
#ifdef __IOS__
|
||||
save_image_library(name);
|
||||
save_image_library(path);
|
||||
#endif
|
||||
#ifdef __OBJC__
|
||||
[files addObject:[NSString stringWithUTF8String : name]];
|
||||
[files addObject : [NSString stringWithUTF8String:path.c_str()] ];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pb->destroy();
|
||||
|
||||
#ifdef __OBJC__
|
||||
static char name[128];
|
||||
sprintf(name, "%s.zip", App::I->work_path.c_str());
|
||||
auto zip_path = [NSString stringWithUTF8String : name];
|
||||
auto zip_path = [NSString stringWithUTF8String:name];
|
||||
//[SSZipArchive createZipFileAtPath:zip_path withFilesAtPaths:files];
|
||||
for (NSString* f : files)
|
||||
[[NSFileManager defaultManager] removeItemAtPath:f error:nil];
|
||||
//for (NSString* f : files)
|
||||
// [[NSFileManager defaultManager] removeItemAtPath:f error:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -204,10 +204,11 @@ public:
|
||||
void export_equirectangular(std::string file_path, std::function<void()> on_complete = nullptr);
|
||||
void export_equirectangular_thread(std::string file_path);
|
||||
void export_layers(std::string file_name, std::function<void()> on_complete = nullptr);
|
||||
void export_layers_thread(std::string file_name);
|
||||
void export_layers_thread(std::string file_name);
|
||||
void export_depth(std::string file_name, std::function<void()> on_complete = nullptr);
|
||||
void export_depth_thread(std::string file_name);
|
||||
void export_cubes();
|
||||
void export_cube_faces(std::string file_name, std::function<void()> on_complete);
|
||||
void export_cube_faces_thread(std::string file_name);
|
||||
void project_save(std::function<void(bool)> on_complete = nullptr);
|
||||
void project_save(std::string file_path, std::function<void(bool)> on_complete = nullptr);
|
||||
bool project_save_thread(std::string file_path, bool show_progress);
|
||||
|
||||
28
src/node.cpp
28
src/node.cpp
@@ -40,7 +40,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<bool(Node*)> observer)
|
||||
@@ -82,11 +82,11 @@ kEventResult Node::on_event(Event* e)
|
||||
{
|
||||
kEventResult ret = kEventResult::Available;
|
||||
|
||||
if (current_mouse_capture && current_mouse_capture != this)
|
||||
if (current_mouse_capture && current_mouse_capture.get() != this)
|
||||
{
|
||||
if (e->m_cat == kEventCategory::MouseEvent &&
|
||||
child_mouse_focus != current_mouse_capture &&
|
||||
is_child(current_mouse_capture))
|
||||
is_child(current_mouse_capture.get()))
|
||||
{
|
||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||
if (child_mouse_focus)
|
||||
@@ -115,7 +115,7 @@ kEventResult Node::on_event(Event* e)
|
||||
}
|
||||
|
||||
skip_children |= (e->m_cat == kEventCategory::MouseEvent || e->m_cat == kEventCategory::GestureEvent) &&
|
||||
(m_mouse_captured) && (root()->current_mouse_capture == this) && m_capture_children; // <-- THIS IS WRONG "!m_capture_children" is correct, but it breaks everything if changed
|
||||
(m_mouse_captured) && (root()->current_mouse_capture.get() == this) && m_capture_children; // <-- THIS IS WRONG "!m_capture_children" is correct, but it breaks everything if changed
|
||||
|
||||
if (!m_display || glm::any(glm::lessThanEqual(zw(m_clip), { 0, 0 })))
|
||||
return kEventResult::Available;
|
||||
@@ -134,7 +134,7 @@ kEventResult Node::on_event(Event* e)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e->m_cat == kEventCategory::MouseEvent && child_mouse_focus != it->get())
|
||||
if (e->m_cat == kEventCategory::MouseEvent && child_mouse_focus.get() != it->get())
|
||||
{
|
||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||
if (child_mouse_focus)
|
||||
@@ -147,7 +147,7 @@ kEventResult Node::on_event(Event* e)
|
||||
MouseEvent e2 = *me;
|
||||
e2.m_type = kEventType::MouseFocus;
|
||||
(*it)->handle_event(&e2);
|
||||
child_mouse_focus = it->get();
|
||||
child_mouse_focus = *it;
|
||||
child_mouse_focus->m_mouse_focus = true;
|
||||
}
|
||||
ret = kEventResult::Consumed;
|
||||
@@ -401,7 +401,7 @@ void Node::remove_child(Node* n)
|
||||
YGNodeRemoveChild(y_node, n->y_node);
|
||||
on_child_removed(n);
|
||||
m_children.erase(i);
|
||||
if (child_mouse_focus == n)
|
||||
if (child_mouse_focus.get() == n)
|
||||
child_mouse_focus = nullptr;
|
||||
});
|
||||
}
|
||||
@@ -542,7 +542,8 @@ void Node::mouse_capture()
|
||||
auto& s = root()->m_capture_stack;
|
||||
|
||||
// already owner of capture
|
||||
if (c == this || std::find(s.begin(), s.end(), this) != s.end())
|
||||
if (c.get() == this || std::find_if(s.begin(), s.end(),
|
||||
[this](const auto& a) { return a.get() == this; }) != s.end())
|
||||
return;
|
||||
|
||||
if (c)
|
||||
@@ -570,7 +571,7 @@ void Node::mouse_capture()
|
||||
}
|
||||
|
||||
// make current
|
||||
c = this;
|
||||
c = shared_from_this();
|
||||
m_mouse_captured = true;
|
||||
}
|
||||
|
||||
@@ -582,8 +583,9 @@ void Node::mouse_release()
|
||||
auto& c = root()->current_mouse_capture;
|
||||
auto& s = root()->m_capture_stack;
|
||||
|
||||
s.erase(std::remove(s.begin(), s.end(), this), s.end());
|
||||
if (c == this)
|
||||
s.erase(std::remove_if(s.begin(), s.end(),
|
||||
[this](const auto& a) { return a.get() == this; }), s.end());
|
||||
if (c.get() == this)
|
||||
{
|
||||
if (s.empty())
|
||||
{
|
||||
@@ -604,7 +606,7 @@ void Node::key_capture()
|
||||
if (!m_parent)
|
||||
return;
|
||||
|
||||
root()->current_key_capture = this;
|
||||
root()->current_key_capture = shared_from_this();
|
||||
m_key_captured = true;
|
||||
}
|
||||
|
||||
@@ -1376,8 +1378,6 @@ void Node::clone_copy(Node* dest) const
|
||||
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
|
||||
|
||||
@@ -103,9 +103,9 @@ public:
|
||||
uint16_t m_nodeID;
|
||||
std::string m_nodeID_s;
|
||||
std::vector<std::shared_ptr<Node>> m_children;
|
||||
Node* current_mouse_capture = nullptr;
|
||||
Node* current_key_capture = nullptr;
|
||||
Node* child_mouse_focus = nullptr;
|
||||
std::shared_ptr<Node> current_mouse_capture = nullptr;
|
||||
std::shared_ptr<Node> current_key_capture = nullptr;
|
||||
std::shared_ptr<Node> child_mouse_focus = nullptr;
|
||||
bool m_mouse_captured = false;
|
||||
bool m_key_captured = false;
|
||||
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
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<Node*> m_capture_stack;
|
||||
std::vector<std::shared_ptr<Node>> m_capture_stack;
|
||||
|
||||
bool m_mouse_ignore = true;
|
||||
float m_zoom = 1.f;
|
||||
|
||||
@@ -63,6 +63,14 @@ void NodeCanvas::clear_context()
|
||||
|
||||
void NodeCanvas::draw()
|
||||
{
|
||||
// sanity checks
|
||||
float zoom = root()->m_zoom;
|
||||
if (zoom == 0.f)
|
||||
zoom = 1.f;
|
||||
auto box = m_clip * zoom;
|
||||
if (box.z == 0 || box.w == 0)
|
||||
return;
|
||||
|
||||
GLint vp[4];
|
||||
GLfloat cc[4];
|
||||
glGetIntegerv(GL_VIEWPORT, vp);
|
||||
@@ -73,8 +81,6 @@ void NodeCanvas::draw()
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
float zoom = root()->m_zoom;
|
||||
auto box = m_clip * zoom;
|
||||
glm::ivec4 c = (glm::ivec4)glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
|
||||
|
||||
//m_canvas->m_cam_rot = m_pan * 0.003f;
|
||||
|
||||
@@ -53,10 +53,10 @@ void NodeComboBox::loaded()
|
||||
m_current_index = index;
|
||||
m_selected_child_index = popup->get_child_index(target);
|
||||
m_text->set_text(m_items[index].c_str());
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
if (on_select)
|
||||
on_select(btn, index);
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -20,5 +20,17 @@ void NodeProgressBar::init()
|
||||
btn_cancel->on_click = [&](Node*) { destroy(); };
|
||||
m_progress = find<NodeBorder>("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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
16
src/rtt.cpp
16
src/rtt.cpp
@@ -274,7 +274,7 @@ void RTT::clear_mask(glm::bool4 mask, glm::vec4 color)
|
||||
glColorMask(old_mask[0], old_mask[1], old_mask[2], old_mask[3]);
|
||||
}
|
||||
|
||||
glm::ivec4 RTT::calc_bounds()
|
||||
glm::ivec4 RTT::calc_bounds() const noexcept
|
||||
{
|
||||
auto data = std::unique_ptr<glm::u8vec4[]>(reinterpret_cast<glm::u8vec4*>(readTextureData()));
|
||||
glm::ivec2 bbmin(w, h);
|
||||
@@ -293,7 +293,7 @@ glm::ivec4 RTT::calc_bounds()
|
||||
return { bbmin, bbmax };
|
||||
}
|
||||
|
||||
uint8_t* RTT::readTextureData(uint8_t* buffer)
|
||||
uint8_t* RTT::readTextureData(uint8_t* buffer) const noexcept
|
||||
{
|
||||
if (!buffer)
|
||||
buffer = createBuffer();
|
||||
@@ -308,7 +308,7 @@ uint8_t* RTT::readTextureData(uint8_t* buffer)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
float* RTT::readTextureDataFloat(float* buffer)
|
||||
float* RTT::readTextureDataFloat(float* buffer) const noexcept
|
||||
{
|
||||
if (!buffer)
|
||||
buffer = createBufferFloat();
|
||||
@@ -323,12 +323,12 @@ float* RTT::readTextureDataFloat(float* buffer)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint8_t* RTT::createBuffer()
|
||||
uint8_t* RTT::createBuffer() const noexcept
|
||||
{
|
||||
return new uint8_t[w * h * 4];
|
||||
}
|
||||
|
||||
float * RTT::createBufferFloat()
|
||||
float * RTT::createBufferFloat() const noexcept
|
||||
{
|
||||
return new float[w * h * 4];
|
||||
}
|
||||
@@ -345,4 +345,10 @@ void RTT::unbindTexture()
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
Image RTT::get_image() const noexcept
|
||||
{
|
||||
Image ret;
|
||||
ret.create(w, h, readTextureData());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
26
src/rtt.h
26
src/rtt.h
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "image.h"
|
||||
|
||||
class RTT
|
||||
{
|
||||
@@ -28,20 +29,21 @@ public:
|
||||
bool recreate() { return create(w, h); }
|
||||
void clear(glm::vec4 color = glm::vec4(0));
|
||||
void clear_mask(glm::bool4 mask, glm::vec4 color = glm::vec4(0));
|
||||
glm::ivec4 calc_bounds();
|
||||
uint8_t* readTextureData(uint8_t* buffer = nullptr);
|
||||
float* readTextureDataFloat(float* buffer = nullptr);
|
||||
uint8_t* createBuffer();
|
||||
float* createBufferFloat();
|
||||
glm::ivec4 calc_bounds() const noexcept;
|
||||
uint8_t* readTextureData(uint8_t* buffer = nullptr) const noexcept;
|
||||
float* readTextureDataFloat(float* buffer = nullptr) const noexcept;
|
||||
uint8_t* createBuffer() const noexcept;
|
||||
float* createBufferFloat() const noexcept;
|
||||
void bindFramebuffer();
|
||||
void unbindFramebuffer();
|
||||
void bindTexture();
|
||||
void unbindTexture();
|
||||
GLuint getTextureID() const { return texID; }
|
||||
int getWidth() const { return w; }
|
||||
int getHeight() const { return h; }
|
||||
glm::ivec2 getSize() const { return { w, h }; }
|
||||
int bytes() const { return w * h * 4; }
|
||||
int stride() const { return w * 4; }
|
||||
GLuint getFBO() const { return fboID; }
|
||||
GLuint getTextureID() const noexcept { return texID; }
|
||||
int getWidth() const noexcept { return w; }
|
||||
int getHeight() const noexcept { return h; }
|
||||
glm::ivec2 getSize() const noexcept { return { w, h }; }
|
||||
int bytes() const noexcept { return w * h * 4; }
|
||||
int stride() const noexcept { return w * 4; }
|
||||
GLuint getFBO() const noexcept { return fboID; }
|
||||
Image get_image() const noexcept;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user