diff --git a/Editor/App_Windows.cpp b/Editor/App_Windows.cpp index 1b2e34efb..526626e7e 100644 --- a/Editor/App_Windows.cpp +++ b/Editor/App_Windows.cpp @@ -250,14 +250,10 @@ protected: if (c == '\b') { - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); } else { - if (wi::backlog::isActive()) - wi::backlog::input(c); wi::gui::TextInputField::AddInput(c); } diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 3fd7b9950..27f4dc0c1 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -54,7 +54,6 @@ void EditorLoadingScreen::Load() font.anim.typewriter.character_start = 7; AddFont(&font); - sprite.textureResource.SetTexture(*wi::texturehelper::getLogo()); // use embedded asset sprite.anim.opa = 1; sprite.anim.repeatable = true; sprite.params.siz = XMFLOAT2(128, 128); @@ -72,6 +71,7 @@ void EditorLoadingScreen::Update(float dt) font.params.posX = GetLogicalWidth()*0.5f - font.TextWidth() * 0.5f; font.params.posY = GetLogicalHeight()*0.5f; sprite.params.pos = XMFLOAT3(GetLogicalWidth()*0.5f, GetLogicalHeight()*0.5f - font.TextHeight(), 0); + sprite.textureResource.SetTexture(*wi::texturehelper::getLogo()); // use embedded asset LoadingScreen::Update(dt); } diff --git a/Editor/OptionsWindow.cpp b/Editor/OptionsWindow.cpp index 188b71c59..5669dbd5b 100644 --- a/Editor/OptionsWindow.cpp +++ b/Editor/OptionsWindow.cpp @@ -580,6 +580,9 @@ void OptionsWindow::Create(EditorComponent* _editor) gui.SetColor(theme_color_deactivating, wi::gui::DEACTIVATING); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.7f), wi::gui::WIDGET_ID_WINDOW_BASE); + gui.SetColor(theme_color_focus, wi::gui::WIDGET_ID_TEXTINPUTFIELD_ACTIVE); + gui.SetColor(theme_color_focus, wi::gui::WIDGET_ID_TEXTINPUTFIELD_DEACTIVATING); + gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.75f), wi::gui::WIDGET_ID_SLIDER_BASE_IDLE); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.8f), wi::gui::WIDGET_ID_SLIDER_BASE_FOCUS); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.85f), wi::gui::WIDGET_ID_SLIDER_BASE_ACTIVE); diff --git a/Editor/main_SDL2.cpp b/Editor/main_SDL2.cpp index 32643227f..aeba989e9 100644 --- a/Editor/main_SDL2.cpp +++ b/Editor/main_SDL2.cpp @@ -60,8 +60,6 @@ int sdl_loop(Editor &editor) if(event.key.keysym.scancode == SDL_SCANCODE_BACKSPACE || event.key.keysym.scancode == SDL_SCANCODE_DELETE || event.key.keysym.scancode == SDL_SCANCODE_KP_BACKSPACE){ - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); textinput_action_delete = true; } @@ -69,8 +67,6 @@ int sdl_loop(Editor &editor) case SDL_TEXTINPUT: if(!textinput_action_delete){ if(event.text.text[0] >= 21){ - if (wi::backlog::isActive()) - wi::backlog::input(event.text.text[0]); wi::gui::TextInputField::AddInput(event.text.text[0]); } } diff --git a/Editor/main_Windows.cpp b/Editor/main_Windows.cpp index 8333a6d0e..c318d98c4 100644 --- a/Editor/main_Windows.cpp +++ b/Editor/main_Windows.cpp @@ -224,8 +224,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (wParam) { case VK_BACK: - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); break; case VK_RETURN: @@ -233,10 +231,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) default: { const char c = (const char)(TCHAR)wParam; - if (wi::backlog::isActive()) - { - wi::backlog::input(c); - } wi::gui::TextInputField::AddInput(c); } break; diff --git a/Example_ImGui/main_Windows.cpp b/Example_ImGui/main_Windows.cpp index beefdf0f8..98ea27095 100644 --- a/Example_ImGui/main_Windows.cpp +++ b/Example_ImGui/main_Windows.cpp @@ -169,8 +169,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (wParam) { case VK_BACK: - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); break; case VK_RETURN: @@ -178,10 +176,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) default: { const char c = (const char)(TCHAR)wParam; - if (wi::backlog::isActive()) - { - wi::backlog::input(c); - } wi::gui::TextInputField::AddInput(c); } break; diff --git a/Example_ImGui_Docking/main_Windows.cpp b/Example_ImGui_Docking/main_Windows.cpp index fad6fdad4..08b6a6046 100644 --- a/Example_ImGui_Docking/main_Windows.cpp +++ b/Example_ImGui_Docking/main_Windows.cpp @@ -177,8 +177,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (wParam) { case VK_BACK: - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); break; case VK_RETURN: @@ -186,10 +184,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) default: { const char c = (const char)(TCHAR)wParam; - if (wi::backlog::isActive()) - { - wi::backlog::input(c); - } wi::gui::TextInputField::AddInput(c); } break; diff --git a/Template_UWP/Main.cpp b/Template_UWP/Main.cpp index cd85659eb..3f1be9206 100644 --- a/Template_UWP/Main.cpp +++ b/Template_UWP/Main.cpp @@ -166,14 +166,10 @@ protected: if (c == '\b') { - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); } else { - if (wi::backlog::isActive()) - wi::backlog::input(c); wi::gui::TextInputField::AddInput(c); } diff --git a/Template_Windows/main.cpp b/Template_Windows/main.cpp index 5f119bb9a..c61d640d8 100644 --- a/Template_Windows/main.cpp +++ b/Template_Windows/main.cpp @@ -169,8 +169,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (wParam) { case VK_BACK: - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); break; case VK_RETURN: diff --git a/Tests/main_Windows.cpp b/Tests/main_Windows.cpp index 508b7d62c..558295ef2 100644 --- a/Tests/main_Windows.cpp +++ b/Tests/main_Windows.cpp @@ -162,8 +162,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (wParam) { case VK_BACK: - if (wi::backlog::isActive()) - wi::backlog::deletefromInput(); wi::gui::TextInputField::DeleteFromInput(); break; case VK_RETURN: @@ -171,10 +169,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) default: { const char c = (const char)(TCHAR)wParam; - if (wi::backlog::isActive()) - { - wi::backlog::input(c); - } wi::gui::TextInputField::AddInput(c); } break; diff --git a/WickedEngine.sln b/WickedEngine.sln index 2b20ee085..bd0b0a4ca 100644 --- a/WickedEngine.sln +++ b/WickedEngine.sln @@ -26,9 +26,6 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WickedEngine_Windows", "WickedEngine\WickedEngine_Windows.vcxproj", "{06163DCB-B183-4ED9-9C62-13EF1658E049}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WickedEngine_UWP", "WickedEngine\WickedEngine_UWP.vcxproj", "{60DA258F-E95F-4CF4-A46B-17D80644464B}" - ProjectSection(ProjectDependencies) = postProject - {3B74A7FE-CED7-4723-8824-AC708A865B98} = {3B74A7FE-CED7-4723-8824-AC708A865B98} - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Supplementary", "Supplementary", "{BF8FCAB8-D7D3-4DAE-92DE-4B5037E9A0ED}" ProjectSection(SolutionItems) = preProject @@ -62,6 +59,17 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example_ImGui_Docking", "Example_ImGui_Docking\Example_ImGui_Docking.vcxproj", "{5646F9FB-C9E3-4DA4-8AAA-EB7A46DD777E}" EndProject Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + WickedEngine\WickedEngine_SOURCE.vcxitems*{06163dcb-b183-4ed9-9c62-13ef1658e049}*SharedItemsImports = 4 + WickedEngine\WickedEngine_SOURCE.vcxitems*{45d41acc-2c3c-43d2-bc10-02aa73ffc7c7}*SharedItemsImports = 9 + Editor\Editor_SOURCE.vcxitems*{5fe97b9b-a445-4eea-a42d-9de60b891d48}*SharedItemsImports = 4 + WickedEngine\WickedEngine_SOURCE.vcxitems*{60da258f-e95f-4cf4-a46b-17d80644464b}*SharedItemsImports = 4 + Editor\Editor_SOURCE.vcxitems*{867febca-09c4-4fe7-8a4c-4d9b1c27e7d0}*SharedItemsImports = 9 + WickedEngine\shaders\Shaders_SOURCE.vcxitems*{92e86448-0724-4387-abac-96e63edf4190}*SharedItemsImports = 9 + Content\Content.vcxitems*{c48f6bff-f91b-4db5-98b5-15287dfb7c95}*SharedItemsImports = 9 + Content\Content.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 + Editor\Editor_SOURCE.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Release|x64 = Release|x64 @@ -122,15 +130,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E3FF044A-B72E-4ED5-BE05-AB641BA048CD} EndGlobalSection - GlobalSection(SharedMSBuildProjectFiles) = preSolution - WickedEngine\WickedEngine_SOURCE.vcxitems*{06163dcb-b183-4ed9-9c62-13ef1658e049}*SharedItemsImports = 4 - WickedEngine\WickedEngine_SOURCE.vcxitems*{45d41acc-2c3c-43d2-bc10-02aa73ffc7c7}*SharedItemsImports = 9 - Editor\Editor_SOURCE.vcxitems*{5fe97b9b-a445-4eea-a42d-9de60b891d48}*SharedItemsImports = 4 - WickedEngine\WickedEngine_SOURCE.vcxitems*{60da258f-e95f-4cf4-a46b-17d80644464b}*SharedItemsImports = 4 - Editor\Editor_SOURCE.vcxitems*{867febca-09c4-4fe7-8a4c-4d9b1c27e7d0}*SharedItemsImports = 9 - WickedEngine\shaders\Shaders_SOURCE.vcxitems*{92e86448-0724-4387-abac-96e63edf4190}*SharedItemsImports = 9 - Content\Content.vcxitems*{c48f6bff-f91b-4db5-98b5-15287dfb7c95}*SharedItemsImports = 9 - Content\Content.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 - Editor\Editor_SOURCE.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 - EndGlobalSection EndGlobal diff --git a/WickedEngine/wiBacklog.cpp b/WickedEngine/wiBacklog.cpp index 73d1dc277..79cdcaffd 100644 --- a/WickedEngine/wiBacklog.cpp +++ b/WickedEngine/wiBacklog.cpp @@ -10,6 +10,7 @@ #include "wiInput.h" #include "wiPlatform.h" #include "wiHelper.h" +#include "wiGUI.h" #include #include @@ -33,12 +34,13 @@ namespace wi::backlog const size_t deletefromline = 500; float pos = 5; float scroll = 0; - std::string inputArea; int historyPos = 0; wi::font::Params font_params; wi::SpinLock logLock; Texture backgroundTex; bool refitscroll = false; + wi::gui::TextInputField inputField; + wi::gui::Button toggleButton; bool locked = false; bool blockLuaExec = false; @@ -97,10 +99,6 @@ namespace wi::backlog { historyNext(); } - if (wi::input::Press(wi::input::KEYBOARD_BUTTON_ENTER)) - { - acceptInput(); - } if (wi::input::Down(wi::input::KEYBOARD_BUTTON_PAGEUP)) { Scroll(1000.0f * dt); @@ -109,6 +107,74 @@ namespace wi::backlog { Scroll(-1000.0f * dt); } + + static bool created = false; + if (!created) + { + created = true; + inputField.Create(""); + inputField.OnInputAccepted([](wi::gui::EventArgs args) { + historyPos = 0; + post(args.sValue); + LogEntry entry; + entry.text = args.sValue; + entry.level = LogLevel::Default; + history.push_back(entry); + if (history.size() > deletefromline) + { + history.pop_front(); + } + if (!blockLuaExec) + { + wi::lua::RunText(args.sValue); + } + else + { + post("Lua execution is disabled", LogLevel::Error); + } + inputField.SetText(""); + }); + wi::Color theme_color_idle = wi::Color(30, 40, 60, 200); + wi::Color theme_color_focus = wi::Color(70, 150, 170, 220); + wi::Color theme_color_active = wi::Color::White(); + wi::Color theme_color_deactivating = wi::Color::lerp(theme_color_focus, wi::Color::White(), 0.5f); + inputField.SetColor(theme_color_idle); // all states the same, it's gonna be always active anyway + inputField.SetShadowRadius(5); + inputField.SetShadowColor(wi::Color(80, 140, 180, 100)); + inputField.font.params.color = wi::Color(160, 240, 250, 255); + inputField.font.params.shadowColor = wi::Color::Transparent(); + + toggleButton.Create("V"); + toggleButton.OnClick([](wi::gui::EventArgs args) { + Toggle(); + }); + toggleButton.SetColor(theme_color_idle, wi::gui::IDLE); + toggleButton.SetColor(theme_color_focus, wi::gui::FOCUS); + toggleButton.SetColor(theme_color_active, wi::gui::ACTIVE); + toggleButton.SetColor(theme_color_deactivating, wi::gui::DEACTIVATING); + toggleButton.SetShadowRadius(5); + toggleButton.SetShadowColor(wi::Color(80, 140, 180, 100)); + toggleButton.font.params.color = wi::Color(160, 240, 250, 255); + toggleButton.font.params.rotation = XM_PI; + toggleButton.font.params.size = 24; + toggleButton.font.params.scaling = 3; + toggleButton.font.params.shadowColor = wi::Color::Transparent(); + } + inputField.SetSize(XMFLOAT2(canvas.GetLogicalWidth() - 20, 20)); + inputField.SetPos(XMFLOAT2(10, canvas.GetLogicalHeight() - 30)); + if (inputField.GetState() != wi::gui::ACTIVE) + { + inputField.SetAsActive(); + } + inputField.Update(canvas, dt); + + toggleButton.SetSize(XMFLOAT2(100, 100)); + toggleButton.SetPos(XMFLOAT2(canvas.GetLogicalWidth() - toggleButton.GetSize().x - 20, 20)); + toggleButton.Update(canvas, dt); + } + else + { + inputField.Deactivate(); } } @@ -145,32 +211,24 @@ namespace wi::backlog } wi::image::Draw(&backgroundTex, fx, cmd); - fx.pos = XMFLOAT3(5, canvas.GetLogicalHeight() - 30, 0); - fx.siz = XMFLOAT2(canvas.GetLogicalWidth() - 10, 25); - fx.color = XMFLOAT4(1, 1, 1, 0.2f); if (colorspace != ColorSpace::SRGB) { - fx.enableLinearOutputMapping(9); + inputField.sprites[inputField.GetState()].params.enableLinearOutputMapping(9); + inputField.font.params.enableLinearOutputMapping(9); + toggleButton.sprites[inputField.GetState()].params.enableLinearOutputMapping(9); + toggleButton.font.params.enableLinearOutputMapping(9); } - wi::image::Draw(wi::texturehelper::getWhite(), fx, cmd); - - wi::font::Params params = wi::font::Params(10, canvas.GetLogicalHeight() - 10, wi::font::WIFONTSIZE_DEFAULT, wi::font::WIFALIGN_LEFT, wi::font::WIFALIGN_BOTTOM); - params.h_wrap = canvas.GetLogicalWidth() - params.posX; - params.v_align = wi::font::WIFALIGN_BOTTOM; - params.shadowColor = 0x10000000u; - params.shadow_offset_x = 2; - params.shadow_offset_y = 2; - params.shadow_softness = 1; - if (colorspace != ColorSpace::SRGB) - { - params.enableLinearOutputMapping(9); - } - wi::font::Draw(inputArea, params, cmd); + inputField.Render(canvas, cmd); Rect rect; rect.left = 0; rect.right = (int32_t)canvas.GetPhysicalWidth(); rect.top = 0; + rect.bottom = (int32_t)canvas.GetPhysicalHeight(); + wi::graphics::GetDevice()->BindScissorRects(1, &rect, cmd); + + toggleButton.Render(canvas, cmd); + rect.bottom = int32_t(canvas.LogicalToPhysical(canvas.GetLogicalHeight() - 35)); wi::graphics::GetDevice()->BindScissorRects(1, &rect, cmd); @@ -302,48 +360,14 @@ namespace wi::backlog write_logfile(); // will lock mutex } } - void input(const char input) - { - std::scoped_lock lock(logLock); - inputArea += input; - } - void acceptInput() - { - historyPos = 0; - post(inputArea.c_str()); - LogEntry entry; - entry.text = inputArea; - entry.level = LogLevel::Default; - history.push_back(entry); - if (history.size() > deletefromline) - { - history.pop_front(); - } - if (!blockLuaExec) - { - wi::lua::RunText(inputArea); - } - else - { - post("Lua execution is disabled", LogLevel::Error); - } - inputArea.clear(); - } - void deletefromInput() - { - std::scoped_lock lock(logLock); - if (!inputArea.empty()) - { - inputArea.pop_back(); - } - } void historyPrev() { std::scoped_lock lock(logLock); if (!history.empty()) { - inputArea = history[history.size() - 1 - historyPos].text; + inputField.SetText(history[history.size() - 1 - historyPos].text); + inputField.SetAsActive(); if ((size_t)historyPos < history.size() - 1) { historyPos++; @@ -359,7 +383,8 @@ namespace wi::backlog { historyPos--; } - inputArea = history[history.size() - 1 - historyPos].text; + inputField.SetText(history[history.size() - 1 - historyPos].text); + inputField.SetAsActive(); } } diff --git a/WickedEngine/wiBacklog.h b/WickedEngine/wiBacklog.h index c0cb82a8e..389830b99 100644 --- a/WickedEngine/wiBacklog.h +++ b/WickedEngine/wiBacklog.h @@ -33,9 +33,6 @@ namespace wi::backlog std::string getText(); void clear(); void post(const std::string& input, LogLevel level = LogLevel::Default); - void input(const char input); - void acceptInput(); - void deletefromInput(); void historyPrev(); void historyNext(); @@ -53,4 +50,10 @@ namespace wi::backlog void UnblockLuaExecution(); void SetLogLevel(LogLevel newLevel); + + + // These are no longer used, but kept here to not break user code: + inline void input(const char input) {} + inline void acceptInput() {} + inline void deletefromInput() {} }; diff --git a/WickedEngine/wiGUI.cpp b/WickedEngine/wiGUI.cpp index ab0ef5d56..e43882702 100644 --- a/WickedEngine/wiGUI.cpp +++ b/WickedEngine/wiGUI.cpp @@ -58,7 +58,7 @@ namespace wi::gui void GUI::Update(const wi::Canvas& canvas, float dt) { - if (!visible) + if (!visible || wi::backlog::isActive()) { return; } @@ -1175,6 +1175,8 @@ namespace wi::gui wi::SpriteFont TextInputField::font_input; + int caret_pos = 0; + wi::Timer caret_timer; void TextInputField::Create(const std::string& name) { SetName(name); @@ -1265,9 +1267,7 @@ namespace wi::gui if (clicked) { - Activate(); - - font_input.SetText(font.GetText()); + SetAsActive(); } if (state == ACTIVE) @@ -1279,11 +1279,14 @@ namespace wi::gui font.SetText(font_input.GetText()); font_input.text.clear(); - EventArgs args; - args.sValue = font.GetTextA(); - args.iValue = atoi(args.sValue.c_str()); - args.fValue = (float)atof(args.sValue.c_str()); - onInputAccepted(args); + if (onInputAccepted) + { + EventArgs args; + args.sValue = font.GetTextA(); + args.iValue = atoi(args.sValue.c_str()); + args.fValue = (float)atof(args.sValue.c_str()); + onInputAccepted(args); + } Deactivate(); } @@ -1294,6 +1297,35 @@ namespace wi::gui font_input.text.clear(); Deactivate(); } + else if (wi::input::Press(wi::input::KEYBOARD_BUTTON_LEFT) && caret_pos > 0) + { + // caret repositioning left: + caret_pos--; + caret_timer.record(); + } + else if (wi::input::Press(wi::input::KEYBOARD_BUTTON_RIGHT) && caret_pos < font_input.GetText().size()) + { + // caret repositioning right: + caret_pos++; + caret_timer.record(); + } + else if (wi::input::Press(wi::input::MOUSE_BUTTON_LEFT) && intersectsPointer) + { + // caret repositioning by mouse click: + caret_pos = (int)font_input.GetText().size(); + const std::wstring& str = font_input.GetText(); + float pos = font_input.params.position.x; + for (size_t i = 0; i < str.size(); ++i) + { + XMFLOAT2 size = wi::font::TextSize(str.c_str() + i, 1, font_input.params); + pos += size.x; + if (pos > pointerHitbox.pos.x) + { + caret_pos = int(i); + break; + } + } + } } } @@ -1357,6 +1389,19 @@ namespace wi::gui if (state == ACTIVE) { font_input.Draw(cmd); + + // caret: + if(std::fmod(caret_timer.elapsed_seconds(), 1) < 0.5f) + { + wi::font::Params params = font_input.params; + XMFLOAT2 size = wi::font::TextSize(font_input.GetText().c_str(), caret_pos, font_input.params); + params.posX += size.x; + params.color = wi::Color::lerp(params.color, wi::Color::Transparent(), 0.1f); + params.size += 4; + params.posY -= 2; + params.h_align = wi::font::WIFALIGN_CENTER; + wi::font::Draw(L"|", params, cmd); + } } else { @@ -1370,25 +1415,44 @@ namespace wi::gui } void TextInputField::AddInput(const char inputChar) { - std::string value_new = font_input.GetTextA(); - value_new.push_back(inputChar); - font_input.SetText(value_new); + std::wstring value_new = font_input.GetText(); + if (value_new.size() >= caret_pos) + { + value_new.insert(value_new.begin() + caret_pos, inputChar); + font_input.SetText(value_new); + caret_pos = std::min((int)font_input.GetText().size(), caret_pos + 1); + } } void TextInputField::DeleteFromInput() { - std::string value_new = font_input.GetTextA(); - if (!value_new.empty()) + std::wstring value_new = font_input.GetText(); + if (caret_pos > 0 && value_new.size() > caret_pos - 1) { - value_new.pop_back(); + value_new.erase(value_new.begin() + caret_pos - 1); + font_input.SetText(value_new); + caret_pos = std::max(0, caret_pos - 1); + } + } + void TextInputField::SetColor(wi::Color color, int id) + { + Widget::SetColor(color, id); + + if (id > WIDGET_ID_TEXTINPUTFIELD_BEGIN && id < WIDGET_ID_TEXTINPUTFIELD_END) + { + sprites[id - WIDGET_ID_TEXTINPUTFIELD_IDLE].params.color = color; } - font_input.SetText(value_new); } void TextInputField::SetTheme(const Theme& theme, int id) { Widget::SetTheme(theme, id); theme.font.Apply(font_description.params); } - + void TextInputField::SetAsActive() + { + Activate(); + font_input.SetText(font.GetText()); + caret_pos = (int)font_input.GetText().size(); + } diff --git a/WickedEngine/wiGUI.h b/WickedEngine/wiGUI.h index 900d9d8b0..a67f350c3 100644 --- a/WickedEngine/wiGUI.h +++ b/WickedEngine/wiGUI.h @@ -49,6 +49,14 @@ namespace wi::gui // IDs for special widget states: + // TextInputField: + WIDGET_ID_TEXTINPUTFIELD_BEGIN, // do not use! + WIDGET_ID_TEXTINPUTFIELD_IDLE, + WIDGET_ID_TEXTINPUTFIELD_FOCUS, + WIDGET_ID_TEXTINPUTFIELD_ACTIVE, + WIDGET_ID_TEXTINPUTFIELD_DEACTIVATING, + WIDGET_ID_TEXTINPUTFIELD_END, // do not use! + // Slider: WIDGET_ID_SLIDER_BEGIN, // do not use! WIDGET_ID_SLIDER_BASE_IDLE, @@ -395,9 +403,11 @@ namespace wi::gui // There can only be ONE active text input field, so these methods modify the active one static void AddInput(const char inputChar); static void DeleteFromInput(); + void SetAsActive(); void Update(const wi::Canvas& canvas, float dt) override; void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override; + void SetColor(wi::Color color, int id = -1) override; void SetTheme(const Theme& theme, int id = -1) override; void OnInputAccepted(std::function func); diff --git a/WickedEngine/wiLua.cpp b/WickedEngine/wiLua.cpp index 2bcca9d4f..0c2d7ab0e 100644 --- a/WickedEngine/wiLua.cpp +++ b/WickedEngine/wiLua.cpp @@ -161,10 +161,10 @@ namespace wi::lua } bool RunFile(const std::string& filename) { - script_path = wi::helper::GetDirectoryFromPath(filename); wi::vector filedata; if (wi::helper::FileRead(filename, filedata)) { + script_path = wi::helper::GetDirectoryFromPath(filename); return RunText(std::string(filedata.begin(), filedata.end())); } return false; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 0520f196f..e46d857a1 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 70; // minor bug fixes, alterations, refactors, updates - const int revision = 19; + const int revision = 20; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);