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 let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>; 106 // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.slicesTimeList数组的第一个对应……,所以i从1开始,在this.slicesTimeList数组中取值时用i-1 107 for (let i = 1; i < tr.length; i++) { 108 tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.slicesTimeList[i - 1].text; 109 } 110 // @ts-ignore 111 event.stopPropagation(); 112 }, 113 { capture: true } 114 ); 115 } 116 117 public setCurrentSlicesTime(slicesTime: SlicesTime): void { 118 this.slicesTimeList = this.systemTrace?.timerShaftEL!.sportRuler?.slicesTimeList || []; 119 this.slicesTime = slicesTime; 120 // 判断当前传入的卡尺是否已经存在 121 let findSlicesTime = this.slicesTimeList.find( 122 (it) => it.startTime === slicesTime.startTime && it.endTime === slicesTime.endTime 123 ); 124 // m键生成的临时卡尺只能同时出现最后一个,所以将永久卡尺过滤出来,并加上最后一个临时卡尺 125 if (this.slicesTime.type === StType.TEMP) { 126 this.slicesTimeList = this.slicesTimeList.filter( 127 (item: SlicesTime) => 128 item.type === StType.PERM || 129 (item.type === StType.TEMP && 130 item.startTime === this.slicesTime!.startTime && 131 item.endTime === this.slicesTime!.endTime) 132 ); 133 } 134 // 如果this.slicesTimeList为空,或者没有在同一位置绘制过,就将当前的框选的范围画上线 135 if (!findSlicesTime || this.slicesTimeList.length === 0) { 136 this.slicesTimeList!.push(this.slicesTime); 137 } 138 this.setTableData(); 139 } 140 141 /** 142 * 根据this.slicesTimeList设置表格数据 143 */ 144 private setTableData(): void { 145 this.tableDataSource = []; 146 // 按照开始时间进行排序,保证泳道图上的卡尺(shift+m键)和表格的顺序一致 147 this.slicesTimeList.sort(function (a, b) { 148 return a.startTime - b.startTime; 149 }); 150 for (let slice of this.slicesTimeList) { 151 let btn = document.createElement('button'); 152 btn.className = 'remove'; 153 let color = document.createElement('input'); 154 color.type = 'color'; 155 let text = document.createElement('input'); 156 text.type = 'text'; 157 color!.value = slice.color; 158 text.value = slice.text; 159 let sliceData = new MarkStruct( 160 btn, 161 color.value, 162 text.value, 163 getTimeString(slice.startTime), 164 slice.startTime, 165 getTimeString(slice.endTime), 166 slice.endTime 167 ); 168 slice.selected === true ? (sliceData.isSelected = true) : (sliceData.isSelected = false); 169 this.tableDataSource.push(sliceData); 170 } 171 // 表格第一行只添加一个RemoveAll按钮 172 let removeAll = document.createElement('button'); 173 removeAll.className = 'removeAll'; 174 removeAll.innerHTML = 'RemoveAll'; 175 let sliceData = new MarkStruct(removeAll); 176 this.tableDataSource.unshift(sliceData); 177 178 // 当前点击了哪个卡尺,就将对应的表格中的那行的背景变色 179 this.tableDataSource.forEach((data, index) => { 180 // @ts-ignore 181 if (data.startTime === this.slicesTime?.startTime && data.endTime === this.slicesTime?.endTime) { 182 this.setTableSelection(index); 183 } 184 }); 185 this.panelTable!.recycleDataSource = this.tableDataSource; 186 this.panelTable!.meauseAllRowHeight(this.tableDataSource); 187 this.eventHandler(); 188 this.systemTrace!.slicesList = this.slicesTimeList || []; 189 } 190 191 /** 192 * 修改卡尺颜色事件和移除卡尺的事件处理 193 */ 194 private eventHandler(): void { 195 let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>; 196 this.trClickEvent(tr); 197 198 // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.slicesTimeList数组的第一个对应……,所以i从1开始,在this.slicesTimeList数组中取值时用i-1 199 for (let i = 1; i < tr.length; i++) { 200 // 修改颜色 201 tr[i].querySelector<HTMLInputElement>('#color-input')!.value = this.slicesTimeList[i - 1].color; 202 // 点击色块修改颜色 203 this.trChangeEvent(tr, i); 204 205 // 修改备注 206 tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.slicesTimeList[i - 1].text; 207 // // 点击色块修改颜色 208 tr[i].querySelector('#text-input')?.addEventListener('keyup', (event: unknown) => { 209 if ( 210 // @ts-ignore 211 this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && 212 // @ts-ignore 213 this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime && 214 // @ts-ignore 215 event.code === 'Enter' || event.code === 'NumpadEnter' 216 ) { 217 this.systemTrace!.slicesList = this.slicesTimeList || []; 218 // @ts-ignore 219 this.slicesTimeList[i - 1].text = event?.target.value; 220 window.publish(window.SmartEvent.UI.KeyboardEnable, { 221 enable: true, 222 }); 223 document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); 224 document.dispatchEvent(new CustomEvent('remarksFocus-change', { detail: 'remarks-focus' })); 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 document.dispatchEvent(new CustomEvent('remarksFocus-change', { detail: '' })); 248 this.setTableData(); 249 this.systemTrace?.refreshCanvas(true); 250 } 251 // @ts-ignore 252 event.stopPropagation(); 253 }); 254 this.trFocusEvent(tr, i); 255 this.removeButtonClickEvent(tr, i); 256 } 257 } 258 259 private trChangeEvent(tr: NodeListOf<HTMLDivElement>, i: number): void { 260 tr[i].querySelector<HTMLInputElement>('#color-input')?.addEventListener('change', (event: unknown) => { 261 if ( 262 // @ts-ignore 263 this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && 264 // @ts-ignore 265 this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime 266 ) { 267 this.systemTrace!.slicesList = this.slicesTimeList || []; 268 // @ts-ignore 269 this.slicesTimeList[i - 1].color = event?.target.value; 270 document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); 271 // 卡尺颜色改变时,重绘泳道图 272 this.systemTrace?.refreshCanvas(true); 273 } 274 // @ts-ignore 275 event.stopPropagation(); 276 }); 277 } 278 279 private trFocusEvent(tr: NodeListOf<HTMLDivElement>, i: number): void { 280 tr[i].querySelector('#text-input')?.addEventListener('focus', (event: unknown) => { 281 // @ts-ignore 282 (window as unknown).flagInputFocus = true; 283 window.publish(window.SmartEvent.UI.KeyboardEnable, { 284 enable: false, 285 }); 286 let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf<HTMLDivElement>; 287 // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.flagList数组的第一个对应……,所以i从1开始,在this.flagList数组中取值时用i-1 288 for (let i = 1; i < tr.length; i++) { 289 tr[i].querySelector<HTMLInputElement>('#text-input')!.value = this.slicesTimeList[i - 1].text; 290 } 291 }); 292 } 293 294 private trClickEvent(tr: NodeListOf<HTMLDivElement>): void { 295 tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: unknown) => { 296 this.systemTrace!.slicesList = []; 297 let slicesTimeList = [...this.slicesTimeList]; 298 for (let i = 0; i < slicesTimeList.length; i++) { 299 slicesTimeList[i].hidden = true; 300 document.dispatchEvent(new CustomEvent('slices-change', { detail: slicesTimeList[i] })); 301 } 302 this.slicesTimeList = []; 303 return; 304 }); 305 } 306 307 private removeButtonClickEvent(tr: NodeListOf<HTMLDivElement>, i: number): void { 308 // 点击remove按钮移除 309 tr[i]!.querySelector('.remove')?.addEventListener('click', (event: unknown) => { 310 if ( 311 // @ts-ignore 312 this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && 313 // @ts-ignore 314 this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime 315 ) { 316 let slicesTimeList = [...this.slicesTimeList]; 317 this.slicesTimeList[i - 1].hidden = true; 318 slicesTimeList.splice(i - 1, 1); 319 this.systemTrace!.slicesList = slicesTimeList || []; 320 document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); 321 this.slicesTimeList = slicesTimeList; 322 // 移除时更新表格内容 323 this.setTableData(); 324 } 325 // @ts-ignore 326 event.stopPropagation(); 327 }); 328 } 329 330 /** 331 * 修改表格指定行数的背景颜色 332 * @param line 要改变的表格行数 333 */ 334 public setTableSelection(line: unknown): void { 335 // @ts-ignore 336 this.tableDataSource[line].isSelected = true; 337 // @ts-ignore 338 this.panelTable?.clearAllSelection(this.tableDataSource[line]); 339 // @ts-ignore 340 this.panelTable?.setCurrentSelection(this.tableDataSource[line]); 341 } 342 343 initHtml(): string { 344 return TabPaneCurrentHtml; 345 } 346} 347