mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-02-13 04:32:39 +00:00
fix: action selector
update dependencies
This commit is contained in:
19
src/lib/assets/layouts/layout.d.ts
vendored
Normal file
19
src/lib/assets/layouts/layout.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
export interface CompiledLayout {
|
||||
name: string;
|
||||
size: [number, number];
|
||||
keys: CompiledLayoutKey[];
|
||||
}
|
||||
|
||||
export interface CompiledLayoutKey {
|
||||
id: number;
|
||||
shape: "quarter-circle" | "square";
|
||||
cornerRadius: number;
|
||||
size: [number, number];
|
||||
pos: [number, number];
|
||||
rotate: number;
|
||||
}
|
||||
|
||||
declare module "*.layout.yml" {
|
||||
const layout: CompiledLayout;
|
||||
export default layout;
|
||||
}
|
||||
@@ -32,6 +32,9 @@
|
||||
|
||||
onMount(() => {
|
||||
search();
|
||||
if (autofocus) {
|
||||
searchBox.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const index = new FlexSearch.Index({ tokenize: "full" });
|
||||
@@ -122,7 +125,6 @@
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<input
|
||||
type="search"
|
||||
{autofocus}
|
||||
bind:this={searchBox}
|
||||
oninput={search}
|
||||
onkeypress={keyboardNavigation}
|
||||
@@ -175,16 +177,19 @@
|
||||
<button
|
||||
class="action-item"
|
||||
draggable="true"
|
||||
ondragstart={(event) => {
|
||||
if (!event.dataTransfer) return;
|
||||
event.stopPropagation();
|
||||
event.dataTransfer.dropEffect = "copy";
|
||||
event.dataTransfer.clearData();
|
||||
event.dataTransfer.setData(
|
||||
"text/plain",
|
||||
actionToValue(action.code),
|
||||
);
|
||||
}}
|
||||
onclick={() => select(action.code)}
|
||||
ondragstart={onselect === undefined
|
||||
? (event) => {
|
||||
if (!event.dataTransfer) return;
|
||||
event.stopPropagation();
|
||||
event.dataTransfer.dropEffect = "copy";
|
||||
event.dataTransfer.clearData();
|
||||
event.dataTransfer.setData(
|
||||
"text/plain",
|
||||
actionToValue(action.code),
|
||||
);
|
||||
}
|
||||
: undefined}
|
||||
>
|
||||
<Action {action} display="verbose"></Action>
|
||||
</button>
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { compileLayout } from "$lib/serialization/visual-layout";
|
||||
import type {
|
||||
VisualLayout,
|
||||
CompiledLayoutKey,
|
||||
} from "$lib/serialization/visual-layout";
|
||||
import { deviceLayout } from "$lib/serial/connection";
|
||||
import { dev } from "$app/environment";
|
||||
import ActionSelector from "$lib/components/layout/ActionSelector.svelte";
|
||||
@@ -15,6 +10,10 @@
|
||||
import { fly } from "svelte/transition";
|
||||
import { expoOut } from "svelte/easing";
|
||||
import { activeLayer, activeProfile } from "$lib/serial/connection";
|
||||
import type {
|
||||
CompiledLayout,
|
||||
CompiledLayoutKey,
|
||||
} from "$lib/assets/layouts/layout.d.ts";
|
||||
|
||||
const { scale, margin, strokeWidth, fontSize, iconFontSize } =
|
||||
getContext<VisualLayoutConfig>("visual-layout-config");
|
||||
@@ -29,8 +28,7 @@
|
||||
console.assert(iconFontSize % 1 === 0, "Icon font size must be an integer");
|
||||
}
|
||||
|
||||
let { visualLayout }: { visualLayout: VisualLayout } = $props();
|
||||
let layoutInfo = $state(compileLayout(visualLayout));
|
||||
let { layoutInfo }: { layout: CompiledLayout } = $props();
|
||||
|
||||
function getCenter(key: CompiledLayoutKey): [x: number, y: number] {
|
||||
return [key.pos[0] + key.size[0] / 2, key.pos[1] + key.size[1] / 2];
|
||||
|
||||
@@ -3,49 +3,49 @@
|
||||
import { action } from "$lib/title";
|
||||
import GenericLayout from "$lib/components/layout/GenericLayout.svelte";
|
||||
import { activeProfile, activeLayer } from "$lib/serial/connection";
|
||||
import type { VisualLayout } from "$lib/serialization/visual-layout";
|
||||
import { fade, fly } from "svelte/transition";
|
||||
import { restoreFromFile } from "$lib/backup/backup";
|
||||
import type { CompiledLayout } from "$lib/assets/layouts/layout.d.ts";
|
||||
|
||||
const layouts = {
|
||||
ONE: () =>
|
||||
import("$lib/assets/layouts/one.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/one.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
TWO: () =>
|
||||
import("$lib/assets/layouts/one.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/one.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
LITE: () =>
|
||||
import("$lib/assets/layouts/lite.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/lite.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
X: () =>
|
||||
import("$lib/assets/layouts/generic/103-key.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/103-key.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
ZERO: () =>
|
||||
import("$lib/assets/layouts/generic/103-key.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/103-key.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
M4G: () =>
|
||||
import("$lib/assets/layouts/m4g.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/m4g.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
M4GR: () =>
|
||||
import("$lib/assets/layouts/m4gr.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/m4gr.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
T4G: () =>
|
||||
import("$lib/assets/layouts/t4g.yml").then(
|
||||
(it) => it.default as VisualLayout,
|
||||
import("$lib/assets/layouts/t4g.layout.yml").then(
|
||||
(it) => it.default as CompiledLayout,
|
||||
),
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
{#if $serialPort}
|
||||
{#await layouts[$serialPort.device]() then visualLayout}
|
||||
{#await layouts[$serialPort.device]() then layoutInfo}
|
||||
<fieldset transition:fade>
|
||||
<div class="layers">
|
||||
{#each Array.from({ length: $serialPort.layerCount }, (_, i) => i) as layer}
|
||||
@@ -75,7 +75,7 @@
|
||||
{/if}
|
||||
</fieldset>
|
||||
|
||||
<GenericLayout {visualLayout} />
|
||||
<GenericLayout {layoutInfo} />
|
||||
{/await}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
export interface VisualLayout {
|
||||
name: string;
|
||||
col: VisualLayoutRow[];
|
||||
}
|
||||
|
||||
interface Positionable {
|
||||
offset: [number, number];
|
||||
rotate: number;
|
||||
}
|
||||
|
||||
export interface VisualLayoutRow extends Positionable {
|
||||
row: Array<VisualLayoutKey | VisualLayoutSwitch>;
|
||||
}
|
||||
|
||||
export interface VisualLayoutKey extends Positionable {
|
||||
key: number;
|
||||
size?: [number, number];
|
||||
}
|
||||
|
||||
export interface VisualLayoutSwitch extends Positionable {
|
||||
switch: {
|
||||
n: number;
|
||||
e: number;
|
||||
w: number;
|
||||
s: number;
|
||||
d: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CompiledLayout {
|
||||
name: string;
|
||||
size: [number, number];
|
||||
keys: CompiledLayoutKey[];
|
||||
}
|
||||
|
||||
export interface CompiledLayoutKey {
|
||||
id: number;
|
||||
shape: "quarter-circle" | "square";
|
||||
cornerRadius: number;
|
||||
size: [number, number];
|
||||
pos: [number, number];
|
||||
rotate: number;
|
||||
}
|
||||
|
||||
export function compileLayout(layout: VisualLayout): CompiledLayout {
|
||||
const compiled: CompiledLayout = {
|
||||
name: layout.name,
|
||||
size: [0, 0],
|
||||
keys: [],
|
||||
};
|
||||
|
||||
let y = 0;
|
||||
for (const { row, offset } of layout.col) {
|
||||
let x = offset?.[0] ?? 0;
|
||||
y += offset?.[1] ?? 0;
|
||||
let maxHeight = 0;
|
||||
for (const info of row) {
|
||||
const [ox, oy] = info.offset || [0, 0];
|
||||
const rotate = info.rotate || 0;
|
||||
if ("key" in info) {
|
||||
const [width, height] = info.size ?? [1, 1];
|
||||
|
||||
compiled.keys.push({
|
||||
id: info.key,
|
||||
shape: "square",
|
||||
size: [width, height],
|
||||
pos: [x + ox, y + oy],
|
||||
cornerRadius: 0.1,
|
||||
rotate,
|
||||
});
|
||||
|
||||
x += width + ox;
|
||||
maxHeight = Math.max(maxHeight, height + oy);
|
||||
} else if ("switch" in info) {
|
||||
const cx = x + ox + 1;
|
||||
const cy = y + oy + 1;
|
||||
for (const [i, id] of [
|
||||
info.switch.s,
|
||||
info.switch.w,
|
||||
info.switch.n,
|
||||
info.switch.e,
|
||||
].entries()) {
|
||||
compiled.keys.push({
|
||||
id,
|
||||
shape: "quarter-circle",
|
||||
cornerRadius: 0,
|
||||
size: [2, 0.6],
|
||||
pos: [cx, cy],
|
||||
rotate: 90 * i + 45,
|
||||
});
|
||||
}
|
||||
compiled.keys.push({
|
||||
id: info.switch.d,
|
||||
shape: "square",
|
||||
cornerRadius: 0.5,
|
||||
size: [0.8, 0.8],
|
||||
pos: [x + 0.6 + ox, y + 0.6 + oy],
|
||||
rotate: 0,
|
||||
});
|
||||
|
||||
x += 2 + ox;
|
||||
maxHeight = Math.max(maxHeight, 2 + oy);
|
||||
}
|
||||
}
|
||||
y += maxHeight;
|
||||
compiled.size[0] = Math.max(compiled.size[0], x);
|
||||
}
|
||||
compiled.size[1] = y;
|
||||
|
||||
return compiled;
|
||||
}
|
||||
Reference in New Issue
Block a user