Changed modifier keys handling and cleaned ImGui Input State:

- Separate modifier keys interface and data from generic keys.
- Cleaned interface to better differentiate between full reset and clearing update data.
- Fixed bug in code clearing characters.
This commit is contained in:
Sebastian 2017-08-19 21:19:38 +01:00
parent 393460f330
commit 53387cf88b
5 changed files with 103 additions and 16 deletions

View File

@ -7,7 +7,7 @@
FImGuiInputState::FImGuiInputState()
{
ClearState();
ResetState();
}
void FImGuiInputState::AddCharacter(TCHAR Char)
@ -45,22 +45,23 @@ void FImGuiInputState::SetMouseDown(uint32 MouseIndex, bool bIsDown)
}
}
void FImGuiInputState::ClearState()
void FImGuiInputState::ResetState()
{
ClearCharacters();
ClearKeys();
using std::fill;
fill(KeysDown, &KeysDown[Utilities::GetArraySize(KeysDown)], false);
fill(MouseButtonsDown, &MouseButtonsDown[Utilities::GetArraySize(MouseButtonsDown)], false);
ClearMouseButtons();
ClearMouseAnalogue();
// Fully expanding dirty parts of both arrays, to inform about the change.
KeysUpdateRange.SetFull();
MouseButtonsUpdateRange.SetFull();
ClearModifierKeys();
}
void FImGuiInputState::ClearUpdateState()
{
if (InputCharactersNum > 0)
{
ClearCharacters();
}
KeysUpdateRange.SetEmpty();
MouseButtonsUpdateRange.SetEmpty();
@ -70,6 +71,38 @@ void FImGuiInputState::ClearUpdateState()
void FImGuiInputState::ClearCharacters()
{
using std::fill;
fill(InputCharacters, &InputCharacters[Utilities::GetArraySize(InputCharacters)], 0);
InputCharactersNum = 0;
InputCharacters[0];
}
void FImGuiInputState::ClearKeys()
{
using std::fill;
fill(KeysDown, &KeysDown[Utilities::GetArraySize(KeysDown)], false);
// Expand update range because keys array has been updated.
KeysUpdateRange.SetFull();
}
void FImGuiInputState::ClearMouseButtons()
{
using std::fill;
fill(MouseButtonsDown, &MouseButtonsDown[Utilities::GetArraySize(MouseButtonsDown)], false);
// Expand update range because mouse buttons array has been updated.
MouseButtonsUpdateRange.SetFull();
}
void FImGuiInputState::ClearMouseAnalogue()
{
MousePosition = FVector2D::ZeroVector;
MouseWheelDelta = 0.f;
}
void FImGuiInputState::ClearModifierKeys()
{
bIsControlDown = false;
bIsShiftDown = false;
bIsAltDown = false;
}

View File

@ -76,8 +76,29 @@ public:
// @param Position - New mouse position
void SetMousePosition(const FVector2D& Position) { MousePosition = Position; }
// Clear state and mark as dirty.
void ClearState();
// Get Control down state.
bool IsControlDown() const { return bIsControlDown; }
// Set Control down state.
// @param bIsDown - True, if Control is down
void SetControlDown(bool bIsDown) { bIsControlDown = bIsDown; }
// Get Shift down state.
bool IsShiftDown() const { return bIsShiftDown; }
// Set Shift down state.
// @param bIsDown - True, if Shift is down
void SetShiftDown(bool bIsDown) { bIsShiftDown = bIsDown; }
// Get Alt down state.
bool IsAltDown() const { return bIsAltDown; }
// Set Alt down state.
// @param bIsDown - True, if Alt is down
void SetAltDown(bool bIsDown) { bIsAltDown = bIsDown; }
// Reset state and mark as dirty.
void ResetState();
// Clear part of the state that is meant to be updated in every frame like: accumulators, buffers and information
// about dirty parts of keys or mouse buttons arrays.
@ -86,6 +107,10 @@ public:
private:
void ClearCharacters();
void ClearKeys();
void ClearMouseButtons();
void ClearMouseAnalogue();
void ClearModifierKeys();
FVector2D MousePosition = FVector2D::ZeroVector;
float MouseWheelDelta = 0.f;
@ -98,4 +123,8 @@ private:
FKeysArray KeysDown;
FKeysIndexRange KeysUpdateRange;
bool bIsControlDown = false;
bool bIsShiftDown = false;
bool bIsAltDown = false;
};

