• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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