1st installment of svg icons for toolbars and gizmos

This commit is contained in:
Enrico Turri 2019-02-26 09:56:23 +01:00
commit 0f683a6a1e
34 changed files with 1629 additions and 374 deletions

View file

@ -2405,20 +2405,37 @@ void GLCanvas3D::Selection::_ensure_on_bed()
}
}
#if ENABLE_SVG_ICONS
const float GLCanvas3D::Gizmos::Default_Icons_Size = 64;
#endif // ENABLE_SVG_ICONS
GLCanvas3D::Gizmos::Gizmos()
: m_enabled(false)
#if ENABLE_SVG_ICONS
, m_icons_texture_dirty(true)
#endif // ENABLE_SVG_ICONS
, m_current(Undefined)
#if ENABLE_SVG_ICONS
, m_overlay_icons_size(Default_Icons_Size)
, m_overlay_scale(1.0f)
, m_overlay_border(5.0f)
, m_overlay_gap_y(5.0f)
{
}
#else
{
set_overlay_scale(1.0);
}
#endif // ENABLE_SVG_ICONS
GLCanvas3D::Gizmos::~Gizmos()
{
_reset();
reset();
}
bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
{
#if !ENABLE_SVG_ICONS
m_icons_texture.metadata.filename = "gizmos.png";
m_icons_texture.metadata.icon_size = 64;
@ -2426,10 +2443,11 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
{
if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false))
{
_reset();
reset();
return false;
}
}
#endif // !ENABLE_SVG_ICONS
m_background_texture.metadata.filename = "toolbar_background.png";
m_background_texture.metadata.left = 16;
@ -2441,12 +2459,16 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
{
if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false))
{
_reset();
reset();
return false;
}
}
#if ENABLE_SVG_ICONS
GLGizmoBase* gizmo = new GLGizmoMove3D(parent, "add.svg", 0);
#else
GLGizmoBase* gizmo = new GLGizmoMove3D(parent, 0);
#endif // ENABLE_SVG_ICONS
if (gizmo == nullptr)
return false;
@ -2455,7 +2477,11 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
m_gizmos.insert(GizmosMap::value_type(Move, gizmo));
#if ENABLE_SVG_ICONS
gizmo = new GLGizmoScale3D(parent, "remove.svg", 1);
#else
gizmo = new GLGizmoScale3D(parent, 1);
#endif // ENABLE_SVG_ICONS
if (gizmo == nullptr)
return false;
@ -2464,49 +2490,65 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
#if ENABLE_SVG_ICONS
gizmo = new GLGizmoRotate3D(parent, "delete_all.svg", 2);
#else
gizmo = new GLGizmoRotate3D(parent, 2);
#endif // ENABLE_SVG_ICONS
if (gizmo == nullptr)
{
_reset();
reset();
return false;
}
if (!gizmo->init())
{
_reset();
reset();
return false;
}
m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo));
#if ENABLE_SVG_ICONS
gizmo = new GLGizmoFlatten(parent, "arrange.svg", 3);
#else
gizmo = new GLGizmoFlatten(parent, 3);
#endif // ENABLE_SVG_ICONS
if (gizmo == nullptr)
return false;
if (!gizmo->init()) {
_reset();
reset();
return false;
}
m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo));
#if ENABLE_SVG_ICONS
gizmo = new GLGizmoCut(parent, "instance_add.svg", 4);
#else
gizmo = new GLGizmoCut(parent, 4);
#endif // ENABLE_SVG_ICONS
if (gizmo == nullptr)
return false;
if (!gizmo->init()) {
_reset();
reset();
return false;
}
m_gizmos.insert(GizmosMap::value_type(Cut, gizmo));
#if ENABLE_SVG_ICONS
gizmo = new GLGizmoSlaSupports(parent, "instance_remove.svg", 5);
#else
gizmo = new GLGizmoSlaSupports(parent, 5);
#endif // ENABLE_SVG_ICONS
if (gizmo == nullptr)
return false;
if (!gizmo->init()) {
_reset();
reset();
return false;
}
@ -2525,11 +2567,30 @@ void GLCanvas3D::Gizmos::set_enabled(bool enable)
m_enabled = enable;
}
#if ENABLE_SVG_ICONS
void GLCanvas3D::Gizmos::set_overlay_icon_size(float size)
{
if (m_overlay_icons_size != size)
{
m_overlay_icons_size = size;
m_icons_texture_dirty = true;
}
}
#endif // ENABLE_SVG_ICONS
void GLCanvas3D::Gizmos::set_overlay_scale(float scale)
{
#if ENABLE_SVG_ICONS
if (m_overlay_scale != scale)
{
m_overlay_scale = scale;
m_icons_texture_dirty = true;
}
#else
m_overlay_icons_scale = scale;
m_overlay_border = 5.0f * scale;
m_overlay_gap_y = 5.0f * scale;
#endif // ENABLE_SVG_ICONS
}
std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const GLCanvas3D::Selection& selection)
@ -2540,24 +2601,39 @@ std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, con
return name;
float cnv_h = (float)canvas.get_canvas_size().get_height();
float height = _get_total_overlay_height();
float height = get_total_overlay_height();
#if ENABLE_SVG_ICONS
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;
#else
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
#endif // ENABLE_SVG_ICONS
for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if ((it->second == nullptr) || !it->second->is_selectable())
continue;
#if ENABLE_SVG_ICONS
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);
#else
bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
#endif // ENABLE_SVG_ICONS
if (inside)
name = it->second->get_name();
if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On))
it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
#if ENABLE_SVG_ICONS
top_y += scaled_stride_y;
#else
top_y += (scaled_icons_size + m_overlay_gap_y);
#endif // ENABLE_SVG_ICONS
}
return name;
@ -2569,17 +2645,29 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec
return;
float cnv_h = (float)canvas.get_canvas_size().get_height();
float height = _get_total_overlay_height();
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
float height = get_total_overlay_height();
#if ENABLE_SVG_ICONS
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;
#else
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
#endif // ENABLE_SVG_ICONS
for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if ((it->second == nullptr) || !it->second->is_selectable())
continue;
#if ENABLE_SVG_ICONS
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);
#else
bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
#endif // ENABLE_SVG_ICONS
if (it->second->is_activable(selection) && inside)
{
if ((it->second->get_state() == GLGizmoBase::On))
@ -2596,7 +2684,11 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec
else
it->second->set_state(GLGizmoBase::Off);
#if ENABLE_SVG_ICONS
top_y += scaled_stride_y;
#else
top_y += (scaled_icons_size + m_overlay_gap_y);
#endif // ENABLE_SVG_ICONS
}
GizmosMap::iterator it = m_gizmos.find(m_current);
@ -2667,20 +2759,36 @@ bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const
return false;
float cnv_h = (float)canvas.get_canvas_size().get_height();
float height = _get_total_overlay_height();
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
float height = get_total_overlay_height();
#if ENABLE_SVG_ICONS
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;
#else
float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
#endif // ENABLE_SVG_ICONS
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if ((it->second == nullptr) || !it->second->is_selectable())
continue;
#if ENABLE_SVG_ICONS
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))
#else
if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size))
#endif // ENABLE_SVG_ICONS
return true;
#if ENABLE_SVG_ICONS
top_y += scaled_stride_y;
#else
top_y += (scaled_icons_size + m_overlay_gap_y);
#endif // ENABLE_SVG_ICONS
}
return false;
@ -2691,7 +2799,7 @@ bool GLCanvas3D::Gizmos::grabber_contains_mouse() const
if (!m_enabled)
return false;
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
return (curr != nullptr) ? (curr->get_hover_id() != -1) : false;
}
@ -2700,7 +2808,7 @@ void GLCanvas3D::Gizmos::update(const Linef3& mouse_ray, const Selection& select
if (!m_enabled)
return;
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
if (curr != nullptr)
curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos, shift_down), selection);
}
@ -2715,7 +2823,7 @@ bool GLCanvas3D::Gizmos::is_running() const
if (!m_enabled)
return false;
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false;
}
@ -2765,7 +2873,7 @@ bool GLCanvas3D::Gizmos::is_dragging() const
if (!m_enabled)
return false;
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
return (curr != nullptr) ? curr->is_dragging() : false;
}
@ -2774,7 +2882,7 @@ void GLCanvas3D::Gizmos::start_dragging(const GLCanvas3D::Selection& selection)
if (!m_enabled)
return;
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
if (curr != nullptr)
curr->start_dragging(selection);
}
@ -2784,7 +2892,7 @@ void GLCanvas3D::Gizmos::stop_dragging()
if (!m_enabled)
return;
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
if (curr != nullptr)
curr->stop_dragging();
}
@ -2884,7 +2992,7 @@ void GLCanvas3D::Gizmos::render_current_gizmo(const GLCanvas3D::Selection& selec
if (!m_enabled)
return;
_render_current_gizmo(selection);
do_render_current_gizmo(selection);
}
void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const GLCanvas3D::Selection& selection) const
@ -2892,7 +3000,7 @@ void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const GLCanvas3D:
if (!m_enabled)
return;
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
if (curr != nullptr)
curr->render_for_picking(selection);
}
@ -2902,12 +3010,17 @@ void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas, const GLCanvas
if (!m_enabled)
return;
#if ENABLE_SVG_ICONS
if (m_icons_texture_dirty)
generate_icons_texture();
#endif // ENABLE_SVG_ICONS
::glDisable(GL_DEPTH_TEST);
::glPushMatrix();
::glLoadIdentity();
_render_overlay(canvas, selection);
do_render_overlay(canvas, selection);
::glPopMatrix();
}
@ -2921,7 +3034,7 @@ void GLCanvas3D::Gizmos::create_external_gizmo_widgets(wxWindow *parent)
}
#endif // not ENABLE_IMGUI
void GLCanvas3D::Gizmos::_reset()
void GLCanvas3D::Gizmos::reset()
{
for (GizmosMap::value_type& gizmo : m_gizmos)
{
@ -2932,7 +3045,7 @@ void GLCanvas3D::Gizmos::_reset()
m_gizmos.clear();
}
void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanvas3D::Selection& selection) const
void GLCanvas3D::Gizmos::do_render_overlay(const GLCanvas3D& canvas, const GLCanvas3D::Selection& selection) const
{
if (m_gizmos.empty())
return;
@ -2944,15 +3057,19 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
float zoom = canvas.get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
float height = _get_total_overlay_height();
float height = get_total_overlay_height();
#if ENABLE_SVG_ICONS
float scaled_border = m_overlay_border * m_overlay_scale * inv_zoom;
#else
float scaled_border = m_overlay_border * inv_zoom;
#endif // ENABLE_SVG_ICONS
float top_x = (-0.5f * cnv_w) * inv_zoom;
float top_y = (0.5f * height) * inv_zoom;
float left = top_x;
float top = top_y;
float right = left + _get_total_overlay_width() * inv_zoom;
float right = left + get_total_overlay_width() * inv_zoom;
float bottom = top - height * inv_zoom;
// renders background
@ -3021,6 +3138,16 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
}
}
#if ENABLE_SVG_ICONS
top_x += scaled_border;
top_y -= scaled_border;
float scaled_gap_y = m_overlay_gap_y * m_overlay_scale * inv_zoom;
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 texture_size = m_icons_texture.get_width();
#else
top_x += m_overlay_border * inv_zoom;
top_y -= m_overlay_border * inv_zoom;
float scaled_gap_y = m_overlay_gap_y * inv_zoom;
@ -3028,8 +3155,14 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale * inv_zoom;
unsigned int icons_texture_id = m_icons_texture.texture.get_id();
unsigned int texture_size = m_icons_texture.texture.get_width();
#endif // ENABLE_SVG_ICONS
float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f;
#if ENABLE_SVG_ICONS
if ((icons_texture_id == 0) || (texture_size <= 0))
return;
#endif // ENABLE_SVG_ICONS
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if ((it->second == nullptr) || !it->second->is_selectable())
@ -3038,7 +3171,11 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
unsigned int sprite_id = it->second->get_sprite_id();
GLGizmoBase::EState state = it->second->get_state();
#if ENABLE_SVG_ICONS
float uv_icon_size = m_overlay_icons_size * inv_texture_size;
#else
float uv_icon_size = (float)m_icons_texture.metadata.icon_size * inv_texture_size;
#endif // ENABLE_SVG_ICONS
float top = sprite_id * uv_icon_size;
float left = state * uv_icon_size;
float bottom = top + uv_icon_size;
@ -3047,48 +3184,98 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva
GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { left, bottom }, { right, bottom }, { right, top }, { left, top } });
#if ENABLE_IMGUI
if (it->second->get_state() == GLGizmoBase::On)
#if ENABLE_SVG_ICONS
it->second->render_input_window(2.0f * scaled_border + scaled_icons_size * zoom, 0.5f * cnv_h - top_y * zoom, selection);
#else
it->second->render_input_window(2.0f * m_overlay_border + scaled_icons_size * zoom, 0.5f * cnv_h - top_y * zoom, selection);
#endif // ENABLE_SVG_ICONS
#endif // ENABLE_IMGUI
#if ENABLE_SVG_ICONS
top_y -= scaled_stride_y;
#else
top_y -= (scaled_icons_size + scaled_gap_y);
#endif // ENABLE_SVG_ICONS
}
}
void GLCanvas3D::Gizmos::_render_current_gizmo(const GLCanvas3D::Selection& selection) const
void GLCanvas3D::Gizmos::do_render_current_gizmo(const GLCanvas3D::Selection& selection) const
{
GLGizmoBase* curr = _get_current();
GLGizmoBase* curr = get_current();
if (curr != nullptr)
curr->render(selection);
}
float GLCanvas3D::Gizmos::_get_total_overlay_height() const
float GLCanvas3D::Gizmos::get_total_overlay_height() const
{
#if ENABLE_SVG_ICONS
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 height = 2.0f * scaled_border;
#else
float height = 2.0f * m_overlay_border;
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
#endif // ENABLE_SVG_ICONS
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if ((it->second == nullptr) || !it->second->is_selectable())
continue;
#if ENABLE_SVG_ICONS
height += scaled_stride_y;
#else
height += (scaled_icons_size + m_overlay_gap_y);
#endif // ENABLE_SVG_ICONS
}
#if ENABLE_SVG_ICONS
return height - scaled_gap_y;
#else
return height - m_overlay_gap_y;
#endif // ENABLE_SVG_ICONS
}
float GLCanvas3D::Gizmos::_get_total_overlay_width() const
float GLCanvas3D::Gizmos::get_total_overlay_width() const
{
float max_icon_width = std::max(max_icon_width, (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale);
return max_icon_width + 2.0f * m_overlay_border;
#if ENABLE_SVG_ICONS
return (2.0f * m_overlay_border + m_overlay_icons_size) * m_overlay_scale;
#else
return (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale + 2.0f * m_overlay_border;
#endif // ENABLE_SVG_ICONS
}
GLGizmoBase* GLCanvas3D::Gizmos::_get_current() const
GLGizmoBase* GLCanvas3D::Gizmos::get_current() const
{
GizmosMap::const_iterator it = m_gizmos.find(m_current);
return (it != m_gizmos.end()) ? it->second : nullptr;
}
#if ENABLE_SVG_ICONS
bool GLCanvas3D::Gizmos::generate_icons_texture() const
{
std::string path = resources_dir() + "/icons/";
std::vector<std::string> filenames;
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
{
if (it->second != nullptr)
{
const std::string& svg_file = it->second->get_svg_file();
if (!svg_file.empty())
filenames.push_back(path + svg_file);
}
}
bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, GLGizmoBase::Num_States, (unsigned int)(m_overlay_icons_size * m_overlay_scale));
if (res)
m_icons_texture_dirty = false;
return res;
}
#endif // ENABLE_SVG_ICONS
const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 9, 91, 134 };
const unsigned char GLCanvas3D::WarningTexture::Opacity = 255;
@ -3197,7 +3384,7 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanva
::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
::glBindTexture(GL_TEXTURE_2D, 0);
return true;
@ -3450,7 +3637,7 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
::glBindTexture(GL_TEXTURE_2D, 0);
return true;
@ -4054,7 +4241,9 @@ void GLCanvas3D::render()
_render_gizmos_overlay();
_render_warning_texture();
_render_legend_texture();
#if !ENABLE_SVG_ICONS
_resize_toolbars();
#endif // !ENABLE_SVG_ICONS
_render_toolbar();
_render_view_toolbar();
if (m_layers_editing.last_object_id >= 0)
@ -4647,7 +4836,19 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
switch (keyCode)
{
// key ESC
case WXK_ESCAPE: { m_gizmos.reset_all_states(); m_dirty = true; break; }
case WXK_ESCAPE: {
if (m_gizmos.get_current_type() != Gizmos::SlaSupports || !m_gizmos.mouse_event(SLAGizmoEventType::DiscardChanges))
m_gizmos.reset_all_states();
m_dirty = true;
break;
}
case WXK_RETURN: {
if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::ApplyChanges))
m_dirty = true;
break;
}
#ifdef __APPLE__
case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead.
#else /* __APPLE__ */
@ -4670,11 +4871,25 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case '-': { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; }
case '?': { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; }
case 'A':
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
case 'a': {
if (m_gizmos.get_current_type() == Gizmos::SlaSupports) {
if (m_gizmos.mouse_event(SLAGizmoEventType::AutomaticGeneration))
m_dirty = true;
}
else
post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE));
break;
}
case 'B':
case 'b': { zoom_to_bed(); break; }
case 'I':
case 'i': { set_camera_zoom(1.0f); break; }
case 'M':
case 'm': {
if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::ManualEditing))
m_dirty = true;
break;
}
case 'O':
case 'o': { set_camera_zoom(-1.0f); break; }
case 'Z':
@ -4769,6 +4984,54 @@ void GLCanvas3D::on_timer(wxTimerEvent& evt)
_perform_layer_editing_action();
}
#ifndef NDEBUG
// #define SLIC3R_DEBUG_MOUSE_EVENTS
#endif
#ifdef SLIC3R_DEBUG_MOUSE_EVENTS
std::string format_mouse_event_debug_message(const wxMouseEvent &evt)
{
static int idx = 0;
char buf[2048];
std::string out;
sprintf(buf, "Mouse Event %d - ", idx ++);
out = buf;
if (evt.Entering())
out += "Entering ";
if (evt.Leaving())
out += "Leaving ";
if (evt.Dragging())
out += "Dragging ";
if (evt.Moving())
out += "Moving ";
if (evt.Magnify())
out += "Magnify ";
if (evt.LeftDown())
out += "LeftDown ";
if (evt.LeftUp())
out += "LeftUp ";
if (evt.LeftDClick())
out += "LeftDClick ";
if (evt.MiddleDown())
out += "MiddleDown ";
if (evt.MiddleUp())
out += "MiddleUp ";
if (evt.MiddleDClick())
out += "MiddleDClick ";
if (evt.RightDown())
out += "RightDown ";
if (evt.RightUp())
out += "RightUp ";
if (evt.RightDClick())
out += "RightDClick ";
sprintf(buf, "(%d, %d)", evt.GetX(), evt.GetY());
out += buf;
return out;
}
#endif /* SLIC3R_DEBUG_MOUSE_EVENTS */
void GLCanvas3D::on_mouse(wxMouseEvent& evt)
{
#if ENABLE_RETINA_GL
@ -4784,15 +5047,27 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (imgui->update_mouse_data(evt)) {
m_mouse.position = evt.Leaving() ? Vec2d(-1.0, -1.0) : pos.cast<double>();
render();
return;
#ifdef SLIC3R_DEBUG_MOUSE_EVENTS
printf((format_mouse_event_debug_message(evt) + " - Consumed by ImGUI\n").c_str());
#endif /* SLIC3R_DEBUG_MOUSE_EVENTS */
return;
}
#endif // ENABLE_IMGUI
bool on_enter_workaround = false;
if (! evt.Entering() && ! evt.Leaving() && m_mouse.position.x() == -1.0) {
// Workaround for SPE-832: There seems to be a mouse event sent to the window before evt.Entering()
m_mouse.position = pos.cast<double>();
render();
}
#ifdef SLIC3R_DEBUG_MOUSE_EVENTS
printf((format_mouse_event_debug_message(evt) + " - OnEnter workaround\n").c_str());
#endif /* SLIC3R_DEBUG_MOUSE_EVENTS */
on_enter_workaround = true;
} else {
#ifdef SLIC3R_DEBUG_MOUSE_EVENTS
printf((format_mouse_event_debug_message(evt) + " - other\n").c_str());
#endif /* SLIC3R_DEBUG_MOUSE_EVENTS */
}
if (m_picking_enabled)
_set_current();
@ -5240,6 +5515,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
else
evt.Skip();
if (on_enter_workaround)
m_mouse.position = Vec2d(-1., -1.);
}
void GLCanvas3D::on_paint(wxPaintEvent& evt)
@ -5588,14 +5866,11 @@ bool GLCanvas3D::_init_toolbar()
if (!m_toolbar.is_enabled())
return true;
#if !ENABLE_SVG_ICONS
ItemsIconsTexture::Metadata icons_data;
icons_data.filename = "toolbar.png";
icons_data.icon_size = 37;
// icons_data.filename = "toolbar141.png";
// icons_data.icon_size = 52;
// icons_data.icon_border_size = 0;
// icons_data.icon_gap_size = 0;
#endif // !ENABLE_SVG_ICONS
BackgroundTexture::Metadata background_data;
background_data.filename = "toolbar_background.png";
@ -5604,7 +5879,11 @@ bool GLCanvas3D::_init_toolbar()
background_data.right = 16;
background_data.bottom = 16;
#if ENABLE_SVG_ICONS
if (!m_toolbar.init(background_data))
#else
if (!m_toolbar.init(icons_data, background_data))
#endif // ENABLE_SVG_ICONS
{
// unable to init the toolbar texture, disable it
m_toolbar.set_enabled(false);
@ -5621,6 +5900,9 @@ bool GLCanvas3D::_init_toolbar()
GLToolbarItem::Data item;
item.name = "add";
#if ENABLE_SVG_ICONS
item.svg_file = "add.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Add...") + " [" + GUI::shortkey_ctrl_prefix() + "I]";
item.sprite_id = 0;
item.action_event = EVT_GLTOOLBAR_ADD;
@ -5628,6 +5910,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "delete";
#if ENABLE_SVG_ICONS
item.svg_file = "remove.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Delete") + " [Del]";
item.sprite_id = 1;
item.action_event = EVT_GLTOOLBAR_DELETE;
@ -5635,6 +5920,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "deleteall";
#if ENABLE_SVG_ICONS
item.svg_file = "delete_all.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Delete all") + " [" + GUI::shortkey_ctrl_prefix() + "Del]";
item.sprite_id = 2;
item.action_event = EVT_GLTOOLBAR_DELETE_ALL;
@ -5642,6 +5930,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "arrange";
#if ENABLE_SVG_ICONS
item.svg_file = "arrange.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Arrange [A]");
item.sprite_id = 3;
item.action_event = EVT_GLTOOLBAR_ARRANGE;
@ -5652,6 +5943,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "more";
#if ENABLE_SVG_ICONS
item.svg_file = "instance_add.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Add instance [+]");
item.sprite_id = 4;
item.action_event = EVT_GLTOOLBAR_MORE;
@ -5659,6 +5953,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "fewer";
#if ENABLE_SVG_ICONS
item.svg_file = "instance_remove.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Remove instance [-]");
item.sprite_id = 5;
item.action_event = EVT_GLTOOLBAR_FEWER;
@ -5669,6 +5966,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "splitobjects";
#if ENABLE_SVG_ICONS
item.svg_file = "split_objects.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Split to objects");
item.sprite_id = 6;
item.action_event = EVT_GLTOOLBAR_SPLIT_OBJECTS;
@ -5676,6 +5976,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "splitvolumes";
#if ENABLE_SVG_ICONS
item.svg_file = "split_parts.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Split to parts");
item.sprite_id = 8;
item.action_event = EVT_GLTOOLBAR_SPLIT_VOLUMES;
@ -5686,6 +5989,9 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "layersediting";
#if ENABLE_SVG_ICONS
item.svg_file = "layers.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Layers editing");
item.sprite_id = 7;
item.is_toggable = true;
@ -6177,11 +6483,63 @@ void GLCanvas3D::_render_gizmos_overlay() const
void GLCanvas3D::_render_toolbar() const
{
#if ENABLE_SVG_ICONS
#if ENABLE_RETINA_GL
m_toolbar.set_scale(m_retina_helper->get_scale_factor());
#else
m_toolbar.set_scale(m_canvas->GetContentScaleFactor());
#endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size();
float zoom = get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation();
float top = 0.0f;
float left = 0.0f;
switch (m_toolbar.get_layout_type())
{
default:
case GLToolbar::Layout::Horizontal:
{
// centers the toolbar on the top edge of the 3d scene
if (orientation == GLToolbar::Layout::Top)
{
top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
left = -0.5f * m_toolbar.get_width() * inv_zoom;
}
else
{
top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar->get_height()) * inv_zoom;
left = -0.5f * m_toolbar.get_width() * inv_zoom;
}
break;
}
case GLToolbar::Layout::Vertical:
{
// centers the toolbar on the right edge of the 3d scene
if (orientation == GLToolbar::Layout::Left)
{
top = 0.5f * m_toolbar.get_height() * inv_zoom;
left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom;
}
else
{
top = 0.5f * m_toolbar.get_height() * inv_zoom;
left = (0.5f * (float)cnv_size.get_width() - m_toolbar.get_width()) * inv_zoom;
}
break;
}
}
m_toolbar.set_position(top, left);
#else
#if ENABLE_RETINA_GL
m_toolbar.set_icons_scale(m_retina_helper->get_scale_factor());
#else
m_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor());
#endif /* __WXMSW__ */
#endif // ENABLE_SVG_ICONS
m_toolbar.render(*this);
}
@ -6189,11 +6547,28 @@ void GLCanvas3D::_render_toolbar() const
void GLCanvas3D::_render_view_toolbar() const
{
if (m_view_toolbar != nullptr) {
#if ENABLE_SVG_ICONS
#if ENABLE_RETINA_GL
m_view_toolbar->set_scale(m_retina_helper->get_scale_factor());
#else
m_view_toolbar->set_scale(m_canvas->GetContentScaleFactor());
#endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size();
float zoom = get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
// places the toolbar on the bottom-left corner of the 3d scene
float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar->get_height()) * inv_zoom;
float left = -0.5f * (float)cnv_size.get_width() * inv_zoom;
m_view_toolbar->set_position(top, left);
#else
#if ENABLE_RETINA_GL
m_view_toolbar->set_icons_scale(m_retina_helper->get_scale_factor());
#else
m_view_toolbar->set_icons_scale(m_canvas->GetContentScaleFactor());
#endif /* __WXMSW__ */
#endif // ENABLE_SVG_ICONS
m_view_toolbar->render(*this);
}
}
@ -7682,6 +8057,7 @@ bool GLCanvas3D::_is_any_volume_outside() const
return false;
}
#if !ENABLE_SVG_ICONS
void GLCanvas3D::_resize_toolbars() const
{
Size cnv_size = get_canvas_size();
@ -7749,6 +8125,7 @@ void GLCanvas3D::_resize_toolbars() const
m_view_toolbar->set_position(top, left);
}
}
#endif // !ENABLE_SVG_ICONS
const Print* GLCanvas3D::fff_print() const
{