Hint notification fixes and improvements

Hint notification bold (diff color) headline on multiple lines
Hint notification: Documentation link button.
Hints.ini header
hints logo - clippy 
disabled a preffered modes and techs for hints notifications
Empty hints array check. Fix of #6774.
This commit is contained in:
David Kocik 2021-08-09 17:09:09 +02:00
parent 4efce682e1
commit b43f225ac8
8 changed files with 538 additions and 92 deletions

View file

@ -124,32 +124,34 @@ namespace ImGui
const char ColorMarkerEnd = 0x3; // ETX
// Special ASCII characters are used here as an ikons markers
const char PrintIconMarker = 0x4;
const char PrinterIconMarker = 0x5;
const char PrinterSlaIconMarker = 0x6;
const char FilamentIconMarker = 0x7;
const char MaterialIconMarker = 0x8;
const char CloseNotifButton = 0xB;
const char CloseNotifHoverButton = 0xC;
const char MinimalizeButton = 0xE;
const char MinimalizeHoverButton = 0xF;
const char WarningMarker = 0x10;
const char ErrorMarker = 0x11;
const char EjectButton = 0x12;
const char EjectHoverButton = 0x13;
const char CancelButton = 0x14;
const char CancelHoverButton = 0x15;
const char VarLayerHeightMarker = 0x16;
const wchar_t PrintIconMarker = 0x4;
const wchar_t PrinterIconMarker = 0x5;
const wchar_t PrinterSlaIconMarker = 0x6;
const wchar_t FilamentIconMarker = 0x7;
const wchar_t MaterialIconMarker = 0x8;
const wchar_t CloseNotifButton = 0xB;
const wchar_t CloseNotifHoverButton = 0xC;
const wchar_t MinimalizeButton = 0xE;
const wchar_t MinimalizeHoverButton = 0xF;
const wchar_t WarningMarker = 0x10;
const wchar_t ErrorMarker = 0x11;
const wchar_t EjectButton = 0x12;
const wchar_t EjectHoverButton = 0x13;
const wchar_t CancelButton = 0x14;
const wchar_t CancelHoverButton = 0x15;
const wchar_t VarLayerHeightMarker = 0x16;
const char RightArrowButton = 0x18;
const char RightArrowHoverButton = 0x19;
const char PreferencesButton = 0x1A;
const char PreferencesHoverButton = 0x1B;
const char SinkingObjectMarker = 0x1C;
const char CustomSupportsMarker = 0x1D;
const char CustomSeamMarker = 0x1E;
const char MmuSegmentationMarker = 0x1F;
const wchar_t RightArrowButton = 0x18;
const wchar_t RightArrowHoverButton = 0x19;
const wchar_t PreferencesButton = 0x1A;
const wchar_t PreferencesHoverButton = 0x1B;
const wchar_t SinkingObjectMarker = 0x1C;
const wchar_t CustomSupportsMarker = 0x1D;
const wchar_t CustomSeamMarker = 0x1E;
const wchar_t MmuSegmentationMarker = 0x1F;
const wchar_t DocumentationButton = 0x2600;
const wchar_t DocumentationHoverButton = 0x2601;
const wchar_t ClippyMarker = 0x2602;
// void MyFunction(const char* name, const MyMatrix44& v);

View file

