azul-sync 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/.gitattributes +1 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/README.md +142 -0
  5. package/dist/build.d.ts +19 -0
  6. package/dist/build.d.ts.map +1 -0
  7. package/dist/build.js +92 -0
  8. package/dist/build.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +397 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/config.d.ts +26 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +105 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/fs/fileWriter.d.ts +100 -0
  18. package/dist/fs/fileWriter.d.ts.map +1 -0
  19. package/dist/fs/fileWriter.js +342 -0
  20. package/dist/fs/fileWriter.js.map +1 -0
  21. package/dist/fs/treeManager.d.ts +84 -0
  22. package/dist/fs/treeManager.d.ts.map +1 -0
  23. package/dist/fs/treeManager.js +365 -0
  24. package/dist/fs/treeManager.js.map +1 -0
  25. package/dist/fs/watcher.d.ts +39 -0
  26. package/dist/fs/watcher.d.ts.map +1 -0
  27. package/dist/fs/watcher.js +120 -0
  28. package/dist/fs/watcher.js.map +1 -0
  29. package/dist/index.d.ts +61 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +349 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/ipc/httpPolling.d.ts +56 -0
  34. package/dist/ipc/httpPolling.d.ts.map +1 -0
  35. package/dist/ipc/httpPolling.js +171 -0
  36. package/dist/ipc/httpPolling.js.map +1 -0
  37. package/dist/ipc/messages.d.ts +112 -0
  38. package/dist/ipc/messages.d.ts.map +1 -0
  39. package/dist/ipc/messages.js +5 -0
  40. package/dist/ipc/messages.js.map +1 -0
  41. package/dist/ipc/server.d.ts +50 -0
  42. package/dist/ipc/server.d.ts.map +1 -0
  43. package/dist/ipc/server.js +168 -0
  44. package/dist/ipc/server.js.map +1 -0
  45. package/dist/pack.d.ts +19 -0
  46. package/dist/pack.d.ts.map +1 -0
  47. package/dist/pack.js +225 -0
  48. package/dist/pack.js.map +1 -0
  49. package/dist/push.d.ts +43 -0
  50. package/dist/push.d.ts.map +1 -0
  51. package/dist/push.js +532 -0
  52. package/dist/push.js.map +1 -0
  53. package/dist/rojo.d.ts +9 -0
  54. package/dist/rojo.d.ts.map +1 -0
  55. package/dist/rojo.js +114 -0
  56. package/dist/rojo.js.map +1 -0
  57. package/dist/snapshot/rojo.d.ts +39 -0
  58. package/dist/snapshot/rojo.d.ts.map +1 -0
  59. package/dist/snapshot/rojo.js +364 -0
  60. package/dist/snapshot/rojo.js.map +1 -0
  61. package/dist/snapshot.d.ts +23 -0
  62. package/dist/snapshot.d.ts.map +1 -0
  63. package/dist/snapshot.js +132 -0
  64. package/dist/snapshot.js.map +1 -0
  65. package/dist/sourcemap/generator.d.ts +78 -0
  66. package/dist/sourcemap/generator.d.ts.map +1 -0
  67. package/dist/sourcemap/generator.js +351 -0
  68. package/dist/sourcemap/generator.js.map +1 -0
  69. package/dist/sourcemap/propertyLoader.d.ts +19 -0
  70. package/dist/sourcemap/propertyLoader.d.ts.map +1 -0
  71. package/dist/sourcemap/propertyLoader.js +131 -0
  72. package/dist/sourcemap/propertyLoader.js.map +1 -0
  73. package/dist/util/id.d.ts +9 -0
  74. package/dist/util/id.d.ts.map +1 -0
  75. package/dist/util/id.js +14 -0
  76. package/dist/util/id.js.map +1 -0
  77. package/dist/util/log.d.ts +13 -0
  78. package/dist/util/log.d.ts.map +1 -0
  79. package/dist/util/log.js +51 -0
  80. package/dist/util/log.js.map +1 -0
  81. package/docs/assets/azul-logo.pdn +0 -0
  82. package/docs/assets/logo-200px.png +0 -0
  83. package/docs/assets/logo.png +0 -0
  84. package/docs/assets/plugin/toolbox.png +0 -0
  85. package/docs/assets/synced.png +0 -0
  86. package/package.json +41 -0
  87. package/plugin/README.md +54 -0
  88. package/plugin/sourcemap.json +264 -0
  89. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Actor/AzulSync.server.luau +905 -0
  90. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/AzulService.luau +1010 -0
  91. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Config.luau +29 -0
  92. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Enums.luau +11 -0
  93. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/CollapsibleTitledSection.luau +214 -0
  94. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/ColorPicker.luau +360 -0
  95. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/CustomTextButton.luau +170 -0
  96. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/DropdownMenu.luau +363 -0
  97. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/HorizontalLine.luau +43 -0
  98. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/ImageButtonWithText.luau +181 -0
  99. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledCheckbox.luau +295 -0
  100. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledColorInputPicker.luau +294 -0
  101. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledMultiChoice.luau +163 -0
  102. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledNumberInput.luau +312 -0
  103. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledRadioButton.luau +55 -0
  104. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledSlider.luau +151 -0
  105. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledTextInput.luau +222 -0
  106. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledToggleButton.luau +73 -0
  107. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/StatefulImageButton.luau +125 -0
  108. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticalScrollingFrame.luau +100 -0
  109. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticalSpacer.luau +35 -0
  110. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticallyScalingListFrame.luau +107 -0
  111. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/GuiUtilities.luau +429 -0
  112. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/RbxGui.luau +4363 -0
  113. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/UI.luau +425 -0
  114. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/WebSocketClient.luau +161 -0
  115. package/src/build.ts +120 -0
  116. package/src/cli.ts +496 -0
  117. package/src/config.ts +170 -0
  118. package/src/fs/fileWriter.ts +414 -0
  119. package/src/fs/treeManager.ts +458 -0
  120. package/src/fs/watcher.ts +142 -0
  121. package/src/index.ts +450 -0
  122. package/src/ipc/httpPolling.ts +214 -0
  123. package/src/ipc/messages.ts +159 -0
  124. package/src/ipc/server.ts +196 -0
  125. package/src/pack.ts +309 -0
  126. package/src/push.ts +726 -0
  127. package/src/snapshot/rojo.ts +467 -0
  128. package/src/snapshot.ts +161 -0
  129. package/src/sourcemap/generator.ts +504 -0
  130. package/src/sourcemap/propertyLoader.ts +195 -0
  131. package/src/util/id.ts +15 -0
  132. package/src/util/log.ts +94 -0
  133. package/tsconfig.json +24 -0
