mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-20 11:28:30 +08:00
Add shifting of layers in stacks as blocks that collide and bump other layers/nodes (#1940)
* Shift nodes as blocks * Implement rubber banding * Improve upstream locking when shifting layers * WIP: Reworked shifting * WIP: Reworked node shifting * Finish shifting * Fix demo artwork * Code review * Right click to end shift * Improve rubber banding * Fix clippy issues * Skip collision for intersecting nodes * Rubber banding bug fix * Fix ctrl+delete node in chain * Grip drag * Fix layer width * Add icon to frontend for the solo drag grip * Reconnect during ctrl+delete * Code review --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -162,15 +162,40 @@
|
||||
transparent calc(6px * sqrt(2) / 2)
|
||||
);
|
||||
|
||||
// Arrow triangle (#eee fill)
|
||||
// Array of 2x3 dots (fill: --color-e-nearwhite)
|
||||
--icon-drag-grip: url('data:image/svg+xml;utf8,\
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 24" fill="%23eee">\
|
||||
<circle cx="0.5" cy="1.5" r="0.5" /><circle cx="3.5" cy="1.5" r="0.5" />\
|
||||
<circle cx="0.5" cy="4.5" r="0.5" /><circle cx="3.5" cy="4.5" r="0.5" />\
|
||||
<circle cx="0.5" cy="7.5" r="0.5" /><circle cx="3.5" cy="7.5" r="0.5" />\
|
||||
</svg>\
|
||||
');
|
||||
// Array of 2x3 dots (fill: --color-f-white)
|
||||
--icon-drag-grip-hover: url('data:image/svg+xml;utf8,\
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 24" fill="%23fff">\
|
||||
<circle cx="0.5" cy="1.5" r="0.5" /><circle cx="3.5" cy="1.5" r="0.5" />\
|
||||
<circle cx="0.5" cy="4.5" r="0.5" /><circle cx="3.5" cy="4.5" r="0.5" />\
|
||||
<circle cx="0.5" cy="7.5" r="0.5" /><circle cx="3.5" cy="7.5" r="0.5" />\
|
||||
</svg>\
|
||||
');
|
||||
// Array of 2x3 dots (fill: --color-8-uppergray)
|
||||
--icon-drag-grip-disabled: url('data:image/svg+xml;utf8,\
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 24" fill="%23888">\
|
||||
<circle cx="0.5" cy="1.5" r="0.5" /><circle cx="3.5" cy="1.5" r="0.5" />\
|
||||
<circle cx="0.5" cy="4.5" r="0.5" /><circle cx="3.5" cy="4.5" r="0.5" />\
|
||||
<circle cx="0.5" cy="7.5" r="0.5" /><circle cx="3.5" cy="7.5" r="0.5" />\
|
||||
</svg>\
|
||||
');
|
||||
|
||||
// Arrow triangle (fill: --color-e-nearwhite)
|
||||
--icon-expand-collapse-arrow: url('data:image/svg+xml;utf8,\
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><polygon fill="%23eee" points="3,0 1,0 5,4 1,8 3,8 7,4" /></svg>\
|
||||
');
|
||||
// Arrow triangle (#fff fill)
|
||||
// Arrow triangle (fill: --color-f-white)
|
||||
--icon-expand-collapse-arrow-hover: url('data:image/svg+xml;utf8,\
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><polygon fill="%23fff" points="3,0 1,0 5,4 1,8 3,8 7,4" /></svg>\
|
||||
');
|
||||
// Arrow triangle (#888 fill)
|
||||
// Arrow triangle (fill: --color-8-uppergray)
|
||||
--icon-expand-collapse-arrow-disabled: url('data:image/svg+xml;utf8,\
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><polygon fill="%23888" points="3,0 1,0 5,4 1,8 3,8 7,4" /></svg>\
|
||||
');
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
{#each $nodeGraph.clickTargets.portClickTargets as pathString}
|
||||
<path class="port" d={pathString} />
|
||||
{/each}
|
||||
{#each $nodeGraph.clickTargets.visibilityClickTargets as pathString}
|
||||
{#each $nodeGraph.clickTargets.iconClickTargets as pathString}
|
||||
<path class="visibility" d={pathString} />
|
||||
{/each}
|
||||
<path class="all-nodes-bounding-box" d={$nodeGraph.clickTargets.allNodesBoundingBox} />
|
||||
@@ -642,6 +642,7 @@
|
||||
{node.displayName}
|
||||
</span>
|
||||
</div>
|
||||
<div class="solo-drag-grip" title="Drag only this layer without pushing others outside the stack"></div>
|
||||
<IconButton
|
||||
class={"visibility"}
|
||||
data-visibility-button
|
||||
@@ -1238,6 +1239,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
.solo-drag-grip {
|
||||
width: 8px;
|
||||
height: 24px;
|
||||
background-position: 2px 8px;
|
||||
right: calc(-12px + 24px);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.solo-drag-grip:hover,
|
||||
&.selected .solo-drag-grip {
|
||||
background-image: var(--icon-drag-grip);
|
||||
|
||||
&:hover {
|
||||
background-image: var(--icon-drag-grip-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.visibility {
|
||||
position: absolute;
|
||||
right: -12px;
|
||||
@@ -1247,6 +1265,7 @@
|
||||
left: calc(-3px + var(--node-chain-area-left-extension) * 24px - 36px);
|
||||
}
|
||||
|
||||
.solo-drag-grip,
|
||||
.visibility,
|
||||
.input.ports,
|
||||
.input.ports .port {
|
||||
|
||||
@@ -173,7 +173,7 @@ export type FrontendClickTargets = {
|
||||
readonly nodeClickTargets: string[];
|
||||
readonly layerClickTargets: string[];
|
||||
readonly portClickTargets: string[];
|
||||
readonly visibilityClickTargets: string[];
|
||||
readonly iconClickTargets: string[];
|
||||
readonly allNodesBoundingBox: string;
|
||||
readonly importExportsBoundingBox: string;
|
||||
};
|
||||
|
||||
@@ -622,7 +622,10 @@ impl EditorHandle {
|
||||
self.dispatch(message);
|
||||
|
||||
let id = NodeId(id);
|
||||
let message = NodeGraphMessage::DeleteNodes { node_ids: vec![id], reconnect: true };
|
||||
let message = NodeGraphMessage::DeleteNodes {
|
||||
node_ids: vec![id],
|
||||
delete_children: true,
|
||||
};
|
||||
self.dispatch(message);
|
||||
}
|
||||
|
||||
@@ -779,7 +782,7 @@ impl EditorHandle {
|
||||
.map(|(id, _)| *id)
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
let layer = LayerNodeIdentifier::new(node, &document.network_interface);
|
||||
let layer = LayerNodeIdentifier::new(node, &document.network_interface, &[]);
|
||||
if layer.has_children(document.metadata()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user