mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-06-04 04:48:55 +00:00
feat: changes
This commit is contained in:
@@ -10,19 +10,15 @@ import Action from "$lib/components/Action.svelte";
|
||||
import type { Range } from "@codemirror/state";
|
||||
import { parsedChordsField } from "./parsed-chords-plugin";
|
||||
import { iterActions } from "./parse-meta";
|
||||
import type { KeyInfo } from "$lib/serial/keymap-codes";
|
||||
|
||||
export class ActionWidget extends WidgetType {
|
||||
component?: {};
|
||||
|
||||
constructor(readonly id: string | number) {
|
||||
constructor(readonly info: KeyInfo) {
|
||||
super();
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/*override eq(other: ActionWidget) {
|
||||
return this.id == other.id;
|
||||
}*/
|
||||
|
||||
toDOM() {
|
||||
if (this.component) {
|
||||
unmount(this.component);
|
||||
@@ -32,15 +28,16 @@ export class ActionWidget extends WidgetType {
|
||||
|
||||
this.component = mount(Action, {
|
||||
target: element,
|
||||
props: { action: this.id, display: "keys", inText: true },
|
||||
props: {
|
||||
action: this.info,
|
||||
display: "keys",
|
||||
inText: true,
|
||||
withPopover: false,
|
||||
},
|
||||
});
|
||||
return element;
|
||||
}
|
||||
|
||||
override ignoreEvent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
override destroy() {
|
||||
if (this.component) {
|
||||
unmount(this.component);
|
||||
@@ -63,7 +60,7 @@ function actionWidgets(view: EditorView) {
|
||||
}
|
||||
if (action.info && action.explicit) {
|
||||
const deco = Decoration.replace({
|
||||
widget: new ActionWidget(action.code),
|
||||
widget: new ActionWidget(action.info),
|
||||
});
|
||||
widgets.push(deco.range(action.range[0], action.range[1]));
|
||||
}
|
||||
|
||||
41
src/lib/chord-editor/action-tooltip.ts
Normal file
41
src/lib/chord-editor/action-tooltip.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { hoverTooltip } from "@codemirror/view";
|
||||
import { parsedChordsField } from "./parsed-chords-plugin";
|
||||
import { type ActionMeta, iterActions } from "./parse-meta";
|
||||
import { mount, unmount } from "svelte";
|
||||
import ActionTooltip from "$lib/components/action/ActionTooltip.svelte";
|
||||
|
||||
function inRange(pos: number, side: 1 | -1, range: [number, number]) {
|
||||
if (side < 0) {
|
||||
return pos > range[0] && pos <= range[1];
|
||||
} else {
|
||||
return pos >= range[0] && pos < range[1];
|
||||
}
|
||||
}
|
||||
|
||||
export const actionHover = hoverTooltip((view, pos, side) => {
|
||||
const chord = view.state
|
||||
.field(parsedChordsField)
|
||||
.chords.find((chord) => inRange(pos, side, chord.range));
|
||||
if (!chord) return null;
|
||||
let action = iterActions<ActionMeta>(chord, (action) =>
|
||||
inRange(pos, side, action.range) ? action : undefined,
|
||||
);
|
||||
if (!action?.info) return null;
|
||||
return {
|
||||
pos: action.range[0],
|
||||
end: action.range[1],
|
||||
create() {
|
||||
const dom = document.createElement("div");
|
||||
const element = mount(ActionTooltip, {
|
||||
target: dom,
|
||||
props: { info: action.info, valid: true },
|
||||
});
|
||||
return {
|
||||
dom,
|
||||
destroy() {
|
||||
unmount(element);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -152,25 +152,35 @@ export function mapParseResult(
|
||||
};
|
||||
}
|
||||
|
||||
export function iterActions(
|
||||
export function iterActions<T = void>(
|
||||
chord: ChordMeta,
|
||||
callback: (action: ActionMeta) => void,
|
||||
) {
|
||||
callback: (action: ActionMeta) => T | void,
|
||||
): T | undefined {
|
||||
if (chord.input) {
|
||||
for (const action of chord.input.actions) {
|
||||
callback(action);
|
||||
const result = callback(action);
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chord.compounds) {
|
||||
for (const compound of chord.compounds) {
|
||||
for (const action of compound.actions) {
|
||||
callback(action);
|
||||
const result = callback(action);
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chord.phrase) {
|
||||
for (const action of chord.phrase.actions) {
|
||||
callback(action);
|
||||
const result = callback(action);
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import { actionMetaPlugin } from "./action-meta-plugin";
|
||||
import { parsedChordsField } from "./parsed-chords-plugin";
|
||||
import { changesPanel } from "./changes-panel.svelte";
|
||||
import { searchKeymap } from "@codemirror/search";
|
||||
import { actionHover } from "./action-tooltip";
|
||||
|
||||
const serializedFields = {
|
||||
history: historyField,
|
||||
@@ -47,6 +48,7 @@ export function createConfig(params: EditorConfig) {
|
||||
actionMetaPlugin.plugin,
|
||||
deviceChordField,
|
||||
parsedChordsField,
|
||||
actionHover,
|
||||
changesPanel(),
|
||||
lintGutter(),
|
||||
params.rawCode ? [lineNumbers()] : [delimPlugin, actionPlugin],
|
||||
|
||||
Reference in New Issue
Block a user