@ -31,9 +31,9 @@ inline void push_style_color(ImGuiCol idx, const ImVec4& col, bool fading_out, f
ImGui::PushStyleColor(idx, col);
}
// return true if NOT in disabled mode.
inline bool disabled_modes_check(const std::string& disabled_modes)
inline bool mode_and_tech_check(const std::string& disabled_mode, const std::string& preferred_mode, const std::string& disabled_tech, const std::string& preferred_tech)
{
if (disabled_modes.empty())
if (disabled_mode.empty() && preferred_mode.empty() && disabled_tech.empty() && preferred_tech.empty())
return true;
// simple / advanced / expert
@ -43,19 +43,37 @@ inline bool disabled_modes_check(const std::string& disabled_modes)
else if (config_mode == ConfigOptionMode::comAdvanced) mode_name = "advanced";
else if (config_mode == ConfigOptionMode::comExpert) mode_name = "expert";
if (!mode_name.empty() && disabled_modes.find(mode_name) != std::string::npos)
if (!preferred_mode.empty() && !mode_name.empty() && preferred_mode.find(mode_name) == std::string::npos)
return false;
if (!mode_name.empty() && disabled_mode.find(mode_name) != std::string::npos)
return false;
// fff / sla
// tchnology
const PrinterTechnology tech = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
if (tech == ptFFF) {
if (disabled_modes.find("FFF") != std::string::npos)
return false;
// MMU
bool is_mmu = wxGetApp().extruders_edited_cnt() > 1;
if (is_mmu)
{
if (!preferred_tech.empty() && preferred_tech.find("MMU") == std::string::npos)
return false;
if (is_mmu && disabled_tech.find("MMU") != std::string::npos)
return false;
} else {
// only FFF - does not show if MMU preffered
if (!preferred_tech.empty() && preferred_tech.find("FFF") == std::string::npos)
return false;
if (disabled_tech.find("FFF") != std::string::npos)
return false;
}
} else {
if (disabled_modes.find("SLA") != std::string::npos)
return false;
}
// SLA
if (!preferred_tech.empty() && preferred_tech.find("SLA") == std::string::npos)
return false;
if (disabled_tech.find("SLA") != std::string::npos)
return false;
}
return true;
}
} //namespace
@ -96,7 +114,11 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
std::string text1;
std::string hypertext_text;
std::string follow_text;
std::string disabled_modes;
std::string disabled_mode;
std::string preferred_mode;
std::string disabled_tech;
std::string preferred_tech;
std::string documentation_link;
unescape_string_cstyle(_utf8(dict["text"]), fulltext);
// replace <b> and </b> for imgui markers
std::string marker_s(1, ImGui::ColorMarkerStart);
@ -143,8 +165,20 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
text1 = fulltext;
}
if (dict.find("disabled_modes") != dict.end()) {
disabled_modes = dict["disabled_modes"];
if (dict.find("disabled_mode") != dict.end()) {
disabled_mode = dict["disabled_mode"];
}
if (dict.find("preferred_mode") != dict.end()) {
preferred_mode = dict["preferred_mode"];
}
if (dict.find("disabled_tech") != dict.end()) {
disabled_tech = dict["disabled_tech"];
}
if (dict.find("preferred_tech") != dict.end()) {
preferred_tech = dict["preferred_tech"];
}
if (dict.find("documentation_link") != dict.end()) {
documentation_link = dict["documentation_link"];
}
// create HintData
@ -152,37 +186,37 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
//link to internet
if(dict["hypertext_type"] == "link") {
std::string hypertext_link = dict["hypertext_link"];
HintData hint_data{ text1, hypertext_text, follow_text, disabled_modes, false, [hypertext_link]() { wxLaunchDefaultBrowser(hypertext_link); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link, [hypertext_link]() { wxLaunchDefaultBrowser(hypertext_link); } };
m_loaded_hints.emplace_back(hint_data);
// highlight settings
} else if (dict["hypertext_type"] == "settings") {
std::string opt = dict["hypertext_settings_opt"];
Preset::Type type = static_cast<Preset::Type>(std::atoi(dict["hypertext_settings_type"].c_str()));
std::wstring category = boost::nowide::widen(dict["hypertext_settings_category"]);
HintData hint_data{ text1, hypertext_text, follow_text, disabled_modes, true, [opt, type, category]() { GUI::wxGetApp().sidebar().jump_to_option(opt, type, category); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, true, documentation_link, [opt, type, category]() { GUI::wxGetApp().sidebar().jump_to_option(opt, type, category); } };
m_loaded_hints.emplace_back(hint_data);
// open preferences
} else if(dict["hypertext_type"] == "preferences") {
int page = static_cast<Preset::Type>(std::atoi(dict["hypertext_preferences_page"].c_str()));
HintData hint_data{ text1, hypertext_text, follow_text, disabled_modes, false, [page]() { wxGetApp().open_preferences(page); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link, [page]() { wxGetApp().open_preferences(page); } };
m_loaded_hints.emplace_back(hint_data);
} else if (dict["hypertext_type"] == "plater") {
std::string item = dict["hypertext_plater_item"];
HintData hint_data{ text1, hypertext_text, follow_text, disabled_modes, true, [item]() { wxGetApp().plater()->canvas3D()->highlight_toolbar_item(item); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, true, documentation_link, [item]() { wxGetApp().plater()->canvas3D()->highlight_toolbar_item(item); } };
m_loaded_hints.emplace_back(hint_data);
} else if (dict["hypertext_type"] == "gizmo") {
std::string item = dict["hypertext_gizmo_item"];
HintData hint_data{ text1, hypertext_text, follow_text, disabled_modes, true, [item]() { wxGetApp().plater()->canvas3D()->highlight_gizmo(item); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, true, documentation_link, [item]() { wxGetApp().plater()->canvas3D()->highlight_gizmo(item); } };
m_loaded_hints.emplace_back(hint_data);
}
else if (dict["hypertext_type"] == "gallery") {
HintData hint_data{ text1, hypertext_text, follow_text, disabled_modes, false, []() { wxGetApp().obj_list()->load_shape_object_from_gallery(); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link, []() { wxGetApp().obj_list()->load_shape_object_from_gallery(); } };
m_loaded_hints.emplace_back(hint_data);
}
} else {
// plain text without hypertext
HintData hint_data{ text1 };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link };
m_loaded_hints.emplace_back(hint_data);
}
}
@ -194,6 +228,12 @@ HintData* HintDatabase::get_hint(bool up)
init();
//return false;
}
if (m_loaded_hints.empty())
{
BOOST_LOG_TRIVIAL(error) << "There were no hints loaded from hints.ini file.";
return nullptr;
}
// shift id
m_hint_id = (up ? m_hint_id + 1 : (m_hint_id == 0 ? m_loaded_hints.size() - 1 : m_hint_id - 1));
m_hint_id %= m_loaded_hints.size();
@ -220,12 +260,16 @@ void NotificationManager::HintNotification::count_spaces()
std::string text;
text = ImGui::WarningMarker;
float picture_width = ImGui::CalcTextSize(text.c_str()).x;
m_left_indentation = picture_width + m_line_height / 2;
m_left_indentation = picture_width * 2 + m_line_height / 2;
// no left button picture
//m_left_indentation = m_line_height;
m_window_width_offset = m_left_indentation + m_line_height * 3.f;// 5.5f; // no right arrow
if (m_documentation_link.empty())
m_window_width_offset = m_left_indentation + m_line_height * 3.f;
else
m_window_width_offset = m_left_indentation + m_line_height * 5.5f;
m_window_width = m_line_height * 25;
}
@ -387,12 +431,12 @@ void NotificationManager::HintNotification::set_next_window_size(ImGuiWrapper& i
m_window_height += 1 * m_line_height; // top and bottom
*/
m_window_height = std::max((m_lines_count + 1.f) * m_line_height, 4.f * m_line_height);
m_window_height = std::max((m_lines_count + 1.f) * m_line_height, 5.f * m_line_height);
}
bool NotificationManager::HintNotification::on_text_click()
{
if (m_hypertext_callback != nullptr && (!m_runtime_disable || disabled_modes_check(m_disabled_modes)))
if (m_hypertext_callback != nullptr && (!m_runtime_disable || mode_and_tech_check(m_disabled_mode, m_preferred_mode, m_disabled_tech, m_preferred_tech)))
m_hypertext_callback();
return false;
}
@ -405,7 +449,7 @@ void NotificationManager::HintNotification::render_text(ImGuiWrapper& imgui, con
float x_offset = m_left_indentation;
int last_end = 0;
float starting_y = (m_lines_count == 2 ? win_size_y / 2 - m_line_height :(m_lines_count == 1 ? win_size_y / 2 - m_line_height / 2: m_line_height / 2));
float starting_y = (m_lines_count < 4 ? m_line_height / 2 * (4 - m_lines_count + 1) : m_line_height / 2);
float shift_y = m_line_height;
std::string line;
@ -425,8 +469,8 @@ void NotificationManager::HintNotification::render_text(ImGuiWrapper& imgui, con
// regural line
line = m_text1.substr(last_end, m_endlines[i] - last_end);
}
// first line is headline
if (i == 0) {
// first line is headline (for hint notification it must be divided by \n)
if (m_text1.find('\n') >= m_endlines[i]) {
line = ImGui::ColorMarkerStart + line + ImGui::ColorMarkerEnd;
}
// Add ImGui::ColorMarkerStart if there is ImGui::ColorMarkerEnd first (start was at prev line)
@ -534,6 +578,11 @@ void NotificationManager::HintNotification::render_close_button(ImGuiWrapper& im
render_right_arrow_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
render_logo(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
render_preferences_button(imgui, win_pos_x, win_pos_y);
if (!m_documentation_link.empty())
{
render_documentation_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
}
}
void NotificationManager::HintNotification::render_preferences_button(ImGuiWrapper& imgui, const float win_pos_x, const float win_pos_y)
@ -576,7 +625,6 @@ void NotificationManager::HintNotification::render_preferences_button(ImGuiWrapp
// preferences button is in place of minimize button
m_minimize_b_visible = true;
}
void NotificationManager::HintNotification::render_right_arrow_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
{
// Used for debuging
@ -621,12 +669,14 @@ void NotificationManager::HintNotification::render_logo(ImGuiWrapper& imgui, con
push_style_color(ImGuiCol_TextSelectedBg, ImVec4(0, .75f, .75f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(.0f, .0f, .0f, .0f));
std::string button_text;
button_text = ImGui::ErrorMarker;//LeftArrowButton;
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
std::wstring button_text;
button_text = ImGui::ClippyMarker;//LeftArrowButton;
std::string placeholder_text;
placeholder_text = ImGui::EjectButton;
ImVec2 button_pic_size = ImGui::CalcTextSize(placeholder_text.c_str());
ImVec2 button_size(button_pic_size.x * 1.25f * 2.f, button_pic_size.y * 1.25f * 2.f);
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y * 1.1f);
ImGui::SetCursorPosX(0);
// shouldnt it render as text?
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
@ -639,10 +689,81 @@ void NotificationManager::HintNotification::render_logo(ImGuiWrapper& imgui, con
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
void NotificationManager::HintNotification::render_documentation_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
{
ImVec2 win_size(win_size_x, win_size_y);
ImVec2 win_pos(win_pos_x, win_pos_y);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.0f, .0f, .0f, .0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.0f, .0f, .0f, .0f));
push_style_color(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
push_style_color(ImGuiCol_TextSelectedBg, ImVec4(0, .75f, .75f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(.0f, .0f, .0f, .0f));
std::wstring button_text;
button_text = ImGui::DocumentationButton;
std::string placeholder_text;
placeholder_text = ImGui::EjectButton;
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - m_line_height * 5.f, win_pos.y),
ImVec2(win_pos.x - m_line_height * 2.5f, win_pos.y + win_size.y - 2 * m_line_height),
true))
{
button_text = ImGui::DocumentationHoverButton;
// tooltip
long time_now = wxGetLocalTime();
if (m_hover_time > 0 && m_hover_time < time_now) {
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::BeginTooltip();
imgui.text(_u8L("Open Documentation in web browser"));
ImGui::EndTooltip();
ImGui::PopStyleColor();
}
if (m_hover_time == 0)
m_hover_time = time_now;
}
else
m_hover_time = 0;
ImVec2 button_pic_size = ImGui::CalcTextSize(placeholder_text.c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
ImGui::SetCursorPosX(win_size.x - m_line_height * 5.0f);
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
{
open_documentation();
}
//invisible large button
ImGui::SetCursorPosX(win_size.x - m_line_height * 4.625f);
ImGui::SetCursorPosY(0);
if (imgui.button(" ", m_line_height * 2.f, win_size.y - 2 * m_line_height))
{
open_documentation();
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
void NotificationManager::HintNotification::open_documentation()
{
if (!m_documentation_link.empty())
{
wxLaunchDefaultBrowser(m_documentation_link);
}
}
void NotificationManager::HintNotification::retrieve_data(size_t recursion_counter)
{
HintData* hint_data = HintDatabase::get_instance().get_hint(true);
if (hint_data != nullptr && !disabled_modes_check(hint_data->disabled_modes))
if (hint_data == nullptr)
close();
if (hint_data != nullptr && !mode_and_tech_check(hint_data->disabled_mode, hint_data->preferred_mode, hint_data->disabled_tech, hint_data->preferred_tech))
{
// Content for different user - retrieve another
size_t count = HintDatabase::get_instance().get_count();
@ -661,12 +782,15 @@ void NotificationManager::HintNotification::retrieve_data(size_t recursion_count
hint_data->text,
hint_data->hypertext, nullptr,
hint_data->follow_text };
update(nd);
m_hypertext_callback = hint_data->callback;
m_disabled_modes = hint_data->disabled_modes;
m_disabled_mode = hint_data->disabled_mode;
m_preferred_mode = hint_data->preferred_mode;
m_disabled_tech = hint_data->disabled_tech;
m_preferred_tech = hint_data->preferred_tech;
m_runtime_disable = hint_data->runtime_disable;
m_documentation_link = hint_data->documentation_link;
m_has_hint_data = true;
update(nd);
}
}
} //namespace Slic3r

View file

@ -12,9 +12,13 @@ struct HintData
std::string text;
std::string hypertext;
std::string follow_text;
std::string disabled_modes;
std::string disabled_mode;
std::string preferred_mode;
std::string disabled_tech;
std::string preferred_tech;
bool runtime_disable; // if true - hyperlink will check before every click if not in disabled mode
std::function<void(void)> callback{ nullptr };
std::string documentation_link;
std::function<void(void)> callback { nullptr };
};
class HintDatabase
@ -77,18 +81,27 @@ protected:
void render_right_arrow_button(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
void render_documentation_button(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
void render_logo(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
void retrieve_data(size_t recursion_counter = 0);
void open_documentation();
bool m_has_hint_data { false };
std::function<void(void)> m_hypertext_callback;
std::string m_disabled_modes;
std::string m_disabled_mode;
std::string m_preferred_mode;
std::string m_disabled_tech;
std::string m_preferred_tech;
bool m_runtime_disable;
std::string m_documentation_link;
float m_close_b_y { 0 };
float m_close_b_w { 0 };
// hover of buttons
size_t m_hover_time { 0 };
};
} //namespace Slic3r

View file

@ -36,7 +36,7 @@ namespace Slic3r {
namespace GUI {
static const std::map<const char, std::string> font_icons = {
static const std::map<const wchar_t, std::string> font_icons = {
{ImGui::PrintIconMarker , "cog" },
{ImGui::PrinterIconMarker , "printer" },
{ImGui::PrinterSlaIconMarker , "sla_printer" },
@ -49,21 +49,27 @@ static const std::map<const char, std::string> font_icons = {
{ImGui::PreferencesButton , "notification_preferences" },
{ImGui::PreferencesHoverButton , "notification_preferences_hover"},
};
static const std::map<const char, std::string> font_icons_large = {
{ImGui::CloseNotifButton , "notification_close" },
{ImGui::CloseNotifHoverButton , "notification_close_hover" },
{ImGui::EjectButton , "notification_eject_sd" },
{ImGui::EjectHoverButton , "notification_eject_sd_hover" },
{ImGui::WarningMarker , "notification_warning" },
{ImGui::ErrorMarker , "notification_error" },
{ImGui::CancelButton , "notification_cancel" },
{ImGui::CancelHoverButton , "notification_cancel_hover" },
{ImGui::SinkingObjectMarker , "move" },
{ImGui::CustomSupportsMarker , "fdm_supports" },
{ImGui::CustomSeamMarker , "seam" },
{ImGui::MmuSegmentationMarker , "move" },
{ImGui::VarLayerHeightMarker , "layers" },
static const std::map<const wchar_t, std::string> font_icons_large = {
{ImGui::CloseNotifButton , "notification_close" },
{ImGui::CloseNotifHoverButton , "notification_close_hover" },
{ImGui::EjectButton , "notification_eject_sd" },
{ImGui::EjectHoverButton , "notification_eject_sd_hover" },
{ImGui::WarningMarker , "notification_warning" },
{ImGui::ErrorMarker , "notification_error" },
{ImGui::CancelButton , "notification_cancel" },
{ImGui::CancelHoverButton , "notification_cancel_hover" },
{ImGui::SinkingObjectMarker , "move" },
{ImGui::CustomSupportsMarker , "fdm_supports" },
{ImGui::CustomSeamMarker , "seam" },
{ImGui::MmuSegmentationMarker , "move" },
{ImGui::VarLayerHeightMarker , "layers" },
{ImGui::DocumentationButton , "notification_documentation" },
{ImGui::DocumentationHoverButton, "notification_documentation_hover"},
};
static const std::map<const wchar_t, std::string> font_icons_extra_large = {
{ImGui::ClippyMarker , "notification_clippy" },
};
const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.333f, 0.333f, 0.333f, 1.0f };
@ -989,6 +995,8 @@ void ImGuiWrapper::init_font(bool compress)
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz);
for (auto& icon : font_icons_large)
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 2, icon_sz * 2, 3.0 * font_scale + icon_sz * 2);
for (auto& icon : font_icons_extra_large)
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 4, icon_sz * 4, 3.0 * font_scale + icon_sz * 4);
// Build texture atlas
unsigned char* pixels;
@ -1027,6 +1035,22 @@ void ImGuiWrapper::init_font(bool compress)
rect_id++;
}
icon_sz *= 2; // default size of extra large icon is 64 px
for (auto icon : font_icons_extra_large) {
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) {
assert(rect->Width == icon_sz);
assert(rect->Height == icon_sz);
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz);
const ImU32* pIn = (ImU32*)raw_data.data();
for (int y = 0; y < icon_sz; y++) {
ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X);
for (int x = 0; x < icon_sz; x++)
*pOut++ = *pIn++;
}
}
rect_id++;
}
// Upload texture to graphics system
GLint last_texture;
glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));