Implemented Input Binding Panel via Editor #318

Merged
mushgunAX merged 8 commits from SP3-10-input-management into main 2023-01-30 15:00:58 +08:00
5 changed files with 198 additions and 2 deletions
Showing only changes of commit 71572381f7 - Show all commits

View File

@ -5,11 +5,193 @@
namespace SHADE
{
//Internal Helper function
std::string labelConcat(char const* label, size_t entryNumber)
{
std::string concat = label;
concat += std::to_string(entryNumber);
return concat;
}
void SHInputBindingsPanel::Init()
{
SHEditorWindow::Init();
}
void SHInputBindingsPanel::Update()
{
if (Begin())
if (SHEditorWindow::Begin())
{
//Binding count
ImGui::Text("Binding Count: %d", SHInputManager::CountBindings());
//Button to add new binding
if (ImGui::Button("Add New Binding"))
{
std::string newBindingName = "Binding" + std::to_string(SHInputManager::CountBindings());
SHInputManager::AddBinding(newBindingName);
}
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("Add a new binding to the list");
ImGui::EndTooltip();
}
//Ensure unique label for entries
size_t entryNumber = 0;
//Listing for each binding
for (auto& binding : SHInputManager::GetBindings())
{
ImGui::Separator();
std::string bindingName = binding.first; //Binding name to use as argument when modifying binding values
//Non-modifiable binding name
ImGui::Text("Binding Name: %s", binding.first);
std::string bindingModifiedName;
//MAKE THE INPUTTEXT WORK
ImGui::InputText(labelConcat("##bindingModifyName", entryNumber).c_str(), &bindingModifiedName);
ImGui::SameLine();
if (ImGui::Button(labelConcat("Rename##bindingRename", entryNumber).c_str()))
{
SHLOGV_CRITICAL("\"{0}\" > \"{1}\"", bindingName, bindingModifiedName);
SHInputManager::RenameBinding(bindingName, bindingModifiedName);
}
//Modifiable binding name
/*size_t constexpr maxLen = 256; //Maximum binding name length
static char bindingNameCStr[maxLen];
std::copy(bindingName.begin(),
bindingName.length() >= maxLen ?
bindingName.begin() + maxLen :
bindingName.end(), //Does not take into account null terminator
bindingNameCStr);
bindingNameCStr[bindingName.length()] = '\0'; //Null terminator
//First character
char firstChar = bindingNameCStr[0];
//If the input text is modified, modify the binding's name
if (ImGui::InputText("Binding Name", bindingNameCStr, maxLen))
{
//Ensure name does not get shorter than 1 character long
if (std::strlen(bindingNameCStr) < 1)
bindingNameCStr[0] = firstChar;
//Rename binding in the input manager
SHInputManager::RenameBinding(bindingName, std::string{ bindingNameCStr });
bindingName = std::string{ bindingNameCStr };
}
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("The name of this binding");
ImGui::EndTooltip();
}*/
//Binding value test
//TODO
ImGui::Text("Value");
//Binding Type Combo Box
int bindingType = static_cast<int>(SHInputManager::GetBindingType(bindingName));
if (ImGui::Combo(labelConcat("Input Type##", entryNumber).c_str(), &bindingType, "Keyboard / Mouse Buttons / Controller\0Mouse Horizontal\0Mouse Vertical\0Mouse Scroll Wheel"))
SHInputManager::SetBindingType(bindingName, static_cast<SHInputManager::SH_BINDINGTYPE>(bindingType));
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("Which of the four types the binding uses");
ImGui::Text("Keyboard / Mouse Buttons / Controller = Keys, mouse buttons and ALL controller inputs");
ImGui::Text("Mouse Horizontal = Horizontal movement of the mouse");
ImGui::Text("Mouse Vertical = Vertical movement of the mouse");
ImGui::Text("Mouse Scroll Wheel = The scroll wheel found at the middle of most mouses");
ImGui::EndTooltip();
}
//Inversion
bool bindingInvert = SHInputManager::GetBindingInverted(bindingName);
if (ImGui::Checkbox(labelConcat("Inverted##", entryNumber).c_str(), &bindingInvert))
SHInputManager::SetBindingInverted(bindingName, bindingInvert);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("If inverted:");
ImGui::Text("Positive inputs mean negative value of the binding");
ImGui::Text("Negative inputs mean positive value of the binding");
ImGui::Text("Mouse moving up / right means negative value of the binding");
ImGui::Text("Scrolling the mouse wheel up means negative value of the binding");
ImGui::EndTooltip();
}
//Sensitivity
double bindingSensitivity = SHInputManager::GetBindingSensitivity(bindingName);
if (ImGui::InputDouble(labelConcat("Sensitivity##", entryNumber).c_str(), &bindingSensitivity))
SHInputManager::SetBindingSensitivity(bindingName, bindingSensitivity);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("Value multiplier for mouse movement and scrolling");
ImGui::Text("For other digital inputs, serves as a rate of how fast axis value goes to maximum positive/negative");
ImGui::Text("For other analog inputs, serves as a multiplier, but axis value magnitude will still be capped at 1");
ImGui::EndTooltip();
}
//Below this section is only for KB/M type bindings
//Not relevant for mouse movement and scrolling
if (SHInputManager::GetBindingType(bindingName) == SHInputManager::SH_BINDINGTYPE::KB_MB_CONTROLLER)
{
//Dead
float bindingDead = static_cast<float>(SHInputManager::GetBindingDead(bindingName));
if (ImGui::SliderFloat(labelConcat("Deadzone##", entryNumber).c_str(), &bindingDead, 0.0f, 1.0f))
SHInputManager::SetBindingDead(bindingName, static_cast<double>(bindingDead));
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("Any positive or negative analog input with magnitude less than this will be registered as neutral");
ImGui::EndTooltip();
}
//Gravity
double bindingGravity = SHInputManager::GetBindingGravity(bindingName);
if (ImGui::InputDouble(labelConcat("Gravity##", entryNumber).c_str(), &bindingGravity))
SHInputManager::SetBindingGravity(bindingName, static_cast<double>(bindingGravity));
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("The rate at which the value moves to neutral if no input in the direction is read");
ImGui::TextColored(ImVec4{ 1.0f, 0.5f, 0.5f, 1.0f }, "Should be non-negative");
ImGui::EndTooltip();
}
//Snap
bool bindingSnap = SHInputManager::GetBindingSnap(bindingName);
if (ImGui::Checkbox(labelConcat("Snap##", entryNumber).c_str(), &bindingSnap))
SHInputManager::SetBindingSnap(bindingName, bindingSnap);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("If no other input on the axis is present and a input is made in the opposite direction of the current value,");
ImGui::Text("the binding's value will jump to neutral 0 before resuming in the input direction");
ImGui::EndTooltip();
}
//Positive key codes
//Negative key codes
//Positive controller codes
//Negative controller codes
}
++entryNumber; //Next entry
}
}
ImGui::End();
}
void SHInputBindingsPanel::Exit()
{
SHEditorWindow::Exit();
}
}

View File

@ -10,6 +10,8 @@ namespace SHADE
public:
SHInputBindingsPanel() : SHEditorWindow("Input Bindings Panel", ImGuiWindowFlags_MenuBar) {}
void Init() override;
void Update() override;
void Exit() override;
};
}

View File

@ -7,3 +7,4 @@
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector
#include "ColliderTagPanel/SHColliderTagPanel.h" //Collider Tag Panel
#include "InputBindings/SHInputBindingsPanel.h" //Input Bindings

View File

@ -104,6 +104,7 @@ namespace SHADE
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
SHEditorWindowManager::CreateEditorWindow<SHInputBindingsPanel>();
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();

View File

@ -738,6 +738,16 @@ namespace SHADE
return bindings.erase(bindingName);
}
//Rename a binding
static inline void RenameBinding(std::string const& oldBindingName, std::string const& newBindingName) noexcept
{
//https://stackoverflow.com/a/44883472
//https://en.cppreference.com/w/cpp/container/map/extract
auto nodeHandler = bindings.extract(oldBindingName);
nodeHandler.key() = newBindingName;
bindings.insert(std::move(nodeHandler));
}
//Clears all bindings from the list
static inline void ClearBindings() noexcept
{