General purpose modules for Roblox development. [Read-only Codeberg mirror]
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 248 lines 9.3 kB view raw
1--!optimize 2 2--!strict 3local module = {} 4 5local TextService = game:GetService("TextService") 6 7local X_ALIGNMENT_MAP = { 8 [Enum.TextXAlignment.Left] = Enum.HorizontalAlignment.Left, 9 [Enum.TextXAlignment.Center] = Enum.HorizontalAlignment.Center, 10 [Enum.TextXAlignment.Right] = Enum.HorizontalAlignment.Right, 11} 12local Y_ALIGNMENT_MAP = { 13 [Enum.TextYAlignment.Top] = Enum.VerticalAlignment.Top, 14 [Enum.TextYAlignment.Center] = Enum.VerticalAlignment.Center, 15 [Enum.TextYAlignment.Bottom] = Enum.VerticalAlignment.Bottom, 16} 17 18-- Creates a <code>Frame</code> from a <code>TextLabel</code> for easy manipulation of letters. 19-- Intended to be used with <code>InsertLetter(listFrame: Frame, letter: string, index: number): Frame?</code> 20function module.CreateFrameFromLabel(labelTemplate: TextLabel): Frame 21 local originalText = labelTemplate.Text 22 local originalSize = labelTemplate.Size 23 local originalPosition = labelTemplate.Position 24 local originalAnchorPoint = labelTemplate.AnchorPoint 25 local originalRotation = labelTemplate.Rotation 26 local originalName = labelTemplate.Name 27 local originalBackgroundColor3 = labelTemplate.BackgroundColor3 28 local originalBackgroundTransparency = labelTemplate.BackgroundTransparency 29 local originalXAlignment = labelTemplate.TextXAlignment 30 local originalYAlignment = labelTemplate.TextYAlignment 31 32 local listFrame = Instance.new("Frame") 33 listFrame.Name = originalName 34 listFrame.Size = originalSize 35 listFrame.Position = originalPosition 36 listFrame.AnchorPoint = originalAnchorPoint 37 listFrame.Rotation = originalRotation 38 listFrame.BorderSizePixel = 0 39 listFrame.BackgroundTransparency = 1 40 listFrame.ClipsDescendants = true 41 listFrame:SetAttribute("OriginalBackgroundColor3", originalBackgroundColor3) 42 listFrame:SetAttribute("OriginalBackgroundTransparency", originalBackgroundTransparency) 43 listFrame:SetAttribute("OriginalText", originalText) 44 45 local layout = Instance.new("UIListLayout") 46 layout.Name = "LetterLayout" 47 layout.FillDirection = Enum.FillDirection.Horizontal 48 layout.Wraps = true 49 layout.HorizontalAlignment = X_ALIGNMENT_MAP[originalXAlignment] or Enum.HorizontalAlignment.Left 50 layout.VerticalAlignment = Y_ALIGNMENT_MAP[originalYAlignment] or Enum.VerticalAlignment.Top 51 layout.SortOrder = Enum.SortOrder.LayoutOrder 52 layout.Parent = listFrame 53 54 return listFrame 55end 56 57-- Transforms a <code>TextLabel</code> into a <code>Frame</code> for easy manipulation of letters. 58-- Letter index is stored in <code>LayoutOrder</code> for each <code>Frame</code>. 59-- Stores necessary style information as attributes on the returned <code>Frame</code>. 60function module.TransformText(labelToTransform: TextLabel): Frame 61 local originalText = labelToTransform.Text 62 local originalParent = labelToTransform.Parent 63 local originalFontFace = labelToTransform.FontFace 64 local originalTextSize = labelToTransform.TextSize 65 local originalTextColor = labelToTransform.TextColor3 66 local originalTextTransparency = labelToTransform.TextTransparency 67 local originalTextStrokeColor = labelToTransform.TextStrokeColor3 68 local originalTextStrokeTransparency = labelToTransform.TextStrokeTransparency 69 local originalXAlignment = labelToTransform.TextXAlignment 70 local originalBackgroundColor3 = labelToTransform.BackgroundColor3 71 local originalBackgroundTransparency = labelToTransform.BackgroundTransparency 72 73 local listFrame = module.CreateFrameFromLabel(labelToTransform) 74 listFrame.BackgroundColor3 = originalBackgroundColor3 75 listFrame.BackgroundTransparency = originalBackgroundTransparency 76 77 listFrame:SetAttribute("LetterFontFace", originalFontFace) 78 listFrame:SetAttribute("LetterTextSize", originalTextSize) 79 listFrame:SetAttribute("LetterTextColor3", originalTextColor) 80 listFrame:SetAttribute("LetterTextTransparency", originalTextTransparency) 81 listFrame:SetAttribute("LetterTextStrokeColor3", originalTextStrokeColor) 82 listFrame:SetAttribute("LetterTextStrokeTransparency", originalTextStrokeTransparency) 83 listFrame:SetAttribute("LetterTextXAlignment", originalXAlignment) 84 85 local spaceParams = Instance.new("GetTextBoundsParams") 86 spaceParams.Font = originalFontFace 87 spaceParams.Size = originalTextSize 88 spaceParams.Text = " " 89 local success, spaceSize: Vector2 = pcall(function() 90 return TextService:GetTextBoundsAsync(spaceParams) 91 end) 92 if success then 93 listFrame:SetAttribute("SpaceSizeX", spaceSize.X) 94 listFrame:SetAttribute("SpaceSizeY", spaceSize.Y) 95 else 96 listFrame:SetAttribute("SpaceSizeX", 10) 97 listFrame:SetAttribute("SpaceSizeY", 10) 98 end 99 100 local charParams = Instance.new("GetTextBoundsParams") 101 charParams.Font = originalFontFace 102 charParams.Size = originalTextSize 103 104 local textLength = utf8.len(originalText) :: number 105 local childrenToParent: { Frame } = table.create(textLength) :: { Frame } 106 local childIndex = 0 107 for char in string.gmatch(originalText, ".") do 108 local charSize: Vector2 109 local isWhitespace = string.match(char, "%s") 110 111 if isWhitespace then 112 charSize = spaceSize 113 else 114 charParams.Text = char 115 charSize = TextService:GetTextBoundsAsync(charParams) 116 end 117 118 local textContainer = Instance.new("Frame") 119 textContainer.Name = char 120 textContainer.BackgroundTransparency = 1 121 textContainer.BorderSizePixel = 0 122 textContainer.Size = UDim2.fromOffset(charSize.X, charSize.Y) 123 textContainer.LayoutOrder = childIndex 124 125 if not isWhitespace then 126 local charLabel = Instance.new("TextLabel") 127 charLabel.Name = "CharLabel" 128 charLabel.FontFace = originalFontFace 129 charLabel.TextSize = originalTextSize 130 charLabel.TextColor3 = originalTextColor 131 charLabel.TextTransparency = originalTextTransparency 132 charLabel.TextStrokeColor3 = originalTextStrokeColor 133 charLabel.TextStrokeTransparency = originalTextStrokeTransparency 134 charLabel.BackgroundTransparency = 1 135 charLabel.Size = UDim2.fromScale(1, 1) 136 charLabel.Text = char 137 charLabel.TextXAlignment = originalXAlignment 138 charLabel.TextYAlignment = Enum.TextYAlignment.Center 139 charLabel.Parent = textContainer 140 end 141 142 childIndex += 1 143 childrenToParent[childIndex] = textContainer 144 end 145 146 for i = 1, childIndex do 147 childrenToParent[i].Parent = listFrame 148 end 149 150 table.clear(childrenToParent) 151 152 listFrame.Parent = originalParent 153 labelToTransform:Destroy() 154 155 return listFrame 156end 157 158-- Inserts a new letter (<code>Frame</code>) into the <code>listFrame</code> at the specified index. 159-- Adjusts <code>LayoutOrder</code> of subsequent letters. 160-- Returns the newly created letter <code>Frame</code> or <code>nil</code> if attributes are missing. 161function module.InsertLetter(listFrame: Frame, letter: string, index: number): Frame? 162 local fontFace = listFrame:GetAttribute("LetterFontFace") :: Font? 163 local textSize = listFrame:GetAttribute("LetterTextSize") :: number? 164 local textColor = listFrame:GetAttribute("LetterTextColor3") :: Color3? 165 local textTransparency = listFrame:GetAttribute("LetterTextTransparency") :: number? 166 local textStrokeColor = listFrame:GetAttribute("LetterTextStrokeColor3") :: Color3? 167 local textStrokeTransparency = listFrame:GetAttribute("LetterTextStrokeTransparency") :: number? 168 local textXAlignment = listFrame:GetAttribute("LetterTextXAlignment") :: Enum.TextXAlignment? 169 local spaceSizeX = listFrame:GetAttribute("SpaceSizeX") :: number? 170 local spaceSizeY = listFrame:GetAttribute("SpaceSizeY") :: number? 171 172 if 173 not ( 174 fontFace 175 and textSize 176 and textColor 177 and textTransparency 178 and textStrokeColor 179 and textStrokeTransparency 180 and textXAlignment 181 and spaceSizeX 182 and spaceSizeY 183 ) 184 then 185 warn("Cannot InsertLetter: listFrame is missing required style attributes.") 186 return nil 187 end 188 189 local spaceSize = Vector2.new(spaceSizeX, spaceSizeY) 190 191 local currentLetters: { Frame } = {} 192 for _, child in ipairs(listFrame:GetChildren()) do 193 if child:IsA("Frame") then 194 table.insert(currentLetters, child) 195 end 196 end 197 198 index = math.clamp(index, 0, #currentLetters) 199 200 for _, childFrame in ipairs(currentLetters) do 201 if childFrame.LayoutOrder >= index then 202 childFrame.LayoutOrder += 1 203 end 204 end 205 206 local charSize: Vector2 207 local isWhitespace = string.match(letter, "%s") 208 209 if isWhitespace then 210 charSize = spaceSize 211 else 212 local charParams = Instance.new("GetTextBoundsParams") 213 charParams.Font = fontFace 214 charParams.Size = textSize 215 charParams.Text = letter 216 charSize = TextService:GetTextBoundsAsync(charParams) 217 end 218 219 local textContainer = Instance.new("Frame") 220 textContainer.Name = letter 221 textContainer.BackgroundTransparency = 1 222 textContainer.BorderSizePixel = 0 223 textContainer.Size = UDim2.fromOffset(charSize.X, charSize.Y) 224 textContainer.LayoutOrder = index 225 226 if not isWhitespace then 227 local charLabel = Instance.new("TextLabel") 228 charLabel.Name = "CharLabel" 229 charLabel.FontFace = fontFace 230 charLabel.TextSize = textSize 231 charLabel.TextColor3 = textColor 232 charLabel.TextTransparency = textTransparency 233 charLabel.TextStrokeColor3 = textStrokeColor 234 charLabel.TextStrokeTransparency = textStrokeTransparency 235 charLabel.BackgroundTransparency = 1 236 charLabel.Size = UDim2.fromScale(1, 1) 237 charLabel.Text = letter 238 charLabel.TextXAlignment = textXAlignment 239 charLabel.TextYAlignment = Enum.TextYAlignment.Center 240 charLabel.Parent = textContainer 241 end 242 243 textContainer.Parent = listFrame 244 245 return textContainer 246end 247 248return module