diff --git a/resources/icons/edit_button_pressed.svg b/resources/icons/edit_button_pressed.svg
new file mode 100644
index 000000000..6e4058d10
--- /dev/null
+++ b/resources/icons/edit_button_pressed.svg
@@ -0,0 +1,91 @@
+
+
+
+
diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h
index 27f5242a8..db0e54e60 100644
--- a/src/imgui/imconfig.h
+++ b/src/imgui/imconfig.h
@@ -155,17 +155,18 @@ namespace ImGui
const wchar_t ClippyMarker = 0x2602;
const wchar_t InfoMarker = 0x2603;
const wchar_t SliderFloatEditBtnIcon = 0x2604;
- const wchar_t LegendTravel = 0x2605;
- const wchar_t LegendWipe = 0x2606;
- const wchar_t LegendRetract = 0x2607;
- const wchar_t LegendDeretract = 0x2608;
- const wchar_t LegendSeams = 0x2609;
- const wchar_t LegendToolChanges = 0x2610;
- const wchar_t LegendColorChanges = 0x2611;
- const wchar_t LegendPausePrints = 0x2612;
- const wchar_t LegendCustomGCodes = 0x2613;
- const wchar_t LegendShells = 0x2614;
- const wchar_t LegendToolMarker = 0x2615;
+ const wchar_t SliderFloatEditBtnPressedIcon = 0x2605;
+ const wchar_t LegendTravel = 0x2606;
+ const wchar_t LegendWipe = 0x2607;
+ const wchar_t LegendRetract = 0x2608;
+ const wchar_t LegendDeretract = 0x2609;
+ const wchar_t LegendSeams = 0x2610;
+ const wchar_t LegendToolChanges = 0x2611;
+ const wchar_t LegendColorChanges = 0x2612;
+ const wchar_t LegendPausePrints = 0x2613;
+ const wchar_t LegendCustomGCodes = 0x2614;
+ const wchar_t LegendShells = 0x2615;
+ const wchar_t LegendToolMarker = 0x2616;
// void MyFunction(const char* name, const MyMatrix44& v);
}
diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp
index b4b37de83..00218af96 100644
--- a/src/slic3r/GUI/ImGuiWrapper.cpp
+++ b/src/slic3r/GUI/ImGuiWrapper.cpp
@@ -51,23 +51,24 @@ static const std::map font_icons = {
{ImGui::MinimalizeHoverButton , "notification_minimalize_hover" },
{ImGui::RightArrowButton , "notification_right" },
{ImGui::RightArrowHoverButton , "notification_right_hover" },
- {ImGui::PreferencesButton , "notification_preferences" },
- {ImGui::PreferencesHoverButton , "notification_preferences_hover"},
+ {ImGui::PreferencesButton , "notification_preferences" },
+ {ImGui::PreferencesHoverButton, "notification_preferences_hover"},
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
- {ImGui::SliderFloatEditBtnIcon , "edit_button" },
+ {ImGui::SliderFloatEditBtnIcon, "edit_button" },
+ {ImGui::SliderFloatEditBtnPressedIcon, "edit_button_pressed" },
#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
#if ENABLE_LEGEND_TOOLBAR_ICONS
- {ImGui::LegendTravel , "legend_travel" },
- {ImGui::LegendWipe , "legend_wipe" },
- {ImGui::LegendRetract , "legend_retract" },
- {ImGui::LegendDeretract , "legend_deretract" },
- {ImGui::LegendSeams , "legend_seams" },
- {ImGui::LegendToolChanges , "legend_toolchanges" },
- {ImGui::LegendColorChanges , "legend_colorchanges" },
- {ImGui::LegendPausePrints , "legend_pauseprints" },
- {ImGui::LegendCustomGCodes , "legend_customgcodes" },
- {ImGui::LegendShells , "legend_shells" },
- {ImGui::LegendToolMarker , "legend_toolmarker" },
+ {ImGui::LegendTravel , "legend_travel" },
+ {ImGui::LegendWipe , "legend_wipe" },
+ {ImGui::LegendRetract , "legend_retract" },
+ {ImGui::LegendDeretract , "legend_deretract" },
+ {ImGui::LegendSeams , "legend_seams" },
+ {ImGui::LegendToolChanges , "legend_toolchanges" },
+ {ImGui::LegendColorChanges , "legend_colorchanges" },
+ {ImGui::LegendPausePrints , "legend_pauseprints" },
+ {ImGui::LegendCustomGCodes , "legend_customgcodes" },
+ {ImGui::LegendShells , "legend_shells" },
+ {ImGui::LegendToolMarker , "legend_toolmarker" },
#endif // ENABLE_LEGEND_TOOLBAR_ICONS
};
static const std::map font_icons_large = {
@@ -423,11 +424,6 @@ bool ImGuiWrapper::draw_radio_button(const std::string& name, float size, bool a
}
#endif // ENABLE_PREVIEW_LAYOUT
-bool ImGuiWrapper::image_button()
-{
- return false;
-}
-
bool ImGuiWrapper::input_double(const std::string &label, const double &value, const std::string &format)
{
return ImGui::InputDouble(label.c_str(), const_cast(&value), 0.0f, 0.0f, format.c_str(), ImGuiInputTextFlags_CharsDecimal);
@@ -551,6 +547,9 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float
ImGui::SameLine();
}
+ // the current slider edit state needs to be detected here before calling SliderFloat()
+ bool slider_editing = ImGui::GetCurrentWindow()->GetID(str_label.c_str()) == ImGui::GetActiveID();
+
bool ret = ImGui::SliderFloat(str_label.c_str(), v, v_min, v_max, format, power);
if (!tooltip.empty() && ImGui::IsItemHovered())
this->tooltip(into_u8(tooltip).c_str(), max_tooltip_width);
@@ -562,15 +561,31 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float
const ImGuiStyle& style = ImGui::GetStyle();
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 1, style.ItemSpacing.y });
ImGui::SameLine();
- std::wstring btn_name = ImGui::SliderFloatEditBtnIcon + boost::nowide::widen(str_label);
+ ImGuiIO& io = ImGui::GetIO();
+ assert(io.Fonts->TexWidth > 0 && io.Fonts->TexHeight > 0);
+ float inv_tex_w = 1.0f / float(io.Fonts->TexWidth);
+ float inv_tex_h = 1.0f / float(io.Fonts->TexHeight);
+
+ const ImFontAtlasCustomRect* const rect = GetTextureCustomRect(slider_editing ? ImGui::SliderFloatEditBtnPressedIcon : ImGui::SliderFloatEditBtnIcon);
+ const ImVec2 size = { float(rect->Width), float(rect->Height) };
+ const ImVec2 uv0 = ImVec2(float(rect->X) * inv_tex_w, float(rect->Y) * inv_tex_h);
+ const ImVec2 uv1 = ImVec2(float(rect->X + rect->Width) * inv_tex_w, float(rect->Y + rect->Height) * inv_tex_h);
+
ImGui::PushStyleColor(ImGuiCol_Button, { 0.25f, 0.25f, 0.25f, 0.0f });
- ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.5f, 0.5f, 0.5f, 1.0f });
- ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.5f, 0.5f, 0.5f, 1.0f });
- if (ImGui::Button(into_u8(btn_name).c_str())) {
- ImGui::SetKeyboardFocusHere(-1);
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.4f, 0.4f, 0.4f, 1.0f });
+ ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.4f, 0.4f, 0.4f, 1.0f });
+
+ const ImTextureID tex_id = io.Fonts->TexID;
+ if (image_button(tex_id, size, uv0, uv1, -1, ImVec4(0.0, 0.0, 0.0, 0.0), ImVec4(1.0, 1.0, 1.0, 1.0), ImGuiButtonFlags_PressedOnClick)) {
+ if (!slider_editing)
+ ImGui::SetKeyboardFocusHere(-1);
+ else
+ ImGui::ClearActiveID();
this->set_requires_extra_frame();
}
+
ImGui::PopStyleColor(3);
+
if (ImGui::IsItemHovered())
this->tooltip(into_u8(_L("Edit")).c_str(), max_tooltip_width);
@@ -590,6 +605,48 @@ bool ImGuiWrapper::slider_float(const wxString& label, float* v, float v_min, fl
auto label_utf8 = into_u8(label);
return this->slider_float(label_utf8.c_str(), v, v_min, v_max, format, power, clamp, tooltip, show_edit_btn);
}
+
+static bool image_button_ex(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags)
+{
+ ImGuiContext& g = *GImGui;
+ ImGuiWindow* window = ImGui::GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
+
+ const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2);
+ ImGui::ItemSize(bb);
+ if (!ImGui::ItemAdd(bb, id))
+ return false;
+
+ bool hovered, held;
+ bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, flags);
+
+ // Render
+ const ImU32 col = ImGui::GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
+ ImGui::RenderNavHighlight(bb, id);
+ ImGui::RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding));
+ if (bg_col.w > 0.0f)
+ window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, ImGui::GetColorU32(bg_col));
+ window->DrawList->AddImage(texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, ImGui::GetColorU32(tint_col));
+
+ return pressed;
+}
+
+bool ImGuiWrapper::image_button(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags)
+{
+ ImGuiContext& g = *GImGui;
+ ImGuiWindow* window = g.CurrentWindow;
+ if (window->SkipItems)
+ return false;
+
+ // Default to using texture ID as ID. User can still push string/integer prefixes.
+ ImGui::PushID((void*)(intptr_t)user_texture_id);
+ const ImGuiID id = window->GetID("#image");
+ ImGui::PopID();
+
+ const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding;
+ return image_button_ex(id, user_texture_id, size, uv0, uv1, padding, bg_col, tint_col, flags);
+}
#else
bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float v_max, const char* format/* = "%.3f"*/, float power/* = 1.0f*/, bool clamp /*= true*/)
{
diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp
index a4e25415c..a1ecc6712 100644
--- a/src/slic3r/GUI/ImGuiWrapper.hpp
+++ b/src/slic3r/GUI/ImGuiWrapper.hpp
@@ -86,7 +86,6 @@ public:
#if ENABLE_PREVIEW_LAYOUT
bool draw_radio_button(const std::string& name, float size, bool active, std::function draw_callback);
#endif // ENABLE_PREVIEW_LAYOUT
- bool image_button();
bool input_double(const std::string &label, const double &value, const std::string &format = "%.3f");
bool input_double(const wxString &label, const double &value, const std::string &format = "%.3f");
bool input_vec3(const std::string &label, const Vec3d &value, float width, const std::string &format = "%.3f");
@@ -109,6 +108,8 @@ public:
bool slider_float(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true);
bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true);
bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true);
+
+ bool image_button(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0.0, 0.0), const ImVec2& uv1 = ImVec2(1.0, 1.0), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0.0, 0.0, 0.0, 0.0), const ImVec4& tint_col = ImVec4(1.0, 1.0, 1.0, 1.0), ImGuiButtonFlags flags = 0);
#else
bool slider_float(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true);
bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true);