diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8b1d636e5..acfc642a3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2501,9 +2501,9 @@ void GLCanvas3D::Selection::_ensure_on_bed() } #endif // ENABLE_ENSURE_ON_BED_WHILE_SCALING -const float GLCanvas3D::Gizmos::OverlayTexturesScale = 1.0f; -const float GLCanvas3D::Gizmos::OverlayOffsetX = 10.0f * OverlayTexturesScale; -const float GLCanvas3D::Gizmos::OverlayGapY = 5.0f * OverlayTexturesScale; +const float GLCanvas3D::Gizmos::OverlayIconsScale = 1.0f; +const float GLCanvas3D::Gizmos::OverlayBorder = 5.0f; +const float GLCanvas3D::Gizmos::OverlayGapY = 5.0f * OverlayIconsScale; GLCanvas3D::Gizmos::Gizmos() : m_enabled(false) @@ -2606,19 +2606,18 @@ std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, con float cnv_h = (float)canvas.get_canvas_size().get_height(); float height = _get_total_overlay_height(); - float top_y = 0.5f * (cnv_h - height); + float top_y = 0.5f * (cnv_h - height) + OverlayBorder; for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; - float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale; - float half_tex_size = 0.5f * tex_size; + float tex_size = (float)it->second->get_textures_size() * OverlayIconsScale; // we currently use circular icons for gizmo, so we check the radius if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On)) { - bool inside = (mouse_pos - Vec2d(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size; + bool inside = (OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + tex_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + tex_size); it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off); if (inside) name = it->second->get_name(); @@ -2636,17 +2635,17 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec float cnv_h = (float)canvas.get_canvas_size().get_height(); float height = _get_total_overlay_height(); - float top_y = 0.5f * (cnv_h - height); + float top_y = 0.5f * (cnv_h - height) + OverlayBorder; for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; - float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale; - float half_tex_size = 0.5f * tex_size; + float tex_size = (float)it->second->get_textures_size() * OverlayIconsScale; // we currently use circular icons for gizmo, so we check the radius - if (it->second->is_activable(selection) && ((mouse_pos - Vec2d(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size)) + bool inside = (OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + tex_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + tex_size); + if (it->second->is_activable(selection) && inside) { if ((it->second->get_state() == GLGizmoBase::On)) { @@ -2734,17 +2733,17 @@ bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const float cnv_h = (float)canvas.get_canvas_size().get_height(); float height = _get_total_overlay_height(); - float top_y = 0.5f * (cnv_h - height); + float top_y = 0.5f * (cnv_h - height) + OverlayBorder; for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; - float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale; + float tex_size = (float)it->second->get_textures_size() * OverlayIconsScale; float half_tex_size = 0.5f * tex_size; // we currently use circular icons for gizmo, so we check the radius - if ((mouse_pos - Vec2d(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size) + if ((OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + tex_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + tex_size)) return true; top_y += (tex_size + OverlayGapY); @@ -3020,19 +3019,19 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float height = _get_total_overlay_height(); - float top_x = (OverlayOffsetX - 0.5f * cnv_w) * inv_zoom; - float top_y = 0.5f * height * inv_zoom; + float top_x = (OverlayBorder - 0.5f * cnv_w) * inv_zoom; + float top_y = (0.5f * height - OverlayBorder) * inv_zoom; float scaled_gap_y = OverlayGapY * inv_zoom; for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) continue; - float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale * inv_zoom; + float tex_size = (float)it->second->get_textures_size() * OverlayIconsScale * inv_zoom; GLTexture::render_texture(it->second->get_texture_id(), top_x, top_x + tex_size, top_y - tex_size, top_y); #if ENABLE_IMGUI if (it->second->get_state() == GLGizmoBase::On) - it->second->render_input_window(2.0f * OverlayOffsetX + tex_size * zoom, 0.5f * cnv_h - top_y * zoom, selection); + it->second->render_input_window(2.0f * OverlayBorder + tex_size * zoom, 0.5f * cnv_h - top_y * zoom, selection); #endif // ENABLE_IMGUI top_y -= (tex_size + scaled_gap_y); } @@ -3047,14 +3046,14 @@ void GLCanvas3D::Gizmos::_render_current_gizmo(const GLCanvas3D::Selection& sele float GLCanvas3D::Gizmos::_get_total_overlay_height() const { - float height = 0.0f; + float height = 2.0f * OverlayBorder; for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { - if (it->first == SlaSupports && wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) + if ((it->second == nullptr) || !it->second->is_selectable()) continue; - height += (float)it->second->get_textures_size() * OverlayTexturesScale + OverlayGapY; + height += (float)it->second->get_textures_size() * OverlayIconsScale + OverlayGapY; } return height - OverlayGapY; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index eecc3261b..8683ef636 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -607,8 +607,8 @@ public: private: class Gizmos { - static const float OverlayTexturesScale; - static const float OverlayOffsetX; + static const float OverlayIconsScale; + static const float OverlayBorder; static const float OverlayGapY; public: diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a7f1ca608..cba42470a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1460,12 +1460,9 @@ void ObjectList::update_selections() select_items(sels); if (GetSelection()) { - const wxRect& sel_rc = GetItemRect(GetSelection()); - if (!sel_rc.IsEmpty()) { - const int rc_h = sel_rc.height; - const int displ = GetMainWindow()->GetClientRect().GetHeight()/(2*rc_h)+1; - ScrollLines(int(sel_rc.y / rc_h - displ)); - } + const int sel_item_row = m_objects_model->GetRowByItem(GetSelection()); + ScrollLines(sel_item_row - m_selected_row); + m_selected_row = sel_item_row; } } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 3664e6fda..7631782df 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -108,6 +108,8 @@ class ObjectList : public wxDataViewCtrl bool m_parts_changed = false; bool m_part_settings_changed = false; + int m_selected_row = 0; + public: ObjectList(wxWindow* parent); ~ObjectList(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 98e758bc8..2daba5df4 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -953,6 +953,44 @@ void PrusaObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type = itUndef; } +int PrusaObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const +{ + if (m_objects.empty()) + return -1; + + int row_num = 0; + + for (int i = 0; i < m_objects.size(); i++) + { + row_num++; + if (item == wxDataViewItem(m_objects[i])) + return row_num; + + for (int j = 0; j < m_objects[i]->GetChildCount(); j++) + { + row_num++; + PrusaObjectDataViewModelNode* cur_node = m_objects[i]->GetNthChild(j); + if (item == wxDataViewItem(cur_node)) + return row_num; + + if (cur_node->m_type == itVolume && cur_node->GetChildCount() == 1) + row_num++; + if (cur_node->m_type == itInstanceRoot) + { + row_num++; + for (int t = 0; t < cur_node->GetChildCount(); t++) + { + row_num++; + if (item == wxDataViewItem(cur_node->GetNthChild(t))) + return row_num; + } + } + } + } + + return -1; +} + wxString PrusaObjectDataViewModel::GetName(const wxDataViewItem &item) const { PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 637f1bcff..e8fba1ea2 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -463,6 +463,7 @@ public: int GetVolumeIdByItem(const wxDataViewItem& item) const; int GetInstanceIdByItem(const wxDataViewItem& item) const; void GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx); + int GetRowByItem(const wxDataViewItem& item) const; bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog @@ -525,8 +526,14 @@ class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer #endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING { public: - PrusaBitmapTextRenderer(wxDataViewCellMode mode = wxDATAVIEW_CELL_EDITABLE, - int align = wxDVR_DEFAULT_ALIGNMENT + PrusaBitmapTextRenderer(wxDataViewCellMode mode = +#ifdef __WXOSX__ + wxDATAVIEW_CELL_INERT +#else + wxDATAVIEW_CELL_EDITABLE +#endif + + ,int align = wxDVR_DEFAULT_ALIGNMENT #if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING ); #else @@ -542,7 +549,14 @@ public: virtual bool Render(wxRect cell, wxDC *dc, int state); virtual wxSize GetSize() const; - bool HasEditorCtrl() const override { return true; } + bool HasEditorCtrl() const override + { +#ifdef __WXOSX__ + return false; +#else + return true; +#endif + } wxWindow* CreateEditorCtrl(wxWindow* parent, wxRect labelRect, const wxVariant& value) override;