forked from rojo-rbx/rojo
Adds the ability to define descriptive tooltips for settings when they are locked.  Makes some minor improvements to tooltip layout logic as well.
183 lines
5.1 KiB
Lua
183 lines
5.1 KiB
Lua
local Rojo = script:FindFirstAncestor("Rojo")
|
|
local Plugin = Rojo.Plugin
|
|
local Packages = Rojo.Packages
|
|
|
|
local Roact = require(Packages.Roact)
|
|
local Flipper = require(Packages.Flipper)
|
|
|
|
local Assets = require(Plugin.Assets)
|
|
local Theme = require(Plugin.App.Theme)
|
|
local bindingUtil = require(Plugin.App.bindingUtil)
|
|
local getTextBoundsAsync = require(Plugin.App.getTextBoundsAsync)
|
|
|
|
local SlicedImage = require(script.Parent.SlicedImage)
|
|
local ScrollingFrame = require(script.Parent.ScrollingFrame)
|
|
local Tooltip = require(script.Parent.Tooltip)
|
|
|
|
local e = Roact.createElement
|
|
|
|
local Dropdown = Roact.Component:extend("Dropdown")
|
|
|
|
function Dropdown:init()
|
|
self.openMotor = Flipper.SingleMotor.new(0)
|
|
self.openBinding = bindingUtil.fromMotor(self.openMotor)
|
|
|
|
self.contentSize, self.setContentSize = Roact.createBinding(Vector2.new(0, 0))
|
|
|
|
self:setState({
|
|
open = false,
|
|
})
|
|
end
|
|
|
|
function Dropdown:didUpdate(prevProps)
|
|
if self.props.locked and not prevProps.locked then
|
|
self:setState({
|
|
open = false,
|
|
})
|
|
end
|
|
|
|
self.openMotor:setGoal(Flipper.Spring.new(self.state.open and 1 or 0, {
|
|
frequency = 6,
|
|
dampingRatio = 1.1,
|
|
}))
|
|
end
|
|
|
|
function Dropdown:render()
|
|
return Theme.with(function(theme)
|
|
local dropdownTheme = theme.Dropdown
|
|
|
|
local optionButtons = {}
|
|
local width = -1
|
|
for i, option in self.props.options do
|
|
local text = tostring(option or "")
|
|
local textBounds = getTextBoundsAsync(text, theme.Font.Main, theme.TextSize.Body, math.huge)
|
|
if textBounds.X > width then
|
|
width = textBounds.X
|
|
end
|
|
|
|
optionButtons[text] = e("TextButton", {
|
|
Text = text,
|
|
LayoutOrder = i,
|
|
Size = UDim2.new(1, 0, 0, 24),
|
|
BackgroundColor3 = dropdownTheme.BackgroundColor,
|
|
TextTransparency = self.props.transparency,
|
|
BackgroundTransparency = self.props.transparency,
|
|
BorderSizePixel = 0,
|
|
TextColor3 = dropdownTheme.TextColor,
|
|
TextXAlignment = Enum.TextXAlignment.Left,
|
|
TextSize = theme.TextSize.Body,
|
|
FontFace = theme.Font.Main,
|
|
|
|
[Roact.Event.Activated] = function()
|
|
if self.props.locked then
|
|
return
|
|
end
|
|
self:setState({
|
|
open = false,
|
|
})
|
|
self.props.onClick(option)
|
|
end,
|
|
}, {
|
|
Padding = e("UIPadding", {
|
|
PaddingLeft = UDim.new(0, 6),
|
|
}),
|
|
})
|
|
end
|
|
|
|
return e("ImageButton", {
|
|
Size = UDim2.new(0, width + 50, 0, 28),
|
|
Position = self.props.position,
|
|
AnchorPoint = self.props.anchorPoint,
|
|
LayoutOrder = self.props.layoutOrder,
|
|
ZIndex = self.props.zIndex,
|
|
BackgroundTransparency = 1,
|
|
|
|
[Roact.Event.Activated] = function()
|
|
if self.props.locked then
|
|
return
|
|
end
|
|
self:setState({
|
|
open = not self.state.open,
|
|
})
|
|
end,
|
|
}, {
|
|
Border = e(SlicedImage, {
|
|
slice = Assets.Slices.RoundedBorder,
|
|
color = dropdownTheme.BorderColor,
|
|
transparency = self.props.transparency,
|
|
size = UDim2.new(1, 0, 1, 0),
|
|
}, {
|
|
DropArrow = e("ImageLabel", {
|
|
Image = if self.props.locked then Assets.Images.Dropdown.Locked else Assets.Images.Dropdown.Arrow,
|
|
ImageColor3 = dropdownTheme.IconColor,
|
|
ImageTransparency = self.props.transparency,
|
|
|
|
Size = UDim2.new(0, 18, 0, 18),
|
|
Position = UDim2.new(1, -6, 0.5, 0),
|
|
AnchorPoint = Vector2.new(1, 0.5),
|
|
Rotation = self.openBinding:map(function(a)
|
|
return a * 180
|
|
end),
|
|
|
|
BackgroundTransparency = 1,
|
|
}, {
|
|
StateTip = if self.props.locked
|
|
then e(Tooltip.Trigger, {
|
|
text = self.props.lockedTooltip or "(Cannot be changed right now)",
|
|
})
|
|
else nil,
|
|
}),
|
|
Active = e("TextLabel", {
|
|
Size = UDim2.new(1, -30, 1, 0),
|
|
Position = UDim2.new(0, 6, 0, 0),
|
|
BackgroundTransparency = 1,
|
|
Text = self.props.active,
|
|
FontFace = theme.Font.Main,
|
|
TextSize = theme.TextSize.Body,
|
|
TextColor3 = dropdownTheme.TextColor,
|
|
TextXAlignment = Enum.TextXAlignment.Left,
|
|
TextTransparency = self.props.transparency,
|
|
}),
|
|
}),
|
|
Options = if self.state.open
|
|
then e(SlicedImage, {
|
|
slice = Assets.Slices.RoundedBackground,
|
|
color = dropdownTheme.BackgroundColor,
|
|
position = UDim2.new(1, 0, 1, 3),
|
|
size = self.openBinding:map(function(a)
|
|
return UDim2.new(1, 0, a * math.min(3, #self.props.options), 0)
|
|
end),
|
|
anchorPoint = Vector2.new(1, 0),
|
|
}, {
|
|
Border = e(SlicedImage, {
|
|
slice = Assets.Slices.RoundedBorder,
|
|
color = dropdownTheme.BorderColor,
|
|
transparency = self.props.transparency,
|
|
size = UDim2.new(1, 0, 1, 0),
|
|
}),
|
|
ScrollingFrame = e(ScrollingFrame, {
|
|
size = UDim2.new(1, -4, 1, -4),
|
|
position = UDim2.new(0, 2, 0, 2),
|
|
transparency = self.props.transparency,
|
|
contentSize = self.contentSize,
|
|
}, {
|
|
Layout = e("UIListLayout", {
|
|
VerticalAlignment = Enum.VerticalAlignment.Top,
|
|
FillDirection = Enum.FillDirection.Vertical,
|
|
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
Padding = UDim.new(0, 0),
|
|
|
|
[Roact.Change.AbsoluteContentSize] = function(object)
|
|
self.setContentSize(object.AbsoluteContentSize)
|
|
end,
|
|
}),
|
|
Options = Roact.createFragment(optionButtons),
|
|
}),
|
|
})
|
|
else nil,
|
|
})
|
|
end)
|
|
end
|
|
|
|
return Dropdown
|