Skip to content

Commit f1e8ebe

Browse files
authored
Improve tooltip docs with Markdown styling and refined math node explanations (#3488)
1 parent 2c21e1a commit f1e8ebe

File tree

19 files changed

+276
-185
lines changed

19 files changed

+276
-185
lines changed

editor/src/messages/frontend/frontend_message.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ pub enum FrontendMessage {
7070
SendShortcutAltClick {
7171
shortcut: Option<ActionShortcut>,
7272
},
73+
SendShortcutShiftClick {
74+
shortcut: Option<ActionShortcut>,
75+
},
7376

7477
// Trigger prefix: cause a frontend specific API to do something
7578
TriggerAboutGraphiteLocalizedCommitDate {

editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
274274
..Default::default()
275275
},
276276
},
277-
description: Cow::Borrowed("Merges new content as an entry into the graphic table that represents a layer compositing stack."),
277+
description: Cow::Borrowed("Merges the provided content as a new element in the graphic table that represents a layer compositing stack."),
278278
properties: None,
279279
},
280280
DocumentNodeDefinition {

editor/src/messages/portfolio/portfolio_message_handler.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
124124
responses.add(FrontendMessage::SendShortcutAltClick {
125125
shortcut: action_shortcut_manual!(Key::Alt, Key::MouseLeft),
126126
});
127+
responses.add(FrontendMessage::SendShortcutShiftClick {
128+
shortcut: action_shortcut_manual!(Key::Shift, Key::MouseLeft),
129+
});
127130

128131
// Before loading any documents, initially prepare the welcome screen buttons layout
129132
responses.add(PortfolioMessage::RequestWelcomeScreenButtonsLayout);

editor/src/messages/tool/common_functionality/pivot.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ pub struct PivotGizmoState {
169169

170170
impl PivotGizmoState {
171171
pub fn is_pivot_type(&self) -> bool {
172+
// A disabled pivot is considered a pivot-type gizmo that is always centered
172173
self.gizmo_type == PivotGizmoType::Pivot || self.disabled
173174
}
174175

frontend/src/components/Editor.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
// State provider systems
2828
let dialog = createDialogState(editor);
2929
setContext("dialog", dialog);
30-
let tooltip = createTooltipState();
30+
let tooltip = createTooltipState(editor);
3131
setContext("tooltip", tooltip);
3232
let document = createDocumentState(editor);
3333
setContext("document", document);

frontend/src/components/floating-menus/ColorPicker.svelte

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script lang="ts">
2-
import { onDestroy, createEventDispatcher } from "svelte";
2+
import { getContext, onDestroy, createEventDispatcher } from "svelte";
33
4-
import type { HSV, RGB, FillChoice } from "@graphite/messages";
5-
import type { MenuDirection } from "@graphite/messages";
4+
import type { HSV, RGB, FillChoice, MenuDirection } from "@graphite/messages";
65
import { Color, contrastingOutlineFactor, Gradient } from "@graphite/messages";
6+
import type { TooltipState } from "@graphite/state-providers/tooltip";
77
import { clamp } from "@graphite/utility-functions/math";
88
99
import FloatingMenu from "@graphite/components/layout/FloatingMenu.svelte";
@@ -40,6 +40,7 @@
4040
];
4141
4242
const dispatch = createEventDispatcher<{ colorOrGradient: FillChoice; startHistoryTransaction: undefined }>();
43+
const tooltip = getContext<TooltipState>("tooltip");
4344
4445
export let colorOrGradient: FillChoice;
4546
export let allowNone = false;
@@ -424,12 +425,16 @@
424425
"--opaque-color-contrasting": (newColor.opaque() || new Color(0, 0, 0, 1)).contrastingColor(),
425426
}}
426427
>
428+
{@const hueDescription = "The shade along the spectrum of the rainbow."}
429+
{@const saturationDescription = "The vividness from grayscale to full color."}
430+
{@const valueDescription = "The brightness from black to full color."}
427431
<LayoutCol class="pickers-and-gradient">
428432
<LayoutRow class="pickers">
429433
<LayoutCol
430434
class="saturation-value-picker"
431435
data-tooltip-label="Saturation and Value"
432-
data-tooltip-description={disabled ? "Disabled (read-only)." : ""}
436+
data-tooltip-description={`To move only along the saturation (X) or value (Y) axis, perform the shortcut shown.${disabled ? "\n\nDisabled (read-only)." : ""}`}
437+
data-tooltip-shortcut={$tooltip.shiftClickShortcut?.shortcut ? JSON.stringify($tooltip.shiftClickShortcut.shortcut) : undefined}
433438
on:pointerdown={onPointerDown}
434439
data-saturation-value-picker
435440
>
@@ -449,7 +454,7 @@
449454
<LayoutCol
450455
class="hue-picker"
451456
data-tooltip-label="Hue"
452-
data-tooltip-description={`The shade along the spectrum of the rainbow.${disabled ? "\n\nDisabled (read-only)." : ""}`}
457+
data-tooltip-description={`${hueDescription}${disabled ? "\n\nDisabled (read-only)." : ""}`}
453458
on:pointerdown={onPointerDown}
454459
data-hue-picker
455460
>
@@ -522,10 +527,8 @@
522527
</LayoutRow>
523528
<!-- <DropdownInput entries={[[{ label: "sRGB" }]]} selectedIndex={0} disabled={true} tooltipDescription="Color model, color space, and HDR (coming soon)." /> -->
524529
<LayoutRow>
525-
<TextLabel
526-
tooltipLabel="Hex Color Code"
527-
tooltipDescription="Color code in hexadecimal format. 6 digits if opaque, 8 with alpha.\nAccepts input of CSS color values including named colors.">Hex</TextLabel
528-
>
530+
{@const hexDescription = "Color code in hexadecimal format. 6 digits if opaque, 8 with alpha. Accepts input of CSS color values including named colors."}
531+
<TextLabel tooltipLabel="Hex Color Code" tooltipDescription={hexDescription}>Hex</TextLabel>
529532
<Separator type="Related" />
530533
<LayoutRow>
531534
<TextInput
@@ -537,7 +540,7 @@
537540
}}
538541
centered={true}
539542
tooltipLabel="Hex Color Code"
540-
tooltipDescription="Color code in hexadecimal format. 6 digits if opaque, 8 with alpha.\nAccepts input of CSS color values including named colors."
543+
tooltipDescription={hexDescription}
541544
bind:this={hexCodeInputWidget}
542545
/>
543546
</LayoutRow>
@@ -601,16 +604,17 @@
601604
v: "Value Component",
602605
}[channel]}
603606
tooltipDescription={{
604-
h: "The shade along the spectrum of the rainbow.",
605-
s: "The vividness from grayscale to full color.",
606-
v: "The brightness from black to full color.",
607+
h: hueDescription,
608+
s: saturationDescription,
609+
v: valueDescription,
607610
}[channel]}
608611
/>
609612
{/each}
610613
</LayoutRow>
611614
</LayoutRow>
612615
<LayoutRow>
613-
<TextLabel tooltipLabel="Alpha" tooltipDescription="The level of translucency, from transparent (0%) to opaque (100%).">Alpha</TextLabel>
616+
{@const alphaDescription = "The level of translucency, from transparent (0%) to opaque (100%)."}
617+
<TextLabel tooltipLabel="Alpha" tooltipDescription={alphaDescription}>Alpha</TextLabel>
614618
<Separator type="Related" />
615619
<NumberInput
616620
value={!isNone ? alpha * 100 : undefined}
@@ -630,7 +634,7 @@
630634
mode="Range"
631635
displayDecimalPlaces={1}
632636
tooltipLabel="Alpha"
633-
tooltipDescription="The level of translucency, from transparent (0%) to opaque (100%)."
637+
tooltipDescription={alphaDescription}
634638
/>
635639
</LayoutRow>
636640
<LayoutRow class="leftover-space" />
@@ -670,7 +674,7 @@
670674
data-pure-tile={name.toLowerCase()}
671675
style:--pure-color={color}
672676
style:--pure-color-gray={gray}
673-
data-tooltip-label="Set to Red"
677+
data-tooltip-label={`Set to ${name}`}
674678
data-tooltip-description={disabled ? "Disabled (read-only)." : ""}
675679
/>
676680
{/each}

