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 { SlicesTime, StType } from '../timer-shaft/SportRuler'; 21import { getTimeString } from './TabPaneCurrentSelection'; 22import { TabPaneCurrentHtml } from './TabPaneCurrent.html'; 23 24@element('tabpane-current') 25export class TabPaneCurrent extends BaseElement { 26 private slicesTimeList: Array<SlicesTime> = []; 27 private slicesTime: SlicesTime | null = null; 28 private systemTrace: SpSystemTrace | undefined | null; 29 private tableDataSource: Array<MarkStruct | unknown> = []; 30 private panelTable: LitTable | undefined | null; 31 32 initElements(): void { 33 this.systemTrace = document 34 .querySelector('body > sp-application') 35 ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace'); 36 this.shadowRoot?.querySelector('#text')?.addEventListener('keyup', (event: unknown) => { 37 // @ts-ignore 38 event.stopPropagation(); 39 // @ts-ignore 40 if (event.keyCode === '13') { 41 if (this.slicesTime) { 42 window.publish(window.SmartEvent.UI.KeyboardEnable, { 43 enable: true, 44 }); 45 // @ts-ignore 46 this.slicesTime.text = event?.target.value; 47 document.dispatchEvent( 48 new CustomEvent('slices-change', { 49 detail: this.slicesTime, 50 }) 51 ); 52 } 53 } 54 }); 55 this.shadowRoot?.querySelector('#text')?.addEventListener('blur', (event: unknown) => { 56 // @ts-ignore 57 (window as unknown).flagInputFocus = false; 58 window.publish(window.SmartEvent.UI.KeyboardEnable, { 59 enable: true, 60 }); 61 }); 62 this.shadowRoot?.querySelector('#text')?.addEventListener('focus', (event: unknown) => { 63 // @ts-ignore 64 (window as unknown).flagInputFocus = true; 65 window.publish(window.SmartEvent.UI.KeyboardEnable, { 66 enable: false, 67 }); 68 }); 69 this.panelTable = this.shadowRoot!.querySelector<LitTable>('.notes-editor-panel'); 70 this.rowClickListener(); 71 this.mouseOutListener(); 72 } 73 74 private rowClickListener(): void { 75 this.panelTable!.addEventListener('row-click', (evt: unknown) => { 76 // @ts-ignore 77 if (evt.detail.data.startTime === undefined) { 78 return; 79 } 80 // 点击表格某一行后,背景变色 81 // @ts-ignore 82 let data = evt.detail.data; 83 this.systemTrace!.slicesList = this.slicesTimeList || []; 84 // 页面上对应的slice变为实心 85 this.slicesTimeList.forEach((slicesTime, index) => { 86 if (data.startTime === slicesTime.startTime && data.endTime === slicesTime.endTime) { 87 slicesTime.selected = true; 88 this.setTableSelection(index + 1); 89 } else { 90 slicesTime.selected = false; 91 } 92 this.systemTrace?.timerShaftEL!.sportRuler!.draw(); 93 }); 94 }); 95 } 96 97 private mouseOutListener(): void { 98 // 当鼠标移出panel时重新加载备注信息 99 this.systemTrace?.shadowRoot?.querySelector('trace-sheet')?.addEventListener( 100 'mouseout', 101 (event: unknown) => { 102 if (this.slicesTimeList.length === 0) { 103 return; 104 } 105 // @ts-ignore 106 if ((window as unknown).flagInputFocus) { 107 return; 108 } 109 let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>; 110 // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.slicesTimeList数组的第一个对应……,所以i从1开始,在this.slicesTimeList数组中取值时用i-1 111 for (let i = 1; i < tr.length; i++) { 112 tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.slicesTimeList[i - 1].text; 113 } 114 // @ts-ignore 115 event.stopPropagation(); 116 }, 117 { capture: true } 118 ); 119 } 120 121 public setCurrentSlicesTime(slicesTime: SlicesTime): void { 122 this.slicesTimeList = this.systemTrace?.timerShaftEL!.sportRuler?.slicesTimeList || []; 123 this.slicesTime = slicesTime; 124 // 判断当前传入的卡尺是否已经存在 125 let findSlicesTime = this.slicesTimeList.find( 126 (it) => it.startTime === slicesTime.startTime && it.endTime === slicesTime.endTime 127 ); 128 // m键生成的临时卡尺只能同时出现最后一个,所以将永久卡尺过滤出来,并加上最后一个临时卡尺 129 if (this.slicesTime.type === StType.TEMP) { 130 this.slicesTimeList = this.slicesTimeList.filter( 131 (item: SlicesTime) => 132 item.type === StType.PERM || 133 (item.type === StType.TEMP && 134 item.startTime === this.slicesTime!.startTime && 135 item.endTime === this.slicesTime!.endTime) 136 ); 137 } 138 // 如果this.slicesTimeList为空,或者没有在同一位置绘制过,就将当前的框选的范围画上线 139 if (!findSlicesTime || this.slicesTimeList.length === 0) { 140 this.slicesTimeList!.push(this.slicesTime); 141 } 142 this.setTableData(); 143 } 144 145 /** 146 * 根据this.slicesTimeList设置表格数据 147 */ 148 private setTableData(): void { 149 this.tableDataSource = []; 150 // 按照开始时间进行排序,保证泳道图上的卡尺(shift+m键)和表格的顺序一致 151 this.slicesTimeList.sort(function (a, b) { 152 return a.startTime - b.startTime; 153 }); 154 for (let slice of this.slicesTimeList) { 155 let btn = document.createElement('button'); 156 btn.className = 'remove'; 157 let color = document.createElement('input'); 158 color.type = 'color'; 159 let text = document.createElement('input'); 160 text.type = 'text'; 161 color!.value = slice.color; 162 text.value = slice.text; 163 let sliceData = new MarkStruct( 164 btn, 165 color.value, 166 text.value, 167 getTimeString(slice.startTime), 168 slice.startTime, 169 getTimeString(slice.endTime), 170 slice.endTime 171 ); 172 slice.selected === true ? (sliceData.isSelected = true) : (sliceData.isSelected = false); 173 this.tableDataSource.push(sliceData); 174 } 175 // 表格第一行只添加一个RemoveAll按钮 176 let removeAll = document.createElement('button'); 177 removeAll.className = 'removeAll'; 178 removeAll.innerHTML = 'RemoveAll'; 179 let sliceData = new MarkStruct(removeAll); 180 this.tableDataSource.unshift(sliceData); 181 182 // 当前点击了哪个卡尺,就将对应的表格中的那行的背景变色 183 this.tableDataSource.forEach((data, index) => { 184 // @ts-ignore 185 if (data.startTime === this.slicesTime?.startTime && data.endTime === this.slicesTime?.endTime) { 186 this.setTableSelection(index); 187 } 188 }); 189 this.panelTable!.recycleDataSource = this.tableDataSource; 190 this.panelTable!.meauseAllRowHeight(this.tableDataSource); 191 this.eventHandler(); 192 this.systemTrace!.slicesList = this.slicesTimeList || []; 193 } 194 195 /** 196 * 修改卡尺颜色事件和移除卡尺的事件处理 197 */ 198 private eventHandler(): void { 199 let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>; 200 this.trClickEvent(tr); 201 202 // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.slicesTimeList数组的第一个对应……,所以i从1开始,在this.slicesTimeList数组中取值时用i-1 203 for (let i = 1; i < tr.length; i++) { 204 // 修改颜色 205 tr[i].querySelector<HTMLInputElement>('#color-input')!.value = this.slicesTimeList[i - 1].color; 206 // 点击色块修改颜色 207 this.trChangeEvent(tr, i); 208 209 // 修改备注 210 tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.slicesTimeList[i - 1].text; 211 // // 点击色块修改颜色 212 tr[i].querySelector('#text-input')?.addEventListener('keyup', (event: unknown) => { 213 if ( 214 // @ts-ignore 215 this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && 216 // @ts-ignore 217 this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime && 218 // @ts-ignore 219 event.code === 'Enter' || event.code === 'NumpadEnter' 220 ) { 221 this.systemTrace!.slicesList = this.slicesTimeList || []; 222 // @ts-ignore 223 this.slicesTimeList[i - 1].text = event?.target.value; 224 document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); 225 226 this.systemTrace?.refreshCanvas(true); 227 } 228 // @ts-ignore 229 event.stopPropagation(); 230 }); 231 232 tr[i].querySelector('#text-input')?.addEventListener('blur', (event: unknown) => { 233 // @ts-ignore 234 (window as unknown).flagInputFocus = false; 235 window.publish(window.SmartEvent.UI.KeyboardEnable, { 236 enable: true, 237 }); 238 if ( 239 // @ts-ignore 240 this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && 241 // @ts-ignore 242 this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime 243 ) { 244 // @ts-ignore 245 this.slicesTimeList[i - 1].text = event?.target.value; 246 document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); 247 this.setTableData(); 248 this.systemTrace?.refreshCanvas(true); 249 } 250 // @ts-ignore 251 event.stopPropagation(); 252 }); 253 this.trFocusEvent(tr, i); 254 this.removeButtonClickEvent(tr, i); 255 } 256 } 257 258 private trChangeEvent(tr: NodeListOf<HTMLDivElement>, i: number): void { 259 tr[i].querySelector<HTMLInputElement>('#color-input')?.addEventListener('change', (event: unknown) => { 260 if ( 261 // @ts-ignore 262 this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && 263 // @ts-ignore 264 this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime 265 ) { 266 this.systemTrace!.slicesList = this.slicesTimeList || []; 267 // @ts-ignore 268 this.slicesTimeList[i - 1].color = event?.target.value; 269 document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); 270 // 卡尺颜色改变时,重绘泳道图 271 this.systemTrace?.refreshCanvas(true); 272 } 273 // @ts-ignore 274 event.stopPropagation(); 275 }); 276 } 277 278 private trFocusEvent(tr: NodeListOf<HTMLDivElement>, i: number): void { 279 tr[i].querySelector('#text-input')?.addEventListener('focus', (event: unknown) => { 280 // @ts-ignore 281 (window as unknown).flagInputFocus = true; 282 window.publish(window.SmartEvent.UI.KeyboardEnable, { 283 enable: false, 284 }); 285 let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>; 286 // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.flagList数组的第一个对应……,所以i从1开始,在this.flagList数组中取值时用i-1 287 for (let i = 1; i < tr.length; i++) { 288 tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.slicesTimeList[i - 1].text; 289 } 290 }); 291 } 292 293 private trClickEvent(tr: NodeListOf<HTMLDivElement>): void { 294 tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: unknown) => { 295 this.systemTrace!.slicesList = []; 296 let slicesTimeList = [...this.slicesTimeList]; 297 for (let i = 0; i < slicesTimeList.length; i++) { 298 slicesTimeList[i].hidden = true; 299 document.dispatchEvent(new CustomEvent('slices-change', { detail: slicesTimeList[i] })); 300 } 301 this.slicesTimeList = []; 302 return; 303 }); 304 } 305 306 private removeButtonClickEvent(tr: NodeListOf<HTMLDivElement>, i: number): void { 307 // 点击remove按钮移除 308 tr[i]!.querySelector('.remove')?.addEventListener('click', (event: unknown) => { 309 if ( 310 // @ts-ignore 311 this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && 312 // @ts-ignore 313 this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime 314 ) { 315 let slicesTimeList = [...this.slicesTimeList]; 316 this.slicesTimeList[i - 1].hidden = true; 317 slicesTimeList.splice(i - 1, 1); 318 this.systemTrace!.slicesList = slicesTimeList || []; 319 document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); 320 this.slicesTimeList = slicesTimeList; 321 // 移除时更新表格内容 322 this.setTableData(); 323 } 324 // @ts-ignore 325 event.stopPropagation(); 326 }); 327 } 328 329 /** 330 * 修改表格指定行数的背景颜色 331 * @param line 要改变的表格行数 332 */ 333 public setTableSelection(line: unknown): void { 334 // @ts-ignore 335 this.tableDataSource[line].isSelected = true; 336 // @ts-ignore 337 this.panelTable?.clearAllSelection(this.tableDataSource[line]); 338 // @ts-ignore 339 this.panelTable?.setCurrentSelection(this.tableDataSource[line]); 340 } 341 342 initHtml(): string { 343 return TabPaneCurrentHtml; 344 } 345} 346