diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 2ace3d4ba2..8d4aa9e18c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -351,7 +351,7 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event) // with Mesa driver OR on Linux if (!m_temp_transformation.has_value()) return false; - // TODO: Disable apply common transformation after draggig + // TODO: Disable applying of common transformation after draggig // Call after is used for apply transformation after common dragging to rewrite it Transform3d volume_trmat = gl_volume->get_instance_transformation().get_matrix().inverse() * @@ -724,8 +724,7 @@ void GLGizmoEmboss::initialize() init_icons(); // initialize text styles - const AppConfig *app_cfg = wxGetApp().app_config; - m_style_manager.init(app_cfg, create_default_styles()); + m_style_manager.init(wxGetApp().app_config, create_default_styles()); set_default_text(); } @@ -1512,7 +1511,7 @@ void GLGizmoEmboss::draw_style_rename_popup() { } m_style_manager.rename(new_name); - m_style_manager.store_styles_to_app_config(wxGetApp().app_config); + m_style_manager.store_styles_to_app_config(); ImGui::CloseCurrentPopup(); } } @@ -1540,16 +1539,17 @@ void GLGizmoEmboss::draw_style_save_button(bool is_modified) { if (draw_button(IconType::save, !is_modified)) { // save styles to app config - m_style_manager.store_styles_to_app_config(wxGetApp().app_config); + m_style_manager.store_styles_to_app_config(); }else if (ImGui::IsItemHovered()) { + std::string tooltip; if (!m_style_manager.exist_stored_style()) { - ImGui::SetTooltip("%s", _u8L("First Add style to list.").c_str()); + tooltip = _u8L("First Add style to list."); } else if (is_modified) { - ImGui::SetTooltip("%s", _u8L("Save changes into style.").c_str()); + tooltip = GUI::format(_L("Save %1% style"), m_style_manager.get_style().name); } else { - ImGui::SetTooltip("%s", _u8L("No changes to save into style").c_str()); + tooltip = _u8L("No changes to save."); } - ImGui::SetTooltip( + ImGui::SetTooltip("%s", tooltip.c_str()); } } @@ -1589,8 +1589,8 @@ void GLGizmoEmboss::draw_style_save_as_popup() { } if (save_style && allow_change) { - m_style_manager.store_style(new_name); - m_style_manager.store_styles_to_app_config(wxGetApp().app_config); + m_style_manager.add_style(new_name); + m_style_manager.store_styles_to_app_config(); ImGui::CloseCurrentPopup(); } } @@ -1692,52 +1692,6 @@ void GLGizmoEmboss::draw_delete_style_button() { } } -//void GLGizmoEmboss::discard_changes_in_style() -//{ -// if (!m_style_manager.exist_stored_style()) return; -// -// EmbossStyle &emboss_style = m_style_manager.get_style(); -// const EmbossStyle* stored_style = m_style_manager.get_stored_style(); -// assert(stored_style != nullptr); -// -// // is rotation changed -// auto &angle = emboss_style.prop.angle; -// const auto &angle_ = stored_style->prop.angle; -// // TODO: compare with approx -// if (angle.has_value() != angle_.has_value() || -// (angle.has_value() && !is_approx(*angle, *angle_))) { -// auto &tc = m_volume->text_configuration; -// if (m_volume != nullptr && tc.has_value()) { -// // change actual text configuration -// tc->style.prop.angle = angle_; -// float act_angle = angle_.has_value() ? *angle_ : .0f; -// float prev_angle = angle.has_value() ? *angle : .0f; -// do_rotate(act_angle - prev_angle); -// } -// } -// -// // is distance changed -// auto &distance = emboss_style.prop.distance; -// const auto &distance_ = stored_style->prop.distance; -// if (distance.has_value() != distance_.has_value() || -// (distance.has_value() && !is_approx(*distance, *distance_))) { -// auto &tc = m_volume->text_configuration; -// if (m_volume != nullptr && tc.has_value()) { -// tc->style.prop.distance = distance_; -// float act_distance = distance_.has_value() ? *distance_ : .0f; -// float prev_distance = distance.has_value() ? *distance : .0f; -// do_translate(Vec3d::UnitZ() * (act_distance - prev_distance)); -// } -// } -// -// if (emboss_style.path != stored_style->path) { -// // NOTE: load font file again -// m_style_manager.load_style(m_style_manager.get_style_index()); -// //m_style_manager.get_wx_font() = WxFontUtils::load_wxFont(emboss_style.path); -// //m_style_manager.wx_font_changed(); -// } -//} - void GLGizmoEmboss::draw_revert_all_styles_button() { if (draw_button(IconType::revert_all)) { m_style_manager = EmbossStyleManager(m_imgui->get_glyph_ranges()); @@ -1748,6 +1702,29 @@ void GLGizmoEmboss::draw_revert_all_styles_button() { ImGui::SetTooltip("%s", _u8L("Revert all styles").c_str()); } +void GLGizmoEmboss::fix_transformation(const FontProp &from, + const FontProp &to) +{ + // fix Z rotation when exists difference in styles + const std::optional &f_angle_opt = from.angle; + const std::optional &t_angle_opt = to.angle; + if (!is_approx(f_angle_opt, t_angle_opt)) { + // fix rotation + float f_angle = f_angle_opt.has_value() ? *f_angle_opt : .0f; + float t_angle = t_angle_opt.has_value() ? *t_angle_opt : .0f; + do_rotate(t_angle - f_angle); + } + + // fix distance (Z move) when exists difference in styles + const std::optional &f_move_opt = from.distance; + const std::optional &t_move_opt = to.distance; + if (!is_approx(f_move_opt, t_move_opt)) { + float f_move = f_move_opt.has_value() ? *f_move_opt : .0f; + float t_move = t_move_opt.has_value() ? *t_move_opt : .0f; + do_translate(Vec3d::UnitZ() * (t_move - f_move)); + } +} + void GLGizmoEmboss::draw_style_list() { if (!m_style_manager.is_activ_font()) return; @@ -1783,26 +1760,26 @@ void GLGizmoEmboss::draw_style_list() { std::optional> swap_indexes; const std::vector &styles = m_style_manager.get_styles(); for (const auto &item : styles) { - size_t index = &item - &styles.front(); - const EmbossStyle &es = item.style; - const std::string &actual_style_name = es.name; + size_t index = &item - &styles.front(); + const EmbossStyle &style = item.style; + const std::string &actual_style_name = style.name; ImGui::PushID(actual_style_name.c_str()); - bool is_selected = (&es == &actual_style); + bool is_selected = (index == m_style_manager.get_style_index()); ImVec2 select_size(0,m_gui_cfg->max_style_image_size.y()); // 0,0 --> calculate in draw const std::optional img = item.image; // allow click delete button ImGuiSelectableFlags_ flags = ImGuiSelectableFlags_AllowItemOverlap; if (ImGui::Selectable(item.truncated_name.c_str(), is_selected, flags, select_size)) { + fix_transformation(actual_style.prop, style.prop); if (m_style_manager.load_style(index)) { - // TODO: - // fix volume transformation after change style --> - // rotation or z-move - // HELP: discard_changes_in_style() - // void style_changed(const FontProp &prev, const FontProp &act); process(); } else { - // TODO: inform user that can't load and erase style + wxString title = _L("Not valid style."); + wxString message = GUI::format_wxstr(_L("Style '%1%' can't be used and will be removed from list."), style.name); + MessageDialog not_loaded_style_message(nullptr, message, title, wxOK); + not_loaded_style_message.ShowModal(); + m_style_manager.erase(index); } } else if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", actual_style_name.c_str()); @@ -2045,17 +2022,10 @@ void GLGizmoEmboss::draw_style_edit() { assert(wx_font_opt.has_value()); if (!wx_font_opt.has_value()) { - // TODO: should not be there - // when actual font not loaded try to load - if (style.type == WxFontUtils::get_actual_type()) { - std::optional new_wx_font = WxFontUtils::load_wxFont(style.path); - - } - ImGui::TextColored(ImGuiWrapper::COL_ORANGE_DARK, "%s", _u8L("Font is not loaded properly. ")); + ImGui::TextColored(ImGuiWrapper::COL_ORANGE_DARK, "%s", _u8L("WxFont is not loaded properly.")); return; } - bool exist_stored_style = m_style_manager.exist_stored_style(); bool is_font_changed = false; if (exist_stored_style && wx_font_opt.has_value()) { @@ -2635,7 +2605,7 @@ EmbossDataBase GLGizmoEmboss::create_emboss_data_base() { // volume must store valid path assert(m_style_manager.get_wx_font().has_value()); assert(es.path.compare(WxFontUtils::store_wxFont(*m_style_manager.get_wx_font())) == 0); - //es.path = WxFontUtils::store_wxFont(*m_style_manager.get_wx_font()); + //style.path = WxFontUtils::store_wxFont(*m_style_manager.get_wx_font()); return TextConfiguration{es, m_text}; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 2de72d7999..79fa42fbac 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -99,6 +99,7 @@ private: void draw_window(); void draw_text_input(); void draw_model_type(); + void fix_transformation(const FontProp &from, const FontProp &to); void draw_style_list(); void draw_delete_style_button(); void draw_revert_all_styles_button(); diff --git a/src/slic3r/Utils/EmbossStyleManager.cpp b/src/slic3r/Utils/EmbossStyleManager.cpp index 5dc3af22e4..a5f3c363bf 100644 --- a/src/slic3r/Utils/EmbossStyleManager.cpp +++ b/src/slic3r/Utils/EmbossStyleManager.cpp @@ -17,20 +17,22 @@ using namespace Slic3r::GUI; EmbossStyleManager::EmbossStyleManager(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) + , m_app_config(nullptr) + , m_last_style_index(std::numeric_limits::max()) {} EmbossStyleManager::~EmbossStyleManager() { clear_imgui_font(); free_style_images(); + store_styles_to_app_config(false); } -void EmbossStyleManager::init(const AppConfig *cfg, const EmbossStyles &default_styles) +void EmbossStyleManager::init(AppConfig *app_config, const EmbossStyles &default_styles) { - EmbossStyles styles = (cfg != nullptr) ? - EmbossStylesSerializable::load_styles(*cfg) : + m_app_config = app_config; + EmbossStyles styles = (app_config != nullptr) ? + EmbossStylesSerializable::load_styles(*app_config) : default_styles; if (styles.empty()) styles = default_styles; for (EmbossStyle &style : styles) { @@ -38,15 +40,12 @@ void EmbossStyleManager::init(const AppConfig *cfg, const EmbossStyles &default_ m_style_items.push_back({style}); } - std::optional activ_index_opt = (cfg != nullptr) ? - EmbossStylesSerializable::load_style_index(*cfg) : + std::optional activ_index_opt = (app_config != nullptr) ? + EmbossStylesSerializable::load_style_index(*app_config) : std::optional{}; 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_opt.has_value()) activ_index = *activ_index_opt; if (activ_index >= m_style_items.size()) activ_index = 0; // find valid font item @@ -69,33 +68,33 @@ void EmbossStyleManager::init(const AppConfig *cfg, const EmbossStyles &default_ } } -bool EmbossStyleManager::store_styles_to_app_config(AppConfig *cfg) +bool EmbossStyleManager::store_styles_to_app_config(bool use_modification) { - assert(cfg != nullptr); - if (cfg == nullptr) return false; - if (exist_stored_style()) { - // update stored item - m_style_items[m_style_cache.style_index].style = m_style_cache.style; - } else { - // add new into stored list - EmbossStyle &style = m_style_cache.style; - make_unique_name(style.name); - m_style_cache.style_index = m_style_items.size(); - m_style_items.push_back({style}); - m_style_cache.stored_wx_font = m_style_cache.wx_font; + assert(m_app_config != nullptr); + if (m_app_config == nullptr) return false; + if (use_modification) { + if (exist_stored_style()) { + // update stored item + m_style_items[m_style_cache.style_index].style = m_style_cache.style; + } else { + // add new into stored list + EmbossStyle &style = m_style_cache.style; + make_unique_name(style.name); + m_style_cache.style_index = m_style_items.size(); + m_style_items.push_back({style}); + m_style_cache.stored_wx_font = m_style_cache.wx_font; + } } - EmbossStylesSerializable::store_style_index(*cfg, m_style_cache.style_index); - m_stored_activ_index = m_style_cache.style_index; - EmbossStyles font_list; - font_list.reserve(m_style_items.size()); - for (const Item &item : m_style_items) font_list.push_back(item.style); - EmbossStylesSerializable::store_styles(*cfg, font_list); - m_change_order = false; + EmbossStylesSerializable::store_style_index(*m_app_config, m_style_cache.style_index); + EmbossStyles styles; + styles.reserve(m_style_items.size()); + for (const Item &item : m_style_items) styles.push_back(item.style); + EmbossStylesSerializable::store_styles(*m_app_config, styles); return true; } -void EmbossStyleManager::store_style(const std::string &name) { +void EmbossStyleManager::add_style(const std::string &name) { EmbossStyle& style = m_style_cache.style; style.name = name; make_unique_name(style.name); @@ -109,7 +108,6 @@ void EmbossStyleManager::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.style_index == i1) { @@ -120,27 +118,13 @@ void EmbossStyleManager::swap(size_t i1, size_t i2) { } void EmbossStyleManager::discard_style_changes() { - if (exist_stored_style()) { - if (m_style_cache.style == m_style_items[m_stored_activ_index].style && - m_style_cache.wx_font == m_style_cache.stored_wx_font) - return; // already loaded - if (load_style(m_style_cache.style_index)) - return; // correct reload style - } + if (exist_stored_style() && load_style(m_style_cache.style_index)) + return; // correct reload style - if (load_style(m_stored_activ_index)) - return; // correct reload last activ font - // try to save situation by load some font load_first_valid_font(); } -bool EmbossStyleManager::is_style_order_changed() const { return m_change_order; } -bool EmbossStyleManager::is_activ_style_changed() const { - if (m_stored_activ_index == std::numeric_limits::max()) - return true; - return m_style_cache.style_index != m_stored_activ_index; -}; void EmbossStyleManager::erase(size_t index) { if (index >= m_style_items.size()) return; @@ -170,6 +154,7 @@ bool EmbossStyleManager::load_style(size_t style_index) if (!load_style(m_style_items[style_index].style)) return false; m_style_cache.style_index = style_index; m_style_cache.stored_wx_font = m_style_cache.wx_font; // copy + m_last_style_index = style_index; return true; } @@ -219,20 +204,6 @@ const EmbossStyle* EmbossStyleManager::get_stored_style() const return &m_style_items[m_style_cache.style_index].style; } -const std::optional &EmbossStyleManager::get_stored_wx_font() const { return m_style_cache.stored_wx_font; } - -const EmbossStyle &EmbossStyleManager::get_style() const { return m_style_cache.style; } - EmbossStyle &EmbossStyleManager::get_style() { return m_style_cache.style; } -const FontProp &EmbossStyleManager::get_font_prop() const { return get_style().prop; } - FontProp &EmbossStyleManager::get_font_prop() { return get_style().prop; } -const std::optional &EmbossStyleManager::get_wx_font() const { return m_style_cache.wx_font; } - -bool EmbossStyleManager::exist_stored_style() const { return m_style_cache.style_index != std::numeric_limits::max(); } -size_t EmbossStyleManager::get_style_index() const { return m_style_cache.style_index; } -Emboss::FontFileWithCache &EmbossStyleManager::get_font_file_with_cache() { return m_style_cache.font_file; } -std::string &EmbossStyleManager::get_truncated_name() { return m_style_cache.truncated_name; } -const ImFontAtlas &EmbossStyleManager::get_atlas() const { return m_style_cache.atlas; } - void EmbossStyleManager::clear_glyphs_cache() { Emboss::FontFileWithCache &ff = m_style_cache.font_file; diff --git a/src/slic3r/Utils/EmbossStyleManager.hpp b/src/slic3r/Utils/EmbossStyleManager.hpp index 950657b795..147ed87aea 100644 --- a/src/slic3r/Utils/EmbossStyleManager.hpp +++ b/src/slic3r/Utils/EmbossStyleManager.hpp @@ -13,10 +13,10 @@ class wxFont; namespace Slic3r::GUI { /// -/// GUI list of loaded fonts -/// Keep pointer to ImGui font pointers -/// Keep file data of TTF files -/// Cache wx font objects +/// Manage Emboss text styles +/// Cache actual state of style +/// + imgui font +/// + wx font /// class EmbossStyleManager { @@ -24,28 +24,35 @@ class EmbossStyleManager public: EmbossStyleManager(const ImWchar *language_glyph_range); + + /// + /// Release imgui font and style images from GPU + /// Store order and last activ font index + /// ~EmbossStyleManager(); /// /// Load font style list from config /// Also select actual activ font /// - /// Application configuration loaded from file "PrusaSlicer.ini" + /// Application configuration loaded from file "PrusaSlicer.ini" + /// + cfg is stored to privat variable /// Used when list is not loadable from config - void init(const AppConfig *cfg, const EmbossStyles &default_styles); + void init(AppConfig *app_config, const EmbossStyles &default_styles); /// /// Write font list into AppConfig /// - /// Stor into this configuration /// Configuration - bool store_styles_to_app_config(AppConfig *cfg); + /// Flag that store should use actual modification + /// True on succes otherwise False. + bool store_styles_to_app_config(bool use_modification = true); /// /// Append actual style to style list /// /// New name for style - void store_style(const std::string& name); + void add_style(const std::string& name); /// /// Change order of style item in m_style_items. @@ -57,22 +64,10 @@ public: /// /// Discard changes in activ style - /// When no activ style use last used + /// When no activ style use last used OR first loadable /// void discard_style_changes(); - /// - /// 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 @@ -104,38 +99,23 @@ public: // remove cached imgui font for actual selected font void clear_imgui_font(); - // getter on stored EmbossStyle + // getters for private data const EmbossStyle *get_stored_style() const; - // getter on stored wxFont - const std::optional &get_stored_wx_font() const; - - // getter on active font item for access to font property - const EmbossStyle &get_style() const; - EmbossStyle &get_style(); - - // getter on active font property - const FontProp &get_font_prop() const; - FontProp &get_font_prop(); - - const ImFontAtlas& get_atlas() const; - - // getter on activ wx font - const std::optional &get_wx_font() const; + const EmbossStyle &get_style() const { return m_style_cache.style; } + EmbossStyle &get_style() { return m_style_cache.style; } + size_t get_style_index() const { return m_style_cache.style_index; } + std::string &get_truncated_name() { return m_style_cache.truncated_name; } + const ImFontAtlas &get_atlas() const { return m_style_cache.atlas; } + const FontProp &get_font_prop() const { return get_style().prop; } + FontProp &get_font_prop() { return get_style().prop; } + const std::optional &get_wx_font() const { return m_style_cache.wx_font; } + const std::optional &get_stored_wx_font() const { return m_style_cache.stored_wx_font; } + Emboss::FontFileWithCache &get_font_file_with_cache() { return m_style_cache.font_file; } // True when activ style has same name as some of stored style - bool exist_stored_style() const; - - size_t get_style_index() const; - - // getter on font file with cache - Emboss::FontFileWithCache &get_font_file_with_cache(); - - // Getter for cached trucated name for style list selector - std::string &get_truncated_name(); + bool exist_stored_style() const { return m_style_cache.style_index != std::numeric_limits::max(); } - // setter of wx font for actual selection - /// /// Setter on wx_font when changed /// @@ -259,8 +239,8 @@ private: // Privat member std::vector m_style_items; - bool m_change_order; - size_t m_stored_activ_index; + AppConfig *m_app_config; + size_t m_last_style_index; /// /// Keep data needed to create Font Style Images in Job @@ -290,7 +270,7 @@ private: // vector of inputs StyleImagesData::Items styles; // job output - std::vector images; + std::vector images; }; // place to store result in main thread in Finalize