diff --git a/src/imgui/CMakeLists.txt b/src/imgui/CMakeLists.txt index 235afe1105..bc3b792eeb 100644 --- a/src/imgui/CMakeLists.txt +++ b/src/imgui/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(imgui STATIC imconfig.h imgui.h imgui_internal.h + imgui_stdlib.h imstb_rectpack.h imstb_textedit.h imstb_truetype.h @@ -13,4 +14,5 @@ add_library(imgui STATIC imgui_demo.cpp imgui_draw.cpp imgui_widgets.cpp + imgui_stdlib.cpp ) diff --git a/src/imgui/_CMakeLists.txt b/src/imgui/_CMakeLists.txt new file mode 100644 index 0000000000..59ab36d1c8 --- /dev/null +++ b/src/imgui/_CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 2.8.12) +project(imgui) + +add_library(imgui STATIC + imconfig.h + imgui.cpp + imgui.h + #imgui_demo.cpp + imgui_draw.cpp + imgui_internal.h + imgui_stdlib.cpp + imgui_stdlib.h + imgui_tables.cpp + imgui_widgets.cpp + imstb_rectpack.h + imstb_textedit.h + imstb_truetype.h +) diff --git a/src/imgui/imgui_stdlib.cpp b/src/imgui/imgui_stdlib.cpp new file mode 100644 index 0000000000..cb1fe1743d --- /dev/null +++ b/src/imgui/imgui_stdlib.cpp @@ -0,0 +1,76 @@ +// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) +// This is also an example of how you may wrap your own similar types. + +// Compatibility: +// - std::string support is only guaranteed to work from C++11. +// If you try to use it pre-C++11, please share your findings (w/ info about compiler/architecture) + +// Changelog: +// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string + +#include "imgui.h" +#include "imgui_stdlib.h" + +struct InputTextCallback_UserData +{ + std::string* Str; + ImGuiInputTextCallback ChainCallback; + void* ChainCallbackUserData; +}; + +static int InputTextCallback(ImGuiInputTextCallbackData* data) +{ + InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData; + if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) + { + // Resize string callback + // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want. + std::string* str = user_data->Str; + IM_ASSERT(data->Buf == str->c_str()); + str->resize(data->BufTextLen); + data->Buf = (char*)str->c_str(); + } + else if (user_data->ChainCallback) + { + // Forward to user callback, if any + data->UserData = user_data->ChainCallbackUserData; + return user_data->ChainCallback(data); + } + return 0; +} + +bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); +} + +bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data); +} + +bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); +} diff --git a/src/imgui/imgui_stdlib.h b/src/imgui/imgui_stdlib.h new file mode 100644 index 0000000000..f860b0c780 --- /dev/null +++ b/src/imgui/imgui_stdlib.h @@ -0,0 +1,22 @@ +// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) +// This is also an example of how you may wrap your own similar types. + +// Compatibility: +// - std::string support is only guaranteed to work from C++11. +// If you try to use it pre-C++11, please share your findings (w/ info about compiler/architecture) + +// Changelog: +// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string + +#pragma once + +#include + +namespace ImGui +{ + // ImGui::InputText() with std::string + // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity + IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); +} diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index a9c3b562f2..54f9fcae43 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -58,8 +58,6 @@ using namespace Slic3r::GUI; GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent) : GLGizmoBase(parent, M_ICON_FILENAME, -2) , m_font_selected(0) - , m_text_size(255) - , m_text(new char[m_text_size]) , m_volume(nullptr) , m_volume_type(ModelVolumeType::MODEL_PART) , m_is_initialized(false) // initialize on first opening gizmo @@ -226,7 +224,7 @@ bool GLGizmoEmboss::gizmo_event(SLAGizmoEventType action, } void GLGizmoEmboss::set_default_configuration() { - set_text(_u8L("Embossed text")); + m_text = _u8L("Embossed text"); m_font_prop = FontProp(); m_volume_type = ModelVolumeType::MODEL_PART; // may be set default font? @@ -285,7 +283,7 @@ ModelVolume *GLGizmoEmboss::get_selected_volume(const Selection &selection, bool GLGizmoEmboss::process() { if (!m_font.has_value()) return false; - Polygons polygons = Emboss::text2polygons(*m_font, m_text.get(), m_font_prop); + Polygons polygons = Emboss::text2polygons(*m_font, m_text.c_str(), m_font_prop); if (polygons.empty()) return false; float scale = m_font_prop.size_in_mm / m_font->ascent; @@ -404,6 +402,7 @@ void GLGizmoEmboss::draw_add_button() { } } +#include "imgui/imgui_stdlib.h" void GLGizmoEmboss::draw_window() { if (!m_font.has_value()) { @@ -468,16 +467,8 @@ void GLGizmoEmboss::draw_window() //|ImGuiInputTextFlags_::ImGuiInputTextFlags_CtrlEnterForNewLine ; - if (ImGui::InputTextMultiline("##Text", m_text.get(), m_text_size, - input_size, flags)) { - process(); - } - - // change text size - int max_text_size = static_cast(m_text_size); - if (ImGui::InputInt("max text size", &max_text_size, 8, 64)) { - set_max_text_size(static_cast(max_text_size)); - } + if (ImGui::InputTextMultiline("##Text", &m_text, input_size, flags)) + process(); // Option to create text volume when reselect volumes m_imgui->disabled_begin(!m_font.has_value()); @@ -550,29 +541,6 @@ bool GLGizmoEmboss::load_font() { return true; } -void GLGizmoEmboss::set_text(const std::string &text) { - if (text.size() > m_text_size-1) - set_max_text_size(text.size() + 1); - - int index = 0; - for (const char &c : text) m_text[index++] = c; - m_text[index] = '\0'; -} - -void GLGizmoEmboss::set_max_text_size(size_t size) { - if (size < 4) size = 4; - std::unique_ptr newData(new char[size]); - size_t index = 0; - while ((index + 1) < size) { - if (m_text.get()[index] == '\0') break; - newData.get()[index] = m_text.get()[index]; - ++index; - } - newData.get()[index] = '\0'; - m_text = std::move(newData); - m_text_size = size; -} - bool GLGizmoEmboss::choose_font_by_dialog() { // keep last selected font did not work // static wxFontData data; @@ -621,8 +589,7 @@ void GLGizmoEmboss::add_fonts(const FontList &font_list) { } TextConfiguration GLGizmoEmboss::create_configuration() { - std::string text((const char *) m_text.get()); - return TextConfiguration(m_font_list[m_font_selected], m_font_prop, text); + return TextConfiguration(m_font_list[m_font_selected], m_font_prop, m_text); } bool GLGizmoEmboss::load_configuration(ModelVolume *volume) @@ -654,7 +621,7 @@ bool GLGizmoEmboss::load_configuration(ModelVolume *volume) } m_font_prop = configuration.font_prop; - set_text(configuration.text); + m_text = configuration.text; m_volume_type = volume->type(); // not neccesary m_volume = volume; return true; @@ -662,11 +629,10 @@ bool GLGizmoEmboss::load_configuration(ModelVolume *volume) std::string GLGizmoEmboss::create_volume_name() { - size_t max_len = 20; - std::string text((const char *)m_text.get()); - if (text.size() > max_len) - text = text.substr(0, max_len - 3) + " .."; - return _u8L("Text") + " - " + text; + const size_t max_len = 20; + return _u8L("Text") + " - " + + ((m_text.size() > max_len)? + (m_text.substr(0, max_len - 3) + " ..") : m_text); } std::optional WxFontUtils::load_font(const FontItem &fi) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 01f93460c3..5f2f2d7dbe 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -49,11 +49,10 @@ private: void draw_window(); void draw_font_list(); void draw_add_button(); + bool load_font(); // try to set font_index bool load_font(size_t font_index); - void set_text(const std::string &text); - void set_max_text_size(size_t size); bool choose_font_by_dialog(); @@ -81,8 +80,7 @@ private: std::optional m_font; - size_t m_text_size; - std::unique_ptr m_text; + std::string m_text; FontProp m_font_prop; @@ -102,6 +100,7 @@ private: // Only for new created volume ModelVolumeType m_volume_type; + // initialize when GL is accessible bool m_is_initialized; // only temporary solution