• 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 
16 #include "core/interfaces/native/node/theme_modifier.h"
17 
18 #include "core/components/common/properties/color.h"
19 #include "core/components_ng/syntax/with_theme_node.h"
20 #include "core/components_ng/token_theme/token_theme.h"
21 #include "core/components_ng/token_theme/token_theme_storage.h"
22 #include "core/pipeline_ng/pipeline_context.h"
23 
24 namespace OHOS::Ace::NG {
25 namespace ThemeModifier {
26 namespace {
MapNumberToColorMode(int32_t number)27 ColorMode MapNumberToColorMode(int32_t number)
28 {
29     switch (number) {
30         case 1: // 1 is the ThemeColorMode.LIGHT
31             return ColorMode::LIGHT;
32         case 2: // 2 is the ThemeColorMode.DARK
33             return ColorMode::DARK;
34         default:
35             return ColorMode::COLOR_MODE_UNDEFINED;
36     }
37     return ColorMode::COLOR_MODE_UNDEFINED;
38 }
39 
ConvertColorArrayToTokenColors(const ArkUI_Uint32 * colorsArray)40 RefPtr<TokenColors> ConvertColorArrayToTokenColors(const ArkUI_Uint32* colorsArray)
41 {
42     std::vector<Color> colors;
43     colors.reserve(TokenColors::TOTAL_NUMBER);
44     for (int i = 0; i < TokenColors::TOTAL_NUMBER; i++) {
45         colors.push_back(Color(colorsArray[i]));
46     }
47     auto themeColors = AceType::MakeRefPtr<TokenColors>();
48     themeColors->SetColors(std::move(colors));
49     return themeColors;
50 }
51 
ConvertResObjArray(const void * resObjs)52 std::vector<RefPtr<ResourceObject>> ConvertResObjArray(const void* resObjs)
53 {
54     auto resourceObjs = *(static_cast<const std::vector<RefPtr<ResourceObject>>*>(resObjs));
55     return resourceObjs;
56 }
57 } // namespace
58 
CreateWithThemeNode(ArkUI_Int32 id)59 ArkUINodeHandle CreateWithThemeNode(ArkUI_Int32 id)
60 {
61     TAG_LOGD(AceLogTag::ACE_DEFAULT_DOMAIN, "WithTheme CreateWithThemeNode id:%{public}d", id);
62     auto withThemeNode = WithThemeNode::CreateWithThemeNode(id);
63     withThemeNode->IncRefCount();
64     return reinterpret_cast<ArkUINodeHandle>(OHOS::Ace::AceType::RawPtr(withThemeNode));
65 }
66 
GetWithThemeNode(ArkUI_Int32 id)67 ArkUINodeHandle GetWithThemeNode(ArkUI_Int32 id)
68 {
69     auto withThemeNode = WithThemeNode::GetWithThemeNode(id);
70     return reinterpret_cast<ArkUINodeHandle>(OHOS::Ace::AceType::RawPtr(withThemeNode));
71 }
72 
CreateTheme(ArkUI_Int32 themeId,const ArkUI_Uint32 * colors,const ArkUI_Uint32 * darkColors,ArkUI_Int32 colorMode,const void * lightResObjs,const void * darkResObjs)73 ArkUINodeHandle CreateTheme(ArkUI_Int32 themeId, const ArkUI_Uint32* colors, const ArkUI_Uint32* darkColors,
74     ArkUI_Int32 colorMode, const void* lightResObjs, const void* darkResObjs)
75 {
76     auto theme = TokenThemeStorage::GetInstance()->CacheGet(themeId);
77     if (!theme) {
78         TAG_LOGD(AceLogTag::ACE_DEFAULT_DOMAIN, "WithTheme CreateTheme themeId:%{public}d colorMode num:%{public}d",
79             themeId, colorMode);
80         ColorMode themeScopeColorMode = MapNumberToColorMode(colorMode);
81         auto themeColors = ConvertColorArrayToTokenColors(colors);
82         auto themeDarkColors = ConvertColorArrayToTokenColors(darkColors);
83         theme = AceType::MakeRefPtr<TokenTheme>(themeId);
84         theme->SetColors(themeColors);
85         theme->SetDarkColors(themeDarkColors);
86         theme->SetColorMode(themeScopeColorMode);
87         auto lightResourceObjs = ConvertResObjArray(lightResObjs);
88         auto darkResourceObjs = ConvertResObjArray(darkResObjs);
89         theme->SetResObjs(std::move(lightResourceObjs));
90         theme->SetDarkResObjs(std::move(darkResourceObjs));
91         TokenThemeStorage::GetInstance()->CacheSet(theme);
92     }
93     return reinterpret_cast<ArkUINodeHandle>(OHOS::Ace::AceType::RawPtr(theme));
94 }
95 
CreateThemeScope(ArkUINodeHandle node,ArkUINodeHandle theme)96 void CreateThemeScope(ArkUINodeHandle node, ArkUINodeHandle theme)
97 {
98     RefPtr<WithThemeNode> withThemeNode = AceType::Claim(reinterpret_cast<WithThemeNode*>(node));
99     CHECK_NULL_VOID(withThemeNode);
100     RefPtr<TokenTheme> tokenTheme = AceType::Claim(reinterpret_cast<TokenTheme*>(theme));
101     CHECK_NULL_VOID(tokenTheme);
102     TokenThemeStorage::GetInstance()->StoreThemeScope(withThemeNode->GetId(), tokenTheme->GetId());
103     TAG_LOGD(AceLogTag::ACE_DEFAULT_DOMAIN, "WithTheme CreateThemeScope and notify node:%{public}d theme:%{public}d",
104         withThemeNode->GetId(), tokenTheme->GetId());
105     withThemeNode->NotifyThemeScopeUpdate();
106 }
107 
SetDefaultTheme(const ArkUI_Uint32 * colors,ArkUI_Bool isDark,const void * resObjs)108 void SetDefaultTheme(const ArkUI_Uint32* colors, ArkUI_Bool isDark, const void* resObjs)
109 {
110     TAG_LOGD(AceLogTag::ACE_DEFAULT_DOMAIN, "WithTheme SetDefaultTheme isDark:%{public}d", isDark);
111     auto themeColors = ConvertColorArrayToTokenColors(colors);
112     auto resourceObjs = ConvertResObjArray(resObjs);
113     auto theme = AceType::MakeRefPtr<TokenTheme>(0);
114     if (isDark) {
115         theme->SetDarkColors(themeColors);
116         theme->SetDarkResObjs(std::move(resourceObjs));
117     } else {
118         theme->SetColors(themeColors);
119         theme->SetResObjs(std::move(resourceObjs));
120     }
121     auto colorMode = isDark ? ColorMode::DARK : ColorMode::LIGHT;
122     TokenThemeStorage::GetInstance()->SetDefaultTheme(theme, colorMode);
123 
124     // global notify if required
125     auto pipelineContext = PipelineContext::GetCurrentContext();
126     CHECK_NULL_VOID(pipelineContext);
127     auto sysColorMode = pipelineContext->GetColorMode();
128     if (sysColorMode != colorMode) {
129         return;
130     }
131     auto rootNode = pipelineContext->GetRootElement();
132     CHECK_NULL_VOID(rootNode);
133     rootNode->UpdateThemeScopeUpdate(0); // 0 means default theme scope id
134 }
135 
RemoveFromCache(ArkUI_Int32 themeId)136 void RemoveFromCache(ArkUI_Int32 themeId)
137 {
138     TokenThemeStorage::GetInstance()->CacheRemove(themeId);
139 }
140 
SetOnThemeScopeDestroy(ArkUINodeHandle node,void * callback)141 void SetOnThemeScopeDestroy(ArkUINodeHandle node, void* callback)
142 {
143     RefPtr<WithThemeNode> withThemeNode = AceType::Claim(reinterpret_cast<WithThemeNode*>(node));
144     if (callback && withThemeNode) {
145         auto cb = reinterpret_cast<std::function<void()>*>(callback);
146         withThemeNode->SetOnThemeScopeDestroy(std::move(*cb));
147     }
148 }
149 
GetThemeScopeId(ArkUINodeHandle node)150 ArkUI_Int32 GetThemeScopeId(ArkUINodeHandle node)
151 {
152     auto ui_node = reinterpret_cast<UINode*>(node);
153     CHECK_NULL_RETURN(ui_node, 0);
154     return ui_node->GetThemeScopeId();
155 }
156 } // namespace ThemeModifier
157 namespace NodeModifier {
GetThemeModifier()158 const ArkUIThemeModifier* GetThemeModifier()
159 {
160     CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
161     static const ArkUIThemeModifier modifier = {
162         .createWithThemeNode = ThemeModifier::CreateWithThemeNode,
163         .getWithThemeNode = ThemeModifier::GetWithThemeNode,
164         .createTheme = ThemeModifier::CreateTheme,
165         .createThemeScope = ThemeModifier::CreateThemeScope,
166         .setDefaultTheme = ThemeModifier::SetDefaultTheme,
167         .removeFromCache = ThemeModifier::RemoveFromCache,
168         .setOnThemeScopeDestroy = ThemeModifier::SetOnThemeScopeDestroy,
169         .getThemeScopeId = ThemeModifier::GetThemeScopeId,
170     };
171     CHECK_INITIALIZED_FIELDS_END(modifier, 0, 0, 0); // don't move this line
172     return &modifier;
173 }
174 } // namespace NodeModifier
175 } // namespace OHOS::Ace::NG