import { Transition, Node, StackOperation } from '../automata';
import { html } from 'lit';
import { styleMap } from 'lit/directives/style-map.js';
import { biDatabase, biDatabaseAdd, biDatabaseDash, biDatabaseSlash, biTrash } from '../styles/icons';
import { AutomatonComponent } from 'index';
import { classMap } from 'lit/directives/class-map.js';
import { msg } from '@lit/localize';
import { Logger } from '@u/logger';
/**
* Represents a context menu component that provides options for interacting with nodes and edges.
*/
export class ContextMenu {
private selected: {
data: Transition | Node;
type: 'Node' | 'Transition' | undefined;
updateFn: Function;
deleteFn: Function;
} = {
data: { id: 0, label: '', initial: false, final: false },
type: undefined,
updateFn: () => {},
deleteFn: () => {},
};
private position = { x: 0, y: 0 };
private translate = { x: '-100%', y: '-100%' };
private visible = false;
public requestUpdate: () => void = () => {};
constructor(private parentComponent: AutomatonComponent) {}
public render() {
return html`
`;
}
private nodeContextMenu() {
return html`
{
this.selected.updateFn({ ...this.selected.data, label: e.target.value });
this.selected.data = { ...this.selected.data, label: e.target.value };
}}
?disabled=${!this.parentComponent.settings.permissions.node.change}
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
>
`;
}
private edgeContextMenu(isPda: boolean = false) {
let transition = this.selected?.data as Transition;
let stackOperations = transition.stackOperations as StackOperation[] || [];
return html`
${transition.from === transition.to ? html`
{
const value = e.target.value;
this.selected.updateFn({
...transition,
selfReference: { angle: ((450 - value) % 360) * (Math.PI / 180) },
});
}}
>`
: html`
{
const value = e.target.value;
this.selected.updateFn({
...transition,
smooth: { type: value < 0 ? 'curvedCCW' : 'curvedCW', roundness: Math.abs(value / 100) },
});
}}
>`
}
`;
}
public setData(data: Node | Transition, type: 'Node' | 'Transition', updateFn: Function, deleteFn: Function) {
this.selected = { data, type, updateFn, deleteFn };
this.requestUpdate();
}
public setPosition({ x, y }: { x: number; y: number }) {
this.position = { x, y };
const totalWidth = this.parentComponent.shadowRoot?.getElementById("graphCanvas")?.clientWidth || 0;
const totalHeight = this.parentComponent.shadowRoot?.getElementById("graphCanvas")?.clientHeight || 0;
this.translate.x = x > totalWidth / 2 ? '-100%' : '0%';
this.translate.y = y > totalHeight / 2 ? '-100%' : '0%';
this.requestUpdate();
}
public show() {
this.visible = true;
this.requestUpdate();
}
public hide() {
this.visible = false;
this.requestUpdate();
}
public isVisible() {
return this.visible;
}
public toggle() {
this.visible = !this.visible;
this.requestUpdate();
}
public blur() {
this.hide();
this.requestUpdate();
}
}