Remake node type icons (closes #483); color picker cleanup

This commit is contained in:
Keavon Chambers
2022-03-04 22:48:22 -08:00
parent 8a05712dac
commit 788f8db127
12 changed files with 101 additions and 63 deletions
+6
View File
@@ -53,6 +53,7 @@
--color-e-nearwhite-rgb: 238, 238, 238;
--color-f-white: #fff;
--color-f-white-rgb: 255, 255, 255;
--color-accent: #3194d6;
--color-accent-rgb: 49, 148, 214;
--color-accent-hover: #49a5e2;
@@ -62,6 +63,11 @@
--color-data-raster: #e4bb72;
--color-data-raster-rgb: 228, 187, 114;
--color-node-background: #f1decd;
--color-node-background-rgb: 241, 222, 205;
--color-node-icon: #473a3a;
--color-node-icon-rgb: 71, 58, 58;
}
html,
+13 -6
View File
@@ -32,7 +32,7 @@
<LayoutRow></LayoutRow>
<LayoutRow>
<!-- TODO: Remember to make these tooltip input hints customized to macOS also -->
<IconButton :action="createEmptyFolder" :icon="'NewLayer'" title="New Folder (Ctrl+Shift+N)" :size="16" />
<IconButton :action="createEmptyFolder" :icon="'NodeFolder'" title="New Folder (Ctrl+Shift+N)" :size="16" />
<IconButton :action="deleteSelectedLayers" :icon="'Trash'" title="Delete Selected (Del)" :size="16" />
</LayoutRow>
</LayoutRow>
@@ -74,8 +74,9 @@
:title="`${listing.entry.name}\n${devMode ? 'Layer Path: ' + listing.entry.path.join(' / ') : ''}`"
>
<LayoutRow class="layer-type-icon">
<IconLabel v-if="listing.entry.layer_type === 'Folder'" :icon="'NodeTypeFolder'" title="Folder" />
<IconLabel v-else :icon="'NodeTypePath'" title="Path" />
<IconLabel v-if="listing.entry.layer_type === 'Folder'" :icon="'NodeFolder'" title="Folder" />
<IconLabel v-else-if="listing.entry.layer_type === 'Shape'" :icon="'NodePath'" title="Path" />
<IconLabel v-else-if="listing.entry.layer_type === 'Text'" :icon="'NodeText'" title="Path" />
</LayoutRow>
<LayoutRow class="layer-name" @dblclick="() => onEditLayerName(listing)">
<input
@@ -142,7 +143,7 @@
flex: 0 0 auto;
align-items: center;
position: relative;
height: 36px;
height: 32px;
margin: 0 4px;
border-bottom: 1px solid var(--color-4-dimgray);
@@ -217,6 +218,12 @@
.layer-type-icon {
flex: 0 0 auto;
margin: 0 4px;
.icon-label {
border-radius: 2px;
background: var(--color-node-background);
fill: var(--color-node-icon);
}
}
.layer-name {
@@ -260,10 +267,10 @@
}
.thumbnail {
height: calc(100% - 4px);
width: 36px;
height: 24px;
margin: 2px 0;
margin-left: 4px;
width: 64px;
background: white;
border-radius: 2px;
flex: 0 0 auto;
@@ -21,10 +21,20 @@
.options-bar {
height: 32px;
flex: 0 0 auto;
.widget-row > .icon-label:first-of-type {
border-radius: 2px;
background: var(--color-node-background);
fill: var(--color-node-icon);
}
}
.sections {
flex: 1 1 100%;
.widget-section + .widget-section {
margin-top: 1px;
}
}
}
</style>
@@ -1,9 +1,9 @@
<template>
<LayoutRow class="color-input">
<TextInput :value="value" :label="label" :disabled="disabled" @commitText="(value: string) => textInputUpdated(value)" :center="true" />
<TextInput :value="displayValue" :label="label" :disabled="disabled" @commitText="(value: string) => textInputUpdated(value)" :center="true" />
<Separator :type="'Related'" />
<LayoutRow class="swatch">
<button class="swatch-button" @click="() => menuOpen()" :style="{ background: `#${value}` }"></button>
<button class="swatch-button" @click="() => menuOpen()" :style="`--swatch-color: #${value}`"></button>
<FloatingMenu :type="'Popover'" :direction="'Bottom'" horizontal ref="colorFloatingMenu">
<ColorPicker @update:color="(color) => colorPickerUpdated(color)" :color="color" />
</FloatingMenu>
@@ -22,6 +22,7 @@
position: relative;
.swatch-button {
--swatch-color: #ffffff;
height: 24px;
width: 24px;
bottom: 0;
@@ -30,6 +31,19 @@
outline: none;
border: none;
border-radius: 2px;
background: linear-gradient(45deg, #cccccc 25%, transparent 25%, transparent 75%, #cccccc 75%), linear-gradient(45deg, #cccccc 25%, transparent 25%, transparent 75%, #cccccc 75%),
linear-gradient(#ffffff, #ffffff);
background-size: 16px 16px;
background-position: 0 0, 8px 8px;
overflow: hidden;
&::before {
content: "";
display: block;
width: 100%;
height: 100%;
background: var(--swatch-color);
}
}
.floating-menu {
@@ -67,6 +81,11 @@ export default defineComponent({
const a = parseInt(this.value.slice(6, 8), 16);
return { r, g, b, a: a / 255 };
},
displayValue() {
const value = this.value.toLowerCase();
const shortenedIfOpaque = value.slice(-2) === "ff" ? value.slice(0, 6) : value;
return `#${shortenedIfOpaque}`;
},
},
methods: {
colorPickerUpdated(color: RGBA) {
@@ -76,9 +95,22 @@ export default defineComponent({
this.$emit("update:value", newValue);
},
textInputUpdated(newValue: string) {
if ((newValue.length !== 6 && newValue.length !== 8) || !newValue.match(/[A-F,a-f,0-9]*/)) return;
const sanitizedMatch = newValue.match(/^\s*#?([0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3})\s*$/);
if (!sanitizedMatch) return;
this.$emit("update:value", newValue);
let sanitized;
const match = sanitizedMatch[1];
if (match.length === 3) {
sanitized = match
.split("")
.map((byte) => `${byte}${byte}`)
.concat("ff")
.join("");
} else if (match.length === 6) sanitized = `${match}ff`;
else if (match.length === 8) sanitized = match;
else return;
this.$emit("update:value", sanitized);
},
menuOpen() {
(this.$refs.colorFloatingMenu as typeof FloatingMenu).setOpen();
+1 -1
View File
@@ -369,7 +369,7 @@ export class LayerMetadata {
selected!: boolean;
}
export type LayerType = "Folder" | "Shape" | "Circle" | "Rect" | "Line" | "PolyLine" | "Ellipse";
export type LayerType = "Folder" | "Shape" | "Text";
export class IndexedDbDocumentDetails extends DocumentDetails {
@Transform(({ value }: { value: BigInt }) => value.toString())
+11 -8
View File
@@ -1,3 +1,4 @@
// 12px Solid
import Checkmark from "@/../assets/12px-solid/checkmark.svg";
import CloseX from "@/../assets/12px-solid/close-x.svg";
import DropdownArrow from "@/../assets/12px-solid/dropdown-arrow.svg";
@@ -28,6 +29,7 @@ import WindowButtonWinMaximize from "@/../assets/12px-solid/window-button-win-ma
import WindowButtonWinMinimize from "@/../assets/12px-solid/window-button-win-minimize.svg";
import WindowButtonWinRestoreDown from "@/../assets/12px-solid/window-button-win-restore-down.svg";
// 16px Solid
import AlignBottom from "@/../assets/16px-solid/align-bottom.svg";
import AlignHorizontalCenter from "@/../assets/16px-solid/align-horizontal-center.svg";
import AlignLeft from "@/../assets/16px-solid/align-left.svg";
@@ -47,6 +49,9 @@ import FlipHorizontal from "@/../assets/16px-solid/flip-horizontal.svg";
import FlipVertical from "@/../assets/16px-solid/flip-vertical.svg";
import GraphiteLogo from "@/../assets/16px-solid/graphite-logo.svg";
import NewLayer from "@/../assets/16px-solid/new-layer.svg";
import NodeFolder from "@/../assets/16px-solid/node-folder.svg";
import NodePath from "@/../assets/16px-solid/node-path.svg";
import NodeText from "@/../assets/16px-solid/node-text.svg";
import Paste from "@/../assets/16px-solid/paste.svg";
import Trash from "@/../assets/16px-solid/trash.svg";
import ViewModeNormal from "@/../assets/16px-solid/view-mode-normal.svg";
@@ -59,6 +64,7 @@ import ZoomIn from "@/../assets/16px-solid/zoom-in.svg";
import ZoomOut from "@/../assets/16px-solid/zoom-out.svg";
import ZoomReset from "@/../assets/16px-solid/zoom-reset.svg";
// 16px Two-Tone
import MouseHintDrag from "@/../assets/16px-two-tone/mouse-hint-drag.svg";
import MouseHintLmbDrag from "@/../assets/16px-two-tone/mouse-hint-lmb-drag.svg";
import MouseHintLmb from "@/../assets/16px-two-tone/mouse-hint-lmb.svg";
@@ -70,9 +76,7 @@ import MouseHintRmb from "@/../assets/16px-two-tone/mouse-hint-rmb.svg";
import MouseHintScrollDown from "@/../assets/16px-two-tone/mouse-hint-scroll-down.svg";
import MouseHintScrollUp from "@/../assets/16px-two-tone/mouse-hint-scroll-up.svg";
import NodeTypeFolder from "@/../assets/24px-full-color/node-type-folder.svg";
import NodeTypePath from "@/../assets/24px-full-color/node-type-path.svg";
// 24px Two-Tone
import GeneralCropTool from "@/../assets/24px-two-tone/general-crop-tool.svg";
import GeneralEyedropperTool from "@/../assets/24px-two-tone/general-eyedropper-tool.svg";
import GeneralFillTool from "@/../assets/24px-two-tone/general-fill-tool.svg";
@@ -96,12 +100,11 @@ import VectorSplineTool from "@/../assets/24px-two-tone/vector-spline-tool.svg";
import VectorTextTool from "@/../assets/24px-two-tone/vector-text-tool.svg";
export type IconName = keyof typeof ICON_LIST;
export type IconSize = 12 | 16 | 24 | 32;
export type IconSize = 12 | 16 | 24;
const size12: IconSize = 12;
const size16: IconSize = 16;
const size24: IconSize = 24;
// const size32: IconSize = 32;
export const ICON_LIST = {
Checkmark: { component: Checkmark, size: size12 },
@@ -154,6 +157,9 @@ export const ICON_LIST = {
GraphiteLogo: { component: GraphiteLogo, size: size16 },
NewLayer: { component: NewLayer, size: size16 },
Paste: { component: Paste, size: size16 },
NodeFolder: { component: NodeFolder, size: size16 },
NodePath: { component: NodePath, size: size16 },
NodeText: { component: NodeText, size: size16 },
Trash: { component: Trash, size: size16 },
ViewModeNormal: { component: ViewModeNormal, size: size16 },
ViewModeOutline: { component: ViewModeOutline, size: size16 },
@@ -176,9 +182,6 @@ export const ICON_LIST = {
MouseHintScrollDown: { component: MouseHintScrollDown, size: size16 },
MouseHintScrollUp: { component: MouseHintScrollUp, size: size16 },
NodeTypeFolder: { component: NodeTypeFolder, size: size24 },
NodeTypePath: { component: NodeTypePath, size: size24 },
GeneralCropTool: { component: GeneralCropTool, size: size24 },
GeneralEyedropperTool: { component: GeneralEyedropperTool, size: size24 },
GeneralNavigateTool: { component: GeneralNavigateTool, size: size24 },