mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
UX update
This commit is contained in:
parent
3e6a50ce4b
commit
0e5e809894
5 changed files with 397 additions and 48 deletions
|
|
@ -61,24 +61,40 @@ local function SelectionOption(props)
|
|||
else Color3.fromHex("7F8C8D"))
|
||||
else theme.BorderedContainer.BackgroundColor
|
||||
local textColor = if isSelected then Color3.new(1, 1, 1) else theme.TextColor
|
||||
-- Add caret if this button can cascade to children
|
||||
local displayText = if props.showCaret then props.text .. " ▼" else props.text
|
||||
local buttonWidth = if props.showCaret then 48 else 36
|
||||
|
||||
return e("TextButton", {
|
||||
Size = UDim2.new(0, 36, 0, 18),
|
||||
Size = UDim2.new(0, buttonWidth, 0, 18),
|
||||
BackgroundColor3 = bgColor,
|
||||
BackgroundTransparency = props.transparency:map(function(t)
|
||||
return if isSelected then 0.1 + (0.9 * t) else 0.7 + (0.3 * t)
|
||||
end),
|
||||
BorderSizePixel = 0,
|
||||
Text = props.text,
|
||||
Text = displayText,
|
||||
FontFace = if isSelected then theme.Font.Bold else theme.Font.Main,
|
||||
TextSize = theme.TextSize.Small,
|
||||
TextColor3 = textColor,
|
||||
TextTransparency = props.transparency,
|
||||
LayoutOrder = props.layoutOrder,
|
||||
ZIndex = 10,
|
||||
[Roact.Event.Activated] = function()
|
||||
if props.onClick then
|
||||
props.onClick()
|
||||
[Roact.Event.Activated] = function(_rbx, _input, clickCount)
|
||||
-- For parent-only nodes, any click triggers subtree selection
|
||||
if props.isParentOnly then
|
||||
if props.onDoubleClick then
|
||||
props.onDoubleClick()
|
||||
end
|
||||
elseif clickCount == 1 then
|
||||
-- Double click: apply to subtree
|
||||
if props.onDoubleClick then
|
||||
props.onDoubleClick()
|
||||
end
|
||||
else
|
||||
-- Single click: apply to this node only
|
||||
if props.onClick then
|
||||
props.onClick()
|
||||
end
|
||||
end
|
||||
end,
|
||||
}, {
|
||||
|
|
@ -95,8 +111,12 @@ local function SelectionRadio(props)
|
|||
return nil
|
||||
end
|
||||
|
||||
local showCaret = props.hasChildren
|
||||
local frameWidth = if showCaret then 154 else 118
|
||||
local isParentOnly = props.isParentOnly
|
||||
|
||||
return e("Frame", {
|
||||
Size = UDim2.new(0, 118, 0, 18),
|
||||
Size = UDim2.new(0, frameWidth, 0, 18),
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(1, -5, 0, 3),
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
|
|
@ -109,17 +129,24 @@ local function SelectionRadio(props)
|
|||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 4),
|
||||
}),
|
||||
Pull = e(SelectionOption, {
|
||||
text = "Pull",
|
||||
Studio = e(SelectionOption, {
|
||||
text = "Studio",
|
||||
optionType = "pull",
|
||||
isSelected = props.selection == "pull",
|
||||
transparency = props.transparency,
|
||||
layoutOrder = 1,
|
||||
showCaret = showCaret,
|
||||
isParentOnly = isParentOnly,
|
||||
onClick = function()
|
||||
if props.onSelectionChange then
|
||||
props.onSelectionChange(props.nodeId, "pull")
|
||||
end
|
||||
end,
|
||||
onDoubleClick = function()
|
||||
if props.onSubtreeSelectionChange then
|
||||
props.onSubtreeSelectionChange(props.nodeId, "pull")
|
||||
end
|
||||
end,
|
||||
}),
|
||||
Skip = e(SelectionOption, {
|
||||
text = "Skip",
|
||||
|
|
@ -127,23 +154,37 @@ local function SelectionRadio(props)
|
|||
isSelected = props.selection == "ignore",
|
||||
transparency = props.transparency,
|
||||
layoutOrder = 2,
|
||||
showCaret = showCaret,
|
||||
isParentOnly = isParentOnly,
|
||||
onClick = function()
|
||||
if props.onSelectionChange then
|
||||
props.onSelectionChange(props.nodeId, "ignore")
|
||||
end
|
||||
end,
|
||||
onDoubleClick = function()
|
||||
if props.onSubtreeSelectionChange then
|
||||
props.onSubtreeSelectionChange(props.nodeId, "ignore")
|
||||
end
|
||||
end,
|
||||
}),
|
||||
Push = e(SelectionOption, {
|
||||
text = "Push",
|
||||
Rojo = e(SelectionOption, {
|
||||
text = "Rojo",
|
||||
optionType = "push",
|
||||
isSelected = props.selection == "push",
|
||||
transparency = props.transparency,
|
||||
layoutOrder = 3,
|
||||
showCaret = showCaret,
|
||||
isParentOnly = isParentOnly,
|
||||
onClick = function()
|
||||
if props.onSelectionChange then
|
||||
props.onSelectionChange(props.nodeId, "push")
|
||||
end
|
||||
end,
|
||||
onDoubleClick = function()
|
||||
if props.onSubtreeSelectionChange then
|
||||
props.onSubtreeSelectionChange(props.nodeId, "push")
|
||||
end
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
|
@ -183,6 +224,7 @@ function DomLabel:init()
|
|||
|
||||
self:setState({
|
||||
renderExpansion = self.expanded,
|
||||
isHovered = false,
|
||||
})
|
||||
self.motorStepConnection = self.motor:onStep(function(value)
|
||||
if not self.isMounted then
|
||||
|
|
@ -301,6 +343,12 @@ function DomLabel:render()
|
|||
BackgroundTransparency = 1,
|
||||
Text = "",
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
[Roact.Event.MouseEnter] = function()
|
||||
self:setState({ isHovered = true })
|
||||
end,
|
||||
[Roact.Event.MouseLeave] = function()
|
||||
self:setState({ isHovered = false })
|
||||
end,
|
||||
[Roact.Event.Activated] = function(_rbx: Instance, _input: InputObject, clickCount: number)
|
||||
if clickCount == 1 then
|
||||
-- Double click opens the instance in explorer
|
||||
|
|
@ -413,11 +461,17 @@ function DomLabel:render()
|
|||
else nil,
|
||||
}),
|
||||
SelectionRadio = e(SelectionRadio, {
|
||||
visible = props.patchType ~= nil and props.onSelectionChange ~= nil,
|
||||
-- Visible for nodes with patchType, or for parent-only nodes on hover
|
||||
visible = (props.patchType ~= nil and props.onSelectionChange ~= nil)
|
||||
or (props.patchType == nil and props.hasChildren and self.state.isHovered and props.onSubtreeSelectionChange ~= nil),
|
||||
nodeId = props.nodeId,
|
||||
selection = props.selection,
|
||||
transparency = props.transparency,
|
||||
hasChildren = props.hasChildren,
|
||||
-- For parent-only nodes (no patchType), only subtree selection makes sense
|
||||
isParentOnly = props.patchType == nil,
|
||||
onSelectionChange = props.onSelectionChange,
|
||||
onSubtreeSelectionChange = props.onSubtreeSelectionChange,
|
||||
}),
|
||||
LineGuides = e("Folder", nil, lineGuides),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ function PatchVisualizer:render()
|
|||
nodeId = node.id,
|
||||
selection = self.props.selections and self.props.selections[node.id],
|
||||
onSelectionChange = self.props.onSelectionChange,
|
||||
onSubtreeSelectionChange = self.props.onSubtreeSelectionChange,
|
||||
})
|
||||
|
||||
if isFinalChild then
|
||||
|
|
|
|||
|
|
@ -48,18 +48,31 @@ function ConfirmingPage:init()
|
|||
end)
|
||||
end
|
||||
|
||||
-- Set all selections to a specific value
|
||||
self.setAllSelections = function(value)
|
||||
-- Set selection for a node and all its descendants (subtree)
|
||||
self.onSubtreeSelectionChange = function(nodeId, selection)
|
||||
if not self.props.patchTree then
|
||||
return
|
||||
end
|
||||
local newSelections = {}
|
||||
self.props.patchTree:forEach(function(node)
|
||||
|
||||
local node = self.props.patchTree:getNode(nodeId)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
|
||||
self:setState(function(state)
|
||||
local newSelections = table.clone(state.selections)
|
||||
-- Set this node if it has a patchType
|
||||
if node.patchType then
|
||||
newSelections[node.id] = value
|
||||
newSelections[nodeId] = selection
|
||||
end
|
||||
-- Set all descendants
|
||||
self.props.patchTree:forEach(function(childNode)
|
||||
if childNode.patchType then
|
||||
newSelections[childNode.id] = selection
|
||||
end
|
||||
end, node)
|
||||
return { selections = newSelections }
|
||||
end)
|
||||
self:setState({ selections = newSelections })
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -123,6 +136,7 @@ function ConfirmingPage:render()
|
|||
patchTree = self.props.patchTree,
|
||||
selections = self.state.selections,
|
||||
onSelectionChange = self.onSelectionChange,
|
||||
onSubtreeSelectionChange = self.onSubtreeSelectionChange,
|
||||
|
||||
showStringDiff = function(currentString: string, incomingString: string)
|
||||
self:setState({
|
||||
|
|
@ -153,41 +167,11 @@ function ConfirmingPage:render()
|
|||
onClick = self.props.onAbort,
|
||||
}),
|
||||
|
||||
PullAll = e(TextButton, {
|
||||
text = "Pull All",
|
||||
style = "Danger",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 2,
|
||||
onClick = function()
|
||||
self.setAllSelections("pull")
|
||||
end,
|
||||
}),
|
||||
|
||||
SkipAll = e(TextButton, {
|
||||
text = "Skip All",
|
||||
style = "Neutral",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 3,
|
||||
onClick = function()
|
||||
self.setAllSelections("ignore")
|
||||
end,
|
||||
}),
|
||||
|
||||
PushAll = e(TextButton, {
|
||||
text = "Push All",
|
||||
style = "Success",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 4,
|
||||
onClick = function()
|
||||
self.setAllSelections("push")
|
||||
end,
|
||||
}),
|
||||
|
||||
Accept = e(TextButton, {
|
||||
text = "Accept",
|
||||
style = "Primary",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 5,
|
||||
layoutOrder = 2,
|
||||
onClick = function()
|
||||
if not self.props.onConfirm then
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue