When creating a plugin that has some Gui whether in the form of a DockWidgetPluginGui or a ScreenGui in CoreGui, you might have though “Wont this gui look bad in dark mode if im making it for light mode?”. Well dont you worry, here is a utility module script that changes the colors acordingly depending on how you set up the attributes.
How?
With just 3 easy steps!
1. Get a studio theme-color viewer plugin
This is technically optional, but it saves all the time to have it. I use Studio Color Viewer. It allowes you to see all the colors studio uses in its theme neatly in a list so you can pick which one to use.
2. Design your gui & setup attributes
When making some GuiObject (Frame, TextLabel, …), check your Studio Color Viewer and find some color that fits your design. If you were setting a BackgroundColor3, this is how you should proceed:
- set the color normally
- add a string attribute to the object named like so
"studio_" + specification + "_clr"
- set the attribute to the name of the color (for example “Titlebar”)
In the end you should have an attribute like this:
What is this specification tohugh? Well its really just the simplified name of the property you are setting, for example for “BackgroundColor3” its “bg” because you wouldnt want to have to write “BackgroundColor3” 40 times in a gui (its also always lowercase).
Here are all the supported properties and their specifications:
- BackgroundColor3 = bg
- BorderColor3 = border
- ImageColor3 = image
- TextColor3 = text
- TextStrokeColor3 = text_stroke
- PlaceholderColor3 = placeholder
- Color3 = clr3
- Color = clr
All studio theme colors also have a “modifier”, the modifiers are: Default
, Hover
, Pressed
, Disabled
, Selected
. This means all studio theme colors are actually 5 colors, by default your attribute uses the Default
modifier but if you wish to use a different one you can, by adding another attribute named "studio_" + specification + "_mod"
and setting it to the desired modifier.
3. Insert the utility module and use it
Under your main plugin script insert a ModuleScript, name it “theme” and paste into it the source code at the very end of this post.
[i will make this a public package once roblox allows public packages]
Then inside your main script, all you need to do is require it and write:
local theme_util = require(script.theme)
theme_util.StudioGuiThemeUpdater.new(gui) -- "gui" is the base parent of your gui
Thats it!
I know it might seem like a lot of instructions but its really a simple process.
Bonus 4th step
If you keep the StudioGuiThemeUpdater you create in your plugin script in a variable, you can then manually call :Update
on it to update all gui objects under its adornee (you can also change the adornee
property) or you can call :UpdateObject
to update just one object in your gui if needed. In both methods you can optionally specify a different StudioTheme than studio currently has.
Source Code
--!strict
local module = {}
local studio_service = settings().Studio
export type StudioGuiThemeUpdater = {
adornee : GuiBase2d,
Update : (self : StudioGuiThemeUpdater, theme : StudioTheme?) -> (),
UpdateObject : (self : StudioGuiThemeUpdater, obj : GuiObject | Color3Value | UIComponent, theme : StudioTheme?) -> ()
}
module.StudioGuiThemeUpdater = {}
local StudioGuiThemeUpdater = {} :: StudioGuiThemeUpdater
function StudioGuiThemeUpdater:Update(theme : StudioTheme?)
if not theme then theme = studio_service.Theme :: StudioTheme end
for _, desc in self.adornee:GetDescendants() do
if desc:IsA("GuiObject") or desc:IsA("Color3Value") or desc:IsA("UIComponent") then
self:UpdateObject(desc, theme)
end
end
end
function StudioGuiThemeUpdater:UpdateObject(obj : GuiObject | Color3Value | UIComponent, theme : StudioTheme?)
if not theme then theme = studio_service.Theme :: StudioTheme end
local function update_prop_if_has_attr(obj : GuiObject | Color3Value | UIComponent, attr_specif : string, prop_name : string)
local clr = obj:GetAttribute("studio_"..attr_specif.."_clr")
if clr ~= nil then
local mod = obj:GetAttribute("studio_"..attr_specif.."_mod")
obj[prop_name] = (theme :: StudioTheme):GetColor(Enum.StudioStyleGuideColor[clr], Enum.StudioStyleGuideModifier[mod or "Default"])
end
end
update_prop_if_has_attr(obj, "bg", "BackgroundColor3")
update_prop_if_has_attr(obj, "border", "BorderColor3")
update_prop_if_has_attr(obj, "image", "ImageColor3")
update_prop_if_has_attr(obj, "text", "TextColor3")
update_prop_if_has_attr(obj, "text_stroke", "TextStrokeColor3")
update_prop_if_has_attr(obj, "placeholder", "PlaceholderColor3")
update_prop_if_has_attr(obj, "clr3", "Color3")
update_prop_if_has_attr(obj, "clr", "Color")
end
function module.StudioGuiThemeUpdater.new(adornee : GuiBase2d) : StudioGuiThemeUpdater
local new = table.clone(StudioGuiThemeUpdater)
new.adornee = adornee
new:Update()
studio_service.ThemeChanged:Connect(function () new:Update() end)
return new
end
return module