Automatic generation of variants of icons for toolbars and gizmos
This commit is contained in:
parent
987a83bb0c
commit
a8610f990e
6 changed files with 120 additions and 16 deletions
|
@ -3276,7 +3276,12 @@ bool GLCanvas3D::Gizmos::generate_icons_texture() const
|
|||
}
|
||||
}
|
||||
|
||||
bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, GLGizmoBase::Num_States, (unsigned int)(m_overlay_icons_size * m_overlay_scale));
|
||||
std::vector<std::pair<int, bool>> states;
|
||||
states.push_back(std::make_pair(1, false));
|
||||
states.push_back(std::make_pair(0, false));
|
||||
states.push_back(std::make_pair(0, true));
|
||||
|
||||
bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_overlay_icons_size * m_overlay_scale));
|
||||
if (res)
|
||||
m_icons_texture_dirty = false;
|
||||
|
||||
|
@ -3713,7 +3718,11 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
|||
#endif
|
||||
, m_in_render(false)
|
||||
, m_bed(nullptr)
|
||||
#if ENABLE_SVG_ICONS
|
||||
, m_toolbar(GLToolbar::Normal, "Top")
|
||||
#else
|
||||
, m_toolbar(GLToolbar::Normal)
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
, m_view_toolbar(nullptr)
|
||||
, m_use_clipping_planes(false)
|
||||
, m_sidebar_field("")
|
||||
|
@ -5988,7 +5997,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
item.icon_filename = "split_parts.svg";
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
item.tooltip = GUI::L_str("Split to parts");
|
||||
item.sprite_id = 8;
|
||||
item.sprite_id = 7;
|
||||
item.action_event = EVT_GLTOOLBAR_SPLIT_VOLUMES;
|
||||
if (!m_toolbar.add_item(item))
|
||||
return false;
|
||||
|
@ -6001,7 +6010,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
item.icon_filename = "layers.svg";
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
item.tooltip = GUI::L_str("Layers editing");
|
||||
item.sprite_id = 7;
|
||||
item.sprite_id = 8;
|
||||
item.is_toggable = true;
|
||||
item.action_event = EVT_GLTOOLBAR_LAYERSEDITING;
|
||||
if (!m_toolbar.add_item(item))
|
||||
|
|
|
@ -138,19 +138,19 @@ bool GLTexture::load_from_file(const std::string& filename, bool use_mipmaps)
|
|||
#endif // ENABLE_TEXTURES_FROM_SVG
|
||||
|
||||
#if ENABLE_SVG_ICONS
|
||||
bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, unsigned int num_states, unsigned int sprite_size_px)
|
||||
bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, const std::vector<std::pair<int, bool>>& states, unsigned int sprite_size_px)
|
||||
{
|
||||
static int pass = 0;
|
||||
++pass;
|
||||
|
||||
reset();
|
||||
|
||||
if (filenames.empty() || (num_states == 0) || (sprite_size_px == 0))
|
||||
if (filenames.empty() || states.empty() || (sprite_size_px == 0))
|
||||
return false;
|
||||
|
||||
m_width = (int)(sprite_size_px * num_states);
|
||||
m_width = (int)(sprite_size_px * states.size());
|
||||
m_height = (int)(sprite_size_px * filenames.size());
|
||||
int n_pixels = m_width * m_height;
|
||||
int sprite_n_pixels = sprite_size_px * sprite_size_px;
|
||||
int sprite_bytes = sprite_n_pixels * 4;
|
||||
int sprite_stride = sprite_size_px * 4;
|
||||
|
||||
if (n_pixels <= 0)
|
||||
{
|
||||
|
@ -159,7 +159,10 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
|||
}
|
||||
|
||||
std::vector<unsigned char> data(n_pixels * 4, 0);
|
||||
std::vector<unsigned char> sprite_data(sprite_size_px * sprite_size_px * 4, 0);
|
||||
std::vector<unsigned char> sprite_data(sprite_bytes, 0);
|
||||
std::vector<unsigned char> sprite_white_only_data(sprite_bytes, 0);
|
||||
std::vector<unsigned char> sprite_gray_only_data(sprite_bytes, 0);
|
||||
std::vector<unsigned char> output_data(sprite_bytes, 0);
|
||||
|
||||
NSVGrasterizer* rast = nsvgCreateRasterizer();
|
||||
if (rast == nullptr)
|
||||
|
@ -185,16 +188,58 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
|||
|
||||
float scale = (float)sprite_size_px / std::max(image->width, image->height);
|
||||
|
||||
nsvgRasterize(rast, image, 0, 0, scale, sprite_data.data(), sprite_size_px, sprite_size_px, sprite_size_px * 4);
|
||||
nsvgRasterize(rast, image, 0, 0, scale, sprite_data.data(), sprite_size_px, sprite_size_px, sprite_stride);
|
||||
|
||||
// makes white only copy of the sprite
|
||||
::memcpy((void*)sprite_white_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
|
||||
for (int i = 0; i < sprite_n_pixels; ++i)
|
||||
{
|
||||
if (sprite_white_only_data.data()[i * 4] != 0)
|
||||
::memset((void*)&sprite_white_only_data.data()[i * 4], 255, 3);
|
||||
}
|
||||
|
||||
// makes gray only copy of the sprite
|
||||
::memcpy((void*)sprite_gray_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
|
||||
for (int i = 0; i < sprite_n_pixels; ++i)
|
||||
{
|
||||
if (sprite_gray_only_data.data()[i * 4] != 0)
|
||||
::memset((void*)&sprite_gray_only_data.data()[i * 4], 128, 3);
|
||||
}
|
||||
|
||||
int sprite_offset_px = sprite_id * sprite_size_px * m_width;
|
||||
for (unsigned int i = 0; i < num_states; ++i)
|
||||
int state_id = -1;
|
||||
for (const std::pair<int, bool>& state : states)
|
||||
{
|
||||
int state_offset_px = sprite_offset_px + i * sprite_size_px;
|
||||
++state_id;
|
||||
|
||||
// select the sprite variant
|
||||
std::vector<unsigned char>* src = nullptr;
|
||||
switch (state.first)
|
||||
{
|
||||
case 1: { src = &sprite_white_only_data; break; }
|
||||
case 2: { src = &sprite_gray_only_data; break; }
|
||||
default: { src = &sprite_data; break; }
|
||||
}
|
||||
|
||||
::memcpy((void*)output_data.data(), (const void*)src->data(), sprite_bytes);
|
||||
// applies background, if needed
|
||||
if (state.second)
|
||||
{
|
||||
for (int i = 0; i < sprite_n_pixels; ++i)
|
||||
{
|
||||
float alpha = (float)output_data.data()[i * 4 + 3] / 255.0f;
|
||||
output_data.data()[i * 4 + 0] = (unsigned char)(0 * (1.0f - alpha) + output_data.data()[i * 4 + 0] * alpha);
|
||||
output_data.data()[i * 4 + 1] = (unsigned char)(0 * (1.0f - alpha) + output_data.data()[i * 4 + 1] * alpha);
|
||||
output_data.data()[i * 4 + 2] = (unsigned char)(0 * (1.0f - alpha) + output_data.data()[i * 4 + 2] * alpha);
|
||||
output_data.data()[i * 4 + 3] = (unsigned char)(128 * (1.0f - alpha) + output_data.data()[i * 4 + 3] * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
int state_offset_px = sprite_offset_px + state_id * sprite_size_px;
|
||||
for (int j = 0; j < sprite_size_px; ++j)
|
||||
{
|
||||
int data_offset = (state_offset_px + j * m_width) * 4;
|
||||
::memcpy((void*)&data.data()[data_offset], (const void*)&sprite_data.data()[j * sprite_size_px * 4], sprite_size_px * 4);
|
||||
::memcpy((void*)&data.data()[data_offset], (const void*)&output_data.data()[j * sprite_stride], sprite_stride);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,6 +261,11 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
|||
|
||||
|
||||
m_source = filenames.front();
|
||||
|
||||
#if 0
|
||||
// debug output
|
||||
static int pass = 0;
|
||||
++pass;
|
||||
|
||||
wxImage output(m_width, m_height);
|
||||
output.InitAlpha();
|
||||
|
@ -232,6 +282,7 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
|||
}
|
||||
|
||||
output.SaveFile("C:/prusa/slic3r/svg_icons/temp/test_" + std::to_string(pass) + ".png", wxBITMAP_TYPE_PNG);
|
||||
#endif // 0
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,15 @@ namespace GUI {
|
|||
bool load_from_svg_file(const std::string& filename, bool use_mipmaps, unsigned int max_size_px);
|
||||
#endif // ENABLE_TEXTURES_FROM_SVG
|
||||
#if ENABLE_SVG_ICONS
|
||||
bool load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, unsigned int num_states, unsigned int sprite_size_px);
|
||||
// meanings of states: (std::pair<int, bool>)
|
||||
// first field (int):
|
||||
// 0 -> no changes
|
||||
// 1 -> use white only color variant
|
||||
// 2 -> use gray only color variant
|
||||
// second field (bool):
|
||||
// false -> no changes
|
||||
// true -> add background color
|
||||
bool load_from_svg_files_as_sprites_array(const std::vector<std::string>& filenames, const std::vector<std::pair<int, bool>>& states, unsigned int sprite_size_px);
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -124,8 +124,15 @@ GLToolbar::Layout::Layout()
|
|||
{
|
||||
}
|
||||
|
||||
#if ENABLE_SVG_ICONS
|
||||
GLToolbar::GLToolbar(GLToolbar::EType type, const std::string& name)
|
||||
#else
|
||||
GLToolbar::GLToolbar(GLToolbar::EType type)
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
: m_type(type)
|
||||
#if ENABLE_SVG_ICONS
|
||||
, m_name(name)
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
, m_enabled(false)
|
||||
#if ENABLE_SVG_ICONS
|
||||
, m_icons_texture_dirty(true)
|
||||
|
@ -1231,7 +1238,25 @@ bool GLToolbar::generate_icons_texture() const
|
|||
filenames.push_back(path + icon_filename);
|
||||
}
|
||||
|
||||
bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, GLToolbarItem::Num_States, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
||||
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));
|
||||
if (res)
|
||||
m_icons_texture_dirty = false;
|
||||
|
||||
|
|
|
@ -203,6 +203,9 @@ private:
|
|||
typedef std::vector<GLToolbarItem*> ItemsList;
|
||||
|
||||
EType m_type;
|
||||
#if ENABLE_SVG_ICONS
|
||||
std::string m_name;
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
bool m_enabled;
|
||||
#if ENABLE_SVG_ICONS
|
||||
mutable GLTexture m_icons_texture;
|
||||
|
@ -216,7 +219,11 @@ private:
|
|||
ItemsList m_items;
|
||||
|
||||
public:
|
||||
#if ENABLE_SVG_ICONS
|
||||
GLToolbar(EType type, const std::string& name);
|
||||
#else
|
||||
explicit GLToolbar(EType type);
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
~GLToolbar();
|
||||
|
||||
#if ENABLE_SVG_ICONS
|
||||
|
|
|
@ -1178,7 +1178,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
, sidebar(new Sidebar(q))
|
||||
, delayed_scene_refresh(false)
|
||||
, project_filename(wxEmptyString)
|
||||
#if ENABLE_SVG_ICONS
|
||||
, view_toolbar(GLToolbar::Radio, "View")
|
||||
#else
|
||||
, view_toolbar(GLToolbar::Radio)
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
{
|
||||
arranging.store(false);
|
||||
rotoptimizing.store(false);
|
||||
|
|
Loading…
Reference in a new issue