mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 05:18:19 +00:00
DropdownInput preview support and ColorButton history improvements (#1598)
* DropdownInput support preview * fix typo and rm logs * Add previewable flag * fix cr typos * Improve color button history * rename * update dropdown preview behaviour * Color picker preset color * Another way to handle blend mode preview * Apply suggestions from code review * Use on_commit instead of on_update for some dropdowns * Debugging progress * add debug * active not equal to highlight in some cases * rm logs --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
282969df3d
commit
e769f50877
11 changed files with 97 additions and 51 deletions
|
@ -31,7 +31,7 @@
|
|||
|
||||
const editor = getContext<Editor>("editor");
|
||||
|
||||
const dispatch = createEventDispatcher<{ color: Color; start: undefined }>();
|
||||
const dispatch = createEventDispatcher<{ color: Color; startHistoryTransaction: undefined }>();
|
||||
|
||||
export let color: Color;
|
||||
export let allowNone = false;
|
||||
|
@ -150,7 +150,7 @@
|
|||
document.addEventListener("pointermove", onPointerMove);
|
||||
document.addEventListener("pointerup", onPointerUp);
|
||||
|
||||
dispatch("start");
|
||||
dispatch("startHistoryTransaction");
|
||||
}
|
||||
|
||||
function removeEvents() {
|
||||
|
@ -219,6 +219,7 @@
|
|||
}
|
||||
|
||||
function setColorPreset(preset: PresetColors) {
|
||||
dispatch("startHistoryTransaction");
|
||||
if (preset === "none") {
|
||||
setNewHSVA(0, 0, 0, 1, true);
|
||||
setColor(new Color("none"));
|
||||
|
@ -259,6 +260,7 @@
|
|||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const result = await new (window as any).EyeDropper().open();
|
||||
dispatch("startHistoryTransaction");
|
||||
setColorCode(result.sRGBHex);
|
||||
} catch {
|
||||
// Do nothing
|
||||
|
@ -314,7 +316,10 @@
|
|||
<LayoutRow>
|
||||
<TextInput
|
||||
value={newColor.toHexOptionalAlpha() || "-"}
|
||||
on:commitText={({ detail }) => setColorCode(detail)}
|
||||
on:commitText={({ detail }) => {
|
||||
dispatch("startHistoryTransaction");
|
||||
setColorCode(detail);
|
||||
}}
|
||||
centered={true}
|
||||
tooltip={"Color code in hexadecimal format. 6 digits if opaque, 8 with alpha.\nAccepts input of CSS color values including named colors."}
|
||||
bind:this={hexCodeInputWidget}
|
||||
|
@ -335,6 +340,9 @@
|
|||
strength = detail;
|
||||
setColorRGB(channel, detail);
|
||||
}}
|
||||
on:startHistoryTransaction={() => {
|
||||
dispatch("startHistoryTransaction");
|
||||
}}
|
||||
min={0}
|
||||
max={255}
|
||||
minWidth={56}
|
||||
|
@ -359,6 +367,9 @@
|
|||
strength = detail;
|
||||
setColorHSV(channel, detail);
|
||||
}}
|
||||
on:startHistoryTransaction={() => {
|
||||
dispatch("startHistoryTransaction");
|
||||
}}
|
||||
min={0}
|
||||
max={channel === "h" ? 360 : 100}
|
||||
unit={channel === "h" ? "°" : "%"}
|
||||
|
@ -379,6 +390,9 @@
|
|||
if (detail !== undefined) alpha = detail / 100;
|
||||
setColorAlphaPercent(detail);
|
||||
}}
|
||||
on:startHistoryTransaction={() => {
|
||||
dispatch("startHistoryTransaction");
|
||||
}}
|
||||
min={0}
|
||||
max={100}
|
||||
rangeMin={0}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
let scroller: LayoutCol | undefined;
|
||||
let searchTextInput: TextInput | undefined;
|
||||
|
||||
const dispatch = createEventDispatcher<{ open: boolean; activeEntry: MenuListEntry; naturalWidth: number }>();
|
||||
const dispatch = createEventDispatcher<{ open: boolean; activeEntry: MenuListEntry; hoverInEntry: MenuListEntry; hoverOutEntry: undefined; naturalWidth: number }>();
|
||||
|
||||
export let entries: MenuListEntry[][];
|
||||
export let activeEntry: MenuListEntry | undefined = undefined;
|
||||
|
@ -164,7 +164,10 @@
|
|||
}
|
||||
|
||||
function onEntryPointerEnter(menuListEntry: MenuListEntry) {
|
||||
if (!menuListEntry.children?.length) return;
|
||||
if (!menuListEntry.children?.length) {
|
||||
dispatch("hoverInEntry", menuListEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
let childReference = getChildReference(menuListEntry);
|
||||
if (childReference) {
|
||||
|
@ -174,7 +177,10 @@
|
|||
}
|
||||
|
||||
function onEntryPointerLeave(menuListEntry: MenuListEntry) {
|
||||
if (!menuListEntry.children?.length) return;
|
||||
if (!menuListEntry.children?.length) {
|
||||
dispatch("hoverOutEntry");
|
||||
return;
|
||||
}
|
||||
|
||||
let childReference = getChildReference(menuListEntry);
|
||||
if (childReference) {
|
||||
|
@ -346,9 +352,9 @@
|
|||
highlighted = newHighlight;
|
||||
|
||||
// Interactive menus should keep the active entry the same as the highlighted one
|
||||
if (interactive && newHighlight?.value !== activeEntry?.value && newHighlight) {
|
||||
dispatch("activeEntry", newHighlight);
|
||||
}
|
||||
// if (interactive && newHighlight?.value !== activeEntry?.value && newHighlight) {
|
||||
// dispatch("activeEntry", newHighlight);
|
||||
// }
|
||||
|
||||
// Scroll into view
|
||||
let container = scroller?.div?.();
|
||||
|
|
|
@ -96,7 +96,16 @@
|
|||
{/if}
|
||||
{@const dropdownInput = narrowWidgetProps(component.props, "DropdownInput")}
|
||||
{#if dropdownInput}
|
||||
<DropdownInput {...exclude(dropdownInput)} on:selectedIndex={({ detail }) => widgetValueCommitAndUpdate(index, detail)} />
|
||||
<DropdownInput
|
||||
{...exclude(dropdownInput)}
|
||||
on:hoverInEntry={({ detail }) => {
|
||||
return widgetValueUpdate(index, detail);
|
||||
}}
|
||||
on:hoverOutEntry={({ detail }) => {
|
||||
return widgetValueUpdate(index, detail);
|
||||
}}
|
||||
on:selectedIndex={({ detail }) => widgetValueCommitAndUpdate(index, detail)}
|
||||
/>
|
||||
{/if}
|
||||
{@const fontInput = narrowWidgetProps(component.props, "FontInput")}
|
||||
{#if fontInput}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
const DASH_ENTRY = { value: "", label: "-" };
|
||||
|
||||
const dispatch = createEventDispatcher<{ selectedIndex: number }>();
|
||||
const dispatch = createEventDispatcher<{ selectedIndex: number; hoverInEntry: number; hoverOutEntry: number }>();
|
||||
|
||||
let menuList: MenuList | undefined;
|
||||
let self: LayoutRow | undefined;
|
||||
|
@ -24,11 +24,17 @@
|
|||
|
||||
let activeEntry = makeActiveEntry();
|
||||
let activeEntrySkipWatcher = false;
|
||||
let initialSelectedIndex: number | undefined = undefined;
|
||||
let open = false;
|
||||
let minWidth = 0;
|
||||
|
||||
$: watchSelectedIndex(selectedIndex);
|
||||
$: watchActiveEntry(activeEntry);
|
||||
$: watchOpen(open);
|
||||
|
||||
function watchOpen(open: boolean) {
|
||||
initialSelectedIndex = open ? selectedIndex : undefined;
|
||||
}
|
||||
|
||||
// Called only when `selectedIndex` is changed from outside this component
|
||||
function watchSelectedIndex(_?: number) {
|
||||
|
@ -41,10 +47,20 @@
|
|||
if (activeEntrySkipWatcher) {
|
||||
activeEntrySkipWatcher = false;
|
||||
} else if (activeEntry !== DASH_ENTRY) {
|
||||
// We need to set to the initial value first to track a right history step, as if we hover in initial selection.
|
||||
dispatch("hoverInEntry", initialSelectedIndex);
|
||||
dispatch("selectedIndex", entries.flat().indexOf(activeEntry));
|
||||
}
|
||||
}
|
||||
|
||||
function dispatchHoverInEntry(hoveredEntry: MenuListEntry) {
|
||||
dispatch("hoverInEntry", entries.flat().indexOf(hoveredEntry));
|
||||
}
|
||||
|
||||
function dispatchHoverOutEntry() {
|
||||
dispatch("hoverOutEntry", initialSelectedIndex);
|
||||
}
|
||||
|
||||
function makeActiveEntry(): MenuListEntry {
|
||||
const allEntries = entries.flat();
|
||||
|
||||
|
@ -81,6 +97,8 @@
|
|||
on:naturalWidth={({ detail }) => (minWidth = detail)}
|
||||
{activeEntry}
|
||||
on:activeEntry={({ detail }) => (activeEntry = detail)}
|
||||
on:hoverInEntry={({ detail }) => dispatchHoverInEntry(detail)}
|
||||
on:hoverOutEntry={() => dispatchHoverOutEntry()}
|
||||
{open}
|
||||
on:open={({ detail }) => (open = detail)}
|
||||
{entries}
|
||||
|
|
|
@ -200,6 +200,11 @@
|
|||
|
||||
let newValue = evaluateMathExpression(textWithLeadingZeroes);
|
||||
if (newValue !== undefined && isNaN(newValue)) newValue = undefined; // Rejects `sqrt(-1)`
|
||||
|
||||
if (newValue !== undefined) {
|
||||
const oldValue = value !== undefined && isInteger ? Math.round(value) : value;
|
||||
if (newValue !== oldValue) dispatch("startHistoryTransaction");
|
||||
}
|
||||
updateValue(newValue);
|
||||
|
||||
editing = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue