diff --git a/src/app.cpp b/src/app.cpp index 596ece9..15cc3d9 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -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); diff --git a/src/app.h b/src/app.h index c8bd09a..c06dd70 100644 --- a/src/app.h +++ b/src/app.h @@ -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 - std::future render_task_async(T task, bool unique = false) + template + std::future render_task_async(T task, bool unique = false) { AppTask pt(task); auto f = pt.get_future(); @@ -308,8 +308,8 @@ public: return f; } - template - R render_task(T task) + template + 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 - std::future ui_task_async(T task, bool unique = false) + template + std::future ui_task_async(T task, bool unique = false) { AppTask pt(task); auto f = pt.get_future(); @@ -378,8 +379,8 @@ public: return f; } - template - R ui_task(T task) + template + 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(), redraw = true : R(); + if (ui_running) + f.get(); + redraw = true; } void ui_sync() diff --git a/src/canvas.cpp b/src/canvas.cpp index 54435bc..a85a0b2 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -1968,7 +1968,7 @@ void Canvas::export_cube_faces_thread(std::string file_name) pb->increment(); #ifdef __IOS__ - save_image_library(name); + save_image_library(path); #endif #ifdef __OBJC__ [files addObject : [NSString stringWithUTF8String:path.c_str()] ]; @@ -1980,10 +1980,10 @@ void Canvas::export_cube_faces_thread(std::string file_name) #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 } diff --git a/src/node.cpp b/src/node.cpp index e96a6ca..c14c8d9 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -58,13 +58,13 @@ void Node::watch(std::function observer) void Node::destroy() { - auto children_copy = m_children; - for (auto c : children_copy) - c->destroy(); - mouse_release(); - key_release(); - remove_from_parent(); - app_redraw(); + App::I->ui_task([&] + { + mouse_release(); + key_release(); + remove_all_children(); + remove_from_parent(); + }); } Node* Node::root() @@ -79,11 +79,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(e); if (child_mouse_focus) @@ -112,7 +112,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; @@ -131,7 +131,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(e); if (child_mouse_focus) @@ -144,7 +144,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; @@ -398,7 +398,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; }); } @@ -539,7 +539,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) @@ -567,7 +568,7 @@ void Node::mouse_capture() } // make current - c = this; + c = shared_from_this(); m_mouse_captured = true; } @@ -579,8 +580,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()) { @@ -601,7 +603,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; } diff --git a/src/node.h b/src/node.h index 720a086..652a601 100644 --- a/src/node.h +++ b/src/node.h @@ -103,9 +103,9 @@ public: uint16_t m_nodeID; std::string m_nodeID_s; std::vector> m_children; - Node* current_mouse_capture = nullptr; - Node* current_key_capture = nullptr; - Node* child_mouse_focus = nullptr; + std::shared_ptr current_mouse_capture = nullptr; + std::shared_ptr current_key_capture = nullptr; + std::shared_ptr child_mouse_focus = nullptr; bool m_mouse_captured = false; bool m_key_captured = false; @@ -116,7 +116,7 @@ public: bool m_flood_events = false; bool m_force_mouse_capture = false; bool m_capture_children = true; // wether to capture children events when xx_capture() is used - std::vector m_capture_stack; + std::vector> m_capture_stack; bool m_mouse_ignore = true; float m_zoom = 1.f; diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index b24bb6a..a21d322 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -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; diff --git a/src/node_combobox.cpp b/src/node_combobox.cpp index 2240f27..3c742ea 100644 --- a/src/node_combobox.cpp +++ b/src/node_combobox.cpp @@ -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(); }; } }