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