From 3d4e387d350bd12366026623d1f0340a034bb1c4 Mon Sep 17 00:00:00 2001 From: boatbomber Date: Mon, 13 May 2024 10:36:03 -0700 Subject: [PATCH] Redesign settings UI in plugin (#886) --- CHANGELOG.md | 2 + README.md | 4 +- assets/{ => brand_images}/icon-32.png | Bin assets/{ => brand_images}/icon-link-32.png | Bin assets/{ => brand_images}/icon-warn-32.png | Bin assets/{ => brand_images}/logo-512.png | Bin assets/images/{ => icons}/back.png | Bin assets/images/{ => icons}/back.svg | 0 assets/images/{ => icons}/close.png | Bin assets/images/{ => icons}/close.svg | 0 assets/images/icons/debug.png | Bin 0 -> 183 bytes assets/images/icons/expand.png | Bin 0 -> 273 bytes assets/images/icons/reset.png | Bin 0 -> 933 bytes assets/images/icons/warning.png | Bin 0 -> 241 bytes assets/{ => images}/round-rect-4px-radius.png | Bin plugin/src/App/Components/SlicedImage.lua | 1 + plugin/src/App/Components/Tag.lua | 56 ++++++++++ .../src/App/StatusPages/Settings/Setting.lua | 105 +++++++++++------- plugin/src/App/StatusPages/Settings/init.lua | 12 +- plugin/src/App/Theme.lua | 3 + plugin/src/Assets.lua | 2 + src/web/assets.rs | 4 +- 22 files changed, 141 insertions(+), 48 deletions(-) rename assets/{ => brand_images}/icon-32.png (100%) rename assets/{ => brand_images}/icon-link-32.png (100%) rename assets/{ => brand_images}/icon-warn-32.png (100%) rename assets/{ => brand_images}/logo-512.png (100%) rename assets/images/{ => icons}/back.png (100%) rename assets/images/{ => icons}/back.svg (100%) rename assets/images/{ => icons}/close.png (100%) rename assets/images/{ => icons}/close.svg (100%) create mode 100644 assets/images/icons/debug.png create mode 100644 assets/images/icons/expand.png create mode 100644 assets/images/icons/reset.png create mode 100644 assets/images/icons/warning.png rename assets/{ => images}/round-rect-4px-radius.png (100%) create mode 100644 plugin/src/App/Components/Tag.lua 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 @@
- Rojo + Rojo
 
@@ -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 0000000000000000000000000000000000000000..b2217f0cc933c166880acd1444f8811676c28814 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$0wn*`OvwRKb)GJcArhB;&j*S!845UG^jJB? z%8BVUgG>XnN(hsXo0Dpc-8S1CyUCvCW>;u`*U4my^Yr-;d(h#fTw%kdNiK=AR6d5L zFIj7stUvwI^;*gF|2@CnJ=My+dG{?>#IsG@^0~~1uEUXg@A}w>H&~*tO@M zJkO<(2#^G09u6@a^fNzv0S+30DORidvIcyc7?LxD=Xi-v_yP}rM5H4Zg(yX`qMr?o z%)v>^to{)w2>MSg+{u`L92@uYp|E!5&=k0TXaOYwoX@g_nX1e@KJsHW=ofIn&&Urp z@&qec!Cg#MVOR3If?cIoz!8<@b&tzK^0U~ln7RUe0;*M4_$3t!NqjBqKM*V~1YRJM zsv7sG95E9p$2;LgF3#u~flRtoMxafDmG!c<@KaZS=0T2zaPMV_CM%UP))gJcF~C@4 zBLxy9Bq0eBBuKDB!ZLitbxXI#A8A8{?_nGn1|HZN1#FTX-^a|jTeS)T+RYG9E(mZ_ zT6_Uk*0$>@vzQLwbgkxYo(ob#?P5YCfyA!ZN^*EO#xYKX=+P8$ zFlP)e=&X{?ubJb`efXy5W>DxDiDZ|1*9ACgkaW7#88_00000NkvXX Hu0mjf$kUj$ literal 0 HcmV?d00001 diff --git a/assets/images/icons/warning.png b/assets/images/icons/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..79d457df0a3d476c26fcad4a30109217d27ec628 GIT binary patch literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6c6hothG?9xouJ5f$U%hlzFO## zMVw0tnxdMV3OcMT994zl{hP8@U1afVJg`WsK{^1>e(l;bzkaQg&LZe8b0mz+rfBY8SjDKBjRS?K6ad#cP-EM z$v@=-FO+lcJBQy$oL9=#%d}(?$BH=@duC47Vw(6cD7e~k^51*n%xrOXEU&75`=#!Y p>1O>uL%K)pRsG$~x3kw@WiBcabDEuDw;1RL22WQ%mvv4FO#ry~UOoT- literal 0 HcmV?d00001 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 }