mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-14 00:52:04 +00:00
Restructure Text/Emboss Tool UI (#12864)
* restructures text tool ui, moves style selector over font, moves reset buttons after settings, matches style popup styling to font popup * makes operation setting single-line * makes "Advanced" button bigger, matching BambuStudio --------- Co-authored-by: Hanno Witzleb <hannowitzleb@gmail.com>
This commit is contained in:
@@ -1362,21 +1362,30 @@ void GLGizmoEmboss::draw_window(float x, float y)
|
||||
|
||||
draw_text_input();
|
||||
|
||||
ImGui::Indent();
|
||||
// When unknown font is inside .3mf only font selection is allowed
|
||||
m_imgui->disabled_end(/*m_is_unknown_font*/);
|
||||
draw_font_list_line();
|
||||
m_imgui->disabled_begin(m_is_unknown_font);
|
||||
bool use_inch = wxGetApp().app_config->get_bool("use_inches");
|
||||
draw_height(use_inch);
|
||||
draw_depth(use_inch);
|
||||
ImGui::Unindent();
|
||||
// subtract 4.0f to counteract weird additional spacing/padding of the revert buttons
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f - 4.0f));
|
||||
ScopeGuard spacing_sc([](){ ImGui::PopStyleVar(/*ImGuiStyleVar_ItemSpacing*/); });
|
||||
|
||||
draw_style_list();
|
||||
|
||||
// When unknown font is inside .3mf only font selection is allowed
|
||||
m_imgui->disabled_end(/*m_is_unknown_font*/);
|
||||
draw_font_list_line();
|
||||
m_imgui->disabled_begin(m_is_unknown_font);
|
||||
|
||||
bool use_inch = wxGetApp().app_config->get_bool("use_inches");
|
||||
draw_height(use_inch);
|
||||
draw_depth(use_inch);
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
// close advanced style property when unknown font is selected
|
||||
if (m_is_unknown_font && m_is_advanced_edit_style)
|
||||
ImGui::SetNextTreeNodeOpen(false);
|
||||
|
||||
if (ImGui::TreeNode(_u8L("Advanced").c_str())) {
|
||||
// ImGui Bug: After switching to another window and switching back, clicking the text doesnt open/close the TreeNode anymore
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_FramePadding;
|
||||
if (ImGui::TreeNodeEx(_u8L("Advanced").c_str(), flags)) {
|
||||
if (!m_is_advanced_edit_style) {
|
||||
m_is_advanced_edit_style = true;
|
||||
m_imgui->set_requires_extra_frame();
|
||||
@@ -1389,9 +1398,7 @@ void GLGizmoEmboss::draw_window(float x, float y)
|
||||
m_imgui->set_requires_extra_frame();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
draw_style_list();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Do not select volume type, when it is text object
|
||||
if (!m_volume->is_the_only_one_part()) {
|
||||
@@ -1680,21 +1687,29 @@ void GLGizmoEmboss::draw_font_list_line()
|
||||
}
|
||||
|
||||
EmbossStyle &style = m_style_manager.get_style();
|
||||
if (exist_change_in_font) {
|
||||
ImGui::SameLine(ImGui::GetStyle().WindowPadding.x);
|
||||
auto r_icon = get_icon(m_icons, IconType::undo, IconState::hovered);
|
||||
if (Slic3r::GUI::button(r_icon, r_icon, r_icon)) { // ORCA draw bottom with same orange color
|
||||
const EmbossStyle *stored_style = m_style_manager.get_stored_style();
|
||||
auto r_icon = get_icon(m_icons, IconType::undo, IconState::hovered);
|
||||
if (exist_change_in_font == false) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.0f);
|
||||
m_imgui->disabled_begin(true);
|
||||
}
|
||||
|
||||
style.path = stored_style->path;
|
||||
style.prop.boldness = stored_style->prop.boldness;
|
||||
style.prop.skew = stored_style->prop.skew;
|
||||
ImGui::SameLine();
|
||||
if (Slic3r::GUI::button(r_icon, r_icon, r_icon)) { // ORCA draw bottom with same orange color
|
||||
const EmbossStyle *stored_style = m_style_manager.get_stored_style();
|
||||
|
||||
wxFont new_wx_font = WxFontUtils::load_wxFont(style.path);
|
||||
if (new_wx_font.IsOk() && m_style_manager.set_wx_font(new_wx_font))
|
||||
exist_change = true;
|
||||
style.path = stored_style->path;
|
||||
style.prop.boldness = stored_style->prop.boldness;
|
||||
style.prop.skew = stored_style->prop.skew;
|
||||
|
||||
wxFont new_wx_font = WxFontUtils::load_wxFont(style.path);
|
||||
if (new_wx_font.IsOk() && m_style_manager.set_wx_font(new_wx_font))
|
||||
exist_change = true;
|
||||
} else if (ImGui::IsItemHovered())
|
||||
m_imgui->tooltip(_u8L("Revert font changes."), m_gui_cfg->max_tooltip_width);
|
||||
m_imgui->tooltip(_u8L("Revert font changes."), m_gui_cfg->max_tooltip_width);
|
||||
|
||||
if (exist_change_in_font == false) {
|
||||
ImGui::PopStyleVar();
|
||||
m_imgui->disabled_end();
|
||||
}
|
||||
|
||||
if (exist_change) {
|
||||
@@ -1750,6 +1765,7 @@ void GLGizmoEmboss::draw_font_list()
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.0f, 0.5f)); // vertically align label
|
||||
|
||||
for (int i = 0; i < show_items_count; i++) {
|
||||
int idx = is_filtered ? filtered_items_idx[i] : i;
|
||||
@@ -1783,7 +1799,7 @@ void GLGizmoEmboss::draw_font_list()
|
||||
::draw_font_preview(face, m_text, *m_face_names, *m_gui_cfg, ImGui::IsItemVisible());
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleVar(4); // ImGuiStyleVar_ItemSpacing, ImGuiStyleVar_ItemInnerSpacing, ImGuiStyleVar_FrameRounding, ImGuiStyleVar_SelectableTextAlign
|
||||
ImGui::EndListBox();
|
||||
ImGui::EndPopup();
|
||||
} else if (m_face_names->is_init) {
|
||||
@@ -1841,7 +1857,8 @@ void GLGizmoEmboss::draw_font_list()
|
||||
|
||||
void GLGizmoEmboss::draw_model_type()
|
||||
{
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Spacing();
|
||||
|
||||
bool is_last_solid_part = m_volume->is_the_only_one_part();
|
||||
std::string title = _u8L("Operation");
|
||||
if (is_last_solid_part) {
|
||||
@@ -1858,13 +1875,18 @@ void GLGizmoEmboss::draw_model_type()
|
||||
ModelVolumeType type = m_volume->type();
|
||||
|
||||
//TRN EmbossOperation
|
||||
float minimum_spacing_x = 8.0f;
|
||||
float minimum_offset_x = ImGui::GetCursorPosX() + minimum_spacing_x;
|
||||
float offset_x = std::max(m_gui_cfg->input_offset, minimum_offset_x);
|
||||
ImGui::SameLine(offset_x);
|
||||
|
||||
ImGuiWrapper::push_radio_style(m_parent.get_scale()); // ORCA
|
||||
if (ImGui::RadioButton(_u8L("Join").c_str(), type == part))
|
||||
new_type = part;
|
||||
else if (ImGui::IsItemHovered())
|
||||
m_imgui->tooltip(_u8L("Click to change text into object part."), m_gui_cfg->max_tooltip_width);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SameLine();
|
||||
std::string last_solid_part_hint = _u8L("You can't change a type of the last solid part of the object.");
|
||||
if (ImGui::RadioButton(_CTX_utf8(L_CONTEXT("Cut", "EmbossOperation"), "EmbossOperation").c_str(), type == negative))
|
||||
new_type = negative;
|
||||
@@ -2181,13 +2203,17 @@ void GLGizmoEmboss::draw_style_list() {
|
||||
trunc_name = ImGuiWrapper::trunc(current_name, max_style_name_width);
|
||||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
||||
std::string title = _u8L("Style");
|
||||
if (m_style_manager.exist_stored_style())
|
||||
ImGui::Text("%s", title.c_str());
|
||||
else
|
||||
ImGui::TextColored(ImGuiWrapper::COL_ORCA, "%s", title.c_str());
|
||||
|
||||
ImGui::SetNextItemWidth(m_gui_cfg->input_width);
|
||||
ImGui::SameLine(m_gui_cfg->input_offset);
|
||||
|
||||
ImGui::SetNextItemWidth(2 * m_gui_cfg->input_width);
|
||||
auto add_text_modify = [&is_modified](const std::string& name) {
|
||||
if (!is_modified) return name;
|
||||
return name + Preset::suffix_modified();
|
||||
@@ -2199,6 +2225,14 @@ void GLGizmoEmboss::draw_style_list() {
|
||||
m_style_manager.init_style_images(m_gui_cfg->max_style_image_size, m_text);
|
||||
m_style_manager.init_trunc_names(max_style_name_width);
|
||||
std::optional<std::pair<size_t,size_t>> swap_indexes;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.0f, 0.5f)); // vertically align label
|
||||
|
||||
const StyleManager::Styles &styles = m_style_manager.get_styles();
|
||||
for (const StyleManager::Style &style : styles) {
|
||||
size_t index = &style - &styles.front();
|
||||
@@ -2206,12 +2240,10 @@ void GLGizmoEmboss::draw_style_list() {
|
||||
ImGui::PushID(actual_style_name.c_str());
|
||||
bool is_selected = (index == m_style_manager.get_style_index());
|
||||
|
||||
float select_height = static_cast<float>(m_gui_cfg->max_style_image_size.y());
|
||||
ImVec2 select_size(0.f, select_height); // 0,0 --> calculate in draw
|
||||
const std::optional<StyleManager::StyleImage> &img = style.image;
|
||||
ImVec2 selectable_size(0, m_imgui->scaled(32.f / 15.f)); // 0.0f -> calculated during draw
|
||||
// allow click delete button
|
||||
ImGuiSelectableFlags_ flags = ImGuiSelectableFlags_AllowItemOverlap;
|
||||
if (ImGui::BBLSelectable(style.truncated_name.c_str(), is_selected, flags, select_size)) {
|
||||
if (ImGui::BBLSelectable(style.truncated_name.c_str(), is_selected, flags, selectable_size)) {
|
||||
selected_style_index = index;
|
||||
} else if (ImGui::IsItemHovered())
|
||||
tooltip = actual_style_name;
|
||||
@@ -2227,6 +2259,7 @@ void GLGizmoEmboss::draw_style_list() {
|
||||
ImGui::ResetMouseDragDelta();
|
||||
}
|
||||
|
||||
const std::optional<StyleManager::StyleImage> &img = style.image;
|
||||
// draw style name
|
||||
if (img.has_value()) {
|
||||
ImGui::SameLine(max_style_name_width);
|
||||
@@ -2239,6 +2272,10 @@ void GLGizmoEmboss::draw_style_list() {
|
||||
if (swap_indexes.has_value())
|
||||
m_style_manager.swap(swap_indexes->first,
|
||||
swap_indexes->second);
|
||||
|
||||
// ImGuiStyleVar_ItemSpacing, ImGuiStyleVar_ItemInnerSpacing, ImGuiStyleVar_FrameRounding,
|
||||
// ImGuiStyleVar_WindowPadding, ImGuiStyleVar_FramePadding, ImGuiStyleVar_SelectableTextAlign
|
||||
ImGui::PopStyleVar(6);
|
||||
ImGui::EndCombo();
|
||||
} else {
|
||||
// do not keep in memory style images when no combo box open
|
||||
@@ -2413,30 +2450,43 @@ bool GLGizmoEmboss::revertible(const std::string &name,
|
||||
Draw draw) const
|
||||
{
|
||||
ImGui::AlignTextToFramePadding();
|
||||
bool changed = exist_change(value, default_value);
|
||||
if (changed || default_value == nullptr)
|
||||
bool changed_from_default = exist_change(value, default_value);
|
||||
if (changed_from_default || default_value == nullptr)
|
||||
ImGuiWrapper::text_colored(ImGuiWrapper::COL_MODIFIED, name); // ORCA Match color
|
||||
else
|
||||
ImGuiWrapper::text(name);
|
||||
|
||||
// render revert changes button
|
||||
if (changed) {
|
||||
ImGuiWindow *window = ImGui::GetCurrentWindow();
|
||||
float prev_x = window->DC.CursorPosPrevLine.x;
|
||||
ImGui::SameLine(undo_offset); // change cursor postion
|
||||
auto r_icon = get_icon(m_icons, IconType::undo, IconState::hovered);
|
||||
if (Slic3r::GUI::button(r_icon, r_icon, r_icon)) { // ORCA draw bottom with same orange color
|
||||
value = *default_value;
|
||||
bool changed = draw();
|
||||
|
||||
// !! Fix to detect change of value after revert of float-slider
|
||||
m_imgui->get_last_slider_status().deactivated_after_edit = true;
|
||||
|
||||
return true;
|
||||
} else if (ImGui::IsItemHovered())
|
||||
m_imgui->tooltip(undo_tooltip, m_gui_cfg->max_tooltip_width);
|
||||
window->DC.CursorPosPrevLine.x = prev_x; // set back previous position
|
||||
if (changed_from_default == false) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.0f);
|
||||
m_imgui->disabled_begin(true);
|
||||
}
|
||||
return draw();
|
||||
|
||||
// render revert changes button
|
||||
auto r_icon = get_icon(m_icons, IconType::undo, IconState::hovered);
|
||||
ImGuiWindow *window = ImGui::GetCurrentWindow();
|
||||
float prev_x = window->DC.CursorPosPrevLine.x;
|
||||
ImGui::SameLine(undo_offset); // change cursor postion
|
||||
if (Slic3r::GUI::button(r_icon, r_icon, r_icon)) { // ORCA draw bottom with same orange color
|
||||
value = *default_value;
|
||||
|
||||
// !! Fix to detect change of value after revert of float-slider
|
||||
m_imgui->get_last_slider_status().deactivated_after_edit = true;
|
||||
|
||||
return true;
|
||||
} else if (ImGui::IsItemHovered())
|
||||
m_imgui->tooltip(undo_tooltip, m_gui_cfg->max_tooltip_width);
|
||||
|
||||
if (undo_offset != 0.0f)
|
||||
window->DC.CursorPosPrevLine.x = prev_x; // set back previous position
|
||||
|
||||
if (changed_from_default == false) {
|
||||
ImGui::PopStyleVar();
|
||||
m_imgui->disabled_end();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
// May be move to ImGuiWrapper
|
||||
template<typename T> bool imgui_input(const char *label, T *v, T step, T step_fast, const char *format, ImGuiInputTextFlags flags);
|
||||
@@ -2457,8 +2507,8 @@ bool GLGizmoEmboss::rev_input(const std::string &name, T &value, const T *defaul
|
||||
return imgui_input(("##" + name).c_str(),
|
||||
&value, step, step_fast, format, flags);
|
||||
};
|
||||
float undo_offset = ImGui::GetStyle().WindowPadding.x;
|
||||
return revertible(name, value, default_value, undo_tooltip, undo_offset, draw_offseted_input);
|
||||
return revertible(name, value, default_value, undo_tooltip,
|
||||
0.0f, draw_offseted_input);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -2509,9 +2559,8 @@ bool GLGizmoEmboss::rev_checkbox(const std::string &name,
|
||||
ImGui::SameLine(offset);
|
||||
return m_imgui->bbl_checkbox(wxString::FromUTF8("##" + name), value);
|
||||
};
|
||||
float undo_offset = ImGui::GetStyle().WindowPadding.x;
|
||||
return revertible(name, value, default_value, undo_tooltip,
|
||||
undo_offset, draw_offseted_input);
|
||||
0.0f, draw_offseted_input);
|
||||
}
|
||||
|
||||
bool GLGizmoEmboss::set_height() {
|
||||
@@ -2592,9 +2641,8 @@ bool GLGizmoEmboss::rev_slider(const std::string &name,
|
||||
return m_imgui->slider_optional_int( ("##" + name).c_str(), value,
|
||||
v_min, v_max, format.c_str(), 1.f, false, tooltip);
|
||||
};
|
||||
float undo_offset = ImGui::GetStyle().WindowPadding.x;
|
||||
return revertible(name, value, default_value,
|
||||
undo_tooltip, undo_offset, draw_slider_optional_int);
|
||||
undo_tooltip, 0.0f, draw_slider_optional_int);
|
||||
}
|
||||
|
||||
bool GLGizmoEmboss::rev_slider(const std::string &name,
|
||||
@@ -2614,9 +2662,8 @@ bool GLGizmoEmboss::rev_slider(const std::string &name,
|
||||
return m_imgui->slider_optional_float(("##" + name).c_str(), value,
|
||||
v_min, v_max, format.c_str(), 1.f, false, tooltip);
|
||||
};
|
||||
float undo_offset = ImGui::GetStyle().WindowPadding.x;
|
||||
return revertible(name, value, default_value,
|
||||
undo_tooltip, undo_offset, draw_slider_optional_float);
|
||||
undo_tooltip, 0.0f, draw_slider_optional_float);
|
||||
}
|
||||
|
||||
bool GLGizmoEmboss::rev_slider(const std::string &name,
|
||||
@@ -2636,9 +2683,8 @@ bool GLGizmoEmboss::rev_slider(const std::string &name,
|
||||
return m_imgui->slider_float("##" + name, &value, v_min, v_max,
|
||||
format.c_str(), 1.f, false, tooltip);
|
||||
};
|
||||
float undo_offset = ImGui::GetStyle().WindowPadding.x;
|
||||
return revertible(name, value, default_value,
|
||||
undo_tooltip, undo_offset, draw_slider_float);
|
||||
undo_tooltip, 0.0f, draw_slider_float);
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::draw_advanced()
|
||||
@@ -2668,6 +2714,8 @@ void GLGizmoEmboss::draw_advanced()
|
||||
m_imgui->text_colored(ImGuiWrapper::COL_GREY_DARK, ff_property);
|
||||
#endif // SHOW_FONT_FILE_PROPERTY
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
auto &tr = m_gui_cfg->translations;
|
||||
|
||||
const StyleManager::Style *stored_style = nullptr;
|
||||
@@ -2744,8 +2792,7 @@ void GLGizmoEmboss::draw_advanced()
|
||||
return is_change;
|
||||
};
|
||||
const FontProp::Align * def_align = stored_style ? &stored_style->prop.align : nullptr;
|
||||
float undo_offset = ImGui::GetStyle().WindowPadding.x;
|
||||
if (revertible(tr.alignment, font_prop.align, def_align, _u8L("Revert alignment."), undo_offset, draw_align)) {
|
||||
if (revertible(tr.alignment, font_prop.align, def_align, _u8L("Revert alignment."), 0.0f, draw_align)) {
|
||||
if (font_prop.per_glyph)
|
||||
reinit_text_lines(m_text_lines.get_lines().size());
|
||||
// TODO: move with text in finalize to not change position
|
||||
@@ -3641,7 +3688,7 @@ GuiCfg create_gui_configuration()
|
||||
ImGui::CalcTextSize(tr.font.c_str()).x,
|
||||
ImGui::CalcTextSize(tr.height.c_str()).x,
|
||||
ImGui::CalcTextSize(tr.depth.c_str()).x});
|
||||
cfg.indent = static_cast<float>(cfg.icon_width);
|
||||
cfg.indent = 20.0f;
|
||||
cfg.input_offset = style.WindowPadding.x + cfg.indent + max_text_width + space;
|
||||
|
||||
// TRN - Input label. Be short as possible
|
||||
@@ -3708,8 +3755,7 @@ GuiCfg create_gui_configuration()
|
||||
cfg.height_of_volume_type_selector = separator_height + line_height_with_spacing + input_height;
|
||||
|
||||
int max_style_image_width = static_cast<int>(std::round(cfg.max_style_name_width - 2 * style.FramePadding.x));
|
||||
int max_style_image_height = static_cast<int>(std::round(input_height));
|
||||
cfg.max_style_image_size = Vec2i32(max_style_image_width, line_height);
|
||||
cfg.max_style_image_size = Vec2i32(max_style_image_width, line_height_with_spacing);
|
||||
cfg.face_name_size = Vec2i32(cfg.input_width, line_height_with_spacing);
|
||||
cfg.face_name_texture_offset_x = cfg.face_name_size.x() + style.WindowPadding.x + space;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user