1 /*
2 * Copyright (c) 2021 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/select/select_component.h"
17
18 #include "core/components/clip/clip_component.h"
19 #include "core/components/flex/flex_item_component.h"
20 #include "core/components/select/render_select.h"
21 #include "core/components/select/select_element.h"
22 #include "core/components/triangle/triangle_component.h"
23
24 namespace OHOS::Ace {
25 namespace {
26
27 constexpr uint32_t SELECT_ITSELF_TEXT_LINES = 1;
28
29 }
30
SelectComponent()31 SelectComponent::SelectComponent() : SoleChildComponent()
32 {
33 popup_ = AceType::MakeRefPtr<SelectPopupComponent>();
34 // the round radius is half of height which is 40dp.
35 border_.SetBorderRadius(Radius(20.0_vp));
36 }
37
InitTheme(const RefPtr<ThemeManager> & themeManager)38 void SelectComponent::InitTheme(const RefPtr<ThemeManager>& themeManager)
39 {
40 if (!themeManager) {
41 return;
42 }
43 popup_->InitTheme(themeManager);
44 #if defined(PREVIEW)
45 popup_->SetSelectPopupId(GetNodeId());
46 #endif
47 auto selectTheme = themeManager->GetTheme<SelectTheme>();
48 if (!selectTheme) {
49 return;
50 }
51 theme_ = selectTheme->clone();
52 theme_->SetFontWeight(FontWeight::W500);
53
54 innerPadding_ =
55 Edge(8.0, 9.25, 8.0, 9.25, DimensionUnit::VP); // the best effect for round triangle.
56 }
57
Initialize()58 bool SelectComponent::Initialize()
59 {
60 if (!tipText_) {
61 LOGE("can not initialize, tip text is null.");
62 return false;
63 }
64
65 RefPtr<TriangleComponent> icon = AceType::MakeRefPtr<TriangleComponent>();
66 icon->SetWidth(10.0_vp); // the with is 10dp from doc.
67 icon->SetHeight(6.0_vp); // the height is 7dp from doc. reduce 1dp for triangle inner.
68
69 RefPtr<BoxComponent> space = AceType::MakeRefPtr<BoxComponent>();
70 space->SetDeliverMinToChild(false);
71 space->SetAlignment(Alignment::CENTER);
72 // the space between text and triangle is 8dp from doc.
73 Edge spaceEdge(8.0, 0.0, 0.0, 0.0, DimensionUnit::VP);
74 if (GetTextDirection() == TextDirection::RTL) {
75 spaceEdge.SetRight(spaceEdge.Left());
76 spaceEdge.SetLeft(0.0_vp);
77 }
78 space->SetPadding(spaceEdge);
79 space->SetChild(icon);
80
81 auto container = Container::Current();
82 if (!container) {
83 return false;
84 }
85 auto context = container->GetPipelineContext();
86 if (!context) {
87 return false;
88 }
89 TextStyle textStyle;
90 if (context->GetIsDeclarative()) {
91 textStyle = GetSelectStyle();
92 if (disabled_) {
93 textStyle.SetTextColor(theme_->GetDisabledColor());
94 }
95 } else {
96 textStyle = tipText_->GetTextStyle();
97 textStyle.SetFontSize(theme_->GetFontSize());
98 textStyle.SetFontWeight(theme_->GetFontWeight());
99 if (disabled_) {
100 textStyle.SetTextColor(theme_->GetDisabledColor());
101 } else {
102 textStyle.SetTextColor(theme_->GetFontColor());
103 }
104 std::vector<std::string> fontFamilies;
105 StringUtils::StringSplitter(theme_->GetFontFamily(), ',', fontFamilies);
106 if (!fontFamilies.empty()) {
107 textStyle.SetFontFamilies(fontFamilies);
108 }
109 }
110
111 textStyle.SetAllowScale(theme_->IsAllowScale());
112 textStyle.SetTextDecoration(theme_->GetTextDecoration());
113 textStyle.SetMaxLines(SELECT_ITSELF_TEXT_LINES);
114 textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
115 tipText_->SetTextStyle(textStyle);
116 tipText_->SetFocusColor(textStyle.GetTextColor());
117 icon->SetColor(textStyle.GetTextColor());
118 RefPtr<FlexItemComponent> textItem = AceType::MakeRefPtr<FlexItemComponent>(0.0, 1.0, 0.0, tipText_);
119
120 RefPtr<RowComponent> row =
121 AceType::MakeRefPtr<RowComponent>(FlexAlign::CENTER, FlexAlign::CENTER, std::list<RefPtr<Component>>());
122 row->SetMainAxisSize(MainAxisSize::MIN);
123 if (GetTextDirection() == TextDirection::RTL) {
124 row->AppendChild(space);
125 row->AppendChild(textItem);
126 } else {
127 row->AppendChild(textItem);
128 row->AppendChild(space);
129 }
130
131 RefPtr<Decoration> backDecoration = AceType::MakeRefPtr<Decoration>();
132 backDecoration->SetBackgroundColor(backgroundColor_);
133 backDecoration->SetBorder(border_);
134
135 RefPtr<BoxComponent> box = AceType::MakeRefPtr<BoxComponent>();
136 box->SetDeliverMinToChild(false);
137 box->SetAlignment(Alignment::CENTER);
138 box->SetBackDecoration(backDecoration);
139 box->SetPadding(innerPadding_);
140 box->SetWidth(width_.Value(), width_.Unit());
141 box->SetHeight(height_.Value(), height_.Unit());
142 box->SetChild(AceType::MakeRefPtr<ClipComponent>(row));
143 boxComponent_ = box;
144 boxComponent_->SetMouseAnimationType(HoverAnimationType::OPACITY);
145 SetChild(box);
146 return true;
147 }
148
CreateRenderNode()149 RefPtr<RenderNode> SelectComponent::CreateRenderNode()
150 {
151 return AceType::MakeRefPtr<RenderSelect>();
152 }
153
CreateElement()154 RefPtr<Element> SelectComponent::CreateElement()
155 {
156 auto refPtr = AceType::MakeRefPtr<SelectElement>();
157 flushRefreshCallback_ = [weakPtr = WeakPtr<SelectElement>(refPtr)]() {
158 auto element = weakPtr.Upgrade();
159 if (!element) {
160 return;
161 }
162 element->FlushRefresh();
163 };
164 return refPtr;
165 }
166
SetClicked(bool clicked,const Color & pressColor)167 void SelectComponent::SetClicked(bool clicked, const Color& pressColor)
168 {
169 clicked_ = clicked;
170 if (!boxComponent_) {
171 LOGE("select: box is null, can not set background color when click changed.");
172 return;
173 }
174
175 auto backDecoration = boxComponent_->GetBackDecoration();
176 if (!backDecoration) {
177 backDecoration = AceType::MakeRefPtr<Decoration>();
178 }
179 backDecoration->SetBackgroundColor(backgroundColor_.BlendColor(pressColor));
180 boxComponent_->SetBackDecoration(backDecoration);
181 }
182
GetPopup() const183 RefPtr<SelectPopupComponent> SelectComponent::GetPopup() const
184 {
185 if (!popup_) {
186 LOGE("select: popup is null now.");
187 return nullptr;
188 }
189
190 return popup_;
191 }
192
GetBoxComponent() const193 RefPtr<BoxComponent> SelectComponent::GetBoxComponent() const
194 {
195 if (!boxComponent_) {
196 LOGE("select: box component of background color is null.");
197 return nullptr;
198 }
199
200 return boxComponent_;
201 }
202
203 } // namespace OHOS::Ace
204