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,312 @@
1
+ ----------------------------------------
2
+ --
3
+ -- LabeledNumberInput.lua
4
+ --
5
+ -- Creates a frame containing a label and a number input control.
6
+ --
7
+ ----------------------------------------
8
+ GuiUtilities = require("../GuiUtilities")
9
+
10
+ local kNumberInputWidth = 89
11
+ local kArrowButtonWidth = 10
12
+ local kTextBoxInternalPadding = 4
13
+ local kReadOnlyTransparency = 0.55
14
+
15
+ LabeledNumberInputClass = {}
16
+ LabeledNumberInputClass.__index = LabeledNumberInputClass
17
+
18
+ --- LabeledNumberInputClass constructor.
19
+ --- @param nameSuffix string -- The name suffix of the number input.
20
+ --- @param labelText string -- The text of the label.
21
+ --- @param stepIncrement number? -- The increment value when pressing the arrow up or down.
22
+ --- @param defaultValue number? -- The default value of the number input.
23
+ --- @param readonly boolean? -- Whether or not it is read only.
24
+ --- @return LabeledNumberInputClass The number input class object.
25
+ function LabeledNumberInputClass.new(nameSuffix: string, labelText: string, stepIncrement: number?, defaultValue: number?, readonly: boolean?)
26
+ local self = {}
27
+ setmetatable(self, LabeledNumberInputClass)
28
+
29
+ -- Note: we are using "graphemes" instead of characters.
30
+ -- In modern text-manipulation-fu, what with internationalization,
31
+ -- emojis, etc, it's not enough to count characters, particularly when
32
+ -- concerned with "how many <things> am I rendering?".
33
+ -- We are using the
34
+ self._MaxGraphemes = 10
35
+
36
+ self._valueChangedFunction = nil
37
+
38
+ defaultValue = defaultValue or 0
39
+ stepIncrement = stepIncrement or 1
40
+
41
+ local frame = GuiUtilities.MakeStandardFixedHeightFrame('NumberInput ' .. nameSuffix)
42
+ self._frame = frame
43
+
44
+ local label = GuiUtilities.MakeStandardPropertyLabel(labelText)
45
+ label.Parent = frame
46
+ self._label = label
47
+
48
+ self._value = defaultValue
49
+
50
+ -- Dumb hack to add padding to text box,
51
+ local textBoxWrapperFrame = Instance.new("Frame")
52
+ textBoxWrapperFrame.Name = "Wrapper"
53
+ textBoxWrapperFrame.Size = UDim2.new(0, kNumberInputWidth, 0.6, 0)
54
+ textBoxWrapperFrame.Position = UDim2.new(0, GuiUtilities.StandardLineElementLeftMargin, .5, 0)
55
+ textBoxWrapperFrame.AnchorPoint = Vector2.new(0, .5)
56
+ textBoxWrapperFrame.Parent = frame
57
+ GuiUtilities.syncGuiElementInputFieldColor(textBoxWrapperFrame)
58
+ GuiUtilities.syncGuiElementBorderColor(textBoxWrapperFrame)
59
+
60
+ local textBox = Instance.new("TextBox")
61
+ textBox.Parent = textBoxWrapperFrame
62
+ textBox.Name = "TextBox"
63
+ textBox.Text = defaultValue
64
+ textBox.Font = Enum.Font.SourceSans
65
+ textBox.TextSize = 15
66
+ textBox.BorderSizePixel = 0
67
+ textBox.BackgroundTransparency = 1
68
+ textBox.TextXAlignment = Enum.TextXAlignment.Left
69
+ textBox.Size = UDim2.new(1, -kTextBoxInternalPadding, 1, GuiUtilities.kTextVerticalFudge)
70
+ textBox.Position = UDim2.new(0, kTextBoxInternalPadding, 0, 0)
71
+ textBox.ClipsDescendants = true
72
+ textBox.ClearTextOnFocus = false
73
+ textBox.TextEditable = true
74
+ GuiUtilities.syncGuiElementBackgroundColor(textBox)
75
+
76
+ local buttonUp = Instance.new("ImageButton")
77
+ buttonUp.Name = "ArrowUp"
78
+ buttonUp.Parent = textBoxWrapperFrame
79
+ buttonUp.AutoButtonColor = false
80
+ buttonUp.BorderSizePixel = 0
81
+ buttonUp.Image = "rbxasset:///textures/WindControl/ArrowUp.png"
82
+ buttonUp.Position = UDim2.new(1, 1, 0, 0)
83
+ buttonUp.Size = UDim2.new(0, kArrowButtonWidth, 0.5, 0)
84
+ GuiUtilities.syncGuiElementInputFieldColor(buttonUp)
85
+
86
+ local buttonDown = Instance.new("ImageButton")
87
+ buttonDown.Name = "ArrowDown"
88
+ buttonDown.Parent = textBoxWrapperFrame
89
+ buttonDown.AnchorPoint = Vector2.new(0, 1)
90
+ buttonDown.AutoButtonColor = false
91
+ buttonDown.BorderSizePixel = 0
92
+ buttonDown.Image = "rbxasset:///textures/WindControl/ArrowDown.png"
93
+ buttonDown.Position = UDim2.new(1, 1, 1, 0)
94
+ buttonDown.Size = UDim2.new(0, kArrowButtonWidth, 0.5, 0)
95
+ GuiUtilities.syncGuiElementInputFieldColor(buttonDown)
96
+
97
+ buttonUp.MouseEnter:Connect(function ()
98
+ if self._readOnly then return end
99
+ buttonUp.BackgroundColor3 = GuiUtilities.GetThemeColor(Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Hover)
100
+ end)
101
+
102
+ buttonUp.MouseLeave:Connect(function ()
103
+ if self._readOnly then return end
104
+ buttonUp.BackgroundColor3 = GuiUtilities.GetThemeColor(Enum.StudioStyleGuideColor.InputFieldBackground)
105
+ end)
106
+
107
+ buttonDown.MouseEnter:Connect(function ()
108
+ if self._readOnly then return end
109
+ buttonDown.BackgroundColor3 = GuiUtilities.GetThemeColor(Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Hover)
110
+ end)
111
+
112
+ buttonDown.MouseLeave:Connect(function ()
113
+ if self._readOnly then return end
114
+ buttonDown.BackgroundColor3 = GuiUtilities.GetThemeColor(Enum.StudioStyleGuideColor.InputFieldBackground)
115
+ end)
116
+
117
+ buttonUp.Activated:Connect(function ()
118
+ if self._readOnly then return end
119
+ local number = tonumber(self._textBox.Text)
120
+ number += stepIncrement
121
+ self._textBox.Text = tostring(self:_RoundToStep(number))
122
+ end)
123
+
124
+ buttonDown.Activated:Connect(function ()
125
+ if self._readOnly then return end
126
+ local number = tonumber(self._textBox.Text)
127
+ number -= stepIncrement
128
+ self._textBox.Text = tostring(self:_RoundToStep(number))
129
+ end)
130
+
131
+ textBox:GetPropertyChangedSignal("Text"):Connect(function()
132
+ -- Never let the text be too long.
133
+ -- Careful here: we want to measure number of graphemes, not characters,
134
+ -- in the text, and we want to clamp on graphemes as well.
135
+ if (utf8.len(self._textBox.Text) > self._MaxGraphemes) then
136
+ local count = 0
137
+ for start, stop in utf8.graphemes(self._textBox.Text) do
138
+ count = count + 1
139
+ if (count > self._MaxGraphemes) then
140
+ -- We have gone one too far.
141
+ -- clamp just before the beginning of this grapheme.
142
+ self._textBox.Text = string.sub(self._textBox.Text, 1, start-1)
143
+ break
144
+ end
145
+ end
146
+ -- Don't continue with rest of function: the resetting of "Text" field
147
+ -- above will trigger re-entry. We don't need to trigger value
148
+ -- changed function twice.
149
+ return
150
+ end
151
+
152
+ -- filter the input text below to ensure it's a valid integer or float
153
+ local lastChar = string.sub(self._textBox.Text, -1, -1)
154
+
155
+ if lastChar:match("%d") then
156
+ -- do nothing
157
+ elseif lastChar:match("%a") then
158
+ -- In a number input letters are not accepted, only numbers!
159
+ self._textBox.Text = string.sub(self._textBox.Text, 1, #self._textBox.Text - 1)
160
+ elseif lastChar == "-" then
161
+ -- Only accept '-' if it's at the very start and hasn't been used before
162
+ if #self._textBox.Text > 1 or self._textBox.Text:find("-", 2, true) then
163
+ self._textBox.Text = string.sub(self._textBox.Text, 1, #self._textBox.Text - 1)
164
+ end
165
+ elseif lastChar ~= "." then
166
+ -- We don't accept any symbols except dot
167
+ self._textBox.Text = string.sub(self._textBox.Text, 1, #self._textBox.Text - 1)
168
+ end
169
+
170
+ if self._textBox.Text:match("%..*%.") then
171
+ -- We don't accept multiple dots
172
+ self._textBox.Text = string.sub(self._textBox.Text, 1, #self._textBox.Text - 1)
173
+ end
174
+
175
+ if self._textBox.Text:match("%.(%d%d%d%d+)") then
176
+ -- We don't accept more than 3 decimals
177
+ self._textBox.Text = string.sub(self._textBox.Text, 1, #self._textBox.Text - 1)
178
+ end
179
+
180
+ self._value = tonumber(self._textBox.Text)
181
+ if (self._valueChangedFunction) then
182
+ self._valueChangedFunction(self._value)
183
+ end
184
+ end)
185
+
186
+ self._textBoxWrapperFrame = textBoxWrapperFrame
187
+ self._textBox = textBox
188
+ self._textBoxThemeConnection = nil :: RBXScriptConnection?
189
+ self._textBoxThemeFontConnection = nil :: RBXScriptConnection?
190
+ self._stepIncrement = stepIncrement
191
+ self._stepDecimalPlaces = self:_CountDecimalPlaces(stepIncrement)
192
+ self._buttonArrowUp = buttonUp
193
+ self._buttonArrowDown = buttonDown
194
+ self:SetReadOnly(readonly)
195
+
196
+ return self
197
+ end
198
+
199
+ function LabeledNumberInputClass:_RoundToDecimals(num: number, decimals: number)
200
+ -- rounds the decimals of a number to a maximum of decimals specified by the parameter
201
+ return tonumber(string.format("%." .. decimals .. "f", num))
202
+ end
203
+
204
+ function LabeledNumberInputClass:_RoundToStep(value: number)
205
+ -- rounds the value to the nearest step based on the stepIncrement variable
206
+ -- tries to avoid floating point imprecision (like 0.1 + 0.1 = 1.999)
207
+ local rounded = tonumber(string.format("%." .. self._stepDecimalPlaces .. "f", value))
208
+ return rounded
209
+ end
210
+
211
+ function LabeledNumberInputClass:_CountDecimalPlaces(num: number): number
212
+ -- counts the decimal places of a number
213
+ local _, decimal = tostring(num):match("^(%-?%d*)%.?(%d*)$")
214
+ return #decimal
215
+ end
216
+
217
+ --- Sets the function to be called when the value changes.
218
+ --- @param vcf () -> () -- The function to call when the value changes.
219
+ function LabeledNumberInputClass:SetValueChangedFunction(vcf: (newValue: number) -> ())
220
+ self._valueChangedFunction = vcf
221
+ end
222
+
223
+ --- Returns the UI frame associated with this input.
224
+ --- @return Frame -- The frame object.
225
+ function LabeledNumberInputClass:GetFrame(): Frame
226
+ return self._frame
227
+ end
228
+
229
+ --- Gets the text box itself.
230
+ --- @return TextBox -- The text box.
231
+ function LabeledNumberInputClass:GetTextBox(): TextBox
232
+ return self._textBox
233
+ end
234
+
235
+ --- Returns the maximum number of graphemes allowed.
236
+ --- @return number -- The maximum grapheme count.
237
+ function LabeledNumberInputClass:GetMaxGraphemes(): number
238
+ return self._MaxGraphemes
239
+ end
240
+
241
+ --- Sets the maximum number of graphemes allowed.
242
+ --- @param newValue number -- The new maximum grapheme count.
243
+ function LabeledNumberInputClass:SetMaxGraphemes(newValue)
244
+ self._MaxGraphemes = newValue
245
+ end
246
+
247
+ --- Returns the current value of the input.
248
+ --- @return number -- The current value.
249
+ function LabeledNumberInputClass:GetValue(): number
250
+ return self._value
251
+ end
252
+
253
+ --- Sets this input number value.
254
+ --- @param newValue number -- The value to set.
255
+ function LabeledNumberInputClass:SetValue(newValue: number)
256
+ if self._value ~= newValue then
257
+ self._value = self:_RoundToDecimals(newValue, 3)
258
+ self._textBox.Text = self._value
259
+ end
260
+ end
261
+
262
+ --- Sets the function that runs when focus is lost.
263
+ --- @param funct (enterPressed: boolean, inputThatCausedFocusLoss: InputObject) -> () -- The function to run.
264
+ function LabeledNumberInputClass:SetFocusLostFunction(funct: (enterPressed: boolean, inputThatCausedFocusLoss: InputObject) -> ())
265
+ self._textBox.FocusLost:Connect(funct)
266
+ end
267
+
268
+ --- Gets this input text read-only state.
269
+ --- @return boolean -- This input text read-only state.
270
+ function LabeledNumberInputClass:GetReadOnly(): boolean
271
+ return self._readOnly
272
+ end
273
+
274
+ --- Sets this input read-only state.
275
+ ---
276
+ --- Read-only inputs are not editable and have a greyed out appearance.
277
+ --- @param state boolean -- Whether or not to set it as read-only.
278
+ function LabeledNumberInputClass:SetReadOnly(state: boolean)
279
+ self._readOnly = state
280
+ if self._textBoxThemeConnection then self._textBoxThemeConnection:Disconnect() end
281
+ if self._textBoxThemeFontConnection then self._textBoxThemeFontConnection:Disconnect() end
282
+ if self._readOnly then
283
+ self._buttonArrowUp.BackgroundTransparency = kReadOnlyTransparency
284
+ self._buttonArrowDown.BackgroundTransparency = kReadOnlyTransparency
285
+ self._textBoxWrapperFrame.BackgroundTransparency = kReadOnlyTransparency
286
+ self._textBox.TextEditable = false
287
+ self._textBoxThemeConnection = GuiUtilities.syncGuiElementColorCustom(self._textBox, "TextColor3", Enum.StudioStyleGuideColor.MainText, Enum.StudioStyleGuideModifier.Disabled)
288
+ self._textBoxThemeFontConnection = GuiUtilities.syncGuiElementColorCustom(self._label, "TextColor3", Enum.StudioStyleGuideColor.MainText, Enum.StudioStyleGuideModifier.Disabled)
289
+ else
290
+ self._buttonArrowUp.BackgroundTransparency = 0
291
+ self._buttonArrowDown.BackgroundTransparency = 0
292
+ self._textBoxWrapperFrame.BackgroundTransparency = 0
293
+ self._textBox.TextEditable = true
294
+ self._textBoxThemeConnection = GuiUtilities.syncGuiElementColorCustom(self._textBox, "TextColor3", Enum.StudioStyleGuideColor.MainText)
295
+ self._textBoxThemeFontConnection = GuiUtilities.syncGuiElementColorCustom(self._label, "TextColor3", Enum.StudioStyleGuideColor.MainText)
296
+ end
297
+ end
298
+
299
+ --- Gets the currently set step increment.
300
+ --- @return number -- This input step increment.
301
+ function LabeledNumberInputClass:GetStepIncrement(): number
302
+ return self._stepIncrement
303
+ end
304
+
305
+ --- Sets the currently set step increment.
306
+ --- @param stepIncrement number -- The step increment.
307
+ function LabeledNumberInputClass:SetStepIncrement(stepIncrement: number)
308
+ self._stepIncrement = stepIncrement
309
+ self._stepDecimalPlaces = self:_CountDecimalPlaces(self._stepIncrement)
310
+ end
311
+
312
+ return LabeledNumberInputClass
@@ -0,0 +1,55 @@
1
+ ----------------------------------------
2
+ --
3
+ -- LabeledRadioButton.lua
4
+ --
5
+ -- Creates a frame containing a label and a radio button.
6
+ --
7
+ ----------------------------------------
8
+ GuiUtilities = require("../GuiUtilities")
9
+ LabeledCheckbox = require("./LabeledCheckbox")
10
+
11
+ local kDefaultImage = "rbxasset://textures/RoactStudioWidgets/button_radiobutton_default.png"
12
+ local kEnabledImageLight = "rbxasset://textures/RoactStudioWidgets/button_radiobutton_chosen.png"
13
+ local kEnabledImageDark = kEnabledImageLight
14
+ local kRadioFrameImage = kDefaultImage
15
+
16
+ LabeledRadioButtonClass = {}
17
+ LabeledRadioButtonClass.__index = LabeledRadioButtonClass
18
+ setmetatable(LabeledRadioButtonClass, LabeledCheckbox)
19
+
20
+ --- LabeledRadioButtonClass constructor.
21
+ --- @param nameSuffix string -- Suffix to append to the name of the UI elements.
22
+ --- @param labelText string -- The label displayed next to the radio button.
23
+ --- @return LabeledRadioButtonClass -- A new instance of the labeled radio button class.
24
+ function LabeledRadioButtonClass.new(nameSuffix: string, labelText: string)
25
+ local newButton = LabeledCheckbox.new(nameSuffix, labelText, false)
26
+ setmetatable(newButton, LabeledRadioButtonClass)
27
+
28
+ newButton:GetFrame().Name = "RBF" .. nameSuffix
29
+ newButton:UseSmallSize()
30
+ newButton._checkImage.Position = UDim2.new(0.5, 0, 0.5, 0)
31
+ newButton._checkImage.Image = ""
32
+ newButton._button.Image = kRadioFrameImage
33
+
34
+ return newButton
35
+ end
36
+
37
+ function LabeledRadioButtonClass:_MaybeToggleState()
38
+ -- A radio can never be toggled off.
39
+ -- Only turns off because another one turns on.
40
+ if (not self._disabled and not self._value) then
41
+ self:SetValue(not self._value)
42
+ end
43
+ end
44
+
45
+ function LabeledRadioButtonClass:_UpdateAppearance()
46
+ if self:GetValue() then
47
+ self._checkImage.Image = if GuiUtilities.GetThemeName() == "Light" then kEnabledImageLight else kEnabledImageDark
48
+ self._checkImage.ImageColor3 = if GuiUtilities.GetThemeName() == "Light" then Color3.fromRGB(219, 219, 219) else Color3.new(1, 1, 1)
49
+ else
50
+ self._checkImage.Image = ""
51
+ self._button.ImageColor3 = Color3.fromRGB(180, 180, 180)
52
+ end
53
+ end
54
+
55
+ return LabeledRadioButtonClass
@@ -0,0 +1,151 @@
1
+ ----------------------------------------
2
+ --
3
+ -- LabeledSlider.lua
4
+ --
5
+ -- Creates a frame containing a label and a slider control.
6
+ --
7
+ ----------------------------------------
8
+ GuiUtilities = require("../GuiUtilities")
9
+ rbxGuiLibrary = require("../RbxGui")
10
+
11
+ local kSliderWidth = 100
12
+
13
+ local kSliderThumbImage = "rbxasset://textures/RoactStudioWidgets/button_radiobutton_chosen.png"
14
+
15
+ local kThumbSize = 13
16
+
17
+ LabeledSliderClass = {}
18
+ LabeledSliderClass.__index = LabeledSliderClass
19
+
20
+ --- LabeledSliderClass constructor.
21
+ --- @param nameSuffix string -- Suffix to append to the slider's name.
22
+ --- @param labelText string -- Text to display as the label for the slider.
23
+ --- @param minValue number? -- Optional minimum value of the slider (default is 1).
24
+ --- @param maxValue number? -- Optional maximum value of the slider.
25
+ --- @param defaultValue number? -- Optional default value of the slider.
26
+ --- @param width number? -- Optional width of the slider component.
27
+ --- @return LabeledSliderClass -- A new instance of the labeled slider class.
28
+ function LabeledSliderClass.new(nameSuffix: string, labelText: string, minValue: number?, maxValue: number?, defaultValue: number?, width: number?)
29
+ local self = {}
30
+ setmetatable(self, LabeledSliderClass)
31
+
32
+ self._valueChangedFunction = nil
33
+
34
+ minValue = minValue or 0
35
+ maxValue = maxValue or 100
36
+ defaultValue = defaultValue or 1
37
+ width = width or kSliderWidth
38
+
39
+ local frame = GuiUtilities.MakeStandardFixedHeightFrame("SLF" .. nameSuffix)
40
+ self._frame = frame
41
+
42
+ local label = GuiUtilities.MakeStandardPropertyLabel(labelText)
43
+ label.Parent = frame
44
+ self._label = label
45
+
46
+ self._value = defaultValue
47
+
48
+ --steps, width, position
49
+ local slider, sliderValue = rbxGuiLibrary.CreateSliderNewest(minValue,maxValue,
50
+ width,
51
+ UDim2.new(0, 0, .5, -3))
52
+ self._slider = slider
53
+ self._sliderValue = sliderValue
54
+ -- Some tweaks to make slider look nice.
55
+ -- Hide the existing bar.
56
+ slider.Bar.BackgroundTransparency = 1
57
+ -- Replace slider thumb image.
58
+ self._thumb = slider.Bar.Slider
59
+ self._thumb.Image = kSliderThumbImage
60
+ self._thumb.AnchorPoint = Vector2.new(0.5, 0.5)
61
+ self._thumb.Size = UDim2.new(0, kThumbSize, 0, kThumbSize)
62
+
63
+ -- Add images on bar.
64
+ self._preThumbImage = Instance.new("ImageLabel")
65
+ self._preThumbImage.Name = "PreThumb"
66
+ self._preThumbImage.Parent = slider.Bar
67
+ self._preThumbImage.BackgroundColor3 = Color3.fromRGB(0, 162, 255)
68
+ self._preThumbImage.Image = ""
69
+ self._preThumbImage.Size = UDim2.new(1, 0, 1, 0)
70
+ self._preThumbImage.Position = UDim2.new(0, 0, 0, 0)
71
+ self._preThumbImage.BorderSizePixel = 0
72
+
73
+ self._postThumbImage = Instance.new("Frame")
74
+ self._postThumbImage.Name = "PostThumb"
75
+ self._postThumbImage.Parent = slider.Bar
76
+ self._postThumbImage.Size = UDim2.new(1, 0, 1, 0)
77
+ self._postThumbImage.Position = UDim2.new(0, 0, 0, 0)
78
+ self._postThumbImage.BorderSizePixel = 0
79
+
80
+ sliderValue.Changed:Connect(function()
81
+ self._value = sliderValue.Value
82
+
83
+ -- Min value is minValue.
84
+ -- Max value is maxValue.
85
+ -- So scale is...
86
+ local scale = (self._value - minValue) / (maxValue :: number - minValue :: number)
87
+
88
+ self._preThumbImage.Size = UDim2.new(scale, 0, 1, 0)
89
+ self._postThumbImage.Size = UDim2.new(1 - scale, 0, 1, 0)
90
+ self._postThumbImage.Position = UDim2.new(scale, 0, 0, 0)
91
+
92
+ self._thumb.Position = UDim2.new(scale, 0,
93
+ 0.5, 0)
94
+
95
+ if self._valueChangedFunction then
96
+ self._valueChangedFunction(self._value)
97
+ end
98
+ end)
99
+
100
+ GuiUtilities.BindThemeChanged(function () self:_UpdateColors() end)
101
+ self:_UpdateColors()
102
+
103
+ if defaultValue == sliderValue.Value then self:SetValue(maxValue) end -- if both are the same the slider won't update its position
104
+ self:SetValue(defaultValue)
105
+ slider.AnchorPoint = Vector2.new(0, 0.5)
106
+ slider.Size = UDim2.new(0, width, 1, 0)
107
+ slider.Position = UDim2.new(0, GuiUtilities.StandardLineElementLeftMargin, 0, GuiUtilities.kStandardPropertyHeight/2)
108
+ slider.Parent = frame
109
+
110
+ return self
111
+ end
112
+
113
+ --- Sets the function to be called when the slider value changes.
114
+ --- @param vcf function -- The callback function to execute on value change.
115
+ function LabeledSliderClass:SetValueChangedFunction(vcf)
116
+ self._valueChangedFunction = vcf
117
+ end
118
+
119
+ --- Returns the UI frame associated with this labeled slider.
120
+ --- @return Frame -- The slider's UI frame.
121
+ function LabeledSliderClass:GetFrame()
122
+ return self._frame
123
+ end
124
+
125
+ --- Sets the slider's current value.
126
+ --- @param newValue number -- The value to set.
127
+ function LabeledSliderClass:SetValue(newValue: number)
128
+ if self._sliderValue.Value ~= newValue then
129
+ self._sliderValue.Value = newValue
130
+ end
131
+ end
132
+
133
+ --- Gets the slider's current value.
134
+ --- @return number -- The current value of the slider.
135
+ function LabeledSliderClass:GetValue()
136
+ return self._sliderValue.Value
137
+ end
138
+
139
+ --- Changes the label text displayed above the slider.
140
+ --- @param labelText string -- New label text to display.
141
+ function LabeledSliderClass:SetLabelText(labelText: string)
142
+ assert(type(labelText) == "string", "Expected string. Got "..type(labelText))
143
+ self._label.Text = labelText
144
+ end
145
+
146
+ function LabeledSliderClass:_UpdateColors()
147
+ local guide = if GuiUtilities.GetThemeName() == "Light" then Enum.StudioStyleGuideColor.ScrollBarBackground else Enum.StudioStyleGuideColor.InputFieldBackground
148
+ self._postThumbImage.BackgroundColor3 = GuiUtilities.GetThemeColor(guide)
149
+ end
150
+
151
+ return LabeledSliderClass