Duplicate font item GUI

This commit is contained in:
Filip Sykala 2022-01-11 14:07:38 +01:00
parent 734026bf96
commit 310d53c1b9
3 changed files with 70 additions and 35 deletions

View File

@ -49,6 +49,7 @@ struct FontProp
// represent selected font
// Name must be human readable is visible in gui
// (Path + Type) must define how to open font for using on different OS
// NOTE: OnEdit fix serializations: FontListSerializable, TextConfigurationSerialization
struct FontItem
{
std::string name;
@ -81,9 +82,12 @@ struct FontItem
// Font item name inside list is unique
// FontList is not map beacuse items order matters (view of list)
// It is stored into AppConfig by FontListSerializable
using FontList = std::vector<FontItem>;
// define how to create 'Text volume'
// It is stored into .3mf by TextConfigurationSerialization
// Also it is stored into undo / redo stack by cereal
struct TextConfiguration
{
// define font

View File

@ -396,16 +396,18 @@ void GLGizmoEmboss::initialize()
ImGui::GetTextLineHeight();
m_gui_cfg->max_font_name_width = ImGui::CalcTextSize("Maximal font name").x;
m_gui_cfg->icon_width = ImGui::GetTextLineHeight();
m_gui_cfg->icon_width_with_spacing = m_gui_cfg->icon_width + space;
float icon_width_with_spacing = m_gui_cfg->icon_width + space;
float scroll_width = m_gui_cfg->icon_width_with_spacing; // fix
m_gui_cfg->combo_font_width = m_gui_cfg->max_font_name_width +
2 * m_gui_cfg->icon_width_with_spacing +
scroll_width;
float scroll_width = icon_width_with_spacing; // fix
m_gui_cfg->combo_font_width = m_gui_cfg->max_font_name_width + space
+ 3 * icon_width_with_spacing
+ scroll_width;
m_gui_cfg->rename_pos_x = m_gui_cfg->max_font_name_width + space;
m_gui_cfg->duplicate_pos_x = m_gui_cfg->max_font_name_width + space;
m_gui_cfg->rename_pos_x = m_gui_cfg->duplicate_pos_x +
icon_width_with_spacing;
m_gui_cfg->delete_pos_x = m_gui_cfg->rename_pos_x +
m_gui_cfg->icon_width_with_spacing;
icon_width_with_spacing;
m_gui_cfg->text_size = ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() *
m_gui_cfg->count_line_of_text);
@ -617,7 +619,8 @@ void GLGizmoEmboss::draw_window()
void GLGizmoEmboss::draw_font_list()
{
const float &max_width = m_gui_cfg->max_font_name_width;
std::optional<size_t> rename_index;
std::optional<size_t> rename_index, delete_index, duplicate_index;
const std::string& current_name = m_font_list[m_font_selected].name;
std::string trunc_name = ImGuiWrapper::trunc(current_name, max_width);
ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width);
@ -643,13 +646,12 @@ void GLGizmoEmboss::draw_font_list()
#endif // ALLOW_DEBUG_MODE
ImGui::Separator();
for (FontItem &f : m_font_list) {
ImGui::PushID(f.name.c_str());
std::string name = ImGuiWrapper::trunc(f.name, max_width);
size_t index = &f - &m_font_list.front();
bool is_selected = index == m_font_selected;
auto flags = ImGuiSelectableFlags_AllowItemOverlap; // allow click buttons
ImGuiSelectableFlags_ flags = ImGuiSelectableFlags_AllowItemOverlap; // allow click buttons
if (ImGui::Selectable(name.c_str(), is_selected, flags) ) {
if (load_font(index)) process();
} else if (ImGui::IsItemHovered())
@ -660,26 +662,44 @@ void GLGizmoEmboss::draw_font_list()
int other_index = index + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1);
if (other_index >= 0 && other_index < m_font_list.size()) {
std::swap(m_font_list[index], m_font_list[other_index]);
// fix selected index
if (m_font_selected == other_index) m_font_selected = index;
else if (m_font_selected == index) m_font_selected = other_index;
ImGui::ResetMouseDragDelta();
}
}
// draw buttons rename and delete
ImGui::SameLine();
ImGui::SetCursorPosX(m_gui_cfg->rename_pos_x);
// draw buttons rename / duplicate / delete
ImGui::SameLine(m_gui_cfg->rename_pos_x);
if (draw_button(IconType::rename)) rename_index = index;
ImGui::SameLine();
ImGui::SetCursorPosX(m_gui_cfg->delete_pos_x);
if (draw_button(IconType::erase, is_selected)) {
ImGui::SameLine(m_gui_cfg->duplicate_pos_x);
if (draw_button(IconType::duplicate)) duplicate_index = index;
ImGui::SameLine(m_gui_cfg->delete_pos_x);
if (draw_button(IconType::erase, is_selected)) delete_index = index;
ImGui::PopID();
}
ImGui::EndCombo();
}
// duplicate font item
if (duplicate_index.has_value()) {
size_t index = *duplicate_index;
FontItem fi = m_font_list[index]; // copy
make_unique_name(fi.name, m_font_list);
m_font_list.insert(m_font_list.begin() + index, fi);
// fix selected index
if (index < m_font_selected) ++m_font_selected;
store_font_list_to_app_config();
}
// delete font item
if (delete_index.has_value()) {
size_t index = *delete_index;
m_font_list.erase(m_font_list.begin() + index);
// fix selected index
if (index < m_font_selected) --m_font_selected;
store_font_list_to_app_config();
}
ImGui::PopID();
}
ImGui::EndCombo();
}
// rename modal window popup
const char *rename_popup_id = "Rename_font";
@ -977,7 +997,7 @@ void GLGizmoEmboss::load_imgui_font()
m_imgui_font_atlas.TexID = (ImTextureID) (intptr_t) font_texture;
}
static void make_unique_name(std::string &name, const FontList &list)
void GLGizmoEmboss::make_unique_name(std::string &name, const FontList &list)
{
auto is_unique = [&list](const std::string &name)->bool {
for (const FontItem &fi : list)
@ -988,6 +1008,13 @@ static void make_unique_name(std::string &name, const FontList &list)
if (name.empty()) name = "font";
if (is_unique(name)) return;
auto pos = name.find(" (");
if (pos != std::string::npos &&
name.find(")", pos) != std::string::npos) {
// short name by ord number
name = name.substr(0, pos);
}
int order = 1; // start with value 2 to represents same font name
std::string new_name;
do {
@ -1217,7 +1244,8 @@ bool GLGizmoEmboss::init_icons()
// icon order has to match the enum IconType
std::vector<std::string> filenames = {path + "wrench.svg",
path + "delete.svg"};
path + "delete.svg",
path + "add_copies.svg"};
// state order has to match the enum IconState
std::vector<std::pair<int, bool>> states;
@ -1247,7 +1275,7 @@ void GLGizmoEmboss::draw_icon(IconType icon, IconState state)
ImTextureID tex_id = (void *) (intptr_t) (GLuint) icons_texture_id;
// ImVec2 image_size(tex_width, tex_height);
size_t count_icons = 2; // wrench | delete
size_t count_icons = 3; // wrench | delete | copy
size_t count_states = 3; // activable | hovered | disabled
ImVec2 icon_size(tex_width / count_states, tex_height / count_icons);
@ -1284,22 +1312,23 @@ bool GLGizmoEmboss::draw_button(IconType icon, bool disable)
draw_icon(icon, IconState::activable);
if (ImGui::IsItemClicked()) return true;
if (ImGui::IsItemHovered()) {
std::string tooltip;
switch (icon) {
case IconType::rename:
ImGui::SetTooltip("%s", _u8L("rename").c_str());
break;
case IconType::erase:
ImGui::SetTooltip("%s", _u8L("delete").c_str());
break;
case IconType::rename: tooltip = _u8L("rename"); break;
case IconType::erase: tooltip = _u8L("delete"); break;
case IconType::duplicate:tooltip = _u8L("duplicate"); break;
default: break;
}
if (!tooltip.empty())
ImGui::SetTooltip("%s", tooltip.c_str());
// redraw image over previous
ImGui::SameLine();
ImGui::SetCursorPosX(cursor_x);
draw_icon(icon, IconState::hovered);
if (ImGui::IsItemClicked()) return true;
}
return false;
}

View File

@ -113,6 +113,8 @@ private:
void load_imgui_font();
void check_imgui_font_range();
// TODO: move to fontList utils
static void make_unique_name(std::string &name, const FontList &list);
bool choose_font_by_wxdialog();
bool choose_true_type_file();
bool choose_svg_file();
@ -152,9 +154,9 @@ private:
float combo_font_width = 0.f;
float rename_pos_x = 0.f;
float delete_pos_x = 0.f;
float duplicate_pos_x = 0.f;
float max_font_name_width = 0.f;
float icon_width = 0.f;
float icon_width_with_spacing = 0.f;
ImVec2 text_size;
GuiCfg() = default;
};
@ -191,7 +193,7 @@ private:
// drawing icons
GLTexture m_icons_texture;
bool init_icons();
enum class IconType: unsigned { rename = 0, erase /*1*/};
enum class IconType: unsigned { rename = 0, erase /*1*/, duplicate /*2*/};
enum class IconState: unsigned { activable = 0, hovered /*1*/, disabled /*2*/};
void draw_icon(IconType icon, IconState state);
bool draw_button(IconType icon, bool disable = false);