diff --git a/CHANGELOG.md b/CHANGELOG.md index 3680a84a9..16c90c4bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Skip confirming patches that contain only a datamodel name change. ([#688]) * Added sync reminder notification. ([#689]) * Added protection against syncing a model to a place. ([#691]) +* Select Instances from diff tree view ([#709]) * Fix Rojo breaking when users undo/redo in Studio ([#708]) * Improved sync info text on Connected page. ([#692]) * Fix patch visualizer breaking when instances are removed during sync ([#713]) @@ -17,6 +18,7 @@ [#688]: https://github.com/rojo-rbx/rojo/pull/688 [#689]: https://github.com/rojo-rbx/rojo/pull/689 [#691]: https://github.com/rojo-rbx/rojo/pull/691 +[#709]: https://github.com/rojo-rbx/rojo/pull/709 [#708]: https://github.com/rojo-rbx/rojo/pull/708 [#692]: https://github.com/rojo-rbx/rojo/pull/692 [#713]: https://github.com/rojo-rbx/rojo/pull/713 diff --git a/plugin/src/App/Components/PatchVisualizer/DomLabel.lua b/plugin/src/App/Components/PatchVisualizer/DomLabel.lua index 9f967c32f..351f8c31a 100644 --- a/plugin/src/App/Components/PatchVisualizer/DomLabel.lua +++ b/plugin/src/App/Components/PatchVisualizer/DomLabel.lua @@ -1,3 +1,4 @@ +local SelectionService = game:GetService("Selection") local StudioService = game:GetService("StudioService") local Rojo = script:FindFirstAncestor("Rojo") @@ -14,6 +15,7 @@ local bindingUtil = require(Plugin.App.bindingUtil) local e = Roact.createElement local ChangeList = require(script.Parent.ChangeList) +local Tooltip = require(script.Parent.Parent.Tooltip) local Expansion = Roact.Component:extend("Expansion") @@ -106,21 +108,47 @@ function DomLabel:render() PaddingLeft = UDim.new(0, 10), PaddingRight = UDim.new(0, 10), }), - ExpandButton = if props.changeList - then e("TextButton", { - BackgroundTransparency = 1, - Text = "", - Size = UDim2.new(1, 0, 1, 0), - [Roact.Event.Activated] = function() - self.expanded = not self.expanded - local goalHeight = 30 + (if self.expanded then math.clamp(#self.props.changeList * 30, 30, 30 * 6) else 0) - self.motor:setGoal(Flipper.Spring.new(goalHeight, { - frequency = 5, - dampingRatio = 1, - })) - end, - }) - else nil, + Button = e("TextButton", { + BackgroundTransparency = 1, + Text = "", + Size = UDim2.new(1, 0, 1, 0), + [Roact.Event.Activated] = function(_rbx: Instance, _input: InputObject, clickCount: number) + if clickCount == 1 then + -- Double click opens the instance in explorer + self.lastDoubleClickTime = os.clock() + if props.instance then + SelectionService:Set({ props.instance }) + end + elseif clickCount == 0 then + -- Single click expands the changes + task.wait(0.25) + if os.clock() - (self.lastDoubleClickTime or 0) <= 0.25 then + -- This is a double click, so don't expand + return + end + + if props.changeList then + self.expanded = not self.expanded + local goalHeight = 30 + + (if self.expanded then math.clamp(#self.props.changeList * 30, 30, 30 * 6) else 0) + self.motor:setGoal(Flipper.Spring.new(goalHeight, { + frequency = 5, + dampingRatio = 1, + })) + end + end + end, + }, { + StateTip = if (props.instance or props.changeList) + then e(Tooltip.Trigger, { + text = (if props.changeList + then "Click to " .. (if self.expanded then "hide" else "view") .. " changes" + else "") .. (if props.instance + then (if props.changeList then " & d" else "D") .. "ouble click to open in Explorer" + else ""), + }) + else nil, + }), Expansion = if props.changeList then e(Expansion, { rendered = self.state.renderExpansion, diff --git a/plugin/src/App/Components/PatchVisualizer/init.lua b/plugin/src/App/Components/PatchVisualizer/init.lua index a751f2ffd..7a3293e62 100644 --- a/plugin/src/App/Components/PatchVisualizer/init.lua +++ b/plugin/src/App/Components/PatchVisualizer/init.lua @@ -131,6 +131,7 @@ local function Tree() id = ancestorId, className = value.ClassName, name = value.Name, + instance = if typeof(value) == "Instance" then value else nil, }) previousId = ancestorId end @@ -236,6 +237,7 @@ function PatchVisualizer:buildTree(patch, instanceMap) patchType = "Edit", className = instance.ClassName, name = instance.Name, + instance = instance, hint = hint, changeList = changeList, }) @@ -271,10 +273,11 @@ function PatchVisualizer:buildTree(patch, instanceMap) patchType = "Remove", className = instance.ClassName, name = instance.Name, + instance = instance, }) end - for _, change in patch.added do + for id, change in patch.added do -- Gather ancestors from existing DOM or future additions local ancestry = {} local parentId = change.Parent @@ -344,6 +347,7 @@ function PatchVisualizer:buildTree(patch, instanceMap) name = change.Name, hint = hint, changeList = changeList, + instance = instanceMap.fromIds[id], }) end @@ -370,6 +374,7 @@ function PatchVisualizer:render() setElementHeight = setElementHeight, patchType = node.patchType, className = node.className, + instance = node.instance, name = node.name, hint = node.hint, changeList = node.changeList,