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 {RangeSelectStruct, TraceRow} from "./TraceRow.js"; 17import {Rect} from "../timer-shaft/Rect.js"; 18import {ns2x, TimerShaftElement} from "../TimerShaftElement.js"; 19import {info} from "../../../../log/Log.js"; 20 21export class RangeSelect { 22 rowsEL: HTMLDivElement | undefined | null; 23 isMouseDown: boolean = false; 24 public rangeTraceRow: Array<TraceRow<any>> | undefined 25 public selectHandler: ((ds: Array<TraceRow<any>>, refreshCheckBox: boolean) => void) | undefined; 26 private startX: number = 0 27 private endX: number = 0; 28 private startY: number = 0 29 private endY: number = 0; 30 private startY2: number = 0 31 private endY2: number = 0; 32 private timerShaftEL: TimerShaftElement | null | undefined; 33 private timerShaftDragEL: HTMLDivElement | null | undefined; 34 private isHover: boolean = false; 35 private movingMark: string = ""; 36 private mark: { startMark: number, endMark: number } = {startMark: 0, endMark: 0} 37 private spacerEL: HTMLDivElement; 38 39 constructor(timerShaftEL: TimerShaftElement | null | undefined) { 40 this.timerShaftEL = timerShaftEL; 41 this.timerShaftDragEL = this.timerShaftEL?.shadowRoot?.querySelector(".total > div:nth-child(1)"); 42 this.spacerEL = this.timerShaftEL?.nextElementSibling! as HTMLDivElement; 43 } 44 45 isInRowsEl(ev: MouseEvent): boolean { 46 return (ev.offsetY > this.timerShaftDragEL!.clientHeight! && 47 ev.offsetY < this.rowsEL!.offsetTop + this.rowsEL!.offsetHeight && 48 ev.offsetX > this.rowsEL!.offsetLeft! && 49 ev.offsetX < this.rowsEL!.offsetLeft + this.rowsEL!.offsetWidth 50 ) 51 } 52 53 isInSpacerEL(ev: MouseEvent): boolean { 54 return (ev.offsetY > this.spacerEL.offsetTop && 55 ev.offsetY < this.spacerEL.offsetTop + this.spacerEL.offsetHeight && 56 ev.offsetX > this.spacerEL.offsetLeft! && 57 ev.offsetX < this.spacerEL.offsetLeft + this.spacerEL.offsetWidth 58 ) 59 } 60 61 mouseDown(ev: MouseEvent) { 62 if (this.isHover) { 63 this.isMouseDown = true; 64 return; 65 } 66 if (this.isInRowsEl(ev)) { 67 this.rangeTraceRow = []; 68 this.isMouseDown = true; 69 TraceRow.rangeSelectObject = undefined; 70 this.startX = ev.offsetX - this.rowsEL!.offsetLeft!; 71 if (this.isInSpacerEL(ev)) { 72 this.startY = 0; 73 this.startY2 = ev.offsetY + 48; 74 } else { 75 this.startY = ev.offsetY - this.rowsEL!.offsetTop!; 76 this.startY2 = this.spacerEL.offsetTop + this.spacerEL.offsetHeight! + 48; 77 } 78 } 79 } 80 81 mouseUp(ev: MouseEvent) { 82 if (this.isInRowsEl(ev) && this.isDrag()) { 83 this.endX = ev.offsetX - this.rowsEL!.offsetLeft!; 84 if (this.isInSpacerEL(ev)) { 85 this.endY = ev.offsetY - this.rowsEL!.clientTop! + this.rowsEL!.offsetTop!; 86 this.endY2 = ev.offsetY + 48; 87 } else { 88 this.endY = ev.offsetY - this.rowsEL!.clientTop! + this.rowsEL!.offsetTop!; 89 this.endY2 = this.spacerEL.offsetTop + this.spacerEL.offsetHeight! + 48; 90 } 91 if (this.selectHandler) { 92 this.selectHandler(this.rangeTraceRow || [], !this.isHover); 93 } 94 } 95 this.isMouseDown = false; 96 } 97 98 isDrag(): boolean { 99 return this.startX != this.endX && (this.startY != this.endY || this.startY2 != this.endY2) 100 } 101 102 isTouchMark(ev: MouseEvent): boolean { 103 let notTimeHeight: boolean = ev.offsetY > (this.timerShaftDragEL!.clientHeight || 0) 104 if (!notTimeHeight) { 105 this.isHover = false; 106 return false 107 } 108 if ((this.rangeTraceRow ? this.rangeTraceRow.length == 0 : false) && !this.isMouseDown) { 109 this.isHover = false; 110 } 111 return notTimeHeight && (this.rangeTraceRow ? this.rangeTraceRow.length > 0 : false) && !this.isMouseDown 112 } 113 114 mouseMove(rows: Array<TraceRow<any>>, ev: MouseEvent) { 115 if (this.isTouchMark(ev) && TraceRow.rangeSelectObject) { 116 info( "isTouchMark"); 117 let markA = ns2x(TraceRow.rangeSelectObject!.startNS!, TraceRow.range!.startNS, TraceRow.range!.endNS, TraceRow.range!.totalNS!, {width: this.timerShaftEL?.canvas?.clientWidth || 0} as Rect); 118 let markB = ns2x(TraceRow.rangeSelectObject!.endNS!, TraceRow.range!.startNS, TraceRow.range!.endNS, TraceRow.range!.totalNS!, {width: this.timerShaftEL?.canvas?.clientWidth || 0} as Rect); 119 this.mark = {startMark: markA, endMark: markB}; 120 let mouseX = ev.offsetX - (this.timerShaftEL?.totalEL?.clientWidth || 0) 121 if ((mouseX > markA - 5 && mouseX < markA + 5)) { 122 this.isHover = true; 123 document.body.style.cursor = "ew-resize" 124 this.movingMark = markA < markB ? "markA" : "markB" 125 } else if (mouseX > markB - 5 && mouseX < markB + 5) { 126 this.isHover = true; 127 document.body.style.cursor = "ew-resize" 128 this.movingMark = markB < markA ? "markA" : "markB" 129 } else { 130 this.isHover = false; 131 } 132 } 133 if (this.isHover && this.isMouseDown) { 134 let rangeSelect: RangeSelectStruct | undefined; 135 this.rangeTraceRow = rows.filter(it => { 136 if (it.rangeSelect) { 137 if (!rangeSelect) { 138 rangeSelect = new RangeSelectStruct(); 139 let mouseX = ev.offsetX - this.rowsEL!.offsetLeft! - (it.canvasContainer?.offsetLeft || 248) 140 let markA = this.movingMark == "markA" ? mouseX : this.mark.startMark; 141 let markB = this.movingMark == "markB" ? mouseX : this.mark.endMark; 142 let startX = markA < markB ? markA : markB 143 let endX = markB < markA ? markA : markB 144 rangeSelect.startX = startX; 145 rangeSelect.endX = endX; 146 rangeSelect.startNS = Math.floor((TraceRow.range!.endNS - TraceRow.range!.startNS) * startX / it.frame.width + TraceRow.range!.startNS!); 147 rangeSelect.endNS = Math.floor((TraceRow.range!.endNS - TraceRow.range!.startNS) * endX / it.frame.width + TraceRow.range!.startNS!); 148 if (rangeSelect.startNS <= TraceRow.range!.startNS) { 149 rangeSelect.startNS = TraceRow.range!.startNS 150 } 151 if (rangeSelect.endNS >= TraceRow.range!.endNS) { 152 rangeSelect.endNS = TraceRow.range!.endNS 153 } 154 } 155 TraceRow.rangeSelectObject = rangeSelect; 156 return true 157 } 158 }) 159 this.timerShaftEL!.sportRuler!.isRangeSelect = (this.rangeTraceRow?.length || 0) > 0; 160 this.timerShaftEL!.sportRuler!.draw(); 161 return; 162 } 163 if (!this.isMouseDown) { 164 this.timerShaftEL!.sportRuler!.isRangeSelect = (this.rangeTraceRow?.length || 0) > 0; 165 this.timerShaftEL!.sportRuler!.draw(); 166 return; 167 } 168 this.endX = ev.offsetX - this.rowsEL!.offsetLeft!; 169 if (this.isInSpacerEL(ev)) { 170 this.endY = 0; 171 this.endY2 = ev.offsetY + 48; 172 } else { 173 this.endY = ev.offsetY - this.rowsEL!.offsetTop!; 174 this.endY2 = this.spacerEL.offsetTop + this.spacerEL.offsetHeight! + 48; 175 } 176 let scrollTop = this.rowsEL?.scrollTop || 0 177 let xMin = this.startX < this.endX ? this.startX : this.endX; 178 let xMax = this.startX > this.endX ? this.startX : this.endX; 179 let yMin = this.startY < this.endY ? this.startY : this.endY; 180 let yMax = this.startY > this.endY ? this.startY : this.endY; 181 let rangeSelect: RangeSelectStruct | undefined; 182 this.rangeTraceRow = rows.filter(it => { 183 let rt: Rect; 184 let canvasOffsetLeft = (it.canvasContainer?.offsetLeft || 0); 185 let canvasOffsetTop = (it.canvasContainer?.offsetTop || 0); 186 if (it.collect) { 187 rt = new Rect(xMin - canvasOffsetLeft, Math.min(this.startY2, this.endY2) - it.offsetTop, xMax - xMin, Math.abs(this.startY2 - this.endY2)); 188 } else { 189 rt = new Rect(xMin - canvasOffsetLeft, yMin - canvasOffsetTop + scrollTop + this.rowsEL!.offsetTop, xMax - xMin, yMax - yMin); 190 } 191 if (Rect.intersect(it.frame, rt)) { 192 if (!rangeSelect) { 193 rangeSelect = new RangeSelectStruct(); 194 let startX = Math.floor(rt.x <= 0 ? 0 : rt.x); 195 let endX = Math.floor((rt.x + rt.width) > it.frame.width ? it.frame.width : (rt.x + rt.width)); 196 rangeSelect.startX = startX; 197 rangeSelect.endX = endX; 198 rangeSelect.startNS = Math.floor((TraceRow.range!.endNS - TraceRow.range!.startNS) * startX / it.frame.width + TraceRow.range!.startNS!); 199 rangeSelect.endNS = Math.floor((TraceRow.range!.endNS - TraceRow.range!.startNS) * endX / it.frame.width + TraceRow.range!.startNS!); 200 } 201 TraceRow.rangeSelectObject = rangeSelect; 202 it.rangeSelect = true; 203 return true 204 } else { 205 it.rangeSelect = false; 206 return false; 207 } 208 }) 209 this.timerShaftEL!.sportRuler!.isRangeSelect = (this.rangeTraceRow?.length || 0) > 0; 210 this.timerShaftEL!.sportRuler!.draw(); 211 } 212} 213