diff --git a/src/inputmode/src/Client/InputModeServiceClient.lua b/src/inputmode/src/Client/InputModeServiceClient.lua index 689075d367..6efdb670e4 100644 --- a/src/inputmode/src/Client/InputModeServiceClient.lua +++ b/src/inputmode/src/Client/InputModeServiceClient.lua @@ -115,6 +115,11 @@ function InputModeServiceClient:_bindProcessor() self._inputModeProcessor:Evaluate(inputObject) self:GetInputMode(InputModeTypes.Thumbsticks):Enable() end + elseif inputObject.UserInputType == Enum.UserInputType.MouseMovement then + -- Prevent mouse movement from flickering + if self:_shouldProcessMouseMovement(inputObject) then + self._inputModeProcessor:Evaluate(inputObject) + end else self._inputModeProcessor:Evaluate(inputObject) end @@ -129,6 +134,27 @@ function InputModeServiceClient:_bindProcessor() end)) end +function InputModeServiceClient:_shouldProcessMouseMovement(inputObject) + -- Prevent mouse movement from flickering + local position = inputObject.Position + local lastMousePosition = self._lastMousePosition + self._lastMousePosition = position + + if inputObject.Delta.magnitude > 0 then + return true + end + + if not lastMousePosition then + return true + end + + if (lastMousePosition - position).magnitude > 0 then + return true + end + + return false +end + function InputModeServiceClient:Destroy() self._maid:DoCleaning() end diff --git a/src/sprites/src/Shared/InputImageLibrary/InputImageLibrary.story.lua b/src/sprites/src/Shared/InputImageLibrary/InputImageLibrary.story.lua index 0c18ad5d34..fc1ba2d8fa 100644 --- a/src/sprites/src/Shared/InputImageLibrary/InputImageLibrary.story.lua +++ b/src/sprites/src/Shared/InputImageLibrary/InputImageLibrary.story.lua @@ -10,7 +10,7 @@ local UIPaddingUtils = require("UIPaddingUtils") local UICornerUtils = require("UICornerUtils") local String = require("String") -local XBOX = { +local CONSOLE = { Enum.KeyCode.ButtonA; Enum.KeyCode.ButtonB; Enum.KeyCode.ButtonX; @@ -90,7 +90,7 @@ local MOUSE = { Enum.UserInputType.MouseMovement; } -local function create(keyCode, theme, parent) +local function createInputKey(keyCode, theme, platform, parent) local container = Instance.new("Frame") container.BorderSizePixel = 0 container.Size = UDim2.new(1, 0, 1, 0) @@ -117,7 +117,7 @@ local function create(keyCode, theme, parent) local uiListLayout = Instance.new("UIListLayout") uiListLayout.Parent = container - local sprite = InputImageLibrary:GetScaledImageLabel(keyCode, theme) + local sprite = InputImageLibrary:GetScaledImageLabel(keyCode, theme, platform) sprite.Parent = container container.Parent = parent @@ -141,11 +141,13 @@ local function makeTitle(title, parent) return titleLabel end -local function makeSection(keycodes, theme, parent) +local function makeSection(keycodes, theme, platform, parent) local container = Instance.new("Frame") container.BorderSizePixel = 0 container.BackgroundTransparency = 1 - container.Size = UDim2.new(1, 0, 1, 0) + container.Size = UDim2.new(1, 0, 0, 0) + container.BackgroundColor3 = Color3.new(0.5, 0, 0) + container.AutomaticSize = Enum.AutomaticSize.Y local uiGridLayout = Instance.new("UIGridLayout") uiGridLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center @@ -156,11 +158,10 @@ local function makeSection(keycodes, theme, parent) uiGridLayout.Parent = container for _, item in pairs(keycodes) do - create(item, theme, container) + createInputKey(item, theme, platform, container) end container.Parent = parent - container.Size = UDim2.new(1, 0, 0, uiGridLayout.AbsoluteContentSize.y) return container end @@ -189,22 +190,28 @@ return function(target) end add(makeTitle("Mouse Light", scrollingFrame)) - add(makeSection(MOUSE, "Light", scrollingFrame)) + add(makeSection(MOUSE, "Light", nil, scrollingFrame)) add(makeTitle("Mouse Dark", scrollingFrame)) - add(makeSection(MOUSE, "Dark", scrollingFrame)) + add(makeSection(MOUSE, "Dark", nil, scrollingFrame)) add(makeTitle("XBox Dark", scrollingFrame)) - add(makeSection(XBOX, "Dark", scrollingFrame)) + add(makeSection(CONSOLE, "Dark", "XBox", scrollingFrame)) add(makeTitle("XBox Light", scrollingFrame)) - add(makeSection(XBOX, "Light", scrollingFrame)) + add(makeSection(CONSOLE, "Light", "XBox", scrollingFrame)) + + add(makeTitle("PS5 Dark", scrollingFrame)) + add(makeSection(CONSOLE, "Dark", "PlayStation", scrollingFrame)) + + add(makeTitle("PS5 Light", scrollingFrame)) + add(makeSection(CONSOLE, "Light", "PlayStation", scrollingFrame)) add(makeTitle("Keyboard Dark", scrollingFrame)) - add(makeSection(KEYBOARD, "Dark", scrollingFrame)) + add(makeSection(KEYBOARD, "Dark", nil, scrollingFrame)) add(makeTitle("Keyboard Light", scrollingFrame)) - add(makeSection(KEYBOARD, "Light", scrollingFrame)) + add(makeSection(KEYBOARD, "Light", nil, scrollingFrame)) return function() diff --git a/src/sprites/src/Shared/InputImageLibrary/Spritesheets/PlayStation/Dark.lua b/src/sprites/src/Shared/InputImageLibrary/Spritesheets/PlayStation/Dark.lua new file mode 100644 index 0000000000..c3d27e94a5 --- /dev/null +++ b/src/sprites/src/Shared/InputImageLibrary/Spritesheets/PlayStation/Dark.lua @@ -0,0 +1,45 @@ +--[[ + Generated PS5Dark with Python + @class PS5Dark +]] + +local parent = script:FindFirstAncestorWhichIsA("ModuleScript") +local require = require(parent.Parent.loader).load(parent) + +local Spritesheet = require("Spritesheet") + +local PS5Dark = setmetatable({}, Spritesheet) +PS5Dark.ClassName = "PS5Dark" +PS5Dark.__index = PS5Dark + +function PS5Dark.new() + local self = setmetatable(Spritesheet.new("rbxassetid://15030465512"), PS5Dark) + + self:AddSprite("DPad", Vector2.new(0, 0), Vector2.new(100, 100)) + self:AddSprite("Microphone", Vector2.new(100, 0), Vector2.new(100, 100)) + self:AddSprite("Options", Vector2.new(200, 0), Vector2.new(100, 100)) + self:AddSprite("OptionsAlt", Vector2.new(300, 0), Vector2.new(100, 100)) + self:AddSprite("ShareAlt", Vector2.new(400, 0), Vector2.new(100, 100)) + self:AddSprite("Thumbstick1_Click", Vector2.new(500, 0), Vector2.new(100, 100)) + self:AddSprite("Thumbstick2_Click", Vector2.new(600, 0), Vector2.new(100, 100)) + self:AddSprite("TouchPad", Vector2.new(700, 0), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonA, Vector2.new(800, 0), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonB, Vector2.new(900, 0), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonL1, Vector2.new(0, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonL2, Vector2.new(100, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonR1, Vector2.new(200, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonR2, Vector2.new(300, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonSelect, Vector2.new(400, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonX, Vector2.new(500, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.ButtonY, Vector2.new(600, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.DPadDown, Vector2.new(700, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.DPadLeft, Vector2.new(800, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.DPadRight, Vector2.new(900, 100), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.DPadUp, Vector2.new(0, 200), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.Thumbstick1, Vector2.new(100, 200), Vector2.new(100, 100)) + self:AddSprite(Enum.KeyCode.Thumbstick2, Vector2.new(200, 200), Vector2.new(100, 100)) + + return self +end + +return PS5Dark diff --git a/src/sprites/src/Shared/InputImageLibrary/Spritesheets/Guestures/All.lua b/src/sprites/src/Shared/InputImageLibrary/Spritesheets/Touch/All.lua similarity index 100% rename from src/sprites/src/Shared/InputImageLibrary/Spritesheets/Guestures/All.lua rename to src/sprites/src/Shared/InputImageLibrary/Spritesheets/Touch/All.lua diff --git a/src/sprites/src/Shared/InputImageLibrary/Spritesheets/XboxOne/Dark.lua b/src/sprites/src/Shared/InputImageLibrary/Spritesheets/XBox/Dark.lua similarity index 100% rename from src/sprites/src/Shared/InputImageLibrary/Spritesheets/XboxOne/Dark.lua rename to src/sprites/src/Shared/InputImageLibrary/Spritesheets/XBox/Dark.lua diff --git a/src/sprites/src/Shared/InputImageLibrary/Spritesheets/XboxOne/Light.lua b/src/sprites/src/Shared/InputImageLibrary/Spritesheets/XBox/Light.lua similarity index 100% rename from src/sprites/src/Shared/InputImageLibrary/Spritesheets/XboxOne/Light.lua rename to src/sprites/src/Shared/InputImageLibrary/Spritesheets/XBox/Light.lua diff --git a/src/sprites/src/Shared/InputImageLibrary/init.lua b/src/sprites/src/Shared/InputImageLibrary/init.lua index aa22b940a6..86ad6e71a3 100644 --- a/src/sprites/src/Shared/InputImageLibrary/init.lua +++ b/src/sprites/src/Shared/InputImageLibrary/init.lua @@ -7,6 +7,8 @@ local require = require(script.Parent.loader).load(script) +local UserInputService = game:GetService("UserInputService") + local SUPRESS_UNFOUND_IMAGE_WARNING = true local InputImageLibrary = {} @@ -38,6 +40,8 @@ function InputImageLibrary:GetPreloadAssetIds() end function InputImageLibrary:_loadSpriteSheets(parentFolder) + assert(typeof(parentFolder) == "Instance", "Bad parentFolder") + for _, platform in pairs(parentFolder:GetChildren()) do self._spritesheets[platform.Name] = {} for _, style in pairs(platform:GetChildren()) do @@ -51,21 +55,74 @@ end --[=[ Retrieves a sprite from the library - @param index number -- The sprite index to get + @param keyCode any -- The sprite keyCode to get @param preferredStyle string -- The preferred style type to retrieve this in @param preferredPlatform string -- The preferred platform to get the sprite for @return Sprite ]=] -function InputImageLibrary:GetSprite(index, preferredStyle, preferredPlatform) - local sheet = self:_pickSheet(index, preferredStyle, preferredPlatform) +function InputImageLibrary:GetSprite(keyCode, preferredStyle, preferredPlatform) + assert(keyCode ~= nil, "Bad keyCode") + assert(type(preferredStyle) == "string" or preferredStyle == nil, "Bad preferredStyle") + assert(type(preferredPlatform) == "string" or preferredPlatform == nil, "Bad preferredPlatform") + + local sheet = self:PickSheet(keyCode, preferredStyle, preferredPlatform) if sheet then - return sheet:GetSprite(index) + return sheet:GetSprite(keyCode) end return nil end +--[=[ + Styles a GUI for a specific keycode + + ```lua + local InputImageLibrary = require("InputImageLibrary") + InputImageLibrary:StyleImage(script.Parent, Enum.KeyCode.ButtonA) + ``` + + @param gui ImageLabel | ImageButton + @param keyCode any -- The sprite keyCode to get + @param preferredStyle string -- The preferred style type to retrieve this in + @param preferredPlatform string -- The preferred platform to get the sprite for + @return Sprite +]=] +function InputImageLibrary:StyleImage(gui, keyCode, preferredStyle, preferredPlatform) + assert(typeof(gui) == "Instance" and (gui:IsA("ImageLabel") or gui:IsA("ImageButton")), "Bad gui") + assert(keyCode ~= nil, "Bad keyCode") + assert(type(preferredStyle) == "string" or preferredStyle == nil, "Bad preferredStyle") + assert(type(preferredPlatform) == "string" or preferredPlatform == nil, "Bad preferredPlatform") + + local sheet = self:PickSheet(keyCode, preferredStyle, preferredPlatform) + if sheet then + return sheet:GetSprite(keyCode):Style(gui) + end + + return nil +end + +function InputImageLibrary:_getDefaultPreferredPlatform() + -- Hack to select the right preferred platform + -- TODO: Maybe pass this into our selector? + local result = UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonA) + if not result then + return nil + end + + if string.find(result, "PlayStation") then + return "PlayStation" + elseif string.find(result, "Xbox") then + return "XBox" + else + return "XBox" + end +end + function InputImageLibrary:GetScaledImageLabel(keyCode, preferredStyle, preferredPlatform) + assert(keyCode ~= nil, "Bad keyCode") + assert(type(preferredStyle) == "string" or preferredStyle == nil, "Bad preferredStyle") + assert(type(preferredPlatform) == "string" or preferredPlatform == nil, "Bad preferredPlatform") + local image = self:_getImageInstance("ImageLabel", keyCode, preferredStyle or "Dark", preferredPlatform) if not image then return nil @@ -84,25 +141,33 @@ function InputImageLibrary:GetScaledImageLabel(keyCode, preferredStyle, preferre return image end -function InputImageLibrary:_pickSheet(index, preferredStyle, preferredPlatform) +function InputImageLibrary:PickSheet(keyCode, preferredStyle, preferredPlatform) + assert(keyCode ~= nil, "Bad keyCode") + assert(type(preferredStyle) == "string" or preferredStyle == nil, "Bad preferredStyle") + assert(type(preferredPlatform) == "string" or preferredPlatform == nil, "Bad preferredPlatform") + local function findSheet(platformSheets) local preferredSheet = platformSheets[preferredStyle] - if preferredSheet and preferredSheet:HasSprite(index) then + if preferredSheet and preferredSheet:HasSprite(keyCode) then return preferredSheet end -- otherwise search (yes, we double hit a sheet) for _, sheet in pairs(platformSheets) do - if sheet:HasSprite(index) then + if sheet:HasSprite(keyCode) then return sheet end end end - local sheet = self._spritesheets[preferredPlatform] - local preferredSheet = sheet and findSheet(sheet) - if preferredSheet then - return preferredSheet + preferredPlatform = preferredPlatform or self:_getDefaultPreferredPlatform() + + if preferredPlatform then + local sheet = self._spritesheets[preferredPlatform] + local preferredSheet = sheet and findSheet(sheet) + if preferredSheet and preferredSheet:HasSprite(keyCode) then + return preferredSheet + end end -- otherwise search (repeats preferred :/ ) @@ -114,17 +179,22 @@ function InputImageLibrary:_pickSheet(index, preferredStyle, preferredPlatform) end if not SUPRESS_UNFOUND_IMAGE_WARNING then - warn("[InputImageLibrary] - Unable to find sprite for", tostring(index), "type", typeof(index)) + warn("[InputImageLibrary] - Unable to find sprite for", tostring(keyCode), "type", typeof(keyCode)) end return nil end -function InputImageLibrary:_getImageInstance(instanceType, index, preferredStyle, preferredPlatform) - local sheet = self:_pickSheet(index, preferredStyle, preferredPlatform) +function InputImageLibrary:_getImageInstance(instanceType, keyCode, preferredStyle, preferredPlatform) + assert(type(instanceType) == "string", "Bad instanceType") + assert(keyCode ~= nil, "Bad keyCode") + assert(type(preferredStyle) == "string" or preferredStyle == nil, "Bad preferredStyle") + assert(type(preferredPlatform) == "string" or preferredPlatform == nil, "Bad preferredPlatform") + + local sheet = self:PickSheet(keyCode, preferredStyle, preferredPlatform) if sheet then - return sheet:GetSprite(index):Get(instanceType) + return sheet:GetSprite(keyCode):Get(instanceType) end return nil diff --git a/src/sprites/src/Shared/Sprite/Sprite.lua b/src/sprites/src/Shared/Sprite/Sprite.lua index ed76c1bb69..0d289275a1 100644 --- a/src/sprites/src/Shared/Sprite/Sprite.lua +++ b/src/sprites/src/Shared/Sprite/Sprite.lua @@ -39,6 +39,8 @@ end @return Instance ]=] function Sprite:Style(gui) + assert(typeof(gui) == "Instance" and (gui:IsA("ImageLabel") or gui:IsA("ImageButton")), "Bad gui") + gui.Image = self.Texture gui.ImageRectOffset = self.Position gui.ImageRectSize = self.Size @@ -52,6 +54,8 @@ end @return ImageLabel | ImageButton ]=] function Sprite:Get(instanceType) + assert(type(instanceType) == "string", "Bad instanceType") + local gui = Instance.new(instanceType) gui.Size = UDim2.new(0, self.Size.X, 0, self.Size.Y) gui.Name = self.Name diff --git a/src/sprites/src/Shared/Sprite/Spritesheet.lua b/src/sprites/src/Shared/Sprite/Spritesheet.lua index 366a8349cf..9425781ec9 100644 --- a/src/sprites/src/Shared/Sprite/Spritesheet.lua +++ b/src/sprites/src/Shared/Sprite/Spritesheet.lua @@ -34,43 +34,43 @@ function Spritesheet:GetPreloadAssetId() end --[=[ - @param index any + @param keyCode any @param position Vector2 @param size Vector2 - Adds a named sprite at the given index + Adds a named sprite at the given keyCode ]=] -function Spritesheet:AddSprite(index, position, size) - assert(not self._sprites[index], "Already exists") +function Spritesheet:AddSprite(keyCode, position, size) + assert(not self._sprites[keyCode], "Already exists") local sprite = Sprite.new({ Texture = self._texture; Position = position; Size = size; - Name = tostring(index); + Name = tostring(keyCode); }) - self._sprites[index] = sprite + self._sprites[keyCode] = sprite end --[=[ - Retrieves the sprite for the given index - @param index any | EnumItem + Retrieves the sprite for the given keyCode + @param keyCode any | EnumItem @return Sprite? ]=] -function Spritesheet:GetSprite(index) - if not index then +function Spritesheet:GetSprite(keyCode) + if not keyCode then warn("[Spritesheet.GetSprite] - Image name cannot be nil") return nil end - local sprite = self._sprites[index] + local sprite = self._sprites[keyCode] if sprite then return sprite end - if typeof(index) == "EnumItem" then - sprite = self._sprites[index.Name] + if typeof(keyCode) == "EnumItem" then + sprite = self._sprites[keyCode.Name] end return sprite @@ -78,11 +78,11 @@ end --[=[ Returns true if the sprite exists - @param index any | EnumItem + @param keyCode any | EnumItem @return boolean ]=] -function Spritesheet:HasSprite(index) - return self:GetSprite(index) ~= nil +function Spritesheet:HasSprite(keyCode) + return self:GetSprite(keyCode) ~= nil end return Spritesheet