1 /*
2 * Copyright (c) 2023 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/app_bar/app_bar_view.h"
17
18 #include <map>
19
20 #include "base/utils/utils.h"
21 #include "base/want/want_wrap.h"
22 #include "core/common/app_bar_helper.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/pattern/app_bar/app_bar_theme.h"
25 #include "core/components_ng/pattern/app_bar/atomic_service_pattern.h"
26 #include "core/components_ng/pattern/button/button_layout_property.h"
27 #include "core/components_ng/pattern/button/button_pattern.h"
28 #include "core/components_ng/pattern/image/image_pattern.h"
29 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
30 #include "core/components_ng/pattern/stage/stage_pattern.h"
31 #include "core/components_ng/pattern/text/text_layout_property.h"
32 #include "core/components_ng/pattern/text/text_pattern.h"
33 #include "core/components_ng/property/border_property.h"
34 #include "core/components_v2/inspector/inspector_constants.h"
35
36 namespace OHOS::Ace::NG {
37 namespace {
38
39 const Dimension MARGIN_TEXT_LEFT = 24.0_vp;
40 const Dimension MARGIN_TEXT_RIGHT = 84.0_vp;
41 const Dimension MARGIN_BUTTON = 12.0_vp;
42 const Dimension MARGIN_BACK_BUTTON_RIGHT = -20.0_vp;
43 const float REVERSED_X = -1.0f;
44 const float UNCHANGED_X = 1.0f;
45 const float UNCHANGED_Y = 1.0f;
46 constexpr int32_t LABLE_ROWSIZE = 2;
47
HasNavigation(const RefPtr<UINode> & node)48 bool HasNavigation(const RefPtr<UINode>& node)
49 {
50 if (node->GetTag() == V2::NAVIGATION_VIEW_ETS_TAG) {
51 return true;
52 }
53 const auto& children = node->GetChildren();
54 return std::any_of(children.begin(), children.end(), [](const auto& node) { return HasNavigation(node); });
55 }
56 } // namespace
57
Create(RefPtr<FrameNode> & content)58 RefPtr<FrameNode> AppBarView::Create(RefPtr<FrameNode>& content)
59 {
60 auto atom = FrameNode::CreateFrameNode(V2::ATOMIC_SERVICE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
61 AceType::MakeRefPtr<AtomicServicePattern>());
62 auto titleBar = BuildBarTitle();
63 atom->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
64 atom->AddChild(titleBar);
65 atom->AddChild(content);
66 #ifndef IS_EMULATOR
67 auto faButton = BuildFaButton();
68 atom->AddChild(faButton);
69 #endif
70 content->GetLayoutProperty()->UpdateLayoutWeight(1.0f);
71 content->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
72 return atom;
73 }
74
iniBehavior()75 void AppBarView::iniBehavior()
76 {
77 CHECK_NULL_VOID(atom_);
78 auto titleBar = AceType::DynamicCast<FrameNode>(atom_->GetFirstChild());
79 CHECK_NULL_VOID(titleBar);
80 auto content = AceType::DynamicCast<FrameNode>(atom_->GetChildAtIndex(1));
81 CHECK_NULL_VOID(content);
82 auto stagePattern = content->GetPattern<StagePattern>();
83 CHECK_NULL_VOID(stagePattern);
84 stagePattern->SetOnRebuildFrameCallback([titleBar, content, this]() {
85 auto backButton = AceType::DynamicCast<FrameNode>(titleBar->GetFirstChild());
86 CHECK_NULL_VOID(backButton);
87 if (content->GetChildren().size() > 1) {
88 backButton->GetLayoutProperty()->UpdateVisibility(VisibleType::VISIBLE);
89 if (!isVisibleSetted) {
90 titleBar->GetLayoutProperty()->UpdateVisibility(VisibleType::VISIBLE);
91 }
92 return;
93 }
94 backButton->GetLayoutProperty()->UpdateVisibility(VisibleType::GONE);
95 if (HasNavigation(content)) {
96 titleBar->GetLayoutProperty()->UpdateVisibility(VisibleType::GONE);
97 }
98 });
99 UpdateRowLayout();
100 }
101
BuildBarTitle()102 RefPtr<FrameNode> AppBarView::BuildBarTitle()
103 {
104 auto appBarRow = FrameNode::CreateFrameNode(V2::APP_BAR_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
105 AceType::MakeRefPtr<LinearLayoutPattern>(false));
106 auto layoutProperty = appBarRow->GetLayoutProperty<LinearLayoutProperty>();
107 CHECK_NULL_RETURN(layoutProperty, nullptr);
108 auto pipeline = PipelineContext::GetCurrentContext();
109 CHECK_NULL_RETURN(pipeline, nullptr);
110 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
111 layoutProperty->UpdateUserDefinedIdealSize(
112 CalcSize(CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(appBarTheme->GetAppBarHeight())));
113 layoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_START);
114 layoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
115 auto renderContext = appBarRow->GetRenderContext();
116 CHECK_NULL_RETURN(renderContext, nullptr);
117 renderContext->UpdateBackgroundColor(appBarTheme->GetBgColor());
118
119 auto titleLabel = BuildBarLabel();
120 appBarRow->AddChild(BuildIconButton(
121 InternalResource::ResourceId::APP_BAR_BACK_SVG,
122 [pipeline](GestureEvent& info) {
123 if (pipeline) {
124 pipeline->CallRouterBackToPopPage();
125 }
126 },
127 true));
128 appBarRow->AddChild(titleLabel);
129 return appBarRow;
130 }
131
BuildBarLabel()132 RefPtr<FrameNode> AppBarView::BuildBarLabel()
133 {
134 // create title label
135 auto appBarLabel = FrameNode::CreateFrameNode(
136 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
137 auto textLayoutProperty = appBarLabel->GetLayoutProperty<TextLayoutProperty>();
138 CHECK_NULL_RETURN(textLayoutProperty, nullptr);
139 auto pipeline = PipelineContext::GetCurrentContext();
140 CHECK_NULL_RETURN(pipeline, nullptr);
141 auto themeManager = pipeline->GetThemeManager();
142 CHECK_NULL_RETURN(themeManager, nullptr);
143 auto themeConstants = themeManager->GetThemeConstants();
144 CHECK_NULL_RETURN(themeConstants, nullptr);
145 #ifdef PREVIEW
146 auto label = themeConstants->GetString(pipeline->GetAppLabelId());
147 if (label.empty()) {
148 label = "label";
149 LOGW("[Engine Log] Unable to get label for shared library in the Previewer. Perform this operation on the "
150 "emulator or a real device instead.");
151 }
152 textLayoutProperty->UpdateContent(label);
153 #else
154 textLayoutProperty->UpdateContent(themeConstants->GetString(pipeline->GetAppLabelId()));
155 #endif
156 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
157 textLayoutProperty->UpdateMaxLines(LABLE_ROWSIZE);
158 textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
159 textLayoutProperty->UpdateFontSize(appBarTheme->GetFontSize());
160 textLayoutProperty->UpdateTextColor(appBarTheme->GetTextColor());
161 textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
162 textLayoutProperty->UpdateAlignment(Alignment::CENTER_LEFT);
163 textLayoutProperty->UpdateLayoutWeight(1.0f);
164
165 MarginProperty margin;
166 margin.left = CalcLength(MARGIN_TEXT_LEFT);
167 margin.right = CalcLength(MARGIN_TEXT_RIGHT);
168 textLayoutProperty->UpdateMargin(margin);
169
170 return appBarLabel;
171 }
172
BuildFaButton()173 RefPtr<FrameNode> AppBarView::BuildFaButton()
174 {
175 auto buttonNode = BuildIconButton(InternalResource::ResourceId::APP_BAR_FA_SVG, nullptr, false);
176 CHECK_NULL_RETURN(buttonNode, nullptr);
177 auto renderContext = buttonNode->GetRenderContext();
178 CHECK_NULL_RETURN(renderContext, nullptr);
179 renderContext->UpdatePosition(OffsetT<Dimension>());
180 auto pipeline = PipelineContext::GetCurrentContext();
181 CHECK_NULL_RETURN(pipeline, nullptr);
182 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
183 auto clickCallback = [pipeline, appBarTheme, buttonNode](GestureEvent& info) {
184 #ifdef PREVIEW
185 LOGW("[Engine Log] Unable to show the SharePanel in the Previewer. Perform this operation on the "
186 "emulator or a real device instead.");
187 #else
188 if (!pipeline || !appBarTheme) {
189 return;
190 }
191 if (SystemProperties::GetExtSurfaceEnabled()) {
192 LOGI("start panel bundleName is %{public}s, abilityName is %{public}s",
193 appBarTheme->GetBundleName().c_str(), appBarTheme->GetAbilityName().c_str());
194 pipeline->FireSharePanelCallback(appBarTheme->GetBundleName(), appBarTheme->GetAbilityName());
195 } else {
196 BindContentCover(buttonNode);
197 }
198 #endif
199 };
200 auto buttonEventHub = buttonNode->GetOrCreateGestureEventHub();
201 if (buttonEventHub) {
202 buttonEventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback)));
203 }
204 return buttonNode;
205 }
206
BuildIconButton(InternalResource::ResourceId icon,GestureEventFunc && clickCallback,bool isBackButton)207 RefPtr<FrameNode> AppBarView::BuildIconButton(
208 InternalResource::ResourceId icon, GestureEventFunc&& clickCallback, bool isBackButton)
209 {
210 // button image icon
211 ImageSourceInfo imageSourceInfo;
212 auto imageIcon = FrameNode::CreateFrameNode(
213 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
214
215 imageSourceInfo.SetResourceId(icon);
216 auto imageLayoutProperty = imageIcon->GetLayoutProperty<ImageLayoutProperty>();
217 CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
218 auto pipeline = PipelineContext::GetCurrentContext();
219 CHECK_NULL_RETURN(pipeline, nullptr);
220 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
221 imageLayoutProperty->UpdateUserDefinedIdealSize(
222 CalcSize(CalcLength(appBarTheme->GetIconSize()), CalcLength(appBarTheme->GetIconSize())));
223 imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
224 imageIcon->MarkModifyDone();
225
226 auto buttonNode = FrameNode::CreateFrameNode(
227 V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
228
229 auto renderContext = buttonNode->GetRenderContext();
230 CHECK_NULL_RETURN(renderContext, nullptr);
231 renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
232
233 auto buttonPattern = AceType::DynamicCast<ButtonPattern>(buttonNode->GetPattern());
234 CHECK_NULL_RETURN(buttonPattern, nullptr);
235 buttonPattern->SetClickedColor(appBarTheme->GetClickEffectColor());
236
237 auto buttonEventHub = buttonNode->GetOrCreateGestureEventHub();
238 CHECK_NULL_RETURN(buttonEventHub, nullptr);
239 auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback));
240 buttonEventHub->AddClickEvent(clickEvent);
241
242 auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
243 CHECK_NULL_RETURN(buttonLayoutProperty, nullptr);
244 buttonLayoutProperty->UpdateType(ButtonType::NORMAL);
245 auto butttonRadius = appBarTheme->GetIconCornerRadius();
246 buttonLayoutProperty->UpdateBorderRadius(BorderRadiusProperty(butttonRadius));
247 buttonLayoutProperty->UpdateUserDefinedIdealSize(
248 CalcSize(CalcLength(appBarTheme->GetIconSize() * 2), CalcLength(appBarTheme->GetIconSize() * 2)));
249 MarginProperty margin;
250 margin.left = CalcLength(isBackButton ? MARGIN_BUTTON : -MARGIN_BUTTON);
251 margin.right = CalcLength(isBackButton ? MARGIN_BACK_BUTTON_RIGHT : MARGIN_BUTTON);
252 buttonLayoutProperty->UpdateMargin(margin);
253 buttonNode->MarkModifyDone();
254 buttonNode->AddChild(imageIcon);
255 return buttonNode;
256 }
257
BindContentCover(const RefPtr<FrameNode> & targetNode)258 void AppBarView::BindContentCover(const RefPtr<FrameNode>& targetNode)
259 {
260 if (OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName().empty()) {
261 LOGE("UIExtension BundleName is empty.");
262 return;
263 }
264
265 auto pipeline = PipelineContext::GetCurrentContext();
266 CHECK_NULL_VOID(pipeline);
267 auto overlayManager = pipeline->GetOverlayManager();
268 CHECK_NULL_VOID(overlayManager);
269
270 std::string stageAbilityName = "";
271 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
272 if (appBarTheme) {
273 stageAbilityName = appBarTheme->GetStageAbilityName();
274 }
275 NG::ModalStyle modalStyle;
276 modalStyle.modalTransition = NG::ModalTransition::NONE;
277 auto buildNodeFunc = [targetNode, overlayManager, &modalStyle, &stageAbilityName]() -> RefPtr<UINode> {
278 auto onRelease = [overlayManager, &modalStyle, targetNode](int32_t releaseCode) {
279 overlayManager->BindContentCover(false, nullptr, nullptr, modalStyle, nullptr, nullptr, targetNode);
280 };
281 auto onError = [overlayManager, &modalStyle, targetNode](
282 int32_t code, const std::string& name, const std::string& message) {
283 overlayManager->BindContentCover(false, nullptr, nullptr, modalStyle, nullptr, nullptr, targetNode);
284 };
285
286 // Create parameters of UIExtension.
287 auto missionId = AceApplicationInfo::GetInstance().GetMissionId();
288 std::map<std::string, std::string> params;
289 params.try_emplace("bundleName", AceApplicationInfo::GetInstance().GetProcessName());
290 params.try_emplace("abilityName", AceApplicationInfo::GetInstance().GetAbilityName());
291 params.try_emplace("module", Container::Current()->GetModuleName());
292 if (missionId != -1) {
293 params.try_emplace("missionId", std::to_string(missionId));
294 }
295 params.try_emplace("ability.want.params.uiExtensionType", "sys/commonUI");
296 LOGI("BundleName: %{public}s, AbilityName: %{public}s, Module: %{public}s",
297 AceApplicationInfo::GetInstance().GetProcessName().c_str(),
298 AceApplicationInfo::GetInstance().GetAbilityName().c_str(), Container::Current()->GetModuleName().c_str());
299
300 // Create UIExtension node.
301 auto appGalleryBundleName = OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName();
302 auto uiExtNode = OHOS::Ace::AppBarHelper::CreateUIExtensionNode(
303 appGalleryBundleName, stageAbilityName, params, std::move(onRelease), std::move(onError));
304 LOGI("UIExtension BundleName: %{public}s, AbilityName: %{public}s", appGalleryBundleName.c_str(),
305 stageAbilityName.c_str());
306
307 // Update ideal size of UIExtension.
308 auto layoutProperty = uiExtNode->GetLayoutProperty();
309 CHECK_NULL_RETURN(layoutProperty, uiExtNode);
310 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(
311 CalcLength(Dimension(1.0, DimensionUnit::PERCENT)), CalcLength(Dimension(1.0, DimensionUnit::PERCENT))));
312 uiExtNode->MarkModifyDone();
313 return uiExtNode;
314 };
315 overlayManager->BindContentCover(true, nullptr, std::move(buildNodeFunc), modalStyle, nullptr, nullptr, targetNode);
316 }
317
SetVisible(bool visible)318 void AppBarView::SetVisible(bool visible)
319 {
320 CHECK_NULL_VOID(atom_);
321 auto uiRow = atom_->GetFirstChild();
322 CHECK_NULL_VOID(uiRow);
323 auto row = AceType::DynamicCast<FrameNode>(uiRow);
324 row->GetLayoutProperty()->UpdateVisibility(visible ? VisibleType::VISIBLE : VisibleType::GONE);
325 row->MarkModifyDone();
326 row->MarkDirtyNode();
327 isVisibleSetted = true;
328 }
329
SetRowColor(const std::optional<Color> & color)330 void AppBarView::SetRowColor(const std::optional<Color>& color)
331 {
332 CHECK_NULL_VOID(atom_);
333 auto uiRow = atom_->GetFirstChild();
334 CHECK_NULL_VOID(uiRow);
335 auto row = AceType::DynamicCast<FrameNode>(uiRow);
336 if (color) {
337 row->GetRenderContext()->UpdateBackgroundColor(color.value());
338 } else {
339 auto pipeline = PipelineContext::GetCurrentContext();
340 CHECK_NULL_VOID(pipeline);
341 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
342 row->GetRenderContext()->UpdateBackgroundColor(appBarTheme->GetBgColor());
343 }
344 row->MarkModifyDone();
345 row->MarkDirtyNode();
346 isRowColorSetted = color.has_value();
347 }
348
SetContent(const std::string & content)349 void AppBarView::SetContent(const std::string& content)
350 {
351 CHECK_NULL_VOID(atom_);
352 auto uiRow = atom_->GetFirstChild();
353 CHECK_NULL_VOID(uiRow);
354 auto uiLabel = uiRow->GetLastChild();
355 CHECK_NULL_VOID(uiLabel);
356 auto label = AceType::DynamicCast<FrameNode>(uiLabel);
357 label->GetLayoutProperty<TextLayoutProperty>()->UpdateContent(content);
358 label->MarkModifyDone();
359 label->MarkDirtyNode();
360 }
361
SetFontStyle(Ace::FontStyle fontStyle)362 void AppBarView::SetFontStyle(Ace::FontStyle fontStyle)
363 {
364 CHECK_NULL_VOID(atom_);
365 auto uiRow = atom_->GetFirstChild();
366 CHECK_NULL_VOID(uiRow);
367 auto uiLabel = uiRow->GetLastChild();
368 CHECK_NULL_VOID(uiLabel);
369 auto label = AceType::DynamicCast<FrameNode>(uiLabel);
370 label->GetLayoutProperty<TextLayoutProperty>()->UpdateItalicFontStyle(fontStyle);
371 label->MarkModifyDone();
372 label->MarkDirtyNode();
373 }
374
SetIconColor(const std::optional<Color> & color)375 void AppBarView::SetIconColor(const std::optional<Color>& color)
376 {
377 CHECK_NULL_VOID(atom_);
378 auto row = atom_->GetFirstChild();
379 CHECK_NULL_VOID(row);
380 auto backButton = row->GetFirstChild();
381 CHECK_NULL_VOID(backButton);
382 auto backIcon = AceType::DynamicCast<FrameNode>(backButton->GetFirstChild());
383 SetEachIconColor(backIcon, color, InternalResource::ResourceId::APP_BAR_BACK_SVG);
384 isIconColorSetted = color.has_value();
385 auto faButton = GetFaButton();
386 CHECK_NULL_VOID(faButton);
387 auto faIcon = AceType::DynamicCast<FrameNode>(faButton->GetFirstChild());
388 SetEachIconColor(faIcon, color, InternalResource::ResourceId::APP_BAR_FA_SVG);
389 }
390
SetRowWidth(const Dimension & width)391 void AppBarView::SetRowWidth(const Dimension& width)
392 {
393 auto pipeline = PipelineContext::GetCurrentContext();
394 CHECK_NULL_VOID(pipeline);
395 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
396 auto butttonRadius = appBarTheme->GetIconCornerRadius();
397 Dimension offset = appBarTheme->GetIconSize() * 3;
398 Dimension positionX = width - offset;
399 Dimension positionLeftX = appBarTheme->GetIconSize() - butttonRadius;
400 Dimension positionY = (appBarTheme->GetAppBarHeight() / 2.0f) - appBarTheme->GetIconSize();
401 auto faButton = GetFaButton();
402 CHECK_NULL_VOID(faButton);
403 auto renderContext = faButton->GetRenderContext();
404 CHECK_NULL_VOID(renderContext);
405 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
406 if (!isRtl) {
407 renderContext->UpdatePosition(OffsetT(positionX, positionY));
408 } else {
409 renderContext->UpdatePosition(OffsetT(positionLeftX, positionY));
410 }
411 }
412
SetEachIconColor(RefPtr<FrameNode> icon,const std::optional<Color> & color,InternalResource::ResourceId image)413 void AppBarView::SetEachIconColor(
414 RefPtr<FrameNode> icon, const std::optional<Color>& color, InternalResource::ResourceId image)
415 {
416 CHECK_NULL_VOID(icon);
417 ImageSourceInfo info;
418 if (color.has_value()) {
419 info.SetResourceId(image, color);
420 } else {
421 auto pipeline = PipelineContext::GetCurrentContext();
422 CHECK_NULL_VOID(pipeline);
423 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
424 info.SetResourceId(image, appBarTheme->GetTextColor());
425 }
426 icon->GetLayoutProperty<ImageLayoutProperty>()->UpdateImageSourceInfo(info);
427 icon->MarkModifyDone();
428 icon->MarkDirtyNode();
429 }
430
IniColor()431 void AppBarView::IniColor()
432 {
433 CHECK_NULL_VOID(atom_);
434 auto pipeline = PipelineContext::GetCurrentContext();
435 CHECK_NULL_VOID(pipeline);
436 auto appBarTheme = pipeline->GetTheme<AppBarTheme>();
437
438 auto row = atom_->GetFirstChild();
439 auto label = AceType::DynamicCast<FrameNode>(row->GetLastChild());
440 CHECK_NULL_VOID(label);
441 auto textLayoutProperty = label->GetLayoutProperty<TextLayoutProperty>();
442 CHECK_NULL_VOID(textLayoutProperty);
443 textLayoutProperty->UpdateTextColor(appBarTheme->GetTextColor());
444
445 if (!isRowColorSetted) {
446 SetRowColor(std::nullopt);
447 }
448
449 if (!isIconColorSetted) {
450 SetIconColor(std::nullopt);
451 }
452 }
453
GetFaButton()454 RefPtr<FrameNode> AppBarView::GetFaButton()
455 {
456 #ifndef IS_EMULATOR
457 CHECK_NULL_RETURN(atom_, nullptr);
458 return AceType::DynamicCast<FrameNode>(atom_->GetLastChild());
459 #endif
460 return nullptr;
461 }
462
GetBackButton()463 RefPtr<FrameNode> AppBarView::GetBackButton()
464 {
465 CHECK_NULL_RETURN(atom_, nullptr);
466 auto row = atom_->GetFirstChild();
467 CHECK_NULL_RETURN(row, nullptr);
468 return AceType::DynamicCast<FrameNode>(row->GetFirstChild());
469 }
470
ReverseBackButton()471 void AppBarView::ReverseBackButton()
472 {
473 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
474 auto backButton = GetBackButton();
475 CHECK_NULL_VOID(backButton);
476 auto renderContext = backButton->GetRenderContext();
477 CHECK_NULL_VOID(renderContext);
478 auto buttonLayoutProperty = backButton->GetLayoutProperty();
479 CHECK_NULL_VOID(buttonLayoutProperty);
480
481 MarginProperty buttonmargin;
482 bool isBackButton = true;
483 if (!isRtl) {
484 buttonmargin.left = CalcLength(isBackButton ? MARGIN_BUTTON : -MARGIN_BUTTON);
485 buttonmargin.right = CalcLength(isBackButton ? MARGIN_BACK_BUTTON_RIGHT : MARGIN_BUTTON);
486 renderContext->UpdateTransformScale(VectorF(UNCHANGED_X, UNCHANGED_Y));
487 } else {
488 buttonmargin.right = CalcLength(isBackButton ? MARGIN_BUTTON : -MARGIN_BUTTON);
489 buttonmargin.left = CalcLength(isBackButton ? MARGIN_BACK_BUTTON_RIGHT : MARGIN_BUTTON);
490 renderContext->UpdateTransformScale(VectorF(REVERSED_X, UNCHANGED_Y));
491 }
492 buttonLayoutProperty->UpdateMargin(buttonmargin);
493
494 backButton->MarkModifyDone();
495 backButton->MarkDirtyNode();
496 }
497
UpdateRowLayout()498 void AppBarView::UpdateRowLayout()
499 {
500 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
501 if (isRtlSetted == isRtl) {
502 return;
503 }
504 CHECK_NULL_VOID(atom_);
505 auto row = atom_->GetFirstChild();
506 auto label = AceType::DynamicCast<FrameNode>(row->GetChildAtIndex(1));
507 CHECK_NULL_VOID(label);
508 auto textLayoutProperty = label->GetLayoutProperty<TextLayoutProperty>();
509 MarginProperty textmargin;
510 if (!isRtl) {
511 textLayoutProperty->UpdateTextAlign(TextAlign::LEFT);
512 textmargin.left = CalcLength(MARGIN_TEXT_LEFT);
513 textmargin.right = CalcLength(MARGIN_TEXT_RIGHT);
514 isRtlSetted = false;
515 } else {
516 textLayoutProperty->UpdateTextAlign(TextAlign::RIGHT);
517 textmargin.right = CalcLength(MARGIN_TEXT_LEFT);
518 textmargin.left = CalcLength(MARGIN_TEXT_RIGHT);
519 isRtlSetted = true;
520 }
521 textLayoutProperty->UpdateMargin(textmargin);
522 label->MarkModifyDone();
523 label->MarkDirtyNode();
524
525 ReverseBackButton();
526 }
527 } // namespace OHOS::Ace::NG
528