mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-26 02:28:12 +08:00
Restyle and refactor shortcut labels to send hints bar and welcome screen layouts from Rust (#3447)
* Restyle UserInputLabel and refactor its usages to have all input its data sent from Rust * Replace the welcome screen quick buttons with ones sent by backend * Add the ShortcutLabel widget to the backend * Replace hints bar with a backend-controlled layout; show mouse icons in place of mouse labels
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onMount, onDestroy, tick } from "svelte";
|
||||
|
||||
import { shortcutAltClick } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import {
|
||||
defaultWidgetLayout,
|
||||
@@ -11,7 +12,7 @@
|
||||
UpdateLayersPanelControlBarRightLayout,
|
||||
UpdateLayersPanelBottomBarLayout,
|
||||
} from "@graphite/messages";
|
||||
import type { DataBuffer, LayerPanelEntry } from "@graphite/messages";
|
||||
import type { ActionShortcut, DataBuffer, LayerPanelEntry } from "@graphite/messages";
|
||||
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
|
||||
import { operatingSystem } from "@graphite/utility-functions/platform";
|
||||
import { extractPixelData } from "@graphite/utility-functions/rasterization";
|
||||
@@ -73,6 +74,8 @@
|
||||
let layersPanelControlBarRightLayout = defaultWidgetLayout();
|
||||
let layersPanelBottomBarLayout = defaultWidgetLayout();
|
||||
|
||||
const altClickKeys: ActionShortcut = shortcutAltClick();
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarLeftLayout, (updateLayersPanelControlBarLeftLayout) => {
|
||||
patchWidgetLayout(layersPanelControlBarLeftLayout, updateLayersPanelControlBarLeftLayout);
|
||||
@@ -622,7 +625,7 @@
|
||||
? "Hide the layers nested within. (To affect all open descendants, perform the shortcut shown.)"
|
||||
: "Show the layers nested within. (To affect all closed descendants, perform the shortcut shown.)") +
|
||||
(listing.entry.ancestorOfSelected && !listing.entry.expanded ? "\n\nNote: a selected layer is currently contained within.\n" : "")}
|
||||
data-tooltip-shortcut="Alt Click"
|
||||
data-tooltip-shortcut={altClickKeys?.shortcut ? JSON.stringify(altClickKeys.shortcut) : undefined}
|
||||
on:click={(e) => handleExpandArrowClickWithModifiers(e, listing.entry.id)}
|
||||
tabindex="0"
|
||||
></button>
|
||||
@@ -634,7 +637,7 @@
|
||||
icon="Clipped"
|
||||
class="clipped-arrow"
|
||||
tooltipDescription="Clipping mask is active. To release it, perform the shortcut on the layer border."
|
||||
tooltipShortcut="Alt Click"
|
||||
tooltipShortcut={altClickKeys}
|
||||
/>
|
||||
{/if}
|
||||
<div class="thumbnail">
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { defaultWidgetLayout, patchWidgetLayout, UpdateWelcomeScreenButtonsLayout } from "@graphite/messages";
|
||||
import { extractPixelData } from "@graphite/utility-functions/rasterization";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
|
||||
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
|
||||
let welcomePanelButtonsLayout = defaultWidgetLayout();
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateWelcomeScreenButtonsLayout, (updateWelcomeScreenButtonsLayout) => {
|
||||
patchWidgetLayout(welcomePanelButtonsLayout, updateWelcomeScreenButtonsLayout);
|
||||
welcomePanelButtonsLayout = welcomePanelButtonsLayout;
|
||||
});
|
||||
|
||||
editor.handle.requestWelcomeScreenButtonsLayout();
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateWelcomeScreenButtonsLayout);
|
||||
});
|
||||
|
||||
function dropFile(e: DragEvent) {
|
||||
if (!e.dataTransfer) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
Array.from(e.dataTransfer.items).forEach(async (item) => {
|
||||
const file = item.getAsFile();
|
||||
if (!file) return;
|
||||
|
||||
if (file.type.includes("svg")) {
|
||||
const svgData = await file.text();
|
||||
editor.handle.pasteSvg(file.name, svgData);
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.type.startsWith("image")) {
|
||||
const imageData = await extractPixelData(file);
|
||||
editor.handle.pasteImage(file.name, new Uint8Array(imageData.data), imageData.width, imageData.height);
|
||||
return;
|
||||
}
|
||||
|
||||
const graphiteFileSuffix = "." + editor.handle.fileExtension();
|
||||
if (file.name.endsWith(graphiteFileSuffix)) {
|
||||
const content = await file.text();
|
||||
const documentName = file.name.slice(0, -graphiteFileSuffix.length);
|
||||
editor.handle.openDocumentFile(documentName, content);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<LayoutCol class="welcome-panel" on:dragover={(e) => e.preventDefault()} on:drop={dropFile}>
|
||||
<LayoutCol class="top-spacer"></LayoutCol>
|
||||
<LayoutCol class="content-container">
|
||||
<LayoutCol class="content">
|
||||
<LayoutRow class="logotype">
|
||||
<IconLabel icon="GraphiteLogotypeSolid" />
|
||||
</LayoutRow>
|
||||
<LayoutRow class="actions">
|
||||
<WidgetLayout layout={welcomePanelButtonsLayout} />
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
</LayoutCol>
|
||||
<LayoutCol class="bottom-message">
|
||||
{#if new Date().getFullYear() === 2025}
|
||||
<TextLabel italic={true} disabled={true}>
|
||||
September 2025 release — <a href="https://youtube.com/watch?v=Vl5BA4g3QXM" target="_blank">What's new? (video)</a>
|
||||
— Note: some older documents may render differently and require manual fixes.
|
||||
<a href="https://ec6796b4.graphite-editor.pages.dev/" target="_blank">Need the old version?</a>
|
||||
</TextLabel>
|
||||
{/if}
|
||||
</LayoutCol>
|
||||
</LayoutCol>
|
||||
|
||||
<style lang="scss" global>
|
||||
.welcome-panel {
|
||||
background: var(--color-2-mildblack);
|
||||
margin: 4px;
|
||||
border-radius: 2px;
|
||||
justify-content: space-between;
|
||||
|
||||
.content-container {
|
||||
flex: 0 0 auto;
|
||||
justify-content: center;
|
||||
|
||||
.content {
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
|
||||
.logotype {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 40px;
|
||||
|
||||
svg {
|
||||
width: auto;
|
||||
height: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-bottom: 8px;
|
||||
|
||||
table {
|
||||
border-spacing: 8px;
|
||||
margin: -8px;
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top-spacer {
|
||||
flex: 0 1 48px;
|
||||
}
|
||||
|
||||
.bottom-message {
|
||||
flex: 0 0 48px;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
|
||||
.text-label {
|
||||
white-space: wrap;
|
||||
margin: 0 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user