diff --git a/CHANGELOG.md b/CHANGELOG.md
index aec5f7ab..05550ae2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
* Updated Theme to use Studio colors ([#838])
* Improved patch visualizer UX ([#883])
* Added experimental setting for Auto Connect in playtests ([#840])
+* Improved settings UI ([#886])
* `Open Scripts Externally` option can now be changed while syncing ([#911])
* 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`:
@@ -60,6 +61,7 @@
[#838]: https://github.com/rojo-rbx/rojo/pull/838
[#840]: https://github.com/rojo-rbx/rojo/pull/840
[#883]: https://github.com/rojo-rbx/rojo/pull/883
+[#886]: https://github.com/rojo-rbx/rojo/pull/886
[#893]: https://github.com/rojo-rbx/rojo/pull/893
[#903]: https://github.com/rojo-rbx/rojo/pull/903
[#911]: https://github.com/rojo-rbx/rojo/pull/911
diff --git a/README.md b/README.md
index bbdeba30..bb4effcf 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-

+
@@ -43,4 +43,4 @@ Pull requests are welcome!
Rojo supports Rust 1.70.0 and newer. The minimum supported version of Rust is based on the latest versions of the dependencies that Rojo has.
## License
-Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details.
\ No newline at end of file
+Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details.
diff --git a/assets/icon-32.png b/assets/brand_images/icon-32.png
similarity index 100%
rename from assets/icon-32.png
rename to assets/brand_images/icon-32.png
diff --git a/assets/icon-link-32.png b/assets/brand_images/icon-link-32.png
similarity index 100%
rename from assets/icon-link-32.png
rename to assets/brand_images/icon-link-32.png
diff --git a/assets/icon-warn-32.png b/assets/brand_images/icon-warn-32.png
similarity index 100%
rename from assets/icon-warn-32.png
rename to assets/brand_images/icon-warn-32.png
diff --git a/assets/logo-512.png b/assets/brand_images/logo-512.png
similarity index 100%
rename from assets/logo-512.png
rename to assets/brand_images/logo-512.png
diff --git a/assets/images/back.png b/assets/images/icons/back.png
similarity index 100%
rename from assets/images/back.png
rename to assets/images/icons/back.png
diff --git a/assets/images/back.svg b/assets/images/icons/back.svg
similarity index 100%
rename from assets/images/back.svg
rename to assets/images/icons/back.svg
diff --git a/assets/images/close.png b/assets/images/icons/close.png
similarity index 100%
rename from assets/images/close.png
rename to assets/images/icons/close.png
diff --git a/assets/images/close.svg b/assets/images/icons/close.svg
similarity index 100%
rename from assets/images/close.svg
rename to assets/images/icons/close.svg
diff --git a/assets/images/icons/debug.png b/assets/images/icons/debug.png
new file mode 100644
index 00000000..b2217f0c
Binary files /dev/null and b/assets/images/icons/debug.png differ
diff --git a/assets/images/icons/expand.png b/assets/images/icons/expand.png
new file mode 100644
index 00000000..fcf561dc
Binary files /dev/null and b/assets/images/icons/expand.png differ
diff --git a/assets/images/icons/reset.png b/assets/images/icons/reset.png
new file mode 100644
index 00000000..802e430a
Binary files /dev/null and b/assets/images/icons/reset.png differ
diff --git a/assets/images/icons/warning.png b/assets/images/icons/warning.png
new file mode 100644
index 00000000..79d457df
Binary files /dev/null and b/assets/images/icons/warning.png differ
diff --git a/assets/round-rect-4px-radius.png b/assets/images/round-rect-4px-radius.png
similarity index 100%
rename from assets/round-rect-4px-radius.png
rename to assets/images/round-rect-4px-radius.png
diff --git a/plugin/src/App/Components/SlicedImage.lua b/plugin/src/App/Components/SlicedImage.lua
index 40279cc8..1dff9caa 100644
--- a/plugin/src/App/Components/SlicedImage.lua
+++ b/plugin/src/App/Components/SlicedImage.lua
@@ -20,6 +20,7 @@ local function SlicedImage(props)
Size = props.size,
Position = props.position,
AnchorPoint = props.anchorPoint,
+ AutomaticSize = props.automaticSize,
ZIndex = props.zIndex,
LayoutOrder = props.layoutOrder,
diff --git a/plugin/src/App/Components/Tag.lua b/plugin/src/App/Components/Tag.lua
new file mode 100644
index 00000000..9fed3d33
--- /dev/null
+++ b/plugin/src/App/Components/Tag.lua
@@ -0,0 +1,56 @@
+local Rojo = script:FindFirstAncestor("Rojo")
+local Plugin = Rojo.Plugin
+local Packages = Rojo.Packages
+
+local Roact = require(Packages.Roact)
+
+local Assets = require(Plugin.Assets)
+
+local SlicedImage = require(Plugin.App.Components.SlicedImage)
+
+local e = Roact.createElement
+
+return function(props)
+ return e(SlicedImage, {
+ slice = Assets.Slices.RoundedBackground,
+ color = props.color,
+ transparency = props.transparency:map(function(transparency)
+ return 0.9 + (0.1 * transparency)
+ end),
+ layoutOrder = props.layoutOrder,
+ position = props.position,
+ anchorPoint = props.anchorPoint,
+ size = UDim2.new(0, 0, 0, 16),
+ automaticSize = Enum.AutomaticSize.X,
+ }, {
+ Padding = e("UIPadding", {
+ PaddingLeft = UDim.new(0, 4),
+ PaddingRight = UDim.new(0, 4),
+ PaddingTop = UDim.new(0, 2),
+ PaddingBottom = UDim.new(0, 2),
+ }),
+ Icon = if props.icon
+ then e("ImageLabel", {
+ Size = UDim2.new(0, 12, 0, 12),
+ Position = UDim2.new(0, 0, 0.5, 0),
+ 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,
+ 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
diff --git a/plugin/src/App/StatusPages/Settings/Setting.lua b/plugin/src/App/StatusPages/Settings/Setting.lua
index 86170ec2..00c75d86 100644
--- a/plugin/src/App/StatusPages/Settings/Setting.lua
+++ b/plugin/src/App/StatusPages/Settings/Setting.lua
@@ -13,10 +13,23 @@ local Theme = require(Plugin.App.Theme)
local Checkbox = require(Plugin.App.Components.Checkbox)
local Dropdown = require(Plugin.App.Components.Dropdown)
local IconButton = require(Plugin.App.Components.IconButton)
+local Tag = require(Plugin.App.Components.Tag)
local e = Roact.createElement
local DIVIDER_FADE_SIZE = 0.1
+local TAG_TYPES = {
+ unstable = {
+ text = "UNSTABLE",
+ icon = Assets.Images.Icons.Warning,
+ color = { "Settings", "Setting", "UnstableColor" },
+ },
+ debug = {
+ text = "DEBUG",
+ icon = Assets.Images.Icons.Debug,
+ color = { "Settings", "Setting", "DebugColor" },
+ },
+}
local function getTextBounds(text, textSize, font, lineHeight, bounds)
local textBounds = TextService:GetTextSize(text, textSize, font, bounds)
@@ -27,6 +40,17 @@ local function getTextBounds(text, textSize, font, lineHeight, bounds)
return Vector2.new(textBounds.X, lineHeightAbsolute * lineCount - (lineHeightAbsolute - textSize))
end
+local function getThemeColorFromPath(theme, path)
+ local color = theme
+ for _, key in path do
+ if color[key] == nil then
+ return theme.BrandColor
+ end
+ color = color[key]
+ end
+ return color
+end
+
local Setting = Roact.Component:extend("Setting")
function Setting:init()
@@ -51,11 +75,11 @@ end
function Setting:render()
return Theme.with(function(theme)
- theme = theme.Settings
+ local settingsTheme = theme.Settings
return e("Frame", {
Size = self.contentSize:map(function(value)
- return UDim2.new(1, 0, 0, 20 + value.Y + 20)
+ return UDim2.new(1, 0, 0, value.Y + 20)
end),
LayoutOrder = self.props.layoutOrder,
ZIndex = -self.props.layoutOrder,
@@ -106,7 +130,7 @@ function Setting:render()
then e(IconButton, {
icon = Assets.Images.Icons.Reset,
iconSize = 24,
- color = theme.BackButtonColor,
+ color = settingsTheme.BackButtonColor,
transparency = self.props.transparency,
visible = self.props.showReset,
layoutOrder = -1,
@@ -120,37 +144,49 @@ function Setting:render()
Size = UDim2.new(1, 0, 1, 0),
BackgroundTransparency = 1,
}, {
- Name = e("TextLabel", {
- Text = (
- if self.props.experimental
- then '⚠ '
- elseif
- self.props.developerDebug
- then '⚑ ' -- Guru is the only font with the flag emoji
- else ""
- ) .. self.props.name,
- Font = Enum.Font.GothamBold,
- TextSize = 17,
- TextColor3 = theme.Setting.NameColor,
- TextXAlignment = Enum.TextXAlignment.Left,
- TextTransparency = self.props.transparency,
- RichText = true,
-
- Size = UDim2.new(1, 0, 0, 17),
-
- LayoutOrder = 1,
+ Heading = e("Frame", {
+ Size = UDim2.new(1, 0, 0, 16),
BackgroundTransparency = 1,
+ }, {
+ Layout = e("UIListLayout", {
+ VerticalAlignment = Enum.VerticalAlignment.Center,
+ FillDirection = Enum.FillDirection.Horizontal,
+ SortOrder = Enum.SortOrder.LayoutOrder,
+ Padding = UDim.new(0, 5),
+ }),
+ Tag = if self.props.tag and TAG_TYPES[self.props.tag]
+ then e(Tag, {
+ layoutOrder = 1,
+ transparency = self.props.transparency,
+ text = TAG_TYPES[self.props.tag].text,
+ icon = TAG_TYPES[self.props.tag].icon,
+ color = getThemeColorFromPath(theme, TAG_TYPES[self.props.tag].color),
+ })
+ else nil,
+ Name = e("TextLabel", {
+ Text = self.props.name,
+ Font = Enum.Font.GothamBold,
+ TextSize = 16,
+ TextColor3 = if self.props.tag and TAG_TYPES[self.props.tag]
+ then getThemeColorFromPath(theme, TAG_TYPES[self.props.tag].color)
+ else settingsTheme.Setting.NameColor,
+ TextXAlignment = Enum.TextXAlignment.Left,
+ TextTransparency = self.props.transparency,
+ RichText = true,
+
+ Size = UDim2.new(1, 0, 0, 16),
+
+ LayoutOrder = 2,
+ BackgroundTransparency = 1,
+ }),
}),
Description = e("TextLabel", {
- Text = (if self.props.experimental
- then '[Experimental] '
- elseif self.props.developerDebug then '[Dev Debug] '
- else "") .. self.props.description,
+ Text = self.props.description,
Font = Enum.Font.Gotham,
LineHeight = 1.2,
TextSize = 14,
- TextColor3 = theme.Setting.DescriptionColor,
+ TextColor3 = settingsTheme.Setting.DescriptionColor,
TextXAlignment = Enum.TextXAlignment.Left,
TextTransparency = self.props.transparency,
TextWrapped = true,
@@ -160,11 +196,9 @@ function Setting:render()
containerSize = self.containerSize,
inputSize = self.inputSize,
}):map(function(values)
- local desc = (if self.props.experimental then "[Experimental] " else "")
- .. self.props.description
local offset = values.inputSize.X + 5
local textBounds = getTextBounds(
- desc,
+ self.props.description,
14,
Enum.Font.Gotham,
1.2,
@@ -173,7 +207,7 @@ function Setting:render()
return UDim2.new(1, -offset, 0, textBounds.Y)
end),
- LayoutOrder = 2,
+ LayoutOrder = 3,
BackgroundTransparency = 1,
}),
@@ -181,21 +215,16 @@ function Setting:render()
VerticalAlignment = Enum.VerticalAlignment.Center,
FillDirection = Enum.FillDirection.Vertical,
SortOrder = Enum.SortOrder.LayoutOrder,
- Padding = UDim.new(0, 6),
+ Padding = UDim.new(0, 5),
[Roact.Change.AbsoluteContentSize] = function(object)
self.setContentSize(object.AbsoluteContentSize)
end,
}),
-
- Padding = e("UIPadding", {
- PaddingTop = UDim.new(0, 20),
- PaddingBottom = UDim.new(0, 20),
- }),
}),
Divider = e("Frame", {
- BackgroundColor3 = theme.DividerColor,
+ BackgroundColor3 = settingsTheme.DividerColor,
BackgroundTransparency = self.props.transparency,
Size = UDim2.new(1, 0, 0, 1),
BorderSizePixel = 0,
diff --git a/plugin/src/App/StatusPages/Settings/init.lua b/plugin/src/App/StatusPages/Settings/init.lua
index e5fb1af4..70f83508 100644
--- a/plugin/src/App/StatusPages/Settings/init.lua
+++ b/plugin/src/App/StatusPages/Settings/init.lua
@@ -166,7 +166,7 @@ function SettingsPage:render()
id = "autoConnectPlaytestServer",
name = "Auto Connect Playtest Server",
description = "Automatically connect game server to Rojo when playtesting while connected in Edit",
- experimental = true,
+ tag = "unstable",
transparency = self.props.transparency,
layoutOrder = layoutIncrement(),
}),
@@ -175,7 +175,7 @@ function SettingsPage:render()
id = "openScriptsExternally",
name = "Open Scripts Externally",
description = "Attempt to open scripts in an external editor",
- experimental = true,
+ tag = "unstable",
transparency = self.props.transparency,
layoutOrder = layoutIncrement(),
}),
@@ -185,7 +185,7 @@ function SettingsPage:render()
name = "Two-Way Sync",
description = "Editing files in Studio will sync them into the filesystem",
locked = self.props.syncActive,
- experimental = true,
+ tag = "unstable",
transparency = self.props.transparency,
layoutOrder = layoutIncrement(),
}),
@@ -194,7 +194,7 @@ function SettingsPage:render()
id = "logLevel",
name = "Log Level",
description = "Plugin output verbosity level",
- developerDebug = true,
+ tag = "debug",
transparency = self.props.transparency,
layoutOrder = layoutIncrement(),
@@ -211,7 +211,7 @@ function SettingsPage:render()
id = "typecheckingEnabled",
name = "Typechecking",
description = "Toggle typechecking on the API surface",
- developerDebug = true,
+ tag = "debug",
transparency = self.props.transparency,
layoutOrder = layoutIncrement(),
}),
@@ -220,7 +220,7 @@ function SettingsPage:render()
id = "timingLogsEnabled",
name = "Timing Logs",
description = "Toggle logging timing of internal actions for benchmarking Rojo performance",
- developerDebug = true,
+ tag = "debug",
transparency = self.props.transparency,
layoutOrder = layoutIncrement(),
}),
diff --git a/plugin/src/App/Theme.lua b/plugin/src/App/Theme.lua
index 84a429c6..42d61942 100644
--- a/plugin/src/App/Theme.lua
+++ b/plugin/src/App/Theme.lua
@@ -35,6 +35,7 @@ function StudioProvider:updateTheme()
local isDark = studioTheme.Name == "Dark"
local theme = strict(studioTheme.Name .. "Theme", {
+ BrandColor = BRAND_COLOR,
BackgroundColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainBackground),
TextColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainText),
SubTextColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.SubText),
@@ -166,6 +167,8 @@ function StudioProvider:updateTheme()
Setting = {
NameColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.BrightText),
DescriptionColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainText),
+ UnstableColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.WarningText),
+ DebugColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.InfoText),
},
},
Header = {
diff --git a/plugin/src/Assets.lua b/plugin/src/Assets.lua
index 91f82d1a..e48c1217 100644
--- a/plugin/src/Assets.lua
+++ b/plugin/src/Assets.lua
@@ -25,6 +25,8 @@ local Assets = {
Back = "rbxassetid://6017213752",
Reset = "rbxassetid://10142422327",
Expand = "rbxassetid://12045401097",
+ Warning = "rbxassetid://16571019891",
+ Debug = "rbxassetid://16588411361",
Checkmark = "rbxassetid://16571012729",
Exclamation = "rbxassetid://16571172190",
SyncSuccess = "rbxassetid://16565035221",
diff --git a/src/web/assets.rs b/src/web/assets.rs
index 37adbe13..39f0958b 100644
--- a/src/web/assets.rs
+++ b/src/web/assets.rs
@@ -29,13 +29,13 @@ macro_rules! declare_asset {
declare_asset!(css, "../../assets/index.css");
pub fn logo() -> &'static [u8] {
- static LOGO: &[u8] = include_bytes!("../../assets/logo-512.png");
+ static LOGO: &[u8] = include_bytes!("../../assets/brand_images/logo-512.png");
LOGO
}
pub fn icon() -> &'static [u8] {
- static ICON: &[u8] = include_bytes!("../../assets/icon-32.png");
+ static ICON: &[u8] = include_bytes!("../../assets/brand_images/icon-32.png");
ICON
}