mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 21:27:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
--[[
|
||||
]]
|
||||
local CoreGui = Game:GetService("CoreGui")
|
||||
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
|
||||
local Modules = GuiRoot:FindFirstChild("Modules")
|
||||
local GuiService = game:GetService("GuiService")
|
||||
local UserInputService = game:GetService("UserInputService")
|
||||
|
||||
local ThumbnailLoader = require(Modules:FindFirstChild('ThumbnailLoader'))
|
||||
local Utility = require(Modules:FindFirstChild('Utility'))
|
||||
|
||||
local function CreateImageSlider(size, position)
|
||||
local this = {}
|
||||
|
||||
local items = {}
|
||||
local maxItems = 0
|
||||
local currentItemIndex = 1
|
||||
local padding = 0
|
||||
local focusSize = 450
|
||||
local itemSize = 300
|
||||
local dataTable = nil
|
||||
|
||||
local lastSelectedObject = nil
|
||||
local newSelectedObjectCn = nil
|
||||
this.OnNewFocusItem = Utility.Signal()
|
||||
|
||||
local imageObjectToLoaderMap = {}
|
||||
|
||||
this.Container = Utility.Create'ScrollingFrame'
|
||||
{
|
||||
Name = "ImageSliderContainer";
|
||||
Size = size;
|
||||
Position = position;
|
||||
BackgroundTransparency = 1;
|
||||
ClipsDescendants = false;
|
||||
ScrollingEnabled = false;
|
||||
Selectable = false;
|
||||
ScrollBarThickness = 0;
|
||||
}
|
||||
|
||||
local function loadNewImage(item, dataIndex)
|
||||
if imageObjectToLoaderMap[item] then
|
||||
imageObjectToLoaderMap[item]:Cancel()
|
||||
imageObjectToLoaderMap[item] = nil
|
||||
end
|
||||
local iconId = dataTable[dataIndex].IconId
|
||||
local thumbLoader = ThumbnailLoader:Create(item, iconId,
|
||||
ThumbnailLoader.Sizes.Medium, ThumbnailLoader.AssetType.Icon)
|
||||
imageObjectToLoaderMap[item] = thumbLoader
|
||||
spawn(function()
|
||||
thumbLoader:LoadAsync()
|
||||
imageObjectToLoaderMap[item] = nil
|
||||
end)
|
||||
end
|
||||
|
||||
local MAX_LEFT = 2
|
||||
local MAX_RIGHT = 6
|
||||
-- TODO: Figure out left/right better
|
||||
local function recalcPositionAndSize(tweenTime, isRight, newSelectedObject)
|
||||
local smIconYPos = (focusSize - itemSize) / 2
|
||||
local startPosition = 0
|
||||
if currentItemIndex == 1 then
|
||||
startPosition = 0
|
||||
elseif currentItemIndex == 2 then
|
||||
startPosition = -1
|
||||
elseif maxItems == #items then
|
||||
startPosition = 1 - currentItemIndex
|
||||
elseif maxItems - currentItemIndex < MAX_RIGHT then
|
||||
startPosition = maxItems - currentItemIndex - MAX_RIGHT - MAX_LEFT
|
||||
else
|
||||
startPosition = -MAX_LEFT
|
||||
end
|
||||
|
||||
-- put front at back
|
||||
if maxItems > #items then
|
||||
if isRight == true and startPosition == -MAX_LEFT and currentItemIndex > 3 then
|
||||
local front = items[1]
|
||||
local back = items[#items]
|
||||
front.Position = UDim2.new(0, back.Position.X.Offset + back.Size.X.Offset + padding, 0, smIconYPos)
|
||||
this:RemoveFromFront()
|
||||
this:AddItemToBack(front)
|
||||
if dataTable and dataTable[currentItemIndex + MAX_RIGHT] then
|
||||
loadNewImage(front, currentItemIndex + MAX_RIGHT)
|
||||
end
|
||||
-- put back in front
|
||||
elseif isRight == false and currentItemIndex < maxItems - MAX_RIGHT and startPosition == -MAX_LEFT then
|
||||
local back = items[#items]
|
||||
local front = items[1]
|
||||
back.Position = UDim2.new(0, front.Position.X.Offset - padding - itemSize, 0, smIconYPos)
|
||||
this:RemoveFromBack()
|
||||
this:AddToFront(back)
|
||||
if dataTable and dataTable[currentItemIndex - MAX_LEFT] then
|
||||
loadNewImage(back, currentItemIndex - MAX_LEFT)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local currentXPosition = itemSize * startPosition + padding * startPosition
|
||||
for i = 1, #items do
|
||||
if items[i] == newSelectedObject then
|
||||
if tweenTime == 0 then
|
||||
items[i].Size = UDim2.new(0, focusSize, 0, focusSize)
|
||||
items[i].Position = UDim2.new(0, currentXPosition, 0, 0)
|
||||
else
|
||||
items[i]:TweenSizeAndPosition(UDim2.new(0, focusSize, 0, focusSize), UDim2.new(0, currentXPosition, 0, 0),
|
||||
Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, tweenTime, true)
|
||||
end
|
||||
currentXPosition = currentXPosition + focusSize + padding
|
||||
else
|
||||
if tweenTime == 0 then
|
||||
items[i].Size = UDim2.new(0, itemSize, 0, itemSize)
|
||||
items[i].Position = UDim2.new(0, currentXPosition, 0, smIconYPos)
|
||||
else
|
||||
items[i]:TweenSizeAndPosition(UDim2.new(0, itemSize, 0, itemSize), UDim2.new(0, currentXPosition, 0, smIconYPos),
|
||||
Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, tweenTime, true)
|
||||
end
|
||||
currentXPosition = currentXPosition + itemSize + padding
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Events ]]--
|
||||
newSelectedObjectCn = GuiService.Changed:connect(function(property)
|
||||
if property == 'SelectedCoreObject' then
|
||||
local selectedObject = GuiService.SelectedCoreObject
|
||||
if selectedObject and selectedObject ~= lastSelectedObject and selectedObject:IsDescendantOf(this.Container) then
|
||||
local isRight = nil
|
||||
if lastSelectedObject then
|
||||
-- slide left
|
||||
if lastSelectedObject.AbsolutePosition.x < selectedObject.AbsolutePosition.x then
|
||||
currentItemIndex = currentItemIndex + 1
|
||||
isRight = true
|
||||
-- slide right
|
||||
else
|
||||
currentItemIndex = currentItemIndex - 1
|
||||
isRight = false
|
||||
end
|
||||
end
|
||||
recalcPositionAndSize(lastSelectedObject and 0.25 or 0, isRight, selectedObject)
|
||||
lastSelectedObject = selectedObject
|
||||
this.OnNewFocusItem:fire(currentItemIndex, isRight, selectedObject)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
--[[ Public API ]]--
|
||||
function this:SetPosition(position)
|
||||
self.Container.Position = position
|
||||
end
|
||||
|
||||
function this:SetSize(size)
|
||||
self.Container.Size = size
|
||||
end
|
||||
|
||||
function this:SetParent(parent)
|
||||
self.Container.Parent = parent
|
||||
end
|
||||
|
||||
function this:SetFocusPosition(index)
|
||||
if index > 0 and index < #items + 1 then
|
||||
currentItemIndex = index
|
||||
recalcPositionAndSize(0, nil, items[currentItemIndex])
|
||||
end
|
||||
end
|
||||
|
||||
function this:SetDataTable(tbl)
|
||||
dataTable = tbl
|
||||
end
|
||||
|
||||
function this:SetMaxItems(value)
|
||||
local index = nil
|
||||
-- we're near the end, so we need to update image content
|
||||
if currentItemIndex > maxItems - MAX_RIGHT then
|
||||
-- find the current selected index in relation to image pool
|
||||
for i = 1, #items do
|
||||
if lastSelectedObject and items[i] == GuiService.SelectedCoreObject then
|
||||
index = i
|
||||
break
|
||||
end
|
||||
end
|
||||
-- TODO: Still might be a visual bug in some cases
|
||||
if index then
|
||||
-- replace images from front of pool
|
||||
for i = 1, index - 3 do
|
||||
if dataTable[currentItemIndex + i] then
|
||||
local item = items[1]
|
||||
loadNewImage(item, currentItemIndex + (maxItems - currentItemIndex) + i)
|
||||
print("NEW IMAGE:", currentItemIndex, ":", maxItems, ":", i, ":", currentItemIndex + (maxItems - currentItemIndex) + i)
|
||||
self:RemoveFromFront()
|
||||
self:AddItemToBack(item)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
maxItems = value
|
||||
recalcPositionAndSize(0)
|
||||
end
|
||||
|
||||
function this:SetPadding(newPadding)
|
||||
padding = newPadding
|
||||
end
|
||||
|
||||
function this:AddToFront(newItem)
|
||||
table.insert(items, 1, newItem)
|
||||
newItem.Parent = this.Container
|
||||
end
|
||||
|
||||
function this:AddItemToBack(newItem)
|
||||
if this and this.Container then
|
||||
items[#items + 1] = newItem
|
||||
newItem.Parent = this.Container
|
||||
end
|
||||
end
|
||||
|
||||
function this:AddItem(newItem)
|
||||
self:AddItemToBack(newItem)
|
||||
end
|
||||
|
||||
function this:RemoveFromFront()
|
||||
table.remove(items, 1)
|
||||
end
|
||||
|
||||
function this:RemoveFromBack()
|
||||
table.remove(items)
|
||||
end
|
||||
|
||||
function this:Destroy()
|
||||
if newSelectedObjectCn then
|
||||
newSelectedObjectCn:disconnect()
|
||||
newSelectedObjectCn = nil
|
||||
end
|
||||
this.Container:Destroy()
|
||||
this.OnNewFocus = nil
|
||||
this = nil
|
||||
end
|
||||
|
||||
return this
|
||||
end
|
||||
|
||||
return CreateImageSlider
|
||||
Reference in New Issue
Block a user