mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 14:18:04 +08:00
Make Data panel scalars selectable inline, denoise float display, and standardize breadcrumb string truncation (#4470)
* Make Data panel scalars selectable inline, denoise float display, and move breadcrumb truncation to Rust * Code review fixes * Remove denoising from f32
This commit is contained in:
@@ -12,31 +12,11 @@
|
||||
export let tooltipShortcut: ActionShortcut | undefined = undefined;
|
||||
// Callbacks
|
||||
export let action: (index: number) => void;
|
||||
|
||||
function truncate(label: string): string {
|
||||
let maxLength = 40;
|
||||
|
||||
if (label.length <= maxLength) return label;
|
||||
|
||||
let truncated = label;
|
||||
const hasQuotes = label.startsWith(`"`) && label.endsWith(`"`);
|
||||
|
||||
if (hasQuotes) {
|
||||
truncated = label.slice(1, -1);
|
||||
maxLength -= 2;
|
||||
}
|
||||
|
||||
truncated = truncated.slice(0, maxLength - 1) + "…";
|
||||
|
||||
if (hasQuotes) truncated = `"${truncated}"`;
|
||||
|
||||
return truncated;
|
||||
}
|
||||
</script>
|
||||
|
||||
<LayoutRow class="breadcrumb-trail-buttons" {tooltipLabel} {tooltipDescription} {tooltipShortcut}>
|
||||
{#each labels as label, index}
|
||||
<TextButton label={truncate(label)} emphasized={index === labels.length - 1} {disabled} action={() => !disabled && index !== labels.length - 1 && action(index)} />
|
||||
<TextButton {label} emphasized={index === labels.length - 1} {disabled} action={() => !disabled && index !== labels.length - 1 && action(index)} />
|
||||
{/each}
|
||||
</LayoutRow>
|
||||
|
||||
|
||||
@@ -205,6 +205,10 @@
|
||||
textarea {
|
||||
color: var(--color-8-uppergray);
|
||||
}
|
||||
|
||||
input {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
export let italic = false;
|
||||
export let monospace = false;
|
||||
export let multiline = false;
|
||||
export let enquote = false;
|
||||
export let selectable = false;
|
||||
export let centerAlign = false;
|
||||
export let tableAlign = false;
|
||||
// Sizing
|
||||
@@ -76,6 +78,8 @@
|
||||
class:italic
|
||||
class:monospace
|
||||
class:multiline
|
||||
class:enquote
|
||||
class:selectable
|
||||
class:center-align={centerAlign}
|
||||
class:table-align={tableAlign}
|
||||
style:min-width={minWidthCharacters ? `${minWidthCharacters}ch` : minWidth > 0 ? `${minWidth}px` : undefined}
|
||||
@@ -125,6 +129,17 @@
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
&.enquote::before,
|
||||
&.enquote::after {
|
||||
content: '"';
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&.selectable {
|
||||
user-select: text;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
&.center-align {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ export function onPointerMove(e: PointerEvent, editor: EditorWrapper, documentSt
|
||||
|
||||
export function onPointerDown(e: PointerEvent, editor: EditorWrapper, dialogStore: DialogStore) {
|
||||
potentiallyRestoreCanvasFocus(e);
|
||||
potentiallyClearTextSelection(e);
|
||||
|
||||
const inFloatingMenu = e.target instanceof Element && e.target.closest("[data-floating-menu-content]");
|
||||
const isTargetingCanvas = !inFloatingMenu && e.target instanceof Element && e.target.closest("[data-viewport], [data-viewport-container], [data-node-graph]");
|
||||
@@ -351,6 +352,20 @@ function targetIsTextField(target: EventTarget | HTMLElement | undefined): boole
|
||||
);
|
||||
}
|
||||
|
||||
function potentiallyClearTextSelection(e: PointerEvent) {
|
||||
const target = e.target instanceof Element ? e.target : undefined;
|
||||
if (target && (targetIsTextField(target) || window.getComputedStyle(target).userSelect !== "none")) return;
|
||||
|
||||
// A text control's selection lives in its shadow tree, which the document's `Selection` reports as collapsed and cannot clear, so each control holding one is collapsed through its own API
|
||||
const controls = window.document.querySelectorAll<HTMLInputElement | HTMLTextAreaElement>("textarea, input[type='text']");
|
||||
controls.forEach((control) => {
|
||||
const caret = control.selectionStart;
|
||||
if (typeof caret === "number" && caret !== control.selectionEnd) control.setSelectionRange(caret, caret);
|
||||
});
|
||||
|
||||
window.getSelection()?.removeAllRanges();
|
||||
}
|
||||
|
||||
function potentiallyRestoreCanvasFocus(e: Event) {
|
||||
const appElement = window.document.querySelector("[data-app-container]");
|
||||
const app = appElement instanceof HTMLElement ? appElement : undefined;
|
||||
|
||||
Reference in New Issue
Block a user