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
16 #include "core/components_ng/pattern/navigation/bar_item_pattern.h"
17 #include "core/components_ng/pattern/image/image_pattern.h"
18 #include "core/components_ng/pattern/text/text_pattern.h"
19 #include "core/components_ng/pattern/image/image_layout_property.h"
20
21 namespace OHOS::Ace::NG {
22
OnModifyDone()23 void BarItemPattern::OnModifyDone()
24 {
25 Pattern::OnModifyDone();
26 auto host = GetHost();
27 CHECK_NULL_VOID(host);
28 auto gesture = host->GetOrCreateGestureEventHub();
29 CHECK_NULL_VOID(gesture);
30 CHECK_NULL_VOID(!clickListener_);
31 auto clickCallback = [weak = WeakClaim(this)](GestureEvent& /* info */) {
32 auto pattern = weak.Upgrade();
33 CHECK_NULL_VOID(pattern);
34 auto eventHub = pattern->GetEventHub<BarItemEventHub>();
35 CHECK_NULL_VOID(eventHub);
36 eventHub->FireItemAction();
37 pattern->UpdateBarItemActiveStatusResource();
38 };
39 if (clickListener_) {
40 gesture->RemoveClickEvent(clickListener_);
41 }
42 clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
43 gesture->AddClickEvent(clickListener_);
44 }
45
UpdateSymbolDefaultEffect(RefPtr<TextLayoutProperty> symbolProperty,bool isActive)46 void UpdateSymbolDefaultEffect(RefPtr<TextLayoutProperty> symbolProperty, bool isActive)
47 {
48 CHECK_NULL_VOID(symbolProperty);
49 auto symbolEffectOptions = SymbolEffectOptions(SymbolEffectType::BOUNCE);
50 symbolEffectOptions.SetIsTxtActive(isActive);
51 symbolEffectOptions.SetIsTxtActiveSource(0);
52 symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
53 }
54
UpdateSymbolBarButton(const RefPtr<BarItemNode> & barItemNode,const RefPtr<FrameNode> & iconNode,const Color & iconColor,std::function<void (WeakPtr<NG::FrameNode>)> & symbol,ImageSourceInfo & info)55 void UpdateSymbolBarButton(const RefPtr<BarItemNode>& barItemNode, const RefPtr<FrameNode>& iconNode,
56 const Color& iconColor, std::function<void(WeakPtr<NG::FrameNode>)>& symbol, ImageSourceInfo& info)
57 {
58 auto theme = NavigationGetTheme();
59 CHECK_NULL_VOID(theme);
60 auto iconSize = theme->GetToolbarIconSize();
61 if (symbol != nullptr) {
62 // symbol -> symbol
63 auto symbolProperty = iconNode->GetLayoutProperty<TextLayoutProperty>();
64 CHECK_NULL_VOID(symbolProperty);
65 symbolProperty->UpdateSymbolColorList({iconColor});
66 // User-defined color overrides the default color of the theme
67 symbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNode)));
68 UpdateSymbolDefaultEffect(symbolProperty, false);
69 symbolProperty->UpdateFontSize(iconSize);
70 iconNode->MarkModifyDone();
71 iconNode->MarkDirtyNode();
72 } else {
73 // symbol -> image
74 barItemNode->RemoveChild(iconNode);
75 auto iconNodeNew = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG,
76 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
77 auto imageLayoutProperty = iconNodeNew->GetLayoutProperty<ImageLayoutProperty>();
78 CHECK_NULL_VOID(imageLayoutProperty);
79 imageLayoutProperty->UpdateImageSourceInfo(info);
80 imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
81 iconNodeNew->MarkModifyDone();
82 iconNodeNew->MarkDirtyNode();
83 barItemNode->SetIconNode(iconNodeNew);
84 barItemNode->AddChild(iconNodeNew);
85 }
86 }
87
UpdateImageBarButton(const RefPtr<BarItemNode> & barItemNode,const RefPtr<FrameNode> & iconNode,const Color & iconColor,std::function<void (WeakPtr<NG::FrameNode>)> & symbol,ImageSourceInfo & info)88 void UpdateImageBarButton(const RefPtr<BarItemNode>& barItemNode, const RefPtr<FrameNode>& iconNode,
89 const Color& iconColor, std::function<void(WeakPtr<NG::FrameNode>)>& symbol, ImageSourceInfo& info)
90 {
91 auto theme = NavigationGetTheme();
92 CHECK_NULL_VOID(theme);
93 auto iconSize = theme->GetToolbarIconSize();
94 if (symbol != nullptr) {
95 // image -> symbol
96 barItemNode->RemoveChild(iconNode);
97 auto iconNodeNew = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
98 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
99 CHECK_NULL_VOID(iconNodeNew);
100 auto symbolProperty = iconNodeNew->GetLayoutProperty<TextLayoutProperty>();
101 CHECK_NULL_VOID(symbolProperty);
102 auto symbolEffectOptions = symbolProperty->GetSymbolEffectOptionsValue(SymbolEffectOptions());
103 symbolEffectOptions.SetEffectType(SymbolEffectType::BOUNCE);
104 symbolEffectOptions.SetIsTxtActive(true);
105 symbolEffectOptions.SetIsTxtActiveSource(0);
106 symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
107 symbolProperty->UpdateSymbolColorList({ iconColor });
108 symbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconNodeNew)));
109 symbolProperty->UpdateFontSize(iconSize);
110 UpdateSymbolDefaultEffect(symbolProperty, false);
111 iconNodeNew->MarkModifyDone();
112 iconNodeNew->MarkDirtyNode();
113 barItemNode->SetIconNode(iconNodeNew);
114 barItemNode->AddChild(iconNodeNew);
115 } else {
116 // image -> image
117 auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
118 CHECK_NULL_VOID(imageLayoutProperty);
119 imageLayoutProperty->UpdateImageSourceInfo(info);
120 iconNode->MarkModifyDone();
121 iconNode->MarkDirtyNode();
122 }
123 }
124
UpdateSymbolEffect(const RefPtr<FrameNode> & iconNode)125 void UpdateSymbolEffect(const RefPtr<FrameNode>& iconNode)
126 {
127 auto symbolProperty = iconNode->GetLayoutProperty<TextLayoutProperty>();
128 CHECK_NULL_VOID(symbolProperty);
129 auto symbolEffectOptions = symbolProperty->GetSymbolEffectOptionsValue(SymbolEffectOptions());
130 symbolEffectOptions.SetEffectType(SymbolEffectType::BOUNCE);
131 symbolEffectOptions.SetIsTxtActive(true);
132 symbolEffectOptions.SetIsTxtActiveSource(0);
133 symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
134 iconNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
135 }
136
UpdateBarItemActiveStatusResource()137 void BarItemPattern::UpdateBarItemActiveStatusResource()
138 {
139 auto theme = NavigationGetTheme();
140 CHECK_NULL_VOID(theme);
141
142 auto barItemNode = AceType::DynamicCast<BarItemNode>(GetHost());
143 CHECK_NULL_VOID(barItemNode);
144 auto status = GetToolbarItemStatus();
145 auto iconStatus = GetCurrentIconStatus();
146
147 auto iconNode = DynamicCast<FrameNode>(barItemNode->GetIconNode());
148 CHECK_NULL_VOID(iconNode);
149
150 if (iconNode->GetTag() == V2::SYMBOL_ETS_TAG) {
151 UpdateSymbolEffect(iconNode);
152 }
153
154 auto textNode = DynamicCast<FrameNode>(barItemNode->GetTextNode());
155 CHECK_NULL_VOID(textNode);
156 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
157 CHECK_NULL_VOID(textLayoutProperty);
158
159 ImageSourceInfo info;
160 ToolbarIconStatus barIconStatus;
161 Color textColor;
162 Color iconColor;
163 std::function<void(WeakPtr<NG::FrameNode>)> symbol;
164 if (iconStatus == ToolbarIconStatus::INITIAL) {
165 info = GetActiveIconImageSourceInfo();
166 barIconStatus = ToolbarIconStatus::ACTIVE;
167 textColor = theme->GetToolBarItemActiveFontColor();
168 symbol = GetActiveIconSymbol();
169 iconColor = theme->GetToolbarActiveIconColor();
170 }
171 if (iconStatus == ToolbarIconStatus::ACTIVE) {
172 info = GetInitialIconImageSourceInfo();
173 barIconStatus = ToolbarIconStatus::INITIAL;
174 textColor = theme->GetToolBarItemFontColor();
175 symbol = GetInitialIconSymbol();
176 iconColor = theme->GetToolbarIconColor();
177 }
178
179 if (status == NavToolbarItemStatus::ACTIVE) {
180 if (iconNode->GetTag() == V2::SYMBOL_ETS_TAG) {
181 UpdateSymbolBarButton(barItemNode, iconNode, iconColor, symbol, info);
182 } else {
183 UpdateImageBarButton(barItemNode, iconNode, iconColor, symbol, info);
184 }
185 barItemNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
186 barItemNode->MarkDirtyNode();
187 textLayoutProperty->UpdateTextColor(textColor);
188 textNode->MarkModifyDone();
189 textNode->MarkDirtyNode();
190 SetCurrentIconStatus(barIconStatus);
191 }
192 }
193
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const194 void BarItemPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
195 {
196 Pattern::ToJsonValue(json, filter);
197
198 /* no fixed attr below, just return */
199 if (filter.IsFastFilter()) {
200 return;
201 }
202
203 auto barItemNode = AceType::DynamicCast<BarItemNode>(GetHost());
204 CHECK_NULL_VOID(barItemNode);
205 auto textNode = AceType::DynamicCast<FrameNode>(barItemNode->GetTextNode());
206 CHECK_NULL_VOID(textNode);
207 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
208 CHECK_NULL_VOID(textLayoutProperty);
209 json->PutExtAttr("label", textLayoutProperty->GetContentValue("").c_str(), filter);
210 }
211 } // namespace OHOS::Ace::NG
212