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() FImGuiInputState::FImGuiInputState()
{ {
ClearState(); ResetState();
} }
void FImGuiInputState::AddCharacter(TCHAR Char) void FImGuiInputState::AddCharacter(TCHAR Char)
@ -45,22 +45,23 @@ void FImGuiInputState::SetMouseDown(uint32 MouseIndex, bool bIsDown)
} }
} }
void FImGuiInputState::ClearState() void FImGuiInputState::ResetState()
{ {
ClearCharacters(); ClearCharacters();
ClearKeys();
using std::fill; ClearMouseButtons();
fill(KeysDown, &KeysDown[Utilities::GetArraySize(KeysDown)], false); ClearMouseAnalogue();
fill(MouseButtonsDown, &MouseButtonsDown[Utilities::GetArraySize(MouseButtonsDown)], false);
// Fully expanding dirty parts of both arrays, to inform about the change. ClearModifierKeys();
KeysUpdateRange.SetFull();
MouseButtonsUpdateRange.SetFull();
} }
void FImGuiInputState::ClearUpdateState() void FImGuiInputState::ClearUpdateState()
{ {
if (InputCharactersNum > 0)
{
ClearCharacters(); ClearCharacters();
}
KeysUpdateRange.SetEmpty(); KeysUpdateRange.SetEmpty();
MouseButtonsUpdateRange.SetEmpty(); MouseButtonsUpdateRange.SetEmpty();
@ -70,6 +71,38 @@ void FImGuiInputState::ClearUpdateState()
void FImGuiInputState::ClearCharacters() void FImGuiInputState::ClearCharacters()
{ {
using std::fill;
fill(InputCharacters, &InputCharacters[Utilities::GetArraySize(InputCharacters)], 0);
InputCharactersNum = 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 // @param Position - New mouse position
void SetMousePosition(const FVector2D& Position) { MousePosition = Position; } void SetMousePosition(const FVector2D& Position) { MousePosition = Position; }
// Clear state and mark as dirty. // Get Control down state.
void ClearState(); 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 // 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. // about dirty parts of keys or mouse buttons arrays.
@ -86,6 +107,10 @@ public:
private: private:
void ClearCharacters(); void ClearCharacters();
void ClearKeys();
void ClearMouseButtons();
void ClearMouseAnalogue();
void ClearModifierKeys();
FVector2D MousePosition = FVector2D::ZeroVector; FVector2D MousePosition = FVector2D::ZeroVector;
float MouseWheelDelta = 0.f; float MouseWheelDelta = 0.f;
@ -98,4 +123,8 @@ private:
FKeysArray KeysDown; FKeysArray KeysDown;
FKeysIndexRange KeysUpdateRange; FKeysIndexRange KeysUpdateRange;
bool bIsControlDown = false;
bool bIsShiftDown = false;
bool bIsAltDown = false;
}; };

View File

@ -154,9 +154,9 @@ namespace ImGuiInterops
IO.MouseWheel += InputState.GetMouseWheelDelta(); IO.MouseWheel += InputState.GetMouseWheelDelta();
// Copy key modifiers. // Copy key modifiers.
IO.KeyCtrl = InputState.GetKeys()[LeftControl] || InputState.GetKeys()[RightControl]; IO.KeyCtrl = InputState.IsControlDown();
IO.KeyShift = InputState.GetKeys()[LeftShift] || InputState.GetKeys()[RightShift]; IO.KeyShift = InputState.IsShiftDown();
IO.KeyAlt = InputState.GetKeys()[LeftAlt] || InputState.GetKeys()[RightAlt]; IO.KeyAlt = InputState.IsAltDown();
IO.KeySuper = false; IO.KeySuper = false;
// Copy buffers. // Copy buffers.
@ -172,7 +172,7 @@ namespace ImGuiInterops
if (InputState.GetCharactersNum() > 0) 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) FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
{ {
InputState.AddCharacter(CharacterEvent.GetCharacter()); InputState.AddCharacter(CharacterEvent.GetCharacter());
return FReply::Handled(); return FReply::Handled();
} }
FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{ {
InputState.SetKeyDown(ImGuiInterops::GetKeyIndex(KeyEvent), true); 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 this is tilde key then let input through and release the focus to allow console to process it.
if (KeyEvent.GetKey() == EKeys::Tilde) 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) FReply SImGuiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{ {
InputState.SetKeyDown(ImGuiInterops::GetKeyIndex(KeyEvent), false); InputState.SetKeyDown(ImGuiInterops::GetKeyIndex(KeyEvent), false);
CopyModifierKeys(KeyEvent);
return FReply::Handled(); return FReply::Handled();
} }
FReply SImGuiWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) FReply SImGuiWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{ {
InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), true); InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), true);
CopyModifierKeys(MouseEvent);
return FReply::Handled(); return FReply::Handled();
} }
FReply SImGuiWidget::OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) FReply SImGuiWidget::OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{ {
InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), true); InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), true);
CopyModifierKeys(MouseEvent);
return FReply::Handled(); return FReply::Handled();
} }
FReply SImGuiWidget::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) FReply SImGuiWidget::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{ {
InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), false); InputState.SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), false);
CopyModifierKeys(MouseEvent);
return FReply::Handled(); return FReply::Handled();
} }
FReply SImGuiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) FReply SImGuiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{ {
InputState.AddMouseWheelDelta(MouseEvent.GetWheelDelta()); InputState.AddMouseWheelDelta(MouseEvent.GetWheelDelta());
CopyModifierKeys(MouseEvent);
return FReply::Handled(); return FReply::Handled();
} }
FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{ {
InputState.SetMousePosition(MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition); InputState.SetMousePosition(MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition);
CopyModifierKeys(MouseEvent);
return FReply::Handled(); return FReply::Handled();
} }
void SImGuiWidget::CopyModifierKeys(const FInputEvent& InputEvent)
{
InputState.SetControlDown(InputEvent.IsControlDown());
InputState.SetShiftDown(InputEvent.IsShiftDown());
InputState.SetAltDown(InputEvent.IsAltDown());
}
void SImGuiWidget::OnPostImGuiUpdate() void SImGuiWidget::OnPostImGuiUpdate()
{ {
InputState.ClearUpdateState(); InputState.ClearUpdateState();

View File

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