Files
2025-09-18 17:55:52 -04:00

284 lines
8.3 KiB
Lua

--[[
// GameSort.lua
// Creates a grid layout for a game sort
]]
local CoreGui = Game:GetService("CoreGui")
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
local Modules = GuiRoot:FindFirstChild("Modules")
local GuiService = game:GetService('GuiService')
local Utility = require(Modules:FindFirstChild('Utility'))
local GlobalSettings = require(Modules:FindFirstChild('GlobalSettings'))
local EventHub = require(Modules:FindFirstChild('EventHub'))
local ScreenManager = require(Modules:FindFirstChild('ScreenManager'))
local SoundManager = require(Modules:FindFirstChild('SoundManager'))
local AssetManager = require(Modules:FindFirstChild('AssetManager'))
local PopupText = require(Modules:FindFirstChild('PopupText'))
local ThumbnailLoader = require(Modules:FindFirstChild('ThumbnailLoader'))
local Strings = require(Modules:FindFirstChild('LocalizedStrings'))
local ErrorOverlay = require(Modules:FindFirstChild('ErrorOverlay'))
local GameCollection = require(Modules:FindFirstChild('GameCollection'))
local GameSort = {}
local function createSortContainer(size)
local sortContainer = Utility.Create'Frame'
{
Name = "SortContainer";
Size = size;
BackgroundTransparency = 1;
}
return sortContainer
end
local function createSortTitle(name)
local sortTitleLabel = Utility.Create'TextLabel'
{
Name = "SortTitle";
Size = UDim2.new(1, 0, 0, 36);
Position = UDim2.new(0, 0, 0, 0);
BackgroundTransparency = 1;
Font = GlobalSettings.RegularFont;
FontSize = GlobalSettings.SubHeaderSize;
TextXAlignment = Enum.TextXAlignment.Left;
TextYAlignment = Enum.TextYAlignment.Top;
TextColor3 = GlobalSettings.WhiteTextColor;
Text = string.upper(name);
Parent = sortContainer;
}
return sortTitleLabel
end
local function createMoreButton(margin, parent)
-- we override the selection on moreButton to fit around the moreImage
local overrideSelection = Utility.Create'ImageLabel'
{
Name = "OverrideSelection";
Image = 'rbxasset://textures/ui/SelectionBox.png';
ScaleType = Enum.ScaleType.Slice;
SliceCenter = Rect.new(19,19,43,43);
BackgroundTransparency = 1;
}
local moreButton = Utility.Create'ImageButton'
{
Name = "MoreButton";
Size = UDim2.new(1, 0, 0, 50);
Position = UDim2.new(0, 0, 1, margin);
BackgroundTransparency = 1;
ZIndex = 2;
Visible = false;
SelectionImageObject = overrideSelection;
Parent = parent;
SoundManager:CreateSound('MoveSelection');
}
local moreImage = Utility.Create'ImageLabel'
{
Name = "MoreImage";
BackgroundTransparency = 1;
BorderSizePixel = 0;
ZIndex = 2;
Parent = moreButton;
}
local function updateMoreImage(isSelected)
local uri = isSelected and 'rbxasset://textures/ui/Shell/Buttons/MoreButtonSelected' or 'rbxasset://textures/ui/Shell/Buttons/MoreButton'
AssetManager.LocalImage(moreImage, uri, {['720'] = UDim2.new(0,72,0,33); ['1080'] = UDim2.new(0,108,0,50);})
moreImage.Position = UDim2.new(1, -moreImage.Size.X.Offset, 0, 0)
overrideSelection.Size = UDim2.new(0, moreImage.Size.X.Offset + 14, 0, moreImage.Size.Y.Offset + 14)
overrideSelection.Position = UDim2.new(1, -overrideSelection.Size.X.Offset + 7, 0, -7)
end
moreButton.SelectionGained:connect(function()
updateMoreImage(true)
end)
moreButton.SelectionLost:connect(function()
updateMoreImage(false)
end)
updateMoreImage(GuiService.SelectedCoreObject == moreButton)
return moreButton
end
local function createImageButton(size, position)
return Utility.Create'ImageButton'
{
Name = "GameThumbButton";
Size = size;
Position = position;
BackgroundTransparency = 0;
BorderSizePixel = 0;
BackgroundColor3 = GlobalSettings.ModalBackgroundColor;
ZIndex = 2;
AssetManager.CreateShadow(1);
SoundManager:CreateSound('MoveSelection');
}
end
local function createImageGrid(rows, columns, size, spacing, offset, images)
for i = 1, rows do
for j = 1, columns do
local image = createImageButton(size,
UDim2.new(0, (j - 1) * size.X.Offset + (j - 1) * spacing.x, 0, offset + (i - 1) * size.Y.Offset + (i - 1) * spacing.y))
table.insert(images, image)
image.Name = tostring(#images)
end
end
end
local function createPopupText(images)
local popupText = {}
for i = 1, #images do
local popup = PopupText(images[i], "")
table.insert(popupText, popup)
end
return popupText
end
local function setImages(imageIds, images)
local size = ThumbnailLoader.Sizes.Medium
local assetType = ThumbnailLoader.AssetType.Icon
for i = 1, #images do
if imageIds[i] then
local thumbLoader = ThumbnailLoader:Create(images[i], imageIds[i], size, assetType)
spawn(function()
if not thumbLoader:LoadAsync(true, false) then
-- TODO
end
end)
else
images[i].BackgroundColor3 = GlobalSettings.GreyButtonColor
images[i].Image = ""
local image = Utility.Create'ImageLabel'
{
Name = "NoGameImage";
Size = UDim2.new(0, 102, 0, 102);
BackgroundTransparency = 1;
Image = 'rbxasset://textures/ui/Shell/Icons/GamePlusIcon.png';
ZIndex = images[i].ZIndex;
Parent = images[i];
}
Utility.CalculateAnchor(image, UDim2.new(0.5, 0, 0.5, 0), Utility.Enum.Anchor.Center)
end
end
end
local function createBaseGrid(size, spacing, images)
local this = {}
this.Container = createSortContainer(size)
this.Title = createSortTitle("")
this.Title.Parent = this.Container
this.MoreButton = createMoreButton(spacing, this.Container)
for i = 1, #images do
images[i].Parent = this.Container
end
local popupText = createPopupText(images)
function this:SetParent(newParent)
self.Container.Parent = newParent
end
function this:GetContainer()
return self.Container
end
function this:SetPosition(newPosition)
self.Container.Position = newPosition
end
function this:SetTitle(newTitle)
self.Title.Text = string.upper(newTitle)
end
function this:SetVisible(value)
self.Container.Visible = value
end
function this:SetImages(imageIds)
setImages(imageIds, images)
end
function this:ConnectInput(ids, names, iconIds, sortName, gameCollection)
for i = 1, #images do
if ids[i] then
images[i].MouseButton1Click:connect(function()
EventHub:dispatchEvent(EventHub.Notifications["OpenGameDetail"], ids[i], names[i], iconIds[i])
end)
else
images[i].MouseButton1Click:connect(function()
-- If there are not enough games in my games section then let them know how to make more!
if gameCollection == GameCollection:GetUserPlaces() then
local titleAndMsg = {
Title = Strings:LocalizedString('PlayMyPlaceMoreGamesTitle');
Msg = Strings:LocalizedString('PlayMyPlaceMoreGamesPhrase');
}
ScreenManager:OpenScreen(ErrorOverlay(titleAndMsg, true), false)
else
-- if there is no game to load in this slot, we're going to redirect to the featured sort if the user presses this button
EventHub:dispatchEvent(EventHub.Notifications["OpenGameGenre"], Strings:LocalizedString('FeaturedTitle'), GameCollection:GetSort(3))
end
end)
end
if popupText[i] then
popupText[i]:SetText(names[i] or Strings:LocalizedString("MoreGamesPhrase"))
end
end
self.MoreButton.Visible = #ids > #images
self.MoreButton.MouseButton1Click:connect(function()
EventHub:dispatchEvent(EventHub.Notifications["OpenGameGenre"], sortName, gameCollection)
end)
end
function this:GetDefaultSelection()
local default = nil
if #images > 0 then
default = images[1]
end
return default
end
function this:Contains(guiObject)
for i = 1, #images do
if images[i] == guiObject then
return true
end
end
return false
end
function this:Destroy()
self.Container:Destroy()
end
return this
end
function GameSort:CreateMainGridView(size, spacing, lgImageSize, smImageSize)
local images = {}
local mainImage = createImageButton(lgImageSize, UDim2.new(0, 0, 0, 36))
table.insert(images, mainImage)
mainImage.Name = tostring(#images)
for i = 1, 2 do
local smImage = createImageButton(smImageSize,
UDim2.new(0, (i - 1) * smImageSize.X.Offset + (i - 1) * spacing.x, 1, -smImageSize.Y.Offset))
table.insert(images, smImage)
smImage.Name = tostring(#images)
end
local this = createBaseGrid(size, 12, images)
return this
end
-- 2x2 grid for the games page
function GameSort:CreateGridView(size, imageSize, spacing, rows, columns)
local images = {}
createImageGrid(rows, columns, imageSize, spacing, 36, images)
local this = createBaseGrid(size, 12, images)
return this
end
return GameSort