• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { BaseElement, element } from '../../../../base-ui/BaseElement';
17import { LitTable } from '../../../../base-ui/table/lit-table';
18import { MarkStruct } from '../../../bean/MarkStruct';
19import { SpSystemTrace } from '../../SpSystemTrace';
20import { getTimeString } from '../sheet/TabPaneCurrentSelection';
21import { Flag } from './Flag';
22
23@element('tabpane-flag')
24export class TabPaneFlag extends BaseElement {
25  private flag: Flag | null = null;
26  private flagList: Array<Flag> = [];
27  private systemTrace: SpSystemTrace | undefined | null;
28  private tableDataSource: Array<MarkStruct | unknown> = [];
29  private panelTable: LitTable | undefined | null;
30
31  initElements(): void {
32    this.systemTrace = document
33      .querySelector('body > sp-application')
34      ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace');
35    this.panelTable = this.shadowRoot!.querySelector<LitTable>('.notes-editor-panel');
36    this.panelTable!.addEventListener('row-click', (evt: unknown) => {
37      // @ts-ignore
38      if (evt.detail.data.startTime === undefined) {
39        return;
40      }
41      this.flagList = this.systemTrace?.timerShaftEL!.sportRuler?.flagList || [];
42      // 点击表格某一行后,背景变色
43      // @ts-ignore
44      let data = evt.detail.data;
45      this.systemTrace!.flagList = this.flagList || [];
46      //   页面上对应的flag变为实心有旗杆
47      this.flagList.forEach((flag, index) => {
48        if (data.startTime === flag.time) {
49          flag.selected = true;
50          this.setTableSelection(index + 1);
51        } else {
52          flag.selected = false;
53        }
54        this.systemTrace?.timerShaftEL!.sportRuler!.drawTriangle(flag.time, flag.type);
55      });
56    });
57    // 当鼠标移出panel时重新加载备注信息
58    this.systemTrace?.shadowRoot?.querySelector('trace-sheet')?.addEventListener(
59      'mouseout',
60      (event: unknown) => {
61        if (this.flagList.length === 0) {
62          return;
63        }
64        // @ts-ignore
65        if ((window as unknown).flagInputFocus) {
66          return;
67        }
68        let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>;
69        //   第一个tr是移除全部,所以跳过,从第二个tr开始,和this.slicestimeList数组的第一个对应……,所以i从1开始,在this.slicestimeList数组中取值时用i-1
70        for (let i = 1; i < tr.length; i++) {
71          tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.flagList[i - 1].text;
72        }
73        // @ts-ignore
74        event.stopPropagation();
75      },
76      { capture: true }
77    );
78    new ResizeObserver((entries) => {
79      if (this.parentElement!.style.display !== 'none') {
80        this.setTableData();
81      }
82    }).observe(this);
83  }
84
85  public setCurrentFlag(flag: Flag): void {
86    this.flagList = this.systemTrace?.timerShaftEL!.sportRuler?.flagList || [];
87    this.flag = flag;
88    // 判断当前传入的旗子是否已经存在
89    let findFlag = this.flagList.find((it) => it.time === flag.time);
90    // 如果this.flagList为空,或者没有在同一位置绘制过,就将当前的flag放进数组
91    if (!findFlag || this.flagList.length === 0) {
92      this.flagList!.push(this.flag);
93    }
94    this.setTableData();
95  }
96
97  /**
98   * 根据this.flagList设置表格数据
99   */
100  private setTableData(): void {
101    this.flagList = this.systemTrace?.timerShaftEL!.sportRuler?.flagList || [];
102    this.tableDataSource = [];
103    // 按照时间进行排序,保证泳道图上的旗子和表格的顺序一致
104    this.flagList.sort(function (a, b) {
105      return a.time - b.time;
106    });
107
108    for (let flag of this.flagList) {
109      let btn = document.createElement('button');
110      btn.className = 'remove';
111      let color = document.createElement('input');
112      color.type = 'color';
113      let text = document.createElement('input');
114      text.type = 'text';
115      color!.value = flag.color;
116      text!.value = flag.text;
117      let flagData = new MarkStruct(btn, color.value, text.value, getTimeString(flag.time), flag.time);
118      flag.selected === true ? (flagData.isSelected = true) : (flagData.isSelected = false);
119      this.systemTrace?.timerShaftEL!.sportRuler!.drawTriangle(flag.time, flag.type);
120      this.tableDataSource.push(flagData);
121    }
122    // 表格第一行只添加一个RemoveAll按钮
123    let removeAll = document.createElement('button');
124    removeAll.className = 'removeAll';
125    removeAll.innerHTML = 'RemoveAll';
126    let flagData = new MarkStruct(removeAll);
127    this.tableDataSource.unshift(flagData);
128
129    // 当前点击了哪个旗子,就将对应的表格中的那行的背景变色
130    this.tableDataSource.forEach((data, index) => {
131      // @ts-ignore
132      if (data.time === this.flag?.time) {
133        this.setTableSelection(index);
134      }
135    });
136    this.panelTable!.recycleDataSource = this.tableDataSource;
137    this.eventHandler();
138    this.systemTrace!.flagList = this.flagList || [];
139  }
140
141  /**
142   * 修改旗子颜色事件和移除旗子的事件处理
143   */
144  private eventHandler(): void {
145    let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>;
146    this.removeAllClickEventByFlag(tr[0]);
147    //   第一个tr是移除全部,所以跳过,从第二个tr开始,和this.flagList数组的第一个对应……,所以i从1开始,在this.flagList数组中取值时用i-1
148    for (let i = 1; i < tr.length; i++) {
149      tr[i].querySelector<HTMLInputElement>('#color-input')!.value = this.flagList[i - 1].color;
150      //  点击色块修改颜色
151      this.colorInputChangeEventByFlag(i, tr[i]);
152      // 修改备注
153      tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.flagList[i - 1].text;
154      this.textInputKeyUpEventByFlag(i, tr[i]);
155      this.textInputBlurEventByFlag(i, tr[i]);
156      this.textInputFocusEventByFlag(tr[i]);
157      // 点击remove按钮移除
158      this.removeClickEventByFlag(i, tr[i]);
159    }
160  }
161
162  private removeAllClickEventByFlag(tr: HTMLDivElement): void {
163    tr.querySelector('.removeAll')!.addEventListener('click', () => {
164      this.systemTrace!.flagList = [];
165      let flagList = [...this.flagList];
166      for (let i = 0; i < flagList.length; i++) {
167        flagList[i].hidden = true;
168        document.dispatchEvent(new CustomEvent('flag-change', { detail: flagList[i] }));
169      }
170      this.flagList = [];
171      return;
172    });
173  }
174
175  private colorInputChangeEventByFlag(index: number, tr: HTMLDivElement): void {
176    tr.querySelector<HTMLInputElement>('#color-input')?.addEventListener('change', (event: unknown) => {
177      // @ts-ignore
178      if (this.tableDataSource[index].startTime === this.flagList[index - 1].time) {
179        // @ts-ignore
180        this.flagList[index - 1].color = event?.target.value;
181        document.dispatchEvent(new CustomEvent('flag-change', { detail: this.flagList[index - 1] }));
182        //   旗子颜色改变时,重绘泳道图
183        this.systemTrace?.refreshCanvas(true);
184      }
185      // @ts-ignore
186      event.stopPropagation();
187    });
188  }
189
190  private textInputKeyUpEventByFlag(index: number, tr: HTMLDivElement): void {
191    tr.querySelector<HTMLInputElement>('#text-input')?.addEventListener('keyup', (event: unknown) => {
192      // @ts-ignore
193      if (this.tableDataSource[index].startTime === this.flagList[index - 1].time && event.code === 'Enter' || event.code === 'NumpadEnter') {
194        // @ts-ignore
195        this.flagList[index - 1].text = event?.target.value;
196        document.dispatchEvent(new CustomEvent('flag-change', { detail: this.flagList[index - 1] }));
197        //   旗子颜色改变时,重绘泳道图
198        this.systemTrace?.refreshCanvas(true);
199      }
200      // @ts-ignore
201      event.stopPropagation();
202    });
203  }
204
205  private textInputBlurEventByFlag(index: number, tr: HTMLDivElement): void {
206    tr.querySelector<HTMLInputElement>('#text-input')?.addEventListener('blur', (event: unknown) => {
207      // @ts-ignore
208      (window as unknown).flagInputFocus = false;
209      window.publish(window.SmartEvent.UI.KeyboardEnable, {
210        enable: true,
211      });
212      // @ts-ignore
213      if (this.tableDataSource[index].startTime === this.flagList[index - 1].time) {
214        // @ts-ignore
215        this.flagList[index - 1].text = event?.target.value;
216        document.dispatchEvent(new CustomEvent('flag-change', { detail: this.flagList[index - 1] }));
217        this.setTableData();
218        //   旗子颜色改变时,重绘泳道图
219        this.systemTrace?.refreshCanvas(true);
220      }
221      // @ts-ignore
222      event.stopPropagation();
223    });
224  }
225
226  private textInputFocusEventByFlag(tr: HTMLDivElement): void {
227    tr.querySelector<HTMLInputElement>('#text-input')?.addEventListener('focus', (event: unknown) => {
228      // @ts-ignore
229      (window as unknown).flagInputFocus = true;
230      window.publish(window.SmartEvent.UI.KeyboardEnable, {
231        enable: false,
232      });
233      let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>;
234      //   第一个tr是移除全部,所以跳过,从第二个tr开始,和this.flagList数组的第一个对应……,所以i从1开始,在this.flagList数组中取值时用i-1
235      for (let i = 1; i < tr.length; i++) {
236        tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.flagList[i - 1].text;
237      }
238    });
239  }
240
241  private removeClickEventByFlag(index: number, tr: HTMLDivElement): void {
242    tr!.querySelector('.remove')?.addEventListener('click', (event: unknown) => {
243      // @ts-ignore
244      if (this.tableDataSource[index].startTime === this.flagList[index - 1].time) {
245        this.flagList[index - 1].hidden = true;
246        this.systemTrace!.flagList = this.flagList || [];
247        document.dispatchEvent(new CustomEvent('flag-change', { detail: this.flagList[index - 1] }));
248        //   移除时更新表格内容
249        this.setTableData();
250      }
251      // @ts-ignore
252      event.stopPropagation();
253    });
254  }
255
256  /**
257   * 修改表格指定行数的背景颜色
258   * @param line 要改变的表格行数
259   */
260  public setTableSelection(line: unknown): void {
261    // @ts-ignore
262    this.tableDataSource[line].isSelected = true;
263    // @ts-ignore
264    this.panelTable?.clearAllSelection(this.tableDataSource[line]);
265    // @ts-ignore
266    this.panelTable?.setCurrentSelection(this.tableDataSource[line]);
267  }
268
269  initHtml(): string {
270    return `
271        <style>
272        :host{
273            display: flex;
274            flex-direction: column;
275            padding: 10px 10px;
276        }
277        </style>
278        <lit-table class="notes-editor-panel" style="height: auto">
279            <lit-table-column width="20%" data-index="startTimeStr" key="startTimeStr" align="flex-start" title="TimeStamp">
280            </lit-table-column>
281            <lit-table-column width="10%" data-index="color" key="color" align="flex-start" title="Color">
282                <template>
283                    <div style='width:50px; height: 21px; position: relative;overflow: hidden;'>
284                        <input type="color" id="color-input" style='
285                            background: var(--dark-background5,#FFFFFF);
286                            padding: 0px;
287                            border: none;
288                            width: 60px;
289                            height: 31px;
290                            position: absolute;
291                            top: -5px;
292                            left: -5px;'/>
293                    </div>
294                </template>
295            </lit-table-column>
296            <lit-table-column width="40%" data-index="text" key="text" align="flex-start" title="Remarks">
297              <template>
298                  <input type="text" id="text-input"  style="width: 100%; border: none" />
299              </template>
300            </lit-table-column>
301            <lit-table-column width="10%" data-index="operate" key="operate" align="flex-start" title="Operate">
302                <template>
303                    <button class="remove" style='
304                        background: var(--dark-border1,#262f3c);
305                        color: white;
306                        border-radius: 10px;
307                        font-size: 10px;
308                        height: 21px;
309                        line-height: 21px;
310                        min-width: 7em;
311                        border: none;
312                        cursor: pointer;
313                        outline: inherit;
314                    '>Remove</button>
315                </template>
316            </lit-table-column>
317        </lit-table>
318        `;
319  }
320}
321