3D scene toolbar uses a single texture
Before Width: | Height: | Size: 831 B |
Before Width: | Height: | Size: 956 B |
Before Width: | Height: | Size: 953 B |
Before Width: | Height: | Size: 934 B |
Before Width: | Height: | Size: 929 B |
Before Width: | Height: | Size: 723 B |
Before Width: | Height: | Size: 826 B |
Before Width: | Height: | Size: 824 B |
Before Width: | Height: | Size: 804 B |
Before Width: | Height: | Size: 800 B |
Before Width: | Height: | Size: 691 B |
Before Width: | Height: | Size: 799 B |
Before Width: | Height: | Size: 795 B |
Before Width: | Height: | Size: 780 B |
Before Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 709 B |
Before Width: | Height: | Size: 796 B |
Before Width: | Height: | Size: 791 B |
Before Width: | Height: | Size: 773 B |
Before Width: | Height: | Size: 770 B |
Before Width: | Height: | Size: 947 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1019 B |
Before Width: | Height: | Size: 1004 B |
Before Width: | Height: | Size: 999 B |
Before Width: | Height: | Size: 953 B |
Before Width: | Height: | Size: 1022 B |
Before Width: | Height: | Size: 1018 B |
Before Width: | Height: | Size: 1002 B |
Before Width: | Height: | Size: 1000 B |
Before Width: | Height: | Size: 880 B |
Before Width: | Height: | Size: 1013 B |
Before Width: | Height: | Size: 1006 B |
Before Width: | Height: | Size: 998 B |
Before Width: | Height: | Size: 990 B |
Before Width: | Height: | Size: 942 B |
Before Width: | Height: | Size: 1007 B |
Before Width: | Height: | Size: 1005 B |
Before Width: | Height: | Size: 984 B |
Before Width: | Height: | Size: 981 B |
Before Width: | Height: | Size: 800 B |
Before Width: | Height: | Size: 875 B |
Before Width: | Height: | Size: 875 B |
Before Width: | Height: | Size: 845 B |
Before Width: | Height: | Size: 843 B |
Before Width: | Height: | Size: 839 B |
Before Width: | Height: | Size: 913 B |
Before Width: | Height: | Size: 911 B |
Before Width: | Height: | Size: 895 B |
Before Width: | Height: | Size: 893 B |
Before Width: | Height: | Size: 935 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1021 B |
Before Width: | Height: | Size: 1015 B |
Before Width: | Height: | Size: 770 B |
Before Width: | Height: | Size: 873 B |
Before Width: | Height: | Size: 866 B |
Before Width: | Height: | Size: 841 B |
Before Width: | Height: | Size: 836 B |
BIN
resources/icons/toolbar.png
Normal file
After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 450 B |
Before Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 471 B |
Before Width: | Height: | Size: 443 B |
Before Width: | Height: | Size: 446 B |
@ -3288,53 +3288,49 @@ bool GLCanvas3D::_init_toolbar()
|
||||
if (!m_toolbar.is_enabled())
|
||||
return true;
|
||||
|
||||
GLToolbar::ItemCreationData item;
|
||||
if (!m_toolbar.init("toolbar.png", 36, 1, 1))
|
||||
{
|
||||
// unable to init the toolbar texture, disable it
|
||||
m_toolbar.set_enabled(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// m_toolbar.set_layout_type(GLToolbar::Layout::Vertical);
|
||||
m_toolbar.set_layout_type(GLToolbar::Layout::Horizontal);
|
||||
m_toolbar.set_separator_size(5);
|
||||
m_toolbar.set_gap_size(2);
|
||||
|
||||
GLToolbarItem::Data item;
|
||||
|
||||
item.name = "add";
|
||||
item.tooltip = GUI::L_str("Add...");
|
||||
item.sprite_id = 0;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_add_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "brick_add_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "brick_add_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "brick_add_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "brick_add_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "brick_add_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "delete";
|
||||
item.tooltip = GUI::L_str("Delete");
|
||||
item.sprite_id = 1;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_delete_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "brick_delete_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "brick_delete_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "brick_delete_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "brick_delete_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "brick_delete_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "deleteall";
|
||||
item.tooltip = GUI::L_str("Delete all");
|
||||
item.sprite_id = 2;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_deleteall_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "cross_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "cross_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "cross_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "cross_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "cross_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "arrange";
|
||||
item.tooltip = GUI::L_str("Arrange");
|
||||
item.sprite_id = 3;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_arrange_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "bricks_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "bricks_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "bricks_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "bricks_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "bricks_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
@ -3343,25 +3339,17 @@ bool GLCanvas3D::_init_toolbar()
|
||||
|
||||
item.name = "more";
|
||||
item.tooltip = GUI::L_str("Add instance");
|
||||
item.sprite_id = 4;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_more_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "add_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "add_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "add_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "add_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "add_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "fewer";
|
||||
item.tooltip = GUI::L_str("Remove instance");
|
||||
item.sprite_id = 5;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_fewer_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "delete_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "delete_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "delete_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "delete_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "delete_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
@ -3370,61 +3358,41 @@ bool GLCanvas3D::_init_toolbar()
|
||||
|
||||
item.name = "ccw45";
|
||||
item.tooltip = GUI::L_str("Rotate CCW 45 degrees");
|
||||
item.sprite_id = 6;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_ccw45_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "arrow_rotate_anticlockwise_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "arrow_rotate_anticlockwise_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "arrow_rotate_anticlockwise_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "arrow_rotate_anticlockwise_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "arrow_rotate_anticlockwise_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "cw45";
|
||||
item.tooltip = GUI::L_str("Rotate CW 45 degrees");
|
||||
item.sprite_id = 7;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_cw45_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "arrow_rotate_clockwise_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "arrow_rotate_clockwise_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "arrow_rotate_clockwise_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "arrow_rotate_clockwise_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "arrow_rotate_clockwise_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "scale";
|
||||
item.tooltip = GUI::L_str("Scale...");
|
||||
item.sprite_id = 8;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_scale_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "arrow_out_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "arrow_out_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "arrow_out_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "arrow_out_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "arrow_out_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "split";
|
||||
item.tooltip = GUI::L_str("Split");
|
||||
item.sprite_id = 9;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_split_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "shape_ungroup_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "shape_ungroup_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "shape_ungroup_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "shape_ungroup_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "shape_ungroup_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "cut";
|
||||
item.tooltip = GUI::L_str("Cut...");
|
||||
item.sprite_id = 10;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_cut_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "package_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "package_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "package_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "package_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "package_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
@ -3433,25 +3401,17 @@ bool GLCanvas3D::_init_toolbar()
|
||||
|
||||
item.name = "settings";
|
||||
item.tooltip = GUI::L_str("Settings...");
|
||||
item.sprite_id = 11;
|
||||
item.is_toggable = false;
|
||||
item.action_callback = &m_action_settings_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "cog_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "cog_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "cog_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "cog_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "cog_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
item.name = "layersediting";
|
||||
item.tooltip = GUI::L_str("Layers editing");
|
||||
item.sprite_id = 12;
|
||||
item.is_toggable = true;
|
||||
item.action_callback = &m_action_layersediting_callback;
|
||||
item.textures[GLToolbarItem::Normal] = "variable_layer_height_normal_36.png";
|
||||
item.textures[GLToolbarItem::Hover] = "variable_layer_height_hover_36.png";
|
||||
item.textures[GLToolbarItem::Pressed] = "variable_layer_height_pressed_36.png";
|
||||
item.textures[GLToolbarItem::HoverPressed] = "variable_layer_height_hover_pressed_36.png";
|
||||
item.textures[GLToolbarItem::Disabled] = "variable_layer_height_disabled_36.png";
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
||||
@ -4067,7 +4027,8 @@ void GLCanvas3D::_render_gizmo() const
|
||||
//###################################################################################################################################
|
||||
void GLCanvas3D::_render_toolbar() const
|
||||
{
|
||||
m_toolbar.render(m_mouse.position);
|
||||
_resize_toolbar();
|
||||
m_toolbar.render();
|
||||
}
|
||||
//###################################################################################################################################
|
||||
|
||||
@ -5301,5 +5262,38 @@ bool GLCanvas3D::_is_any_volume_outside() const
|
||||
return false;
|
||||
}
|
||||
|
||||
//###################################################################################################################################
|
||||
void GLCanvas3D::_resize_toolbar() const
|
||||
{
|
||||
Size cnv_size = get_canvas_size();
|
||||
float zoom = get_camera_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
switch (m_toolbar.get_layout_type())
|
||||
{
|
||||
default:
|
||||
case GLToolbar::Layout::Horizontal:
|
||||
{
|
||||
// centers the toolbar on the top edge of the 3d scene
|
||||
unsigned int toolbar_width = m_toolbar.get_width();
|
||||
float top = (0.5f * (float)cnv_size.get_height() - 2.0f) * inv_zoom;
|
||||
float left = -0.5f * (float)toolbar_width * inv_zoom;
|
||||
m_toolbar.set_position(top, left);
|
||||
break;
|
||||
}
|
||||
case GLToolbar::Layout::Vertical:
|
||||
{
|
||||
// centers the toolbar on the right edge of the 3d scene
|
||||
unsigned int toolbar_width = m_toolbar.get_width();
|
||||
unsigned int toolbar_height = m_toolbar.get_height();
|
||||
float top = 0.5f * (float)toolbar_height * inv_zoom;
|
||||
float left = (0.5f * (float)cnv_size.get_width() - toolbar_width - 2.0f) * inv_zoom;
|
||||
m_toolbar.set_position(top, left);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//###################################################################################################################################
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -746,6 +746,10 @@ private:
|
||||
|
||||
bool _is_any_volume_outside() const;
|
||||
|
||||
//###################################################################################################################################
|
||||
void _resize_toolbar() const;
|
||||
//###################################################################################################################################
|
||||
|
||||
static std::vector<float> _parse_colors(const std::vector<std::string>& colors);
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,10 @@
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
//###################################################################################################################################
|
||||
GLTexture::Quad_UVs GLTexture::FullTextureUVs = { { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 0.0f, 0.0f } };
|
||||
//###################################################################################################################################
|
||||
|
||||
GLTexture::GLTexture()
|
||||
: m_id(0)
|
||||
, m_width(0)
|
||||
@ -128,6 +132,34 @@ const std::string& GLTexture::get_source() const
|
||||
}
|
||||
|
||||
void GLTexture::render_texture(unsigned int tex_id, float left, float right, float bottom, float top)
|
||||
{
|
||||
//###################################################################################################################################
|
||||
render_sub_texture(tex_id, left, right, bottom, top, FullTextureUVs);
|
||||
|
||||
// ::glEnable(GL_BLEND);
|
||||
// ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//
|
||||
// ::glEnable(GL_TEXTURE_2D);
|
||||
// ::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
//
|
||||
// ::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id);
|
||||
//
|
||||
// ::glBegin(GL_QUADS);
|
||||
// ::glTexCoord2f(0.0f, 1.0f); ::glVertex2f(left, bottom);
|
||||
// ::glTexCoord2f(1.0f, 1.0f); ::glVertex2f(right, bottom);
|
||||
// ::glTexCoord2f(1.0f, 0.0f); ::glVertex2f(right, top);
|
||||
// ::glTexCoord2f(0.0f, 0.0f); ::glVertex2f(left, top);
|
||||
// ::glEnd();
|
||||
//
|
||||
// ::glBindTexture(GL_TEXTURE_2D, 0);
|
||||
//
|
||||
// ::glDisable(GL_TEXTURE_2D);
|
||||
// ::glDisable(GL_BLEND);
|
||||
//###################################################################################################################################
|
||||
}
|
||||
|
||||
//###################################################################################################################################
|
||||
void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, float bottom, float top, const GLTexture::Quad_UVs& uvs)
|
||||
{
|
||||
::glEnable(GL_BLEND);
|
||||
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@ -138,10 +170,10 @@ void GLTexture::render_texture(unsigned int tex_id, float left, float right, flo
|
||||
::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id);
|
||||
|
||||
::glBegin(GL_QUADS);
|
||||
::glTexCoord2f(0.0f, 1.0f); ::glVertex2f(left, bottom);
|
||||
::glTexCoord2f(1.0f, 1.0f); ::glVertex2f(right, bottom);
|
||||
::glTexCoord2f(1.0f, 0.0f); ::glVertex2f(right, top);
|
||||
::glTexCoord2f(0.0f, 0.0f); ::glVertex2f(left, top);
|
||||
::glTexCoord2f(uvs.left_bottom.u, uvs.left_bottom.v); ::glVertex2f(left, bottom);
|
||||
::glTexCoord2f(uvs.right_bottom.u, uvs.right_bottom.v); ::glVertex2f(right, bottom);
|
||||
::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top);
|
||||
::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top);
|
||||
::glEnd();
|
||||
|
||||
::glBindTexture(GL_TEXTURE_2D, 0);
|
||||
@ -149,6 +181,7 @@ void GLTexture::render_texture(unsigned int tex_id, float left, float right, flo
|
||||
::glDisable(GL_TEXTURE_2D);
|
||||
::glDisable(GL_BLEND);
|
||||
}
|
||||
//###################################################################################################################################
|
||||
|
||||
unsigned int GLTexture::_generate_mipmaps(wxImage& image)
|
||||
{
|
||||
|
@ -10,6 +10,25 @@ namespace GUI {
|
||||
|
||||
class GLTexture
|
||||
{
|
||||
//###################################################################################################################################
|
||||
public:
|
||||
struct UV
|
||||
{
|
||||
float u;
|
||||
float v;
|
||||
};
|
||||
|
||||
struct Quad_UVs
|
||||
{
|
||||
UV left_bottom;
|
||||
UV right_bottom;
|
||||
UV right_top;
|
||||
UV left_top;
|
||||
};
|
||||
|
||||
static Quad_UVs FullTextureUVs;
|
||||
//###################################################################################################################################
|
||||
|
||||
protected:
|
||||
unsigned int m_id;
|
||||
int m_width;
|
||||
@ -30,6 +49,9 @@ namespace GUI {
|
||||
const std::string& get_source() const;
|
||||
|
||||
static void render_texture(unsigned int tex_id, float left, float right, float bottom, float top);
|
||||
//###################################################################################################################################
|
||||
static void render_sub_texture(unsigned int tex_id, float left, float right, float bottom, float top, const Quad_UVs& uvs);
|
||||
//###################################################################################################################################
|
||||
|
||||
protected:
|
||||
unsigned int _generate_mipmaps(wxImage& image);
|
||||
|
@ -11,34 +11,20 @@
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
GLToolbarItem::GLToolbarItem(EType type, const std::string& name, const std::string& tooltip, bool is_toggable, PerlCallback* action_callback)
|
||||
: m_type(type)
|
||||
, m_state(Disabled)
|
||||
, m_name(name)
|
||||
, m_tooltip(tooltip)
|
||||
, m_is_toggable(is_toggable)
|
||||
, m_action_callback(action_callback)
|
||||
GLToolbarItem::Data::Data()
|
||||
: name("")
|
||||
, tooltip("")
|
||||
, sprite_id(-1)
|
||||
, is_toggable(false)
|
||||
, action_callback(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool GLToolbarItem::load_textures(const std::string* filenames)
|
||||
GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Data& data)
|
||||
: m_type(type)
|
||||
, m_state(Disabled)
|
||||
, m_data(data)
|
||||
{
|
||||
if (filenames == nullptr)
|
||||
return false;
|
||||
|
||||
std::string path = resources_dir() + "/icons/";
|
||||
|
||||
for (unsigned int i = (unsigned int)Normal; i < (unsigned int)Num_States; ++i)
|
||||
{
|
||||
if (!filenames[i].empty())
|
||||
{
|
||||
std::string filename = path + filenames[i];
|
||||
if (!m_icon_textures[i].load_from_file(filename, false))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GLToolbarItem::EState GLToolbarItem::get_state() const
|
||||
@ -53,28 +39,18 @@ void GLToolbarItem::set_state(GLToolbarItem::EState state)
|
||||
|
||||
const std::string& GLToolbarItem::get_name() const
|
||||
{
|
||||
return m_name;
|
||||
return m_data.name;
|
||||
}
|
||||
|
||||
const std::string& GLToolbarItem::get_tooltip() const
|
||||
{
|
||||
return m_tooltip;
|
||||
}
|
||||
|
||||
unsigned int GLToolbarItem::get_icon_texture_id() const
|
||||
{
|
||||
return m_icon_textures[m_state].get_id();
|
||||
}
|
||||
|
||||
int GLToolbarItem::get_icon_textures_size() const
|
||||
{
|
||||
return m_icon_textures[Normal].get_width();
|
||||
return m_data.tooltip;
|
||||
}
|
||||
|
||||
void GLToolbarItem::do_action()
|
||||
{
|
||||
if (m_action_callback != nullptr)
|
||||
m_action_callback->call();
|
||||
if (m_data.action_callback != nullptr)
|
||||
m_data.action_callback->call();
|
||||
}
|
||||
|
||||
bool GLToolbarItem::is_enabled() const
|
||||
@ -94,7 +70,7 @@ bool GLToolbarItem::is_pressed() const
|
||||
|
||||
bool GLToolbarItem::is_toggable() const
|
||||
{
|
||||
return m_is_toggable;
|
||||
return m_data.is_toggable;
|
||||
}
|
||||
|
||||
bool GLToolbarItem::is_separator() const
|
||||
@ -102,16 +78,97 @@ bool GLToolbarItem::is_separator() const
|
||||
return m_type == Separator;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, _get_uvs(texture_size, border_size, icon_size, gap_size));
|
||||
}
|
||||
|
||||
GLTexture::Quad_UVs GLToolbarItem::_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;
|
||||
}
|
||||
|
||||
GLToolbar::ItemsIconsTexture::ItemsIconsTexture()
|
||||
: 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)
|
||||
{
|
||||
}
|
||||
|
||||
GLToolbar::GLToolbar(GLCanvas3D& parent)
|
||||
: m_parent(parent)
|
||||
, m_enabled(false)
|
||||
, m_textures_scale(1.0f)
|
||||
, m_offset_y(5.0f)
|
||||
, m_gap_x(2.0f)
|
||||
, m_separator_x(5.0f)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
GLToolbar::Layout::Type GLToolbar::get_layout_type() const
|
||||
{
|
||||
return m_layout.type;
|
||||
}
|
||||
|
||||
void GLToolbar::set_layout_type(GLToolbar::Layout::Type type)
|
||||
{
|
||||
m_layout.type = type;
|
||||
}
|
||||
|
||||
void GLToolbar::set_position(float top, float left)
|
||||
{
|
||||
m_layout.top = top;
|
||||
m_layout.left = left;
|
||||
}
|
||||
|
||||
void GLToolbar::set_separator_size(float size)
|
||||
{
|
||||
m_layout.separator_size = size;
|
||||
}
|
||||
|
||||
void GLToolbar::set_gap_size(float size)
|
||||
{
|
||||
m_layout.gap_size = size;
|
||||
}
|
||||
|
||||
bool GLToolbar::is_enabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
@ -122,40 +179,9 @@ void GLToolbar::set_enabled(bool enable)
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
void GLToolbar::set_textures_scale(float scale)
|
||||
bool GLToolbar::add_item(const GLToolbarItem::Data& data)
|
||||
{
|
||||
m_textures_scale = scale;
|
||||
}
|
||||
|
||||
void GLToolbar::set_offset_y(float offset)
|
||||
{
|
||||
m_offset_y = offset;
|
||||
}
|
||||
|
||||
void GLToolbar::set_gap_x(float gap)
|
||||
{
|
||||
m_gap_x = gap;
|
||||
}
|
||||
|
||||
void GLToolbar::set_separator_x(float separator)
|
||||
{
|
||||
m_separator_x = separator;
|
||||
}
|
||||
|
||||
bool GLToolbar::add_item(const GLToolbar::ItemCreationData& data)
|
||||
{
|
||||
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Action, data.name, data.tooltip, data.is_toggable, data.action_callback);
|
||||
if ((item == nullptr) || !item->load_textures(data.textures))
|
||||
return false;
|
||||
|
||||
m_items.push_back(item);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLToolbar::add_separator()
|
||||
{
|
||||
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Separator, "", "", false, nullptr);
|
||||
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Action, data);
|
||||
if (item == nullptr)
|
||||
return false;
|
||||
|
||||
@ -163,6 +189,49 @@ bool GLToolbar::add_separator()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLToolbar::add_separator()
|
||||
{
|
||||
GLToolbarItem::Data data;
|
||||
GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Separator, data);
|
||||
if (item == nullptr)
|
||||
return false;
|
||||
|
||||
m_items.push_back(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
float GLToolbar::get_width() const
|
||||
{
|
||||
switch (m_layout.type)
|
||||
{
|
||||
default:
|
||||
case Layout::Horizontal:
|
||||
{
|
||||
return _get_width_horizontal();
|
||||
}
|
||||
case Layout::Vertical:
|
||||
{
|
||||
return _get_width_vertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float GLToolbar::get_height() const
|
||||
{
|
||||
switch (m_layout.type)
|
||||
{
|
||||
default:
|
||||
case Layout::Horizontal:
|
||||
{
|
||||
return _get_height_horizontal();
|
||||
}
|
||||
case Layout::Vertical:
|
||||
{
|
||||
return _get_height_vertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLToolbar::enable_item(const std::string& name)
|
||||
{
|
||||
for (GLToolbarItem* item : m_items)
|
||||
@ -203,25 +272,252 @@ void GLToolbar::update_hover_state(const Pointf& mouse_pos)
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
float cnv_w = (float)m_parent.get_canvas_size().get_width();
|
||||
float width = _get_total_width();
|
||||
float left = 0.5f * (cnv_w - width);
|
||||
float top = m_offset_y;
|
||||
switch (m_layout.type)
|
||||
{
|
||||
default:
|
||||
case Layout::Horizontal:
|
||||
{
|
||||
_update_hover_state_horizontal(mouse_pos);
|
||||
break;
|
||||
}
|
||||
case Layout::Vertical:
|
||||
{
|
||||
_update_hover_state_vertical(mouse_pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GLToolbar::contains_mouse(const Pointf& mouse_pos) const
|
||||
{
|
||||
if (!m_enabled)
|
||||
return -1;
|
||||
|
||||
switch (m_layout.type)
|
||||
{
|
||||
default:
|
||||
case Layout::Horizontal:
|
||||
{
|
||||
return _contains_mouse_horizontal(mouse_pos);
|
||||
}
|
||||
case Layout::Vertical:
|
||||
{
|
||||
return _contains_mouse_vertical(mouse_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
item->do_action();
|
||||
}
|
||||
else
|
||||
{
|
||||
item->set_state(GLToolbarItem::HoverPressed);
|
||||
m_parent.render();
|
||||
item->do_action();
|
||||
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
|
||||
//void GLToolbar::render(const Pointf& mouse_pos) const
|
||||
{
|
||||
if (!m_enabled || m_items.empty())
|
||||
return;
|
||||
|
||||
::glDisable(GL_DEPTH_TEST);
|
||||
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity();
|
||||
|
||||
switch (m_layout.type)
|
||||
{
|
||||
default:
|
||||
case Layout::Horizontal:
|
||||
{
|
||||
_render_horizontal();
|
||||
break;
|
||||
}
|
||||
case Layout::Vertical:
|
||||
{
|
||||
_render_vertical();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
float GLToolbar::_get_width_horizontal() const
|
||||
{
|
||||
return _get_main_size();
|
||||
}
|
||||
|
||||
float GLToolbar::_get_width_vertical() const
|
||||
{
|
||||
return m_icons_texture.items_icon_size;
|
||||
}
|
||||
|
||||
float GLToolbar::_get_height_horizontal() const
|
||||
{
|
||||
return m_icons_texture.items_icon_size;
|
||||
}
|
||||
|
||||
float GLToolbar::_get_height_vertical() const
|
||||
{
|
||||
return _get_main_size();
|
||||
}
|
||||
|
||||
float GLToolbar::_get_main_size() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void GLToolbar::_update_hover_state_horizontal(const Pointf& mouse_pos)
|
||||
{
|
||||
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();
|
||||
Pointf scaled_mouse_pos((mouse_pos.x - 0.5f * (float)cnv_size.get_width()) * inv_zoom, (0.5f * (float)cnv_size.get_height() - mouse_pos.y) * inv_zoom);
|
||||
|
||||
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();
|
||||
bool inside = (left <= scaled_mouse_pos.x) && (scaled_mouse_pos.x <= right) && (bottom <= scaled_mouse_pos.y) && (scaled_mouse_pos.y <= top);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
m_parent.set_tooltip(tooltip);
|
||||
}
|
||||
|
||||
void GLToolbar::_update_hover_state_vertical(const Pointf& mouse_pos)
|
||||
{
|
||||
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();
|
||||
Pointf scaled_mouse_pos((mouse_pos.x - 0.5f * (float)cnv_size.get_width()) * inv_zoom, (0.5f * (float)cnv_size.get_height() - mouse_pos.y) * inv_zoom);
|
||||
|
||||
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 += (m_separator_x + m_gap_x);
|
||||
top -= separator_stride;
|
||||
else
|
||||
{
|
||||
float tex_size = (float)item->get_icon_textures_size() * m_textures_scale;
|
||||
float right = left + tex_size;
|
||||
float bottom = top + tex_size;
|
||||
float right = left + scaled_icons_size;
|
||||
float bottom = top - scaled_icons_size;
|
||||
|
||||
GLToolbarItem::EState state = item->get_state();
|
||||
bool inside = (left <= mouse_pos.x) && (mouse_pos.x <= right) && (top <= mouse_pos.y) && (mouse_pos.y <= bottom);
|
||||
bool inside = (left <= scaled_mouse_pos.x) && (scaled_mouse_pos.x <= right) && (bottom <= scaled_mouse_pos.y) && (scaled_mouse_pos.y <= top);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
@ -263,22 +559,72 @@ void GLToolbar::update_hover_state(const Pointf& mouse_pos)
|
||||
break;
|
||||
}
|
||||
}
|
||||
left += (tex_size + m_gap_x);
|
||||
|
||||
top -= icon_stride;
|
||||
}
|
||||
}
|
||||
|
||||
m_parent.set_tooltip(tooltip);
|
||||
}
|
||||
|
||||
int GLToolbar::contains_mouse(const Pointf& mouse_pos) const
|
||||
int GLToolbar::_contains_mouse_horizontal(const Pointf& mouse_pos) const
|
||||
{
|
||||
if (!m_enabled)
|
||||
return -1;
|
||||
float zoom = m_parent.get_camera_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
float cnv_w = (float)m_parent.get_canvas_size().get_width();
|
||||
float width = _get_total_width();
|
||||
float left = 0.5f * (cnv_w - width);
|
||||
float top = m_offset_y;
|
||||
Size cnv_size = m_parent.get_canvas_size();
|
||||
Pointf scaled_mouse_pos((mouse_pos.x - 0.5f * (float)cnv_size.get_width()) * inv_zoom, (0.5f * (float)cnv_size.get_height() - mouse_pos.y) * inv_zoom);
|
||||
|
||||
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)
|
||||
{
|
||||
++id;
|
||||
|
||||
if (item->is_separator())
|
||||
left += separator_stride;
|
||||
else
|
||||
{
|
||||
float right = left + scaled_icons_size;
|
||||
float bottom = top - scaled_icons_size;
|
||||
|
||||
if ((left <= scaled_mouse_pos.x) && (scaled_mouse_pos.x <= right) && (bottom <= scaled_mouse_pos.y) && (scaled_mouse_pos.y <= top))
|
||||
return id;
|
||||
|
||||
left += icon_stride;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GLToolbar::_contains_mouse_vertical(const Pointf& mouse_pos) const
|
||||
{
|
||||
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();
|
||||
Pointf scaled_mouse_pos((mouse_pos.x - 0.5f * (float)cnv_size.get_width()) * inv_zoom, (0.5f * (float)cnv_size.get_height() - mouse_pos.y) * inv_zoom);
|
||||
|
||||
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;
|
||||
|
||||
@ -287,110 +633,88 @@ int GLToolbar::contains_mouse(const Pointf& mouse_pos) const
|
||||
++id;
|
||||
|
||||
if (item->is_separator())
|
||||
left += (m_separator_x + m_gap_x);
|
||||
top -= separator_stride;
|
||||
else
|
||||
{
|
||||
float tex_size = (float)item->get_icon_textures_size() * m_textures_scale;
|
||||
float right = left + tex_size;
|
||||
float bottom = top + tex_size;
|
||||
float right = left + scaled_icons_size;
|
||||
float bottom = top - scaled_icons_size;
|
||||
|
||||
if ((left <= mouse_pos.x) && (mouse_pos.x <= right) && (top <= mouse_pos.y) && (mouse_pos.y <= bottom))
|
||||
if ((left <= scaled_mouse_pos.x) && (scaled_mouse_pos.x <= right) && (bottom <= scaled_mouse_pos.y) && (scaled_mouse_pos.y <= top))
|
||||
return id;
|
||||
|
||||
left += (tex_size + m_gap_x);
|
||||
top -= icon_stride;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void GLToolbar::do_action(unsigned int item_id)
|
||||
void GLToolbar::_render_horizontal() const
|
||||
{
|
||||
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);
|
||||
unsigned int tex_id = m_icons_texture.texture.get_id();
|
||||
int tex_size = m_icons_texture.texture.get_width();
|
||||
|
||||
m_parent.render();
|
||||
item->do_action();
|
||||
}
|
||||
else
|
||||
{
|
||||
item->set_state(GLToolbarItem::HoverPressed);
|
||||
m_parent.render();
|
||||
item->do_action();
|
||||
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 Pointf& mouse_pos) const
|
||||
{
|
||||
if (!m_enabled || m_items.empty())
|
||||
if ((tex_id == 0) || (tex_size <= 0))
|
||||
return;
|
||||
|
||||
::glDisable(GL_DEPTH_TEST);
|
||||
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity();
|
||||
|
||||
float cnv_w = (float)m_parent.get_canvas_size().get_width();
|
||||
float cnv_h = (float)m_parent.get_canvas_size().get_height();
|
||||
float zoom = m_parent.get_camera_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
float width = _get_total_width();
|
||||
float top_x = -0.5f * width * inv_zoom;
|
||||
float top_y = (0.5f * cnv_h - m_offset_y * m_textures_scale) * inv_zoom;
|
||||
float scaled_gap_x = m_gap_x * inv_zoom;
|
||||
float scaled_separator_x = m_separator_x * inv_zoom;
|
||||
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)
|
||||
{
|
||||
if (item->is_separator())
|
||||
top_x += (scaled_separator_x + scaled_gap_x);
|
||||
left += separator_stride;
|
||||
else
|
||||
{
|
||||
float tex_size = (float)item->get_icon_textures_size() * m_textures_scale * inv_zoom;
|
||||
GLTexture::render_texture(item->get_icon_texture_id(), top_x, top_x + tex_size, top_y - tex_size, top_y);
|
||||
top_x += (tex_size + scaled_gap_x);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
float GLToolbar::_get_total_width() const
|
||||
void GLToolbar::_render_vertical() const
|
||||
{
|
||||
float width = 0.0f;
|
||||
unsigned int tex_id = m_icons_texture.texture.get_id();
|
||||
int tex_size = m_icons_texture.texture.get_width();
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
|
||||
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)
|
||||
{
|
||||
if (m_items[i]->is_separator())
|
||||
width += m_separator_x;
|
||||
if (item->is_separator())
|
||||
top -= separator_stride;
|
||||
else
|
||||
width += m_items[i]->get_icon_textures_size();
|
||||
|
||||
if (i < (unsigned int)m_items.size() - 1)
|
||||
width += m_gap_x;
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -28,41 +28,38 @@ public:
|
||||
enum EState : unsigned char
|
||||
{
|
||||
Normal,
|
||||
Hover,
|
||||
Pressed,
|
||||
HoverPressed,
|
||||
Disabled,
|
||||
Hover,
|
||||
HoverPressed,
|
||||
Num_States
|
||||
};
|
||||
|
||||
private:
|
||||
// icon textures are assumed to be square and all with the same size in pixels, no internal check is done
|
||||
GLTexture m_icon_textures[Num_States];
|
||||
struct Data
|
||||
{
|
||||
std::string name;
|
||||
std::string tooltip;
|
||||
unsigned int sprite_id;
|
||||
bool is_toggable;
|
||||
PerlCallback* action_callback;
|
||||
|
||||
Data();
|
||||
};
|
||||
|
||||
private:
|
||||
EType m_type;
|
||||
EState m_state;
|
||||
|
||||
std::string m_name;
|
||||
std::string m_tooltip;
|
||||
|
||||
bool m_is_toggable;
|
||||
PerlCallback* m_action_callback;
|
||||
Data m_data;
|
||||
|
||||
public:
|
||||
GLToolbarItem(EType type, const std::string& name, const std::string& tooltip, bool is_toggable, PerlCallback* action_callback);
|
||||
|
||||
bool load_textures(const std::string* filenames);
|
||||
GLToolbarItem(EType type, const Data& data);
|
||||
|
||||
EState get_state() const;
|
||||
void set_state(EState state);
|
||||
|
||||
const std::string& get_name() const;
|
||||
|
||||
const std::string& get_tooltip() const;
|
||||
|
||||
unsigned int get_icon_texture_id() const;
|
||||
int get_icon_textures_size() const;
|
||||
|
||||
void do_action();
|
||||
|
||||
bool is_enabled() const;
|
||||
@ -71,18 +68,48 @@ public:
|
||||
|
||||
bool is_toggable() const;
|
||||
bool is_separator() const;
|
||||
|
||||
void 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;
|
||||
|
||||
private:
|
||||
GLTexture::Quad_UVs _get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
|
||||
};
|
||||
|
||||
class GLToolbar
|
||||
{
|
||||
public:
|
||||
struct ItemCreationData
|
||||
// items icon textures are assumed to be square and all with the same size in pixels, no internal check is done
|
||||
// icons are layed-out into the texture starting from the top-left corner in the same order as enum GLToolbarItem::EState
|
||||
// from left to right
|
||||
struct ItemsIconsTexture
|
||||
{
|
||||
std::string name;
|
||||
std::string tooltip;
|
||||
bool is_toggable;
|
||||
PerlCallback* action_callback;
|
||||
std::string textures[GLToolbarItem::Num_States];
|
||||
GLTexture texture;
|
||||
// size of the square icons, in pixels
|
||||
unsigned int items_icon_size;
|
||||
// distance from the border, in pixels
|
||||
unsigned int items_icon_border_size;
|
||||
// distance between two adjacent icons (to avoid filtering artifacts), in pixels
|
||||
unsigned int items_icon_gap_size;
|
||||
|
||||
ItemsIconsTexture();
|
||||
};
|
||||
|
||||
struct Layout
|
||||
{
|
||||
enum Type : unsigned char
|
||||
{
|
||||
Horizontal,
|
||||
Vertical,
|
||||
Num_Types
|
||||
};
|
||||
|
||||
Type type;
|
||||
float top;
|
||||
float left;
|
||||
float separator_size;
|
||||
float gap_size;
|
||||
|
||||
Layout();
|
||||
};
|
||||
|
||||
private:
|
||||
@ -90,27 +117,32 @@ private:
|
||||
|
||||
GLCanvas3D& m_parent;
|
||||
bool m_enabled;
|
||||
ItemsList m_items;
|
||||
ItemsIconsTexture m_icons_texture;
|
||||
Layout m_layout;
|
||||
|
||||
float m_textures_scale;
|
||||
float m_offset_y;
|
||||
float m_gap_x;
|
||||
float m_separator_x;
|
||||
ItemsList m_items;
|
||||
|
||||
public:
|
||||
explicit GLToolbar(GLCanvas3D& parent);
|
||||
|
||||
bool init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size);
|
||||
|
||||
Layout::Type get_layout_type() const;
|
||||
void set_layout_type(Layout::Type type);
|
||||
|
||||
void set_position(float top, float left);
|
||||
void set_separator_size(float size);
|
||||
void set_gap_size(float size);
|
||||
|
||||
bool is_enabled() const;
|
||||
void set_enabled(bool enable);
|
||||
|
||||
void set_textures_scale(float scale);
|
||||
void set_offset_y(float offset);
|
||||
void set_gap_x(float gap);
|
||||
void set_separator_x(float separator);
|
||||
|
||||
bool add_item(const ItemCreationData& data);
|
||||
bool add_item(const GLToolbarItem::Data& data);
|
||||
bool add_separator();
|
||||
|
||||
float get_width() const;
|
||||
float get_height() const;
|
||||
|
||||
void enable_item(const std::string& name);
|
||||
void disable_item(const std::string& name);
|
||||
|
||||
@ -123,10 +155,20 @@ public:
|
||||
|
||||
void do_action(unsigned int item_id);
|
||||
|
||||
void render(const Pointf& mouse_pos) const;
|
||||
void render() const;
|
||||
|
||||
private:
|
||||
float _get_total_width() const;
|
||||
float _get_width_horizontal() const;
|
||||
float _get_width_vertical() const;
|
||||
float _get_height_horizontal() const;
|
||||
float _get_height_vertical() const;
|
||||
float _get_main_size() const;
|
||||
void _update_hover_state_horizontal(const Pointf& mouse_pos);
|
||||
void _update_hover_state_vertical(const Pointf& mouse_pos);
|
||||
int _contains_mouse_horizontal(const Pointf& mouse_pos) const;
|
||||
int _contains_mouse_vertical(const Pointf& mouse_pos) const;
|
||||
void _render_horizontal() const;
|
||||
void _render_vertical() const;
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|