diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index a98c7a62fb..12018ac47e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -90,7 +90,9 @@ void GLGizmoEmboss::set_fine_position() Polygon hull = CameraUtils::create_hull2d(camera, *volume); const ImVec2 &windows_size = get_minimal_window_size(); - ImVec2 offset = ImGuiWrapper::suggest_location(windows_size, hull); + Size c_size = m_parent.get_canvas_size(); + ImVec2 canvas_size(c_size.get_width(), c_size.get_height()); + ImVec2 offset = ImGuiWrapper::suggest_location(windows_size, hull, canvas_size); m_set_window_offset = offset; return; @@ -116,7 +118,9 @@ static void draw_fine_position(const Selection &selection) Slic3r::Polygon hull = CameraUtils::create_hull2d(camera, *volume); ImVec2 windows_size(174, 202); - ImVec2 offset = ImGuiWrapper::suggest_location(windows_size, hull); + Size c_size = m_parent.get_canvas_size(); + ImVec2 canvas_size(c_size.get_width(), c_size.get_height()); + ImVec2 offset = ImGuiWrapper::suggest_location(windows_size, hull,canvas_size); Slic3r::Polygon rect( {Point(offset.x, offset.y), Point(offset.x + windows_size.x, offset.y), Point(offset.x + windows_size.x, offset.y + windows_size.y), diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index b28736f034..dbac75ba54 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -37,10 +37,7 @@ #include "nanosvg/nanosvgrast.h" // suggest location -#include "slic3r/GUI/GLCanvas3D.hpp" -#include "slic3r/GUI/Plater.hpp" -#include "slic3r/GUI/GUI_App.hpp" -#include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/ClipperUtils.hpp" // Slic3r::intersection namespace Slic3r { namespace GUI { @@ -1185,7 +1182,7 @@ ColorRGBA ImGuiWrapper::from_ImVec4(const ImVec4& color) } template -static bool input_optional(std::optional &v, Func& f, std::function is_default) +static bool input_optional(std::optional &v, Func& f, std::function is_default, const T& def_val) { if (v.has_value()) { if (f(*v)) { @@ -1193,7 +1190,7 @@ static bool input_optional(std::optional &v, Func& f, std::function& v, int step, int step_fast, - ImGuiInputTextFlags flags) + ImGuiInputTextFlags flags, + int def_val) { auto func = [&](int &value) { return ImGui::InputInt(label, &value, step, step_fast, flags); }; std::function is_default = - [](const int &value) -> bool { return value == 0; }; - return input_optional(v, func, is_default); + [def_val](const int &value) -> bool { return value == def_val; }; + return input_optional(v, func, is_default, def_val); } bool ImGuiWrapper::input_optional_float(const char * label, @@ -1221,16 +1219,17 @@ bool ImGuiWrapper::input_optional_float(const char * label, float step, float step_fast, const char * format, - ImGuiInputTextFlags flags) + ImGuiInputTextFlags flags, + float def_val) { auto func = [&](float &value) { return ImGui::InputFloat(label, &value, step, step_fast, format, flags); }; std::function is_default = - [](const float &value) -> bool { - return std::fabs(value) < std::numeric_limits::epsilon(); + [def_val](const float &value) -> bool { + return std::fabs(value-def_val) <= std::numeric_limits::epsilon(); }; - return input_optional(v, func, is_default); + return input_optional(v, func, is_default, def_val); } bool ImGuiWrapper::drag_optional_float(const char * label, @@ -1239,47 +1238,50 @@ bool ImGuiWrapper::drag_optional_float(const char * label, float v_min, float v_max, const char * format, - float power) + float power, + float def_val) { auto func = [&](float &value) { return ImGui::DragFloat(label, &value, v_speed, v_min, v_max, format, power); }; std::function is_default = - [](const float &value) -> bool { - return std::fabs(value) < std::numeric_limits::epsilon(); + [def_val](const float &value) -> bool { + return std::fabs(value-def_val) <= std::numeric_limits::epsilon(); }; - return input_optional(v, func, is_default); + return input_optional(v, func, is_default, def_val); } -bool ImGuiWrapper::slider_optional_float(const char * label, +bool ImGuiWrapper::slider_optional_float(const char *label, std::optional &v, float v_min, float v_max, - const char * format, + const char *format, float power, bool clamp, - const wxString & tooltip, - bool show_edit_btn) + const wxString &tooltip, + bool show_edit_btn, + float def_val) { auto func = [&](float &value) { return slider_float(label, &value, v_min, v_max, format, power, clamp, tooltip, show_edit_btn); }; std::function is_default = - [](const float &value) -> bool { - return std::fabs(value) < std::numeric_limits::epsilon(); + [def_val](const float &value) -> bool { + return std::fabs(value - def_val) <= std::numeric_limits::epsilon(); }; - return input_optional(v, func, is_default); + return input_optional(v, func, is_default, def_val); } -bool ImGuiWrapper::slider_optional_int(const char * label, +bool ImGuiWrapper::slider_optional_int(const char *label, std::optional &v, int v_min, int v_max, - const char * format, + const char *format, float power, bool clamp, - const wxString & tooltip, - bool show_edit_btn) + const wxString &tooltip, + bool show_edit_btn, + int def_val) { std::optional val; if (v.has_value()) val = static_cast(*v); @@ -1287,11 +1289,12 @@ bool ImGuiWrapper::slider_optional_int(const char * label, return slider_float(label, &value, v_min, v_max, format, power, clamp, tooltip, show_edit_btn); }; std::function is_default = - [](const float &value) -> bool { - return std::fabs(value) < 0.9f; + [def_val](const float &value) -> bool { + return std::fabs(value - def_val) < 0.9f; }; - if (input_optional(val, func, is_default)) { + float default_value = static_cast(def_val); + if (input_optional(val, func, is_default, default_value)) { if (val.has_value()) v = static_cast(std::round(*val)); else @@ -1339,11 +1342,9 @@ std::string ImGuiWrapper::trunc(const std::string &text, } ImVec2 ImGuiWrapper::suggest_location(const ImVec2 &dialog_size, - const Slic3r::Polygon &interest) -{ - Plater * plater = wxGetApp().plater(); - GLCanvas3D *canvas = plater->get_current_canvas3D(); - + const Slic3r::Polygon &interest, + const ImVec2 &canvas_size) +{ // IMPROVE 1: do not select place over menu // BoundingBox top_menu; // GLGizmosManager &gizmo_mng = canvas->get_gizmos_manager(); @@ -1358,8 +1359,7 @@ ImVec2 ImGuiWrapper::suggest_location(const ImVec2 &dialog_size, Point center = bb.center(); // interest.centroid(); // area size - Size size = canvas->get_canvas_size(); - Point window_center(size.get_width() / 2, size.get_height() / 2); + Point window_center(canvas_size.x / 2, canvas_size.y / 2); // mov on side Point bb_half_size = (bb.max - bb.min) / 2 + Point(1,1); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 28851ec71a..cee192ec38 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -135,14 +135,19 @@ public: bool want_text_input() const; bool want_any_input() const; - // Input [optional] int for nonzero value more info in ImGui::InputInt - static bool input_optional_int(const char *label, std::optional& v, int step=1, int step_fast=100, ImGuiInputTextFlags flags=0); - // Input [optional] float for nonzero value more info in ImGui::InputFloat - static bool input_optional_float(const char* label, std::optional &v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0); - static bool drag_optional_float(const char* label, std::optional &v, float v_speed, float v_min, float v_max, const char* format, float power); - - bool slider_optional_float(const char* label, std::optional &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_optional_int(const char* label, std::optional &v, int v_min, int v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true); + // Optional inputs are used for set up value inside of an optional, with default value + // + // Extended function ImGui::InputInt to work with std::optional, when value == def_val optional is released. + static bool input_optional_int(const char *label, std::optional& v, int step=1, int step_fast=100, ImGuiInputTextFlags flags=0, int def_val = 0); + // Extended function ImGui::InputFloat to work with std::optional value near def_val cause release of optional + static bool input_optional_float(const char* label, std::optional &v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0, float def_val = .0f); + // Extended function ImGui::DragFloat to work with std::optional value near def_val cause release of optional + static bool drag_optional_float(const char* label, std::optional &v, float v_speed, float v_min, float v_max, const char* format, float power, float def_val = .0f); + // Extended function ImGuiWrapper::slider_float to work with std::optional value near def_val cause release of optional + bool slider_optional_float(const char* label, std::optional &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, float def_val = .0f); + // Extended function ImGuiWrapper::slider_float to work with std::optional, when value == def_val than optional release its value + bool slider_optional_int(const char* label, std::optional &v, int v_min, int v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true, int def_val = 0); + /// /// Truncate text by ImGui draw function to specific width /// NOTE 1: ImGui must be initialized @@ -164,10 +169,12 @@ public: /// And also not out of visible area. /// /// Define width and height of diaog window - /// Area of interest. Result should be close to it + /// Area of interest. Result should be close to it + /// Available space a.k.a GLCanvas3D::get_current_canvas3D() /// Suggestion for dialog offest - static ImVec2 suggest_location(const ImVec2 & dialog_size, - const Slic3r::Polygon &interest); + static ImVec2 suggest_location(const ImVec2 &dialog_size, + const Slic3r::Polygon &interest, + const ImVec2 &canvas_size); /// /// Visualization of polygon