Fix rename and save as style text

This commit is contained in:
Filip Sykala - NTB T15p 2022-07-29 18:21:40 +02:00
parent f7eef00abb
commit 569ba0600c
6 changed files with 335 additions and 194 deletions

View File

@ -614,7 +614,7 @@ void GLGizmoEmboss::on_set_state()
// to reload fonts from system, when install new one // to reload fonts from system, when install new one
wxFontEnumerator::InvalidateCache(); wxFontEnumerator::InvalidateCache();
// Try(when exist) set configuration by volume // Try(when exist) set text configuration by volume
load_configuration(get_selected_volume()); load_configuration(get_selected_volume());
// change position of just opened emboss window // change position of just opened emboss window
@ -971,41 +971,14 @@ void GLGizmoEmboss::close()
mng.open_gizmo(GLGizmosManager::Emboss); 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() void GLGizmoEmboss::draw_window()
{ {
#ifdef ALLOW_DEBUG_MODE #ifdef ALLOW_DEBUG_MODE
if (ImGui::Button("re-process")) process(); if (ImGui::Button("re-process")) process();
if (ImGui::Button("add svg")) choose_svg_file(); if (ImGui::Button("add svg")) choose_svg_file();
if (ImGui::Button("use system font")) { if (ImGui::Button("use system font")) {
size_t font_index = m_font_list.size(); size_t font_index = m_style_items.size();
m_font_list.emplace_back(WxFontUtils::get_os_font()); m_style_items.emplace_back(WxFontUtils::get_os_font());
bool loaded = load_font(font_index); bool loaded = load_font(font_index);
} }
#endif // ALLOW_DEBUG_MODE #endif // ALLOW_DEBUG_MODE
@ -1487,37 +1460,149 @@ void GLGizmoEmboss::draw_model_type()
} }
} }
void GLGizmoEmboss::draw_rename_style_botton() void GLGizmoEmboss::draw_rename_popup() {
{ std::string& new_name = m_style_manager.get_font_item().name;
bool start_rename = false; const std::string &old_name = m_style_manager.get_stored_font_item()->name;
if (draw_button(IconType::rename)) std::string text_in_popup = GUI::format(_u8L("Rename style(%1%) for embossing text: "), old_name);
start_rename = true; ImGui::Text("%s", text_in_popup.c_str());
else if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Rename actual style.").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"); std::string title = _u8L("Rename style");
const char * popup_id = title.c_str(); const char * popup_id = title.c_str();
static FontItem * rename_item; if (draw_button(IconType::rename, !can_rename)) {
static std::string new_name; assert(m_style_manager.get_stored_font_item());
if (start_rename && !ImGui::IsPopupOpen(popup_id)) {
ImGui::OpenPopup(popup_id); 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)) { if (ImGui::BeginPopupModal(popup_id, 0, ImGuiWindowFlags_AlwaysAutoResize)) {
const std::string &original_style_name = rename_item->name; ImGui::Text("%s", _u8L("New name of style: ").c_str());
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());
bool is_unique = true; bool is_unique = true;
for (const auto &item : m_style_manager.get_styles()) { for (const auto &item : m_style_manager.get_styles())
const FontItem &fi = item.font_item; if (item.font_item.name == new_name) is_unique = false;
if (&fi == rename_item)
continue; // could be same as original name
if (fi.name == new_name) is_unique = false;
}
bool allow_change = false; bool allow_change = false;
if (new_name.empty()) { if (new_name.empty()) {
m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_DARK, _u8L("Name can't be 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; 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)) { m_imgui->button(_L("ok"), ImVec2(0.f, 0.f), allow_change)) {
rename_item->name = new_name; m_style_manager.store_style(new_name);
m_style_manager.get_truncated_name().clear(); m_style_manager.store_font_list_to_app_config(wxGetApp().app_config);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::SameLine();
if (ImGui::Button(_u8L("cancel").c_str()))
ImGui::CloseCurrentPopup();
ImGui::EndPopup(); 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() { void GLGizmoEmboss::draw_delete_style_button() {
bool can_delete = bool is_stored = m_style_manager.exist_stored_style();
m_style_manager.get_style_index() != std::numeric_limits<size_t>::max(); bool is_last = m_style_manager.get_styles().size() == 1;
bool can_delete = is_stored && !is_last;
std::string title = _u8L("Remove style"); std::string title = _u8L("Remove style");
const char * popup_id = title.c_str(); const char * popup_id = title.c_str();
@ -1573,9 +1683,10 @@ void GLGizmoEmboss::draw_delete_style_button() {
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {
const std::string &style_name = m_style_manager.get_font_item().name; const std::string &style_name = m_style_manager.get_font_item().name;
std::string tooltip = can_delete ? std::string tooltip;
GUI::format(_L("Delete \"%1%\" style."), style_name) : if (can_delete) tooltip = GUI::format(_L("Delete \"%1%\" style."), style_name);
GUI::format(_L("Can't delete \"%1%\". It is last 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()); 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); 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()); ImGui::Text("%s", text_in_popup.c_str());
if (ImGui::Button(_u8L("Yes").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(); 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.erase(activ_index);
m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); m_style_manager.store_font_list_to_app_config(wxGetApp().app_config);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
@ -1664,7 +1775,11 @@ void GLGizmoEmboss::draw_style_list() {
const std::string &current_name = actual_font_item.name; const std::string &current_name = actual_font_item.name;
trunc_name = ImGuiWrapper::trunc(current_name, max_width); 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::SameLine(m_gui_cfg->style_offset);
ImGui::SetNextItemWidth(m_gui_cfg->input_width); ImGui::SetNextItemWidth(m_gui_cfg->input_width);
if (ImGui::BeginCombo("##style_selector", trunc_name.c_str())) { if (ImGui::BeginCombo("##style_selector", trunc_name.c_str())) {
@ -1720,7 +1835,7 @@ void GLGizmoEmboss::draw_style_list() {
} }
ImGui::SameLine(); ImGui::SameLine();
draw_rename_style_botton(); draw_style_rename_button();
// Is style changed against stored one // Is style changed against stored one
FontItem &font_item = m_style_manager.get_font_item(); 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; bool is_changed = (is_stored) ? !(*stored_fi == font_item) : true;
// TODO: check order of font items in list to allowe save actual order // TODO: check order of font items in list to allowe save actual order
// save button
ImGui::SameLine(); ImGui::SameLine();
if (draw_button(IconType::save, !is_changed)) { draw_style_save_button();
// save styles to app config
m_style_manager.store_font_list_to_app_config(wxGetApp().app_config); ImGui::SameLine();
}else if (ImGui::IsItemHovered()) { draw_style_save_as_button();
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());
}
}
// undo button // undo button
ImGui::SameLine(); ImGui::SameLine();
bool can_undo = is_stored && is_changed; draw_style_undo_button();
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());
}
#ifdef ALLOW_REVERT_ALL_STYLES #ifdef ALLOW_REVERT_ALL_STYLES
ImGui::SameLine(); ImGui::SameLine();
@ -1771,7 +1868,7 @@ void GLGizmoEmboss::draw_style_list() {
draw_delete_style_button(); draw_delete_style_button();
} }
bool GLGizmoEmboss::italic_button() bool GLGizmoEmboss::draw_italic_button()
{ {
std::optional<wxFont> &wx_font = m_style_manager.get_wx_font(); std::optional<wxFont> &wx_font = m_style_manager.get_wx_font();
const auto& ff = m_style_manager.get_font_file_with_cache(); const auto& ff = m_style_manager.get_font_file_with_cache();
@ -1814,7 +1911,7 @@ bool GLGizmoEmboss::italic_button()
return false; return false;
} }
bool GLGizmoEmboss::bold_button() { bool GLGizmoEmboss::draw_bold_button() {
std::optional<wxFont> &wx_font = m_style_manager.get_wx_font(); std::optional<wxFont> &wx_font = m_style_manager.get_wx_font();
const auto& ff = m_style_manager.get_font_file_with_cache(); const auto& ff = m_style_manager.get_font_file_with_cache();
if (!wx_font.has_value() || !ff.has_value()) { if (!wx_font.has_value() || !ff.has_value()) {
@ -1881,7 +1978,7 @@ bool GLGizmoEmboss::revertible(const std::string &name,
Draw draw) Draw draw)
{ {
bool changed = exist_change(value, default_value); bool changed = exist_change(value, default_value);
if (changed) if (changed || default_value == nullptr)
ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, name); ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, name);
else else
ImGuiWrapper::text(name); ImGuiWrapper::text(name);
@ -1976,7 +2073,7 @@ void GLGizmoEmboss::draw_style_edit() {
is_font_changed = is_font_face_changed || is_font_style_changed; 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); ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, tr.font);
else else
ImGuiWrapper::text(tr.font); ImGuiWrapper::text(tr.font);
@ -1985,9 +2082,10 @@ void GLGizmoEmboss::draw_style_edit() {
draw_font_list(); draw_font_list();
ImGui::SameLine(); ImGui::SameLine();
bool exist_change = false; bool exist_change = false;
exist_change |= italic_button(); if (draw_italic_button()) exist_change = true;
ImGui::SameLine(); ImGui::SameLine();
exist_change |= bold_button(); if (draw_bold_button()) exist_change = true;
if (is_font_changed) { if (is_font_changed) {
ImGui::SameLine(ImGui::GetStyle().FramePadding.x); ImGui::SameLine(ImGui::GetStyle().FramePadding.x);
@ -2537,50 +2635,46 @@ bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
if (volume == nullptr) return false; if (volume == nullptr) return false;
if (!volume->text_configuration.has_value()) return false; if (!volume->text_configuration.has_value()) return false;
TextConfiguration &configuration = *volume->text_configuration; TextConfiguration &tc = *volume->text_configuration;
FontItem & c_font_item = configuration.font_item; 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; const FontItem &fi = font_item.font_item;
return fi.name == c_font_item.name; return fi.name == tc_fi.name;
}; };
std::optional<wxFont> 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(); const auto& styles = m_style_manager.get_styles();
auto it = std::find_if(styles.begin(), styles.end(), has_same_name); auto it = std::find_if(styles.begin(), styles.end(), has_same_name);
bool found_font = it != styles.end(); if (it == styles.end()) {
size_t font_index; // style was not found
if (!found_font) { if (wx_font_opt.has_value())
// font is not in list m_style_manager.load_font(tc_fi, *wx_font_opt);
// 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
} else { } else {
// font is found in list size_t style_index = it - styles.begin();
font_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 { } else {
// can't create similar font use previous // stored style is loaded, add volume changes
m_style_manager.erase(font_index); 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; return true;
} }
@ -2759,26 +2853,6 @@ bool GLGizmoEmboss::is_text_object(const ModelVolume *text) {
return true; 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) std::string GLGizmoEmboss::get_file_name(const std::string &file_path)
{ {
size_t pos_last_delimiter = file_path.find_last_of("/\\"); size_t pos_last_delimiter = file_path.find_last_of("/\\");

View File

@ -104,11 +104,15 @@ private:
void draw_delete_style_button(); void draw_delete_style_button();
void discard_changes_in_style(); void discard_changes_in_style();
void draw_revert_all_styles_button(); 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_font_list();
void draw_style_edit(); void draw_style_edit();
bool italic_button(); bool draw_italic_button();
bool bold_button(); bool draw_bold_button();
void draw_advanced(); void draw_advanced();
bool select_facename(const wxString& facename); bool select_facename(const wxString& facename);

View File

@ -17,6 +17,8 @@ using namespace Slic3r::GUI;
FontManager::FontManager(const ImWchar *language_glyph_range) FontManager::FontManager(const ImWchar *language_glyph_range)
: m_imgui_init_glyph_range(language_glyph_range) : m_imgui_init_glyph_range(language_glyph_range)
, m_exist_style_images(false) , m_exist_style_images(false)
, m_change_order(false)
, m_stored_activ_index(std::numeric_limits<size_t>::max())
, m_temp_style_images(nullptr) , 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; if (font_list.empty()) font_list = default_font_list;
for (FontItem &fi : font_list) { for (FontItem &fi : font_list) {
make_unique_name(fi.name); make_unique_name(fi.name);
m_font_list.push_back({fi}); m_style_items.push_back({fi});
} }
std::optional<size_t> activ_index_opt = (cfg != nullptr) ? std::optional<size_t> activ_index_opt = (cfg != nullptr) ?
FontListSerializable::load_font_index(*cfg) : FontListSerializable::load_font_index(*cfg) :
std::optional<size_t>{}; std::optional<size_t>{};
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 // find valid font item
if (!load_font(activ_index)) { 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; activ_index = 0;
while (m_font_list.empty() || !load_font(activ_index)) while (m_style_items.empty() || !load_font(activ_index))
m_font_list.erase(m_font_list.begin()); m_style_items.erase(m_style_items.begin());
// no one style from config is loadable // no one style from config is loadable
if (m_font_list.empty()) { if (m_style_items.empty()) {
// set up default font list // set up default font list
for (FontItem fi : default_font_list) { for (FontItem fi : default_font_list) {
make_unique_name(fi.name); 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 // try to load first default font
bool loaded = load_font(activ_index); 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 (cfg == nullptr) return false;
if (exist_stored_style()) { if (exist_stored_style()) {
// update stored item // 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 { } else {
// add new into stored list // add new into stored list
FontItem &fi = m_style_cache.font_item; FontItem &fi = m_style_cache.font_item;
make_unique_name(fi.name); make_unique_name(fi.name);
m_style_cache.font_index = m_font_list.size(); m_style_cache.font_index = m_style_items.size();
m_font_list.push_back({fi}); m_style_items.push_back({fi});
} }
FontListSerializable::store_font_index(*cfg, m_style_cache.font_index); FontListSerializable::store_font_index(*cfg, m_style_cache.font_index);
m_stored_activ_index = m_style_cache.font_index;
FontList font_list; FontList font_list;
font_list.reserve(m_font_list.size()); font_list.reserve(m_style_items.size());
for (const Item &item : m_font_list) font_list.push_back(item.font_item); for (const Item &item : m_style_items) font_list.push_back(item.font_item);
FontListSerializable::store_font_list(*cfg, font_list); FontListSerializable::store_font_list(*cfg, font_list);
m_change_order = false;
return true; return true;
} }
void FontManager::swap(size_t i1, size_t i2) { void FontManager::store_style(const std::string &name) {
if (i1 >= m_font_list.size() || FontItem& fi = m_style_cache.font_item;
i2 >= m_font_list.size()) return; fi.name = name;
std::swap(m_font_list[i1], m_font_list[i2]); 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 // fix selected index
if (!exist_stored_style()) return; if (!exist_stored_style()) return;
if (m_style_cache.font_index == i1) { 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<size_t>::max())
return true;
return m_style_cache.font_index != m_stored_activ_index;
};
void FontManager::erase(size_t index) { void FontManager::erase(size_t index) {
if (index >= m_font_list.size()) return; if (index >= m_style_items.size()) return;
// fix selected index // fix selected index
if (exist_stored_style() && if (exist_stored_style()) {
index < m_style_cache.font_index) size_t &i = m_style_cache.font_index;
--m_style_cache.font_index; if (index < i) --i;
else if (index == i) i = std::numeric_limits<size_t>::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<Emboss::FontFile> font_file) bool FontManager::wx_font_changed(std::unique_ptr<Emboss::FontFile> font_file)
@ -131,8 +168,8 @@ bool FontManager::wx_font_changed(std::unique_ptr<Emboss::FontFile> font_file)
bool FontManager::load_font(size_t font_index) bool FontManager::load_font(size_t font_index)
{ {
if (font_index >= m_font_list.size()) return false; if (font_index >= m_style_items.size()) return false;
if (!load_font(m_font_list[font_index].font_item)) return false; if (!load_font(m_style_items[font_index].font_item)) return false;
m_style_cache.font_index = font_index; m_style_cache.font_index = font_index;
m_style_cache.stored_wx_font = m_style_cache.wx_font; m_style_cache.stored_wx_font = m_style_cache.wx_font;
return true; 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_item = fi; // copy
m_style_cache.font_index = std::numeric_limits<size_t>::max(); m_style_cache.font_index = std::numeric_limits<size_t>::max();
m_style_cache.stored_wx_font = {}; m_style_cache.stored_wx_font = {};
m_style_cache.truncated_name.clear();
return true; return true;
} }
bool FontManager::is_activ_font() { return m_style_cache.font_file.has_value(); } bool FontManager::is_activ_font() { return m_style_cache.font_file.has_value(); }
bool FontManager::load_first_valid_font() { bool FontManager::load_first_valid_font() {
while (!m_font_list.empty()) { while (!m_style_items.empty()) {
if (load_font(0)) return true; if (load_font(0)) return true;
// can't load so erase it from list // 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; return false;
} }
const FontItem* FontManager::get_stored_font_item() const const FontItem* FontManager::get_stored_font_item() const
{ {
if (m_style_cache.font_index >= m_font_list.size()) return nullptr; if (m_style_cache.font_index >= m_style_items.size()) return nullptr;
return &m_font_list[m_style_cache.font_index].font_item; return &m_style_items[m_style_cache.font_index].font_item;
} }
const std::optional<wxFont> &FontManager::get_stored_wx_font() const { return m_style_cache.stored_wx_font; } const std::optional<wxFont> &FontManager::get_stored_wx_font() const { return m_style_cache.stored_wx_font; }
@ -226,7 +264,7 @@ ImFont *FontManager::get_imgui_font()
return font; return font;
} }
const std::vector<FontManager::Item> &FontManager::get_styles() const{ return m_font_list; } const std::vector<FontManager::Item> &FontManager::get_styles() const{ return m_style_items; }
ImFont* FontManager::extend_imgui_font_range(size_t index, const std::string& text) 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) void FontManager::make_unique_name(std::string &name)
{ {
auto is_unique = [&](const std::string &name) -> bool { 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; if (it.font_item.name == name) return false;
return true; return true;
}; };
@ -261,7 +299,7 @@ void FontManager::make_unique_name(std::string &name)
} }
void FontManager::init_trunc_names(float max_width) { 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()) if (s.truncated_name.empty())
s.truncated_name = ImGuiWrapper::trunc(s.font_item.name, max_width); 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]; StyleImagesData::Item &style = m_temp_style_images->styles[index];
// find style in font list and copy to it // 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 || if (it.font_item.name != style.text ||
!(it.font_item.prop == style.prop)) !(it.font_item.prop == style.prop))
continue; continue;
@ -309,8 +347,8 @@ void FontManager::init_style_images(const Vec2i &max_size,
// create job for init images // create job for init images
m_temp_style_images = std::make_shared<StyleImagesData::StyleImages>(); m_temp_style_images = std::make_shared<StyleImagesData::StyleImages>();
StyleImagesData::Items styles; StyleImagesData::Items styles;
styles.reserve(m_font_list.size()); styles.reserve(m_style_items.size());
for (const Item &item : m_font_list) { for (const Item &item : m_style_items) {
const FontItem &fi = item.font_item; const FontItem &fi = item.font_item;
std::optional<wxFont> wx_font_opt = WxFontUtils::load_wxFont(fi.path); std::optional<wxFont> wx_font_opt = WxFontUtils::load_wxFont(fi.path);
if (!wx_font_opt.has_value()) continue; if (!wx_font_opt.has_value()) continue;
@ -334,7 +372,7 @@ void FontManager::free_style_images() {
GLuint tex_id = 0; GLuint tex_id = 0;
for (Item &it : m_font_list) { for (Item &it : m_style_items) {
if (tex_id == 0 && it.image.has_value()) if (tex_id == 0 && it.image.has_value())
tex_id = (GLuint)(intptr_t) it.image->texture_id; tex_id = (GLuint)(intptr_t) it.image->texture_id;
it.image.reset(); it.image.reset();

View File

@ -42,20 +42,44 @@ public:
bool store_font_list_to_app_config(AppConfig *cfg); bool store_font_list_to_app_config(AppConfig *cfg);
/// <summary> /// <summary>
/// Change order of style item in m_font_list. /// Append actual style to style list and store
/// </summary>
/// <param name="name">New name for style</param>
void store_style(const std::string& name);
/// <summary>
/// Change order of style item in m_style_items.
/// Fix selected font index when (i1 || i2) == m_font_selected /// Fix selected font index when (i1 || i2) == m_font_selected
/// </summary> /// </summary>
/// <param name="i1">First index to m_font_list</param> /// <param name="i1">First index to m_style_items</param>
/// <param name="i2">Second index to m_font_list</param> /// <param name="i2">Second index to m_style_items</param>
void swap(size_t i1, size_t i2); void swap(size_t i1, size_t i2);
/// <summary> /// <summary>
/// Remove style from m_font_list. /// Track using of swap between saves
/// </summary>
/// <returns>True when swap was call after save otherwise false</returns>
bool is_style_order_changed() const;
/// <summary>
/// Check that actual selected style is same as activ style stored in "PrusaSlicer.ini"
/// </summary>
/// <returns>True when actual selection is not stored otherwise False</returns>
bool is_activ_style_changed() const;
/// <summary>
/// Remove style from m_style_items.
/// Fix selected font index when index is under m_font_selected /// Fix selected font index when index is under m_font_selected
/// </summary> /// </summary>
/// <param name="index">Index of style to be removed</param> /// <param name="index">Index of style to be removed</param>
void erase(size_t index); void erase(size_t index);
/// <summary>
/// Rename actual selected font item
/// </summary>
/// <param name="name">New name</param>
void rename(const std::string &name);
/// <summary> /// <summary>
/// Actual wx font was changed /// Actual wx font was changed
/// Clear caches /// Clear caches
@ -67,7 +91,7 @@ public:
/// Change active font /// Change active font
/// When font not loaded roll back activ font /// When font not loaded roll back activ font
/// </summary> /// </summary>
/// <param name="font_index">New font index(from m_font_list range)</param> /// <param name="font_index">New font index(from m_style_items range)</param>
/// <returns>True on succes. False on fail load font</returns> /// <returns>True on succes. False on fail load font</returns>
bool load_font(size_t font_index); bool load_font(size_t font_index);
// load font style not stored in list // load font style not stored in list
@ -205,7 +229,7 @@ private:
// cache for stored wx font to not create every frame // cache for stored wx font to not create every frame
std::optional<wxFont> stored_wx_font; std::optional<wxFont> stored_wx_font;
// index into m_font_list // index into m_style_items
size_t font_index = std::numeric_limits<size_t>::max(); size_t font_index = std::numeric_limits<size_t>::max();
} m_style_cache; } m_style_cache;
@ -218,7 +242,9 @@ private:
void make_unique_name(std::string &name); void make_unique_name(std::string &name);
// Privat member // Privat member
std::vector<Item> m_font_list; std::vector<Item> m_style_items;
bool m_change_order = false;
size_t m_stored_activ_index;
/// <summary> /// <summary>
/// Keep data needed to create Font Style Images in Job /// Keep data needed to create Font Style Images in Job

View File

@ -194,9 +194,9 @@ const TypeToWeight WxFontUtils::type_to_weight =
(wxFONTWEIGHT_HEAVY, "heavy") (wxFONTWEIGHT_HEAVY, "heavy")
(wxFONTWEIGHT_EXTRAHEAVY, "extraHeavy"); (wxFONTWEIGHT_EXTRAHEAVY, "extraHeavy");
std::optional<wxFont> WxFontUtils::create_wxFont(const FontItem &fi, std::optional<wxFont> WxFontUtils::create_wxFont(const FontItem &fi)
const FontProp &fp)
{ {
const FontProp &fp = fi.prop;
double point_size = static_cast<double>(fp.size_in_mm); double point_size = static_cast<double>(fp.size_in_mm);
wxFontInfo info(point_size); wxFontInfo info(point_size);
if (fp.family.has_value()) { if (fp.family.has_value()) {

View File

@ -36,8 +36,7 @@ public:
static std::optional<wxFont> load_wxFont(const std::string &font_descriptor); static std::optional<wxFont> load_wxFont(const std::string &font_descriptor);
// Try to create similar font, loaded from 3mf from different Computer // Try to create similar font, loaded from 3mf from different Computer
static std::optional<wxFont> create_wxFont(const FontItem &fi, static std::optional<wxFont> create_wxFont(const FontItem &fi);
const FontProp &fp);
// update font property by wxFont // update font property by wxFont
static void update_property(FontProp &font_prop, const wxFont &font); static void update_property(FontProp &font_prop, const wxFont &font);