1 /*
2  * Copyright (c) 2021-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 "frameworks/bridge/common/dom/dom_stepper_item.h"
17 
18 #include "core/components/focus_animation/focus_animation_theme.h"
19 #include "core/components/stepper/stepper_theme.h"
20 #include "frameworks/bridge/common/utils/utils.h"
21 
22 namespace OHOS::Ace::Framework {
23 namespace {
24 
25 constexpr double DEFAULT_OPACITY = 1.0;
26 
27 } // namespace
28 
DOMStepperItem(NodeId nodeId,const std::string & nodeName,int32_t index)29 DOMStepperItem::DOMStepperItem(NodeId nodeId, const std::string& nodeName, int32_t index) : DOMNode(nodeId, nodeName)
30 {
31     itemIndex_ = index;
32     stepperItemComponent_ = AceType::MakeRefPtr<StepperItemComponent>(RefPtr<Component>());
33 }
34 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)35 bool DOMStepperItem::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
36 {
37     static const LinearMapNode<void (*)(const std::string&, DOMStepperItem&)> stepperItemStyleOperators[] = {
38         { DOM_ALIGN_ITEMS, [](const std::string& val,
39             DOMStepperItem& stepperItem) { stepperItem.flexCrossAlign_ = ConvertStrToFlexAlign(val); } },
40         { DOM_TEXT_ALLOW_SCALE,
41             [](const std::string& value, DOMStepperItem& stepperItem) {
42               stepperItem.textStyle_.SetAllowScale(StringToBool(value));
43             } },
44         { DOM_STEPPER_TEXT_COLOR,
45             [](const std::string& value, DOMStepperItem& stepperItem) {
46               stepperItem.textStyle_.SetTextColor(stepperItem.ParseColor(value));
47             } },
48         { DOM_FLEX_DIRECTION, [](const std::string& val,
49             DOMStepperItem& stepperItem) { stepperItem.flexDirection_ = ConvertStrToFlexDirection(val); } },
50         { DOM_STEPPER_FONT_FAMILY,
51             [](const std::string& value, DOMStepperItem& stepperItem) {
52               stepperItem.textStyle_.SetFontFamilies(ConvertStrToFontFamilies(value));
53             } },
54         { DOM_STEPPER_FONT_SIZE,
55             [](const std::string& value, DOMStepperItem& stepperItem) {
56               stepperItem.textStyle_.SetFontSize(stepperItem.ParseDimension(value));
57             } },
58         { DOM_STEPPER_FONT_STYLE,
59             [](const std::string& value, DOMStepperItem& stepperItem) {
60               stepperItem.textStyle_.SetFontStyle(ConvertStrToFontStyle(value));
61             } },
62         { DOM_STEPPER_FONT_WEIGHT,
63             [](const std::string& value, DOMStepperItem& stepperItem) {
64               stepperItem.textStyle_.SetFontWeight(ConvertStrToFontWeight(value));
65             } },
66         { DOM_JUSTIFY_CONTENT, [](const std::string& val,
67             DOMStepperItem& stepperItem) { stepperItem.flexMainAlign_ = ConvertStrToFlexAlign(val); } },
68         { DOM_STEPPER_TEXT_DECORATION,
69             [](const std::string& value, DOMStepperItem& stepperItem) {
70               stepperItem.textStyle_.SetTextDecoration(ConvertStrToTextDecoration(value));
71             } },
72     };
73     auto operatorIter = BinarySearchFindIndex(stepperItemStyleOperators,
74         ArraySize(stepperItemStyleOperators), style.first.c_str());
75     if (operatorIter != -1) {
76         stepperItemStyleOperators[operatorIter].value(style.second, *this);
77         return true;
78     }
79     return  false;
80 }
81 
InitializeStyle()82 void DOMStepperItem::InitializeStyle()
83 {
84     auto theme = GetTheme<StepperTheme>();
85     if (!theme) {
86         return;
87     }
88     textStyle_ = theme->GetTextStyle();
89     textStyle_.SetAdaptTextSize(theme->GetTextStyle().GetFontSize(), theme->GetMinFontSize());
90     textStyle_.SetMaxLines(theme->GetTextMaxLines());
91     textStyle_.SetTextOverflow(TextOverflow::ELLIPSIS);
92 }
93 
AddSpecializedEvent(int32_t pageId,const std::string & event)94 bool DOMStepperItem::AddSpecializedEvent(int32_t pageId, const std::string& event)
95 {
96     if (event == DOM_STEPPER_ITEM_EVENT_APPEAR) {
97         appearEventId_ = EventMarker(GetNodeIdForEvent(), event, pageId);
98         stepperItemComponent_->SetAppearEventId(appearEventId_);
99         return true;
100     } else if (event == DOM_STEPPER_ITEM_EVENT_DISAPPEAR) {
101         disappearEventId_ = EventMarker(GetNodeIdForEvent(), event, pageId);
102         stepperItemComponent_->SetDisappearEventId(disappearEventId_);
103         return true;
104     } else {
105         return false;
106     }
107 }
108 
AddStepperItem(const RefPtr<DOMNode> & node,int32_t slot)109 void DOMStepperItem::AddStepperItem(const RefPtr<DOMNode>& node, int32_t slot)
110 {
111     const auto& childComponent = node->GetRootComponent();
112     if (!flexComponent_) {
113         flexComponent_ = AceType::MakeRefPtr<FlexComponent>(
114             flexDirection_, flexMainAlign_, flexCrossAlign_, std::list<RefPtr<Component>>());
115     }
116     flexComponent_->InsertChild(slot, childComponent);
117     Component::MergeRSNode(childComponent, flexComponent_);
118 }
119 
RemoveStepperItem(const RefPtr<DOMNode> & node)120 void DOMStepperItem::RemoveStepperItem(const RefPtr<DOMNode>& node)
121 {
122     const auto& childComponent = node->GetRootComponent();
123     if (flexComponent_) {
124         flexComponent_->RemoveChild(childComponent);
125     }
126 }
127 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)128 void DOMStepperItem::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
129 {
130     if (child) {
131         AddStepperItem(child, slot);
132     }
133 }
134 
OnChildNodeRemoved(const RefPtr<DOMNode> & child)135 void DOMStepperItem::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
136 {
137     if (child) {
138         RemoveStepperItem(child);
139     }
140 }
141 
PrepareSpecializedComponent()142 void DOMStepperItem::PrepareSpecializedComponent()
143 {
144     if (!stepperItemComponent_) {
145         stepperItemComponent_ = AceType::MakeRefPtr<StepperItemComponent>(RefPtr<Component>());
146     }
147     stepperItemComponent_->SetLabel(GetLabel());
148     stepperItemComponent_->SetTextStyle(textStyle_);
149     ResetInitializedStyle();
150 
151     if (flexComponent_) {
152         flexComponent_->SetDirection(flexDirection_);
153         flexComponent_->SetMainAxisAlign(flexMainAlign_);
154         flexComponent_->SetCrossAxisAlign(flexCrossAlign_);
155     } else {
156         flexComponent_ = AceType::MakeRefPtr<FlexComponent>(
157             flexDirection_, flexMainAlign_, flexCrossAlign_, std::list<RefPtr<Component>>());
158         flexComponent_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
159     }
160 
161     if (displayComponent_) {
162         displayComponent_->SetVisible(VisibleType::VISIBLE);
163         displayComponent_->SetOpacity(DEFAULT_OPACITY);
164     } else {
165         displayComponent_ = AceType::MakeRefPtr<DisplayComponent>();
166     }
167 }
168 
CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>> & components)169 RefPtr<Component> DOMStepperItem::CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>>& components)
170 {
171     auto scroll = AceType::MakeRefPtr<ScrollComponent>(flexComponent_);
172     scroll->SetTakeBoundary(false);
173     RefPtr<Component> component = scroll;
174 
175     if (!components.empty()) {
176         const auto& parent = components.back();
177         if (parent) {
178             parent->SetChild(component);
179         }
180         component = AceType::DynamicCast<Component>(components.front());
181     }
182 
183     if (stepperItemComponent_) {
184         if (displayComponent_) {
185             displayComponent_->SetChild(component);
186             stepperItemComponent_->SetChild(displayComponent_);
187         } else {
188             stepperItemComponent_->SetChild(component);
189         }
190     }
191     return stepperItemComponent_;
192 }
193 
ResetInitializedStyle()194 void DOMStepperItem::ResetInitializedStyle()
195 {
196     if (!stepperItemComponent_) {
197         return;
198     }
199     auto theme = GetTheme<FocusAnimationTheme>();
200     if (theme) {
201         stepperItemComponent_->SetFocusAnimationColor(theme->GetColor());
202     }
203 }
204 
205 } // namespace OHOS::Ace::Framework
206