diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 18053dcd6..da3042779 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -69,7 +69,6 @@ public: enum EState { Off, - Hover, On, Num_States }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp index c69d64134..9cd2ab6bb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp @@ -44,12 +44,12 @@ public: Vec3d get_flattening_normal() const; protected: - virtual bool on_init(); - virtual std::string on_get_name() const; - virtual bool on_is_activable() const; - virtual void on_start_dragging(); - virtual void on_render() const; - virtual void on_render_for_picking() const; + virtual bool on_init() override; + virtual std::string on_get_name() const override; + virtual bool on_is_activable() const override; + virtual void on_start_dragging() override; + virtual void on_render() const override; + virtual void on_render_for_picking() const override; virtual void on_set_state() override; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index 8733c9a11..c856e5465 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -87,16 +87,12 @@ protected: virtual void on_set_state() { for (GLGizmoRotate& g : m_gizmos) - { g.set_state(m_state); - } } virtual void on_set_hover_id() { for (int i = 0; i < 3; ++i) - { m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1); - } } virtual void on_enable_grabber(unsigned int id) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 3f91a3556..25c1d4d42 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -12,6 +12,7 @@ #include "slic3r/GUI/GUI.hpp" #include "slic3r/GUI/GUI_ObjectSettings.hpp" #include "slic3r/GUI/GUI_ObjectList.hpp" +#include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/PresetBundle.hpp" #include "libslic3r/SLAPrint.hpp" #include "libslic3r/Tesselate.hpp" @@ -1099,9 +1100,6 @@ std::string GLGizmoSlaSupports::on_get_name() const void GLGizmoSlaSupports::on_set_state() { - if (m_state == Hover) - return; - // m_model_object pointer can be invalid (for instance because of undo/redo action), // we should recover it from the object id m_model_object = nullptr; @@ -1112,6 +1110,11 @@ void GLGizmoSlaSupports::on_set_state() } } + if (m_state == m_old_state) + return; + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo on/off"))); + if (m_state == On && m_old_state != On) { // the gizmo was just turned on Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned on"))); if (is_mesh_update_necessary()) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 49aad0dd2..787d220da 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -157,6 +157,7 @@ private: protected: void on_set_state() override; void on_set_hover_id() override + { if (! m_editing_mode || (int)m_editing_cache.size() <= m_hover_id) m_hover_id = -1; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 1528a4bcb..00ca9ee05 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -29,9 +29,49 @@ GLGizmosManager::GLGizmosManager(GLCanvas3D& parent) { } -GLGizmosManager::~GLGizmosManager() +std::vector GLGizmosManager::get_selectable_idxs() const { - reset(); + std::vector out; + for (size_t i=0; iis_selectable()) + out.push_back(i); + return out; +} + +std::vector GLGizmosManager::get_activable_idxs() const +{ + std::vector out; + for (size_t i=0; iis_activable()) + out.push_back(i); + return out; +} + +size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const +{ + if (! m_enabled) + return Undefined; + + float cnv_h = (float)m_parent.get_canvas_size().get_height(); + float height = get_total_overlay_height(); + float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; + float scaled_border = m_overlay_border * m_overlay_scale; + float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; + float scaled_stride_y = scaled_icons_size + scaled_gap_y; + float top_y = 0.5f * (cnv_h - height) + scaled_border; + + // is mouse horizontally in the area? + if ((scaled_border <= (float)mouse_pos(0) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size))) { + // which icon is it on? + size_t from_top = (size_t)((float)mouse_pos(1) - top_y)/scaled_stride_y; + // is it really on the icon or already past the border? + if ((float)mouse_pos(1) <= top_y + from_top*scaled_stride_y + scaled_icons_size) { + std::vector selectable = get_selectable_idxs(); + if (from_top < selectable.size()) + return selectable[from_top]; + } + } + return Undefined; } bool GLGizmosManager::init() @@ -45,77 +85,25 @@ bool GLGizmosManager::init() if (!m_background_texture.metadata.filename.empty()) { if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false, GLTexture::SingleThreaded, false)) - { - reset(); + return false; + } + + m_gizmos.emplace_back(new GLGizmoMove3D(m_parent, "move.svg", 0)); + m_gizmos.emplace_back(new GLGizmoScale3D(m_parent, "scale.svg", 1)); + m_gizmos.emplace_back(new GLGizmoRotate3D(m_parent, "rotate.svg", 2)); + m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "place.svg", 3)); + m_gizmos.emplace_back(new GLGizmoCut(m_parent, "cut.svg", 4)); + m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 5)); + + for (auto& gizmo : m_gizmos) { + if (! gizmo->init()) { + m_gizmos.clear(); return false; } } - GLGizmoBase* gizmo = new GLGizmoMove3D(m_parent, "move.svg", 0); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) - return false; - - m_gizmos.insert(GizmosMap::value_type(Move, gizmo)); - - gizmo = new GLGizmoScale3D(m_parent, "scale.svg", 1); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) - return false; - - m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); - - gizmo = new GLGizmoRotate3D(m_parent, "rotate.svg", 2); - if (gizmo == nullptr) - { - reset(); - return false; - } - - if (!gizmo->init()) - { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo)); - - gizmo = new GLGizmoFlatten(m_parent, "place.svg", 3); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); - - gizmo = new GLGizmoCut(m_parent, "cut.svg", 4); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Cut, gizmo)); - - gizmo = new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 5); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo)); + m_current = Undefined; + m_hover = Undefined; return true; } @@ -140,65 +128,39 @@ void GLGizmosManager::set_overlay_scale(float scale) void GLGizmosManager::refresh_on_off_state() { - if (m_serializing) + if (m_serializing || m_current == Undefined || m_gizmos.empty()) return; - GizmosMap::iterator it = m_gizmos.find(m_current); - if ((it != m_gizmos.end()) && (it->second != nullptr)) - { - if (!it->second->is_activable()) - { - it->second->set_state(GLGizmoBase::Off); - m_current = Undefined; - } - } + if (m_current != Undefined && ! m_gizmos[m_current]->is_activable()) + activate_gizmo(Undefined); } void GLGizmosManager::reset_all_states() { - if (!m_enabled) + if (! m_enabled || m_serializing) return; - if (m_serializing) - return; - - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if (it->second != nullptr) - { - it->second->set_state(GLGizmoBase::Off); - it->second->set_hover_id(-1); - } - } - - m_current = Undefined; + activate_gizmo(Undefined); + m_hover = Undefined; } void GLGizmosManager::set_hover_id(int id) { - if (!m_enabled) + if (!m_enabled || m_current == Undefined) return; - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On)) - it->second->set_hover_id(id); - } + m_gizmos[m_current]->set_hover_id(id); } void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) { - if (!m_enabled) + if (!m_enabled || type == Undefined || m_gizmos.empty()) return; - GizmosMap::const_iterator it = m_gizmos.find(type); - if (it != m_gizmos.end()) - { - if (enable) - it->second->enable_grabber(id); - else - it->second->disable_grabber(id); - } + if (enable) + m_gizmos[type]->enable_grabber(id); + else + m_gizmos[type]->disable_grabber(id); } void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos) @@ -269,8 +231,9 @@ bool GLGizmosManager::is_running() const if (!m_enabled) return false; - GLGizmoBase* curr = get_current(); - return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; + //GLGizmoBase* curr = get_current(); + //return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; + return m_current != Undefined; } bool GLGizmosManager::handle_shortcut(int key) @@ -283,43 +246,12 @@ bool GLGizmosManager::handle_shortcut(int key) bool handled = false; - for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; + for (size_t idx : get_selectable_idxs()) { + int it_key = m_gizmos[idx]->get_shortcut_key(); - int it_key = it->second->get_shortcut_key(); - - if (it->second->is_activable() && ((it_key == key - 64) || (it_key == key - 96))) - { - if ((it->second->get_state() == GLGizmoBase::On)) - { - it->second->set_state(GLGizmoBase::Off); - if (it->second->get_state() == GLGizmoBase::Off) { - m_current = Undefined; - } + if (m_gizmos[idx]->is_activable() && ((it_key == key - 64) || (it_key == key - 96))) { + activate_gizmo(m_current == idx ? Undefined : (EType)idx); handled = true; - } - else if ((it->second->get_state() == GLGizmoBase::Off)) - { - // Before turning anything on, turn everything else off to see if - // nobody refuses. Only then activate the gizmo. - bool can_open = true; - for (GizmosMap::iterator i = m_gizmos.begin(); i != m_gizmos.end(); ++i) { - if (i->first != it->first) { - if (m_current == i->first && i->second->get_state() != GLGizmoBase::Off ) { - i->second->set_state(GLGizmoBase::Off); - if (i->second->get_state() != GLGizmoBase::Off) - can_open = false; - } - } - } - if (can_open) { - it->second->set_state(GLGizmoBase::On); - m_current = it->first; - } - handled = true; - } } } @@ -328,31 +260,25 @@ bool GLGizmosManager::handle_shortcut(int key) bool GLGizmosManager::is_dragging() const { - if (!m_enabled) + if (! m_enabled || m_current == Undefined) return false; - GLGizmoBase* curr = get_current(); - return (curr != nullptr) ? curr->is_dragging() : false; + return m_gizmos[m_current]->is_dragging(); } void GLGizmosManager::start_dragging() { - if (!m_enabled) + if (! m_enabled || m_current == Undefined) return; - - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->start_dragging(); + m_gizmos[m_current]->start_dragging(); } void GLGizmosManager::stop_dragging() { - if (!m_enabled) + if (! m_enabled || m_current == Undefined) return; - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->stop_dragging(); + m_gizmos[m_current]->stop_dragging(); } Vec3d GLGizmosManager::get_displacement() const @@ -360,8 +286,7 @@ Vec3d GLGizmosManager::get_displacement() const if (!m_enabled) return Vec3d::Zero(); - GizmosMap::const_iterator it = m_gizmos.find(Move); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_displacement() : Vec3d::Zero(); + return dynamic_cast(m_gizmos[Move].get())->get_displacement(); } Vec3d GLGizmosManager::get_scale() const @@ -369,126 +294,101 @@ Vec3d GLGizmosManager::get_scale() const if (!m_enabled) return Vec3d::Ones(); - GizmosMap::const_iterator it = m_gizmos.find(Scale); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_scale() : Vec3d::Ones(); + return dynamic_cast(m_gizmos[Scale].get())->get_scale(); } void GLGizmosManager::set_scale(const Vec3d& scale) { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return; - GizmosMap::const_iterator it = m_gizmos.find(Scale); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_scale(scale); + dynamic_cast(m_gizmos[Scale].get())->set_scale(scale); } Vec3d GLGizmosManager::get_scale_offset() const { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return Vec3d::Zero(); - GizmosMap::const_iterator it = m_gizmos.find(Scale); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_offset() : Vec3d::Zero(); + return dynamic_cast(m_gizmos[Scale].get())->get_offset(); } Vec3d GLGizmosManager::get_rotation() const { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return Vec3d::Zero(); - GizmosMap::const_iterator it = m_gizmos.find(Rotate); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_rotation() : Vec3d::Zero(); + return dynamic_cast(m_gizmos[Rotate].get())->get_rotation(); } void GLGizmosManager::set_rotation(const Vec3d& rotation) { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return; - - GizmosMap::const_iterator it = m_gizmos.find(Rotate); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_rotation(rotation); + dynamic_cast(m_gizmos[Rotate].get())->set_rotation(rotation); } Vec3d GLGizmosManager::get_flattening_normal() const { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return Vec3d::Zero(); - GizmosMap::const_iterator it = m_gizmos.find(Flatten); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_flattening_normal() : Vec3d::Zero(); + return dynamic_cast(m_gizmos[Flatten].get())->get_flattening_normal(); } void GLGizmosManager::set_flattening_data(const ModelObject* model_object) { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return; - GizmosMap::const_iterator it = m_gizmos.find(Flatten); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_flattening_data(model_object); + dynamic_cast(m_gizmos[Flatten].get())->set_flattening_data(model_object); } void GLGizmosManager::set_sla_support_data(ModelObject* model_object) { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return; - GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_sla_support_data(model_object, m_parent.get_selection()); + dynamic_cast(m_gizmos[SlaSupports].get())->set_sla_support_data(model_object, m_parent.get_selection()); } // Returns true if the gizmo used the event to do something, false otherwise. bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { - if (!m_enabled) + if (!m_enabled || m_gizmos.empty()) return false; - GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); - if (it != m_gizmos.end()) - return reinterpret_cast(it->second)->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); - - return false; + return dynamic_cast(m_gizmos[SlaSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); } ClippingPlane GLGizmosManager::get_sla_clipping_plane() const { - if (!m_enabled || m_current != SlaSupports) + if (!m_enabled || m_current != SlaSupports || m_gizmos.empty()) return ClippingPlane::ClipsNothing(); - GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); - if (it != m_gizmos.end()) - return reinterpret_cast(it->second)->get_sla_clipping_plane(); - - return ClippingPlane::ClipsNothing(); + return dynamic_cast(m_gizmos[SlaSupports].get())->get_sla_clipping_plane(); } bool GLGizmosManager::wants_reslice_supports_on_undo() const { return (m_current == SlaSupports - && dynamic_cast(m_gizmos.at(SlaSupports))->has_backend_supports()); + && dynamic_cast(m_gizmos.at(SlaSupports).get())->has_backend_supports()); } void GLGizmosManager::render_current_gizmo() const { - if (!m_enabled) + if (!m_enabled || m_current == Undefined) return; - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->render(); + m_gizmos[m_current]->render(); } void GLGizmosManager::render_current_gizmo_for_picking_pass() const { - if (!m_enabled) + if (! m_enabled || m_current == Undefined) return; - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->render_for_picking(); + m_gizmos[m_current]->render_for_picking(); } void GLGizmosManager::render_overlay() const @@ -547,7 +447,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) // if the button down was done on this toolbar, prevent from dragging into the scene processed = true; - if (!overlay_contains_mouse(mouse_pos)) + if (get_gizmo_idx_from_mouse(mouse_pos) == Undefined) { // mouse is outside the toolbar m_tooltip = ""; @@ -557,14 +457,12 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown())) // the gizmo got the event and took some action, there is no need to do anything more processed = true; - else if (!selection.is_empty() && grabber_contains_mouse()) - { + else if (!selection.is_empty() && grabber_contains_mouse()) { update_data(); selection.start_dragging(); start_dragging(); - if (m_current == Flatten) - { + if (m_current == Flatten) { // Rotate the object so the normal points downward: m_parent.do_flatten(get_flattening_normal(), L("Gizmo-Place on Face")); wxGetApp().obj_manipul()->set_dirty(); @@ -634,25 +532,14 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) } else if (evt.LeftUp() && is_dragging()) { - switch (m_current) - { - case Move: - { - m_parent.do_move(L("Gizmo-Move")); - break; - } - case Scale: - { - m_parent.do_scale(L("Gizmo-Scale")); - break; - } - case Rotate: - { - m_parent.do_rotate(L("Gizmo-Rotate")); - break; - } - default: - break; + switch (m_current) { + case Move : m_parent.do_move(L("Gizmo-Move")); + break; + case Scale : m_parent.do_scale(L("Gizmo-Scale")); + break; + case Rotate : m_parent.do_rotate(L("Gizmo-Rotate")); + break; + default : break; } stop_dragging(); @@ -842,7 +729,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) { if (m_current == SlaSupports) { - GLGizmoSlaSupports* gizmo = reinterpret_cast(get_current()); + GLGizmoSlaSupports* gizmo = dynamic_cast(get_current()); if (keyCode == WXK_SHIFT) { @@ -863,7 +750,8 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) } else if (evt.GetEventType() == wxEVT_KEY_DOWN) { - if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)) && reinterpret_cast(get_current())->is_in_editing_mode()) + if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)) + && dynamic_cast(get_current())->is_in_editing_mode()) { // m_parent.set_cursor(GLCanvas3D::Cross); processed = true; @@ -882,18 +770,7 @@ void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot) m_serializing = false; if (m_current == SlaSupports && snapshot.snapshot_data.flags & UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS) - dynamic_cast(m_gizmos[SlaSupports])->reslice_SLA_supports(true); -} - -void GLGizmosManager::reset() -{ - for (GizmosMap::value_type& gizmo : m_gizmos) - { - delete gizmo.second; - gizmo.second = nullptr; - } - - m_gizmos.clear(); + dynamic_cast(m_gizmos[SlaSupports].get())->reslice_SLA_supports(true); } void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const @@ -911,7 +788,7 @@ void GLGizmosManager::render_background(float left, float top, float right, floa float internal_top = top - border; float internal_bottom = bottom + border; - float left_uv = 0.0f; + // float left_uv = 0.0f; float right_uv = 1.0f; float top_uv = 1.0f; float bottom_uv = 0.0f; @@ -981,33 +858,32 @@ void GLGizmosManager::do_render_overlay() const float scaled_icons_size = m_overlay_icons_size * m_overlay_scale * inv_zoom; float scaled_stride_y = scaled_icons_size + scaled_gap_y; unsigned int icons_texture_id = m_icons_texture.get_id(); - unsigned int tex_width = m_icons_texture.get_width(); - unsigned int tex_height = m_icons_texture.get_height(); - float inv_tex_width = (tex_width != 0) ? 1.0f / (float)tex_width : 0.0f; - float inv_tex_height = (tex_height != 0) ? 1.0f / (float)tex_height : 0.0f; + int tex_width = m_icons_texture.get_width(); + int tex_height = m_icons_texture.get_height(); + float inv_tex_width = (tex_width != 0) ? 1.0f / tex_width : 0.0f; + float inv_tex_height = (tex_height != 0) ? 1.0f / tex_height : 0.0f; if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + for (size_t idx : get_selectable_idxs()) { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; + GLGizmoBase* gizmo = m_gizmos[idx].get(); - unsigned int sprite_id = it->second->get_sprite_id(); - GLGizmoBase::EState state = it->second->get_state(); + unsigned int sprite_id = gizmo->get_sprite_id(); + int icon_idx = m_current == idx ? 2 : (m_hover == idx ? 1 : 0); float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width; float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height; float v_top = sprite_id * v_icon_size; - float u_left = state * u_icon_size; + float u_left = icon_idx * u_icon_size; float v_bottom = v_top + v_icon_size; float u_right = u_left + u_icon_size; GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); - if (it->second->get_state() == GLGizmoBase::On) { - float toolbar_top = (float)cnv_h - m_parent.get_view_toolbar_height(); - it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top); + if (idx == m_current) { + float toolbar_top = cnv_h - m_parent.get_view_toolbar_height(); + gizmo->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top); } top_y -= scaled_stride_y; } @@ -1021,13 +897,14 @@ float GLGizmosManager::get_total_overlay_height() const float scaled_stride_y = scaled_icons_size + scaled_gap_y; float height = 2.0f * scaled_border; - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + /*for (size_t idx=0; idxsecond == nullptr) || !it->second->is_selectable()) + if ((m_gizmos[idx] == nullptr) || !m_gizmos[idx]->is_selectable()) continue; height += scaled_stride_y; - } + }*/ + height += get_selectable_idxs().size() * scaled_stride_y; return height - scaled_gap_y; } @@ -1039,19 +916,21 @@ float GLGizmosManager::get_total_overlay_width() const GLGizmoBase* GLGizmosManager::get_current() const { - GizmosMap::const_iterator it = m_gizmos.find(m_current); - return (it != m_gizmos.end()) ? it->second : nullptr; + if (m_current==Undefined || m_gizmos.empty()) + return nullptr; + else + return m_gizmos[m_current].get(); } bool GLGizmosManager::generate_icons_texture() const { std::string path = resources_dir() + "/icons/"; std::vector filenames; - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + for (size_t idx=0; idxsecond != nullptr) + if (m_gizmos[idx] != nullptr) { - const std::string& icon_filename = it->second->get_icon_filename(); + const std::string& icon_filename = m_gizmos[idx]->get_icon_filename(); if (!icon_filename.empty()) filenames.push_back(path + icon_filename); } @@ -1074,74 +953,9 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) if (!m_enabled) return; - float cnv_h = (float)m_parent.get_canvas_size().get_height(); - float height = get_total_overlay_height(); - - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float top_y = 0.5f * (cnv_h - height) + scaled_border; - - auto inside = [scaled_border, scaled_icons_size, &mouse_pos](float top_y) { - return (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); - }; - - bool could_activate = true; - for (std::pair &type_and_gizmo : m_gizmos) - { - GLGizmoBase *gizmo = type_and_gizmo.second; - if ((gizmo == nullptr) || !gizmo->is_selectable()) - continue; - - if (! (gizmo->is_activable() && inside(top_y))) { - gizmo->set_state(GLGizmoBase::Off); - if (gizmo->get_state() != GLGizmoBase::Off) { - // Gizmo refused to leave it's active state. Don't try to select - could_activate = false; - } - } - - top_y += scaled_stride_y; - } - - // We may change m_current soon. If we did it during following loop, gizmos that take undo/redo snapshots - // in their on_set_state function could snapshot a state with the new gizmo already active. - // Therefore, just remember what needs to be done and actually change m_current afterwards. - EType new_current = m_current; - top_y = 0.5f * (cnv_h - height) + scaled_border; - for (std::pair &type_and_gizmo : m_gizmos) - { - GLGizmoBase *gizmo = type_and_gizmo.second; - if ((gizmo == nullptr) || !gizmo->is_selectable()) - continue; - - if (gizmo->is_activable() && inside(top_y)) - { - if ((gizmo->get_state() == GLGizmoBase::On)) - { - gizmo->set_state(GLGizmoBase::Off); - if (gizmo->get_state() == GLGizmoBase::Off) { - gizmo->set_state(GLGizmoBase::Hover); - new_current = Undefined; - } - } - else if ((gizmo->get_state() == GLGizmoBase::Hover) && could_activate) - { - gizmo->set_state(GLGizmoBase::On); - new_current = type_and_gizmo.first; - } - } - - top_y += scaled_stride_y; - } - m_current = new_current; - - if (could_activate) { - GizmosMap::iterator it = m_gizmos.find(m_current); - if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) - it->second->set_state(GLGizmoBase::On); - } + size_t idx = get_gizmo_idx_from_mouse(mouse_pos); + if (idx != Undefined && m_gizmos[idx]->is_activable() && m_hover == idx) + activate_gizmo(m_current == idx ? Undefined : (EType)idx); } std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) @@ -1151,60 +965,37 @@ std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) if (!m_enabled) return name; - float cnv_h = (float)m_parent.get_canvas_size().get_height(); - float height = get_total_overlay_height(); - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float top_y = 0.5f * (cnv_h - height) + scaled_border; + m_hover = Undefined; - for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; + size_t idx = get_gizmo_idx_from_mouse(mouse_pos); + if (idx != Undefined) { + name = m_gizmos[idx]->get_name(); - bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); - if (inside) - name = it->second->get_name(); - - if (it->second->is_activable() && (it->second->get_state() != GLGizmoBase::On)) - it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off); - - top_y += scaled_stride_y; + if (m_gizmos[idx]->is_activable()) + m_hover = (EType)idx; } return name; } -bool GLGizmosManager::overlay_contains_mouse(const Vec2d& mouse_pos) const +void GLGizmosManager::activate_gizmo(EType type) { - if (!m_enabled) - return false; + if (m_gizmos.empty() || m_current == type) + return; - float cnv_h = (float)m_parent.get_canvas_size().get_height(); - float height = get_total_overlay_height(); - - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float top_y = 0.5f * (cnv_h - height) + scaled_border; - - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - - if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) - return true; - - top_y += scaled_stride_y; + if (m_current != Undefined) { + m_gizmos[m_current]->set_state(GLGizmoBase::Off); + if (m_gizmos[m_current]->get_state() != GLGizmoBase::Off) + return; // gizmo refused to be turned off, do nothing. } - return false; + if (type != Undefined) + m_gizmos[type]->set_state(GLGizmoBase::On); + + m_current = type; } + bool GLGizmosManager::grabber_contains_mouse() const { if (!m_enabled) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index c0adeb957..f649c98b2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -54,25 +54,30 @@ public: enum EType : unsigned char { - Undefined, Move, Scale, Rotate, Flatten, Cut, SlaSupports, - Num_Types + Undefined }; private: GLCanvas3D& m_parent; bool m_enabled; - typedef std::map GizmosMap; - GizmosMap m_gizmos; + std::vector> m_gizmos; mutable GLTexture m_icons_texture; mutable bool m_icons_texture_dirty; BackgroundTexture m_background_texture; EType m_current; + EType m_hover; + + std::vector get_selectable_idxs() const; + std::vector get_activable_idxs() const; + size_t get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const; + + void activate_gizmo(EType type); float m_overlay_icons_size; float m_overlay_scale; @@ -98,7 +103,6 @@ private: public: explicit GLGizmosManager(GLCanvas3D& parent); - ~GLGizmosManager(); bool init(); @@ -112,16 +116,8 @@ public: ar(m_current); - GLGizmoBase* curr = get_current(); - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { - GLGizmoBase* gizmo = it->second; - if (gizmo != nullptr) { - gizmo->set_hover_id(-1); - gizmo->set_state((it->second == curr) ? GLGizmoBase::On : GLGizmoBase::Off); - if (gizmo == curr) - gizmo->load(ar); - } - } + if (m_current != Undefined) + m_gizmos[m_current]->load(ar); } template @@ -132,9 +128,8 @@ public: ar(m_current); - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->save(ar); + if (m_current != Undefined && !m_gizmos.empty()) + m_gizmos[m_current]->save(ar); } bool is_enabled() const { return m_enabled; } @@ -195,8 +190,6 @@ public: void update_after_undo_redo(const UndoRedo::Snapshot& snapshot); private: - void reset(); - void render_background(float left, float top, float right, float bottom, float border) const; void do_render_overlay() const; @@ -209,7 +202,6 @@ private: void update_on_off_state(const Vec2d& mouse_pos); std::string update_hover_state(const Vec2d& mouse_pos); - bool overlay_contains_mouse(const Vec2d& mouse_pos) const; bool grabber_contains_mouse() const; };