From 569ba0600cd5bde8f99eef7c4f68fff2534f4593 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Fri, 29 Jul 2022 18:21:40 +0200 Subject: [PATCH] Fix rename and save as style text --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 364 ++++++++++++++---------- src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp | 10 +- src/slic3r/Utils/FontManager.cpp | 108 ++++--- src/slic3r/Utils/FontManager.hpp | 40 ++- src/slic3r/Utils/WxFontUtils.cpp | 4 +- src/slic3r/Utils/WxFontUtils.hpp | 3 +- 6 files changed, 335 insertions(+), 194 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 056257526..527e6fb3c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -614,7 +614,7 @@ void GLGizmoEmboss::on_set_state() // to reload fonts from system, when install new one wxFontEnumerator::InvalidateCache(); - // Try(when exist) set configuration by volume + // Try(when exist) set text configuration by volume load_configuration(get_selected_volume()); // change position of just opened emboss window @@ -971,41 +971,14 @@ void GLGizmoEmboss::close() mng.open_gizmo(GLGizmosManager::Emboss); } -//void GLGizmoEmboss::fill_stored_font_items() -//{ -// m_stored_font_items.clear(); -// for (const auto &item : m_style_manager.get_styles()) { -// const FontItem &fi = item.font_item; -// // skip file paths + fonts from other OS(loaded from .3mf) -// if (fi.type != WxFontUtils::get_actual_type()) continue; -// -// assert(m_stored_font_items.find(fi.name) == m_stored_font_items.end()); -// m_stored_font_items[fi.name] = fi; // copy -// } -// select_stored_font_item(); -//} -// -//void GLGizmoEmboss::select_stored_font_item() -//{ -// const std::string &name = m_style_manager.get_font_item().name; -// const auto &it = m_stored_font_items.find(name); -// if (it == m_stored_font_items.end()) { -// m_stored_font_item.reset(); -// m_stored_wx_font.reset(); -// return; -// } -// m_stored_font_item = it->second; -// m_stored_wx_font = WxFontUtils::load_wxFont(m_stored_font_item->path); -//} - void GLGizmoEmboss::draw_window() { #ifdef ALLOW_DEBUG_MODE if (ImGui::Button("re-process")) process(); if (ImGui::Button("add svg")) choose_svg_file(); if (ImGui::Button("use system font")) { - size_t font_index = m_font_list.size(); - m_font_list.emplace_back(WxFontUtils::get_os_font()); + size_t font_index = m_style_items.size(); + m_style_items.emplace_back(WxFontUtils::get_os_font()); bool loaded = load_font(font_index); } #endif // ALLOW_DEBUG_MODE @@ -1487,37 +1460,149 @@ void GLGizmoEmboss::draw_model_type() } } -void GLGizmoEmboss::draw_rename_style_botton() -{ - bool start_rename = false; - if (draw_button(IconType::rename)) - start_rename = true; - else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("%s", _u8L("Rename actual style.").c_str()); +void GLGizmoEmboss::draw_rename_popup() { + std::string& new_name = m_style_manager.get_font_item().name; + const std::string &old_name = m_style_manager.get_stored_font_item()->name; + std::string text_in_popup = GUI::format(_u8L("Rename style(%1%) for embossing text: "), old_name); + ImGui::Text("%s", text_in_popup.c_str()); + + bool is_unique = true; + for (const auto &item : m_style_manager.get_styles()) { + const FontItem &fi = item.font_item; + if (&fi == &m_style_manager.get_font_item()) + continue; // could be same as original name + if (fi.name == new_name) is_unique = false; + } + bool allow_change = false; + if (new_name.empty()) { + m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_DARK, _u8L("Name can't be empty.")); + }else if (!is_unique) { + m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_DARK, _u8L("Name has to be unique.")); + } else { + ImGui::NewLine(); + allow_change = true; + } + bool store = false; + ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue; + if (ImGui::InputText("##rename style", &new_name, flags) && allow_change) store = true; + + static bool rename_in_volumes = true; + ImGui::Checkbox(_u8L("Rename style in scene volumes.").c_str(), &rename_in_volumes); + + if (m_imgui->button(_L("ok"), ImVec2(0.f, 0.f), allow_change)) store = true; + + ImGui::SameLine(); + if (ImGui::Button(_u8L("cancel").c_str())) { + new_name = old_name; + ImGui::CloseCurrentPopup(); + } + + if (store) { + if (rename_in_volumes) { + // rename style in all objects and volumes + for (ModelObject *mo :wxGetApp().plater()->model().objects) { + for (ModelVolume *mv : mo->volumes) { + if (!mv->text_configuration.has_value()) continue; + std::string& name = mv->text_configuration->font_item.name; + if (name != old_name) continue; + name = new_name; + } + } + } + m_style_manager.rename(new_name); + m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); + ImGui::CloseCurrentPopup(); + } +} + +void GLGizmoEmboss::draw_style_rename_button() +{ + bool can_rename = m_style_manager.exist_stored_style(); std::string title = _u8L("Rename style"); const char * popup_id = title.c_str(); - static FontItem * rename_item; - static std::string new_name; - if (start_rename && !ImGui::IsPopupOpen(popup_id)) { + if (draw_button(IconType::rename, !can_rename)) { + assert(m_style_manager.get_stored_font_item()); ImGui::OpenPopup(popup_id); - rename_item = &m_style_manager.get_font_item(); - new_name = rename_item->name; // initialize with original copy + } + else if (ImGui::IsItemHovered()) { + if (can_rename) ImGui::SetTooltip("%s", _u8L("Rename actual style.").c_str()); + else ImGui::SetTooltip("%s", _u8L("Can't rename temporary style.").c_str()); + } + if (ImGui::BeginPopupModal(popup_id, 0, ImGuiWindowFlags_AlwaysAutoResize)) { + draw_rename_popup(); + ImGui::EndPopup(); + } +} + +void GLGizmoEmboss::draw_style_save_button() +{ + bool is_stored_style = m_style_manager.exist_stored_style(); + const FontItem *stored_fi = nullptr; + if (is_stored_style) + stored_fi = m_style_manager.get_stored_font_item(); + + const FontItem &fi = m_style_manager.get_font_item(); + bool is_changed = (stored_fi)? !(*stored_fi == fi) : true; + + bool is_style_order_changed = m_style_manager.is_style_order_changed(); + bool is_activ_style_changed = m_style_manager.is_activ_style_changed(); + bool can_save = is_changed || is_style_order_changed || is_activ_style_changed; + if (draw_button(IconType::save, !can_save)) { + // save styles to app config + m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); + }else if (ImGui::IsItemHovered()) { + if (!is_stored_style) { + ImGui::SetTooltip("%s", _u8L("Add style to be able save.").c_str()); + } else if (is_changed) { + ImGui::SetTooltip("%s", _u8L("Save changes into style.").c_str()); + } else if (is_style_order_changed) { + ImGui::SetTooltip("%s", _u8L("Save order of styles.").c_str()); + } else if (is_activ_style_changed) { + ImGui::SetTooltip("%s", _u8L("Save style selection.").c_str()); + } else { + ImGui::SetTooltip("%s", _u8L("No changes to save into style").c_str()); + } + } +} + +void GLGizmoEmboss::draw_style_save_as_button() +{ + bool start_save_as = false; + bool only_add_style = !m_style_manager.exist_stored_style(); + // save as new style + ImGui::SameLine(); + if (draw_button(IconType::duplicate)) { + if (!m_style_manager.exist_stored_style()) { + m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); + } else { + start_save_as = true; + } + //m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); + } else if (ImGui::IsItemHovered()) { + if (only_add_style) { + ImGui::SetTooltip("%s", _u8L("Add style to my list.").c_str()); + } else { + ImGui::SetTooltip("%s", _u8L("Add as new named style.").c_str()); + } + } + + std::string title = _u8L("Save as new style"); + const char * popup_id = title.c_str(); + static std::string new_name; + if (start_save_as && !ImGui::IsPopupOpen(popup_id)) { + ImGui::OpenPopup(popup_id); + // initialize with original copy + new_name = m_style_manager.get_font_item().name; } if (ImGui::BeginPopupModal(popup_id, 0, ImGuiWindowFlags_AlwaysAutoResize)) { - const std::string &original_style_name = rename_item->name; - std::string text_in_popup = - GUI::format(_u8L("Rename style(%1%) for embossing text: "), original_style_name); - ImGui::Text("%s", text_in_popup.c_str()); + ImGui::Text("%s", _u8L("New name of style: ").c_str()); bool is_unique = true; - for (const auto &item : m_style_manager.get_styles()) { - const FontItem &fi = item.font_item; - if (&fi == rename_item) - continue; // could be same as original name - if (fi.name == new_name) is_unique = false; - } + for (const auto &item : m_style_manager.get_styles()) + if (item.font_item.name == new_name) is_unique = false; + bool allow_change = false; if (new_name.empty()) { m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_DARK, _u8L("Name can't be empty.")); @@ -1529,19 +1614,44 @@ void GLGizmoEmboss::draw_rename_style_botton() } ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue; - if ((ImGui::InputText("##rename style", &new_name, flags) && allow_change) || + if ((ImGui::InputText("##save as style", &new_name, flags) && allow_change) || m_imgui->button(_L("ok"), ImVec2(0.f, 0.f), allow_change)) { - rename_item->name = new_name; - m_style_manager.get_truncated_name().clear(); + m_style_manager.store_style(new_name); + m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); ImGui::CloseCurrentPopup(); } + ImGui::SameLine(); + if (ImGui::Button(_u8L("cancel").c_str())) + ImGui::CloseCurrentPopup(); ImGui::EndPopup(); } } +void GLGizmoEmboss::draw_style_undo_button() { + const FontItem *stored_fi = nullptr; + bool is_stored = m_style_manager.exist_stored_style(); + if (is_stored) + stored_fi = m_style_manager.get_stored_font_item(); + const FontItem &fi = m_style_manager.get_font_item(); + bool is_changed = (stored_fi)? !(*stored_fi == fi) : true; + bool can_undo = is_stored && is_changed; + if (draw_button(IconType::undo, !can_undo)) { + discard_changes_in_style(); + process(); + } else if (ImGui::IsItemHovered()) { + if (can_undo) + ImGui::SetTooltip("%s", _u8L("Discard style changes.").c_str()); + else if (!is_stored) + ImGui::SetTooltip("%s", _u8L("Not stored yet.").c_str()); + else if (!is_changed) + ImGui::SetTooltip("%s", _u8L("No change to discard.").c_str()); + } +} + void GLGizmoEmboss::draw_delete_style_button() { - bool can_delete = - m_style_manager.get_style_index() != std::numeric_limits::max(); + bool is_stored = m_style_manager.exist_stored_style(); + bool is_last = m_style_manager.get_styles().size() == 1; + bool can_delete = is_stored && !is_last; std::string title = _u8L("Remove style"); const char * popup_id = title.c_str(); @@ -1573,9 +1683,10 @@ void GLGizmoEmboss::draw_delete_style_button() { if (ImGui::IsItemHovered()) { const std::string &style_name = m_style_manager.get_font_item().name; - std::string tooltip = can_delete ? - GUI::format(_L("Delete \"%1%\" style."), style_name) : - GUI::format(_L("Can't delete \"%1%\". It is last style."), style_name) ; + std::string tooltip; + if (can_delete) tooltip = GUI::format(_L("Delete \"%1%\" style."), style_name); + else if (is_last) tooltip = GUI::format(_L("Can't delete \"%1%\". It is last style."), style_name); + else/*if(!is_stored)*/ tooltip = GUI::format(_L("Can't delete temporary style \"%1%\"."), style_name); ImGui::SetTooltip("%s", tooltip.c_str()); } @@ -1584,8 +1695,8 @@ void GLGizmoEmboss::draw_delete_style_button() { std::string text_in_popup = GUI::format(_u8L("Are you sure,\nthat you want permanently and unrecoverable \nremove style \"%1%\"?"), style_name); ImGui::Text("%s", text_in_popup.c_str()); if (ImGui::Button(_u8L("Yes").c_str())) { - m_style_manager.load_font(next_style_index); size_t activ_index = m_style_manager.get_style_index(); + m_style_manager.load_font(next_style_index); m_style_manager.erase(activ_index); m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); ImGui::CloseCurrentPopup(); @@ -1664,7 +1775,11 @@ void GLGizmoEmboss::draw_style_list() { const std::string ¤t_name = actual_font_item.name; trunc_name = ImGuiWrapper::trunc(current_name, max_width); } - ImGui::Text("%s", m_gui_cfg->translations.style.c_str()); + + if (m_style_manager.exist_stored_style()) + ImGui::Text("%s", m_gui_cfg->translations.style.c_str()); + else ImGui::TextColored(ImGuiWrapper::COL_ORANGE_LIGHT, "%s", m_gui_cfg->translations.style.c_str()); + ImGui::SameLine(m_gui_cfg->style_offset); ImGui::SetNextItemWidth(m_gui_cfg->input_width); if (ImGui::BeginCombo("##style_selector", trunc_name.c_str())) { @@ -1720,7 +1835,7 @@ void GLGizmoEmboss::draw_style_list() { } ImGui::SameLine(); - draw_rename_style_botton(); + draw_style_rename_button(); // Is style changed against stored one FontItem &font_item = m_style_manager.get_font_item(); @@ -1733,33 +1848,15 @@ void GLGizmoEmboss::draw_style_list() { bool is_changed = (is_stored) ? !(*stored_fi == font_item) : true; // TODO: check order of font items in list to allowe save actual order - // save button ImGui::SameLine(); - if (draw_button(IconType::save, !is_changed)) { - // save styles to app config - m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); - }else if (ImGui::IsItemHovered()) { - if (is_changed) { - ImGui::SetTooltip("%s", _u8L("Save current settings to selected style").c_str()); - } else { - ImGui::SetTooltip("%s", _u8L("No changes to save into style").c_str()); - } - } + draw_style_save_button(); + + ImGui::SameLine(); + draw_style_save_as_button(); // undo button ImGui::SameLine(); - bool can_undo = is_stored && is_changed; - if (draw_button(IconType::undo, !can_undo)) { - discard_changes_in_style(); - process(); - } else if (ImGui::IsItemHovered()) { - if (can_undo) - ImGui::SetTooltip("%s", _u8L("Reload stored values of selected style").c_str()); - else if (!is_stored) - ImGui::SetTooltip("%s", _u8L("Nothing to reload from").c_str()); - else if (!is_changed) - ImGui::SetTooltip("%s", _u8L("No change to restore from style").c_str()); - } + draw_style_undo_button(); #ifdef ALLOW_REVERT_ALL_STYLES ImGui::SameLine(); @@ -1771,7 +1868,7 @@ void GLGizmoEmboss::draw_style_list() { draw_delete_style_button(); } -bool GLGizmoEmboss::italic_button() +bool GLGizmoEmboss::draw_italic_button() { std::optional &wx_font = m_style_manager.get_wx_font(); const auto& ff = m_style_manager.get_font_file_with_cache(); @@ -1814,7 +1911,7 @@ bool GLGizmoEmboss::italic_button() return false; } -bool GLGizmoEmboss::bold_button() { +bool GLGizmoEmboss::draw_bold_button() { std::optional &wx_font = m_style_manager.get_wx_font(); const auto& ff = m_style_manager.get_font_file_with_cache(); if (!wx_font.has_value() || !ff.has_value()) { @@ -1881,7 +1978,7 @@ bool GLGizmoEmboss::revertible(const std::string &name, Draw draw) { bool changed = exist_change(value, default_value); - if (changed) + if (changed || default_value == nullptr) ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, name); else ImGuiWrapper::text(name); @@ -1976,7 +2073,7 @@ void GLGizmoEmboss::draw_style_edit() { is_font_changed = is_font_face_changed || is_font_style_changed; } - if (is_font_changed) + if (is_font_changed || !exist_stored_style) ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, tr.font); else ImGuiWrapper::text(tr.font); @@ -1985,9 +2082,10 @@ void GLGizmoEmboss::draw_style_edit() { draw_font_list(); ImGui::SameLine(); bool exist_change = false; - exist_change |= italic_button(); + if (draw_italic_button()) exist_change = true; + ImGui::SameLine(); - exist_change |= bold_button(); + if (draw_bold_button()) exist_change = true; if (is_font_changed) { ImGui::SameLine(ImGui::GetStyle().FramePadding.x); @@ -2537,50 +2635,46 @@ bool GLGizmoEmboss::load_configuration(ModelVolume *volume) if (volume == nullptr) return false; if (!volume->text_configuration.has_value()) return false; - TextConfiguration &configuration = *volume->text_configuration; - FontItem & c_font_item = configuration.font_item; + TextConfiguration &tc = *volume->text_configuration; + FontItem &tc_fi = tc.font_item; - auto has_same_name = [&c_font_item](const FontManager::Item &font_item) -> bool { + auto has_same_name = [&tc_fi](const FontManager::Item &font_item) -> bool { const FontItem &fi = font_item.font_item; - return fi.name == c_font_item.name; + return fi.name == tc_fi.name; }; + std::optional wx_font_opt; + if (tc_fi.type == WxFontUtils::get_actual_type()) + wx_font_opt = WxFontUtils::load_wxFont(tc_fi.path); + if (!wx_font_opt.has_value()) { + create_notification_not_valid_font(tc); + // Try create similar wx font + wx_font_opt = WxFontUtils::create_wxFont(tc_fi); + } + const auto& styles = m_style_manager.get_styles(); auto it = std::find_if(styles.begin(), styles.end(), has_same_name); - bool found_font = it != styles.end(); - size_t font_index; - if (!found_font) { - // font is not in list - // add font to list - font_index = styles.size(); - m_style_manager.load_font(c_font_item); - // TODO: Add style only temporary !! - // IMPROVE: Use private member for actual style + if (it == styles.end()) { + // style was not found + if (wx_font_opt.has_value()) + m_style_manager.load_font(tc_fi, *wx_font_opt); } else { - // font is found in list - font_index = it - styles.begin(); - } + size_t style_index = it - styles.begin(); + if (!m_style_manager.load_font(style_index)) { + // can`t load stored style + m_style_manager.erase(style_index); + if (wx_font_opt.has_value()) + m_style_manager.load_font(tc_fi, *wx_font_opt); - m_text = configuration.text; - m_volume = volume; - - if (!m_style_manager.load_font(font_index)) { - // create similar font - auto wx_font = WxFontUtils::create_wxFont(c_font_item, configuration.font_item.prop); - if (wx_font.has_value()) { - // fix not loadable font item - FontItem &fi = m_style_manager.get_font_item(); - FontItem fi_new = WxFontUtils::get_font_item(*wx_font); - fi_new.name = fi.name; // use previous name - fi = fi_new; // rewrite font item - fi.prop = configuration.font_item.prop; - if (!m_style_manager.load_font(fi, *wx_font)) return false; } else { - // can't create similar font use previous - m_style_manager.erase(font_index); + // stored style is loaded, add volume changes + m_style_manager.get_font_item() = tc_fi; + m_style_manager.get_wx_font() = wx_font_opt; } - create_notification_not_valid_font(configuration); } + + m_text = tc.text; + m_volume = volume; return true; } @@ -2759,26 +2853,6 @@ bool GLGizmoEmboss::is_text_object(const ModelVolume *text) { return true; } -//void GLGizmoEmboss::store_font_item_to_app_config() const -//{ -// AppConfig *cfg = wxGetApp().app_config; -// // index of section start from 1 -// const auto &act_item = m_style_manager.get_activ_style(); -// const FontItem &fi = act_item.font_item; -// -// //size_t index = &m_style_manager.get_activ_style() - -// // &m_style_manager.get_fonts().front(); -// // fix index when, not serialized font is in list -// size_t index = 0; -// for (const auto &item : m_style_manager.get_fonts()) { -// if (fi.type != WxFontUtils::get_actual_type()) continue; -// if (&item == &act_item) break; -// ++index; -// } -// -// FontListSerializable::store_font_item(*cfg, fi, index); -//} - std::string GLGizmoEmboss::get_file_name(const std::string &file_path) { size_t pos_last_delimiter = file_path.find_last_of("/\\"); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 4a413229b..cdfd86e42 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -104,11 +104,15 @@ private: void draw_delete_style_button(); void discard_changes_in_style(); void draw_revert_all_styles_button(); - void draw_rename_style_botton(); + void draw_rename_popup(); + void draw_style_rename_button(); + void draw_style_save_button(); + void draw_style_save_as_button(); + void draw_style_undo_button(); void draw_font_list(); void draw_style_edit(); - bool italic_button(); - bool bold_button(); + bool draw_italic_button(); + bool draw_bold_button(); void draw_advanced(); bool select_facename(const wxString& facename); diff --git a/src/slic3r/Utils/FontManager.cpp b/src/slic3r/Utils/FontManager.cpp index a744f4fcf..f30da38d9 100644 --- a/src/slic3r/Utils/FontManager.cpp +++ b/src/slic3r/Utils/FontManager.cpp @@ -17,6 +17,8 @@ using namespace Slic3r::GUI; FontManager::FontManager(const ImWchar *language_glyph_range) : m_imgui_init_glyph_range(language_glyph_range) , m_exist_style_images(false) + , m_change_order(false) + , m_stored_activ_index(std::numeric_limits::max()) , m_temp_style_images(nullptr) {} @@ -33,27 +35,32 @@ void FontManager::init(const AppConfig *cfg, const FontList &default_font_list) if (font_list.empty()) font_list = default_font_list; for (FontItem &fi : font_list) { make_unique_name(fi.name); - m_font_list.push_back({fi}); + m_style_items.push_back({fi}); } std::optional activ_index_opt = (cfg != nullptr) ? FontListSerializable::load_font_index(*cfg) : std::optional{}; - size_t activ_index = activ_index_opt.has_value() ? *activ_index_opt : 0; - if (activ_index >= m_font_list.size()) activ_index = 0; + + size_t activ_index = 0; + if (activ_index_opt.has_value()) { + m_stored_activ_index = *activ_index_opt; + activ_index = *activ_index_opt; + } + if (activ_index >= m_style_items.size()) activ_index = 0; // find valid font item if (!load_font(activ_index)) { - m_font_list.erase(m_font_list.begin() + activ_index); + m_style_items.erase(m_style_items.begin() + activ_index); activ_index = 0; - while (m_font_list.empty() || !load_font(activ_index)) - m_font_list.erase(m_font_list.begin()); + while (m_style_items.empty() || !load_font(activ_index)) + m_style_items.erase(m_style_items.begin()); // no one style from config is loadable - if (m_font_list.empty()) { + if (m_style_items.empty()) { // set up default font list for (FontItem fi : default_font_list) { make_unique_name(fi.name); - m_font_list.push_back({std::move(fi)}); + m_style_items.push_back({std::move(fi)}); } // try to load first default font bool loaded = load_font(activ_index); @@ -68,28 +75,40 @@ bool FontManager::store_font_list_to_app_config(AppConfig *cfg) if (cfg == nullptr) return false; if (exist_stored_style()) { // update stored item - m_font_list[m_style_cache.font_index].font_item = m_style_cache.font_item; + m_style_items[m_style_cache.font_index].font_item = m_style_cache.font_item; } else { // add new into stored list FontItem &fi = m_style_cache.font_item; make_unique_name(fi.name); - m_style_cache.font_index = m_font_list.size(); - m_font_list.push_back({fi}); + m_style_cache.font_index = m_style_items.size(); + m_style_items.push_back({fi}); } FontListSerializable::store_font_index(*cfg, m_style_cache.font_index); + m_stored_activ_index = m_style_cache.font_index; FontList font_list; - font_list.reserve(m_font_list.size()); - for (const Item &item : m_font_list) font_list.push_back(item.font_item); + font_list.reserve(m_style_items.size()); + for (const Item &item : m_style_items) font_list.push_back(item.font_item); FontListSerializable::store_font_list(*cfg, font_list); + m_change_order = false; return true; } -void FontManager::swap(size_t i1, size_t i2) { - if (i1 >= m_font_list.size() || - i2 >= m_font_list.size()) return; - std::swap(m_font_list[i1], m_font_list[i2]); +void FontManager::store_style(const std::string &name) { + FontItem& fi = m_style_cache.font_item; + fi.name = name; + make_unique_name(fi.name); + m_style_cache.font_index = m_style_items.size(); + m_style_cache.stored_wx_font = m_style_cache.wx_font; + m_style_cache.truncated_name.clear(); + m_style_items.push_back({fi}); +} +void FontManager::swap(size_t i1, size_t i2) { + if (i1 >= m_style_items.size() || + i2 >= m_style_items.size()) return; + std::swap(m_style_items[i1], m_style_items[i2]); + m_change_order = true; // fix selected index if (!exist_stored_style()) return; if (m_style_cache.font_index == i1) { @@ -99,15 +118,33 @@ void FontManager::swap(size_t i1, size_t i2) { } } +bool FontManager::is_style_order_changed() const { return m_change_order; } +bool FontManager::is_activ_style_changed() const { + if (m_stored_activ_index == std::numeric_limits::max()) + return true; + return m_style_cache.font_index != m_stored_activ_index; +}; void FontManager::erase(size_t index) { - if (index >= m_font_list.size()) return; + if (index >= m_style_items.size()) return; // fix selected index - if (exist_stored_style() && - index < m_style_cache.font_index) - --m_style_cache.font_index; + if (exist_stored_style()) { + size_t &i = m_style_cache.font_index; + if (index < i) --i; + else if (index == i) i = std::numeric_limits::max(); + } - m_font_list.erase(m_font_list.begin() + index); + m_style_items.erase(m_style_items.begin() + index); +} + +void FontManager::rename(const std::string& name) { + m_style_cache.font_item.name = name; + m_style_cache.truncated_name.clear(); + if (exist_stored_style()) { + Item &it = m_style_items[m_style_cache.font_index]; + it.font_item.name = name; + it.truncated_name.clear(); + } } bool FontManager::wx_font_changed(std::unique_ptr font_file) @@ -131,8 +168,8 @@ bool FontManager::wx_font_changed(std::unique_ptr font_file) bool FontManager::load_font(size_t font_index) { - if (font_index >= m_font_list.size()) return false; - if (!load_font(m_font_list[font_index].font_item)) return false; + if (font_index >= m_style_items.size()) return false; + if (!load_font(m_style_items[font_index].font_item)) return false; m_style_cache.font_index = font_index; m_style_cache.stored_wx_font = m_style_cache.wx_font; return true; @@ -163,24 +200,25 @@ bool FontManager::load_font(const FontItem &fi, const wxFont &font) m_style_cache.font_item = fi; // copy m_style_cache.font_index = std::numeric_limits::max(); m_style_cache.stored_wx_font = {}; + m_style_cache.truncated_name.clear(); return true; } bool FontManager::is_activ_font() { return m_style_cache.font_file.has_value(); } bool FontManager::load_first_valid_font() { - while (!m_font_list.empty()) { + while (!m_style_items.empty()) { if (load_font(0)) return true; // can't load so erase it from list - m_font_list.erase(m_font_list.begin()); + m_style_items.erase(m_style_items.begin()); } return false; } const FontItem* FontManager::get_stored_font_item() const { - if (m_style_cache.font_index >= m_font_list.size()) return nullptr; - return &m_font_list[m_style_cache.font_index].font_item; + if (m_style_cache.font_index >= m_style_items.size()) return nullptr; + return &m_style_items[m_style_cache.font_index].font_item; } const std::optional &FontManager::get_stored_wx_font() const { return m_style_cache.stored_wx_font; } @@ -226,7 +264,7 @@ ImFont *FontManager::get_imgui_font() return font; } -const std::vector &FontManager::get_styles() const{ return m_font_list; } +const std::vector &FontManager::get_styles() const{ return m_style_items; } ImFont* FontManager::extend_imgui_font_range(size_t index, const std::string& text) { @@ -238,7 +276,7 @@ ImFont* FontManager::extend_imgui_font_range(size_t index, const std::string& te void FontManager::make_unique_name(std::string &name) { auto is_unique = [&](const std::string &name) -> bool { - for (const Item &it : m_font_list) + for (const Item &it : m_style_items) if (it.font_item.name == name) return false; return true; }; @@ -261,7 +299,7 @@ void FontManager::make_unique_name(std::string &name) } void FontManager::init_trunc_names(float max_width) { - for (auto &s : m_font_list) + for (auto &s : m_style_items) if (s.truncated_name.empty()) s.truncated_name = ImGuiWrapper::trunc(s.font_item.name, max_width); } @@ -290,7 +328,7 @@ void FontManager::init_style_images(const Vec2i &max_size, StyleImagesData::Item &style = m_temp_style_images->styles[index]; // find style in font list and copy to it - for (auto &it : m_font_list) { + for (auto &it : m_style_items) { if (it.font_item.name != style.text || !(it.font_item.prop == style.prop)) continue; @@ -309,8 +347,8 @@ void FontManager::init_style_images(const Vec2i &max_size, // create job for init images m_temp_style_images = std::make_shared(); StyleImagesData::Items styles; - styles.reserve(m_font_list.size()); - for (const Item &item : m_font_list) { + styles.reserve(m_style_items.size()); + for (const Item &item : m_style_items) { const FontItem &fi = item.font_item; std::optional wx_font_opt = WxFontUtils::load_wxFont(fi.path); if (!wx_font_opt.has_value()) continue; @@ -334,7 +372,7 @@ void FontManager::free_style_images() { GLuint tex_id = 0; - for (Item &it : m_font_list) { + for (Item &it : m_style_items) { if (tex_id == 0 && it.image.has_value()) tex_id = (GLuint)(intptr_t) it.image->texture_id; it.image.reset(); diff --git a/src/slic3r/Utils/FontManager.hpp b/src/slic3r/Utils/FontManager.hpp index 7aeee90e1..c83836ea7 100644 --- a/src/slic3r/Utils/FontManager.hpp +++ b/src/slic3r/Utils/FontManager.hpp @@ -42,20 +42,44 @@ public: bool store_font_list_to_app_config(AppConfig *cfg); /// - /// Change order of style item in m_font_list. + /// Append actual style to style list and store + /// + /// New name for style + void store_style(const std::string& name); + + /// + /// Change order of style item in m_style_items. /// Fix selected font index when (i1 || i2) == m_font_selected /// - /// First index to m_font_list - /// Second index to m_font_list + /// First index to m_style_items + /// Second index to m_style_items void swap(size_t i1, size_t i2); /// - /// Remove style from m_font_list. + /// Track using of swap between saves + /// + /// True when swap was call after save otherwise false + bool is_style_order_changed() const; + + /// + /// Check that actual selected style is same as activ style stored in "PrusaSlicer.ini" + /// + /// True when actual selection is not stored otherwise False + bool is_activ_style_changed() const; + + /// + /// Remove style from m_style_items. /// Fix selected font index when index is under m_font_selected /// /// Index of style to be removed void erase(size_t index); + /// + /// Rename actual selected font item + /// + /// New name + void rename(const std::string &name); + /// /// Actual wx font was changed /// Clear caches @@ -67,7 +91,7 @@ public: /// Change active font /// When font not loaded roll back activ font /// - /// New font index(from m_font_list range) + /// New font index(from m_style_items range) /// True on succes. False on fail load font bool load_font(size_t font_index); // load font style not stored in list @@ -205,7 +229,7 @@ private: // cache for stored wx font to not create every frame std::optional stored_wx_font; - // index into m_font_list + // index into m_style_items size_t font_index = std::numeric_limits::max(); } m_style_cache; @@ -218,7 +242,9 @@ private: void make_unique_name(std::string &name); // Privat member - std::vector m_font_list; + std::vector m_style_items; + bool m_change_order = false; + size_t m_stored_activ_index; /// /// Keep data needed to create Font Style Images in Job diff --git a/src/slic3r/Utils/WxFontUtils.cpp b/src/slic3r/Utils/WxFontUtils.cpp index 975501319..16ca79d19 100644 --- a/src/slic3r/Utils/WxFontUtils.cpp +++ b/src/slic3r/Utils/WxFontUtils.cpp @@ -194,9 +194,9 @@ const TypeToWeight WxFontUtils::type_to_weight = (wxFONTWEIGHT_HEAVY, "heavy") (wxFONTWEIGHT_EXTRAHEAVY, "extraHeavy"); -std::optional WxFontUtils::create_wxFont(const FontItem &fi, - const FontProp &fp) +std::optional WxFontUtils::create_wxFont(const FontItem &fi) { + const FontProp &fp = fi.prop; double point_size = static_cast(fp.size_in_mm); wxFontInfo info(point_size); if (fp.family.has_value()) { diff --git a/src/slic3r/Utils/WxFontUtils.hpp b/src/slic3r/Utils/WxFontUtils.hpp index d06d10c07..acccb9d1c 100644 --- a/src/slic3r/Utils/WxFontUtils.hpp +++ b/src/slic3r/Utils/WxFontUtils.hpp @@ -36,8 +36,7 @@ public: static std::optional load_wxFont(const std::string &font_descriptor); // Try to create similar font, loaded from 3mf from different Computer - static std::optional create_wxFont(const FontItem &fi, - const FontProp &fp); + static std::optional create_wxFont(const FontItem &fi); // update font property by wxFont static void update_property(FontProp &font_prop, const wxFont &font);