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 { ColorUtils } from './ColorUtils'; 18import { LitRadioBox } from '../../../../base-ui/radiobox/LitRadioBox'; 19import { SpApplication } from '../../../SpApplication'; 20import { SpSystemTrace } from '../../SpSystemTrace'; 21import { CustomThemeColorHtml } from './CustomThemeColor.html'; 22 23@element('custom-theme-color') 24export class CustomThemeColor extends BaseElement { 25 private application: SpApplication | undefined | null; 26 private radios: NodeListOf<LitRadioBox> | undefined | null; 27 private colorsArray: Array<string> = []; 28 private colorsEl: HTMLDivElement | undefined | null; 29 private theme: Theme = Theme.LIGHT; 30 private systemTrace: SpSystemTrace | undefined | null; 31 32 static get observedAttributes(): string[] { 33 return ['mode']; 34 } 35 36 init(): void { 37 window.localStorage.getItem('Theme') === 'light' ? (this.theme = Theme.LIGHT) : (this.theme = Theme.DARK); 38 if (window.localStorage.getItem('Theme') === 'light' || !window.localStorage.getItem('Theme')) { 39 this.theme = Theme.LIGHT; 40 } else { 41 this.theme = Theme.DARK; 42 } 43 this.application!.changeTheme(this.theme); 44 this.setRadioChecked(this.theme); 45 } 46 47 /** 48 * 更新色板 49 * @param colorsEl 色板的父元素 50 */ 51 createColorsEl(colorsEl: HTMLDivElement): void { 52 for (let i = 0; i < this.colorsArray!.length; i++) { 53 let div = document.createElement('div'); 54 div.className = 'color-wrap'; 55 let input = document.createElement('input'); 56 input.type = 'color'; 57 input.className = 'color'; 58 input.value = this.colorsArray![i]; 59 div.appendChild(input); 60 colorsEl?.appendChild(div); 61 input.addEventListener('change', (evt: unknown): void => { 62 //@ts-ignore 63 input.value = evt?.target.value; //@ts-ignore 64 this.colorsArray![i] = evt?.target.value; 65 }); 66 } 67 } 68 69 /** 70 * 根据传入的主题改变color setting页面的单选框状态,更新颜色数组 71 * @param theme 主题模式 72 */ 73 setRadioChecked(theme: Theme): void { 74 for (let i = 0; i < this.radios!.length; i++) { 75 if (this.radios![i].innerHTML === theme) { 76 this.radios![i].setAttribute('checked', ''); 77 if (theme === Theme.LIGHT) { 78 this.colorsArray = 79 window.localStorage.getItem('LightThemeColors') === null 80 ? [...ColorUtils.FUNC_COLOR_A] 81 : JSON.parse(window.localStorage.getItem('LightThemeColors')!); 82 } else { 83 this.colorsArray = 84 window.localStorage.getItem('DarkThemeColors') === null 85 ? [...ColorUtils.FUNC_COLOR_B] 86 : JSON.parse(window.localStorage.getItem('DarkThemeColors')!); 87 } 88 } else { 89 this.radios![i].removeAttribute('checked'); 90 } 91 } 92 this.colorsEl!.innerHTML = ''; 93 this.createColorsEl(this.colorsEl!); 94 } 95 96 initElements(): void { 97 this.colorsEl = this.shadowRoot?.querySelector('.colors') as HTMLDivElement; 98 this.application = document.querySelector('body > sp-application') as SpApplication; 99 this.systemTrace = this.application.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace'); 100 let close = this.shadowRoot?.querySelector('.page-close'); 101 this.radioClick(); 102 close!.addEventListener('click', (): void => { 103 if (this.application!.hasAttribute('custom-color')) { 104 this.application!.removeAttribute('custom-color'); 105 this.setAttribute('hidden', ''); 106 } 107 this.cancelOperate(); 108 }); 109 let resetBtn = this.shadowRoot?.querySelector<HTMLButtonElement>('#reset'); 110 let previewBtn = this.shadowRoot?.querySelector<HTMLButtonElement>('#preview'); 111 let confirmBtn = this.shadowRoot?.querySelector<HTMLButtonElement>('#confirm'); 112 113 resetBtn?.addEventListener('click', (): void => { 114 if (this.theme === Theme.LIGHT) { 115 window.localStorage.setItem('LightThemeColors', JSON.stringify(ColorUtils.FUNC_COLOR_A)); 116 } else { 117 window.localStorage.setItem('DarkThemeColors', JSON.stringify(ColorUtils.FUNC_COLOR_B)); 118 } 119 this.application!.changeTheme(this.theme); 120 }); 121 122 previewBtn?.addEventListener('click', (): void => { 123 this.application!.changeTheme(this.theme, [...this.colorsArray]); 124 }); 125 126 confirmBtn?.addEventListener('click', (): void => { 127 this.confirmOPerate(); 128 }); 129 // 鼠标移入该页面,cpu泳道图恢复鼠标移出状态(鼠标移入cpu泳道图有数据的矩形上,和该矩形的tid或者pid不同的矩形会变灰,移出矩形,所有矩形恢复颜色) 130 this.addEventListener('mousemove', (): void => { 131 this.systemTrace!.tipEL!.style.display = 'none'; 132 this.systemTrace!.hoverStructNull(); 133 this.systemTrace!.refreshCanvas(true); 134 }); 135 } 136 137 private radioClick(): void { 138 this.radios = this.shadowRoot?.querySelectorAll('.litRadio'); 139 if (this.radios) { 140 for (let i = 0; i < this.radios.length; i++) { 141 this.radios![i].shadowRoot!.querySelector<HTMLSpanElement>('.selected')!.classList.add('blue'); 142 this.radios[i].addEventListener('click', (): void => { 143 // 点击颜色模式的单选框,色板切换 144 if (this.radios![i].innerHTML === Theme.LIGHT) { 145 if (this.radios![i].getAttribute('checked') === null) { 146 this.colorsArray = 147 window.localStorage.getItem('LightThemeColors') === null 148 ? [...ColorUtils.FUNC_COLOR_A] 149 : JSON.parse(window.localStorage.getItem('LightThemeColors')!); 150 this.theme = Theme.LIGHT; 151 } else { 152 return; 153 } 154 } else if (this.radios![i].innerHTML === Theme.DARK) { 155 if (this.radios![i].getAttribute('checked') === null) { 156 this.colorsArray = 157 window.localStorage.getItem('DarkThemeColors') === null 158 ? [...ColorUtils.FUNC_COLOR_B] 159 : JSON.parse(window.localStorage.getItem('DarkThemeColors')!); 160 this.theme = Theme.DARK; 161 } else { 162 return; 163 } 164 } 165 this.colorsEl!.innerHTML = ''; 166 this.createColorsEl(this.colorsEl!); 167 this.confirmOPerate(); 168 }); 169 } 170 } 171 } 172 173 confirmOPerate(): void { 174 window.localStorage.setItem('Theme', this.theme); 175 if (this.theme === Theme.LIGHT) { 176 window.localStorage.setItem('LightThemeColors', JSON.stringify([...this.colorsArray])); 177 } else { 178 window.localStorage.setItem('DarkThemeColors', JSON.stringify([...this.colorsArray])); 179 } 180 this.application!.changeTheme(this.theme); 181 this.setRadioChecked(this.theme); 182 } 183 184 cancelOperate(): void { 185 if (window.localStorage.getItem('Theme') === 'light' || !window.localStorage.getItem('Theme')) { 186 this.theme = Theme.LIGHT; 187 this.colorsArray = 188 window.localStorage.getItem('LightThemeColors') === null 189 ? [...ColorUtils.FUNC_COLOR_A] 190 : JSON.parse(window.localStorage.getItem('LightThemeColors')!); 191 } else if (window.localStorage.getItem('Theme') === 'dark') { 192 this.theme = Theme.DARK; 193 this.colorsArray = 194 window.localStorage.getItem('DarkThemeColors') === null 195 ? [...ColorUtils.FUNC_COLOR_B] 196 : JSON.parse(window.localStorage.getItem('DarkThemeColors')!); 197 } 198 this.application!.changeTheme(this.theme); 199 // 恢复颜色模式单选框checked状态 200 this.setRadioChecked(this.theme); 201 } 202 203 connectedCallback(): void {} 204 205 initHtml(): string { 206 return CustomThemeColorHtml; 207 } 208 209 attributeChangedCallback(name: string, oldValue: string, newValue: string): void { 210 if (name === 'mode' && newValue === '') { 211 this.init(); 212 } 213 } 214} 215export enum Theme { 216 LIGHT = 'light', 217 DARK = 'dark', 218} 219