frontend/src/components/floating-menus/Tooltip.svelte

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
1616
let self: FloatingMenu | undefined;
1717
18-
$: label = filterTodo($tooltip.element?.getAttribute("data-tooltip-label")?.trim());
19-
$: description = filterTodo($tooltip.element?.getAttribute("data-tooltip-description")?.trim());
18+
$: label = parseMarkdown(filterTodo($tooltip.element?.getAttribute("data-tooltip-label")?.trim()));
19+
$: description = parseMarkdown(filterTodo($tooltip.element?.getAttribute("data-tooltip-description")?.trim()));
2020
$: shortcutJSON = $tooltip.element?.getAttribute("data-tooltip-shortcut")?.trim();
2121
$: shortcut = ((shortcutJSON) => {
2222
if (!shortcutJSON) return undefined;
@@ -32,6 +32,26 @@
3232
if (text?.trim().toUpperCase() === "TODO" && !editor.handle.inDevelopmentMode()) return "";
3333
return text;
3434
}
35+
36+
function parseMarkdown(markdown: string | undefined): string | undefined {
37+
if (!markdown) return undefined;
38+
39+
return (
40+
markdown
41+
// .split("\n")
42+
// .map((line) => line.trim())
43+
// .join("\n")
44+
// .split("\n\n")
45+
// .map((paragraph) => paragraph.replaceAll("\n", " "))
46+
// .join("\n\n")
47+
// Bold
48+
.replace(/\*\*((?:(?!\*\*).)+)\*\*/g, "<strong>$1</strong>")
49+
// Italic
50+
.replace(/\*([^*]+)\*/g, "<em>$1</em>")
51+
// Backticks
52+
.replace(/`([^`]+)`/g, "<code>$1</code>")
53+
);
54+
}
3555
</script>
3656

3757
{#if label || description}
@@ -40,15 +60,15 @@
4060
{#if label || shortcut}
4161
<LayoutRow class="tooltip-header">
4262
{#if label}
43-
<TextLabel class="tooltip-label">{label}</TextLabel>
63+
<TextLabel class="tooltip-label">{@html label}</TextLabel>
4464
{/if}
4565
{#if shortcut}
4666
<ShortcutLabel shortcut={{ shortcut }} />
4767
{/if}
4868
</LayoutRow>
4969
{/if}
5070
{#if description}
51-
<TextLabel class="tooltip-description">{description}</TextLabel>
71+
<TextLabel class="tooltip-description">{@html description}</TextLabel>
5272
{/if}
5373
</FloatingMenu>
5474
</div>

frontend/src/components/panels/Layers.svelte

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
UpdateLayersPanelControlBarLeftLayout,
1010
UpdateLayersPanelControlBarRightLayout,
1111
UpdateLayersPanelBottomBarLayout,
12-
SendShortcutAltClick,
1312
} from "@graphite/messages";
14-
import type { ActionShortcut, DataBuffer, LayerPanelEntry, Layout } from "@graphite/messages";
13+
import type { DataBuffer, LayerPanelEntry, Layout } from "@graphite/messages";
1514
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
15+
import type { TooltipState } from "@graphite/state-providers/tooltip";
1616
import { operatingSystem } from "@graphite/utility-functions/platform";
1717
import { extractPixelData } from "@graphite/utility-functions/rasterization";
1818
@@ -49,6 +49,7 @@
4949
5050
const editor = getContext<Editor>("editor");
5151
const nodeGraph = getContext<NodeGraphState>("nodeGraph");
52+
const tooltip = getContext<TooltipState>("tooltip");
5253
5354
let list: LayoutCol | undefined;
5455
@@ -73,13 +74,7 @@
7374
let layersPanelControlBarRightLayout: Layout = [];
7475
let layersPanelBottomBarLayout: Layout = [];
7576
76-
let altClickShortcut: ActionShortcut | undefined;
77-
7877
onMount(() => {
79-
editor.subscriptions.subscribeJsMessage(SendShortcutAltClick, async (data) => {
80-
altClickShortcut = data.shortcut;
81-
});
82-
8378
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarLeftLayout, (updateLayersPanelControlBarLeftLayout) => {
8479
patchLayout(layersPanelControlBarLeftLayout, updateLayersPanelControlBarLeftLayout);
8580
layersPanelControlBarLeftLayout = layersPanelControlBarLeftLayout;
@@ -628,7 +623,7 @@
628623
? "Hide the layers nested within. (To affect all open descendants, perform the shortcut shown.)"
629624
: "Show the layers nested within. (To affect all closed descendants, perform the shortcut shown.)") +
630625
(listing.entry.ancestorOfSelected && !listing.entry.expanded ? "\n\nA selected layer is currently contained within.\n" : "")}
631-
data-tooltip-shortcut={altClickShortcut?.shortcut ? JSON.stringify(altClickShortcut.shortcut) : undefined}
626+
data-tooltip-shortcut={$tooltip.altClickShortcut?.shortcut ? JSON.stringify($tooltip.altClickShortcut.shortcut) : undefined}
632627
on:click={(e) => handleExpandArrowClickWithModifiers(e, listing.entry.id)}
633628
tabindex="0"
634629
></button>
@@ -639,8 +634,9 @@
639634
<IconLabel
640635
icon="Clipped"
641636
class="clipped-arrow"
642-
tooltipDescription="Clipping mask is active. To release it, perform the shortcut on the layer border."
643-
tooltipShortcut={altClickShortcut}
637+
tooltipLabel="Layer Clipped"
638+
tooltipDescription="Clipping mask is active. To release it, target the bottom border of the layer and perform the shortcut shown."
639+
tooltipShortcut={$tooltip.altClickShortcut}
644640
/>
645641
{/if}
646642
<div class="thumbnail">

frontend/src/components/views/Graph.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@
501501
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
502502
style:--layer-area-width={layerAreaWidth}
503503
style:--node-chain-area-left-extension={layerChainWidth !== 0 ? layerChainWidth + 0.5 : 0}
504-
data-tooltip-label={node.displayName === node.reference ? node.displayName : `${node.displayName} (${node.reference})`}
504+
data-tooltip-label={node.displayName === node.reference || !node.reference ? node.displayName : `${node.displayName} (${node.reference})`}
505505
data-tooltip-description={`
506506
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position.x}, ${node.position.y}).` : ""}
507507
`.trim()}
@@ -651,7 +651,7 @@
651651
style:--clip-path-id={`url(#${clipPathId})`}
652652
style:--data-color={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()})`}
653653
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
654-
data-tooltip-label={node.displayName === node.reference ? node.displayName : `${node.displayName} (${node.reference})`}
654+
data-tooltip-label={node.displayName === node.reference || !node.reference ? node.displayName : `${node.displayName} (${node.reference})`}
655655
data-tooltip-description={`
656656
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position.x}, ${node.position.y}).` : ""}
657657
`.trim()}

frontend/src/components/widgets/labels/TextLabel.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@
7272
font-style: italic;
7373
}
7474
75-
&.monospace {
75+
&.monospace,
76+
code {
7677
font-family: "Source Code Pro", monospace;
7778
font-size: 12px;
7879
}
@@ -94,5 +95,10 @@
9495
a {
9596
color: inherit;
9697
}
98+
99+
code {
100+
background: var(--color-3-darkgray);
101+
padding: 0 2px;
102+
}
97103
}
98104
</style>

0 commit comments

Comments
 (0)