Use wxWidgets tooltip for 3D scene toolbar

This commit is contained in:
Enrico Turri 2018-07-25 10:01:17 +02:00
parent 496a83bb28
commit 93a05c4946
4 changed files with 32 additions and 149 deletions

View file

@ -3438,6 +3438,14 @@ void GLCanvas3D::reset_legend_texture()
m_legend_texture.reset();
}
//###################################################################################################################################
void GLCanvas3D::set_tooltip(const std::string& tooltip)
{
if (m_canvas != nullptr)
m_canvas->SetToolTip(tooltip);
}
//###################################################################################################################################
bool GLCanvas3D::_is_shown_on_screen() const
{
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
@ -3518,7 +3526,7 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "ccw45";
item.tooltip = GUI::L_str("Rotate CCW 45°");
item.tooltip = GUI::L_str("Rotate CCW 45 degrees");
item.textures[GLToolbarItem::Normal] = "arrow_rotate_anticlockwise_normal_36.png";
item.textures[GLToolbarItem::Hover] = "arrow_rotate_anticlockwise_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "arrow_rotate_anticlockwise_pressed_36.png";
@ -3527,7 +3535,7 @@ bool GLCanvas3D::_init_toolbar()
return false;
item.name = "cw45";
item.tooltip = GUI::L_str("Rotate CW 45°");
item.tooltip = GUI::L_str("Rotate CW 45 degrees");
item.textures[GLToolbarItem::Normal] = "arrow_rotate_clockwise_normal_36.png";
item.textures[GLToolbarItem::Hover] = "arrow_rotate_clockwise_hover_36.png";
item.textures[GLToolbarItem::Pressed] = "arrow_rotate_clockwise_pressed_36.png";
@ -3886,7 +3894,7 @@ void GLCanvas3D::_picking_pass() const
m_gizmos.reset_all_states();
//###################################################################################################################################
m_toolbar.update_hover_state(*this, pos);
m_toolbar.update_hover_state(const_cast<GLCanvas3D&>(*this), pos);
//###################################################################################################################################
}
}

View file

@ -619,6 +619,10 @@ public:
void reset_legend_texture();
//###################################################################################################################################
void set_tooltip(const std::string& tooltip);
//###################################################################################################################################
private:
bool _is_shown_on_screen() const;
void _force_zoom_to_bed();

View file

