1 /*
2 * Copyright (c) 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 "bridge/declarative_frontend/jsview/models/text_field_model_impl.h"
17
18 #include "base/geometry/dimension.h"
19 #include "base/memory/referenced.h"
20 #include "base/utils/utils.h"
21 #include "bridge/declarative_frontend/jsview/js_textfield.h"
22 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
23 #include "bridge/declarative_frontend/view_stack_processor.h"
24 #include "core/components/common/layout/constants.h"
25 #include "core/components/common/properties/text_style.h"
26 #include "core/components/text_field/text_field_component.h"
27 #include "core/components/text_field/textfield_theme.h"
28 #include "core/components_ng/pattern/text_field/text_field_model.h"
29 #include "core/pipeline/pipeline_context.h"
30
31 namespace OHOS::Ace::Framework {
32 namespace {
33 const std::vector<std::string> INPUT_FONT_FAMILY_VALUE = { "sans-serif" };
34 constexpr Dimension INNER_PADDING = 0.0_vp;
35 } // namespace
36
CreateTextInput(const std::optional<std::string> & placeholder,const std::optional<std::string> & value)37 RefPtr<TextFieldControllerBase> TextFieldModelImpl::CreateTextInput(
38 const std::optional<std::string>& placeholder, const std::optional<std::string>& value)
39 {
40 auto textInputComponent = AceType::MakeRefPtr<TextFieldComponent>();
41 if (placeholder) {
42 textInputComponent->SetPlaceholder(placeholder.value());
43 }
44 if (value) {
45 textInputComponent->SetValue(value.value());
46 }
47 ViewStackProcessor::GetInstance()->ClaimElementId(textInputComponent);
48 textInputComponent->SetTextFieldController(AceType::MakeRefPtr<TextFieldController>());
49 // default type is text, default action is done.
50 textInputComponent->SetTextInputType(TextInputType::TEXT);
51 textInputComponent->SetAction(TextInputAction::DONE);
52 textInputComponent->SetInspectorTag("TextInput");
53 textInputComponent->SetHoverAnimationType(HoverAnimationType::BOARD);
54 ViewStackProcessor::GetInstance()->Push(textInputComponent);
55 InitTextInputDefaultStyle();
56 Border boxBorder;
57 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
58 auto pipeline = PipelineContext::GetCurrentContext();
59 if (pipeline) {
60 auto theme = pipeline->GetThemeManager()->GetTheme<TextFieldTheme>();
61 if (boxComponent->GetBackDecoration()) {
62 boxBorder = boxComponent->GetBackDecoration()->GetBorder();
63 }
64 JSTextField::UpdateDecoration(boxComponent, textInputComponent, boxBorder, theme);
65 }
66
67 return textInputComponent->GetTextFieldController();
68 }
69
InitTextInputDefaultStyle()70 void TextFieldModelImpl::InitTextInputDefaultStyle()
71 {
72 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
73 auto* stack = ViewStackProcessor::GetInstance();
74 auto textInputComponent = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
75 auto theme = JSViewAbstract::GetTheme<TextFieldTheme>();
76 if (!boxComponent || !textInputComponent || !theme) {
77 return;
78 }
79
80 textInputComponent->SetCursorColor(theme->GetCursorColor());
81 textInputComponent->SetCursorRadius(theme->GetCursorRadius());
82 textInputComponent->SetPlaceholderColor(theme->GetPlaceholderColor());
83 textInputComponent->SetFocusBgColor(theme->GetFocusBgColor());
84 textInputComponent->SetFocusPlaceholderColor(theme->GetFocusPlaceholderColor());
85 textInputComponent->SetFocusTextColor(theme->GetFocusTextColor());
86 textInputComponent->SetBgColor(theme->GetBgColor());
87 textInputComponent->SetTextColor(theme->GetTextColor());
88 textInputComponent->SetSelectedColor(theme->GetSelectedColor());
89 textInputComponent->SetHoverColor(theme->GetHoverColor());
90 textInputComponent->SetPressColor(theme->GetPressColor());
91 textInputComponent->SetNeedFade(theme->NeedFade());
92 textInputComponent->SetShowEllipsis(theme->ShowEllipsis());
93
94 TextStyle textStyle = textInputComponent->GetTextStyle();
95 textStyle.SetTextColor(theme->GetTextColor());
96 textStyle.SetFontSize(theme->GetFontSize());
97 textStyle.SetFontWeight(theme->GetFontWeight());
98 textStyle.SetFontFamilies(INPUT_FONT_FAMILY_VALUE);
99 textInputComponent->SetTextStyle(textStyle);
100 textInputComponent->SetEditingStyle(textStyle);
101 textInputComponent->SetPlaceHoldStyle(textStyle);
102
103 textInputComponent->SetCountTextStyle(theme->GetCountTextStyle());
104 textInputComponent->SetOverCountStyle(theme->GetOverCountStyle());
105 textInputComponent->SetCountTextStyleOuter(theme->GetCountTextStyleOuter());
106 textInputComponent->SetOverCountStyleOuter(theme->GetOverCountStyleOuter());
107
108 textInputComponent->SetErrorTextStyle(theme->GetErrorTextStyle());
109 textInputComponent->SetErrorSpacing(theme->GetErrorSpacing());
110 textInputComponent->SetErrorIsInner(theme->GetErrorIsInner());
111 textInputComponent->SetErrorBorderWidth(theme->GetErrorBorderWidth());
112 textInputComponent->SetErrorBorderColor(theme->GetErrorBorderColor());
113
114 RefPtr<Decoration> decoration = AceType::MakeRefPtr<Decoration>();
115 // Need to update when UX of PC supported.
116 auto edge = theme->GetPadding();
117 edge.SetTop(INNER_PADDING);
118 edge.SetBottom(INNER_PADDING);
119 decoration->SetPadding(edge);
120 decoration->SetBackgroundColor(theme->GetBgColor());
121 decoration->SetBorderRadius(theme->GetBorderRadius());
122 const auto& boxDecoration = boxComponent->GetBackDecoration();
123 if (boxDecoration) {
124 decoration->SetImage(boxDecoration->GetImage());
125 decoration->SetGradient(boxDecoration->GetGradient());
126 }
127 textInputComponent->SetOriginBorder(decoration->GetBorder());
128 textInputComponent->SetDecoration(decoration);
129 textInputComponent->SetIconSize(theme->GetIconSize());
130 textInputComponent->SetIconHotZoneSize(theme->GetIconHotZoneSize());
131 textInputComponent->SetHeight(theme->GetHeight());
132 }
133
SetType(TextInputType value)134 void TextFieldModelImpl::SetType(TextInputType value)
135 {
136 auto* stack = ViewStackProcessor::GetInstance();
137 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
138 CHECK_NULL_VOID(component);
139 component->SetTextInputType(value);
140 component->SetObscure(value == TextInputType::VISIBLE_PASSWORD);
141 }
142
SetPlaceholderColor(const Color & value)143 void TextFieldModelImpl::SetPlaceholderColor(const Color& value)
144 {
145 auto* stack = ViewStackProcessor::GetInstance();
146 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
147 CHECK_NULL_VOID(component);
148 component->SetPlaceholderColor(value);
149 component->SetFocusPlaceholderColor(value);
150 }
151
SetPlaceholderFont(const Font & value)152 void TextFieldModelImpl::SetPlaceholderFont(const Font& value)
153 {
154 auto* stack = ViewStackProcessor::GetInstance();
155 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
156 CHECK_NULL_VOID(component);
157 auto textStyle = component->GetPlaceHoldStyle();
158 if (value.fontSize && value.fontSize->IsNonNegative()) {
159 textStyle.SetFontSize(value.fontSize.value());
160 }
161 if (value.fontWeight) {
162 textStyle.SetFontWeight(value.fontWeight.value());
163 }
164 if (value.fontStyle) {
165 textStyle.SetFontStyle(value.fontStyle.value());
166 }
167 if (!value.fontFamilies.empty()) {
168 textStyle.SetFontFamilies(value.fontFamilies);
169 }
170 component->SetPlaceHoldStyle(textStyle);
171 }
172
SetEnterKeyType(TextInputAction value)173 void TextFieldModelImpl::SetEnterKeyType(TextInputAction value)
174 {
175 auto* stack = ViewStackProcessor::GetInstance();
176 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
177 CHECK_NULL_VOID(component);
178 component->SetAction(value);
179 }
180
SetTextAlign(TextAlign value)181 void TextFieldModelImpl::SetTextAlign(TextAlign value)
182 {
183 auto* stack = ViewStackProcessor::GetInstance();
184 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
185 CHECK_NULL_VOID(component);
186 component->SetTextAlign(value);
187 }
188
SetInputStyle(InputStyle value)189 void TextFieldModelImpl::SetInputStyle(InputStyle value)
190 {
191 auto* stack = ViewStackProcessor::GetInstance();
192 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
193 CHECK_NULL_VOID(component);
194 component->SetInputStyle(value);
195 }
196
SetCaretColor(const Color & value)197 void TextFieldModelImpl::SetCaretColor(const Color& value)
198 {
199 auto* stack = ViewStackProcessor::GetInstance();
200 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
201 CHECK_NULL_VOID(component);
202 component->SetCursorColor(value);
203 }
204
SetMaxLength(uint32_t value)205 void TextFieldModelImpl::SetMaxLength(uint32_t value)
206 {
207 auto* stack = ViewStackProcessor::GetInstance();
208 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
209 CHECK_NULL_VOID(component);
210 component->SetMaxLength(value);
211 }
212
SetMaxLines(uint32_t value)213 void TextFieldModelImpl::SetMaxLines(uint32_t value)
214 {
215 auto* stack = ViewStackProcessor::GetInstance();
216 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
217 CHECK_NULL_VOID(component);
218 component->SetTextMaxLines(value);
219 }
220
SetFontSize(const Dimension & value)221 void TextFieldModelImpl::SetFontSize(const Dimension& value)
222 {
223 if (value.IsNegative()) {
224 return;
225 }
226 auto* stack = ViewStackProcessor::GetInstance();
227 auto component = AceType::DynamicCast<TextFieldComponent>(stack->GetMainComponent());
228 CHECK_NULL_VOID(component);
229 auto textStyle = component->GetEditingStyle();
230 textStyle.SetFontSize(value);
231 component->SetEditingStyle(textStyle);
232 }
233
SetFontWeight(FontWeight value)234 void TextFieldModelImpl::SetFontWeight(FontWeight value)
235 {
236 auto* stack = ViewStackProcessor::GetInstance();
237 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
238 CHECK_NULL_VOID(component);
239 auto textStyle = component->GetEditingStyle();
240 textStyle.SetFontWeight(value);
241 component->SetEditingStyle(textStyle);
242 }
243
SetTextColor(const Color & value)244 void TextFieldModelImpl::SetTextColor(const Color& value)
245 {
246 auto* stack = ViewStackProcessor::GetInstance();
247 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
248 CHECK_NULL_VOID(component);
249 auto textStyle = component->GetEditingStyle();
250 textStyle.SetTextColor(value);
251 component->SetEditingStyle(textStyle);
252 }
253
SetFontStyle(FontStyle value)254 void TextFieldModelImpl::SetFontStyle(FontStyle value)
255 {
256 auto* stack = ViewStackProcessor::GetInstance();
257 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
258 CHECK_NULL_VOID(component);
259 auto textStyle = component->GetEditingStyle();
260 textStyle.SetFontStyle(value);
261 component->SetEditingStyle(textStyle);
262 }
263
SetFontFamily(const std::vector<std::string> & value)264 void TextFieldModelImpl::SetFontFamily(const std::vector<std::string>& value)
265 {
266 auto* stack = ViewStackProcessor::GetInstance();
267 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
268 CHECK_NULL_VOID(component);
269 auto textStyle = component->GetEditingStyle();
270 textStyle.SetFontFamilies(value);
271 component->SetEditingStyle(textStyle);
272 }
273
SetInputFilter(const std::string & value,const std::function<void (const std::string &)> & onError)274 void TextFieldModelImpl::SetInputFilter(
275 const std::string& value, const std::function<void(const std::string&)>& onError)
276 {
277 auto* stack = ViewStackProcessor::GetInstance();
278 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
279 CHECK_NULL_VOID(component);
280 component->SetInputFilter(value);
281
282 if (onError) {
283 component->SetOnError(onError);
284 }
285 }
286
SetShowPasswordIcon(bool value)287 void TextFieldModelImpl::SetShowPasswordIcon(bool value)
288 {
289 auto* stack = ViewStackProcessor::GetInstance();
290 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
291 CHECK_NULL_VOID(component);
292 component->SetShowPasswordIcon(value);
293 }
294
SetOnEditChanged(std::function<void (bool)> && func)295 void TextFieldModelImpl::SetOnEditChanged(std::function<void(bool)>&& func)
296 {
297 auto* stack = ViewStackProcessor::GetInstance();
298 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
299 CHECK_NULL_VOID(component);
300 component->SetOnEditChanged(std::move(func));
301 }
302
SetOnSubmit(std::function<void (int32_t)> && func)303 void TextFieldModelImpl::SetOnSubmit(std::function<void(int32_t)>&& func)
304 {
305 auto* stack = ViewStackProcessor::GetInstance();
306 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
307 CHECK_NULL_VOID(component);
308 component->SetOnSubmit(std::move(func));
309 }
310
SetOnChange(std::function<void (const std::string &)> && func)311 void TextFieldModelImpl::SetOnChange(std::function<void(const std::string&)>&& func)
312 {
313 auto* stack = ViewStackProcessor::GetInstance();
314 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
315 CHECK_NULL_VOID(component);
316 component->SetOnChange(std::move(func));
317 }
318
SetOnCopy(std::function<void (const std::string &)> && func)319 void TextFieldModelImpl::SetOnCopy(std::function<void(const std::string&)>&& func)
320 {
321 auto* stack = ViewStackProcessor::GetInstance();
322 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
323 CHECK_NULL_VOID(component);
324 component->SetOnCopy(std::move(func));
325 }
326
SetOnCut(std::function<void (const std::string &)> && func)327 void TextFieldModelImpl::SetOnCut(std::function<void(const std::string&)>&& func)
328 {
329 auto* stack = ViewStackProcessor::GetInstance();
330 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
331 CHECK_NULL_VOID(component);
332 component->SetOnCut(std::move(func));
333 }
334
SetOnPaste(std::function<void (const std::string &)> && func)335 void TextFieldModelImpl::SetOnPaste(std::function<void(const std::string&)>&& func)
336 {
337 auto* stack = ViewStackProcessor::GetInstance();
338 auto component = AceType::DynamicCast<OHOS::Ace::TextFieldComponent>(stack->GetMainComponent());
339 CHECK_NULL_VOID(component);
340 component->SetOnPaste(std::move(func));
341 }
342
SetCopyOption(CopyOptions copyOption)343 void TextFieldModelImpl::SetCopyOption(CopyOptions copyOption)
344 {
345 JSViewSetProperty(&TextFieldComponent::SetCopyOption, copyOption);
346 }
347
348 } // namespace OHOS::Ace::Framework
349