Implemented Input Binding Panel via Editor #318
|
@ -5,11 +5,193 @@
|
||||||
|
|
||||||
namespace SHADE
|
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()
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,6 +10,8 @@ namespace SHADE
|
||||||
public:
|
public:
|
||||||
SHInputBindingsPanel() : SHEditorWindow("Input Bindings Panel", ImGuiWindowFlags_MenuBar) {}
|
SHInputBindingsPanel() : SHEditorWindow("Input Bindings Panel", ImGuiWindowFlags_MenuBar) {}
|
||||||
|
|
||||||
|
void Init() override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -7,3 +7,4 @@
|
||||||
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
||||||
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector
|
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector
|
||||||
#include "ColliderTagPanel/SHColliderTagPanel.h" //Collider Tag Panel
|
#include "ColliderTagPanel/SHColliderTagPanel.h" //Collider Tag Panel
|
||||||
|
#include "InputBindings/SHInputBindingsPanel.h" //Input Bindings
|
|
@ -104,6 +104,7 @@ namespace SHADE
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
|
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHInputBindingsPanel>();
|
||||||
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||||
|
|
||||||
|
|
|
@ -738,6 +738,16 @@ namespace SHADE
|
||||||
return bindings.erase(bindingName);
|
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
|
//Clears all bindings from the list
|
||||||
static inline void ClearBindings() noexcept
|
static inline void ClearBindings() noexcept
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue