• 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 {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