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);
|
2019-04-11 11:20:34 +00:00
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent);
|
|
|
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent);
|
2018-10-03 09:34:39 +00:00
|
|
|
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
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
const GLToolbarItem::ActionCallback GLToolbarItem::Default_Action_Callback = [](){};
|
|
|
|
const GLToolbarItem::VisibilityCallback GLToolbarItem::Default_Visibility_Callback = []()->bool { return true; };
|
|
|
|
const GLToolbarItem::EnabledStateCallback GLToolbarItem::Default_Enabled_State_Callback = []()->bool { return true; };
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
GLToolbarItem::Data::Data()
|
|
|
|
: name("")
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
2019-02-26 09:40:00 +00:00
|
|
|
, icon_filename("")
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
, tooltip("")
|
|
|
|
, sprite_id(-1)
|
|
|
|
, is_toggable(false)
|
2019-01-31 12:19:26 +00:00
|
|
|
, visible(true)
|
2019-03-14 12:54:05 +00:00
|
|
|
, action_callback(Default_Action_Callback)
|
|
|
|
, visibility_callback(Default_Visibility_Callback)
|
|
|
|
, enabled_state_callback(Default_Enabled_State_Callback)
|
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)
|
2019-03-14 12:54:05 +00:00
|
|
|
, m_state(Normal)
|
2018-07-31 10:25:00 +00:00
|
|
|
, m_data(data)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
bool GLToolbarItem::update_visibility()
|
|
|
|
{
|
|
|
|
bool visible = m_data.visibility_callback();
|
|
|
|
bool ret = (m_data.visible != visible);
|
|
|
|
if (ret)
|
|
|
|
m_data.visible = visible;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLToolbarItem::update_enabled_state()
|
|
|
|
{
|
|
|
|
bool enabled = m_data.enabled_state_callback();
|
|
|
|
bool ret = (is_enabled() != enabled);
|
|
|
|
if (ret)
|
|
|
|
m_state = enabled ? GLToolbarItem::Normal : GLToolbarItem::Disabled;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2018-07-27 10:08:33 +00:00
|
|
|
|
2019-02-26 09:40:00 +00:00
|
|
|
void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
|
2019-02-22 09:01:34 +00:00
|
|
|
{
|
2019-02-26 09:40:00 +00:00
|
|
|
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size));
|
2019-02-22 09:01:34 +00:00
|
|
|
}
|
|
|
|
|
2019-02-26 09:40:00 +00:00
|
|
|
GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
GLTexture::Quad_UVs uvs;
|
|
|
|
|
2019-02-26 09:40:00 +00:00
|
|
|
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;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2019-02-26 09:40:00 +00:00
|
|
|
float scaled_icon_width = (float)icon_size * inv_tex_width;
|
|
|
|
float scaled_icon_height = (float)icon_size * inv_tex_height;
|
|
|
|
float left = (float)m_state * scaled_icon_width;
|
|
|
|
float right = left + scaled_icon_width;
|
|
|
|
float top = (float)m_data.sprite_id * scaled_icon_height;
|
|
|
|
float bottom = top + scaled_icon_height;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
uvs.left_top = { left, top };
|
|
|
|
uvs.left_bottom = { left, bottom };
|
|
|
|
uvs.right_bottom = { right, bottom };
|
|
|
|
uvs.right_top = { right, top };
|
|
|
|
|
|
|
|
return uvs;
|
|
|
|
}
|
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if !ENABLE_SVG_ICONS
|
2018-12-17 09:55:14 +00:00
|
|
|
ItemsIconsTexture::Metadata::Metadata()
|
|
|
|
: filename("")
|
|
|
|
, icon_size(0)
|
|
|
|
{
|
|
|
|
}
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // !ENABLE_SVG_ICONS
|
2018-12-17 09:55:14 +00:00
|
|
|
|
|
|
|
BackgroundTexture::Metadata::Metadata()
|
|
|
|
: filename("")
|
|
|
|
, left(0)
|
|
|
|
, right(0)
|
|
|
|
, top(0)
|
|
|
|
, bottom(0)
|
|
|
|
{
|
|
|
|
}
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
2019-05-22 11:51:02 +00:00
|
|
|
const float GLToolbar::Default_Icons_Size = 40.0f;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
GLToolbar::Layout::Layout()
|
|
|
|
: type(Horizontal)
|
2018-12-17 09:55:14 +00:00
|
|
|
, orientation(Center)
|
2018-07-31 10:25:00 +00:00
|
|
|
, top(0.0f)
|
|
|
|
, left(0.0f)
|
2018-12-17 09:55:14 +00:00
|
|
|
, border(0.0f)
|
2018-07-31 10:25:00 +00:00
|
|
|
, separator_size(0.0f)
|
|
|
|
, gap_size(0.0f)
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
, icons_size(Default_Icons_Size)
|
|
|
|
, scale(1.0f)
|
|
|
|
#else
|
2018-12-17 10:11:49 +00:00
|
|
|
, icons_scale(1.0f)
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-12-17 09:55:14 +00:00
|
|
|
, width(0.0f)
|
|
|
|
, height(0.0f)
|
|
|
|
, dirty(true)
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-02-26 11:56:13 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
GLToolbar::GLToolbar(GLToolbar::EType type, const std::string& name)
|
|
|
|
#else
|
2018-12-17 09:55:14 +00:00
|
|
|
GLToolbar::GLToolbar(GLToolbar::EType type)
|
2019-02-26 11:56:13 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-12-17 09:55:14 +00:00
|
|
|
: m_type(type)
|
2019-02-26 11:56:13 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
, m_name(name)
|
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-27 12:38:19 +00:00
|
|
|
, m_enabled(false)
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
, m_icons_texture_dirty(true)
|
|
|
|
#endif // ENABLE_SVG_ICONS
|
2019-03-14 12:54:05 +00:00
|
|
|
, m_tooltip("")
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
bool GLToolbar::init(const BackgroundTexture::Metadata& background_texture)
|
|
|
|
#else
|
2018-12-17 09:55:14 +00:00
|
|
|
bool GLToolbar::init(const ItemsIconsTexture::Metadata& icons_texture, const BackgroundTexture::Metadata& background_texture)
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
if (m_background_texture.texture.get_id() != 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
std::string path = resources_dir() + "/icons/";
|
|
|
|
bool res = false;
|
|
|
|
#else
|
2018-12-17 09:55:14 +00:00
|
|
|
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.metadata = icons_texture;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-12-17 09:55:14 +00:00
|
|
|
|
|
|
|
if (!background_texture.filename.empty())
|
|
|
|
res = m_background_texture.texture.load_from_file(path + background_texture.filename, false);
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
m_background_texture.metadata = background_texture;
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
GLToolbar::Layout::EType 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-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::set_layout_type(GLToolbar::Layout::EType type)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
m_layout.type = type;
|
2018-12-17 09:55:14 +00:00
|
|
|
m_layout.dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLToolbar::Layout::EOrientation GLToolbar::get_layout_orientation() const
|
|
|
|
{
|
|
|
|
return m_layout.orientation;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::set_layout_orientation(GLToolbar::Layout::EOrientation orientation)
|
|
|
|
{
|
|
|
|
m_layout.orientation = orientation;
|
|
|
|
}
|
|
|
|
|
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-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::set_border(float border)
|
|
|
|
{
|
|
|
|
m_layout.border = border;
|
|
|
|
m_layout.dirty = true;
|
|
|
|
}
|
|
|
|
|
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-12-17 09:55:14 +00:00
|
|
|
m_layout.dirty = true;
|
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-12-17 09:55:14 +00:00
|
|
|
m_layout.dirty = true;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
void GLToolbar::set_icons_size(float size)
|
|
|
|
{
|
|
|
|
if (m_layout.icons_size != size)
|
|
|
|
{
|
|
|
|
m_layout.icons_size = size;
|
|
|
|
m_layout.dirty = true;
|
|
|
|
m_icons_texture_dirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLToolbar::set_scale(float scale)
|
|
|
|
{
|
|
|
|
if (m_layout.scale != scale)
|
|
|
|
{
|
|
|
|
m_layout.scale = scale;
|
|
|
|
m_layout.dirty = true;
|
|
|
|
m_icons_texture_dirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2018-12-17 10:11:49 +00:00
|
|
|
void GLToolbar::set_icons_scale(float scale)
|
|
|
|
{
|
|
|
|
m_layout.icons_scale = scale;
|
|
|
|
m_layout.dirty = true;
|
|
|
|
}
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-12-17 10:11:49 +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);
|
2018-12-17 09:55:14 +00:00
|
|
|
m_layout.dirty = true;
|
2018-07-23 11:49:48 +00:00
|
|
|
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);
|
2018-12-17 09:55:14 +00:00
|
|
|
m_layout.dirty = true;
|
2018-07-23 11:49:48 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
float GLToolbar::get_width() const
|
|
|
|
{
|
2018-12-17 09:55:14 +00:00
|
|
|
if (m_layout.dirty)
|
|
|
|
calc_layout();
|
|
|
|
|
|
|
|
return m_layout.width;
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float GLToolbar::get_height() const
|
|
|
|
{
|
2018-12-17 09:55:14 +00:00
|
|
|
if (m_layout.dirty)
|
|
|
|
calc_layout();
|
|
|
|
|
|
|
|
return m_layout.height;
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::select_item(const std::string& name)
|
|
|
|
{
|
|
|
|
if (is_item_disabled(name))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (!item->is_disabled())
|
|
|
|
{
|
|
|
|
bool hover = item->is_hovered();
|
|
|
|
item->set_state((item->get_name() == name) ? (hover ? GLToolbarItem::HoverPressed : GLToolbarItem::Pressed) : (hover ? GLToolbarItem::Hover : GLToolbarItem::Normal));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-17 09:55:14 +00:00
|
|
|
bool GLToolbar::is_item_disabled(const std::string& name) const
|
|
|
|
{
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (item->get_name() == name)
|
|
|
|
return item->is_disabled();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-01-31 12:19:26 +00:00
|
|
|
bool GLToolbar::is_item_visible(const std::string& name) const
|
|
|
|
{
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (item->get_name() == name)
|
|
|
|
return item->is_visible();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
bool GLToolbar::update_items_state()
|
|
|
|
{
|
|
|
|
bool ret = false;
|
|
|
|
ret |= update_items_visibility();
|
|
|
|
ret |= update_items_enabled_state();
|
|
|
|
return ret;
|
2019-01-31 12:19:26 +00:00
|
|
|
}
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::render(const GLCanvas3D& parent) const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
|
|
|
if (!m_enabled || m_items.empty())
|
|
|
|
return;
|
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
if (m_icons_texture_dirty)
|
|
|
|
generate_icons_texture();
|
|
|
|
#endif // ENABLE_SVG_ICONS
|
|
|
|
|
2019-03-27 13:42:09 +00:00
|
|
|
glsafe(::glDisable(GL_DEPTH_TEST));
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2019-03-27 13:42:09 +00:00
|
|
|
glsafe(::glPushMatrix());
|
|
|
|
glsafe(::glLoadIdentity());
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
2018-12-17 09:55:14 +00:00
|
|
|
case Layout::Horizontal: { render_horizontal(parent); break; }
|
|
|
|
case Layout::Vertical: { render_vertical(parent); break; }
|
|
|
|
}
|
|
|
|
|
2019-03-27 13:42:09 +00:00
|
|
|
glsafe(::glPopMatrix());
|
2018-12-17 09:55:14 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
|
|
|
{
|
|
|
|
Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY());
|
|
|
|
bool processed = false;
|
|
|
|
|
|
|
|
// mouse anywhere
|
2019-03-25 07:48:41 +00:00
|
|
|
if (!evt.Dragging() && !evt.Leaving() && !evt.Entering() && (m_mouse_capture.parent != nullptr))
|
2019-03-22 12:03:34 +00:00
|
|
|
{
|
2019-03-25 07:48:41 +00:00
|
|
|
if (m_mouse_capture.any() && (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()))
|
|
|
|
// prevents loosing selection into the scene if mouse down was done inside the toolbar and mouse up was down outside it,
|
|
|
|
// as when switching between views
|
|
|
|
processed = true;
|
|
|
|
|
|
|
|
m_mouse_capture.reset();
|
2019-03-22 12:03:34 +00:00
|
|
|
}
|
2019-03-25 07:48:41 +00:00
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
if (evt.Moving())
|
|
|
|
m_tooltip = update_hover_state(mouse_pos, parent);
|
|
|
|
else if (evt.LeftUp())
|
|
|
|
m_mouse_capture.left = false;
|
|
|
|
else if (evt.MiddleUp())
|
|
|
|
m_mouse_capture.middle = false;
|
|
|
|
else if (evt.RightUp())
|
|
|
|
m_mouse_capture.right = false;
|
2019-03-22 12:03:34 +00:00
|
|
|
else if (evt.Dragging() && m_mouse_capture.any())
|
2019-03-25 07:48:41 +00:00
|
|
|
// if the button down was done on this toolbar, prevent from dragging into the scene
|
2019-03-22 12:03:34 +00:00
|
|
|
processed = true;
|
2019-03-14 12:54:05 +00:00
|
|
|
|
|
|
|
int item_id = contains_mouse(mouse_pos, parent);
|
|
|
|
if (item_id == -1)
|
|
|
|
{
|
|
|
|
// mouse is outside the toolbar
|
|
|
|
m_tooltip = "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-20 14:30:03 +00:00
|
|
|
// mouse inside toolbar
|
2019-03-14 12:54:05 +00:00
|
|
|
if (evt.LeftDown() || evt.LeftDClick())
|
|
|
|
{
|
|
|
|
m_mouse_capture.left = true;
|
2019-03-20 14:30:03 +00:00
|
|
|
m_mouse_capture.parent = &parent;
|
2019-03-26 08:01:04 +00:00
|
|
|
processed = true;
|
2019-03-14 12:54:05 +00:00
|
|
|
if ((item_id != -2) && !m_items[item_id]->is_separator())
|
|
|
|
{
|
|
|
|
// mouse is inside an icon
|
|
|
|
do_action((unsigned int)item_id, parent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (evt.MiddleDown())
|
2019-03-20 14:30:03 +00:00
|
|
|
{
|
2019-03-14 12:54:05 +00:00
|
|
|
m_mouse_capture.middle = true;
|
2019-03-20 14:30:03 +00:00
|
|
|
m_mouse_capture.parent = &parent;
|
|
|
|
}
|
2019-03-14 12:54:05 +00:00
|
|
|
else if (evt.RightDown())
|
2019-03-20 14:30:03 +00:00
|
|
|
{
|
2019-03-14 12:54:05 +00:00
|
|
|
m_mouse_capture.right = true;
|
2019-03-20 14:30:03 +00:00
|
|
|
m_mouse_capture.parent = &parent;
|
|
|
|
}
|
2019-03-14 12:54:05 +00:00
|
|
|
else if (evt.LeftUp())
|
|
|
|
processed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return processed;
|
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::calc_layout() const
|
|
|
|
{
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
2018-07-31 10:25:00 +00:00
|
|
|
case Layout::Horizontal:
|
|
|
|
{
|
2018-12-17 09:55:14 +00:00
|
|
|
m_layout.width = get_width_horizontal();
|
|
|
|
m_layout.height = get_height_horizontal();
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Layout::Vertical:
|
|
|
|
{
|
2018-12-17 09:55:14 +00:00
|
|
|
m_layout.width = get_width_vertical();
|
|
|
|
m_layout.height = get_height_vertical();
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
m_layout.dirty = false;
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale;
|
|
|
|
#else
|
2019-01-24 12:16:46 +00:00
|
|
|
return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
2018-08-24 10:32:14 +00:00
|
|
|
float GLToolbar::get_height_horizontal() const
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale;
|
|
|
|
#else
|
2019-01-24 12:16:46 +00:00
|
|
|
return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float size = 2.0f * m_layout.border;
|
|
|
|
for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
|
|
|
|
{
|
|
|
|
if (!m_items[i]->is_visible())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (m_items[i]->is_separator())
|
|
|
|
size += m_layout.separator_size;
|
|
|
|
else
|
|
|
|
size += (float)m_layout.icons_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_items.size() > 1)
|
|
|
|
size += ((float)m_items.size() - 1.0f) * m_layout.gap_size;
|
|
|
|
|
|
|
|
size *= m_layout.scale;
|
|
|
|
#else
|
2019-01-24 12:16:46 +00:00
|
|
|
float size = 2.0f * m_layout.border * m_layout.icons_scale;
|
2018-07-31 10:25:00 +00:00
|
|
|
for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
|
|
|
|
{
|
2019-01-31 12:19:26 +00:00
|
|
|
if (!m_items[i]->is_visible())
|
|
|
|
continue;
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
if (m_items[i]->is_separator())
|
2019-01-24 12:16:46 +00:00
|
|
|
size += m_layout.separator_size * m_layout.icons_scale;
|
2018-07-31 10:25:00 +00:00
|
|
|
else
|
2018-12-17 10:11:49 +00:00
|
|
|
size += (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale;
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (m_items.size() > 1)
|
2019-01-24 12:16:46 +00:00
|
|
|
size += ((float)m_items.size() - 1.0f) * m_layout.gap_size * m_layout.icons_scale;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
parent.render();
|
|
|
|
item->do_action();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_type == Radio)
|
|
|
|
select_item(item->get_name());
|
|
|
|
else
|
|
|
|
item->set_state(GLToolbarItem::HoverPressed);
|
|
|
|
|
|
|
|
parent.render();
|
|
|
|
item->do_action();
|
|
|
|
if ((m_type == Normal) && (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);
|
|
|
|
parent.render();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent)
|
|
|
|
{
|
|
|
|
if (!m_enabled)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case Layout::Horizontal: { return update_hover_state_horizontal(mouse_pos, parent); }
|
|
|
|
case Layout::Vertical: { return update_hover_state_vertical(mouse_pos, parent); }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent)
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
2019-01-24 16:02:13 +00:00
|
|
|
// NB: mouse_pos is already scaled appropriately
|
2019-01-24 12:16:46 +00:00
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
float zoom = parent.get_camera().zoom;
|
2018-07-31 10:25:00 +00:00
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float factor = m_layout.scale * inv_zoom;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float factor = m_layout.icons_scale * inv_zoom;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
Size cnv_size = 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
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float scaled_icons_size = m_layout.icons_size * factor;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_separator_size = m_layout.separator_size * factor;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * factor;
|
|
|
|
float scaled_border = m_layout.border * factor;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
float left = m_layout.left + scaled_border;
|
|
|
|
float top = m_layout.top - scaled_border;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
std::string tooltip = "";
|
|
|
|
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
2019-01-31 12:19:26 +00:00
|
|
|
if (!item->is_visible())
|
|
|
|
continue;
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
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);
|
2019-01-16 10:10:24 +00:00
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case GLToolbarItem::Normal:
|
|
|
|
{
|
|
|
|
if (inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
item->set_state(GLToolbarItem::Hover);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::Hover:
|
|
|
|
{
|
2019-01-16 10:10:24 +00:00
|
|
|
if (!inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
item->set_state(GLToolbarItem::Normal);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::Pressed:
|
|
|
|
{
|
|
|
|
if (inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
item->set_state(GLToolbarItem::HoverPressed);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::HoverPressed:
|
|
|
|
{
|
2019-01-16 10:10:24 +00:00
|
|
|
if (!inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-31 10:25:00 +00:00
|
|
|
item->set_state(GLToolbarItem::Pressed);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
case GLToolbarItem::Disabled:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
left += icon_stride;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-06 09:38:19 +00:00
|
|
|
return tooltip;
|
2018-07-31 10:25:00 +00:00
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent)
|
2018-07-31 10:25:00 +00:00
|
|
|
{
|
2019-01-24 16:02:13 +00:00
|
|
|
// NB: mouse_pos is already scaled appropriately
|
2019-01-24 12:16:46 +00:00
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
float zoom = parent.get_camera().zoom;
|
2018-07-31 10:25:00 +00:00
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float factor = m_layout.scale * inv_zoom;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float factor = m_layout.icons_scale * inv_zoom;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
Size cnv_size = 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
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float scaled_icons_size = m_layout.icons_size * factor;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_separator_size = m_layout.separator_size * factor;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * factor;
|
|
|
|
float scaled_border = m_layout.border * factor;
|
2018-07-31 10:25:00 +00:00
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
float left = m_layout.left + scaled_border;
|
|
|
|
float top = m_layout.top - scaled_border;
|
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)
|
|
|
|
{
|
2019-01-31 12:19:26 +00:00
|
|
|
if (!item->is_visible())
|
|
|
|
continue;
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
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);
|
2019-01-16 10:10:24 +00:00
|
|
|
if (inside)
|
|
|
|
tooltip = item->get_tooltip();
|
2018-07-23 11:49:48 +00:00
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case GLToolbarItem::Normal:
|
|
|
|
{
|
|
|
|
if (inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-23 11:49:48 +00:00
|
|
|
item->set_state(GLToolbarItem::Hover);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-07-23 11:49:48 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::Hover:
|
2018-07-25 08:01:17 +00:00
|
|
|
{
|
2019-01-16 10:10:24 +00:00
|
|
|
if (!inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-25 08:01:17 +00:00
|
|
|
item->set_state(GLToolbarItem::Normal);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-07-25 08:01:17 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2018-07-23 11:49:48 +00:00
|
|
|
case GLToolbarItem::Pressed:
|
|
|
|
{
|
2018-07-27 10:08:33 +00:00
|
|
|
if (inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-27 10:08:33 +00:00
|
|
|
item->set_state(GLToolbarItem::HoverPressed);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
2018-07-27 10:08:33 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GLToolbarItem::HoverPressed:
|
|
|
|
{
|
2019-01-16 10:10:24 +00:00
|
|
|
if (!inside)
|
2018-12-17 09:55:14 +00:00
|
|
|
{
|
2018-07-27 10:08:33 +00:00
|
|
|
item->set_state(GLToolbarItem::Pressed);
|
2018-12-17 09:55:14 +00:00
|
|
|
parent.set_as_dirty();
|
|
|
|
}
|
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
|
|
|
return tooltip;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
int GLToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
|
|
|
|
{
|
|
|
|
if (!m_enabled)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
switch (m_layout.type)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case Layout::Horizontal: { return contains_mouse_horizontal(mouse_pos, parent); }
|
|
|
|
case Layout::Vertical: { return contains_mouse_vertical(mouse_pos, parent); }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
|
2018-07-27 10:08:33 +00:00
|
|
|
{
|
2019-01-24 16:02:13 +00:00
|
|
|
// NB: mouse_pos is already scaled appropriately
|
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
float zoom = parent.get_camera().zoom;
|
2018-07-31 10:25:00 +00:00
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float factor = m_layout.scale * inv_zoom;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float factor = m_layout.icons_scale * inv_zoom;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-27 10:08:33 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
Size cnv_size = 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
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float scaled_icons_size = m_layout.icons_size * factor;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_separator_size = m_layout.separator_size * factor;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * factor;
|
|
|
|
float scaled_border = m_layout.border * factor;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
float left = m_layout.left + scaled_border;
|
|
|
|
float top = m_layout.top - scaled_border;
|
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
|
|
|
|
2019-01-31 12:19:26 +00:00
|
|
|
if (!item->is_visible())
|
|
|
|
continue;
|
|
|
|
|
2018-07-27 10:08:33 +00:00
|
|
|
if (item->is_separator())
|
2019-03-14 12:54:05 +00:00
|
|
|
{
|
|
|
|
float right = left + scaled_separator_size;
|
|
|
|
float bottom = top - scaled_icons_size;
|
|
|
|
|
|
|
|
// mouse inside the separator
|
|
|
|
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 = right;
|
|
|
|
right += scaled_gap_size;
|
|
|
|
|
|
|
|
if (id < m_items.size() - 1)
|
|
|
|
{
|
|
|
|
// mouse inside the gap
|
|
|
|
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 -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
left = right;
|
|
|
|
}
|
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;
|
2019-02-22 09:01:34 +00:00
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
// mouse inside the icon
|
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
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
left = right;
|
|
|
|
right += scaled_gap_size;
|
|
|
|
|
|
|
|
if (id < m_items.size() - 1)
|
|
|
|
{
|
|
|
|
// mouse inside the gap
|
|
|
|
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 -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
left = right;
|
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-12-17 09:55:14 +00:00
|
|
|
int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
|
2018-07-27 10:08:33 +00:00
|
|
|
{
|
2019-01-24 16:02:13 +00:00
|
|
|
// NB: mouse_pos is already scaled appropriately
|
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
float zoom = parent.get_camera().zoom;
|
2018-07-31 10:25:00 +00:00
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float factor = m_layout.scale * inv_zoom;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float factor = m_layout.icons_scale * inv_zoom;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
Size cnv_size = 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
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float scaled_icons_size = m_layout.icons_size * factor;
|
|
|
|
#else
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2019-01-24 16:02:13 +00:00
|
|
|
float scaled_separator_size = m_layout.separator_size * factor;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * factor;
|
|
|
|
float scaled_border = m_layout.border * factor;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
float left = m_layout.left + scaled_border;
|
|
|
|
float top = m_layout.top - scaled_border;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2019-01-31 12:19:26 +00:00
|
|
|
if (!item->is_visible())
|
|
|
|
continue;
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
if (item->is_separator())
|
2019-03-14 12:54:05 +00:00
|
|
|
{
|
|
|
|
float right = left + scaled_icons_size;
|
|
|
|
float bottom = top - scaled_separator_size;
|
|
|
|
|
|
|
|
// mouse inside the separator
|
|
|
|
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;
|
|
|
|
|
|
|
|
top = bottom;
|
|
|
|
bottom -= scaled_gap_size;
|
|
|
|
|
|
|
|
if (id < m_items.size() - 1)
|
|
|
|
{
|
|
|
|
// mouse inside the gap
|
|
|
|
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 -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
top = bottom;
|
|
|
|
}
|
2018-07-31 10:25:00 +00:00
|
|
|
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
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
// mouse inside the icon
|
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;
|
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
top = bottom;
|
|
|
|
bottom -= scaled_gap_size;
|
|
|
|
|
|
|
|
if (id < m_items.size() - 1)
|
|
|
|
{
|
|
|
|
// mouse inside the gap
|
|
|
|
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 -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
top = bottom;
|
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-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::render_horizontal(const GLCanvas3D& parent) const
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
unsigned int tex_id = m_icons_texture.get_id();
|
2019-02-26 09:40:00 +00:00
|
|
|
int tex_width = m_icons_texture.get_width();
|
|
|
|
int tex_height = m_icons_texture.get_height();
|
2019-02-26 08:56:23 +00:00
|
|
|
#else
|
2018-07-31 10:25:00 +00:00
|
|
|
unsigned int tex_id = m_icons_texture.texture.get_id();
|
2019-02-26 09:57:37 +00:00
|
|
|
int tex_width = m_icons_texture.texture.get_width();
|
|
|
|
int tex_height = m_icons_texture.texture.get_height();
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if !ENABLE_SVG_ICONS
|
2019-02-26 09:57:37 +00:00
|
|
|
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
2018-07-31 10:25:00 +00:00
|
|
|
return;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // !ENABLE_SVG_ICONS
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
float zoom = parent.get_camera().zoom;
|
2018-07-23 11:49:48 +00:00
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float factor = inv_zoom * m_layout.scale;
|
|
|
|
#else
|
2019-01-24 12:16:46 +00:00
|
|
|
float factor = inv_zoom * m_layout.icons_scale;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float scaled_icons_size = m_layout.icons_size * factor;
|
|
|
|
#else
|
2019-01-24 12:16:46 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2019-01-24 12:16:46 +00:00
|
|
|
float scaled_separator_size = m_layout.separator_size * factor;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * factor;
|
|
|
|
float scaled_border = m_layout.border * factor;
|
2018-12-17 09:55:14 +00:00
|
|
|
float scaled_width = get_width() * inv_zoom;
|
|
|
|
float scaled_height = get_height() * inv_zoom;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
|
|
|
float right = left + scaled_width;
|
|
|
|
float bottom = top - scaled_height;
|
|
|
|
|
|
|
|
// renders background
|
|
|
|
unsigned int bg_tex_id = m_background_texture.texture.get_id();
|
|
|
|
float bg_tex_width = (float)m_background_texture.texture.get_width();
|
|
|
|
float bg_tex_height = (float)m_background_texture.texture.get_height();
|
|
|
|
if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0))
|
|
|
|
{
|
|
|
|
float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f;
|
|
|
|
float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f;
|
|
|
|
|
|
|
|
float bg_uv_left = 0.0f;
|
|
|
|
float bg_uv_right = 1.0f;
|
|
|
|
float bg_uv_top = 1.0f;
|
|
|
|
float bg_uv_bottom = 0.0f;
|
|
|
|
|
|
|
|
float bg_left = left;
|
|
|
|
float bg_right = right;
|
|
|
|
float bg_top = top;
|
|
|
|
float bg_bottom = bottom;
|
|
|
|
float bg_width = right - left;
|
|
|
|
float bg_height = top - bottom;
|
|
|
|
float bg_min_size = std::min(bg_width, bg_height);
|
|
|
|
|
|
|
|
float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width;
|
|
|
|
float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width;
|
|
|
|
float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height;
|
|
|
|
float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height;
|
|
|
|
|
|
|
|
float bg_i_left = bg_left + scaled_border;
|
|
|
|
float bg_i_right = bg_right - scaled_border;
|
|
|
|
float bg_i_top = bg_top - scaled_border;
|
|
|
|
float bg_i_bottom = bg_bottom + scaled_border;
|
|
|
|
|
|
|
|
switch (m_layout.orientation)
|
|
|
|
{
|
|
|
|
case Layout::Top:
|
|
|
|
{
|
|
|
|
bg_uv_top = bg_uv_i_top;
|
|
|
|
bg_i_top = bg_top;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Layout::Bottom:
|
|
|
|
{
|
|
|
|
bg_uv_bottom = bg_uv_i_bottom;
|
|
|
|
bg_i_bottom = bg_bottom;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Layout::Center:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_top != bg_uv_i_top))
|
|
|
|
{
|
|
|
|
if (bg_uv_left != bg_uv_i_left)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } });
|
|
|
|
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } });
|
|
|
|
|
|
|
|
if (bg_uv_right != bg_uv_i_right)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } });
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_left != bg_uv_i_left))
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } });
|
|
|
|
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } });
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_right != bg_uv_i_right))
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } });
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_bottom != bg_uv_i_bottom))
|
|
|
|
{
|
|
|
|
if (bg_uv_left != bg_uv_i_left)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } });
|
|
|
|
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } });
|
|
|
|
|
|
|
|
if (bg_uv_right != bg_uv_i_right)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
left += scaled_border;
|
|
|
|
top -= scaled_border;
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
2019-02-26 09:40:00 +00:00
|
|
|
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
2019-02-26 08:56:23 +00:00
|
|
|
return;
|
|
|
|
#endif // ENABLE_SVG_ICONS
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
// renders icons
|
|
|
|
for (const GLToolbarItem* item : m_items)
|
|
|
|
{
|
2019-01-31 12:19:26 +00:00
|
|
|
if (!item->is_visible())
|
|
|
|
continue;
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
if (item->is_separator())
|
2018-07-31 10:25:00 +00:00
|
|
|
left += separator_stride;
|
2018-07-23 11:49:48 +00:00
|
|
|
else
|
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
2019-02-26 09:40:00 +00:00
|
|
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
2019-02-26 08:56:23 +00:00
|
|
|
#else
|
2019-02-26 09:57:37 +00:00
|
|
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, m_icons_texture.metadata.icon_size);
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
left += icon_stride;
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
void GLToolbar::render_vertical(const GLCanvas3D& parent) const
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
unsigned int tex_id = m_icons_texture.get_id();
|
2019-02-26 09:40:00 +00:00
|
|
|
int tex_width = m_icons_texture.get_width();
|
|
|
|
int tex_height = m_icons_texture.get_height();
|
2019-02-26 08:56:23 +00:00
|
|
|
#else
|
2018-07-31 10:25:00 +00:00
|
|
|
unsigned int tex_id = m_icons_texture.texture.get_id();
|
2019-02-26 09:57:37 +00:00
|
|
|
int tex_width = m_icons_texture.texture.get_width();
|
|
|
|
int tex_height = m_icons_texture.texture.get_height();
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-23 11:49:48 +00:00
|
|
|
|
2019-02-26 09:40:00 +00:00
|
|
|
#if !ENABLE_SVG_ICONS
|
2019-02-26 09:57:37 +00:00
|
|
|
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
2018-07-31 10:25:00 +00:00
|
|
|
return;
|
2019-02-26 09:40:00 +00:00
|
|
|
#endif // !ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
float zoom = parent.get_camera().zoom;
|
2018-07-31 10:25:00 +00:00
|
|
|
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float factor = inv_zoom * m_layout.scale;
|
|
|
|
#else
|
2019-01-24 12:16:46 +00:00
|
|
|
float factor = inv_zoom * m_layout.icons_scale;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
float scaled_icons_size = m_layout.icons_size * factor;
|
|
|
|
#else
|
2019-01-24 12:16:46 +00:00
|
|
|
float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale * factor;
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2019-01-24 12:16:46 +00:00
|
|
|
float scaled_separator_size = m_layout.separator_size * factor;
|
|
|
|
float scaled_gap_size = m_layout.gap_size * factor;
|
|
|
|
float scaled_border = m_layout.border * factor;
|
2018-12-17 09:55:14 +00:00
|
|
|
float scaled_width = get_width() * inv_zoom;
|
|
|
|
float scaled_height = get_height() * inv_zoom;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
|
|
|
float separator_stride = scaled_separator_size + scaled_gap_size;
|
|
|
|
float icon_stride = scaled_icons_size + scaled_gap_size;
|
|
|
|
|
2018-12-17 09:55:14 +00:00
|
|
|
float left = m_layout.left;
|
|
|
|
float top = m_layout.top;
|
|
|
|
float right = left + scaled_width;
|
|
|
|
float bottom = top - scaled_height;
|
|
|
|
|
|
|
|
// renders background
|
|
|
|
unsigned int bg_tex_id = m_background_texture.texture.get_id();
|
|
|
|
float bg_tex_width = (float)m_background_texture.texture.get_width();
|
|
|
|
float bg_tex_height = (float)m_background_texture.texture.get_height();
|
|
|
|
if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0))
|
|
|
|
{
|
|
|
|
float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f;
|
|
|
|
float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f;
|
|
|
|
|
|
|
|
float bg_uv_left = 0.0f;
|
|
|
|
float bg_uv_right = 1.0f;
|
|
|
|
float bg_uv_top = 1.0f;
|
|
|
|
float bg_uv_bottom = 0.0f;
|
|
|
|
|
|
|
|
float bg_left = left;
|
|
|
|
float bg_right = right;
|
|
|
|
float bg_top = top;
|
|
|
|
float bg_bottom = bottom;
|
|
|
|
float bg_width = right - left;
|
|
|
|
float bg_height = top - bottom;
|
|
|
|
float bg_min_size = std::min(bg_width, bg_height);
|
|
|
|
|
|
|
|
float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width;
|
|
|
|
float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width;
|
|
|
|
float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height;
|
|
|
|
float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height;
|
|
|
|
|
|
|
|
float bg_i_left = bg_left + scaled_border;
|
|
|
|
float bg_i_right = bg_right - scaled_border;
|
|
|
|
float bg_i_top = bg_top - scaled_border;
|
|
|
|
float bg_i_bottom = bg_bottom + scaled_border;
|
|
|
|
|
|
|
|
switch (m_layout.orientation)
|
|
|
|
{
|
|
|
|
case Layout::Left:
|
|
|
|
{
|
|
|
|
bg_uv_left = bg_uv_i_left;
|
|
|
|
bg_i_left = bg_left;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Layout::Right:
|
|
|
|
{
|
|
|
|
bg_uv_right = bg_uv_i_right;
|
|
|
|
bg_i_right = bg_right;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Layout::Center:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_top != bg_uv_i_top))
|
|
|
|
{
|
|
|
|
if (bg_uv_left != bg_uv_i_left)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } });
|
|
|
|
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } });
|
|
|
|
|
|
|
|
if (bg_uv_right != bg_uv_i_right)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } });
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_left != bg_uv_i_left))
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } });
|
|
|
|
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } });
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_right != bg_uv_i_right))
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } });
|
|
|
|
|
|
|
|
if ((m_layout.border > 0) && (bg_uv_bottom != bg_uv_i_bottom))
|
|
|
|
{
|
|
|
|
if (bg_uv_left != bg_uv_i_left)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } });
|
|
|
|
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } });
|
|
|
|
|
|
|
|
if (bg_uv_right != bg_uv_i_right)
|
|
|
|
GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
left += scaled_border;
|
|
|
|
top -= scaled_border;
|
2018-07-31 10:25:00 +00:00
|
|
|
|
2019-02-26 09:40:00 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
|
|
|
return;
|
|
|
|
#endif // ENABLE_SVG_ICONS
|
|
|
|
|
2018-07-31 10:25:00 +00:00
|
|
|
// renders icons
|
|
|
|
for (const GLToolbarItem* item : m_items)
|
2018-07-23 11:49:48 +00:00
|
|
|
{
|
2019-01-31 12:19:26 +00:00
|
|
|
if (!item->is_visible())
|
|
|
|
continue;
|
|
|
|
|
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
|
|
|
{
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
2019-02-26 09:40:00 +00:00
|
|
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
2019-02-26 08:56:23 +00:00
|
|
|
#else
|
2019-02-26 09:57:37 +00:00
|
|
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, m_icons_texture.metadata.icon_size);
|
2019-02-26 08:56:23 +00:00
|
|
|
#endif // ENABLE_SVG_ICONS
|
2018-07-31 10:25:00 +00:00
|
|
|
top -= icon_stride;
|
|
|
|
}
|
2018-07-23 11:49:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-26 08:56:23 +00:00
|
|
|
#if ENABLE_SVG_ICONS
|
|
|
|
bool GLToolbar::generate_icons_texture() const
|
|
|
|
{
|
|
|
|
std::string path = resources_dir() + "/icons/";
|
|
|
|
std::vector<std::string> filenames;
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
2019-02-26 09:40:00 +00:00
|
|
|
const std::string& icon_filename = item->get_icon_filename();
|
|
|
|
if (!icon_filename.empty())
|
|
|
|
filenames.push_back(path + icon_filename);
|
2019-02-26 08:56:23 +00:00
|
|
|
}
|
|
|
|
|
2019-02-26 11:56:13 +00:00
|
|
|
std::vector<std::pair<int, bool>> states;
|
|
|
|
if (m_name == "Top")
|
|
|
|
{
|
|
|
|
states.push_back(std::make_pair(1, false));
|
|
|
|
states.push_back(std::make_pair(0, false));
|
|
|
|
states.push_back(std::make_pair(2, false));
|
|
|
|
states.push_back(std::make_pair(0, false));
|
|
|
|
states.push_back(std::make_pair(0, false));
|
|
|
|
}
|
|
|
|
else if (m_name == "View")
|
|
|
|
{
|
|
|
|
states.push_back(std::make_pair(1, false));
|
|
|
|
states.push_back(std::make_pair(1, true));
|
|
|
|
states.push_back(std::make_pair(1, false));
|
|
|
|
states.push_back(std::make_pair(0, false));
|
|
|
|
states.push_back(std::make_pair(1, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
2019-02-26 08:56:23 +00:00
|
|
|
if (res)
|
|
|
|
m_icons_texture_dirty = false;
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
#endif // ENABLE_SVG_ICONS
|
|
|
|
|
2019-03-14 12:54:05 +00:00
|
|
|
bool GLToolbar::update_items_visibility()
|
|
|
|
{
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
ret |= item->update_visibility();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
m_layout.dirty = true;
|
|
|
|
|
|
|
|
// updates separators visibility to avoid having two of them consecutive
|
|
|
|
bool any_item_visible = false;
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
if (!item->is_separator())
|
|
|
|
any_item_visible |= item->is_visible();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->set_visible(any_item_visible);
|
|
|
|
any_item_visible = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLToolbar::update_items_enabled_state()
|
|
|
|
{
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
for (GLToolbarItem* item : m_items)
|
|
|
|
{
|
|
|
|
ret |= item->update_enabled_state();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
m_layout.dirty = true;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-07-23 11:49:48 +00:00
|
|
|
} // namespace GUI
|
|
|
|
} // namespace Slic3r
|