plugin: Add PluginSettings context item, render it in settings screen

This commit is contained in:
Lucien Greathouse
2020-03-17 23:03:01 -07:00
parent c5ce15fe34
commit 2cefd1bf2e
4 changed files with 161 additions and 34 deletions

View File

@@ -18,7 +18,6 @@ local ConnectingPanel = require(Plugin.Components.ConnectingPanel)
local ConnectionActivePanel = require(Plugin.Components.ConnectionActivePanel) local ConnectionActivePanel = require(Plugin.Components.ConnectionActivePanel)
local ErrorPanel = require(Plugin.Components.ErrorPanel) local ErrorPanel = require(Plugin.Components.ErrorPanel)
local SettingsPanel = require(Plugin.Components.SettingsPanel) local SettingsPanel = require(Plugin.Components.SettingsPanel)
local Theme = require(Plugin.Components.Theme)
local e = Roact.createElement local e = Roact.createElement
@@ -214,11 +213,9 @@ function App:render()
} }
end end
return e(Theme.StudioProvider, nil, { return e(Roact.Portal, {
UI = e(Roact.Portal, { target = self.dockWidget,
target = self.dockWidget, }, children)
}, children),
})
end end
function App:didMount() function App:didMount()

View File

@@ -0,0 +1,119 @@
--[[
Persistent plugin settings that can be accessed via Roact context.
]]
local Rojo = script:FindFirstAncestor("Rojo")
local Roact = require(Rojo.Roact)
local defaultSettings = {
openScriptsExternally = false,
}
local Settings = {}
Settings.__index = Settings
function Settings.fromPlugin(plugin)
local values = {}
for name, defaultValue in pairs(defaultSettings) do
local savedValue = plugin:GetSetting("Rojo_" .. name)
if savedValue == nil then
values[name] = defaultValue
else
values[name] = savedValue
end
end
return setmetatable({
__values = values,
__plugin = plugin,
__updateListeners = {},
}, Settings)
end
function Settings:get(name)
if defaultSettings[name] == nil then
error("Invalid setings name " .. tostring(name), 2)
end
return self.__values[name]
end
function Settings:set(name, value)
self.__plugin:SetSetting(name, value)
self.__values[name] = value
for callback in pairs(self.__updateListeners) do
callback(name, value)
end
end
function Settings:onUpdate(newCallback)
local newListeners = {}
for callback in pairs(self.__updateListeners) do
newListeners[callback] = true
end
newListeners[newCallback] = true
self.__updateListeners = newListeners
return function()
local newListeners = {}
for callback in pairs(self.__updateListeners) do
if callback ~= newCallback then
newListeners[callback] = true
end
end
self.__updateListeners = newListeners
end
end
local Context = Roact.createContext(nil)
local StudioProvider = Roact.Component:extend("StudioProvider")
function StudioProvider:init()
self.settings = Settings.fromPlugin(self.props.plugin)
end
function StudioProvider:render()
return Roact.createElement(Context.Provider, {
value = self.settings,
}, self.props[Roact.Children])
end
local InternalConsumer = Roact.Component:extend("InternalConsumer")
function InternalConsumer:render()
return self.props.render(self.props.settings)
end
function InternalConsumer:didMount()
self.disconnect = self.props.settings:onUpdate(function()
-- Trigger a dummy state update to update the settings consumer.
self:setState({})
end)
end
function InternalConsumer:willUnmount()
self.disconnect()
end
local function with(callback)
return Roact.createElement(Context.Consumer, {
render = function(settings)
return Roact.createElement(InternalConsumer, {
settings = settings,
render = callback,
})
end,
})
end
return {
StudioProvider = StudioProvider,
with = with,
}

View File

@@ -2,10 +2,11 @@ local Roact = require(script:FindFirstAncestor("Rojo").Roact)
local Plugin = script:FindFirstAncestor("Plugin") local Plugin = script:FindFirstAncestor("Plugin")
local Theme = require(Plugin.Components.Theme)
local Panel = require(Plugin.Components.Panel)
local FitText = require(Plugin.Components.FitText) local FitText = require(Plugin.Components.FitText)
local FormButton = require(Plugin.Components.FormButton) local FormButton = require(Plugin.Components.FormButton)
local Panel = require(Plugin.Components.Panel)
local PluginSettings = require(Plugin.Components.PluginSettings)
local Theme = require(Plugin.Components.Theme)
local e = Roact.createElement local e = Roact.createElement
@@ -15,32 +16,34 @@ function SettingsPanel:render()
local back = self.props.back local back = self.props.back
return Theme.with(function(theme) return Theme.with(function(theme)
return e(Panel, nil, { return PluginSettings.with(function(settings)
Layout = Roact.createElement("UIListLayout", { return e(Panel, nil, {
HorizontalAlignment = Enum.HorizontalAlignment.Center, Layout = Roact.createElement("UIListLayout", {
VerticalAlignment = Enum.VerticalAlignment.Center, HorizontalAlignment = Enum.HorizontalAlignment.Center,
SortOrder = Enum.SortOrder.LayoutOrder, VerticalAlignment = Enum.VerticalAlignment.Center,
Padding = UDim.new(0, 8), SortOrder = Enum.SortOrder.LayoutOrder,
}), Padding = UDim.new(0, 8),
}),
Text = e(FitText, { Text = e(FitText, {
Padding = Vector2.new(12, 6), Padding = Vector2.new(12, 6),
Font = theme.ButtonFont, Font = theme.ButtonFont,
TextSize = 18, TextSize = 18,
Text = "This will be a settings panel.", Text = "openScriptsExternally: " .. tostring(settings:get("openScriptsExternally")),
TextColor3 = theme.Text1, TextColor3 = theme.Text1,
BackgroundTransparency = 1, BackgroundTransparency = 1,
}), }),
DisconnectButton = e(FormButton, { DisconnectButton = e(FormButton, {
layoutOrder = 2, layoutOrder = 2,
text = "Okay", text = "Okay",
secondary = true, secondary = true,
onClick = function() onClick = function()
back() back()
end, end,
}), }),
}) })
end)
end) end)
end end

View File

@@ -14,9 +14,17 @@ local Roact = require(script.Parent.Roact)
local Config = require(script.Config) local Config = require(script.Config)
local App = require(script.Components.App) local App = require(script.Components.App)
local Theme = require(script.Components.Theme)
local PluginSettings = require(script.Components.PluginSettings)
local app = Roact.createElement(App, { local app = Roact.createElement(Theme.StudioProvider, nil, {
plugin = plugin, Roact.createElement(PluginSettings.StudioProvider, {
plugin = plugin,
}, {
RojoUI = Roact.createElement(App, {
plugin = plugin,
}),
})
}) })
local tree = Roact.mount(app, nil, "Rojo UI") local tree = Roact.mount(app, nil, "Rojo UI")