Clients/Client2018/content/internal/AppShell/Modules/Shell/GameCarouselItem.lua

349 lines
9.2 KiB
Lua

local CoreGui = game:GetService("CoreGui")
local GuiService = game:GetService('GuiService')
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
local Modules = GuiRoot:FindFirstChild("Modules")
local ShellModules = Modules:FindFirstChild("Shell")
local GlobalSettings = require(ShellModules:FindFirstChild('GlobalSettings'))
local Strings = require(ShellModules:FindFirstChild('LocalizedStrings'))
local Utility = require(ShellModules:FindFirstChild('Utility'))
local LoadingWidget = require(ShellModules:FindFirstChild('LoadingWidget'))
local CarouselView = require(ShellModules:FindFirstChild('CarouselView'))
local CarouselController = require(ShellModules:FindFirstChild('CarouselController'))
local function GameCarouselItem(size, sortName, getGameCollection, onNewGameSelected, hasResultsChanged)
local this = {}
local myCarouselController = nil
local controllerMutex = false
local myCarouselView = CarouselView()
local TEXT_OFFSET = 112
local CAROUSEL_OFFSET = 110
local hasResults = true
local lockInPUP = false
--Initially is unlocked
local locked = false
local currentLoader = nil
local inFocus = false
local noSelectionObject = Utility.Create'ImageLabel'
{
Name = 'NoSelectionObject';
BackgroundTransparency = 1;
}
local container = Utility.Create'ImageButton'
{
Name = sortName.." ImageButton";
Size = size;
Position = UDim2.new(0, 0, 0, 0);
BorderSizePixel = 0;
BackgroundTransparency = 1;
ClipsDescendants = false;
AutoButtonColor = false;
SelectionImageObject = noSelectionObject;
Selectable = false;
}
local selectionHolder = Utility.Create'ImageLabel'
{
Name = sortName.." SelectionHolder";
BackgroundTransparency = 1;
Size = UDim2.new(0, 400, 1, 0);
Position = UDim2.new(0, 50, 0, 50);
SelectionImageObject = noSelectionObject;
Selectable = true;
Parent = container;
}
selectionHolder.NextSelectionLeft = selectionHolder
selectionHolder.NextSelectionRight = selectionHolder
local nameLabel = Utility.Create'TextLabel'
{
Name = "NameLabel";
Text = Strings:LocalizedString("LoadingWord");
Size = UDim2.new(0, 0, 0, 0);
Position = UDim2.new(0, TEXT_OFFSET, 0, 22);
TextXAlignment = Enum.TextXAlignment.Left;
TextColor3 = GlobalSettings.WhiteTextColor;
Font = GlobalSettings.RegularFont;
FontSize = Enum.FontSize.Size36; -- GlobalSettings.TitleSize;
BackgroundTransparency = 1;
Selectable = false;
Parent = container;
}
local function loadGameCollection(carouselController, carouselView, container)
local loaderImgTransparency = 0
if currentLoader then
loaderImgTransparency = Utility.Clamp(0, 1, currentLoader:GetTransparency())
currentLoader:Cleanup()
end
nameLabel.Text = Strings:LocalizedString("LoadingWord");
selectionHolder.Selectable = true
spawn(function()
local loader = LoadingWidget(
{ Parent = container; Position = UDim2.new(0.5, CAROUSEL_OFFSET, 0.5, 50); ImageTransparency = loaderImgTransparency },
{
function()
--The InitializeAsync will also remove old items if exist
carouselController:InitializeAsync(getGameCollection())
--The Connect will also remove old connections if exist
carouselController:Connect()
carouselController.NewItemSelected:connect(onNewGameSelected)
--Make sure this thread is the latest one, if so,
--make the callback and update selection
if this and myCarouselController == carouselController and myCarouselView == carouselView then
hasResults = carouselController:HasResults()
hasResultsChanged(this)
if hasResults then
selectionHolder.Selectable = false
nameLabel.Text = sortName
if this:IsSelected() then
this:RemoveFocus()
this:Focus()
end
else
selectionHolder.Selectable = true
nameLabel.Text = ""
end
else
if carouselView then
carouselView:SetParent(nil)
end
end
end
}
)
if currentLoader then
currentLoader:SetParent(nil)
end
currentLoader = loader
loader:AwaitFinished()
loader:Cleanup()
end)
end
function this:Init(Transparency)
Transparency = Transparency and Transparency or 0
myCarouselView:SetTransparency(Transparency)
myCarouselView:SetSize(UDim2.new(0, 1700, 0, 232))
myCarouselView:SetPosition(UDim2.new(0, CAROUSEL_OFFSET, 0, 50))
myCarouselView:SetPadding(20)
myCarouselView:SetItemSizePercentOfContainer(0.84)
myCarouselView:SetSelectionImageObject(
Utility.Create'ImageLabel'
{
BackgroundTransparency = 1;
}
)
myCarouselView:SetParent(container)
if myCarouselController then
myCarouselController:Disconnect()
end
if myCarouselController then
local prevFrontPageIndex, prevEndPageIndex, prevAbsoluteDataIndex = myCarouselController:GetIndexData()
myCarouselController = CarouselController(myCarouselView, true, prevFrontPageIndex, prevEndPageIndex, prevAbsoluteDataIndex)
else
myCarouselController = CarouselController(myCarouselView, true)
end
myCarouselController:SetLoadBuffer(15)
loadGameCollection(myCarouselController, myCarouselView, container)
end
function this:Refresh()
if myCarouselView then
if this:IsSelected() then
selectionHolder.Selectable = true
Utility.SetSelectedCoreObject(selectionHolder)
--Clear game data
onNewGameSelected(nil)
end
--Reset the old CarouselView
myCarouselView:RemoveFocus()
myCarouselView:RemoveAllItems()
myCarouselView:SetParent(nil)
--Init with previous Transparency
local prevTransparency = myCarouselView:GetTransparency()
myCarouselView = CarouselView()
this:Init(prevTransparency)
end
end
function this:HasResults()
return hasResults
end
function this:GetContainer()
return container
end
function this:ContainsItem(item)
return myCarouselView:ContainsItem(item)
end
function this:GetCarouselView()
return myCarouselView
end
function this:GetSortName()
return sortName
end
function this:GetNameText()
return nameLabel.Text
end
function this:SetNameText(name)
nameLabel.Text = name
end
-- Important subtle detail: the center of this needs to be in about the same
-- x-coordinate as the first item in each carousel so that selection doesn't
-- move laterally when you arrow up and down.
local LockOverlay = Utility.Create'ImageLabel'
{
Name = "LockOverlay";
Size = UDim2.new(0, 400, 1, 0);
Position = UDim2.new(0, 50, 0, 50);
BackgroundTransparency = 1;
Selectable = true;
SelectionImageObject = Utility.Create'ImageLabel'
{
BackgroundTransparency = 1;
};
ZIndex = 3;
}
LockOverlay.NextSelectionRight = LockOverlay
LockOverlay.NextSelectionLeft = LockOverlay
function this:Lock()
locked = true
LockOverlay.Parent = container
if this:IsSelected() then
this:RemoveFocus()
this:Focus()
end
myCarouselView:SetSelectable(false)
myCarouselView:SetClipsDescendants(true)
end
function this:Unlock()
locked = false
myCarouselView:SetSelectable(true)
myCarouselView:SetClipsDescendants(false)
if this:IsSelected() then
this:RemoveFocus()
this:Focus()
end
LockOverlay.Parent = nil
end
function this:IsLocked()
return locked
end
function this:SetLockInPUP(State)
lockInPUP = State
end
function this:GetLockInPUP()
return lockInPUP
end
function this:Focus()
if inFocus then return end
inFocus = true
if this then
if locked then
if myCarouselController then
onNewGameSelected(myCarouselController:GetFrontGameData(), true)
end
Utility.SetSelectedCoreObject(LockOverlay)
else
myCarouselView:Focus()
if not selectionHolder.Selectable and myCarouselView:GetAvailableItem() then
Utility.SetSelectedCoreObject(myCarouselView:GetAvailableItem())
else
Utility.SetSelectedCoreObject(selectionHolder)
--Clear game data
onNewGameSelected(nil)
end
end
end
end
function this:RemoveFocus()
if not inFocus then return end
myCarouselView:RemoveFocus()
inFocus = false
end
local fadeDuration = 0.2
local targetTextTransparency = 0
local textTransparencyTweens = {}
local function setTextTransparency(value, duration, refresh)
if not refresh and value == targetTextTransparency then return end
if duration then
targetTextTransparency = Utility.Clamp(0, 1, targetTextTransparency)
if not refresh and value == targetTextTransparency then return end
else
duration = fadeDuration
end
Utility.CancelTweens(textTransparencyTweens)
table.insert(textTransparencyTweens,
Utility.PropertyTweener(
nameLabel,
'TextTransparency',
targetTextTransparency,
value,
duration,
Utility.EaseOutQuad,
true))
targetTextTransparency = value
end
function this:SetTransparency(imageTransparency, textTransparency, duration, refresh)
setTextTransparency(textTransparency, duration, refresh)
myCarouselView:SetTransparency(imageTransparency, duration, refresh)
if currentLoader then
currentLoader:SetTransparency(Utility.Clamp(0, 1, imageTransparency))
end
end
function this:Destroy()
container:Destroy()
this = nil
end
function this:IsSelected()
if GuiService.SelectedCoreObject then
return GuiService.SelectedCoreObject == selectionHolder or myCarouselView:ContainsItem(GuiService.SelectedCoreObject) or
GuiService.SelectedCoreObject == LockOverlay
end
return false
end
return this
end
return GameCarouselItem