-
diff --git a/ide/src/trace/component/setting/SpWebHdcShell.ts b/ide/src/trace/component/setting/SpWebHdcShell.ts
index 2d659367f509eab6328e983a94eb31b0822eb980..4cf510625cfc0e6c5e0a404d28fc26c095f2766f 100644
--- a/ide/src/trace/component/setting/SpWebHdcShell.ts
+++ b/ide/src/trace/component/setting/SpWebHdcShell.ts
@@ -168,14 +168,17 @@ export class SpWebHdcShell extends BaseElement {
(endY > textLastRowY && endY < textEndY)
) {
index++;
- if (index == 1) {
+ if (index === 1) {
if (depth > 1) {
- selectedText += line.substring(Math.floor((startX - x) / 8)) + (endX < x + w ? '\n' : '');
+ selectedText += line.slice(
+ this.getCurrentLineBackSize(line, startX - x, true)) + (endX < x + w ? '\n' : '');
} else {
- selectedText += `${line.substring(Math.floor((startX - x) / 8), Math.ceil((endX - x) / 8))}\n`;
+ selectedText += `${line.slice(
+ this.getCurrentLineBackSize(line, startX - x, true),
+ this.getCurrentLineBackSize(line, endX - x, false))}\n`;
}
- } else if (index == depth) {
- selectedText += `${line.substring(0, Math.ceil((endX - x) / 8))}\n`;
+ } else if (index === depth) {
+ selectedText += `${line.slice(0, this.getCurrentLineBackSize(line, endX - x, false))}\n`;
} else {
selectedText += `${line}\n`;
}
@@ -229,6 +232,23 @@ export class SpWebHdcShell extends BaseElement {
this.points = {startX: startPointX, startY: startPointY, endX: endPointX, endY: endPointY};
}
+ getCurrentLineBackSize(currentLine: string, maxBackSize: number, isStart: boolean): number{
+ let fillText = '';
+ let strings = currentLine.split('');
+ for (let index = 0; index < strings.length; index++) {
+ let text = strings[index];
+ if (this.shellCanvasCtx!.measureText(fillText).width < maxBackSize &&
+ this.shellCanvasCtx!.measureText(fillText + text).width >= maxBackSize) {
+ if (!isStart) {
+ fillText += text;
+ }
+ break;
+ }
+ fillText += text;
+ }
+ return fillText.length;
+ }
+
reverseSelected(startX: number, startY: number, endX: number, endY: number): void {
//左边界x为SpWebHdcShell.LEFT_OFFSET,右边界为this.shellCanvas!.width
let depth = Math.ceil((startY - endY) / 16);
@@ -257,6 +277,7 @@ export class SpWebHdcShell extends BaseElement {
startPointY = endY;
} else {
this.shellCanvasCtx!.fillRect(SpWebHdcShell.LEFT_OFFSET, startY - index * 16, this.shellCanvas!.width, 16);
+ this.shellCanvasCtx!.textBaseline = 'middle';
}
}
}
@@ -320,7 +341,8 @@ export class SpWebHdcShell extends BaseElement {
textY = SpWebHdcShell.TOP_OFFSET + index * 16;
this.shellCanvasCtx!.fillText(shellStr, SpWebHdcShell.LEFT_OFFSET, textY);
}
- shellStrLength = this.cursorIndex * unitWidth + SpWebHdcShell.LEFT_OFFSET;
+ shellStrLength = this.shellCanvasCtx!.measureText(
+ this.cursorRow.slice(0, this.cursorIndex)).width + SpWebHdcShell.LEFT_OFFSET;
if (scroller) {
if (textY > this.shellDiv!.clientHeight) {
this.shellDiv!.scrollTop = textY - this.shellDiv!.clientHeight + 3;
diff --git a/ide/src/trace/component/trace/TimerShaftElement.ts b/ide/src/trace/component/trace/TimerShaftElement.ts
index 727870754e12fc1a67539240f249c7c403339fcf..45649810e326c90669ff8304dc38911f8030b014 100644
--- a/ide/src/trace/component/trace/TimerShaftElement.ts
+++ b/ide/src/trace/component/trace/TimerShaftElement.ts
@@ -123,7 +123,7 @@ export class TimerShaftElement extends BaseElement {
canvasHeight: number = 0;
_cpuUsage: Array<{ cpu: number; ro: number; rate: number }> = [];
protected timeRuler: TimeRuler | undefined;
- protected rangeRuler: RangeRuler | undefined;
+ protected _rangeRuler: RangeRuler | undefined;
protected _sportRuler: SportRuler | undefined;
private root: HTMLDivElement | undefined | null;
private _totalNS: number = 10_000_000_000;
@@ -138,11 +138,15 @@ export class TimerShaftElement extends BaseElement {
return this._sportRuler;
}
+ get rangeRuler(): RangeRuler | undefined {
+ return this._rangeRuler;
+ }
+
set cpuUsage(value: Array<{ cpu: number; ro: number; rate: number }>) {
info('set cpuUsage values :', value);
this._cpuUsage = value;
- if (this.rangeRuler) {
- this.rangeRuler.cpuUsage = this._cpuUsage;
+ if (this._rangeRuler) {
+ this._rangeRuler.cpuUsage = this._cpuUsage;
}
}
@@ -154,7 +158,7 @@ export class TimerShaftElement extends BaseElement {
info('set totalNS values :', value);
this._totalNS = value;
if (this.timeRuler) this.timeRuler.totalNS = value;
- if (this.rangeRuler) this.rangeRuler.range.totalNS = value;
+ if (this._rangeRuler) this._rangeRuler.range.totalNS = value;
if (this.timeTotalEL) this.timeTotalEL.textContent = `${ns2s(value)}`;
requestAnimationFrame(() => this.render());
}
@@ -176,7 +180,7 @@ export class TimerShaftElement extends BaseElement {
}
isScaling(): boolean {
- return this.rangeRuler?.isPress || false;
+ return this._rangeRuler?.isPress || false;
}
reset(): void {
@@ -184,17 +188,17 @@ export class TimerShaftElement extends BaseElement {
this.totalNS = 10_000_000_000;
this.startNS = 0;
this.endNS = 10_000_000_000;
- if (this.rangeRuler) {
- this.rangeRuler.drawMark = false;
- this.rangeRuler.range.totalNS = this.totalNS;
- this.rangeRuler.markAObj.frame.x = 0;
- this.rangeRuler.markBObj.frame.x = this.rangeRuler.frame.width;
- this.rangeRuler.cpuUsage = [];
+ if (this._rangeRuler) {
+ this._rangeRuler.drawMark = false;
+ this._rangeRuler.range.totalNS = this.totalNS;
+ this._rangeRuler.markAObj.frame.x = 0;
+ this._rangeRuler.markBObj.frame.x = this._rangeRuler.frame.width;
+ this._rangeRuler.cpuUsage = [];
this.sportRuler!.flagList.length = 0;
this.sportRuler!.slicesTimeList.length = 0;
this.selectionList.length = 0;
this.selectionMap.clear();
- this.rangeRuler.rangeRect = new Rect(0, 25, this.canvas?.clientWidth || 0, 75);
+ this._rangeRuler.rangeRect = new Rect(0, 25, this.canvas?.clientWidth || 0, 75);
this.sportRuler!.isRangeSelect = false;
this.setSlicesMark();
}
@@ -214,7 +218,7 @@ export class TimerShaftElement extends BaseElement {
}
getRangeRuler() {
- return this.rangeRuler;
+ return this._rangeRuler;
}
connectedCallback() {
@@ -228,8 +232,8 @@ export class TimerShaftElement extends BaseElement {
}
}
if (this.timeTotalEL) this.timeTotalEL.textContent = ns2s(this._totalNS);
- if (this.timeOffsetEL && this.rangeRuler)
- this.timeOffsetEL.textContent = ns2UnitS(this._startNS, this.rangeRuler.getScale());
+ if (this.timeOffsetEL && this._rangeRuler)
+ this.timeOffsetEL.textContent = ns2UnitS(this._startNS, this._rangeRuler.getScale());
const width = this.canvas?.clientWidth || 0;
const height = this.canvas?.clientHeight || 0;
if (!this.timeRuler) {
@@ -250,8 +254,8 @@ export class TimerShaftElement extends BaseElement {
}
);
}
- if (!this.rangeRuler) {
- this.rangeRuler = new RangeRuler(
+ if (!this._rangeRuler) {
+ this._rangeRuler = new RangeRuler(
this,
new Rect(0, 25, width, 75),
{
@@ -274,8 +278,8 @@ export class TimerShaftElement extends BaseElement {
if (this._sportRuler) {
this._sportRuler.range = a;
}
- if (this.timeOffsetEL && this.rangeRuler) {
- this.timeOffsetEL.textContent = ns2UnitS(a.startNS, this.rangeRuler.getScale());
+ if (this.timeOffsetEL && this._rangeRuler) {
+ this.timeOffsetEL.textContent = ns2UnitS(a.startNS, this._rangeRuler.getScale());
}
if (this.loadComplete) {
this.rangeChangeHandler?.(a);
@@ -283,18 +287,18 @@ export class TimerShaftElement extends BaseElement {
}
);
}
- this.rangeRuler.frame.width = width;
+ this._rangeRuler.frame.width = width;
this._sportRuler.frame.width = width;
this.timeRuler.frame.width = width;
}
setRangeNS(startNS: number, endNS: number) {
info('set startNS values :' + startNS + 'endNS values : ' + endNS);
- this.rangeRuler?.setRangeNS(startNS, endNS);
+ this._rangeRuler?.setRangeNS(startNS, endNS);
}
getRange(): TimeRange | undefined {
- return this.rangeRuler?.getRange();
+ return this._rangeRuler?.getRange();
}
updateWidth(width: number) {
@@ -309,32 +313,33 @@ export class TimerShaftElement extends BaseElement {
this.canvas!.style.height = oldHeight + 'px';
this.ctx?.scale(this.dpr, this.dpr);
this.ctx?.translate(0, 0);
- this.rangeRuler!.frame.width = oldWidth;
+ this._rangeRuler!.frame.width = oldWidth;
this._sportRuler!.frame.width = oldWidth;
this.timeRuler!.frame.width = oldWidth;
- this.rangeRuler?.fillX();
+ this._rangeRuler?.fillX();
this.render();
}
documentOnMouseDown = (ev: MouseEvent) => {
if ((window as any).isSheetMove) return;
- this.rangeRuler?.mouseDown(ev);
+ this._rangeRuler?.mouseDown(ev);
};
documentOnMouseUp = (ev: MouseEvent) => {
if ((window as any).isSheetMove) return;
- this.rangeRuler?.mouseUp(ev);
+ this._rangeRuler?.mouseUp(ev);
this.sportRuler?.mouseUp(ev);
};
documentOnMouseMove = (ev: MouseEvent, trace: SpSystemTrace) => {
trace.style.cursor = 'default';
- let x = ev.offsetX - (this.canvas?.offsetLeft || 0); // 鼠标的x轴坐标
+ let x = ev.offsetX - (this.canvas?.offsetLeft || 0); // 鼠标的x轴坐标
let y = ev.offsetY; // 鼠标的y轴坐标
let findSlicestime = this.sportRuler?.findSlicesTime(x, y); // 查找帽子
- if (!findSlicestime) { // 如果在该位置没有找到一个“帽子”,则可以显示一个旗子。
+ if (!findSlicestime) {
+ // 如果在该位置没有找到一个“帽子”,则可以显示一个旗子。
this.sportRuler?.showHoverFlag();
- this.rangeRuler?.mouseMove(ev, trace);
+ this._rangeRuler?.mouseMove(ev, trace);
if (this.sportRuler?.edgeDetection(ev)) {
this.sportRuler?.mouseMove(ev);
} else {
@@ -342,26 +347,26 @@ export class TimerShaftElement extends BaseElement {
}
} else {
this.sportRuler?.clearHoverFlag();
- this.sportRuler?.modifyFlagList(null);//重新绘制旗子,清除hover flag
+ this.sportRuler?.modifyFlagList(null); //重新绘制旗子,清除hover flag
}
};
documentOnMouseOut = (ev: MouseEvent) => {
- this.rangeRuler?.mouseOut(ev);
+ this._rangeRuler?.mouseOut(ev);
this.sportRuler?.mouseOut(ev);
};
documentOnKeyPress = (ev: KeyboardEvent, currentSlicesTime?: CurrentSlicesTime) => {
if ((window as any).isSheetMove) return;
if ((window as any).flagInputFocus) return;
- this.rangeRuler?.keyPress(ev, currentSlicesTime);
+ this._rangeRuler?.keyPress(ev, currentSlicesTime);
this.sportRuler?.clearHoverFlag();
};
documentOnKeyUp = (ev: KeyboardEvent) => {
if ((window as any).isSheetMove) return;
if ((window as any).flagInputFocus) return;
- this.rangeRuler?.keyUp(ev);
+ this._rangeRuler?.keyUp(ev);
};
disconnectedCallback() {}
@@ -378,7 +383,7 @@ export class TimerShaftElement extends BaseElement {
this.ctx.fillStyle = 'transparent';
this.ctx?.fillRect(0, 0, this.canvas?.width || 0, this.canvas?.height || 0);
this.timeRuler?.draw();
- this.rangeRuler?.draw();
+ this._rangeRuler?.draw();
this._sportRuler?.draw();
} else {
procedurePool.submitWithName(
@@ -415,15 +420,15 @@ export class TimerShaftElement extends BaseElement {
this._sportRuler?.modifySicesTimeList(slicestime);
}
cancelPressFrame() {
- this.rangeRuler?.cancelPressFrame();
+ this._rangeRuler?.cancelPressFrame();
}
cancelUpFrame() {
- this.rangeRuler?.cancelUpFrame();
+ this._rangeRuler?.cancelUpFrame();
}
stopWASD(ev: any) {
- this.rangeRuler?.keyUp(ev);
+ this._rangeRuler?.keyUp(ev);
}
drawTriangle(time: number, type: string) {
@@ -455,7 +460,6 @@ export class TimerShaftElement extends BaseElement {
return sliceTime;
}
-
displayCollect(showCollect: boolean) {
if (showCollect) {
this.collecBtn!.style.display = 'flex';
diff --git a/ide/src/trace/component/trace/base/ColorUtils.ts b/ide/src/trace/component/trace/base/ColorUtils.ts
index 74e594709f4bd086889a312b42b9bbf8bb6bce2f..fe7cea2de47ea7885eb7efcd099002c1545d941f 100644
--- a/ide/src/trace/component/trace/base/ColorUtils.ts
+++ b/ide/src/trace/component/trace/base/ColorUtils.ts
@@ -13,12 +13,34 @@
* limitations under the License.
*/
-import {CpuStruct} from '../../../database/ui-worker/ProcedureWorkerCPU.js';
+import { CpuStruct } from '../../../database/ui-worker/ProcedureWorkerCPU.js';
export class ColorUtils {
public static GREY_COLOR: string = '#f0f0f0';
public static FUNC_COLOR_A: Array
= [
+ '#8770D3',
+ '#A37775',
+ '#0CBDD4',
+ '#7DA6F4',
+ '#A56DF5',
+ '#E86B6A',
+ '#69D3E5',
+ '#998FE6',
+ '#E3AA7D',
+ '#76D1C0',
+ '#99C47C',
+ '#DC8077',
+ '#36BAA4',
+ '#A1CD94',
+ '#E68C43',
+ '#66C7BA',
+ '#B1CDF1',
+ '#E7B75D',
+ '#93D090',
+ '#ADB7DB',
+ ];
+ public static FUNC_COLOR_B: Array = [
'#40b3e7',
'#23b0e7',
'#8d9171',
@@ -26,6 +48,9 @@ export class ColorUtils {
'#7a9160',
'#9fafc4',
'#8a8a8b',
+ '#8983B5',
+ '#78aec2',
+ '#4ca694',
'#e05b52',
'#9bb87a',
'#ebc247',
@@ -33,23 +58,9 @@ export class ColorUtils {
'#a16a40',
'#a94eb9',
'#aa4fba',
- ];
- public static FUNC_COLOR_B: Array = [
- '#9785D3',
- '#A27F7E',
- '#00bdd6',
- '#94B5F4',
- '#B282F6',
- '#E97978',
- '#7AD7E6',
- '#A1C38A',
- '#DB8E86',
- '#42B7A4',
- '#AACEA0',
- '#E69553',
- '#7EC6BB',
- '#8d9171',
-
+ '#B9A683',
+ '#789876',
+ '#8091D0',
];
public static ANIMATION_COLOR: Array = [
@@ -62,7 +73,7 @@ export class ColorUtils {
'#BFEBE5',
'#0A59F7',
'#25ACF5',
- '#FFFFFF'
+ '#FFFFFF',
];
public static JANK_COLOR: Array = [
@@ -194,3 +205,99 @@ export class ColorUtils {
}
}
}
+export function interpolateColorBrightness(colorHex: string, percentage: number): number[] {
+ const color = hexToRgb(colorHex);
+ if (color.length === 0) {
+ return [];
+ }
+ const [h, s, l] = rgbToHsl(color[0] / 255, color[1] / 255, color[2] / 255);
+
+ // 根据百分比计算亮度插值
+ const interpolatedL = 1 - percentage * 0.75; // 百分比越高,亮度越低
+
+ // 将插值后的亮度值与原始的色相和饱和度值组合
+ const interpolatedColor = hslToRgb(h, s, interpolatedL);
+ const interpolatedColorScaled = interpolatedColor.map((val) => Math.round(val * 255));
+
+ return interpolatedColorScaled;
+}
+
+function rgbToHsl(r: number, g: number, b: number): number[] {
+ const max = Math.max(r, g, b);
+ const min = Math.min(r, g, b);
+ let h = 0,
+ s = 0,
+ l = (max + min) / 2;
+
+ if (max === min) {
+ h = s = 0; // achromatic
+ } else {
+ const d = max - min;
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ switch (max) {
+ case r:
+ h = (g - b) / d + (g < b ? 6 : 0);
+ break;
+ case g:
+ h = (b - r) / d + 2;
+ break;
+ case b:
+ h = (r - g) / d + 4;
+ break;
+ }
+ h /= 6;
+ }
+
+ return [h, s, l];
+}
+
+function hexToRgb(colorHex: string): number[] {
+ // 16进制颜色值
+ const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
+ let color = colorHex.toLowerCase();
+ if (reg.test(color)) {
+ // 如果只有三位的值,需变成六位,如:#fff => #ffffff
+ if (color.length === 4) {
+ let colorNew = '#';
+ for (let i = 1; i < 4; i += 1) {
+ colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
+ }
+ color = colorNew;
+ }
+ // 处理六位的颜色值,转为RGB
+ let rgb = [];
+ for (let i = 1; i < 7; i += 2) {
+ rgb.push(parseInt('0x' + color.slice(i, i + 2)));
+ }
+ return rgb;
+ }
+ return [];
+}
+
+function hslToRgb(h: number, s: number, l: number): number[] {
+ let r = 0,
+ g = 0,
+ b = 0;
+
+ if (s === 0) {
+ r = g = b = l; // achromatic
+ } else {
+ const hue2rgb = (p: number, q: number, t: number) => {
+ if (t < 0) t += 1;
+ if (t > 1) t -= 1;
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
+ if (t < 1 / 2) return q;
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+ return p;
+ };
+
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ const p = 2 * l - q;
+
+ r = hue2rgb(p, q, h + 1 / 3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1 / 3);
+ }
+
+ return [r, g, b];
+}
diff --git a/ide/src/trace/component/trace/base/CustomThemeColor.ts b/ide/src/trace/component/trace/base/CustomThemeColor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4c882f97ccdb7eeafbc24b69f221f9d398f1bced
--- /dev/null
+++ b/ide/src/trace/component/trace/base/CustomThemeColor.ts
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { BaseElement, element } from '../../../../base-ui/BaseElement.js';
+import { ColorUtils } from './ColorUtils.js';
+import { LitRadioBox } from '../../../../base-ui/radiobox/LitRadioBox.js';
+import { SpApplication } from '../../../SpApplication.js';
+
+@element('custom-theme-color')
+export class CustomThemeColor extends BaseElement {
+ private application: SpApplication | undefined | null;
+ private radios: NodeListOf | undefined | null;
+ private colorsArray: Array = [];
+ private colorsEl: HTMLDivElement | undefined | null;
+ private theme: Theme = Theme.LIGHT;
+
+ static get observedAttributes(): string[] {
+ return ['mode'];
+ }
+
+ init(): void {
+ window.localStorage.getItem('Theme') === 'light' ? (this.theme = Theme.LIGHT) : (this.theme = Theme.DARK);
+ if (window.localStorage.getItem('Theme') === 'light' || !window.localStorage.getItem('Theme')) {
+ this.theme = Theme.LIGHT;
+ } else {
+ this.theme = Theme.DARK;
+ }
+ this.application!.changeTheme(this.theme);
+ this.setRadioChecked(this.theme);
+ }
+
+ /**
+ * 更新色板
+ * @param colorsEl 色板的父元素
+ */
+ createColorsEl(colorsEl: HTMLDivElement) {
+ for (let i = 0; i < this.colorsArray!.length; i++) {
+ let div = document.createElement('div');
+ div.className = 'color-wrap';
+ let input = document.createElement('input');
+ input.type = 'color';
+ input.className = 'color';
+ input.value = this.colorsArray![i];
+ div.appendChild(input);
+ colorsEl?.appendChild(div);
+ input.addEventListener('change', (evt: any) => {
+ input.value = evt?.target.value;
+ this.colorsArray![i] = evt?.target.value;
+ });
+ }
+ }
+
+ /**
+ * 根据传入的主题改变color setting页面的单选框状态,更新颜色数组
+ * @param theme 主题模式
+ */
+ setRadioChecked(theme: Theme) {
+ for (let i = 0; i < this.radios!.length; i++) {
+ if (this.radios![i].innerHTML === theme) {
+ this.radios![i].setAttribute('checked', '');
+ if (theme === Theme.LIGHT) {
+ this.colorsArray =
+ window.localStorage.getItem('LightThemeColors') === null
+ ? [...ColorUtils.FUNC_COLOR_A]
+ : JSON.parse(window.localStorage.getItem('LightThemeColors')!);
+ } else {
+ this.colorsArray =
+ window.localStorage.getItem('DarkThemeColors') === null
+ ? [...ColorUtils.FUNC_COLOR_B]
+ : JSON.parse(window.localStorage.getItem('DarkThemeColors')!);
+ }
+ } else {
+ this.radios![i].removeAttribute('checked');
+ }
+ }
+ this.colorsEl!.innerHTML = '';
+ this.createColorsEl(this.colorsEl!);
+ }
+
+ initElements(): void {
+ this.radios = this.shadowRoot?.querySelectorAll('.litRadio');
+ this.colorsEl = this.shadowRoot?.querySelector('.colors') as HTMLDivElement;
+ this.application = document.querySelector('body > sp-application') as SpApplication;
+ let close = this.shadowRoot?.querySelector('.page-close');
+ if (this.radios) {
+ for (let i = 0; i < this.radios.length; i++) {
+ this.radios![i].shadowRoot!.querySelector('.selected')!.classList.add('blue');
+ this.radios[i].addEventListener('click', (evt) => {
+ // 点击颜色模式的单选框,色板切换
+ if (this.radios![i].innerHTML === Theme.LIGHT) {
+ if (this.radios![i].getAttribute('checked') === null) {
+ this.colorsArray =
+ window.localStorage.getItem('LightThemeColors') === null
+ ? [...ColorUtils.FUNC_COLOR_A]
+ : JSON.parse(window.localStorage.getItem('LightThemeColors')!);
+ this.theme = Theme.LIGHT;
+ } else {
+ return;
+ }
+ } else if (this.radios![i].innerHTML === Theme.DARK) {
+ if (this.radios![i].getAttribute('checked') === null) {
+ this.colorsArray =
+ window.localStorage.getItem('DarkThemeColors') === null
+ ? [...ColorUtils.FUNC_COLOR_B]
+ : JSON.parse(window.localStorage.getItem('DarkThemeColors')!);
+ this.theme = Theme.DARK;
+ } else {
+ return;
+ }
+ }
+ this.colorsEl!.innerHTML = '';
+ this.createColorsEl(this.colorsEl!);
+ this.confirmOPerate();
+ });
+ }
+ }
+
+ close!.addEventListener('click', (ev) => {
+ if (this.application!.hasAttribute('custom-color')) {
+ this.application!.removeAttribute('custom-color');
+ }
+ this.cancelOperate();
+ });
+ let resetBtn = this.shadowRoot?.querySelector('#reset');
+ let previewBtn = this.shadowRoot?.querySelector('#preview');
+ let confirmBtn = this.shadowRoot?.querySelector('#confirm');
+
+ resetBtn?.addEventListener('click', () => {
+ if (this.theme === Theme.LIGHT) {
+ window.localStorage.setItem('LightThemeColors', JSON.stringify(ColorUtils.FUNC_COLOR_A));
+ } else {
+ window.localStorage.setItem('DarkThemeColors', JSON.stringify(ColorUtils.FUNC_COLOR_B));
+ }
+ this.application!.changeTheme(this.theme);
+ });
+
+ previewBtn?.addEventListener('click', () => {
+ this.application!.changeTheme(this.theme, [...this.colorsArray]);
+ });
+
+ confirmBtn?.addEventListener('click', () => {
+ this.confirmOPerate();
+ });
+ }
+
+ confirmOPerate() {
+ window.localStorage.setItem('Theme', this.theme);
+ if (this.theme === Theme.LIGHT) {
+ window.localStorage.setItem('LightThemeColors', JSON.stringify([...this.colorsArray]));
+ } else {
+ window.localStorage.setItem('DarkThemeColors', JSON.stringify([...this.colorsArray]));
+ }
+ this.application!.changeTheme(this.theme);
+ this.setRadioChecked(this.theme);
+ }
+
+ cancelOperate() {
+ if (window.localStorage.getItem('Theme') === 'light' || !window.localStorage.getItem('Theme')) {
+ this.theme = Theme.LIGHT;
+ this.colorsArray =
+ window.localStorage.getItem('LightThemeColors') === null
+ ? [...ColorUtils.FUNC_COLOR_A]
+ : JSON.parse(window.localStorage.getItem('LightThemeColors')!);
+ } else if (window.localStorage.getItem('Theme') === 'dark') {
+ this.theme = Theme.DARK;
+ this.colorsArray =
+ window.localStorage.getItem('DarkThemeColors') === null
+ ? [...ColorUtils.FUNC_COLOR_B]
+ : JSON.parse(window.localStorage.getItem('DarkThemeColors')!);
+ }
+ this.application!.changeTheme(this.theme);
+ // 恢复颜色模式单选框checked状态
+ this.setRadioChecked(this.theme);
+ }
+
+ connectedCallback(): void {}
+
+ initHtml(): string {
+ return `
+
+
+
+ Color Setting
+
+
+
+
+ Appearance
+ ${Theme.LIGHT}
+ ${Theme.DARK}
+
+
+ Color Customization
+ Please customize colors according to your preferences
+
+
+
+
+
+
+
+
+
+
+ `;
+ }
+
+ attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
+ if (name === 'mode' && newValue === '') {
+ this.init();
+ }
+ }
+}
+export enum Theme {
+ LIGHT = 'light',
+ DARK = 'dark',
+}
diff --git a/ide/src/trace/component/trace/base/TraceRowConfig.ts b/ide/src/trace/component/trace/base/TraceRowConfig.ts
index c6f0b4f43d9acfdb61035e3b428983fb7030c7f0..d9cd7a67a4f62718e7a7444cc66e856e606c56ea 100644
--- a/ide/src/trace/component/trace/base/TraceRowConfig.ts
+++ b/ide/src/trace/component/trace/base/TraceRowConfig.ts
@@ -46,16 +46,26 @@ export class TraceRowConfig extends BaseElement {
}
init(): void {
- let sceneList = ['FrameTimeline', 'Task Pool', 'Animation Effect', 'Ark Ts', 'AppStartup'];
+ let sceneList = [
+ 'FrameTimeline',
+ 'TaskPool',
+ 'AnimationEffect',
+ 'AppStartup',
+ 'HiSysEvent',
+ 'ProcessMemory',
+ 'ArkTs',
+ 'NativeMemory',
+ 'HiPerf',
+ 'HiEBpf',
+ ];
this.selectTypeList = [];
this.sceneTable!.innerHTML = '';
this.chartTable!.innerHTML = '';
this.inputElement!.value = '';
this.spSystemTrace = this.parentElement!.querySelector('sp-system-trace');
- this.traceRowList =
- this.spSystemTrace!.shadowRoot?.querySelector('div[class=rows-pane]')!.querySelectorAll>(
- 'trace-row[row-parent-id=\'\']'
- );
+ this.traceRowList = this.spSystemTrace!.shadowRoot?.querySelector('div[class=rows-pane]')!.querySelectorAll<
+ TraceRow
+ >("trace-row[row-parent-id='']");
let allowSceneList: Array = [];
TraceRowConfig.allTraceRowList.push(...this.traceRowList!);
this.traceRowList!.forEach((traceRow: TraceRow) => {
diff --git a/ide/src/trace/component/trace/search/Search.ts b/ide/src/trace/component/trace/search/Search.ts
index 677f9ed6b6d5d6e8cb00934d61281c1c77a9dc03..8846c4151b0f68b10103428085e27969b2e0eb4c 100644
--- a/ide/src/trace/component/trace/search/Search.ts
+++ b/ide/src/trace/component/trace/search/Search.ts
@@ -15,6 +15,8 @@
import { BaseElement, element } from '../../../../base-ui/BaseElement.js';
+const LOCAL_STORAGE_SEARCH_KEY = 'search_key';
+
@element('lit-search')
export class LitSearch extends BaseElement {
valueChangeHandler: ((str: string) => void) | undefined | null;
@@ -24,6 +26,11 @@ export class LitSearch extends BaseElement {
private _list: Array = [];
private totalEL: HTMLSpanElement | null | undefined;
private indexEL: HTMLSpanElement | null | undefined;
+ private searchHistoryListEL: HTMLUListElement | null | undefined;
+ private historyMaxCount = 100;
+ private lastSearch = '';
+ private searchList: Array = [];
+ private searchELList: Array = [];
get list(): Array {
return this._list;
@@ -52,7 +59,12 @@ export class LitSearch extends BaseElement {
}
set total(value: number) {
- value > 0 ? this.setAttribute('show-search-info', '') : this.removeAttribute('show-search-info');
+ if (value > 0) {
+ this.setAttribute('show-search-info', '');
+ this.updateSearchList(this.search!.value);
+ } else {
+ this.removeAttribute('show-search-info');
+ }
this._total = value;
this.totalEL!.textContent = value.toString();
}
@@ -66,6 +78,7 @@ export class LitSearch extends BaseElement {
this.setAttribute('isLoading', '');
} else {
this.removeAttribute('isLoading');
+ window.localStorage.setItem(LOCAL_STORAGE_SEARCH_KEY, '');
}
}
@@ -123,57 +136,104 @@ export class LitSearch extends BaseElement {
this.search?.blur();
}
+ updateSearchList(searchStr: string | null) {
+ if (searchStr === null || searchStr.length === 0 || searchStr.trim().length === 0) {
+ return;
+ }
+ if (this.lastSearch === searchStr) {
+ return;
+ }
+ this.lastSearch = searchStr;
+ let searchInfo = this.searchList.find(searchInfo => searchInfo.searchContent === searchStr);
+ if (searchInfo != undefined) {
+ searchInfo.useCount += 1;
+ } else {
+ this.searchList.push({searchContent: searchStr, useCount: 1});
+ }
+ }
+
+ getSearchHistory(): Array {
+ let searchString = window.localStorage.getItem(LOCAL_STORAGE_SEARCH_KEY);
+ if (searchString) {
+ let searHistory = JSON.parse(searchString);
+ if (Array.isArray(searHistory)) {
+ this.searchList = searHistory;
+ return searHistory;
+ }
+ }
+ return [];
+ }
+
+ private searchFocusListener() {
+ if (!this.search?.hasAttribute('readonly')) {
+ this.showSearchHistoryList();
+ }
+ this.dispatchEvent(
+ new CustomEvent('focus', {
+ detail: {
+ value: this.search!.value,
+ },
+ })
+ );
+ }
+
+ private searchBlurListener() {
+ this.dispatchEvent(
+ new CustomEvent('blur', {
+ detail: {
+ value: this.search!.value,
+ },
+ })
+ );
+ setTimeout(() => {
+ this.hideSearchHistoryList();
+ }, 200);
+ }
+
+ private searchKeyupListener(e: KeyboardEvent) {
+ if (e.code == 'Enter') {
+ if (e.shiftKey) {
+ this.dispatchEvent(
+ new CustomEvent('previous-data', {
+ detail: {
+ value: this.search!.value,
+ },
+ composed: false,
+ })
+ );
+ } else {
+ this.dispatchEvent(
+ new CustomEvent('next-data', {
+ detail: {
+ value: this.search!.value,
+ },
+ composed: false,
+ })
+ );
+ }
+ } else {
+ this.updateSearchHistoryList(this.search!.value);
+ this.valueChangeHandler?.(this.search!.value);
+ }
+ e.stopPropagation();
+ }
+
initElements(): void {
this.search = this.shadowRoot!.querySelector('input');
this.totalEL = this.shadowRoot!.querySelector('#total');
this.indexEL = this.shadowRoot!.querySelector('#index');
- this.search!.addEventListener('focus', (e) => {
- this.dispatchEvent(
- new CustomEvent('focus', {
- detail: {
- value: this.search!.value,
- },
- })
- );
+ this.searchHistoryListEL = this.shadowRoot!.querySelector('.search-history-list');
+ this.search!.addEventListener('focus', () => {
+ this.searchFocusListener();
});
this.search!.addEventListener('blur', (e) => {
- this.dispatchEvent(
- new CustomEvent('blur', {
- detail: {
- value: this.search!.value,
- },
- })
- );
+ this.searchBlurListener();
});
this.search!.addEventListener('change', (event) => {
this.index = -1;
});
-
this.search!.addEventListener('keyup', (e: KeyboardEvent) => {
- if (e.code == 'Enter') {
- if (e.shiftKey) {
- this.dispatchEvent(
- new CustomEvent('previous-data', {
- detail: {
- value: this.search!.value,
- },
- composed: false,
- })
- );
- } else {
- this.dispatchEvent(
- new CustomEvent('next-data', {
- detail: {
- value: this.search!.value,
- },
- composed: false,
- })
- );
- }
- } else {
- this.valueChangeHandler?.(this.search!.value);
- }
- e.stopPropagation();
+ this.searchKeyupListener(e);
});
this.shadowRoot?.querySelector('#arrow-left')?.addEventListener('click', (e) => {
this.dispatchEvent(
@@ -213,6 +273,7 @@ export class LitSearch extends BaseElement {
}
.root input{
outline: none;
+ width: max-content;
border: 0px;
background-color: transparent;
font-size: inherit;
@@ -222,7 +283,7 @@ export class LitSearch extends BaseElement {
vertical-align:middle;
line-height:inherit;
height:inherit;
- padding: 6px 6px 6px 6px};
+ padding: 6px 6px 6px 6px;
max-height: inherit;
box-sizing: border-box;
}
@@ -272,8 +333,29 @@ export class LitSearch extends BaseElement {
100% {
left: 100%;
}
+ }
+ .search-history {
+ position: relative;
+ }
+ .search-history-list {
+ list-style-type: none;
+ margin: 0;
+ position: absolute;
+ width: 35vw;
+ top: 100%;
+ background-color: #FFFFFF;
+ border: 1px solid #ddd;
+ max-height: 200px;
+ overflow-y: auto;
+ display: none;
+ border-radius: 0 0 20px 20px;
}
-
+ .search-history-list-item {
+ cursor: pointer;
+ }
+ .search-history-list-item:hover {
+ background-color: #e9e9e9;
+ }
@@ -288,6 +370,64 @@ export class LitSearch extends BaseElement {
+