mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 09:18:11 +08:00
Make Imaginate into a node (#878)
* Simplify document node input defenitions * Remove imaginate layer * Imaginate node properties * Fix serde feature gate * Add Proc Macro for Protonode implementation * Fix incorrect type * Add cargo.toml metadata * Send imaginate params to frontend * Fix image_creativity range * Finish imaginate implementation * Fix the imaginate draw tool * Remove node-graph/rpco-macro * Cargo fmt * Fix missing workspace member * Changes to the resolution * Add checkbox for Imaginate auto resolution; improve Properties panel layouts And fix bugs in panel resizing * Implement the Rescale button * Reorder imports * Update Rust deps Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Keavon Chambers
parent
2f2daa25e9
commit
2732492307
@@ -267,6 +267,7 @@ export default defineComponent({
|
||||
|
||||
if (!inParentFloatingMenu) {
|
||||
// Required to correctly position content when scrolled (it has a `position: fixed` to prevent clipping)
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
const tailOffset = this.type === "Popover" ? 10 : 0;
|
||||
if (this.direction === "Bottom") floatingMenuContent.style.top = `${tailOffset + this.floatingMenuBounds.top}px`;
|
||||
if (this.direction === "Top") floatingMenuContent.style.bottom = `${tailOffset + this.floatingMenuBounds.bottom}px`;
|
||||
@@ -274,7 +275,7 @@ export default defineComponent({
|
||||
if (this.direction === "Left") floatingMenuContent.style.right = `${tailOffset + this.floatingMenuBounds.right}px`;
|
||||
|
||||
// Required to correctly position tail when scrolled (it has a `position: fixed` to prevent clipping)
|
||||
// We use a ref here, instead of a `:style` binding, because that causes the `updated()` hook to call the function we're in recursively forever
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
const tail = this.$refs.tail as HTMLElement;
|
||||
if (tail && this.direction === "Bottom") tail.style.top = `${this.floatingMenuBounds.top}px`;
|
||||
if (tail && this.direction === "Top") tail.style.bottom = `${this.floatingMenuBounds.bottom}px`;
|
||||
@@ -289,6 +290,7 @@ export default defineComponent({
|
||||
if (this.direction === "Top" || this.direction === "Bottom") {
|
||||
zeroedBorderVertical = this.direction === "Top" ? "Bottom" : "Top";
|
||||
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
if (this.floatingMenuContentBounds.left - this.windowEdgeMargin <= this.workspaceBounds.left) {
|
||||
floatingMenuContent.style.left = `${this.windowEdgeMargin}px`;
|
||||
if (this.workspaceBounds.left + floatingMenuContainerBounds.left === 12) zeroedBorderHorizontal = "Left";
|
||||
@@ -301,6 +303,7 @@ export default defineComponent({
|
||||
if (this.direction === "Left" || this.direction === "Right") {
|
||||
zeroedBorderHorizontal = this.direction === "Left" ? "Right" : "Left";
|
||||
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
if (this.floatingMenuContentBounds.top - this.windowEdgeMargin <= this.workspaceBounds.top) {
|
||||
floatingMenuContent.style.top = `${this.windowEdgeMargin}px`;
|
||||
if (this.workspaceBounds.top + floatingMenuContainerBounds.top === 12) zeroedBorderVertical = "Top";
|
||||
@@ -313,6 +316,7 @@ export default defineComponent({
|
||||
|
||||
// Remove the rounded corner from the content where the tail perfectly meets the corner
|
||||
if (this.type === "Popover" && this.windowEdgeMargin === 6 && zeroedBorderVertical && zeroedBorderHorizontal) {
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
switch (`${zeroedBorderVertical}${zeroedBorderHorizontal}`) {
|
||||
case "TopLeft":
|
||||
floatingMenuContent.style.borderTopLeftRadius = "0";
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 100%;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 100%;
|
||||
|
||||
@@ -133,8 +133,6 @@
|
||||
flex: 0 0 auto;
|
||||
|
||||
.widget-row {
|
||||
min-height: 0;
|
||||
|
||||
.swatch-pair {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -77,8 +77,6 @@
|
||||
|
||||
<style lang="scss">
|
||||
.layer-tree {
|
||||
min-height: 0;
|
||||
|
||||
// Options bar
|
||||
.options-bar {
|
||||
height: 32px;
|
||||
|
||||
@@ -409,6 +409,7 @@ export default defineComponent({
|
||||
nodeIcon(nodeName: string): IconName {
|
||||
const iconMap: Record<string, IconName> = {
|
||||
Output: "NodeOutput",
|
||||
Imaginate: "NodeImaginate",
|
||||
"Hue Shift Image": "NodeColorCorrection",
|
||||
"Brighten Image": "NodeColorCorrection",
|
||||
"Grayscale Image": "NodeColorCorrection",
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
.widget-row {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
min-height: 32px;
|
||||
|
||||
> * {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 0 0 auto;
|
||||
max-height: 24px;
|
||||
|
||||
button {
|
||||
flex: 0 0 auto;
|
||||
|
||||
@@ -96,12 +96,12 @@
|
||||
}
|
||||
|
||||
> .text-label:first-of-type {
|
||||
flex: 0 0 30%;
|
||||
text-align: right;
|
||||
flex: 0 0 25%;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
> .parameter-expose-button ~ .text-label:first-of-type {
|
||||
text-align: left;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
> .text-button {
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: calc(18px * 4);
|
||||
min-height: calc(18px * 2);
|
||||
margin: 3px;
|
||||
padding: 0 5px;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -168,7 +168,6 @@
|
||||
background: var(--color-3-darkgray);
|
||||
flex: 1 1 100%;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
|
||||
.empty-panel {
|
||||
background: var(--color-2-mildblack);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<LayoutRow class="workspace" data-workspace>
|
||||
<LayoutRow class="workspace-grid-subdivision">
|
||||
<LayoutCol class="workspace-grid-subdivision">
|
||||
<LayoutRow class="workspace-grid-subdivision">
|
||||
<LayoutRow class="workspace-grid-subdivision" :style="{ 'flex-grow': panelSizes['root'] }" data-subdivision-name="root">
|
||||
<LayoutCol class="workspace-grid-subdivision" :style="{ 'flex-grow': panelSizes['content'] }" data-subdivision-name="content">
|
||||
<LayoutRow class="workspace-grid-subdivision" :style="{ 'flex-grow': panelSizes['document'] }" data-subdivision-name="document">
|
||||
<Panel
|
||||
:panelType="portfolio.state.documents.length > 0 ? 'Document' : undefined"
|
||||
:tabCloseButtons="true"
|
||||
@@ -15,17 +15,17 @@
|
||||
/>
|
||||
</LayoutRow>
|
||||
<LayoutRow class="workspace-grid-resize-gutter" data-gutter-vertical @pointerdown="(e: PointerEvent) => resizePanel(e)" v-if="nodeGraphVisible"></LayoutRow>
|
||||
<LayoutRow class="workspace-grid-subdivision" v-if="nodeGraphVisible">
|
||||
<LayoutRow class="workspace-grid-subdivision" v-if="nodeGraphVisible" :style="{ 'flex-grow': panelSizes['graph'] }" data-subdivision-name="graph">
|
||||
<Panel :panelType="'NodeGraph'" :tabLabels="[{ name: 'Node Graph' }]" :tabActiveIndex="0" />
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
<LayoutCol class="workspace-grid-resize-gutter" data-gutter-horizontal @pointerdown="(e: PointerEvent) => resizePanel(e)"></LayoutCol>
|
||||
<LayoutCol class="workspace-grid-subdivision" style="flex-grow: 0.2">
|
||||
<LayoutRow class="workspace-grid-subdivision" style="flex-grow: 402">
|
||||
<LayoutCol class="workspace-grid-subdivision" :style="{ 'flex-grow': panelSizes['details'] }" data-subdivision-name="details">
|
||||
<LayoutRow class="workspace-grid-subdivision" :style="{ 'flex-grow': panelSizes['properties'] }" data-subdivision-name="properties">
|
||||
<Panel :panelType="'Properties'" :tabLabels="[{ name: 'Properties' }]" :tabActiveIndex="0" />
|
||||
</LayoutRow>
|
||||
<LayoutRow class="workspace-grid-resize-gutter" data-gutter-vertical @pointerdown="(e: PointerEvent) => resizePanel(e)"></LayoutRow>
|
||||
<LayoutRow class="workspace-grid-subdivision" style="flex-grow: 590">
|
||||
<LayoutRow class="workspace-grid-subdivision" :style="{ 'flex-grow': panelSizes['layers'] }" data-subdivision-name="layers">
|
||||
<Panel :panelType="'LayerTree'" :tabLabels="[{ name: 'Layer Tree' }]" :tabActiveIndex="0" />
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
@@ -72,9 +72,23 @@ import LayoutRow from "@/components/layout/LayoutRow.vue";
|
||||
import Panel from "@/components/window/workspace/Panel.vue";
|
||||
|
||||
const MIN_PANEL_SIZE = 100;
|
||||
const PANEL_SIZES = {
|
||||
/**/ root: 100,
|
||||
/* ├── */ content: 80,
|
||||
/* │ ├── */ document: 60,
|
||||
/* │ └── */ graph: 40,
|
||||
/* └── */ details: 20,
|
||||
/* ├── */ properties: 45,
|
||||
/* └── */ layers: 55,
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
inject: ["workspace", "portfolio", "dialog", "editor"],
|
||||
data() {
|
||||
return {
|
||||
panelSizes: PANEL_SIZES,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
activeDocumentIndex() {
|
||||
return this.portfolio.state.activeDocumentIndex;
|
||||
@@ -97,16 +111,26 @@ export default defineComponent({
|
||||
resizePanel(event: PointerEvent) {
|
||||
const gutter = (event.target || undefined) as HTMLDivElement | undefined;
|
||||
const nextSibling = (gutter?.nextElementSibling || undefined) as HTMLDivElement | undefined;
|
||||
const previousSibling = (gutter?.previousElementSibling || undefined) as HTMLDivElement | undefined;
|
||||
const prevSibling = (gutter?.previousElementSibling || undefined) as HTMLDivElement | undefined;
|
||||
const parentElement = (gutter?.parentElement || undefined) as HTMLDivElement | undefined;
|
||||
|
||||
if (!gutter || !nextSibling || !previousSibling) return;
|
||||
const nextSiblingName = (nextSibling?.getAttribute("data-subdivision-name") || undefined) as keyof typeof PANEL_SIZES;
|
||||
const prevSiblingName = (prevSibling?.getAttribute("data-subdivision-name") || undefined) as keyof typeof PANEL_SIZES;
|
||||
|
||||
if (!gutter || !nextSibling || !prevSibling || !parentElement || !nextSiblingName || !prevSiblingName) return;
|
||||
|
||||
// Are we resizing horizontally?
|
||||
const isHorizontal = gutter.getAttribute("data-gutter-horizontal") !== null;
|
||||
|
||||
// Get the current size in px of the panels being resized
|
||||
// Get the current size in px of the panels being resized and the gutter
|
||||
const gutterSize = isHorizontal ? gutter.getBoundingClientRect().width : gutter.getBoundingClientRect().height;
|
||||
const nextSiblingSize = isHorizontal ? nextSibling.getBoundingClientRect().width : nextSibling.getBoundingClientRect().height;
|
||||
const previousSiblingSize = isHorizontal ? previousSibling.getBoundingClientRect().width : previousSibling.getBoundingClientRect().height;
|
||||
const prevSiblingSize = isHorizontal ? prevSibling.getBoundingClientRect().width : prevSibling.getBoundingClientRect().height;
|
||||
const parentElementSize = isHorizontal ? parentElement.getBoundingClientRect().width : parentElement.getBoundingClientRect().height;
|
||||
|
||||
// Measure the resizing panels as a percentage of all sibling panels
|
||||
const totalResizingSpaceOccupied = gutterSize + nextSiblingSize + prevSiblingSize;
|
||||
const proportionBeingResized = totalResizingSpaceOccupied / parentElementSize;
|
||||
|
||||
// Prevent cursor flicker as mouse temporarily leaves the gutter
|
||||
gutter.setPointerCapture(event.pointerId);
|
||||
@@ -118,10 +142,10 @@ export default defineComponent({
|
||||
let mouseDelta = mouseStart - mouseCurrent;
|
||||
|
||||
mouseDelta = Math.max(nextSiblingSize + mouseDelta, MIN_PANEL_SIZE) - nextSiblingSize;
|
||||
mouseDelta = previousSiblingSize - Math.max(previousSiblingSize - mouseDelta, MIN_PANEL_SIZE);
|
||||
mouseDelta = prevSiblingSize - Math.max(prevSiblingSize - mouseDelta, MIN_PANEL_SIZE);
|
||||
|
||||
nextSibling.style.flexGrow = (nextSiblingSize + mouseDelta).toString();
|
||||
previousSibling.style.flexGrow = (previousSiblingSize - mouseDelta).toString();
|
||||
this.panelSizes[nextSiblingName] = ((nextSiblingSize + mouseDelta) / totalResizingSpaceOccupied) * proportionBeingResized * 100;
|
||||
this.panelSizes[prevSiblingName] = ((prevSiblingSize - mouseDelta) / totalResizingSpaceOccupied) * proportionBeingResized * 100;
|
||||
|
||||
window.dispatchEvent(new CustomEvent("resize"));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user