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/option/option_component.h"
17
18 #include "base/utils/string_utils.h"
19 #include "base/utils/system_properties.h"
20 #include "core/common/container.h"
21 #include "core/components/box/box_component.h"
22 #include "core/components/common/properties/text_style.h"
23 #include "core/components/flex/flex_item_component.h"
24 #include "core/components/image/image_component.h"
25 #include "core/components/list/list_component.h"
26 #include "core/components/option/option_element.h"
27 #include "core/components/option/render_option.h"
28 #include "core/components/positioned/positioned_component.h"
29 #include "core/components/select/select_theme.h"
30
31 namespace OHOS::Ace {
32 namespace {
33
34 constexpr uint32_t SELECT_OPTION_TEXT_LINES = 2;
35 constexpr double MIN_TEXT_SIZE_TV = 14.0;
36 constexpr double MIN_TEXT_SIZE_PHONE = 9.0;
37
38 } // namespace
39
OptionComponent(const RefPtr<SelectTheme> & theme)40 OptionComponent::OptionComponent(const RefPtr<SelectTheme>& theme)
41 {
42 if (theme) {
43 theme_ = theme->clone();
44 theme_->SetFontWeight(FontWeight::W400);
45 }
46 }
47
InitTheme(const RefPtr<ThemeManager> & themeManager)48 void OptionComponent::InitTheme(const RefPtr<ThemeManager>& themeManager)
49 {
50 if (!themeManager) {
51 return;
52 }
53 auto selectTheme = themeManager->GetTheme<SelectTheme>();
54 if (!selectTheme) {
55 return;
56 }
57 theme_ = selectTheme->clone();
58 theme_->SetFontWeight(FontWeight::W400);
59 }
60
Initialize(const RefPtr<AccessibilityManager> & manager)61 bool OptionComponent::Initialize(const RefPtr<AccessibilityManager>& manager)
62 {
63 if (customComponent_) {
64 ClearChildren();
65 AppendChild(customComponent_);
66 return true;
67 }
68
69 if (!text_ || value_.empty()) {
70 LOGW("can not initialize now, text null or value empty.");
71 return false;
72 }
73
74 ClearChildren();
75
76 if (icon_) {
77 icon_->SetImageFit(ImageFit::SCALE_DOWN);
78 icon_->SetAlignment((SystemProperties::GetDeviceType() == DeviceType::TV ?
79 Alignment::CENTER : Alignment::CENTER_LEFT));
80 icon_->SetWidth(24.0_vp); // icon is only for phone which is fixes size 24dp*24dp
81 icon_->SetHeight(24.0_vp);
82 AppendChild(icon_);
83 }
84
85 auto container = Container::Current();
86 if (!container) {
87 return false;
88 }
89 auto context = container->GetPipelineContext();
90 if (!context) {
91 return false;
92 }
93 TextStyle textStyle;
94 if (context->GetIsDeclarative()) {
95 if (GetSelected()) {
96 textStyle = GetSelectedTextStyle();
97 text_->SetTextStyle(textStyle);
98 } else {
99 textStyle = GetTextStyle();
100 text_->SetTextStyle(textStyle);
101 }
102 textStyle.SetFontSize(GetFontSize());
103 textStyle.SetTextDecoration(GetTextDecoration());
104 text_->SetData(value_);
105 } else {
106 textStyle = text_->GetTextStyle();
107 std::vector<std::string> fontFamilies;
108 StringUtils::StringSplitter(GetFontFamily(), ',', fontFamilies);
109 if (!fontFamilies.empty()) {
110 textStyle.SetFontFamilies(fontFamilies);
111 }
112 textStyle.SetFontSize(GetFontSize());
113 textStyle.SetFontWeight(GetFontWeight());
114 textStyle.SetTextDecoration(GetTextDecoration());
115 if (GetDisabled() && theme_) {
116 textStyle.SetTextColor(theme_->GetFocusedTextDisableColor());
117 } else if (GetSelected() && theme_) {
118 textStyle.SetTextColor(theme_->GetSelectedColorText());
119 } else {
120 textStyle.SetTextColor(GetFontColor());
121 }
122 }
123 textStyle.SetAllowScale(IsAllowScale());
124 double minFontSize = (SystemProperties::GetDeviceType() == DeviceType::TV ?
125 MIN_TEXT_SIZE_TV : MIN_TEXT_SIZE_PHONE);
126 textStyle.SetAdaptTextSize(textStyle.GetFontSize(), Dimension(minFontSize, DimensionUnit::FP));
127 if (SystemProperties::GetDeviceType() == DeviceType::TV) {
128 textStyle.SetTextAlign(TextAlign::CENTER);
129 } else if (GetTextDirection() == TextDirection::RTL) {
130 textStyle.SetTextAlign(TextAlign::RIGHT);
131 } else {
132 textStyle.SetTextAlign(TextAlign::LEFT);
133 }
134 // use single line, do not change line.
135 textStyle.SetMaxLines(SELECT_OPTION_TEXT_LINES);
136 textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
137 text_->SetTextStyle(textStyle);
138 text_->SetFocusColor(textStyle.GetTextColor());
139 AppendChild(text_);
140 SetNode((!manager ? nullptr
141 : manager->CreateAccessibilityNode("option", StringUtils::StringToInt(GetId()), GetParentId(), -1)));
142 #if defined(PREVIEW)
143 if (node_) {
144 node_->SetAttr(GetAttr());
145 node_->SetStyle(GetStyle());
146 }
147 #endif
148 return true;
149 }
150
CheckOptionModify()151 void OptionComponent::CheckOptionModify()
152 {
153 if (!text_) {
154 LOGE("text is null of option component.");
155 return;
156 }
157 if (!modifiedCallback_) {
158 LOGD("modify callback of option component is null.");
159 return;
160 }
161 if (text_->GetData() == lastText_) {
162 return;
163 }
164 modifiedCallback_(GetIndex());
165 lastText_ = text_->GetData();
166 }
167
CreateRenderNode()168 RefPtr<RenderNode> OptionComponent::CreateRenderNode()
169 {
170 return RenderOption::Create();
171 }
172
CreateElement()173 RefPtr<Element> OptionComponent::CreateElement()
174 {
175 return AceType::MakeRefPtr<OptionElement>();
176 }
177
178 } // namespace OHOS::Ace
179