View File

@ -154,9 +154,9 @@ namespace ImGuiInterops
IO.MouseWheel += InputState.GetMouseWheelDelta();
// Copy key modifiers.
IO.KeyCtrl = InputState.GetKeys()[LeftControl] || InputState.GetKeys()[RightControl];
IO.KeyShift = InputState.GetKeys()[LeftShift] || InputState.GetKeys()[RightShift];
IO.KeyAlt = InputState.GetKeys()[LeftAlt] || InputState.GetKeys()[RightAlt];
IO.KeyCtrl = InputState.IsControlDown();
IO.KeyShift = InputState.IsShiftDown();
IO.KeyAlt = InputState.IsAltDown();
IO.KeySuper = false;
// Copy buffers.
@ -172,7 +172,7 @@ namespace ImGuiInterops
if (InputState.GetCharactersNum() > 0)
{
Copy(InputState.GetCharacters(), IO.InputCharacters, InputState.GetCharactersNum());
Copy(InputState.GetCharacters(), IO.InputCharacters);
}
}
}

View File

@ -29,12 +29,14 @@ SImGuiWidget::~SImGuiWidget()
FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
{
InputState.AddCharacter(CharacterEvent.GetCharacter());
return FReply::Handled();
}
FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{
InputState.SetKeyDown(ImGuiInterops::GetKeyIndex(KeyEvent), true);
CopyModifierKeys(KeyEvent);
// If this is tilde key then let input through and release the focus to allow console to process it.
if (KeyEvent.GetKey() == EKeys::Tilde)
@ -48,39 +50,58 @@ FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& Key
FReply SImGuiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{
InputState.SetKeyDown(ImGuiInterops::GetKeyIndex(KeyEvent), false);
CopyModifierKeys(KeyEvent);
return FReply::Handled();
}
FReply SImGuiWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), true);
CopyModifierKeys(MouseEvent);
return FReply::Handled();
}
FReply SImGuiWidget::OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), true);
CopyModifierKeys(MouseEvent);
return FReply::Handled();
}
FReply SImGuiWidget::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), false);
CopyModifierKeys(MouseEvent);
return FReply::Handled();
}
FReply SImGuiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
InputState.AddMouseWheelDelta(MouseEvent.GetWheelDelta());
CopyModifierKeys(MouseEvent);
return FReply::Handled();
}
FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
InputState.SetMousePosition(MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition);
CopyModifierKeys(MouseEvent);
return FReply::Handled();
}
void SImGuiWidget::CopyModifierKeys(const FInputEvent& InputEvent)
{
InputState.SetControlDown(InputEvent.IsControlDown());
InputState.SetShiftDown(InputEvent.IsShiftDown());
InputState.SetAltDown(InputEvent.IsAltDown());
}
void SImGuiWidget::OnPostImGuiUpdate()
{
InputState.ClearUpdateState();

View File

@ -12,6 +12,8 @@ class FImGuiModuleManager;
// Slate widget for rendering ImGui output and storing Slate inputs.
class SImGuiWidget : public SLeafWidget
{
typedef SLeafWidget Super;
public:
SLATE_BEGIN_ARGS(SImGuiWidget)
@ -49,6 +51,8 @@ public:
private:
FORCEINLINE void CopyModifierKeys(const FInputEvent& InputEvent);
void OnPostImGuiUpdate();
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;