@ -12,85 +12,11 @@
namespace Slic3r {
namespace GUI {
const unsigned char GLToolbarItem::TooltipTexture::Border_Color[3] = { 0, 0, 0 };
const int GLToolbarItem::TooltipTexture::Border_Offset = 5;
bool GLToolbarItem::TooltipTexture::generate(const std::string& text)
{
reset();
if (text.empty())
return false;
wxMemoryDC memDC;
// select default font
memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
// calculates texture size
wxCoord w, h;
memDC.GetTextExtent(text, &w, &h);
m_width = (int)w + 2 * Border_Offset;
m_height = (int)h + 2 * Border_Offset;
// generates bitmap
wxBitmap bitmap(m_width, m_height);
memDC.SelectObject(bitmap);
memDC.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK));
memDC.Clear();
// draw message
memDC.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT));
memDC.DrawText(text, (wxCoord)Border_Offset, (wxCoord)Border_Offset);
wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVEBORDER));
memDC.SetPen(pen);
wxCoord ww = (wxCoord)m_width - 1;
wxCoord hh = (wxCoord)m_height - 1;
memDC.DrawLine(0, 0, ww, 0);
memDC.DrawLine(ww, 0, ww, hh);
memDC.DrawLine(ww, hh, 0, hh);
memDC.DrawLine(0, hh, 0, 0);
memDC.SelectObject(wxNullBitmap);
// Convert the bitmap into a linear data ready to be loaded into the GPU.
wxImage image = bitmap.ConvertToImage();
// prepare buffer
std::vector<unsigned char> data(4 * m_width * m_height, 0);
for (int h = 0; h < m_height; ++h)
{
int hh = h * m_width;
unsigned char* px_ptr = data.data() + 4 * hh;
for (int w = 0; w < m_width; ++w)
{
*px_ptr++ = image.GetRed(w, h);
*px_ptr++ = image.GetGreen(w, h);
*px_ptr++ = image.GetBlue(w, h);
*px_ptr++ = 255;
}
}
// sends buffer to gpu
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
::glGenTextures(1, &m_id);
::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id);
::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);
::glBindTexture(GL_TEXTURE_2D, 0);
return true;
}
GLToolbarItem::GLToolbarItem(EType type, const std::string& name, const std::string& tooltip)
: m_type(type)
, m_state(Disabled)
, m_name(name)
, m_tooltip(tooltip)
, m_tooltip_shown(false)
{
}
@ -108,12 +34,6 @@ bool GLToolbarItem::load_textures(const std::string* filenames)
return false;
}
if ((m_type == Action) && !m_tooltip.empty())
{
if (!m_tooltip_texture.generate(m_tooltip))
return false;
}
return true;
}
@ -132,19 +52,9 @@ const std::string& GLToolbarItem::get_name() const
return m_name;
}
void GLToolbarItem::show_tooltip()
const std::string& GLToolbarItem::get_tooltip() const
{
m_tooltip_shown = true;
}
void GLToolbarItem::hide_tooltip()
{
m_tooltip_shown = false;
}
bool GLToolbarItem::is_tooltip_shown() const
{
return m_tooltip_shown && (m_tooltip_texture.get_id() > 0);
return m_tooltip;
}
unsigned int GLToolbarItem::get_icon_texture_id() const
@ -157,21 +67,6 @@ int GLToolbarItem::get_icon_textures_size() const
return m_icon_textures[Normal].get_width();
}
unsigned int GLToolbarItem::get_tooltip_texture_id() const
{
return m_tooltip_texture.get_id();
}
int GLToolbarItem::get_tooltip_texture_width() const
{
return m_tooltip_texture.get_width();
}
int GLToolbarItem::get_tooltip_texture_height() const
{
return m_tooltip_texture.get_height();
}
bool GLToolbarItem::is_separator() const
{
return m_type == Separator;
@ -224,9 +119,6 @@ bool GLToolbar::add_item(const GLToolbar::ItemCreationData& data)
m_items.push_back(item);
if (data.name == "add")
item->show_tooltip();
return true;
}
@ -264,7 +156,7 @@ void GLToolbar::disable_item(const std::string& name)
}
}
void GLToolbar::update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse_pos)
void GLToolbar::update_hover_state(GLCanvas3D& canvas, const Pointf& mouse_pos)
{
if (!m_enabled)
return;
@ -274,6 +166,8 @@ void GLToolbar::update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse
float left = 0.5f * (cnv_w - width);
float top = m_offset_y;
std::string tooltip = "";
for (GLToolbarItem* item : m_items)
{
if (item->is_separator())
@ -297,6 +191,14 @@ void GLToolbar::update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse
break;
}
case GLToolbarItem::Hover:
{
if (inside)
tooltip = item->get_tooltip();
else
item->set_state(GLToolbarItem::Normal);
break;
}
case GLToolbarItem::Pressed:
{
if (!inside)
@ -313,6 +215,8 @@ void GLToolbar::update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse
left += (tex_size + m_gap_x);
}
}
canvas.set_tooltip(tooltip);
}
void GLToolbar::render(const GLCanvas3D& canvas, const Pointf& mouse_pos) const
@ -349,20 +253,6 @@ void GLToolbar::render(const GLCanvas3D& canvas, const Pointf& mouse_pos) const
}
}
// renders tooltip
for (const GLToolbarItem* item : m_items)
{
if (!item->is_separator() && item->is_tooltip_shown())
{
float l = (-0.5f * cnv_w + (float)mouse_pos.x) * inv_zoom;
float r = l + (float)item->get_tooltip_texture_width() * inv_zoom;
float t = (0.5f * cnv_h - (float)mouse_pos.y) * inv_zoom;
float b = t - (float)item->get_tooltip_texture_height() * inv_zoom;
GLTexture::render_texture(item->get_tooltip_texture_id(), l, r, b, t);
break;
}
}
::glPopMatrix();
}

View file

@ -33,19 +33,9 @@ public:
Num_States
};
class TooltipTexture : public GLTexture
{
static const unsigned char Border_Color[3];
static const int Border_Offset;
public:
bool generate(const std::string& text);
};
private:
// icon textures are assumed to be square and all with the same size in pixels, no internal check is done
GLTexture m_icon_textures[Num_States];
TooltipTexture m_tooltip_texture;
EType m_type;
EState m_state;
@ -53,8 +43,6 @@ private:
std::string m_name;
std::string m_tooltip;
bool m_tooltip_shown;
public:
GLToolbarItem(EType type, const std::string& name, const std::string& tooltip);
@ -65,18 +53,11 @@ public:
const std::string& get_name() const;
void show_tooltip();
void hide_tooltip();
bool is_tooltip_shown() const;
const std::string& get_tooltip() const;
unsigned int get_icon_texture_id() const;
int get_icon_textures_size() const;
unsigned int get_tooltip_texture_id() const;
int get_tooltip_texture_width() const;
int get_tooltip_texture_height() const;
bool is_separator() const;
};
@ -118,7 +99,7 @@ public:
void enable_item(const std::string& name);
void disable_item(const std::string& name);
void update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse_pos);
void update_hover_state(GLCanvas3D& canvas, const Pointf& mouse_pos);
void render(const GLCanvas3D& canvas, const Pointf& mouse_pos) const;