xref: /aosp_15_r20/tools/netsim/ui/ts/device-dropzone.ts (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1*cf78ab8cSAndroid Build Coastguard Workerimport {html, LitElement} from 'lit';
2*cf78ab8cSAndroid Build Coastguard Workerimport {customElement, property} from 'lit/decorators.js';
3*cf78ab8cSAndroid Build Coastguard Worker
4*cf78ab8cSAndroid Build Coastguard Workerimport {DeviceDragZone} from './device-dragzone.js';
5*cf78ab8cSAndroid Build Coastguard Workerimport {simulationState} from './device-observer.js';
6*cf78ab8cSAndroid Build Coastguard Worker
7*cf78ab8cSAndroid Build Coastguard Worker@customElement('ns-device-dropzone')
8*cf78ab8cSAndroid Build Coastguard Workerexport class DeviceDropZone extends LitElement {
9*cf78ab8cSAndroid Build Coastguard Worker  @property({type: String, attribute: 'serial'}) serial: string = '';
10*cf78ab8cSAndroid Build Coastguard Worker
11*cf78ab8cSAndroid Build Coastguard Worker  @property({type: String, attribute: 'type'}) type: string = '';
12*cf78ab8cSAndroid Build Coastguard Worker
13*cf78ab8cSAndroid Build Coastguard Worker  constructor() {
14*cf78ab8cSAndroid Build Coastguard Worker    super();
15*cf78ab8cSAndroid Build Coastguard Worker    this.addEventListener('drop', this.handleDrop);
16*cf78ab8cSAndroid Build Coastguard Worker    this.addEventListener('drag', this.handleDragOver);
17*cf78ab8cSAndroid Build Coastguard Worker    this.addEventListener('dragenter', DeviceDropZone.handleDragEnter);
18*cf78ab8cSAndroid Build Coastguard Worker    this.addEventListener('dragleave', DeviceDropZone.handleDragLeave);
19*cf78ab8cSAndroid Build Coastguard Worker    this.addEventListener('dragover', this.handleDragOver);
20*cf78ab8cSAndroid Build Coastguard Worker  }
21*cf78ab8cSAndroid Build Coastguard Worker
22*cf78ab8cSAndroid Build Coastguard Worker  static handleDragEnter(ev: DragEvent) {
23*cf78ab8cSAndroid Build Coastguard Worker    ev.preventDefault();
24*cf78ab8cSAndroid Build Coastguard Worker  }
25*cf78ab8cSAndroid Build Coastguard Worker
26*cf78ab8cSAndroid Build Coastguard Worker  static handleDragLeave(ev: DragEvent) {
27*cf78ab8cSAndroid Build Coastguard Worker    ev.preventDefault();
28*cf78ab8cSAndroid Build Coastguard Worker  }
29*cf78ab8cSAndroid Build Coastguard Worker
30*cf78ab8cSAndroid Build Coastguard Worker  slottedDropZone() {
31*cf78ab8cSAndroid Build Coastguard Worker    // Returns the #dropzone div inside the slotted children, where devices are
32*cf78ab8cSAndroid Build Coastguard Worker    // stored. note: needs better checking when not the first element.
33*cf78ab8cSAndroid Build Coastguard Worker    const slot = this.shadowRoot?.querySelector('slot');
34*cf78ab8cSAndroid Build Coastguard Worker    return slot?.assignedElements({flatten: true})[0];
35*cf78ab8cSAndroid Build Coastguard Worker  }
36*cf78ab8cSAndroid Build Coastguard Worker
37*cf78ab8cSAndroid Build Coastguard Worker  handleDrop(ev: DragEvent) {
38*cf78ab8cSAndroid Build Coastguard Worker    ev.preventDefault();
39*cf78ab8cSAndroid Build Coastguard Worker    const dropzone = this.slottedDropZone();
40*cf78ab8cSAndroid Build Coastguard Worker    if (dropzone) {
41*cf78ab8cSAndroid Build Coastguard Worker      const draggedElement = DeviceDragZone.dragged as HTMLElement;
42*cf78ab8cSAndroid Build Coastguard Worker      if (ev.dataTransfer?.effectAllowed === 'move') {
43*cf78ab8cSAndroid Build Coastguard Worker        draggedElement.parentNode?.removeChild(draggedElement);
44*cf78ab8cSAndroid Build Coastguard Worker        draggedElement.style.opacity = '';
45*cf78ab8cSAndroid Build Coastguard Worker        dropzone.appendChild(draggedElement);
46*cf78ab8cSAndroid Build Coastguard Worker      } else {
47*cf78ab8cSAndroid Build Coastguard Worker        // copy
48*cf78ab8cSAndroid Build Coastguard Worker        dropzone.appendChild(draggedElement.cloneNode(true));
49*cf78ab8cSAndroid Build Coastguard Worker      }
50*cf78ab8cSAndroid Build Coastguard Worker      const dropped = dropzone.lastChild as HTMLElement;
51*cf78ab8cSAndroid Build Coastguard Worker      if (dropped) {
52*cf78ab8cSAndroid Build Coastguard Worker        const rect = (dropzone as HTMLElement).getBoundingClientRect();
53*cf78ab8cSAndroid Build Coastguard Worker        dropped.setAttribute('action', 'move');
54*cf78ab8cSAndroid Build Coastguard Worker        dropped.style.position = 'absolute';
55*cf78ab8cSAndroid Build Coastguard Worker        dropped.style.left = `${ev.clientX - rect.left}px`;
56*cf78ab8cSAndroid Build Coastguard Worker        dropped.style.top = `${ev.clientY - rect.top}px`;
57*cf78ab8cSAndroid Build Coastguard Worker        dropped.style.opacity = `1.0`;
58*cf78ab8cSAndroid Build Coastguard Worker        // Patch the position of a dropped element
59*cf78ab8cSAndroid Build Coastguard Worker        let id = dropped.getElementsByTagName('ns-cube-sprite')
60*cf78ab8cSAndroid Build Coastguard Worker                     .item(0)
61*cf78ab8cSAndroid Build Coastguard Worker                     ?.getAttribute('id');
62*cf78ab8cSAndroid Build Coastguard Worker        if (id === undefined) {
63*cf78ab8cSAndroid Build Coastguard Worker          id = dropped.getElementsByTagName('ns-pyramid-sprite')
64*cf78ab8cSAndroid Build Coastguard Worker                   .item(0)
65*cf78ab8cSAndroid Build Coastguard Worker                   ?.getAttribute('id');
66*cf78ab8cSAndroid Build Coastguard Worker        }
67*cf78ab8cSAndroid Build Coastguard Worker        if (id === undefined || id === null) {
68*cf78ab8cSAndroid Build Coastguard Worker          id = '';
69*cf78ab8cSAndroid Build Coastguard Worker        }
70*cf78ab8cSAndroid Build Coastguard Worker        simulationState.handleDrop(
71*cf78ab8cSAndroid Build Coastguard Worker            id, (ev.clientX - rect.left) / 100, (ev.clientY - rect.top) / 100);
72*cf78ab8cSAndroid Build Coastguard Worker      }
73*cf78ab8cSAndroid Build Coastguard Worker    }
74*cf78ab8cSAndroid Build Coastguard Worker  }
75*cf78ab8cSAndroid Build Coastguard Worker
76*cf78ab8cSAndroid Build Coastguard Worker  handleDragOver(ev: DragEvent) {
77*cf78ab8cSAndroid Build Coastguard Worker    ev.preventDefault();
78*cf78ab8cSAndroid Build Coastguard Worker    this.slottedDropZone();
79*cf78ab8cSAndroid Build Coastguard Worker  }
80*cf78ab8cSAndroid Build Coastguard Worker
81*cf78ab8cSAndroid Build Coastguard Worker  render() {
82*cf78ab8cSAndroid Build Coastguard Worker    return html`<slot></slot>`;
83*cf78ab8cSAndroid Build Coastguard Worker  }
84*cf78ab8cSAndroid Build Coastguard Worker}
85