mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 12:45:05 +00:00
Use FontFace and consistent text sizing (#988)
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
* Improved settings UI ([#886])
|
* Improved settings UI ([#886])
|
||||||
* `Open Scripts Externally` option can now be changed while syncing ([#911])
|
* `Open Scripts Externally` option can now be changed while syncing ([#911])
|
||||||
* The sync reminder notification will now tell you what was last synced and when ([#987])
|
* The sync reminder notification will now tell you what was last synced and when ([#987])
|
||||||
|
* Fixed notification and tooltip text sometimes getting cut off ([#988])
|
||||||
* Projects may now specify rules for syncing files as if they had a different file extension. ([#813])
|
* Projects may now specify rules for syncing files as if they had a different file extension. ([#813])
|
||||||
This is specified via a new field on project files, `syncRules`:
|
This is specified via a new field on project files, `syncRules`:
|
||||||
|
|
||||||
@@ -89,6 +90,7 @@
|
|||||||
[#915]: https://github.com/rojo-rbx/rojo/pull/915
|
[#915]: https://github.com/rojo-rbx/rojo/pull/915
|
||||||
[#974]: https://github.com/rojo-rbx/rojo/pull/974
|
[#974]: https://github.com/rojo-rbx/rojo/pull/974
|
||||||
[#987]: https://github.com/rojo-rbx/rojo/pull/987
|
[#987]: https://github.com/rojo-rbx/rojo/pull/987
|
||||||
|
[#988]: https://github.com/rojo-rbx/rojo/pull/988
|
||||||
|
|
||||||
## [7.4.3] - August 6th, 2024
|
## [7.4.3] - August 6th, 2024
|
||||||
* Fixed issue with building binary files introduced in 7.4.2
|
* Fixed issue with building binary files introduced in 7.4.2
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ end
|
|||||||
|
|
||||||
function Checkbox:render()
|
function Checkbox:render()
|
||||||
return Theme.with(function(theme)
|
return Theme.with(function(theme)
|
||||||
theme = theme.Checkbox
|
local checkboxTheme = theme.Checkbox
|
||||||
|
|
||||||
local activeTransparency = Roact.joinBindings({
|
local activeTransparency = Roact.joinBindings({
|
||||||
self.binding:map(function(value)
|
self.binding:map(function(value)
|
||||||
@@ -63,14 +63,14 @@ function Checkbox:render()
|
|||||||
|
|
||||||
Active = e(SlicedImage, {
|
Active = e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBackground,
|
slice = Assets.Slices.RoundedBackground,
|
||||||
color = theme.Active.BackgroundColor,
|
color = checkboxTheme.Active.BackgroundColor,
|
||||||
transparency = activeTransparency,
|
transparency = activeTransparency,
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
zIndex = 2,
|
zIndex = 2,
|
||||||
}, {
|
}, {
|
||||||
Icon = e("ImageLabel", {
|
Icon = e("ImageLabel", {
|
||||||
Image = if self.props.locked then Assets.Images.Checkbox.Locked else Assets.Images.Checkbox.Active,
|
Image = if self.props.locked then Assets.Images.Checkbox.Locked else Assets.Images.Checkbox.Active,
|
||||||
ImageColor3 = theme.Active.IconColor,
|
ImageColor3 = checkboxTheme.Active.IconColor,
|
||||||
ImageTransparency = activeTransparency,
|
ImageTransparency = activeTransparency,
|
||||||
|
|
||||||
Size = UDim2.new(0, 16, 0, 16),
|
Size = UDim2.new(0, 16, 0, 16),
|
||||||
@@ -83,7 +83,7 @@ function Checkbox:render()
|
|||||||
|
|
||||||
Inactive = e(SlicedImage, {
|
Inactive = e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBorder,
|
slice = Assets.Slices.RoundedBorder,
|
||||||
color = theme.Inactive.BorderColor,
|
color = checkboxTheme.Inactive.BorderColor,
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
}, {
|
}, {
|
||||||
@@ -91,7 +91,7 @@ function Checkbox:render()
|
|||||||
Image = if self.props.locked
|
Image = if self.props.locked
|
||||||
then Assets.Images.Checkbox.Locked
|
then Assets.Images.Checkbox.Locked
|
||||||
else Assets.Images.Checkbox.Inactive,
|
else Assets.Images.Checkbox.Inactive,
|
||||||
ImageColor3 = theme.Inactive.IconColor,
|
ImageColor3 = checkboxTheme.Inactive.IconColor,
|
||||||
ImageTransparency = self.props.transparency,
|
ImageTransparency = self.props.transparency,
|
||||||
|
|
||||||
Size = UDim2.new(0, 16, 0, 16),
|
Size = UDim2.new(0, 16, 0, 16),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
|
local Plugin = Rojo.Plugin
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
|
|
||||||
local Roact = require(Packages.Roact)
|
local Roact = require(Packages.Roact)
|
||||||
@@ -7,6 +8,8 @@ Highlighter.matchStudioSettings()
|
|||||||
|
|
||||||
local e = Roact.createElement
|
local e = Roact.createElement
|
||||||
|
|
||||||
|
local Theme = require(Plugin.App.Theme)
|
||||||
|
|
||||||
local CodeLabel = Roact.PureComponent:extend("CodeLabel")
|
local CodeLabel = Roact.PureComponent:extend("CodeLabel")
|
||||||
|
|
||||||
function CodeLabel:init()
|
function CodeLabel:init()
|
||||||
@@ -40,22 +43,24 @@ function CodeLabel:updateHighlights()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function CodeLabel:render()
|
function CodeLabel:render()
|
||||||
return e("TextLabel", {
|
return Theme.with(function(theme)
|
||||||
Size = self.props.size,
|
return e("TextLabel", {
|
||||||
Position = self.props.position,
|
Size = self.props.size,
|
||||||
Text = self.props.text,
|
Position = self.props.position,
|
||||||
BackgroundTransparency = 1,
|
Text = self.props.text,
|
||||||
Font = Enum.Font.RobotoMono,
|
BackgroundTransparency = 1,
|
||||||
TextSize = 16,
|
FontFace = theme.Font.Code,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextSize = theme.TextSize.Code,
|
||||||
TextYAlignment = Enum.TextYAlignment.Top,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextColor3 = Color3.fromRGB(255, 255, 255),
|
TextYAlignment = Enum.TextYAlignment.Top,
|
||||||
[Roact.Ref] = self.labelRef,
|
TextColor3 = Color3.fromRGB(255, 255, 255),
|
||||||
}, {
|
[Roact.Ref] = self.labelRef,
|
||||||
SyntaxHighlights = e("Folder", {
|
}, {
|
||||||
[Roact.Ref] = self.highlightsRef,
|
SyntaxHighlights = e("Folder", {
|
||||||
}),
|
[Roact.Ref] = self.highlightsRef,
|
||||||
})
|
}),
|
||||||
|
})
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return CodeLabel
|
return CodeLabel
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
local TextService = game:GetService("TextService")
|
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
local Plugin = Rojo.Plugin
|
local Plugin = Rojo.Plugin
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
@@ -10,6 +8,7 @@ local Flipper = require(Packages.Flipper)
|
|||||||
local Assets = require(Plugin.Assets)
|
local Assets = require(Plugin.Assets)
|
||||||
local Theme = require(Plugin.App.Theme)
|
local Theme = require(Plugin.App.Theme)
|
||||||
local bindingUtil = require(Plugin.App.bindingUtil)
|
local bindingUtil = require(Plugin.App.bindingUtil)
|
||||||
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
||||||
|
|
||||||
local SlicedImage = require(script.Parent.SlicedImage)
|
local SlicedImage = require(script.Parent.SlicedImage)
|
||||||
local ScrollingFrame = require(script.Parent.ScrollingFrame)
|
local ScrollingFrame = require(script.Parent.ScrollingFrame)
|
||||||
@@ -44,29 +43,29 @@ end
|
|||||||
|
|
||||||
function Dropdown:render()
|
function Dropdown:render()
|
||||||
return Theme.with(function(theme)
|
return Theme.with(function(theme)
|
||||||
theme = theme.Dropdown
|
local dropdownTheme = theme.Dropdown
|
||||||
|
|
||||||
local optionButtons = {}
|
local optionButtons = {}
|
||||||
local width = -1
|
local width = -1
|
||||||
for i, option in self.props.options do
|
for i, option in self.props.options do
|
||||||
local text = tostring(option or "")
|
local text = tostring(option or "")
|
||||||
local textSize = TextService:GetTextSize(text, 15, Enum.Font.GothamMedium, Vector2.new(math.huge, 20))
|
local textBounds = getTextBoundsAsync(text, theme.Font.Main, theme.TextSize.Body, math.huge)
|
||||||
if textSize.X > width then
|
if textBounds.X > width then
|
||||||
width = textSize.X
|
width = textBounds.X
|
||||||
end
|
end
|
||||||
|
|
||||||
optionButtons[text] = e("TextButton", {
|
optionButtons[text] = e("TextButton", {
|
||||||
Text = text,
|
Text = text,
|
||||||
LayoutOrder = i,
|
LayoutOrder = i,
|
||||||
Size = UDim2.new(1, 0, 0, 24),
|
Size = UDim2.new(1, 0, 0, 24),
|
||||||
BackgroundColor3 = theme.BackgroundColor,
|
BackgroundColor3 = dropdownTheme.BackgroundColor,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
BackgroundTransparency = self.props.transparency,
|
BackgroundTransparency = self.props.transparency,
|
||||||
BorderSizePixel = 0,
|
BorderSizePixel = 0,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = dropdownTheme.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Body,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
|
|
||||||
[Roact.Event.Activated] = function()
|
[Roact.Event.Activated] = function()
|
||||||
if self.props.locked then
|
if self.props.locked then
|
||||||
@@ -103,13 +102,13 @@ function Dropdown:render()
|
|||||||
}, {
|
}, {
|
||||||
Border = e(SlicedImage, {
|
Border = e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBorder,
|
slice = Assets.Slices.RoundedBorder,
|
||||||
color = theme.BorderColor,
|
color = dropdownTheme.BorderColor,
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
}, {
|
}, {
|
||||||
DropArrow = e("ImageLabel", {
|
DropArrow = e("ImageLabel", {
|
||||||
Image = if self.props.locked then Assets.Images.Dropdown.Locked else Assets.Images.Dropdown.Arrow,
|
Image = if self.props.locked then Assets.Images.Dropdown.Locked else Assets.Images.Dropdown.Arrow,
|
||||||
ImageColor3 = theme.IconColor,
|
ImageColor3 = dropdownTheme.IconColor,
|
||||||
ImageTransparency = self.props.transparency,
|
ImageTransparency = self.props.transparency,
|
||||||
|
|
||||||
Size = UDim2.new(0, 18, 0, 18),
|
Size = UDim2.new(0, 18, 0, 18),
|
||||||
@@ -126,9 +125,9 @@ function Dropdown:render()
|
|||||||
Position = UDim2.new(0, 6, 0, 0),
|
Position = UDim2.new(0, 6, 0, 0),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = self.props.active,
|
Text = self.props.active,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = dropdownTheme.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
}),
|
}),
|
||||||
@@ -136,7 +135,7 @@ function Dropdown:render()
|
|||||||
Options = if self.state.open
|
Options = if self.state.open
|
||||||
then e(SlicedImage, {
|
then e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBackground,
|
slice = Assets.Slices.RoundedBackground,
|
||||||
color = theme.BackgroundColor,
|
color = dropdownTheme.BackgroundColor,
|
||||||
position = UDim2.new(1, 0, 1, 3),
|
position = UDim2.new(1, 0, 1, 3),
|
||||||
size = self.openBinding:map(function(a)
|
size = self.openBinding:map(function(a)
|
||||||
return UDim2.new(1, 0, a * math.min(3, #self.props.options), 0)
|
return UDim2.new(1, 0, a * math.min(3, #self.props.options), 0)
|
||||||
@@ -145,7 +144,7 @@ function Dropdown:render()
|
|||||||
}, {
|
}, {
|
||||||
Border = e(SlicedImage, {
|
Border = e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBorder,
|
slice = Assets.Slices.RoundedBorder,
|
||||||
color = theme.BorderColor,
|
color = dropdownTheme.BorderColor,
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ local function Header(props)
|
|||||||
|
|
||||||
Version = e("TextLabel", {
|
Version = e("TextLabel", {
|
||||||
Text = Version.display(Config.version),
|
Text = Version.display(Config.version),
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Header.VersionColor,
|
TextColor3 = theme.Header.VersionColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
|
|
||||||
Size = UDim2.new(1, 0, 0, 14),
|
Size = UDim2.new(1, 0, 0, theme.TextSize.Body),
|
||||||
|
|
||||||
LayoutOrder = 2,
|
LayoutOrder = 2,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ local function ViewDiffButton(props)
|
|||||||
Label = e("TextLabel", {
|
Label = e("TextLabel", {
|
||||||
Text = "View Diff",
|
Text = "View Diff",
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -170,8 +170,8 @@ function ChangeList:render()
|
|||||||
ColumnA = e("TextLabel", {
|
ColumnA = e("TextLabel", {
|
||||||
Text = tostring(headerRow[1]),
|
Text = tostring(headerRow[1]),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = theme.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -182,8 +182,8 @@ function ChangeList:render()
|
|||||||
ColumnB = e("TextLabel", {
|
ColumnB = e("TextLabel", {
|
||||||
Text = tostring(headerRow[2]),
|
Text = tostring(headerRow[2]),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = theme.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -194,8 +194,8 @@ function ChangeList:render()
|
|||||||
ColumnC = e("TextLabel", {
|
ColumnC = e("TextLabel", {
|
||||||
Text = tostring(headerRow[3]),
|
Text = tostring(headerRow[3]),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = theme.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -230,8 +230,8 @@ function ChangeList:render()
|
|||||||
ColumnA = e("TextLabel", {
|
ColumnA = e("TextLabel", {
|
||||||
Text = (if isWarning then "⚠ " else "") .. tostring(values[1]),
|
Text = (if isWarning then "⚠ " else "") .. tostring(values[1]),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = if isWarning then theme.Diff.Warning else theme.TextColor,
|
TextColor3 = if isWarning then theme.Diff.Warning else theme.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ local function DisplayValue(props)
|
|||||||
Label = e("TextLabel", {
|
Label = e("TextLabel", {
|
||||||
Text = string.format("%d, %d, %d", props.value.R * 255, props.value.G * 255, props.value.B * 255),
|
Text = string.format("%d, %d, %d", props.value.R * 255, props.value.G * 255, props.value.B * 255),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = props.textColor,
|
TextColor3 = props.textColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -90,8 +90,8 @@ local function DisplayValue(props)
|
|||||||
return e("TextLabel", {
|
return e("TextLabel", {
|
||||||
Text = textRepresentation,
|
Text = textRepresentation,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = props.textColor,
|
TextColor3 = props.textColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -112,8 +112,8 @@ local function DisplayValue(props)
|
|||||||
return e("TextLabel", {
|
return e("TextLabel", {
|
||||||
Text = textRepresentation,
|
Text = textRepresentation,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = props.textColor,
|
TextColor3 = props.textColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
|
|||||||
@@ -225,8 +225,8 @@ function DomLabel:render()
|
|||||||
Text = (if props.isWarning then "⚠ " else "") .. props.name,
|
Text = (if props.isWarning then "⚠ " else "") .. props.name,
|
||||||
RichText = true,
|
RichText = true,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = if props.patchType then Enum.Font.GothamBold else Enum.Font.GothamMedium,
|
FontFace = if props.patchType then theme.Font.Bold else theme.Font.Main,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = color,
|
TextColor3 = color,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -251,11 +251,11 @@ function DomLabel:render()
|
|||||||
then e("TextLabel", {
|
then e("TextLabel", {
|
||||||
Text = props.changeInfo.edits .. if props.changeInfo.failed then "," else "",
|
Text = props.changeInfo.edits .. if props.changeInfo.failed then "," else "",
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.SubTextColor,
|
TextColor3 = theme.SubTextColor,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
Size = UDim2.new(0, 0, 0, 16),
|
Size = UDim2.new(0, 0, 0, theme.TextSize.Body),
|
||||||
AutomaticSize = Enum.AutomaticSize.X,
|
AutomaticSize = Enum.AutomaticSize.X,
|
||||||
LayoutOrder = 2,
|
LayoutOrder = 2,
|
||||||
})
|
})
|
||||||
@@ -264,11 +264,11 @@ function DomLabel:render()
|
|||||||
then e("TextLabel", {
|
then e("TextLabel", {
|
||||||
Text = props.changeInfo.failed,
|
Text = props.changeInfo.failed,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Diff.Warning,
|
TextColor3 = theme.Diff.Warning,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
Size = UDim2.new(0, 0, 0, 16),
|
Size = UDim2.new(0, 0, 0, theme.TextSize.Body),
|
||||||
AutomaticSize = Enum.AutomaticSize.X,
|
AutomaticSize = Enum.AutomaticSize.X,
|
||||||
LayoutOrder = 6,
|
LayoutOrder = 6,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -124,8 +124,8 @@ function PatchVisualizer:render()
|
|||||||
CleanMerge = e("TextLabel", {
|
CleanMerge = e("TextLabel", {
|
||||||
Visible = #scrollElements == 0,
|
Visible = #scrollElements == 0,
|
||||||
Text = "No changes to sync, project is up to date.",
|
Text = "No changes to sync, project is up to date.",
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Medium,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = theme.TextColor,
|
||||||
TextWrapped = true,
|
TextWrapped = true,
|
||||||
Size = UDim2.new(1, 0, 1, 0),
|
Size = UDim2.new(1, 0, 1, 0),
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
local TextService = game:GetService("TextService")
|
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
local Plugin = Rojo.Plugin
|
local Plugin = Rojo.Plugin
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
@@ -11,6 +9,7 @@ local StringDiff = require(script:FindFirstChild("StringDiff"))
|
|||||||
|
|
||||||
local Timer = require(Plugin.Timer)
|
local Timer = require(Plugin.Timer)
|
||||||
local Theme = require(Plugin.App.Theme)
|
local Theme = require(Plugin.App.Theme)
|
||||||
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
||||||
|
|
||||||
local CodeLabel = require(Plugin.App.Components.CodeLabel)
|
local CodeLabel = require(Plugin.App.Components.CodeLabel)
|
||||||
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
||||||
@@ -32,7 +31,6 @@ function StringDiffVisualizer:init()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
self:calculateContentSize()
|
|
||||||
self:updateScriptBackground()
|
self:updateScriptBackground()
|
||||||
|
|
||||||
self:setState({
|
self:setState({
|
||||||
@@ -54,7 +52,6 @@ end
|
|||||||
|
|
||||||
function StringDiffVisualizer:didUpdate(previousProps)
|
function StringDiffVisualizer:didUpdate(previousProps)
|
||||||
if previousProps.oldString ~= self.props.oldString or previousProps.newString ~= self.props.newString then
|
if previousProps.oldString ~= self.props.oldString or previousProps.newString ~= self.props.newString then
|
||||||
self:calculateContentSize()
|
|
||||||
local add, remove = self:calculateDiffLines()
|
local add, remove = self:calculateDiffLines()
|
||||||
self:setState({
|
self:setState({
|
||||||
add = add,
|
add = add,
|
||||||
@@ -63,11 +60,11 @@ function StringDiffVisualizer:didUpdate(previousProps)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function StringDiffVisualizer:calculateContentSize()
|
function StringDiffVisualizer:calculateContentSize(theme)
|
||||||
local oldString, newString = self.props.oldString, self.props.newString
|
local oldString, newString = self.props.oldString, self.props.newString
|
||||||
|
|
||||||
local oldStringBounds = TextService:GetTextSize(oldString, 16, Enum.Font.RobotoMono, Vector2.new(99999, 99999))
|
local oldStringBounds = getTextBoundsAsync(oldString, theme.Font.Code, theme.TextSize.Code, math.huge)
|
||||||
local newStringBounds = TextService:GetTextSize(newString, 16, Enum.Font.RobotoMono, Vector2.new(99999, 99999))
|
local newStringBounds = getTextBoundsAsync(newString, theme.Font.Code, theme.TextSize.Code, math.huge)
|
||||||
|
|
||||||
self.setContentSize(
|
self.setContentSize(
|
||||||
Vector2.new(math.max(oldStringBounds.X, newStringBounds.X), math.max(oldStringBounds.Y, newStringBounds.Y))
|
Vector2.new(math.max(oldStringBounds.X, newStringBounds.X), math.max(oldStringBounds.Y, newStringBounds.Y))
|
||||||
@@ -143,6 +140,8 @@ function StringDiffVisualizer:render()
|
|||||||
local oldString, newString = self.props.oldString, self.props.newString
|
local oldString, newString = self.props.oldString, self.props.newString
|
||||||
|
|
||||||
return Theme.with(function(theme)
|
return Theme.with(function(theme)
|
||||||
|
self:calculateContentSize(theme)
|
||||||
|
|
||||||
return e(BorderedContainer, {
|
return e(BorderedContainer, {
|
||||||
size = self.props.size,
|
size = self.props.size,
|
||||||
position = self.props.position,
|
position = self.props.position,
|
||||||
|
|||||||
@@ -152,8 +152,8 @@ function Array:render()
|
|||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = "Old",
|
Text = "Old",
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
||||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||||
}),
|
}),
|
||||||
@@ -163,8 +163,8 @@ function Array:render()
|
|||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = "New",
|
Text = "New",
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
||||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ function Dictionary:render()
|
|||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = key,
|
Text = key,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
||||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||||
}),
|
}),
|
||||||
@@ -157,8 +157,8 @@ function Dictionary:render()
|
|||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = "Key",
|
Text = "Key",
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
||||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||||
}),
|
}),
|
||||||
@@ -168,8 +168,8 @@ function Dictionary:render()
|
|||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = "Old",
|
Text = "Old",
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
||||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||||
}),
|
}),
|
||||||
@@ -179,8 +179,8 @@ function Dictionary:render()
|
|||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = "New",
|
Text = "New",
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
||||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ local Packages = Rojo.Packages
|
|||||||
|
|
||||||
local Roact = require(Packages.Roact)
|
local Roact = require(Packages.Roact)
|
||||||
|
|
||||||
|
local Theme = require(Plugin.App.Theme)
|
||||||
local Assets = require(Plugin.Assets)
|
local Assets = require(Plugin.Assets)
|
||||||
|
|
||||||
local SlicedImage = require(Plugin.App.Components.SlicedImage)
|
local SlicedImage = require(Plugin.App.Components.SlicedImage)
|
||||||
@@ -11,46 +12,48 @@ local SlicedImage = require(Plugin.App.Components.SlicedImage)
|
|||||||
local e = Roact.createElement
|
local e = Roact.createElement
|
||||||
|
|
||||||
return function(props)
|
return function(props)
|
||||||
return e(SlicedImage, {
|
return Theme.with(function(theme)
|
||||||
slice = Assets.Slices.RoundedBackground,
|
return e(SlicedImage, {
|
||||||
color = props.color,
|
slice = Assets.Slices.RoundedBackground,
|
||||||
transparency = props.transparency:map(function(transparency)
|
color = props.color,
|
||||||
return 0.9 + (0.1 * transparency)
|
transparency = props.transparency:map(function(transparency)
|
||||||
end),
|
return 0.9 + (0.1 * transparency)
|
||||||
layoutOrder = props.layoutOrder,
|
end),
|
||||||
position = props.position,
|
layoutOrder = props.layoutOrder,
|
||||||
anchorPoint = props.anchorPoint,
|
position = props.position,
|
||||||
size = UDim2.new(0, 0, 0, 16),
|
anchorPoint = props.anchorPoint,
|
||||||
automaticSize = Enum.AutomaticSize.X,
|
size = UDim2.new(0, 0, 0, theme.TextSize.Medium),
|
||||||
}, {
|
automaticSize = Enum.AutomaticSize.X,
|
||||||
Padding = e("UIPadding", {
|
}, {
|
||||||
PaddingLeft = UDim.new(0, 4),
|
Padding = e("UIPadding", {
|
||||||
PaddingRight = UDim.new(0, 4),
|
PaddingLeft = UDim.new(0, 4),
|
||||||
PaddingTop = UDim.new(0, 2),
|
PaddingRight = UDim.new(0, 4),
|
||||||
PaddingBottom = UDim.new(0, 2),
|
PaddingTop = UDim.new(0, 2),
|
||||||
}),
|
PaddingBottom = UDim.new(0, 2),
|
||||||
Icon = if props.icon
|
}),
|
||||||
then e("ImageLabel", {
|
Icon = if props.icon
|
||||||
Size = UDim2.new(0, 12, 0, 12),
|
then e("ImageLabel", {
|
||||||
Position = UDim2.new(0, 0, 0.5, 0),
|
Size = UDim2.new(0, 12, 0, 12),
|
||||||
AnchorPoint = Vector2.new(0, 0.5),
|
Position = UDim2.new(0, 0, 0.5, 0),
|
||||||
Image = props.icon,
|
AnchorPoint = Vector2.new(0, 0.5),
|
||||||
|
Image = props.icon,
|
||||||
|
BackgroundTransparency = 1,
|
||||||
|
ImageColor3 = props.color,
|
||||||
|
ImageTransparency = props.transparency,
|
||||||
|
})
|
||||||
|
else nil,
|
||||||
|
Text = e("TextLabel", {
|
||||||
|
Text = props.text,
|
||||||
|
FontFace = theme.Font.Main,
|
||||||
|
TextSize = theme.TextSize.Small,
|
||||||
|
TextColor3 = props.color,
|
||||||
|
TextXAlignment = Enum.TextXAlignment.Center,
|
||||||
|
TextTransparency = props.transparency,
|
||||||
|
Size = UDim2.new(0, 0, 1, 0),
|
||||||
|
Position = UDim2.new(0, if props.icon then 15 else 0, 0, 0),
|
||||||
|
AutomaticSize = Enum.AutomaticSize.X,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
ImageColor3 = props.color,
|
}),
|
||||||
ImageTransparency = props.transparency,
|
})
|
||||||
})
|
end)
|
||||||
else nil,
|
|
||||||
Text = e("TextLabel", {
|
|
||||||
Text = props.text,
|
|
||||||
Font = Enum.Font.GothamMedium,
|
|
||||||
TextSize = 12,
|
|
||||||
TextColor3 = props.color,
|
|
||||||
TextXAlignment = Enum.TextXAlignment.Center,
|
|
||||||
TextTransparency = props.transparency,
|
|
||||||
Size = UDim2.new(0, 0, 1, 0),
|
|
||||||
Position = UDim2.new(0, if props.icon then 15 else 0, 0, 0),
|
|
||||||
AutomaticSize = Enum.AutomaticSize.X,
|
|
||||||
BackgroundTransparency = 1,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
local TextService = game:GetService("TextService")
|
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
local Plugin = Rojo.Plugin
|
local Plugin = Rojo.Plugin
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
@@ -10,6 +8,7 @@ local Flipper = require(Packages.Flipper)
|
|||||||
local Theme = require(Plugin.App.Theme)
|
local Theme = require(Plugin.App.Theme)
|
||||||
local Assets = require(Plugin.Assets)
|
local Assets = require(Plugin.Assets)
|
||||||
local bindingUtil = require(Plugin.App.bindingUtil)
|
local bindingUtil = require(Plugin.App.bindingUtil)
|
||||||
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
||||||
|
|
||||||
local SlicedImage = require(script.Parent.SlicedImage)
|
local SlicedImage = require(script.Parent.SlicedImage)
|
||||||
local TouchRipple = require(script.Parent.TouchRipple)
|
local TouchRipple = require(script.Parent.TouchRipple)
|
||||||
@@ -41,18 +40,17 @@ end
|
|||||||
|
|
||||||
function TextButton:render()
|
function TextButton:render()
|
||||||
return Theme.with(function(theme)
|
return Theme.with(function(theme)
|
||||||
local textSize =
|
local textBounds = getTextBoundsAsync(self.props.text, theme.Font.Main, theme.TextSize.Large, math.huge)
|
||||||
TextService:GetTextSize(self.props.text, 18, Enum.Font.GothamMedium, Vector2.new(math.huge, math.huge))
|
|
||||||
|
|
||||||
local style = self.props.style
|
local style = self.props.style
|
||||||
|
|
||||||
theme = theme.Button[style]
|
local buttonTheme = theme.Button[style]
|
||||||
|
|
||||||
local bindingHover = bindingUtil.deriveProperty(self.binding, "hover")
|
local bindingHover = bindingUtil.deriveProperty(self.binding, "hover")
|
||||||
local bindingEnabled = bindingUtil.deriveProperty(self.binding, "enabled")
|
local bindingEnabled = bindingUtil.deriveProperty(self.binding, "enabled")
|
||||||
|
|
||||||
return e("ImageButton", {
|
return e("ImageButton", {
|
||||||
Size = UDim2.new(0, 15 + textSize.X + 15, 0, 34),
|
Size = UDim2.new(0, (theme.TextSize.Body * 2) + textBounds.X, 0, 34),
|
||||||
Position = self.props.position,
|
Position = self.props.position,
|
||||||
AnchorPoint = self.props.anchorPoint,
|
AnchorPoint = self.props.anchorPoint,
|
||||||
|
|
||||||
@@ -74,18 +72,22 @@ function TextButton:render()
|
|||||||
end,
|
end,
|
||||||
}, {
|
}, {
|
||||||
TouchRipple = e(TouchRipple, {
|
TouchRipple = e(TouchRipple, {
|
||||||
color = theme.ActionFillColor,
|
color = buttonTheme.ActionFillColor,
|
||||||
transparency = self.props.transparency:map(function(value)
|
transparency = self.props.transparency:map(function(value)
|
||||||
return bindingUtil.blendAlpha({ theme.ActionFillTransparency, value })
|
return bindingUtil.blendAlpha({ buttonTheme.ActionFillTransparency, value })
|
||||||
end),
|
end),
|
||||||
zIndex = 2,
|
zIndex = 2,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Text = e("TextLabel", {
|
Text = e("TextLabel", {
|
||||||
Text = self.props.text,
|
Text = self.props.text,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 18,
|
TextSize = theme.TextSize.Large,
|
||||||
TextColor3 = bindingUtil.mapLerp(bindingEnabled, theme.Enabled.TextColor, theme.Disabled.TextColor),
|
TextColor3 = bindingUtil.mapLerp(
|
||||||
|
bindingEnabled,
|
||||||
|
buttonTheme.Enabled.TextColor,
|
||||||
|
buttonTheme.Disabled.TextColor
|
||||||
|
),
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
|
|
||||||
Size = UDim2.new(1, 0, 1, 0),
|
Size = UDim2.new(1, 0, 1, 0),
|
||||||
@@ -95,7 +97,11 @@ function TextButton:render()
|
|||||||
|
|
||||||
Border = style == "Bordered" and e(SlicedImage, {
|
Border = style == "Bordered" and e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBorder,
|
slice = Assets.Slices.RoundedBorder,
|
||||||
color = bindingUtil.mapLerp(bindingEnabled, theme.Enabled.BorderColor, theme.Disabled.BorderColor),
|
color = bindingUtil.mapLerp(
|
||||||
|
bindingEnabled,
|
||||||
|
buttonTheme.Enabled.BorderColor,
|
||||||
|
buttonTheme.Disabled.BorderColor
|
||||||
|
),
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
|
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
@@ -105,14 +111,18 @@ function TextButton:render()
|
|||||||
|
|
||||||
HoverOverlay = e(SlicedImage, {
|
HoverOverlay = e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBackground,
|
slice = Assets.Slices.RoundedBackground,
|
||||||
color = theme.ActionFillColor,
|
color = buttonTheme.ActionFillColor,
|
||||||
transparency = Roact.joinBindings({
|
transparency = Roact.joinBindings({
|
||||||
hover = bindingHover:map(function(value)
|
hover = bindingHover:map(function(value)
|
||||||
return 1 - value
|
return 1 - value
|
||||||
end),
|
end),
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
}):map(function(values)
|
}):map(function(values)
|
||||||
return bindingUtil.blendAlpha({ theme.ActionFillTransparency, values.hover, values.transparency })
|
return bindingUtil.blendAlpha({
|
||||||
|
buttonTheme.ActionFillTransparency,
|
||||||
|
values.hover,
|
||||||
|
values.transparency,
|
||||||
|
})
|
||||||
end),
|
end),
|
||||||
|
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
@@ -124,8 +134,8 @@ function TextButton:render()
|
|||||||
slice = Assets.Slices.RoundedBackground,
|
slice = Assets.Slices.RoundedBackground,
|
||||||
color = bindingUtil.mapLerp(
|
color = bindingUtil.mapLerp(
|
||||||
bindingEnabled,
|
bindingEnabled,
|
||||||
theme.Enabled.BackgroundColor,
|
buttonTheme.Enabled.BackgroundColor,
|
||||||
theme.Disabled.BackgroundColor
|
buttonTheme.Disabled.BackgroundColor
|
||||||
),
|
),
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
|
|
||||||
|
|||||||
@@ -38,14 +38,18 @@ end
|
|||||||
|
|
||||||
function TextInput:render()
|
function TextInput:render()
|
||||||
return Theme.with(function(theme)
|
return Theme.with(function(theme)
|
||||||
theme = theme.TextInput
|
local textInputTheme = theme.TextInput
|
||||||
|
|
||||||
local bindingHover = bindingUtil.deriveProperty(self.binding, "hover")
|
local bindingHover = bindingUtil.deriveProperty(self.binding, "hover")
|
||||||
local bindingEnabled = bindingUtil.deriveProperty(self.binding, "enabled")
|
local bindingEnabled = bindingUtil.deriveProperty(self.binding, "enabled")
|
||||||
|
|
||||||
return e(SlicedImage, {
|
return e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBorder,
|
slice = Assets.Slices.RoundedBorder,
|
||||||
color = bindingUtil.mapLerp(bindingEnabled, theme.Enabled.BorderColor, theme.Disabled.BorderColor),
|
color = bindingUtil.mapLerp(
|
||||||
|
bindingEnabled,
|
||||||
|
textInputTheme.Enabled.BorderColor,
|
||||||
|
textInputTheme.Disabled.BorderColor
|
||||||
|
),
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
|
|
||||||
size = self.props.size or UDim2.new(1, 0, 1, 0),
|
size = self.props.size or UDim2.new(1, 0, 1, 0),
|
||||||
@@ -55,14 +59,18 @@ function TextInput:render()
|
|||||||
}, {
|
}, {
|
||||||
HoverOverlay = e(SlicedImage, {
|
HoverOverlay = e(SlicedImage, {
|
||||||
slice = Assets.Slices.RoundedBackground,
|
slice = Assets.Slices.RoundedBackground,
|
||||||
color = theme.ActionFillColor,
|
color = textInputTheme.ActionFillColor,
|
||||||
transparency = Roact.joinBindings({
|
transparency = Roact.joinBindings({
|
||||||
hover = bindingHover:map(function(value)
|
hover = bindingHover:map(function(value)
|
||||||
return 1 - value
|
return 1 - value
|
||||||
end),
|
end),
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
}):map(function(values)
|
}):map(function(values)
|
||||||
return bindingUtil.blendAlpha({ theme.ActionFillTransparency, values.hover, values.transparency })
|
return bindingUtil.blendAlpha({
|
||||||
|
textInputTheme.ActionFillTransparency,
|
||||||
|
values.hover,
|
||||||
|
values.transparency,
|
||||||
|
})
|
||||||
end),
|
end),
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
zIndex = -1,
|
zIndex = -1,
|
||||||
@@ -72,14 +80,18 @@ function TextInput:render()
|
|||||||
Size = UDim2.fromScale(1, 1),
|
Size = UDim2.fromScale(1, 1),
|
||||||
Text = self.props.text,
|
Text = self.props.text,
|
||||||
PlaceholderText = self.props.placeholder,
|
PlaceholderText = self.props.placeholder,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextColor3 = bindingUtil.mapLerp(bindingEnabled, theme.Disabled.TextColor, theme.Enabled.TextColor),
|
TextColor3 = bindingUtil.mapLerp(
|
||||||
|
bindingEnabled,
|
||||||
|
textInputTheme.Disabled.TextColor,
|
||||||
|
textInputTheme.Enabled.TextColor
|
||||||
|
),
|
||||||
PlaceholderColor3 = bindingUtil.mapLerp(
|
PlaceholderColor3 = bindingUtil.mapLerp(
|
||||||
bindingEnabled,
|
bindingEnabled,
|
||||||
theme.Disabled.PlaceholderColor,
|
textInputTheme.Disabled.PlaceholderColor,
|
||||||
theme.Enabled.PlaceholderColor
|
textInputTheme.Enabled.PlaceholderColor
|
||||||
),
|
),
|
||||||
TextSize = 18,
|
TextSize = theme.TextSize.Large,
|
||||||
TextEditable = self.props.enabled,
|
TextEditable = self.props.enabled,
|
||||||
ClearTextOnFocus = self.props.clearTextOnFocus,
|
ClearTextOnFocus = self.props.clearTextOnFocus,
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
local TextService = game:GetService("TextService")
|
|
||||||
local HttpService = game:GetService("HttpService")
|
local HttpService = game:GetService("HttpService")
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
@@ -8,6 +7,8 @@ local Packages = Rojo.Packages
|
|||||||
local Roact = require(Packages.Roact)
|
local Roact = require(Packages.Roact)
|
||||||
local Theme = require(Plugin.App.Theme)
|
local Theme = require(Plugin.App.Theme)
|
||||||
|
|
||||||
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
||||||
|
|
||||||
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
||||||
|
|
||||||
local e = Roact.createElement
|
local e = Roact.createElement
|
||||||
@@ -21,50 +22,51 @@ local Y_OVERLAP = 10 -- Let the triangle tail piece overlap the target a bit to
|
|||||||
local TooltipContext = Roact.createContext({})
|
local TooltipContext = Roact.createContext({})
|
||||||
|
|
||||||
local function Popup(props)
|
local function Popup(props)
|
||||||
local textSize = TextService:GetTextSize(
|
|
||||||
props.Text,
|
|
||||||
16,
|
|
||||||
Enum.Font.GothamMedium,
|
|
||||||
Vector2.new(math.min(props.parentSize.X, 160), math.huge)
|
|
||||||
) + TEXT_PADDING + (Vector2.one * 2)
|
|
||||||
|
|
||||||
local trigger = props.Trigger:getValue()
|
|
||||||
|
|
||||||
local spaceBelow = props.parentSize.Y
|
|
||||||
- (trigger.AbsolutePosition.Y + trigger.AbsoluteSize.Y - Y_OVERLAP + TAIL_SIZE)
|
|
||||||
local spaceAbove = trigger.AbsolutePosition.Y + Y_OVERLAP - TAIL_SIZE
|
|
||||||
|
|
||||||
-- If there's not enough space below, and there's more space above, then show the tooltip above the trigger
|
|
||||||
local displayAbove = spaceBelow < textSize.Y and spaceAbove > spaceBelow
|
|
||||||
|
|
||||||
local X = math.clamp(props.Position.X - X_OFFSET, 0, props.parentSize.X - textSize.X)
|
|
||||||
local Y = 0
|
|
||||||
|
|
||||||
if displayAbove then
|
|
||||||
Y = math.max(trigger.AbsolutePosition.Y - TAIL_SIZE - textSize.Y + Y_OVERLAP, 0)
|
|
||||||
else
|
|
||||||
Y = math.min(
|
|
||||||
trigger.AbsolutePosition.Y + trigger.AbsoluteSize.Y + TAIL_SIZE - Y_OVERLAP,
|
|
||||||
props.parentSize.Y - textSize.Y
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
return Theme.with(function(theme)
|
return Theme.with(function(theme)
|
||||||
|
local textXSpace = math.min(props.parentSize.X, 120)
|
||||||
|
local textBounds = Vector2.new(
|
||||||
|
textXSpace,
|
||||||
|
getTextBoundsAsync(props.Text, theme.Font.Main, theme.TextSize.Medium, textXSpace).Y
|
||||||
|
)
|
||||||
|
local contentSize = textBounds + TEXT_PADDING + (Vector2.one * 2)
|
||||||
|
|
||||||
|
local trigger = props.Trigger:getValue()
|
||||||
|
|
||||||
|
local spaceBelow = props.parentSize.Y
|
||||||
|
- (trigger.AbsolutePosition.Y + trigger.AbsoluteSize.Y - Y_OVERLAP + TAIL_SIZE)
|
||||||
|
local spaceAbove = trigger.AbsolutePosition.Y + Y_OVERLAP - TAIL_SIZE
|
||||||
|
|
||||||
|
-- If there's not enough space below, and there's more space above, then show the tooltip above the trigger
|
||||||
|
local displayAbove = spaceBelow < contentSize.Y and spaceAbove > spaceBelow
|
||||||
|
|
||||||
|
local X = math.clamp(props.Position.X - X_OFFSET, 0, props.parentSize.X - contentSize.X)
|
||||||
|
local Y = 0
|
||||||
|
|
||||||
|
if displayAbove then
|
||||||
|
Y = math.max(trigger.AbsolutePosition.Y - TAIL_SIZE - contentSize.Y + Y_OVERLAP, 0)
|
||||||
|
else
|
||||||
|
Y = math.min(
|
||||||
|
trigger.AbsolutePosition.Y + trigger.AbsoluteSize.Y + TAIL_SIZE - Y_OVERLAP,
|
||||||
|
props.parentSize.Y - contentSize.Y
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
return e(BorderedContainer, {
|
return e(BorderedContainer, {
|
||||||
position = UDim2.fromOffset(X, Y),
|
position = UDim2.fromOffset(X, Y),
|
||||||
size = UDim2.fromOffset(textSize.X, textSize.Y),
|
size = UDim2.fromOffset(contentSize.X, contentSize.Y),
|
||||||
transparency = props.transparency,
|
transparency = props.transparency,
|
||||||
}, {
|
}, {
|
||||||
Label = e("TextLabel", {
|
Label = e("TextLabel", {
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Position = UDim2.fromScale(0.5, 0.5),
|
Position = UDim2.fromScale(0.5, 0.5),
|
||||||
Size = UDim2.new(1, -TEXT_PADDING.X, 1, -TEXT_PADDING.Y),
|
|
||||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||||
|
Size = UDim2.fromOffset(textBounds.X, textBounds.Y),
|
||||||
Text = props.Text,
|
Text = props.Text,
|
||||||
TextSize = 16,
|
TextSize = theme.TextSize.Medium,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextWrapped = true,
|
TextWrapped = true,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
|
TextYAlignment = Enum.TextYAlignment.Center,
|
||||||
TextColor3 = theme.Button.Bordered.Enabled.TextColor,
|
TextColor3 = theme.Button.Bordered.Enabled.TextColor,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
}),
|
}),
|
||||||
@@ -72,8 +74,8 @@ local function Popup(props)
|
|||||||
Tail = e("ImageLabel", {
|
Tail = e("ImageLabel", {
|
||||||
ZIndex = 100,
|
ZIndex = 100,
|
||||||
Position = if displayAbove
|
Position = if displayAbove
|
||||||
then UDim2.new(0, math.clamp(props.Position.X - X, 6, textSize.X - 6), 1, -1)
|
then UDim2.new(0, math.clamp(props.Position.X - X, 6, contentSize.X - 6), 1, -1)
|
||||||
else UDim2.new(0, math.clamp(props.Position.X - X, 6, textSize.X - 6), 0, -TAIL_SIZE + 1),
|
else UDim2.new(0, math.clamp(props.Position.X - X, 6, contentSize.X - 6), 0, -TAIL_SIZE + 1),
|
||||||
Size = UDim2.fromOffset(TAIL_SIZE, TAIL_SIZE),
|
Size = UDim2.fromOffset(TAIL_SIZE, TAIL_SIZE),
|
||||||
AnchorPoint = Vector2.new(0.5, 0),
|
AnchorPoint = Vector2.new(0.5, 0),
|
||||||
Rotation = if displayAbove then 180 else 0,
|
Rotation = if displayAbove then 180 else 0,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
local TextService = game:GetService("TextService")
|
|
||||||
local StudioService = game:GetService("StudioService")
|
local StudioService = game:GetService("StudioService")
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
@@ -9,10 +8,10 @@ local Roact = require(Packages.Roact)
|
|||||||
local Flipper = require(Packages.Flipper)
|
local Flipper = require(Packages.Flipper)
|
||||||
local Log = require(Packages.Log)
|
local Log = require(Packages.Log)
|
||||||
|
|
||||||
local bindingUtil = require(script.Parent.bindingUtil)
|
|
||||||
|
|
||||||
local Theme = require(Plugin.App.Theme)
|
local Theme = require(Plugin.App.Theme)
|
||||||
local Assets = require(Plugin.Assets)
|
local Assets = require(Plugin.Assets)
|
||||||
|
local bindingUtil = require(Plugin.App.bindingUtil)
|
||||||
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
||||||
|
|
||||||
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
||||||
local TextButton = require(Plugin.App.Components.TextButton)
|
local TextButton = require(Plugin.App.Components.TextButton)
|
||||||
@@ -86,51 +85,49 @@ function Notification:render()
|
|||||||
return 1 - value
|
return 1 - value
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local textBounds = TextService:GetTextSize(self.props.text, 15, Enum.Font.GothamMedium, Vector2.new(350, 700))
|
return Theme.with(function(theme)
|
||||||
|
local actionButtons = {}
|
||||||
|
local buttonsX = 0
|
||||||
|
if self.props.actions then
|
||||||
|
local count = 0
|
||||||
|
for key, action in self.props.actions do
|
||||||
|
actionButtons[key] = e(TextButton, {
|
||||||
|
text = action.text,
|
||||||
|
style = action.style,
|
||||||
|
onClick = function()
|
||||||
|
local success, err = pcall(action.onClick, self)
|
||||||
|
if not success then
|
||||||
|
Log.warn("Error in notification action: " .. tostring(err))
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
layoutOrder = -action.layoutOrder,
|
||||||
|
transparency = transparency,
|
||||||
|
})
|
||||||
|
|
||||||
local actionButtons = {}
|
buttonsX += getTextBoundsAsync(action.text, theme.Font.Main, theme.TextSize.Large, math.huge).X + (theme.TextSize.Body * 2)
|
||||||
local buttonsX = 0
|
|
||||||
if self.props.actions then
|
|
||||||
local count = 0
|
|
||||||
for key, action in self.props.actions do
|
|
||||||
actionButtons[key] = e(TextButton, {
|
|
||||||
text = action.text,
|
|
||||||
style = action.style,
|
|
||||||
onClick = function()
|
|
||||||
local success, err = pcall(action.onClick, self)
|
|
||||||
if not success then
|
|
||||||
Log.warn("Error in notification action: " .. tostring(err))
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
layoutOrder = -action.layoutOrder,
|
|
||||||
transparency = transparency,
|
|
||||||
})
|
|
||||||
|
|
||||||
buttonsX += TextService:GetTextSize(
|
count += 1
|
||||||
action.text,
|
end
|
||||||
18,
|
|
||||||
Enum.Font.GothamMedium,
|
|
||||||
Vector2.new(math.huge, math.huge)
|
|
||||||
).X + 30
|
|
||||||
|
|
||||||
count += 1
|
buttonsX += (count - 1) * 5
|
||||||
end
|
end
|
||||||
|
|
||||||
buttonsX += (count - 1) * 5
|
local paddingY, logoSize = 20, 32
|
||||||
end
|
local actionsY = if self.props.actions then 35 else 0
|
||||||
|
local textXSpace = math.max(250, buttonsX) + 35
|
||||||
local paddingY, logoSize = 20, 32
|
local textBounds = Vector2.new(
|
||||||
local actionsY = if self.props.actions then 35 else 0
|
textXSpace,
|
||||||
local contentX = math.max(textBounds.X, buttonsX)
|
getTextBoundsAsync(self.props.text, theme.Font.Main, theme.TextSize.Body, textXSpace).Y
|
||||||
|
|
||||||
local size = self.binding:map(function(value)
|
|
||||||
return UDim2.fromOffset(
|
|
||||||
(35 + 40 + contentX) * value,
|
|
||||||
5 + actionsY + paddingY + math.max(logoSize, textBounds.Y)
|
|
||||||
)
|
)
|
||||||
end)
|
local contentX = math.max(textBounds.X, buttonsX)
|
||||||
|
|
||||||
|
local size = self.binding:map(function(value)
|
||||||
|
return UDim2.fromOffset(
|
||||||
|
(35 + 40 + contentX) * value,
|
||||||
|
5 + actionsY + paddingY + math.max(logoSize, textBounds.Y)
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
return Theme.with(function(theme)
|
|
||||||
return e("TextButton", {
|
return e("TextButton", {
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Size = size,
|
Size = size,
|
||||||
@@ -147,8 +144,7 @@ function Notification:render()
|
|||||||
size = UDim2.new(1, 0, 1, 0),
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
}, {
|
}, {
|
||||||
Contents = e("Frame", {
|
Contents = e("Frame", {
|
||||||
Size = UDim2.new(0, 35 + contentX, 1, -paddingY),
|
Size = UDim2.new(1, 0, 1, 0),
|
||||||
Position = UDim2.new(0, 0, 0, paddingY / 2),
|
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
}, {
|
}, {
|
||||||
Logo = e("ImageLabel", {
|
Logo = e("ImageLabel", {
|
||||||
@@ -161,14 +157,15 @@ function Notification:render()
|
|||||||
}),
|
}),
|
||||||
Info = e("TextLabel", {
|
Info = e("TextLabel", {
|
||||||
Text = self.props.text,
|
Text = self.props.text,
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Notification.InfoColor,
|
TextColor3 = theme.Notification.InfoColor,
|
||||||
TextTransparency = transparency,
|
TextTransparency = transparency,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
|
TextYAlignment = Enum.TextYAlignment.Top,
|
||||||
TextWrapped = true,
|
TextWrapped = true,
|
||||||
|
|
||||||
Size = UDim2.new(0, textBounds.X, 0, textBounds.Y),
|
Size = UDim2.new(1, -35, 1, -actionsY),
|
||||||
Position = UDim2.fromOffset(35, 0),
|
Position = UDim2.fromOffset(35, 0),
|
||||||
|
|
||||||
LayoutOrder = 1,
|
LayoutOrder = 1,
|
||||||
@@ -176,7 +173,7 @@ function Notification:render()
|
|||||||
}),
|
}),
|
||||||
Actions = if self.props.actions
|
Actions = if self.props.actions
|
||||||
then e("Frame", {
|
then e("Frame", {
|
||||||
Size = UDim2.new(1, -40, 0, 35),
|
Size = UDim2.new(1, -40, 0, actionsY),
|
||||||
Position = UDim2.new(1, 0, 1, 0),
|
Position = UDim2.new(1, 0, 1, 0),
|
||||||
AnchorPoint = Vector2.new(1, 1),
|
AnchorPoint = Vector2.new(1, 1),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
@@ -196,6 +193,8 @@ function Notification:render()
|
|||||||
Padding = e("UIPadding", {
|
Padding = e("UIPadding", {
|
||||||
PaddingLeft = UDim.new(0, 17),
|
PaddingLeft = UDim.new(0, 17),
|
||||||
PaddingRight = UDim.new(0, 15),
|
PaddingRight = UDim.new(0, 15),
|
||||||
|
PaddingTop = UDim.new(0, paddingY / 2),
|
||||||
|
PaddingBottom = UDim.new(0, paddingY / 2),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -64,13 +64,13 @@ function ConfirmingPage:render()
|
|||||||
"Sync changes for project '%s':",
|
"Sync changes for project '%s':",
|
||||||
self.props.confirmData.serverInfo.projectName or "UNKNOWN"
|
self.props.confirmData.serverInfo.projectName or "UNKNOWN"
|
||||||
),
|
),
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
LineHeight = 1.2,
|
LineHeight = 1.2,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = theme.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
Size = UDim2.new(1, 0, 0, 20),
|
Size = UDim2.new(1, 0, 0, theme.TextSize.Large + 2),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -61,12 +61,12 @@ function ChangesViewer:render()
|
|||||||
|
|
||||||
Title = e("TextLabel", {
|
Title = e("TextLabel", {
|
||||||
Text = "Sync",
|
Text = "Sync",
|
||||||
Font = Enum.Font.GothamMedium,
|
FontFace = theme.Font.Main,
|
||||||
TextSize = 17,
|
TextSize = theme.TextSize.Large,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = theme.TextColor,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
Size = UDim2.new(1, -40, 0, 20),
|
Size = UDim2.new(1, -40, 0, theme.TextSize.Large + 2),
|
||||||
Position = UDim2.new(0, 40, 0, 0),
|
Position = UDim2.new(0, 40, 0, 0),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
}),
|
}),
|
||||||
@@ -74,13 +74,13 @@ function ChangesViewer:render()
|
|||||||
Subtitle = e("TextLabel", {
|
Subtitle = e("TextLabel", {
|
||||||
Text = DateTime.fromUnixTimestamp(self.props.patchData.timestamp):FormatLocalTime("LTS", "en-us"),
|
Text = DateTime.fromUnixTimestamp(self.props.patchData.timestamp):FormatLocalTime("LTS", "en-us"),
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Medium,
|
||||||
TextColor3 = theme.SubTextColor,
|
TextColor3 = theme.SubTextColor,
|
||||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
Size = UDim2.new(1, -40, 0, 16),
|
Size = UDim2.new(1, -40, 0, theme.TextSize.Medium),
|
||||||
Position = UDim2.new(0, 40, 0, 20),
|
Position = UDim2.new(0, 40, 0, theme.TextSize.Large + 2),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -131,8 +131,8 @@ function ChangesViewer:render()
|
|||||||
}),
|
}),
|
||||||
AppliedText = e("TextLabel", {
|
AppliedText = e("TextLabel", {
|
||||||
Text = applied,
|
Text = applied,
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = theme.TextColor,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
Size = UDim2.new(0, 0, 1, 0),
|
Size = UDim2.new(0, 0, 1, 0),
|
||||||
@@ -156,8 +156,8 @@ function ChangesViewer:render()
|
|||||||
}),
|
}),
|
||||||
UnappliedText = e("TextLabel", {
|
UnappliedText = e("TextLabel", {
|
||||||
Text = unapplied,
|
Text = unapplied,
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = theme.Diff.Warning,
|
TextColor3 = theme.Diff.Warning,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
Size = UDim2.new(0, 0, 1, 0),
|
Size = UDim2.new(0, 0, 1, 0),
|
||||||
@@ -217,13 +217,13 @@ local function ConnectionDetails(props)
|
|||||||
}, {
|
}, {
|
||||||
ProjectName = e("TextLabel", {
|
ProjectName = e("TextLabel", {
|
||||||
Text = props.projectName,
|
Text = props.projectName,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 20,
|
TextSize = theme.TextSize.Large,
|
||||||
TextColor3 = theme.ConnectionDetails.ProjectNameColor,
|
TextColor3 = theme.ConnectionDetails.ProjectNameColor,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
|
|
||||||
Size = UDim2.new(1, 0, 0, 20),
|
Size = UDim2.new(1, 0, 0, theme.TextSize.Large),
|
||||||
|
|
||||||
LayoutOrder = 1,
|
LayoutOrder = 1,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
@@ -231,13 +231,13 @@ local function ConnectionDetails(props)
|
|||||||
|
|
||||||
Address = e("TextLabel", {
|
Address = e("TextLabel", {
|
||||||
Text = props.address,
|
Text = props.address,
|
||||||
Font = Enum.Font.Code,
|
FontFace = theme.Font.Code,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Medium,
|
||||||
TextColor3 = theme.ConnectionDetails.AddressColor,
|
TextColor3 = theme.ConnectionDetails.AddressColor,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
|
|
||||||
Size = UDim2.new(1, 0, 0, 15),
|
Size = UDim2.new(1, 0, 0, theme.TextSize.Medium),
|
||||||
|
|
||||||
LayoutOrder = 2,
|
LayoutOrder = 2,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
@@ -410,8 +410,8 @@ function ConnectedPage:render()
|
|||||||
Text = e("TextLabel", {
|
Text = e("TextLabel", {
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Text = self.changeInfoText,
|
Text = self.changeInfoText,
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 15,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = if syncWarning then theme.Diff.Warning else theme.Header.VersionColor,
|
TextColor3 = if syncWarning then theme.Diff.Warning else theme.Header.VersionColor,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
TextXAlignment = Enum.TextXAlignment.Right,
|
TextXAlignment = Enum.TextXAlignment.Right,
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
local TextService = game:GetService("TextService")
|
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
local Plugin = Rojo.Plugin
|
local Plugin = Rojo.Plugin
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
@@ -7,6 +5,7 @@ local Packages = Rojo.Packages
|
|||||||
local Roact = require(Packages.Roact)
|
local Roact = require(Packages.Roact)
|
||||||
|
|
||||||
local Theme = require(Plugin.App.Theme)
|
local Theme = require(Plugin.App.Theme)
|
||||||
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
||||||
|
|
||||||
local TextButton = require(Plugin.App.Components.TextButton)
|
local TextButton = require(Plugin.App.Components.TextButton)
|
||||||
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
|
||||||
@@ -24,43 +23,43 @@ function Error:init()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Error:render()
|
function Error:render()
|
||||||
return e(BorderedContainer, {
|
return Theme.with(function(theme)
|
||||||
size = Roact.joinBindings({
|
return e(BorderedContainer, {
|
||||||
containerSize = self.props.containerSize,
|
size = Roact.joinBindings({
|
||||||
contentSize = self.contentSize,
|
containerSize = self.props.containerSize,
|
||||||
}):map(function(values)
|
contentSize = self.contentSize,
|
||||||
local maximumSize = values.containerSize
|
}):map(function(values)
|
||||||
maximumSize -= Vector2.new(14, 14) * 2 -- Page padding
|
local maximumSize = values.containerSize
|
||||||
maximumSize -= Vector2.new(0, 34 + 10) -- Buttons and spacing
|
maximumSize -= Vector2.new(14, 14) * 2 -- Page padding
|
||||||
|
maximumSize -= Vector2.new(0, 34 + 10) -- Buttons and spacing
|
||||||
|
|
||||||
local outerSize = values.contentSize + ERROR_PADDING * 2
|
local outerSize = values.contentSize + ERROR_PADDING * 2
|
||||||
|
|
||||||
return UDim2.new(1, 0, 0, math.min(outerSize.Y, maximumSize.Y))
|
return UDim2.new(1, 0, 0, math.min(outerSize.Y, maximumSize.Y))
|
||||||
end),
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
}, {
|
|
||||||
ScrollingFrame = e(ScrollingFrame, {
|
|
||||||
size = UDim2.new(1, 0, 1, 0),
|
|
||||||
contentSize = self.contentSize:map(function(value)
|
|
||||||
return value + ERROR_PADDING * 2
|
|
||||||
end),
|
end),
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
|
|
||||||
[Roact.Change.AbsoluteSize] = function(object)
|
|
||||||
local containerSize = object.AbsoluteSize - ERROR_PADDING * 2
|
|
||||||
|
|
||||||
local textBounds = TextService:GetTextSize(
|
|
||||||
self.props.errorMessage,
|
|
||||||
16,
|
|
||||||
Enum.Font.Code,
|
|
||||||
Vector2.new(containerSize.X, math.huge)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.setContentSize(Vector2.new(containerSize.X, textBounds.Y))
|
|
||||||
end,
|
|
||||||
}, {
|
}, {
|
||||||
ErrorMessage = Theme.with(function(theme)
|
ScrollingFrame = e(ScrollingFrame, {
|
||||||
return e("TextBox", {
|
size = UDim2.new(1, 0, 1, 0),
|
||||||
|
contentSize = self.contentSize:map(function(value)
|
||||||
|
return value + ERROR_PADDING * 2
|
||||||
|
end),
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
|
||||||
|
[Roact.Change.AbsoluteSize] = function(object)
|
||||||
|
local containerSize = object.AbsoluteSize - ERROR_PADDING * 2
|
||||||
|
|
||||||
|
local textBounds = getTextBoundsAsync(
|
||||||
|
self.props.errorMessage,
|
||||||
|
theme.Font.Code,
|
||||||
|
theme.TextSize.Code,
|
||||||
|
containerSize.X
|
||||||
|
)
|
||||||
|
|
||||||
|
self.setContentSize(Vector2.new(containerSize.X, textBounds.Y))
|
||||||
|
end,
|
||||||
|
}, {
|
||||||
|
ErrorMessage = e("TextBox", {
|
||||||
[Roact.Event.InputBegan] = function(rbx, input)
|
[Roact.Event.InputBegan] = function(rbx, input)
|
||||||
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then
|
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then
|
||||||
return
|
return
|
||||||
@@ -71,8 +70,8 @@ function Error:render()
|
|||||||
|
|
||||||
Text = self.props.errorMessage,
|
Text = self.props.errorMessage,
|
||||||
TextEditable = false,
|
TextEditable = false,
|
||||||
Font = Enum.Font.Code,
|
FontFace = theme.Font.Code,
|
||||||
TextSize = 16,
|
TextSize = theme.TextSize.Code,
|
||||||
TextColor3 = theme.ErrorColor,
|
TextColor3 = theme.ErrorColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextYAlignment = Enum.TextYAlignment.Top,
|
TextYAlignment = Enum.TextYAlignment.Top,
|
||||||
@@ -81,17 +80,17 @@ function Error:render()
|
|||||||
ClearTextOnFocus = false,
|
ClearTextOnFocus = false,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
Size = UDim2.new(1, 0, 1, 0),
|
Size = UDim2.new(1, 0, 1, 0),
|
||||||
})
|
}),
|
||||||
end),
|
|
||||||
|
|
||||||
Padding = e("UIPadding", {
|
Padding = e("UIPadding", {
|
||||||
PaddingLeft = UDim.new(0, ERROR_PADDING.X),
|
PaddingLeft = UDim.new(0, ERROR_PADDING.X),
|
||||||
PaddingRight = UDim.new(0, ERROR_PADDING.X),
|
PaddingRight = UDim.new(0, ERROR_PADDING.X),
|
||||||
PaddingTop = UDim.new(0, ERROR_PADDING.Y),
|
PaddingTop = UDim.new(0, ERROR_PADDING.Y),
|
||||||
PaddingBottom = UDim.new(0, ERROR_PADDING.Y),
|
PaddingBottom = UDim.new(0, ERROR_PADDING.Y),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
}),
|
})
|
||||||
})
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local ErrorPage = Roact.Component:extend("ErrorPage")
|
local ErrorPage = Roact.Component:extend("ErrorPage")
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ local function AddressEntry(props)
|
|||||||
}, {
|
}, {
|
||||||
Host = e("TextBox", {
|
Host = e("TextBox", {
|
||||||
Text = props.host or "",
|
Text = props.host or "",
|
||||||
Font = Enum.Font.Code,
|
FontFace = theme.Font.Code,
|
||||||
TextSize = 18,
|
TextSize = theme.TextSize.Large,
|
||||||
TextColor3 = theme.AddressEntry.TextColor,
|
TextColor3 = theme.AddressEntry.TextColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
@@ -51,8 +51,8 @@ local function AddressEntry(props)
|
|||||||
|
|
||||||
Port = e("TextBox", {
|
Port = e("TextBox", {
|
||||||
Text = props.port or "",
|
Text = props.port or "",
|
||||||
Font = Enum.Font.Code,
|
FontFace = theme.Font.Code,
|
||||||
TextSize = 18,
|
TextSize = theme.TextSize.Large,
|
||||||
TextColor3 = theme.AddressEntry.TextColor,
|
TextColor3 = theme.AddressEntry.TextColor,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
PlaceholderText = Config.defaultPort,
|
PlaceholderText = Config.defaultPort,
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
local TextService = game:GetService("TextService")
|
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
local Plugin = Rojo.Plugin
|
local Plugin = Rojo.Plugin
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
@@ -9,6 +7,7 @@ local Roact = require(Packages.Roact)
|
|||||||
local Settings = require(Plugin.Settings)
|
local Settings = require(Plugin.Settings)
|
||||||
local Assets = require(Plugin.Assets)
|
local Assets = require(Plugin.Assets)
|
||||||
local Theme = require(Plugin.App.Theme)
|
local Theme = require(Plugin.App.Theme)
|
||||||
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
||||||
|
|
||||||
local Checkbox = require(Plugin.App.Components.Checkbox)
|
local Checkbox = require(Plugin.App.Components.Checkbox)
|
||||||
local Dropdown = require(Plugin.App.Components.Dropdown)
|
local Dropdown = require(Plugin.App.Components.Dropdown)
|
||||||
@@ -31,10 +30,16 @@ local TAG_TYPES = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
local function getTextBounds(text, textSize, font, lineHeight, bounds)
|
local function getTextBoundsWithLineHeight(
|
||||||
local textBounds = TextService:GetTextSize(text, textSize, font, bounds)
|
text: string,
|
||||||
|
font: Font,
|
||||||
|
textSize: number,
|
||||||
|
width: number,
|
||||||
|
lineHeight: number
|
||||||
|
)
|
||||||
|
local textBounds = getTextBoundsAsync(text, font, textSize, width)
|
||||||
|
|
||||||
local lineCount = textBounds.Y / textSize
|
local lineCount = math.ceil(textBounds.Y / textSize)
|
||||||
local lineHeightAbsolute = textSize * lineHeight
|
local lineHeightAbsolute = textSize * lineHeight
|
||||||
|
|
||||||
return Vector2.new(textBounds.X, lineHeightAbsolute * lineCount - (lineHeightAbsolute - textSize))
|
return Vector2.new(textBounds.X, lineHeightAbsolute * lineCount - (lineHeightAbsolute - textSize))
|
||||||
@@ -145,7 +150,7 @@ function Setting:render()
|
|||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
}, {
|
}, {
|
||||||
Heading = e("Frame", {
|
Heading = e("Frame", {
|
||||||
Size = UDim2.new(1, 0, 0, 16),
|
Size = UDim2.new(1, 0, 0, theme.TextSize.Medium),
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
}, {
|
}, {
|
||||||
Layout = e("UIListLayout", {
|
Layout = e("UIListLayout", {
|
||||||
@@ -165,8 +170,8 @@ function Setting:render()
|
|||||||
else nil,
|
else nil,
|
||||||
Name = e("TextLabel", {
|
Name = e("TextLabel", {
|
||||||
Text = self.props.name,
|
Text = self.props.name,
|
||||||
Font = Enum.Font.GothamBold,
|
FontFace = theme.Font.Bold,
|
||||||
TextSize = 16,
|
TextSize = theme.TextSize.Medium,
|
||||||
TextColor3 = if self.props.tag and TAG_TYPES[self.props.tag]
|
TextColor3 = if self.props.tag and TAG_TYPES[self.props.tag]
|
||||||
then getThemeColorFromPath(theme, TAG_TYPES[self.props.tag].color)
|
then getThemeColorFromPath(theme, TAG_TYPES[self.props.tag].color)
|
||||||
else settingsTheme.Setting.NameColor,
|
else settingsTheme.Setting.NameColor,
|
||||||
@@ -174,7 +179,7 @@ function Setting:render()
|
|||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
RichText = true,
|
RichText = true,
|
||||||
|
|
||||||
Size = UDim2.new(1, 0, 0, 16),
|
Size = UDim2.new(1, 0, 0, theme.TextSize.Medium),
|
||||||
|
|
||||||
LayoutOrder = 2,
|
LayoutOrder = 2,
|
||||||
BackgroundTransparency = 1,
|
BackgroundTransparency = 1,
|
||||||
@@ -183,9 +188,9 @@ function Setting:render()
|
|||||||
|
|
||||||
Description = e("TextLabel", {
|
Description = e("TextLabel", {
|
||||||
Text = self.props.description,
|
Text = self.props.description,
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Main,
|
||||||
LineHeight = 1.2,
|
LineHeight = 1.2,
|
||||||
TextSize = 14,
|
TextSize = theme.TextSize.Body,
|
||||||
TextColor3 = settingsTheme.Setting.DescriptionColor,
|
TextColor3 = settingsTheme.Setting.DescriptionColor,
|
||||||
TextXAlignment = Enum.TextXAlignment.Left,
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
TextTransparency = self.props.transparency,
|
TextTransparency = self.props.transparency,
|
||||||
@@ -197,12 +202,12 @@ function Setting:render()
|
|||||||
inputSize = self.inputSize,
|
inputSize = self.inputSize,
|
||||||
}):map(function(values)
|
}):map(function(values)
|
||||||
local offset = values.inputSize.X + 5
|
local offset = values.inputSize.X + 5
|
||||||
local textBounds = getTextBounds(
|
local textBounds = getTextBoundsWithLineHeight(
|
||||||
self.props.description,
|
self.props.description,
|
||||||
14,
|
theme.Font.Main,
|
||||||
Enum.Font.Gotham,
|
theme.TextSize.Body,
|
||||||
1.2,
|
values.containerSize.X - offset,
|
||||||
Vector2.new(values.containerSize.X - offset, math.huge)
|
1.2
|
||||||
)
|
)
|
||||||
return UDim2.new(1, -offset, 0, textBounds.Y)
|
return UDim2.new(1, -offset, 0, textBounds.Y)
|
||||||
end),
|
end),
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ local confirmationBehaviors = { "Initial", "Always", "Large Changes", "Unlisted
|
|||||||
|
|
||||||
local function Navbar(props)
|
local function Navbar(props)
|
||||||
return Theme.with(function(theme)
|
return Theme.with(function(theme)
|
||||||
theme = theme.Settings.Navbar
|
local navbarTheme = theme.Settings.Navbar
|
||||||
|
|
||||||
return e("Frame", {
|
return e("Frame", {
|
||||||
Size = UDim2.new(1, 0, 0, 46),
|
Size = UDim2.new(1, 0, 0, 46),
|
||||||
@@ -40,7 +40,7 @@ local function Navbar(props)
|
|||||||
Back = e(IconButton, {
|
Back = e(IconButton, {
|
||||||
icon = Assets.Images.Icons.Back,
|
icon = Assets.Images.Icons.Back,
|
||||||
iconSize = 24,
|
iconSize = 24,
|
||||||
color = theme.BackButtonColor,
|
color = navbarTheme.BackButtonColor,
|
||||||
transparency = props.transparency,
|
transparency = props.transparency,
|
||||||
|
|
||||||
position = UDim2.new(0, 0, 0.5, 0),
|
position = UDim2.new(0, 0, 0.5, 0),
|
||||||
@@ -55,9 +55,9 @@ local function Navbar(props)
|
|||||||
|
|
||||||
Text = e("TextLabel", {
|
Text = e("TextLabel", {
|
||||||
Text = "Settings",
|
Text = "Settings",
|
||||||
Font = Enum.Font.Gotham,
|
FontFace = theme.Font.Thin,
|
||||||
TextSize = 18,
|
TextSize = theme.TextSize.Large,
|
||||||
TextColor3 = theme.TextColor,
|
TextColor3 = navbarTheme.TextColor,
|
||||||
TextTransparency = props.transparency,
|
TextTransparency = props.transparency,
|
||||||
|
|
||||||
Size = UDim2.new(1, 0, 1, 0),
|
Size = UDim2.new(1, 0, 1, 0),
|
||||||
@@ -81,185 +81,181 @@ function SettingsPage:render()
|
|||||||
return layoutOrder
|
return layoutOrder
|
||||||
end
|
end
|
||||||
|
|
||||||
return Theme.with(function(theme)
|
return Roact.createFragment({
|
||||||
theme = theme.Settings
|
Navbar = e(Navbar, {
|
||||||
|
onBack = self.props.onBack,
|
||||||
return Roact.createFragment({
|
transparency = self.props.transparency,
|
||||||
Navbar = e(Navbar, {
|
layoutOrder = layoutIncrement(),
|
||||||
onBack = self.props.onBack,
|
}),
|
||||||
|
Content = e(ScrollingFrame, {
|
||||||
|
size = UDim2.new(1, 0, 1, -47),
|
||||||
|
position = UDim2.new(0, 0, 0, 47),
|
||||||
|
contentSize = self.contentSize,
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
}, {
|
||||||
|
ShowNotifications = e(Setting, {
|
||||||
|
id = "showNotifications",
|
||||||
|
name = "Show Notifications",
|
||||||
|
description = "Popup notifications in viewport",
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
layoutOrder = layoutIncrement(),
|
layoutOrder = layoutIncrement(),
|
||||||
}),
|
}),
|
||||||
Content = e(ScrollingFrame, {
|
|
||||||
size = UDim2.new(1, 0, 1, -47),
|
SyncReminder = e(Setting, {
|
||||||
position = UDim2.new(0, 0, 0, 47),
|
id = "syncReminder",
|
||||||
contentSize = self.contentSize,
|
name = "Sync Reminder",
|
||||||
|
description = "Notify to sync when opening a place that has previously been synced",
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
}, {
|
visible = Settings:getBinding("showNotifications"),
|
||||||
ShowNotifications = e(Setting, {
|
layoutOrder = layoutIncrement(),
|
||||||
id = "showNotifications",
|
}),
|
||||||
name = "Show Notifications",
|
|
||||||
description = "Popup notifications in viewport",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
SyncReminder = e(Setting, {
|
ConfirmationBehavior = e(Setting, {
|
||||||
id = "syncReminder",
|
id = "confirmationBehavior",
|
||||||
name = "Sync Reminder",
|
name = "Confirmation Behavior",
|
||||||
description = "Notify to sync when opening a place that has previously been synced",
|
description = "When to prompt for confirmation before syncing",
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
visible = Settings:getBinding("showNotifications"),
|
layoutOrder = layoutIncrement(),
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
ConfirmationBehavior = e(Setting, {
|
options = confirmationBehaviors,
|
||||||
id = "confirmationBehavior",
|
}),
|
||||||
name = "Confirmation Behavior",
|
|
||||||
description = "When to prompt for confirmation before syncing",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
|
|
||||||
options = confirmationBehaviors,
|
LargeChangesConfirmationThreshold = e(Setting, {
|
||||||
}),
|
id = "largeChangesConfirmationThreshold",
|
||||||
|
name = "Confirmation Threshold",
|
||||||
LargeChangesConfirmationThreshold = e(Setting, {
|
description = "How many modified instances to be considered a large change",
|
||||||
id = "largeChangesConfirmationThreshold",
|
transparency = self.props.transparency,
|
||||||
name = "Confirmation Threshold",
|
layoutOrder = layoutIncrement(),
|
||||||
description = "How many modified instances to be considered a large change",
|
visible = Settings:getBinding("confirmationBehavior"):map(function(value)
|
||||||
transparency = self.props.transparency,
|
return value == "Large Changes"
|
||||||
layoutOrder = layoutIncrement(),
|
end),
|
||||||
visible = Settings:getBinding("confirmationBehavior"):map(function(value)
|
input = e(TextInput, {
|
||||||
return value == "Large Changes"
|
size = UDim2.new(0, 40, 0, 28),
|
||||||
|
text = Settings:getBinding("largeChangesConfirmationThreshold"):map(function(value)
|
||||||
|
return tostring(value)
|
||||||
end),
|
end),
|
||||||
input = e(TextInput, {
|
|
||||||
size = UDim2.new(0, 40, 0, 28),
|
|
||||||
text = Settings:getBinding("largeChangesConfirmationThreshold"):map(function(value)
|
|
||||||
return tostring(value)
|
|
||||||
end),
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
enabled = true,
|
|
||||||
onEntered = function(text)
|
|
||||||
local number = tonumber(string.match(text, "%d+"))
|
|
||||||
if number then
|
|
||||||
Settings:set("largeChangesConfirmationThreshold", math.clamp(number, 1, 999))
|
|
||||||
else
|
|
||||||
-- Force text back to last valid value
|
|
||||||
Settings:set(
|
|
||||||
"largeChangesConfirmationThreshold",
|
|
||||||
Settings:get("largeChangesConfirmationThreshold")
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
|
|
||||||
PlaySounds = e(Setting, {
|
|
||||||
id = "playSounds",
|
|
||||||
name = "Play Sounds",
|
|
||||||
description = "Toggle sound effects",
|
|
||||||
transparency = self.props.transparency,
|
transparency = self.props.transparency,
|
||||||
layoutOrder = layoutIncrement(),
|
enabled = true,
|
||||||
}),
|
onEntered = function(text)
|
||||||
|
local number = tonumber(string.match(text, "%d+"))
|
||||||
CheckForUpdates = e(Setting, {
|
if number then
|
||||||
id = "checkForUpdates",
|
Settings:set("largeChangesConfirmationThreshold", math.clamp(number, 1, 999))
|
||||||
name = "Check For Updates",
|
else
|
||||||
description = "Notify about newer compatible Rojo releases",
|
-- Force text back to last valid value
|
||||||
transparency = self.props.transparency,
|
Settings:set(
|
||||||
layoutOrder = layoutIncrement(),
|
"largeChangesConfirmationThreshold",
|
||||||
}),
|
Settings:get("largeChangesConfirmationThreshold")
|
||||||
|
)
|
||||||
CheckForPreleases = e(Setting, {
|
end
|
||||||
id = "checkForPrereleases",
|
|
||||||
name = "Include Prerelease Updates",
|
|
||||||
description = "Include prereleases when checking for updates",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
visible = if string.find(debug.traceback(), "\n[^\n]-user_.-$") == nil
|
|
||||||
then false -- Must be a local install to allow prerelease checks
|
|
||||||
else Settings:getBinding("checkForUpdates"),
|
|
||||||
}),
|
|
||||||
|
|
||||||
AutoConnectPlaytestServer = e(Setting, {
|
|
||||||
id = "autoConnectPlaytestServer",
|
|
||||||
name = "Auto Connect Playtest Server",
|
|
||||||
description = "Automatically connect game server to Rojo when playtesting while connected in Edit",
|
|
||||||
tag = "unstable",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
OpenScriptsExternally = e(Setting, {
|
|
||||||
id = "openScriptsExternally",
|
|
||||||
name = "Open Scripts Externally",
|
|
||||||
description = "Attempt to open scripts in an external editor",
|
|
||||||
tag = "unstable",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
TwoWaySync = e(Setting, {
|
|
||||||
id = "twoWaySync",
|
|
||||||
name = "Two-Way Sync",
|
|
||||||
description = "Editing files in Studio will sync them into the filesystem",
|
|
||||||
locked = self.props.syncActive,
|
|
||||||
tag = "unstable",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
LogLevel = e(Setting, {
|
|
||||||
id = "logLevel",
|
|
||||||
name = "Log Level",
|
|
||||||
description = "Plugin output verbosity level",
|
|
||||||
tag = "debug",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
|
|
||||||
options = invertedLevels,
|
|
||||||
showReset = Settings:getBinding("logLevel"):map(function(value)
|
|
||||||
return value ~= "Info"
|
|
||||||
end),
|
|
||||||
onReset = function()
|
|
||||||
Settings:set("logLevel", "Info")
|
|
||||||
end,
|
end,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
TypecheckingEnabled = e(Setting, {
|
|
||||||
id = "typecheckingEnabled",
|
|
||||||
name = "Typechecking",
|
|
||||||
description = "Toggle typechecking on the API surface",
|
|
||||||
tag = "debug",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
TimingLogsEnabled = e(Setting, {
|
|
||||||
id = "timingLogsEnabled",
|
|
||||||
name = "Timing Logs",
|
|
||||||
description = "Toggle logging timing of internal actions for benchmarking Rojo performance",
|
|
||||||
tag = "debug",
|
|
||||||
transparency = self.props.transparency,
|
|
||||||
layoutOrder = layoutIncrement(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
Layout = e("UIListLayout", {
|
|
||||||
FillDirection = Enum.FillDirection.Vertical,
|
|
||||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
||||||
|
|
||||||
[Roact.Change.AbsoluteContentSize] = function(object)
|
|
||||||
self.setContentSize(object.AbsoluteContentSize)
|
|
||||||
end,
|
|
||||||
}),
|
|
||||||
|
|
||||||
Padding = e("UIPadding", {
|
|
||||||
PaddingLeft = UDim.new(0, 20),
|
|
||||||
PaddingRight = UDim.new(0, 20),
|
|
||||||
}),
|
|
||||||
}),
|
}),
|
||||||
})
|
|
||||||
end)
|
PlaySounds = e(Setting, {
|
||||||
|
id = "playSounds",
|
||||||
|
name = "Play Sounds",
|
||||||
|
description = "Toggle sound effects",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
CheckForUpdates = e(Setting, {
|
||||||
|
id = "checkForUpdates",
|
||||||
|
name = "Check For Updates",
|
||||||
|
description = "Notify about newer compatible Rojo releases",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
CheckForPreleases = e(Setting, {
|
||||||
|
id = "checkForPrereleases",
|
||||||
|
name = "Include Prerelease Updates",
|
||||||
|
description = "Include prereleases when checking for updates",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
visible = if string.find(debug.traceback(), "\n[^\n]-user_.-$") == nil
|
||||||
|
then false -- Must be a local install to allow prerelease checks
|
||||||
|
else Settings:getBinding("checkForUpdates"),
|
||||||
|
}),
|
||||||
|
|
||||||
|
AutoConnectPlaytestServer = e(Setting, {
|
||||||
|
id = "autoConnectPlaytestServer",
|
||||||
|
name = "Auto Connect Playtest Server",
|
||||||
|
description = "Automatically connect game server to Rojo when playtesting while connected in Edit",
|
||||||
|
tag = "unstable",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
OpenScriptsExternally = e(Setting, {
|
||||||
|
id = "openScriptsExternally",
|
||||||
|
name = "Open Scripts Externally",
|
||||||
|
description = "Attempt to open scripts in an external editor",
|
||||||
|
tag = "unstable",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
TwoWaySync = e(Setting, {
|
||||||
|
id = "twoWaySync",
|
||||||
|
name = "Two-Way Sync",
|
||||||
|
description = "Editing files in Studio will sync them into the filesystem",
|
||||||
|
locked = self.props.syncActive,
|
||||||
|
tag = "unstable",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
LogLevel = e(Setting, {
|
||||||
|
id = "logLevel",
|
||||||
|
name = "Log Level",
|
||||||
|
description = "Plugin output verbosity level",
|
||||||
|
tag = "debug",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
|
||||||
|
options = invertedLevels,
|
||||||
|
showReset = Settings:getBinding("logLevel"):map(function(value)
|
||||||
|
return value ~= "Info"
|
||||||
|
end),
|
||||||
|
onReset = function()
|
||||||
|
Settings:set("logLevel", "Info")
|
||||||
|
end,
|
||||||
|
}),
|
||||||
|
|
||||||
|
TypecheckingEnabled = e(Setting, {
|
||||||
|
id = "typecheckingEnabled",
|
||||||
|
name = "Typechecking",
|
||||||
|
description = "Toggle typechecking on the API surface",
|
||||||
|
tag = "debug",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
TimingLogsEnabled = e(Setting, {
|
||||||
|
id = "timingLogsEnabled",
|
||||||
|
name = "Timing Logs",
|
||||||
|
description = "Toggle logging timing of internal actions for benchmarking Rojo performance",
|
||||||
|
tag = "debug",
|
||||||
|
transparency = self.props.transparency,
|
||||||
|
layoutOrder = layoutIncrement(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
Layout = e("UIListLayout", {
|
||||||
|
FillDirection = Enum.FillDirection.Vertical,
|
||||||
|
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||||
|
|
||||||
|
[Roact.Change.AbsoluteContentSize] = function(object)
|
||||||
|
self.setContentSize(object.AbsoluteContentSize)
|
||||||
|
end,
|
||||||
|
}),
|
||||||
|
|
||||||
|
Padding = e("UIPadding", {
|
||||||
|
PaddingLeft = UDim.new(0, 20),
|
||||||
|
PaddingRight = UDim.new(0, 20),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
return SettingsPage
|
return SettingsPage
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
--[[
|
--[[
|
||||||
Theming system taking advantage of Roact's new context API.
|
Theming system provided through Roact's context.
|
||||||
Doesn't use colors provided by Studio and instead just branches on theme
|
Uses Studio colors when possible.
|
||||||
name. This isn't exactly best practice.
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
-- Studio does not exist outside Roblox Studio, so we'll lazily initialize it
|
-- Studio does not exist outside Roblox Studio, so we'll lazily initialize it
|
||||||
@@ -15,6 +14,8 @@ local function getStudio()
|
|||||||
return _Studio
|
return _Studio
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local ContentProvider = game:GetService("ContentProvider")
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
|
|
||||||
@@ -35,6 +36,27 @@ function StudioProvider:updateTheme()
|
|||||||
local isDark = studioTheme.Name == "Dark"
|
local isDark = studioTheme.Name == "Dark"
|
||||||
|
|
||||||
local theme = strict(studioTheme.Name .. "Theme", {
|
local theme = strict(studioTheme.Name .. "Theme", {
|
||||||
|
Font = {
|
||||||
|
Main = Font.new("rbxasset://fonts/families/Montserrat.json", Enum.FontWeight.Medium, Enum.FontStyle.Normal),
|
||||||
|
Bold = Font.new("rbxasset://fonts/families/Montserrat.json", Enum.FontWeight.Bold, Enum.FontStyle.Normal),
|
||||||
|
Thin = Font.new(
|
||||||
|
"rbxasset://fonts/families/Montserrat.json",
|
||||||
|
Enum.FontWeight.Regular,
|
||||||
|
Enum.FontStyle.Normal
|
||||||
|
),
|
||||||
|
Code = Font.new(
|
||||||
|
"rbxasset://fonts/families/Inconsolata.json",
|
||||||
|
Enum.FontWeight.Regular,
|
||||||
|
Enum.FontStyle.Normal
|
||||||
|
),
|
||||||
|
},
|
||||||
|
TextSize = {
|
||||||
|
Body = 15,
|
||||||
|
Small = 13,
|
||||||
|
Medium = 16,
|
||||||
|
Large = 18,
|
||||||
|
Code = 16,
|
||||||
|
},
|
||||||
BrandColor = BRAND_COLOR,
|
BrandColor = BRAND_COLOR,
|
||||||
BackgroundColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainBackground),
|
BackgroundColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainBackground),
|
||||||
TextColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainText),
|
TextColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainText),
|
||||||
@@ -190,6 +212,13 @@ end
|
|||||||
|
|
||||||
function StudioProvider:init()
|
function StudioProvider:init()
|
||||||
self:updateTheme()
|
self:updateTheme()
|
||||||
|
|
||||||
|
-- Preload the Fonts so that getTextBoundsAsync won't yield
|
||||||
|
local fontAssetIds = {}
|
||||||
|
for _, font in self.state.theme.Font do
|
||||||
|
table.insert(fontAssetIds, font.Family)
|
||||||
|
end
|
||||||
|
pcall(ContentProvider.PreloadAsync, ContentProvider, fontAssetIds)
|
||||||
end
|
end
|
||||||
|
|
||||||
function StudioProvider:render()
|
function StudioProvider:render()
|
||||||
|
|||||||
41
plugin/src/App/getTextBoundsAsync.lua
Normal file
41
plugin/src/App/getTextBoundsAsync.lua
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
local TextService = game:GetService("TextService")
|
||||||
|
|
||||||
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
|
local Packages = Rojo.Packages
|
||||||
|
|
||||||
|
local Log = require(Packages.Log)
|
||||||
|
|
||||||
|
local params = Instance.new("GetTextBoundsParams")
|
||||||
|
|
||||||
|
local function getTextBoundsAsync(
|
||||||
|
text: string,
|
||||||
|
font: Font,
|
||||||
|
textSize: number,
|
||||||
|
width: number,
|
||||||
|
richText: boolean?
|
||||||
|
): Vector2
|
||||||
|
if type(text) ~= "string" then
|
||||||
|
Log.warn(`Invalid text. Expected string, received {type(text)} instead`)
|
||||||
|
return Vector2.zero
|
||||||
|
end
|
||||||
|
if #text >= 200_000 then
|
||||||
|
Log.warn(`Invalid text. Exceeds the 199,999 character limit`)
|
||||||
|
return Vector2.zero
|
||||||
|
end
|
||||||
|
|
||||||
|
params.Text = text
|
||||||
|
params.Font = font
|
||||||
|
params.Size = textSize
|
||||||
|
params.Width = width
|
||||||
|
params.RichText = not not richText
|
||||||
|
|
||||||
|
local success, bounds = pcall(TextService.GetTextBoundsAsync, TextService, params)
|
||||||
|
if not success then
|
||||||
|
Log.warn(`Failed to get text bounds: {bounds}`)
|
||||||
|
return Vector2.zero
|
||||||
|
end
|
||||||
|
|
||||||
|
return bounds
|
||||||
|
end
|
||||||
|
|
||||||
|
return getTextBoundsAsync
|
||||||
Reference in New Issue
Block a user