@@ -0,0 +1,222 @@
1
+ ----------------------------------------
2
+ --
3
+ -- LabeledTextInput.lua
4
+ --
5
+ -- Creates a frame containing a label and a text input control.
6
+ --
7
+ ----------------------------------------
8
+ GuiUtilities = require("../GuiUtilities")
9
+
10
+ local kTextInputWidth = 130
11
+ local kTextBoxInternalPadding = 4
12
+ local kReadOnlyTransparency = 0.55
13
+
14
+ LabeledTextInputClass = {}
15
+ LabeledTextInputClass.__index = LabeledTextInputClass
16
+
17
+ --- LabeledTextInputClass constructor.
18
+ --- @param nameSuffix string -- The name suffix of the text input.
19
+ --- @param labelText string -- The text of the label.
20
+ --- @param defaultValue string? -- The default value of the text input.
21
+ --- @param readonly boolean? -- Whether or not it is read only.
22
+ --- @return LabeledTextInputClass The text input class object.
23
+ function LabeledTextInputClass.new(nameSuffix: string, labelText: string, defaultValue: string?, readonly: boolean?)
24
+ local self = {}
25
+ setmetatable(self, LabeledTextInputClass)
26
+
27
+ -- Note: we are using "graphemes" instead of characters.
28
+ -- In modern text-manipulation-fu, what with internationalization,
29
+ -- emojis, etc, it's not enough to count characters, particularly when
30
+ -- concerned with "how many <things> am I rendering?".
31
+ -- We are using the
32
+ self._MaxGraphemes = 50
33
+
34
+ self._valueChangedFunction = nil
35
+
36
+ defaultValue = defaultValue or ""
37
+
38
+ local frame = GuiUtilities.MakeStandardFixedHeightFrame("TextInput " .. nameSuffix)
39
+ self._frame = frame
40
+
41
+ local label = GuiUtilities.MakeStandardPropertyLabel(labelText)
42
+ label.Parent = frame
43
+ self._label = label
44
+
45
+ self._value = defaultValue
46
+
47
+ -- Dumb hack to add padding to text box,
48
+ local textBoxWrapperFrame = Instance.new("Frame")
49
+ textBoxWrapperFrame.Name = "Wrapper"
50
+ textBoxWrapperFrame.Size = UDim2.new(0, kTextInputWidth, 0.6, 0)
51
+ textBoxWrapperFrame.Position = UDim2.new(0, GuiUtilities.StandardLineElementLeftMargin, 0.5, 0)
52
+ textBoxWrapperFrame.AnchorPoint = Vector2.new(0, 0.5)
53
+ textBoxWrapperFrame.Parent = frame
54
+ GuiUtilities.syncGuiElementInputFieldColor(textBoxWrapperFrame)
55
+ GuiUtilities.syncGuiElementBorderColor(textBoxWrapperFrame)
56
+
57
+ local textBox = Instance.new("TextBox")
58
+ textBox.Parent = textBoxWrapperFrame
59
+ textBox.Name = "TextBox"
60
+ textBox.Text = defaultValue
61
+ textBox.PlaceholderText = defaultValue
62
+ textBox.Font = Enum.Font.SourceSans
63
+ textBox.TextSize = 15
64
+ textBox.BorderSizePixel = 0
65
+ textBox.BackgroundTransparency = 1
66
+ textBox.TextXAlignment = Enum.TextXAlignment.Left
67
+ textBox.Size = UDim2.new(1, -kTextBoxInternalPadding, 1, GuiUtilities.kTextVerticalFudge)
68
+ textBox.Position = UDim2.new(0, kTextBoxInternalPadding, 0, 0)
69
+ textBox.ClipsDescendants = true
70
+ -- textBox.ClearTextOnFocus = true
71
+ textBox.ClearTextOnFocus = false -- Changed to false to prevent accidental data loss.
72
+ textBox.TextEditable = true
73
+
74
+ GuiUtilities.syncGuiElementBackgroundColor(textBox)
75
+
76
+ textBox:GetPropertyChangedSignal("Text"):Connect(function()
77
+ -- Never let the text be too long.
78
+ -- Careful here: we want to measure number of graphemes, not characters,
79
+ -- in the text, and we want to clamp on graphemes as well.
80
+ if utf8.len(self._textBox.Text) > self._MaxGraphemes then
81
+ local count = 0
82
+ for start, stop in utf8.graphemes(self._textBox.Text) do
83
+ count = count + 1
84
+ if count > self._MaxGraphemes then
85
+ -- We have gone one too far.
86
+ -- clamp just before the beginning of this grapheme.
87
+ self._textBox.Text = string.sub(self._textBox.Text, 1, start - 1)
88
+ break
89
+ end
90
+ end
91
+ -- Don't continue with rest of function: the resetting of "Text" field
92
+ -- above will trigger re-entry. We don't need to trigger value
93
+ -- changed function twice.
94
+ return
95
+ end
96
+
97
+ self._value = self._textBox.Text
98
+ if self._valueChangedFunction then self._valueChangedFunction(self._value) end
99
+ end)
100
+
101
+ self._textBox = textBox
102
+ self._textBoxThemeConnection = nil :: RBXScriptConnection?
103
+ self._textBoxThemeFontConnection = nil :: RBXScriptConnection?
104
+ self:SetReadOnly(readonly)
105
+
106
+ return self
107
+ end
108
+
109
+ --- Sets the function to be called when the value changes.
110
+ --- @param vcf () -> () -- The function to call when the value changes.
111
+ function LabeledTextInputClass:SetValueChangedFunction(vcf: (newValue: string) -> ())
112
+ self._valueChangedFunction = vcf
113
+ end
114
+
115
+ --- Returns the UI frame associated with this input.
116
+ --- @return Frame -- The frame object.
117
+ function LabeledTextInputClass:GetFrame(): Frame
118
+ return self._frame
119
+ end
120
+
121
+ --- Gets the text box itself.
122
+ --- @return TextBox -- The text box.
123
+ function LabeledTextInputClass:GetTextBox(): TextBox
124
+ return self._textBox
125
+ end
126
+
127
+ --- Returns the maximum number of graphemes allowed.
128
+ --- @return number -- The maximum grapheme count.
129
+ function LabeledTextInputClass:GetMaxGraphemes(): number
130
+ return self._MaxGraphemes
131
+ end
132
+
133
+ --- Sets the maximum number of graphemes allowed.
134
+ --- @param newValue number -- The new maximum grapheme count.
135
+ function LabeledTextInputClass:SetMaxGraphemes(newValue)
136
+ self._MaxGraphemes = newValue
137
+ end
138
+
139
+ --- Returns the current value of the input.
140
+ --- @return string -- The current value.
141
+ function LabeledTextInputClass:GetValue(): string
142
+ return self._value
143
+ end
144
+
145
+ --- Sets this input text value.
146
+ --- @param newValue string -- The value to set.
147
+ function LabeledTextInputClass:SetValue(newValue: string)
148
+ if self._value ~= newValue then self._textBox.Text = newValue end
149
+ end
150
+
151
+ --- Gets this input text editable state.
152
+ --- @return boolean -- This input text editable state.
153
+ function LabeledTextInputClass:GetTextEditable(state: boolean)
154
+ return self._textBox.TextEditable
155
+ end
156
+
157
+ --- Sets this input text editable state.
158
+ ---
159
+ --- If not editable the user can't edit the contents of this input text.
160
+ --- @param state boolean -- Whether or not to set it as editable.
161
+ function LabeledTextInputClass:SetTextEditable(state: boolean)
162
+ self._textBox.TextEditable = state
163
+ end
164
+
165
+ --- Sets this input text clear text on focus state.
166
+ ---
167
+ --- If true the text inside this input text are cleared once the user focus it.
168
+ --- @param state boolean -- Whether or not to set it to clear text on focus.
169
+ function LabeledTextInputClass:SetClearTextOnFocusEnabled(state: boolean)
170
+ self._textBox.ClearTextOnFocus = state
171
+ end
172
+
173
+ --- Sets the function that runs when focus is lost.
174
+ --- @param funct (enterPressed: boolean, inputThatCausedFocusLoss: InputObject) -> () -- The function to run.
175
+ function LabeledTextInputClass:SetFocusLostFunction(funct: (
176
+ enterPressed: boolean,
177
+ inputThatCausedFocusLoss: InputObject
178
+ ) -> ())
179
+ self._textBox.FocusLost:Connect(funct)
180
+ end
181
+
182
+ --- Gets this input text read-only state.
183
+ --- @return boolean -- This input text read-only state.
184
+ function LabeledTextInputClass:GetReadOnly(): boolean
185
+ return self._readOnly
186
+ end
187
+
188
+ --- Sets this input text read-only state.
189
+ ---
190
+ --- Read-only text inputs are not editable and have a greyed out appearance.
191
+ --- @param state boolean -- Whether or not to set it as read-only.
192
+ function LabeledTextInputClass:SetReadOnly(state: boolean)
193
+ self._readOnly = state
194
+ if self._textBoxThemeConnection then self._textBoxThemeConnection:Disconnect() end
195
+ if self._textBoxThemeFontConnection then self._textBoxThemeFontConnection:Disconnect() end
196
+ if self._readOnly then
197
+ self._textBox.BackgroundTransparency = kReadOnlyTransparency
198
+ self._textBox.TextEditable = false
199
+ self._textBox.ClearTextOnFocus = false
200
+ self._textBoxThemeConnection = GuiUtilities.syncGuiElementColorCustom(
201
+ self._textBox,
202
+ "TextColor3",
203
+ Enum.StudioStyleGuideColor.MainText,
204
+ Enum.StudioStyleGuideModifier.Disabled
205
+ )
206
+ self._textBoxThemeFontConnection = GuiUtilities.syncGuiElementColorCustom(
207
+ self._label,
208
+ "TextColor3",
209
+ Enum.StudioStyleGuideColor.MainText,
210
+ Enum.StudioStyleGuideModifier.Disabled
211
+ )
212
+ else
213
+ self._textBox.BackgroundTransparency = 1
214
+ self._textBox.TextEditable = true
215
+ self._textBoxThemeConnection =
216
+ GuiUtilities.syncGuiElementColorCustom(self._textBox, "TextColor3", Enum.StudioStyleGuideColor.MainText)
217
+ self._textBoxThemeFontConnection =
218
+ GuiUtilities.syncGuiElementColorCustom(self._label, "TextColor3", Enum.StudioStyleGuideColor.MainText)
219
+ end
220
+ end
221
+
222
+ return LabeledTextInputClass
@@ -0,0 +1,73 @@
1
+ ----------------------------------------
2
+ --
3
+ -- LabeledToggleButtonClass.lua
4
+ --
5
+ -- Creates a frame containing a label and a toggle button.
6
+ --
7
+ ----------------------------------------
8
+ GuiUtilities = require("../GuiUtilities")
9
+ LabeledCheckbox = require("./LabeledCheckbox")
10
+
11
+ local kToggleOffDark = "rbxasset://textures/RoactStudioWidgets/toggle_off_dark.png"
12
+ local kToggleOnDark = "rbxasset://textures/RoactStudioWidgets/toggle_on_dark.png"
13
+
14
+ local kToggleOffLight = "rbxasset://textures/RoactStudioWidgets/toggle_off_light.png"
15
+ local kToggleOnLight = "rbxasset://textures/RoactStudioWidgets/toggle_on_light.png"
16
+
17
+ local kToggleOffDisabledDark = "rbxasset://textures/RoactStudioWidgets/toggle_disable_dark.png"
18
+ local kToggleOnDisabledDark = "rbxasset://textures/RoactStudioWidgets/toggle_on_disable_dark.png"
19
+
20
+ local kToggleOffDisabledLight = "rbxasset://textures/RoactStudioWidgets/toggle_disable_light.png"
21
+ local kToggleOnDisabledLight = "rbxasset://textures/RoactStudioWidgets/toggle_on_disable_light.png"
22
+
23
+ local kFrameSizeX = 28
24
+ local kFrameSizeY = 16
25
+
26
+ LabeledToggleButtonClass = {}
27
+ LabeledToggleButtonClass.__index = LabeledToggleButtonClass
28
+ setmetatable(LabeledToggleButtonClass, LabeledCheckbox)
29
+
30
+ --- LabeledToggleButtonClass constructor.
31
+ --- @param nameSuffix string -- Suffix to append to the name of the UI elements.
32
+ --- @param labelText string -- The label displayed next to the toggle button.
33
+ --- @return LabeledToggleButtonClass -- A new instance of the labeled toggle button class.
34
+ function LabeledToggleButtonClass.new(nameSuffix: string, labelText: string)
35
+ local newButton = LabeledCheckbox.new(nameSuffix, labelText, false)
36
+ setmetatable(newButton, LabeledToggleButtonClass)
37
+
38
+ newButton:GetFrame().Name = "TBF" .. nameSuffix
39
+ newButton._button.Size = UDim2.new(0, kFrameSizeX, 0, kFrameSizeY)
40
+ newButton._button.Image = ""
41
+ newButton._button.ImageColor3 = Color3.new(1,1,1)
42
+ newButton._button.BackgroundTransparency = 1
43
+ newButton._checkImage.ImageColor3 = Color3.new(1,1,1)
44
+
45
+ newButton:_UpdateAppearance()
46
+
47
+ return newButton
48
+ end
49
+
50
+ function LabeledToggleButtonClass:_MaybeToggleState()
51
+ if (not self._disabled) then
52
+ self:SetValue(not self._value)
53
+ end
54
+ end
55
+
56
+ function LabeledToggleButtonClass:_UpdateAppearance()
57
+ local themeName = GuiUtilities:GetThemeName()
58
+ if self:GetValue() then
59
+ if self:GetDisabled() then
60
+ self._checkImage.Image = if themeName == "Light" then kToggleOnDisabledLight else kToggleOnDisabledDark
61
+ else
62
+ self._checkImage.Image = if themeName == "Light" then kToggleOnLight else kToggleOnDark
63
+ end
64
+ else
65
+ if self:GetDisabled() then
66
+ self._checkImage.Image = if themeName == "Light" then kToggleOffDisabledLight else kToggleOffDisabledDark
67
+ else
68
+ self._checkImage.Image = if themeName == "Light" then kToggleOffLight else kToggleOffDark
69
+ end
70
+ end
71
+ end
72
+
73
+ return LabeledToggleButtonClass
@@ -0,0 +1,125 @@
1
+ ----------------------------------------
2
+ --
3
+ -- StatefulImageButton.lua
4
+ --
5
+ -- Image button.
6
+ -- Has custom image for when "selected"
7
+ -- Uses shading to indicate hover and click states.
8
+ --
9
+ ----------------------------------------
10
+ GuiUtilities = require("../GuiUtilities")
11
+
12
+ StatefulImageButtonClass = {}
13
+ StatefulImageButtonClass.__index = StatefulImageButtonClass
14
+
15
+ --- StatefulImageButtonClass constructor.
16
+ --- @param buttonName string -- The name of the button instance.
17
+ --- @param imageAsset string -- The asset ID or path for the button's image.
18
+ --- @param buttonSize UDim2 -- The size of the button.
19
+ --- @return StatefulImageButtonClass -- A new instance of the StatefulImageButtonClass.
20
+ function StatefulImageButtonClass.new(buttonName: string, imageAsset: string, buttonSize: UDim2)
21
+ local self = {}
22
+ setmetatable(self, StatefulImageButtonClass)
23
+
24
+ self._clickedFunction = nil
25
+
26
+ local button = Instance.new("ImageButton")
27
+ --button.Parent = parent
28
+ button.Image = imageAsset
29
+ button.BackgroundTransparency = 1
30
+ button.BorderSizePixel = 0
31
+ button.Size = buttonSize
32
+ button.Name = buttonName
33
+
34
+ self._button = button
35
+
36
+ self._hovered = false
37
+ self._clicked = false
38
+ self._selected = false
39
+
40
+ button.InputBegan:Connect(function(input)
41
+ if (input.UserInputType == Enum.UserInputType.MouseMovement) then
42
+ self._hovered = true
43
+ self:_UpdateButtonVisual()
44
+ end
45
+ end)
46
+
47
+
48
+ button.InputEnded:Connect(function(input)
49
+ if (input.UserInputType == Enum.UserInputType.MouseMovement) then
50
+ self._hovered = false
51
+ self._clicked = false
52
+ self:_UpdateButtonVisual()
53
+ end
54
+ end)
55
+
56
+ button.MouseButton1Down:Connect(function()
57
+ self._clicked = true
58
+ self:_UpdateButtonVisual()
59
+ end)
60
+
61
+ button.MouseButton1Up:Connect(function()
62
+ self._clicked = false
63
+ self:_UpdateButtonVisual()
64
+ end)
65
+
66
+ button.Activated:Connect(function (inputObject, timesPressed)
67
+ if self._clickedFunction then
68
+ self._clickedFunction(inputObject, timesPressed)
69
+ end
70
+ end)
71
+
72
+ self:_UpdateButtonVisual()
73
+
74
+ return self
75
+ end
76
+
77
+ -- Backwards compatibility (should be removed in the future)
78
+ StatefulImageButtonClass.setSelected = StatefulImageButtonClass.SetSelected
79
+ StatefulImageButtonClass.getSelected = StatefulImageButtonClass.GetSelected
80
+ StatefulImageButtonClass.getButton = StatefulImageButtonClass.GetButton
81
+
82
+ function StatefulImageButtonClass:_UpdateButtonVisual()
83
+ if (self._selected) then
84
+ self._button.ImageTransparency = 0
85
+ self._button.ImageColor3 = Color3.new(1,1,1)
86
+ else
87
+ self._button.ImageTransparency = 0.5
88
+ self._button.ImageColor3 = Color3.new(.5,.5,.5)
89
+ end
90
+
91
+ if (self._clicked) then
92
+ self._button.BackgroundTransparency = 0.8
93
+ elseif (self._hovered) then
94
+ self._button.BackgroundTransparency = 0.9
95
+ else
96
+ self._button.BackgroundTransparency = 1
97
+ end
98
+ end
99
+
100
+ --- Sets the selection state of the button.
101
+ --- @param selected boolean -- Whether the button should appear selected.
102
+ function StatefulImageButtonClass:SetSelected(selected)
103
+ self._selected = selected
104
+ self:_updateButtonVisual()
105
+ end
106
+
107
+ --- Gets the current selection state of the button.
108
+ --- @return boolean -- True if the button is selected, false otherwise.
109
+ function StatefulImageButtonClass:GetSelected()
110
+ return self._selected
111
+ end
112
+
113
+ --- Returns the underlying ImageButton instance.
114
+ --- @return ImageButton -- The ImageButton instance.
115
+ function StatefulImageButtonClass:GetButton()
116
+ return self._button
117
+ end
118
+
119
+ --- Sets the function to be called when the button is clicked.
120
+ --- @param cf (inputObject: InputObject, timesPressed: number) -> () -- A callback function or nil to remove the function.
121
+ function StatefulImageButtonClass:SetClickedFunction(cf: (inputObject: InputObject, timesPressed: number) -> () | nil)
122
+ self._clickedFunction = cf
123
+ end
124
+
125
+ return StatefulImageButtonClass
@@ -0,0 +1,100 @@
1
+ ----------------------------------------
2
+ --
3
+ -- VerticalScrollingFrame.lua
4
+ --
5
+ -- Creates a scrolling frame that automatically updates canvas size
6
+ --
7
+ ----------------------------------------
8
+
9
+ local GuiUtilities = require("../GuiUtilities")
10
+
11
+ local VerticalScrollingFrame = {}
12
+ VerticalScrollingFrame.__index = VerticalScrollingFrame
13
+
14
+ --- VerticalScrollingFrame constructor.
15
+ --- @param suffix string -- A suffix to append to the names of internal GUI elements for uniqueness.
16
+ --- @return table -- A new instance of the vertical scrolling frame class.
17
+ function VerticalScrollingFrame.new(suffix: string)
18
+ local self = {}
19
+ setmetatable(self, VerticalScrollingFrame)
20
+
21
+ local section = Instance.new("Frame")
22
+ section.BorderSizePixel = 0
23
+ section.Size = UDim2.new(1, 0, 1, 0)
24
+ section.Position = UDim2.new(0, 0, 0, 0)
25
+ section.BackgroundTransparency = 1
26
+ section.Name = "VerticalScrollFrame" .. suffix
27
+
28
+ local scrollBackground = Instance.new("Frame")
29
+ scrollBackground.Name = "ScrollbarBackground"
30
+ scrollBackground.BackgroundColor3 = Color3.fromRGB(238, 238, 238)
31
+ scrollBackground.BorderColor3 = Color3.fromRGB(182, 182, 182)
32
+ scrollBackground.Size = UDim2.new(0, 15, 1, -2)
33
+ scrollBackground.Position = UDim2.new(1, -16, 0, 1)
34
+ scrollBackground.Parent = section
35
+ scrollBackground.ZIndex = 2;
36
+
37
+ local scrollFrame = Instance.new("ScrollingFrame")
38
+ scrollFrame.Name = "ScrollFrame" .. suffix
39
+ scrollFrame.VerticalScrollBarPosition = Enum.VerticalScrollBarPosition.Right
40
+ scrollFrame.VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar
41
+ scrollFrame.ElasticBehavior = Enum.ElasticBehavior.Never
42
+ scrollFrame.ScrollBarThickness = 17
43
+ scrollFrame.BorderSizePixel = 0
44
+ scrollFrame.BackgroundTransparency = 1
45
+ scrollFrame.ZIndex = 2
46
+ scrollFrame.TopImage = "http://www.roblox.com/asset/?id=1533255544"
47
+ scrollFrame.MidImage = "http://www.roblox.com/asset/?id=1535685612"
48
+ scrollFrame.BottomImage = "http://www.roblox.com/asset/?id=1533256504"
49
+ scrollFrame.Size = UDim2.new(1, 0, 1, 0)
50
+ scrollFrame.Position = UDim2.new(0, 0, 0, 0)
51
+ scrollFrame.Parent = section
52
+
53
+ local uiListLayout = Instance.new("UIListLayout")
54
+ uiListLayout.SortOrder = Enum.SortOrder.LayoutOrder
55
+ uiListLayout.Parent = scrollFrame
56
+
57
+ self._section = section
58
+ self._scrollFrame = scrollFrame
59
+ self._scrollBackground = scrollBackground
60
+ self._uiListLayout = uiListLayout
61
+
62
+ scrollFrame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() self:_updateScrollingFrameCanvas() end)
63
+ uiListLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() self:_updateScrollingFrameCanvas() end)
64
+ self:_updateScrollingFrameCanvas()
65
+
66
+ GuiUtilities.syncGuiElementScrollColor(scrollFrame)
67
+ GuiUtilities.syncGuiElementBorderColor(scrollBackground)
68
+ GuiUtilities.syncGuiElementTitleColor(scrollBackground)
69
+
70
+ return self
71
+ end
72
+
73
+ function VerticalScrollingFrame:_updateScrollbarBackingVisibility()
74
+ self._scrollBackground.Visible = self._scrollFrame.AbsoluteSize.y < self._uiListLayout.AbsoluteContentSize.y
75
+ end
76
+
77
+ function VerticalScrollingFrame:_updateScrollingFrameCanvas()
78
+ self._scrollFrame.CanvasSize = UDim2.new(0, 0, 0, self._uiListLayout.AbsoluteContentSize.Y)
79
+ self:_updateScrollbarBackingVisibility()
80
+ end
81
+
82
+ --- Returns the internal ScrollingFrame that holds the scrollable content.
83
+ --- @return ScrollingFrame -- The scrolling content frame.
84
+ function VerticalScrollingFrame:GetContentsFrame(): Frame
85
+ return self._scrollFrame
86
+ end
87
+
88
+ --- Returns the top-level section frame that contains the scrollbar and scrollable content.
89
+ --- @return Frame -- The outer section frame.
90
+ function VerticalScrollingFrame:GetSectionFrame(): Frame
91
+ return self._section
92
+ end
93
+
94
+ --- Adds a child frame to the scrollable content area.
95
+ --- @param childFrame GuiObject -- The GUI object to be added to the scrollable content.
96
+ function VerticalScrollingFrame:AddChild(childFrame)
97
+ childFrame.Parent = self._scrollFrame
98
+ end
99
+
100
+ return VerticalScrollingFrame
@@ -0,0 +1,35 @@
1
+ ----------------------------------------
2
+ --
3
+ -- VerticalSpacerClass.lua
4
+ --
5
+ -- Creates an empty space of a fixed height
6
+ --
7
+ ----------------------------------------
8
+ GuiUtilities = require("../GuiUtilities")
9
+
10
+ local VerticalSpacerClass = {}
11
+ VerticalSpacerClass.__index = VerticalSpacerClass
12
+
13
+ --- VerticalSpacerClass constructor.
14
+ --- @param nameSuffix string -- A unique suffix to append to the spacer's name.
15
+ --- @param height number? -- Optional height of the spacer in pixels. Defaults to a preset value if not provided.
16
+ --- @return VerticalSpacerClass -- A new instance of the vertical spacer component.
17
+ function VerticalSpacerClass.new(nameSuffix: string, height: number?)
18
+ local self = setmetatable({}, VerticalSpacerClass)
19
+
20
+ local frame = GuiUtilities.MakeStandardFixedHeightFrame("VSPF " .. nameSuffix)
21
+ frame.BackgroundTransparency = 1
22
+ if height then frame.Size = UDim2.new(1, 0, 0, height) end
23
+
24
+ self._frame = frame
25
+
26
+ return self
27
+ end
28
+
29
+ --- Returns the UI frame representing the vertical spacer.
30
+ --- @return Frame -- The frame instance used for layout spacing.
31
+ function VerticalSpacerClass:GetFrame(): Frame
32
+ return self._frame
33
+ end
34
+
35
+ return VerticalSpacerClass
@@ -0,0 +1,107 @@
1
+ ----------------------------------------
2
+ --
3
+ -- VerticallyScalingListFrame
4
+ --
5
+ -- Creates a frame that organizes children into a list layout.
6
+ -- Will scale dynamically as children grow.
7
+ --
8
+ ----------------------------------------
9
+ GuiUtilities = require("../GuiUtilities")
10
+
11
+ VerticallyScalingListFrameClass = {}
12
+ VerticallyScalingListFrameClass.__index = VerticallyScalingListFrameClass
13
+
14
+ local kBottomPadding = 10
15
+
16
+ --- VerticallyScalingListFrameClass constructor.
17
+ --- @param nameSuffix string -- Suffix to append to the name of the scroll frame components.
18
+ --- @return VerticallyScalingListFrameClass -- A new instance of the vertically scaling list frame class.
19
+ function VerticallyScalingListFrameClass.new(nameSuffix: string)
20
+ local self = {}
21
+ setmetatable(self, VerticallyScalingListFrameClass)
22
+
23
+ self._resizeCallback = nil
24
+
25
+ local frame = Instance.new('Frame')
26
+ frame.Name = 'VSLFrame' .. nameSuffix
27
+ frame.Size = UDim2.new(1, 0, 0, 0)
28
+ frame.BackgroundTransparency = 0
29
+ frame.BorderSizePixel = 0
30
+ GuiUtilities.syncGuiElementBackgroundColor(frame)
31
+
32
+ self._frame = frame
33
+
34
+ local uiListLayout = Instance.new('UIListLayout')
35
+ uiListLayout.SortOrder = Enum.SortOrder.LayoutOrder
36
+ uiListLayout.Parent = frame
37
+ self._uiListLayout = uiListLayout
38
+
39
+ local function updateSizes()
40
+ self._frame.Size = UDim2.new(1, 0, 0, uiListLayout.AbsoluteContentSize.Y)
41
+ if (self._resizeCallback) then
42
+ self._resizeCallback()
43
+ end
44
+ end
45
+ self._uiListLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(updateSizes)
46
+ updateSizes()
47
+
48
+ self._childCount = 0
49
+
50
+ return self
51
+ end
52
+
53
+ --- Adds a transparent bottom padding frame to the list.
54
+ function VerticallyScalingListFrameClass:AddBottomPadding()
55
+ local frame = Instance.new("Frame")
56
+ frame.Name = "BottomPadding"
57
+ frame.BackgroundTransparency = 1
58
+ frame.Size = UDim2.new(1, 0, 0, kBottomPadding)
59
+ frame.LayoutOrder = 1000
60
+ frame.Parent = self._frame
61
+ end
62
+
63
+ --- Returns the internal UI frame containing all children.
64
+ --- @return Frame -- The internal frame used for layout.
65
+ function VerticallyScalingListFrameClass:GetFrame()
66
+ return self._frame
67
+ end
68
+
69
+ --- Adds a child frame to the list with automatic layout order.
70
+ --- @param childFrame GuiObject -- The child frame to add to the list.
71
+ function VerticallyScalingListFrameClass:AddChild(childFrame: GuiObject)
72
+ childFrame.LayoutOrder = self._childCount
73
+ self._childCount = self._childCount + 1
74
+ childFrame.Parent = self._frame
75
+ end
76
+
77
+ --- Sets a callback function to be called when the frame is resized.
78
+ --- @param callback function -- The function to call on resize.
79
+ function VerticallyScalingListFrameClass:SetCallbackOnResize(callback: () -> ())
80
+ self._resizeCallback = callback
81
+ end
82
+
83
+ --- Sets the horizontal alignment of elements in the UI list layout.
84
+ --- @param alignment Enum.HorizontalAlignment -- The desired horizontal alignment.
85
+ function VerticallyScalingListFrameClass:SetHorizontalAlignment(alignment: Enum.HorizontalAlignment)
86
+ self._uiListLayout.HorizontalAlignment = alignment
87
+ end
88
+
89
+ --- Sets the vertical alignment of elements in the UI list layout.
90
+ --- @param alignment Enum.VerticalAlignment -- The desired vertical alignment.
91
+ function VerticallyScalingListFrameClass:SetVerticalAlignment(alignment: Enum.VerticalAlignment)
92
+ self._uiListLayout.VerticalAlignment = alignment
93
+ end
94
+
95
+ --- Sets the fill direction of the UIListLayout inside the frame.
96
+ --- @param fillDirection Enum.FillDirection -- The direction in which UI elements will be laid out (Vertical or Horizontal).
97
+ function VerticallyScalingListFrameClass:SetFillDirection(fillDirection: Enum.FillDirection)
98
+ self._uiListLayout.FillDirection = fillDirection
99
+ end
100
+
101
+ --- Sets the padding between UI elements in the list layout.
102
+ --- @param padding UDim -- The space to apply between child elements.
103
+ function VerticallyScalingListFrameClass:SetLayoutPadding(padding: UDim)
104
+ self._uiListLayout.Padding = padding
105
+ end
106
+
107
+ return VerticallyScalingListFrameClass