diff --git a/ImGuiToolkit.cpp b/ImGuiToolkit.cpp index 311d6b9..36fdaab 100644 --- a/ImGuiToolkit.cpp +++ b/ImGuiToolkit.cpp @@ -1677,22 +1677,47 @@ void word_wrap(std::string *str, unsigned per_line) } -struct InputTextCallback_UserData +void wrap(std::string *text, size_t per_line) { - std::string* Str; - int WordWrap; -}; + size_t line_begin = 0; + + while (line_begin < text->size()) + { + const size_t ideal_end = line_begin + per_line ; + size_t line_end = ideal_end <= text->size() ? ideal_end : text->size()-1; + + if (line_end == text->size() - 1) + ++line_end; + else if (std::isspace(text->at(line_end))) + { + text->replace(line_end, 1, 1, '\n'); + ++line_end; + } + else // backtrack + { + size_t end = line_end; + while ( end > line_begin && !std::isspace(text->at(end))) + --end; + + if (end != line_begin) + { + line_end = end; + text->replace(line_end++, 1, 1, '\n'); + } + else + text->insert(line_end++, 1, '\n'); + } + + line_begin = line_end; + } +} + static int InputTextCallback(ImGuiInputTextCallbackData* data) { - InputTextCallback_UserData* user_data = static_cast(data->UserData); + std::string* str = static_cast(data->UserData); if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) { -// if (user_data->WordWrap > 1) -// word_wrap(user_data->Str, user_data->WordWrap ); - - // Resize string callback - std::string* str = user_data->Str; IM_ASSERT(data->Buf == str->c_str()); str->resize(data->BufTextLen); data->Buf = (char*)str->c_str(); @@ -1704,24 +1729,20 @@ static int InputTextCallback(ImGuiInputTextCallbackData* data) bool ImGuiToolkit::InputText(const char* label, std::string* str) { ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackResize | ImGuiInputTextFlags_CharsNoBlank; - InputTextCallback_UserData cb_user_data; - cb_user_data.Str = str; - return ImGui::InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); + return ImGui::InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, str); } -bool ImGuiToolkit::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, int linesize) +bool ImGuiToolkit::InputTextMultiline(const char* label, std::string* str, const ImVec2& size) { ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackResize; - InputTextCallback_UserData cb_user_data; - cb_user_data.Str = str; - cb_user_data.WordWrap = linesize; - return ImGui::InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data); + ImGui::InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, str); + + return ImGui::IsItemDeactivatedAfterEdit(); } - -void ImGuiToolkit::ShowTextMultiline(const char* label, const std::string &str, float width) +void ImGuiToolkit::TextMultiline(const char* label, const std::string &str, float width) { size_t numlines = std::count(str.begin(), str.end(), '\n') + 1; @@ -1731,5 +1752,46 @@ void ImGuiToolkit::ShowTextMultiline(const char* label, const std::string &str, ImGui::PushStyleColor(ImGuiCol_FrameBg, g.Style.Colors[ImGuiCol_FrameBgHovered]); ImGui::InputTextMultiline(label, (char*)str.c_str(), str.capacity() + 1, size, ImGuiInputTextFlags_ReadOnly); ImGui::PopStyleColor(); - +} + + +bool ImGuiToolkit::InputCodeMultiline(const char* label, std::string* str, const ImVec2& size) +{ + bool ret = false; + char hiddenlabel[256]; + sprintf(hiddenlabel, "##%s", label); + + ImGuiToolkit::PushFont(FONT_MONO); + static ImVec2 onechar = ImGui::CalcTextSize("C"); + + // prepare input multiline + ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackResize | ImGuiInputTextFlags_CtrlEnterForNewLine; + + // Input text into std::string with callback + ImGui::InputTextMultiline(hiddenlabel, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, str); + if (ImGui::IsItemDeactivatedAfterEdit() ){ + wrap(str, (size_t) ceil(size.x / onechar.x) - 1); + ret = true; + } + + ImGui::PopFont(); + + // show label + ImGui::SameLine(); + ImGui::Text(label); + + return ret; +} + +void ImGuiToolkit::CodeMultiline(const char* label, const std::string &str, float width) +{ + char hiddenlabel[256]; + sprintf(hiddenlabel, "##%s", label); + + ImGuiToolkit::PushFont(FONT_MONO); + ImGuiToolkit::TextMultiline(hiddenlabel, str, width); + ImGui::PopFont(); + + ImGui::SameLine(); + ImGui::Text(label); } diff --git a/ImGuiToolkit.h b/ImGuiToolkit.h index 47edd3d..695186a 100644 --- a/ImGuiToolkit.h +++ b/ImGuiToolkit.h @@ -68,8 +68,11 @@ namespace ImGuiToolkit // text input bool InputText(const char* label, std::string* str); - bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), int linesize = 0); - void ShowTextMultiline(const char* label, const std::string &str, float width); + bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0)); + void TextMultiline(const char* label, const std::string &str, float width); + + bool InputCodeMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0)); + void CodeMultiline(const char* label, const std::string &str, float width); // accent color of UI typedef enum { diff --git a/ImGuiVisitor.cpp b/ImGuiVisitor.cpp index 9848010..907608d 100644 --- a/ImGuiVisitor.cpp +++ b/ImGuiVisitor.cpp @@ -899,10 +899,8 @@ void ImGuiVisitor::visit (GenericStreamSource& s) } // display pipeline text - std::string pipelinetxt = BaseToolkit::wrapped( s.description(), 30); - ImGuiToolkit::ShowTextMultiline("##pipeline", pipelinetxt, w); - ImGui::SameLine(0, IMGUI_SAME_LINE); - ImGui::Text("Pipeline"); + std::string pipelinetxt = BaseToolkit::wrapped( s.description(), 20); + ImGuiToolkit::CodeMultiline("Pipeline", pipelinetxt, w); // // TODO allow editing pipeline diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 043d42a..996aa33 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -3936,6 +3936,7 @@ void Navigator::clearButtonSelection() // clear new source pannel new_source_preview_.setSource(); pattern_type = -1; + custom_pipeline = false; sourceSequenceFiles.clear(); sourceMediaFileCurrent.clear(); new_media_mode_changed = true; @@ -4612,10 +4613,16 @@ void Navigator::RenderNewPannel() ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); if (ImGui::BeginCombo("##Pattern", "Select generator")) { + if ( ImGui::Selectable("Custom") ) { + update_new_source = true; + custom_pipeline = true; + pattern_type = -1; + } for (int p = 0; p < (int) Pattern::count(); ++p){ if (Pattern::get(p).available && ImGui::Selectable( Pattern::get(p).label.c_str() )) { - pattern_type = p; update_new_source = true; + custom_pipeline = false; + pattern_type = p; } } ImGui::EndCombo(); @@ -4625,25 +4632,42 @@ void Navigator::RenderNewPannel() ImGui::SameLine(); ImGuiToolkit::HelpMarker("Create a source with graphics generated algorithmically."); - // resolution (if pattern selected) - if (pattern_type > 0) { - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if (ImGui::Combo("Ratio", &Settings::application.source.ratio, - GlmToolkit::aspect_ratio_names, IM_ARRAYSIZE(GlmToolkit::aspect_ratio_names) ) ) - update_new_source = true; + if (custom_pipeline) { + static std::string description = "videotestsrc pattern=smpte"; + static ImVec2 fieldsize(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 100); + + size_t numlines = std::count(description.begin(), description.end(), '\n') + 1; + fieldsize.y = MAX( 100, numlines * ImGui::GetTextLineHeightWithSpacing() ); + + if ( ImGuiToolkit::InputCodeMultiline("Pipeline", &description, fieldsize) ) { - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if (ImGui::Combo("Height", &Settings::application.source.res, - GlmToolkit::height_names, IM_ARRAYSIZE(GlmToolkit::height_names) ) ) update_new_source = true; + } + + if (update_new_source) { + new_source_preview_.setSource( Mixer::manager().createSourceStream(description), description.substr(0, description.find(" "))); + } } + // if pattern selected + else { + // resolution + if (pattern_type >= 0) { + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + if (ImGui::Combo("Ratio", &Settings::application.source.ratio, + GlmToolkit::aspect_ratio_names, IM_ARRAYSIZE(GlmToolkit::aspect_ratio_names) ) ) + update_new_source = true; - // create preview - if (update_new_source) - { - glm::ivec2 res = GlmToolkit::resolutionFromDescription(Settings::application.source.ratio, Settings::application.source.res); - new_source_preview_.setSource( Mixer::manager().createSourcePattern(pattern_type, res), - Pattern::get(pattern_type).label); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + if (ImGui::Combo("Height", &Settings::application.source.res, + GlmToolkit::height_names, IM_ARRAYSIZE(GlmToolkit::height_names) ) ) + update_new_source = true; + } + // create preview + if (update_new_source) { + glm::ivec2 res = GlmToolkit::resolutionFromDescription(Settings::application.source.ratio, Settings::application.source.res); + new_source_preview_.setSource( Mixer::manager().createSourcePattern(pattern_type, res), + Pattern::get(pattern_type).label); + } } } // External source creator @@ -5820,8 +5844,8 @@ void ShowSandbox(bool* p_open) ImGui::Separator(); static Source *tmp = nullptr; - static char buf1[1280] = "videotestsrc pattern=smpte ! queue ! videoconvert"; -// static char buf1[1280] = "udpsrc port=5000 buffer-size=200000 ! h264parse ! avdec_h264"; +// static char buf1[1280] = "videotestsrc pattern=smpte ! queue ! videoconvert"; + static char buf1[1280] = "udpsrc port=5000 buffer-size=200000 ! h264parse ! avdec_h264"; // static char buf1[1280] = "srtsrc uri=\"srt://192.168.0.37:5000?mode=listener\" ! decodebin "; ImGui::InputText("gstreamer pipeline", buf1, 1280); if (ImGui::Button("Create Generic Stream Source") ) @@ -5841,6 +5865,18 @@ void ShowSandbox(bool* p_open) std::string tra = BaseToolkit::transliterate(std::string(str0)); ImGui::Text("Transliteration: '%s'", tra.c_str()); + + ImGui::Separator(); + + static std::string description = "A long string can always be wrapped into many pieces"; + + + if ( ImGuiToolkit::InputCodeMultiline("Wrapped", &description, ImVec2(ImGui::GetContentRegionAvail().x, 200))) { + + } + + ImGui::Text(description.c_str()); + ImGui::End(); } diff --git a/UserInterfaceManager.h b/UserInterfaceManager.h index aa07071..6318101 100644 --- a/UserInterfaceManager.h +++ b/UserInterfaceManager.h @@ -126,6 +126,7 @@ class Navigator bool view_pannel_visible; bool selected_button[NAV_COUNT]; int pattern_type; + bool custom_pipeline; void clearButtonSelection(); void applyButtonSelection(int index);