• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 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
16class ArkThemeScopeItem {
17    elmtId: number;
18    owner: number;
19    name: string;
20    isInWhiteList?: boolean = undefined;
21}
22
23class ArkThemeScopeArray extends Array<ArkThemeScopeItem> {
24    binarySearch(elmtId: number): number {
25        let start = 0;
26        let end = this.length - 1;
27        while (start <= end) {
28            let mid = (start + end) >> 1;
29            if (this[mid].elmtId === elmtId) {
30                return mid;
31            }
32            if (elmtId < this[mid].elmtId) {
33                end = mid - 1;
34            } else {
35                start = mid + 1;
36            }
37        }
38        return -1;
39    }
40}
41
42/**
43 * Used to store elmtIds of the components that are in WithTheme container scope.
44 */
45class ArkThemeScope {
46    /**
47     * elmtId of the CustomComponent which defines WithTheme container
48     */
49    private ownerComponentId: number;
50
51    /**
52     * elmtId of the WithTheme container that defines theme scope
53     */
54    private withThemeId: number;
55
56    /**
57     * WithTheme container options
58     */
59    private withThemeOptions: WithThemeOptions;
60
61    /**
62     * Previous scope color mode before option change
63     */
64    private prevColorMode: ThemeColorMode;
65
66    /**
67     * elmtIds of the components that are in this theme scope
68     */
69    private components: ArkThemeScopeArray;
70
71    /**
72     * Theme instance associated with this Theme Scope
73     */
74    private theme: ThemeInternal;
75
76    /**
77     * Initialize Theme Scope
78     *
79     * @param ownerComponentId elmtId of the CustomComponent which defines WithTheme container
80     * @param withThemeId elmtId of the WithTheme container that defines theme scope
81     * @param withThemeOptions WithTheme container options
82     * @param theme Theme instance associated with this Theme Scope
83     */
84    constructor(ownerComponentId: number, withThemeId: number, withThemeOptions: WithThemeOptions, theme: ThemeInternal) {
85        this.ownerComponentId = ownerComponentId;
86        this.withThemeId = withThemeId;
87        this.withThemeOptions = withThemeOptions;
88        this.theme = theme;
89        this.prevColorMode = this.colorMode();
90    }
91
92    /**
93     * Get elmtId of the CustomComponent which defines WithTheme container
94     *
95     * @returns elmtId as number
96     */
97    getOwnerComponentId(): number {
98        return this.ownerComponentId;
99    }
100
101    /**
102     * Get elmtId of the WithTheme container that defines theme scope
103     *
104     * @returns elmtId as number
105     */
106    getWithThemeId(): number {
107        return this.withThemeId;
108    }
109
110    /**
111     * Add component to the current theme scope by elmtId
112     *
113     * @param elmtId elmtId as number
114     * @param owner component owner id
115     * @param componentName component name
116     */
117    addComponentToScope(elmtId: number, owner: number, componentName: string) {
118        if (this.isComponentInScope(elmtId)) {
119            return;
120        }
121        if (!this.components) {
122            this.components = new ArkThemeScopeArray();
123        }
124        this.components.push({ elmtId: elmtId, owner: owner, name: componentName });
125    }
126
127    /**
128     * Remove components from the current theme scope by elmtId
129     *
130     * @param elmtId elmtId as number
131     */
132    removeComponentFromScope(elmtId: number) {
133        if (this.components) {
134            const index = this.components.binarySearch(elmtId);
135            if (index > -1) {
136                this.components.splice(index, 1);
137            }
138        }
139    }
140
141    /**
142     * Check whether the component with elmtId is in current theme scope
143     *
144     * @param elmtId elmtId as number
145     * @returns true if theme scope contains component, otherwise false
146     */
147    isComponentInScope(elmtId: number): boolean {
148        return this.components && (this.components.binarySearch(elmtId) > -1);
149    }
150
151    /**
152     * Get all components elmtIds which are in current theme scope
153     *
154     * @returns array of elmIds as numbers
155     */
156    componentsInScope(): Array<ArkThemeScopeItem> {
157        return this.components;
158    }
159
160    /**
161     * Get color mode of the current theme scope
162     *
163     * @returns DARK, Light or SYSTEM values
164     */
165    colorMode(): ThemeColorMode {
166        return this.withThemeOptions.colorMode ?? ThemeColorMode.SYSTEM;
167    }
168
169    /**
170     * Get Custom Theme of the current theme scope
171     *
172     * @returns CustomTheme instance
173     */
174    customTheme(): CustomTheme {
175        return this.withThemeOptions.theme ?? {};
176    }
177
178    /**
179     * Get theme instance associated with this Theme Scope
180     *
181     * @returns theme instance
182     */
183    getTheme(): ThemeInternal {
184        return this.theme;
185    }
186
187    /**
188     * Get WithTheme container options
189     *
190     * @returns WithThemeOptions instance
191     */
192    options(): WithThemeOptions {
193        return this.withThemeOptions;
194    }
195
196    /**
197     * Update WithThemeOptions
198     *
199     * @param options WithThemeOptions instance
200     * @param theme Theme instance associated with this Theme Scope
201     */
202    updateWithThemeOptions(options: WithThemeOptions, theme: ThemeInternal) {
203        this.prevColorMode = this.colorMode();
204        this.withThemeOptions = options;
205        this.theme = theme;
206    }
207
208    /**
209     * Check whether scope color mode changed in last update
210     *
211     * @returns true if color mode changed, otherwise false
212     */
213    isColorModeChanged() {
214        return this.prevColorMode !== this.colorMode();
215    }
216}