Move gradient picking into the color picker (#1778)

* Gradient picker

* Fix up color picker layout CSS problems

* Begin hooking up SpectrumInput for gradient in the ColorPicker

* Working gradient picking on the frontend only

* Plumb FillColorChoice into the backend

* Hook everything else up, just with a weird bug remaining

* Fix some svelty reactivity issues

* Add and remove stops

* Cleanup

* Rename type

* Fill node document format upgrading

* Fix lint

* Polish the color picker UX and fix a bug

---------

Co-authored-by: 0hypercube <0hypercube@gmail.com>
This commit is contained in:
Keavon Chambers
2024-06-09 22:55:13 -07:00
committed by GitHub
co-authored by 0hypercube
parent 449729f1e1
commit a9a4b5cd19
48 changed files with 1380 additions and 664 deletions
@@ -1,33 +1,36 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import type { Color } from "@graphite/wasm-communication/messages";
import type { FillChoice } from "@graphite/wasm-communication/messages";
import { Color, Gradient } from "@graphite/wasm-communication/messages";
import ColorPicker from "@graphite/components/floating-menus/ColorPicker.svelte";
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
const dispatch = createEventDispatcher<{ value: Color; startHistoryTransaction: undefined }>();
const dispatch = createEventDispatcher<{ value: FillChoice; startHistoryTransaction: undefined }>();
let open = false;
export let value: Color;
export let value: FillChoice;
export let disabled = false;
export let allowNone = false;
// export let allowTransparency = false; // TODO: Implement
export let tooltip: string | undefined = undefined;
$: chosenGradient = value instanceof Gradient ? value.toLinearGradientCSS() : `linear-gradient(${value.toHexOptionalAlpha()}, ${value.toHexOptionalAlpha()})`;
</script>
<LayoutCol class="color-button" classes={{ disabled, none: value.none, open }} {tooltip}>
<button {disabled} style:--chosen-color={value.toHexOptionalAlpha()} on:click={() => (open = true)} tabindex="0" data-floating-menu-spawner></button>
{#if disabled && !value.none}
<LayoutCol class="color-button" classes={{ disabled, none: value instanceof Color ? value.none : false, open }} {tooltip}>
<button {disabled} style:--chosen-gradient={chosenGradient} on:click={() => (open = true)} tabindex="0" data-floating-menu-spawner></button>
{#if disabled && value instanceof Color && !value.none}
<TextLabel>sRGB</TextLabel>
{/if}
<ColorPicker
{open}
on:open={({ detail }) => (open = detail)}
color={value}
on:color={({ detail }) => {
colorOrGradient={value}
on:colorOrGradient={({ detail }) => {
value = detail;
dispatch("value", detail);
}}
@@ -71,9 +74,14 @@
margin-top: 2px;
width: calc(100% - 4px);
height: calc(100% - 4px);
background: linear-gradient(var(--chosen-color), var(--chosen-color)), var(--color-transparent-checkered-background);
background-size: var(--color-transparent-checkered-background-size);
background-position: var(--color-transparent-checkered-background-position);
background-image: var(--chosen-gradient), var(--color-transparent-checkered-background);
background-size:
100% 100%,
var(--color-transparent-checkered-background-size);
background-position:
0 0,
var(--color-transparent-checkered-background-position);
background-repeat: no-repeat, var(--color-transparent-checkered-background-repeat);
}
&.none {
@@ -5,7 +5,6 @@
import MenuList from "@graphite/components/floating-menus/MenuList.svelte";
import ConditionalWrapper from "@graphite/components/layout/ConditionalWrapper.svelte";
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
import Separator from "@graphite/components/widgets/labels/Separator.svelte";
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
let self: MenuList;
@@ -74,9 +73,6 @@
<IconLabel icon={hoverIcon} />
{/if}
{/if}
{#if icon && label}
<Separator type={flush ? "Unrelated" : "Related"} />
{/if}
{#if label}
<TextLabel>{label}</TextLabel>
{/if}
@@ -161,22 +157,26 @@
}
}
.widget-span.row > & + .text-button,
.layout-row > & + .text-button {
margin-left: 8px;
}
.widget-span.column > & + .text-button,
.layout-column > & + .text-button {
margin-top: 8px;
}
.icon-label {
fill: var(--button-text-color);
+ .text-label {
margin-left: 8px;
}
}
.text-label {
overflow: hidden;
}
// Custom styling for when multiple TextButton widgets are used next to one another in a row or column
.widget-span.row > & + .text-button,
.layout-row > & + .text-button {
margin-left: 8px;
}
.widget-span.column > & + .text-button,
.layout-column > & + .text-button {
margin-top: 8px;
}
}
</style>