2018-12-06 11:52:28 +00:00
|
|
|
#include "libslic3r/Point.hpp"
|
|
|
|
#include "libslic3r/libslic3r.h"
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
#include "GLToolbar.hpp"
|
|
|
|
|
|
|
|
#include "../../slic3r/GUI/GLCanvas3D.hpp"
|
|
|
|
|
|
|
|
#include <GL/glew.h>
|
|
|
|
|
2018-09-17 10:15:11 +00:00
|
|
|
#include <wx/event.h>
|
2018-07-23 11:49:48 +00:00
|
|
|
#include <wx/bitmap.h>
|
|
|
|
#include <wx/dcmemory.h>
|
|
|
|
#include <wx/settings.h>
|
2018-09-17 10:15:11 +00:00
|
|
|
#include <wx/glcanvas.h>
|
2018-07-23 11:49:48 +00:00
|
|
|
|
|
|
|
namespace Slic3r {
|
|
|
|
namespace GUI {
|
|
|
|
|
2018-09-17 10:15:11 +00:00
|
|
|
|
2018-10-03 09:34:39 +00:00
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
|
2018-10-24 10:55:38 +00:00
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_VOLUMES, SimpleEvent);
|
2018-10-03 09:34:39 +00:00
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent);
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_3D, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_PREVIEW, SimpleEvent);
|
2018-09-17 10:15:11 +00:00
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
GLToolbarItem::Data::Data()
|
|
|
|
: name("")
|
|
|
|
, tooltip("")
|
|
|
|
, sprite_id(-1)
|
|
|
|
, is_toggable(false)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Data& data)
|
|
|
|
: m_type(type)
|
|
|
|
, m_state(Disabled)
|
|
|
|
, m_data(data)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GLToolbarItem::EState GLToolbarItem::get_state() const
|
|
|
|
{
|
|
|
|
return m_state;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLToolbarItem::set_state(GLToolbarItem::EState state)
|
|
|
|
{
|
|
|
|
m_state = state;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string& GLToolbarItem::get_name() const
|
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
return m_data.name;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 08:01:17 +00:00
|
|
|
const std::string& GLToolbarItem::get_tooltip() const
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
return m_data.tooltip;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-09-17 10:15:11 +00:00
|
|
|
void GLToolbarItem::do_action(wxEvtHandler *target)
|
2018-07-27 10:08:33 +00:00
|
|
|
{
|
2018-10-03 09:34:39 +00:00
|
|
|
wxPostEvent(target, SimpleEvent(m_data.action_event));
|
2018-07-27 10:08:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool GLToolbarItem::is_enabled() const
|
|
|
|
{
|
|
|
|
return m_state != Disabled;
|
|
|
|
}
|
|
|
|
|
2018-07-27 12:38:19 +00:00
|
|
|
bool GLToolbarItem::is_hovered() const
|
|
|
|
{
|
|
|
|
return (m_state == Hover) || (m_state == HoverPressed);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLToolbarItem::is_pressed() const
|
|
|
|
{
|
|
|
|
return (m_state == Pressed) || (m_state == HoverPressed);
|
|
|
|
}
|
|
|
|
|
2018-07-27 10:08:33 +00:00
|
|
|
bool GLToolbarItem::is_toggable() const
|
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
return m_data.is_toggable;
|
2018-07-27 10:08:33 +00:00
|
|
|
}
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
bool GLToolbarItem::is_separator() const
|
|
|
|
{
|
|
|
|
return m_type == Separator;
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size));
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
GLTexture::Quad_UVs uvs;
|
|
|
|
|
|
|
|
float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f;
|
|
|
|
|
|
|
|
float scaled_icon_size = (float)icon_size * inv_texture_size;
|
|
|
|
float scaled_border_size = (float)border_size * inv_texture_size;
|
|
|
|
float scaled_gap_size = (float)gap_size * inv_texture_size;
|
|
|
|
float stride = scaled_icon_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = scaled_border_size + (float)m_state * stride;
|
|
|
|
float right = left + scaled_icon_size;
|
|
|
|
float top = scaled_border_size + (float)m_data.sprite_id * stride;
|
|
|
|
float bottom = top + scaled_icon_size;
|
|
|
|
|
|
|
|
uvs.left_top = { left, top };
|
|
|
|
uvs.left_bottom = { left, bottom };
|
|
|
|
uvs.right_bottom = { right, bottom };
|
|
|
|
uvs.right_top = { right, top };
|
|
|
|
|
|
|
|
return uvs;
|
|
|
|
}
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
ItemsIconsTexture::ItemsIconsTexture()
|
2018-07-31 10:25:00 +00:00
|
|
|
: items_icon_size(0)
|
|
|
|
, items_icon_border_size(0)
|
|
|
|
, items_icon_gap_size(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GLToolbar::Layout::Layout()
|
|
|
|
: type(Horizontal)
|
|
|
|
, top(0.0f)
|
|
|
|
, left(0.0f)
|
|
|
|
, separator_size(0.0f)
|
|
|
|
, gap_size(0.0f)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-07-27 12:38:19 +00:00
|
|
|
GLToolbar::GLToolbar(GLCanvas3D& parent)
|
|
|
|
: m_parent(parent)
|
|
|
|
, m_enabled(false)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-10-24 08:55:35 +00:00
|
|
|
GLToolbar::~GLToolbar()
|
|
|
|
{
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
bool GLToolbar::init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
std::string path = resources_dir() + "/icons/";
|
|
|
|
bool res = !icons_texture_filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture_filename, false);
|
|
|
|
if (res)
|
|
|
|
{
|
|
|
|
m_icons_texture.items_icon_size = items_icon_size;
|
|
|
|
m_icons_texture.items_icon_border_size = items_icon_border_size;
|
|
|
|
m_icons_texture.items_icon_gap_size = items_icon_gap_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
GLToolbar::Layout::Type GLToolbar::get_layout_type() const
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
return m_layout.type;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
void GLToolbar::set_layout_type(GLToolbar::Layout::Type type)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
m_layout.type = type;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
void GLToolbar::set_position(float top, float left)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
m_layout.top = top;
|
|
|
|
m_layout.left = left;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
void GLToolbar::set_separator_size(float size)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
m_layout.separator_size = size;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
void GLToolbar::set_gap_size(float size)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
m_layout.gap_size = size;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
bool GLToolbar::is_enabled() const
|
|
|
|
{
|
|
|
|
return m_enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLToolbar::set_enabled(bool enable)
|
|
|
|
{
|
|
|
|
m_enabled = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLToolbar::add_item(const GLToolbarItem::Data& data)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Action, data);
|
|
|
|
if (item == nullptr)
|
2018-07-23 11:49:48 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
m_items.push_back(item);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLToolbar::add_separator()
|
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
GLToolbarItem::Data data;
|
|
|
|
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Separator, data);
|
2018-07-23 11:49:48 +00:00
|
|
|
if (item == nullptr)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
m_items.push_back(item);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
float GLToolbar::get_width() const
|
|
|
|
{
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case Layout::Horizontal:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return get_width_horizontal();
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
case Layout::Vertical:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return get_width_vertical();
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
float GLToolbar::get_height() const
|
|
|
|
{
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case Layout::Horizontal:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return get_height_horizontal();
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
case Layout::Vertical:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return get_height_vertical();
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
void GLToolbar::enable_item(const std::string& name)
|
|
|
|
{
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
2018-07-27 12:38:19 +00:00
|
|
|
if ((item->get_name() == name) && (item->get_state() == GLToolbarItem::Disabled))
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
|
|
|
item->set_state(GLToolbarItem::Normal);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLToolbar::disable_item(const std::string& name)
|
|
|
|
{
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (item->get_name() == name)
|
|
|
|
{
|
|
|
|
item->set_state(GLToolbarItem::Disabled);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-27 10:08:33 +00:00
|
|
|
bool GLToolbar::is_item_pressed(const std::string& name) const
|
|
|
|
{
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (item->get_name() == name)
|
2018-07-27 12:38:19 +00:00
|
|
|
return item->is_pressed();
|
2018-07-27 10:08:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
|
|
|
std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos)
|
|
|
|
#else
|
2018-08-23 13:37:38 +00:00
|
|
|
void GLToolbar::update_hover_state(const Vec2d& mouse_pos)
|
2018-12-06 09:38:19 +00:00
|
|
|
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-12-06 09:38:19 +00:00
|
|
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
|
|
|
if (!m_enabled)
|
|
|
|
return "";
|
|
|
|
#else
|
2018-07-23 11:49:48 +00:00
|
|
|
if (!m_enabled)
|
|
|
|
return;
|
2018-12-06 09:38:19 +00:00
|
|
|
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
2018-12-06 09:38:19 +00:00
|
|
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
|
|
|
case Layout::Horizontal: { return update_hover_state_horizontal(mouse_pos); }
|
|
|
|
case Layout::Vertical: { return update_hover_state_vertical(mouse_pos); }
|
|
|
|
#else
|
2018-07-31 10:25:00 +00:00
|
|
|
case Layout::Horizontal:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
update_hover_state_horizontal(mouse_pos);
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Layout::Vertical:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
update_hover_state_vertical(mouse_pos);
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-12-06 09:38:19 +00:00
|
|
|
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-23 13:37:38 +00:00
|
|
|
int GLToolbar::contains_mouse(const Vec2d& mouse_pos) const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
if (!m_enabled)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case Layout::Horizontal:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return contains_mouse_horizontal(mouse_pos);
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
case Layout::Vertical:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return contains_mouse_vertical(mouse_pos);
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLToolbar::do_action(unsigned int item_id)
|
|
|
|
{
|
|
|
|
if (item_id < (unsigned int)m_items.size())
|
|
|
|
{
|
|
|
|
GLToolbarItem* item = m_items[item_id];
|
|
|
|
if ((item != nullptr) && !item->is_separator() && item->is_hovered())
|
|
|
|
{
|
|
|
|
if (item->is_toggable())
|
|
|
|
{
|
|
|
|
GLToolbarItem::EState state = item->get_state();
|
|
|
|
if (state == GLToolbarItem::Hover)
|
|
|
|
item->set_state(GLToolbarItem::HoverPressed);
|
|
|
|
else if (state == GLToolbarItem::HoverPressed)
|
|
|
|
item->set_state(GLToolbarItem::Hover);
|
|
|
|
|
|
|
|
m_parent.render();
|
2018-10-04 08:41:11 +00:00
|
|
|
item->do_action(m_parent.get_wxglcanvas());
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->set_state(GLToolbarItem::HoverPressed);
|
|
|
|
m_parent.render();
|
2018-10-04 08:41:11 +00:00
|
|
|
item->do_action(m_parent.get_wxglcanvas());
|
2018-07-31 10:25:00 +00:00
|
|
|
if (item->get_state() != GLToolbarItem::Disabled)
|
|
|
|
{
|
|
|
|
// the item may get disabled during the action, if not, set it back to hover state
|
|
|
|
item->set_state(GLToolbarItem::Hover);
|
|
|
|
m_parent.render();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLToolbar::render() const
|
|
|
|
{
|
|
|
|
if (!m_enabled || m_items.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
::glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
::glPushMatrix();
|
|
|
|
::glLoadIdentity();
|
|
|
|
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case Layout::Horizontal:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
render_horizontal();
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Layout::Vertical:
|
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
render_vertical();
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
::glPopMatrix();
|
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
float GLToolbar::get_width_horizontal() const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return get_main_size();
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
float GLToolbar::get_width_vertical() const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
return m_icons_texture.items_icon_size;
|
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
float GLToolbar::get_height_horizontal() const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
return m_icons_texture.items_icon_size;
|
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
float GLToolbar::get_height_vertical() const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
2018-08-24 10:32:14 +00:00
|
|
|
return get_main_size();
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
float GLToolbar::get_main_size() const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
float size = 0.0f;
|
|
|
|
for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
|
|
|
|
{
|
|
|
|
if (m_items[i]->is_separator())
|
|
|
|
size += m_layout.separator_size;
|
|
|
|
else
|
|
|
|
size += (float)m_icons_texture.items_icon_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_items.size() > 1)
|
|
|
|
size += ((float)m_items.size() - 1.0f) * m_layout.gap_size;
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
|
|
|
std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos)
|
|
|
|
#else
|
2018-08-24 10:32:14 +00:00
|
|
|
void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos)
|
2018-12-06 09:38:19 +00:00
|
|
|
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
float zoom = m_parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
|
|
|
Size cnv_size = m_parent.get_canvas_size();
|
2018-08-23 13:37:38 +00:00
|
|
|
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
float scaled_separator_size = m_layout.separator_size * inv_zoom;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * inv_zoom;
|
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
|
|
|
|
|
|
|
std::string tooltip = "";
|
|
|
|
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (item->is_separator())
|
|
|
|
left += separator_stride;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float right = left + scaled_icons_size;
|
|
|
|
float bottom = top - scaled_icons_size;
|
|
|
|
|
|
|
|
GLToolbarItem::EState state = item->get_state();
|
2018-08-23 13:37:38 +00:00
|
|
|
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case GLToolbarItem::Normal:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
item->set_state(GLToolbarItem::Hover);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::Hover:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
|
|
|
else
|
|
|
|
item->set_state(GLToolbarItem::Normal);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::Pressed:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
item->set_state(GLToolbarItem::HoverPressed);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::HoverPressed:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
|
|
|
else
|
|
|
|
item->set_state(GLToolbarItem::Pressed);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
case GLToolbarItem::Disabled:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
left += icon_stride;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
|
|
|
return tooltip;
|
|
|
|
#else
|
2018-10-25 07:35:08 +00:00
|
|
|
if (!tooltip.empty())
|
|
|
|
m_parent.set_tooltip(tooltip);
|
2018-12-06 09:38:19 +00:00
|
|
|
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
|
|
|
std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos)
|
|
|
|
#else
|
2018-08-24 10:32:14 +00:00
|
|
|
void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos)
|
2018-12-06 09:38:19 +00:00
|
|
|
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
float zoom = m_parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
|
|
|
Size cnv_size = m_parent.get_canvas_size();
|
2018-08-23 13:37:38 +00:00
|
|
|
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
float scaled_separator_size = m_layout.separator_size * inv_zoom;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * inv_zoom;
|
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2018-07-25 08:01:17 +00:00
|
|
|
std::string tooltip = "";
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (item->is_separator())
|
2018-07-31 10:25:00 +00:00
|
|
|
top -= separator_stride;
|
2018-07-23 11:49:48 +00:00
|
|
|
else
|
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
float right = left + scaled_icons_size;
|
|
|
|
float bottom = top - scaled_icons_size;
|
2018-07-23 11:49:48 +00:00
|
|
|
|
|
|
|
GLToolbarItem::EState state = item->get_state();
|
2018-08-23 13:37:38 +00:00
|
|
|
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
|
2018-07-23 11:49:48 +00:00
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case GLToolbarItem::Normal:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
item->set_state(GLToolbarItem::Hover);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::Hover:
|
2018-07-25 08:01:17 +00:00
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
|
|
|
else
|
|
|
|
item->set_state(GLToolbarItem::Normal);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2018-07-23 11:49:48 +00:00
|
|
|
case GLToolbarItem::Pressed:
|
|
|
|
{
|
2018-07-27 10:08:33 +00:00
|
|
|
if (inside)
|
|
|
|
item->set_state(GLToolbarItem::HoverPressed);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::HoverPressed:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
|
|
|
else
|
|
|
|
item->set_state(GLToolbarItem::Pressed);
|
2018-07-23 11:49:48 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
case GLToolbarItem::Disabled:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
top -= icon_stride;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-25 08:01:17 +00:00
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
|
|
|
return tooltip;
|
|
|
|
#else
|
2018-07-27 12:38:19 +00:00
|
|
|
m_parent.set_tooltip(tooltip);
|
2018-12-06 09:38:19 +00:00
|
|
|
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos) const
|
2018-07-27 10:08:33 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
float zoom = m_parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
2018-07-27 10:08:33 +00:00
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
Size cnv_size = m_parent.get_canvas_size();
|
2018-08-23 13:37:38 +00:00
|
|
|
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
|
2018-07-27 10:08:33 +00:00
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
float scaled_separator_size = m_layout.separator_size * inv_zoom;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * inv_zoom;
|
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
2018-07-27 10:08:33 +00:00
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
int id = -1;
|
|
|
|
|
2018-07-27 10:08:33 +00:00
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
++id;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-07-27 10:08:33 +00:00
|
|
|
if (item->is_separator())
|
2018-07-31 10:25:00 +00:00
|
|
|
left += separator_stride;
|
2018-07-27 10:08:33 +00:00
|
|
|
else
|
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
float right = left + scaled_icons_size;
|
|
|
|
float bottom = top - scaled_icons_size;
|
|
|
|
|
2018-08-23 13:37:38 +00:00
|
|
|
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
|
2018-07-27 10:08:33 +00:00
|
|
|
return id;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
left += icon_stride;
|
2018-07-27 10:08:33 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-07-27 10:08:33 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos) const
|
2018-07-27 10:08:33 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
float zoom = m_parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
|
|
|
Size cnv_size = m_parent.get_canvas_size();
|
2018-08-23 13:37:38 +00:00
|
|
|
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
float scaled_separator_size = m_layout.separator_size * inv_zoom;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * inv_zoom;
|
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
|
|
|
|
|
|
|
int id = -1;
|
|
|
|
|
|
|
|
for (GLToolbarItem* item : m_items)
|
2018-07-27 10:08:33 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
++id;
|
|
|
|
|
|
|
|
if (item->is_separator())
|
|
|
|
top -= separator_stride;
|
|
|
|
else
|
2018-07-27 10:08:33 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
float right = left + scaled_icons_size;
|
|
|
|
float bottom = top - scaled_icons_size;
|
2018-07-27 10:08:33 +00:00
|
|
|
|
2018-08-23 13:37:38 +00:00
|
|
|
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
|
2018-07-31 10:25:00 +00:00
|
|
|
return id;
|
|
|
|
|
|
|
|
top -= icon_stride;
|
2018-07-27 10:08:33 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
return -1;
|
2018-07-27 10:08:33 +00:00
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
void GLToolbar::render_horizontal() const
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
unsigned int tex_id = m_icons_texture.texture.get_id();
|
|
|
|
int tex_size = m_icons_texture.texture.get_width();
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
if ((tex_id == 0) || (tex_size <= 0))
|
|
|
|
return;
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2018-07-27 12:38:19 +00:00
|
|
|
float zoom = m_parent.get_camera_zoom();
|
2018-07-23 11:49:48 +00:00
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
float scaled_separator_size = m_layout.separator_size * inv_zoom;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * inv_zoom;
|
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
2018-07-23 11:49:48 +00:00
|
|
|
|
|
|
|
// renders icons
|
|
|
|
for (const GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (item->is_separator())
|
2018-07-31 10:25:00 +00:00
|
|
|
left += separator_stride;
|
2018-07-23 11:49:48 +00:00
|
|
|
else
|
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.items_icon_border_size, m_icons_texture.items_icon_size, m_icons_texture.items_icon_gap_size);
|
|
|
|
left += icon_stride;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
void GLToolbar::render_vertical() const
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
unsigned int tex_id = m_icons_texture.texture.get_id();
|
|
|
|
int tex_size = m_icons_texture.texture.get_width();
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
if ((tex_id == 0) || (tex_size <= 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
float zoom = m_parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
float scaled_separator_size = m_layout.separator_size * inv_zoom;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * inv_zoom;
|
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
|
|
|
|
|
|
|
// renders icons
|
|
|
|
for (const GLToolbarItem* item : m_items)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
if (item->is_separator())
|
|
|
|
top -= separator_stride;
|
2018-07-23 11:49:48 +00:00
|
|
|
else
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.items_icon_border_size, m_icons_texture.items_icon_size, m_icons_texture.items_icon_gap_size);
|
|
|
|
top -= icon_stride;
|
|
|
|
}
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
GLRadioToolbarItem::Data::Data()
|
|
|
|
: name("")
|
|
|
|
, tooltip("")
|
|
|
|
, sprite_id(-1)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GLRadioToolbarItem::GLRadioToolbarItem(const GLRadioToolbarItem::Data& data)
|
|
|
|
: m_state(Normal)
|
|
|
|
, m_data(data)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GLRadioToolbarItem::EState GLRadioToolbarItem::get_state() const
|
|
|
|
{
|
|
|
|
return m_state;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLRadioToolbarItem::set_state(GLRadioToolbarItem::EState state)
|
|
|
|
{
|
|
|
|
m_state = state;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string& GLRadioToolbarItem::get_name() const
|
|
|
|
{
|
|
|
|
return m_data.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string& GLRadioToolbarItem::get_tooltip() const
|
|
|
|
{
|
|
|
|
return m_data.tooltip;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLRadioToolbarItem::is_hovered() const
|
|
|
|
{
|
|
|
|
return (m_state == Hover) || (m_state == HoverPressed);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLRadioToolbarItem::is_pressed() const
|
|
|
|
{
|
|
|
|
return (m_state == Pressed) || (m_state == HoverPressed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLRadioToolbarItem::do_action(wxEvtHandler *target)
|
|
|
|
{
|
|
|
|
wxPostEvent(target, SimpleEvent(m_data.action_event));
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLRadioToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
|
|
|
|
{
|
|
|
|
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size));
|
|
|
|
}
|
|
|
|
|
|
|
|
GLTexture::Quad_UVs GLRadioToolbarItem::get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
|
|
|
|
{
|
|
|
|
GLTexture::Quad_UVs uvs;
|
|
|
|
|
|
|
|
float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f;
|
|
|
|
|
|
|
|
float scaled_icon_size = (float)icon_size * inv_texture_size;
|
|
|
|
float scaled_border_size = (float)border_size * inv_texture_size;
|
|
|
|
float scaled_gap_size = (float)gap_size * inv_texture_size;
|
|
|
|
float stride = scaled_icon_size + scaled_gap_size;
|
|
|
|
|
|
|
|
float left = scaled_border_size + (float)m_state * stride;
|
|
|
|
float right = left + scaled_icon_size;
|
|
|
|
float top = scaled_border_size + (float)m_data.sprite_id * stride;
|
|
|
|
float bottom = top + scaled_icon_size;
|
|
|
|
|
|
|
|
uvs.left_top = { left, top };
|
|
|
|
uvs.left_bottom = { left, bottom };
|
|
|
|
uvs.right_bottom = { right, bottom };
|
|
|
|
uvs.right_top = { right, top };
|
|
|
|
|
|
|
|
return uvs;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLRadioToolbar::GLRadioToolbar()
|
|
|
|
: m_top(0.0f)
|
|
|
|
, m_left(0.0f)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GLRadioToolbar::~GLRadioToolbar()
|
|
|
|
{
|
|
|
|
for (GLRadioToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLRadioToolbar::init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size)
|
|
|
|
{
|
|
|
|
if (m_icons_texture.texture.get_id() != 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
std::string path = resources_dir() + "/icons/";
|
|
|
|
bool res = !icons_texture_filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture_filename, false);
|
|
|
|
if (res)
|
|
|
|
{
|
|
|
|
m_icons_texture.items_icon_size = items_icon_size;
|
|
|
|
m_icons_texture.items_icon_border_size = items_icon_border_size;
|
|
|
|
m_icons_texture.items_icon_gap_size = items_icon_gap_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLRadioToolbar::add_item(const GLRadioToolbarItem::Data& data)
|
|
|
|
{
|
|
|
|
GLRadioToolbarItem* item = new GLRadioToolbarItem(data);
|
|
|
|
if (item == nullptr)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
m_items.push_back(item);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
float GLRadioToolbar::get_height() const
|
|
|
|
{
|
|
|
|
return m_icons_texture.items_icon_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLRadioToolbar::set_position(float top, float left)
|
|
|
|
{
|
|
|
|
m_top = top;
|
|
|
|
m_left = left;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLRadioToolbar::set_selection(const std::string& name)
|
|
|
|
{
|
|
|
|
for (GLRadioToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
item->set_state((item->get_name() == name) ? GLRadioToolbarItem::Pressed : GLRadioToolbarItem::Normal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int GLRadioToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
|
|
|
|
{
|
|
|
|
float zoom = parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
|
|
|
Size cnv_size = parent.get_canvas_size();
|
|
|
|
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
|
|
|
|
|
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
|
|
|
|
float left = m_left;
|
|
|
|
float top = m_top;
|
|
|
|
|
|
|
|
int id = -1;
|
|
|
|
|
|
|
|
for (GLRadioToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
++id;
|
|
|
|
|
|
|
|
float right = left + scaled_icons_size;
|
|
|
|
float bottom = top - scaled_icons_size;
|
|
|
|
|
|
|
|
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
|
|
|
|
return id;
|
|
|
|
|
|
|
|
left += scaled_icons_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-12-06 11:37:39 +00:00
|
|
|
std::string GLRadioToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent)
|
2018-12-06 09:38:19 +00:00
|
|
|
{
|
|
|
|
float zoom = parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
|
|
|
Size cnv_size = parent.get_canvas_size();
|
|
|
|
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
|
|
|
|
|
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
|
|
|
|
float left = m_left;
|
|
|
|
float top = m_top;
|
|
|
|
|
|
|
|
std::string tooltip = "";
|
|
|
|
|
|
|
|
for (GLRadioToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
float right = left + scaled_icons_size;
|
|
|
|
float bottom = top - scaled_icons_size;
|
|
|
|
|
|
|
|
GLRadioToolbarItem::EState state = item->get_state();
|
|
|
|
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
|
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case GLRadioToolbarItem::Normal:
|
|
|
|
{
|
|
|
|
if (inside)
|
2018-12-06 11:37:39 +00:00
|
|
|
{
|
2018-12-06 09:38:19 +00:00
|
|
|
item->set_state(GLRadioToolbarItem::Hover);
|
2018-12-06 11:37:39 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-12-06 09:38:19 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLRadioToolbarItem::Hover:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
|
|
|
else
|
2018-12-06 11:37:39 +00:00
|
|
|
{
|
2018-12-06 09:38:19 +00:00
|
|
|
item->set_state(GLRadioToolbarItem::Normal);
|
2018-12-06 11:37:39 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-12-06 09:38:19 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLRadioToolbarItem::Pressed:
|
|
|
|
{
|
|
|
|
if (inside)
|
2018-12-06 11:37:39 +00:00
|
|
|
{
|
2018-12-06 09:38:19 +00:00
|
|
|
item->set_state(GLRadioToolbarItem::HoverPressed);
|
2018-12-06 11:37:39 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-12-06 09:38:19 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLRadioToolbarItem::HoverPressed:
|
|
|
|
{
|
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
|
|
|
else
|
2018-12-06 11:37:39 +00:00
|
|
|
{
|
2018-12-06 09:38:19 +00:00
|
|
|
item->set_state(GLRadioToolbarItem::Pressed);
|
2018-12-06 11:37:39 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-12-06 09:38:19 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
left += scaled_icons_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tooltip;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLRadioToolbar::do_action(unsigned int item_id, GLCanvas3D& parent)
|
|
|
|
{
|
|
|
|
for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
|
|
|
|
{
|
|
|
|
if (i != item_id)
|
|
|
|
m_items[i]->set_state(GLRadioToolbarItem::Normal);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item_id < (unsigned int)m_items.size())
|
|
|
|
{
|
|
|
|
GLRadioToolbarItem* item = m_items[item_id];
|
|
|
|
if ((item != nullptr) && item->is_hovered() && !item->is_pressed())
|
|
|
|
{
|
|
|
|
item->set_state(GLRadioToolbarItem::HoverPressed);
|
|
|
|
item->do_action(parent.get_wxglcanvas());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLRadioToolbar::render(const GLCanvas3D& parent) const
|
|
|
|
{
|
|
|
|
if (m_items.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
::glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
::glPushMatrix();
|
|
|
|
::glLoadIdentity();
|
|
|
|
|
|
|
|
unsigned int tex_id = m_icons_texture.texture.get_id();
|
|
|
|
int tex_size = m_icons_texture.texture.get_width();
|
|
|
|
|
|
|
|
if ((tex_id == 0) || (tex_size <= 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
float zoom = parent.get_camera_zoom();
|
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
|
|
|
|
|
|
|
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
|
|
|
|
|
|
|
|
float left = m_left;
|
|
|
|
float top = m_top;
|
|
|
|
|
|
|
|
// renders icons
|
|
|
|
for (const GLRadioToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.items_icon_border_size, m_icons_texture.items_icon_size, m_icons_texture.items_icon_gap_size);
|
|
|
|
left += scaled_icons_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
::glPopMatrix();
|
|
|
|
}
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
} // namespace GUI
|
|
|
|
} // namespace Slic3r
|