mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-27 01:03:08 +00:00
!41628 【收编】【TextInput/Search】渐隐&&差异化配置——功能代码
Merge pull request !41628 from zhangwenbin00001/pr-textinput-0822-8-24
This commit is contained in:
commit
c11a042d54
@ -91,6 +91,8 @@ static const std::set<std::string> stringAttrs = {
|
||||
"textfield_accessibility_hide_password",
|
||||
"rich_editor_show_handle",
|
||||
"text_show_handle",
|
||||
"list_fadeout_enable",
|
||||
"text_fadeout_enable",
|
||||
"slider_accessibility_selected",
|
||||
"slider_accessibility_unselected",
|
||||
"slider_accessibility_unselectedDesc",
|
||||
|
@ -92,6 +92,13 @@ public:
|
||||
theme->symbolIconColor_ = pattern->GetAttr<Color>("search_symbol_icon_color", Color());
|
||||
theme->searchSymbolId_ = themeConstants->GetSymbolByName("sys.symbol.magnifyingglass");
|
||||
theme->cancelSymbolId_ = themeConstants->GetSymbolByName("sys.symbol.xmark");
|
||||
theme->borderColor_ = pattern->GetAttr<Color>("search_border_color", Color());
|
||||
theme->borderWidth_ = pattern->GetAttr<Dimension>("search_border_width", 0.0_vp);
|
||||
theme->focusBgColor_ = pattern->GetAttr<Color>("search_focus_bg_color", Color());
|
||||
theme->focusIconColor_ = pattern->GetAttr<Color>("search_focus_icon_color", Color());
|
||||
theme->needFocusBox_ = static_cast<bool>(pattern->GetAttr<double>("search_need_focus_box", 0.0));
|
||||
theme->cancelButtonStyle_ = static_cast<CancelButtonStyle>(
|
||||
static_cast<int32_t>(pattern->GetAttr<double>("search_cancel_button_style", 2.0f)));
|
||||
}
|
||||
};
|
||||
|
||||
@ -257,6 +264,31 @@ public:
|
||||
return symbolIconColor_;
|
||||
}
|
||||
|
||||
const Color& GetBorderColor() const
|
||||
{
|
||||
return borderColor_;
|
||||
}
|
||||
|
||||
const Dimension& GetBorderWidth() const
|
||||
{
|
||||
return borderWidth_;
|
||||
}
|
||||
|
||||
const Color& GetFocusBgColor() const
|
||||
{
|
||||
return focusBgColor_;
|
||||
}
|
||||
|
||||
const Color& GetFocusIconColor() const
|
||||
{
|
||||
return focusIconColor_;
|
||||
}
|
||||
|
||||
bool NeedFocusBox() const
|
||||
{
|
||||
return needFocusBox_;
|
||||
}
|
||||
|
||||
protected:
|
||||
SearchTheme() = default;
|
||||
|
||||
@ -293,6 +325,11 @@ private:
|
||||
uint32_t searchSymbolId_ = 0;
|
||||
uint32_t cancelSymbolId_ = 0;
|
||||
Color symbolIconColor_;
|
||||
Color borderColor_;
|
||||
Dimension borderWidth_;
|
||||
Color focusBgColor_;
|
||||
Color focusIconColor_;
|
||||
bool needFocusBox_ = false;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
ParsePatternSubFirstPart(pattern, theme);
|
||||
ParsePatternSubSecondPart(pattern, theme);
|
||||
ParsePatternSubThirdPart(pattern, theme);
|
||||
ParsePatternSubFourthPart(pattern, theme);
|
||||
}
|
||||
|
||||
void ParsePatternSubFirstPart(const RefPtr<ThemeStyle>& pattern, const RefPtr<TextFieldTheme>& theme) const
|
||||
@ -216,6 +217,22 @@ public:
|
||||
theme->aiWriteAbilityName_ = pattern->GetAttr<std::string>("textfield_writting_ability_name", "");
|
||||
|
||||
}
|
||||
|
||||
void ParsePatternSubFourthPart(const RefPtr<ThemeStyle>& pattern, const RefPtr<TextFieldTheme>& theme) const
|
||||
{
|
||||
std::string isTextFadeout = pattern->GetAttr<std::string>("text_fadeout_enable", "");
|
||||
theme->textFadeoutEnabled_ = isTextFadeout == "true";
|
||||
theme->textInputBorderColor_ = pattern->GetAttr<Color>("text_input_border_color", Color());
|
||||
theme->textInputBorderWidth_ = pattern->GetAttr<Dimension>("text_input_border_width", 0.0_vp);
|
||||
theme->errorTextInputBorderWidth_ = pattern->GetAttr<Dimension>("error_text_input_border_width", 1.0_vp);
|
||||
theme->textInputAndErrTipsSpacing_ =
|
||||
pattern->GetAttr<Dimension>("text_input_and_error_tips_spacing", 8.0_vp);
|
||||
theme->showPasswordIcon_ = static_cast<bool>(pattern->GetAttr<double>("show_icon_text_input", 1.0));
|
||||
theme->hoverAndPressBgColorEnabled_ =
|
||||
static_cast<uint32_t>(pattern->GetAttr<int>("textfield_hover_press_bg_color_enabled", 0));
|
||||
theme->needFocusBox_ = static_cast<bool>(pattern->GetAttr<double>("text_input_need_focus_box", 0.0));
|
||||
theme->focusPadding_ = pattern->GetAttr<Dimension>("text_input_focus_padding", 0.0_vp);
|
||||
}
|
||||
};
|
||||
|
||||
~TextFieldTheme() override = default;
|
||||
@ -637,6 +654,52 @@ public:
|
||||
{
|
||||
return aiWriteAbilityName_;
|
||||
}
|
||||
|
||||
bool TextFadeoutEnabled() const
|
||||
{
|
||||
return textFadeoutEnabled_;
|
||||
}
|
||||
|
||||
const Dimension& GetTextInputWidth() const
|
||||
{
|
||||
return textInputBorderWidth_;
|
||||
}
|
||||
|
||||
const Color& GetTextInputColor() const
|
||||
{
|
||||
return textInputBorderColor_;
|
||||
}
|
||||
|
||||
const Dimension& GetTextInputAndErrTipsSpacing() const
|
||||
{
|
||||
return textInputAndErrTipsSpacing_;
|
||||
}
|
||||
|
||||
bool IsShowPasswordIcon() const
|
||||
{
|
||||
return showPasswordIcon_;
|
||||
}
|
||||
|
||||
bool GetHoverAndPressBgColorEnabled() const
|
||||
{
|
||||
return hoverAndPressBgColorEnabled_;
|
||||
}
|
||||
|
||||
const Dimension& GetErrorTextInputBorderWidth() const
|
||||
{
|
||||
return errorTextInputBorderWidth_;
|
||||
}
|
||||
|
||||
bool NeedFocusBox() const
|
||||
{
|
||||
return needFocusBox_;
|
||||
}
|
||||
|
||||
const Dimension& GetFocusPadding() const
|
||||
{
|
||||
return focusPadding_;
|
||||
}
|
||||
|
||||
protected:
|
||||
TextFieldTheme() = default;
|
||||
|
||||
@ -736,6 +799,14 @@ private:
|
||||
Color previewUnderlineColor_;
|
||||
Color previewBoardColor_;
|
||||
|
||||
bool textFadeoutEnabled_ = false;
|
||||
Dimension textInputBorderWidth_ = 0.0_vp;
|
||||
Dimension textInputAndErrTipsSpacing_ = 8.0_vp;
|
||||
Dimension errorTextInputBorderWidth_ = 1.0_vp;
|
||||
Color textInputBorderColor_;
|
||||
bool showPasswordIcon_ = true;
|
||||
bool hoverAndPressBgColorEnabled_ = false;
|
||||
|
||||
std::string cancelButton_;
|
||||
|
||||
Dimension inlinePaddingRight_ = 12.0_vp;
|
||||
@ -745,6 +816,8 @@ private:
|
||||
std::string hiddenPasswordPromptInformation_;
|
||||
std::string aiWriteBundleName_;
|
||||
std::string aiWriteAbilityName_;
|
||||
bool needFocusBox_ = false;
|
||||
Dimension focusPadding_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "core/components_ng/property/layout_constraint.h"
|
||||
#include "core/components_ng/property/measure_utils.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
#include "core/components_ng/pattern/search/search_pattern.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
namespace {
|
||||
@ -421,7 +422,9 @@ double SearchLayoutAlgorithm::CalcSearchHeight(
|
||||
searchHeightAdapt = std::max(searchHeightAdapt, CalcSearchAdaptHeight(layoutWrapper));
|
||||
renderContext->SetClipToBounds(false);
|
||||
} else {
|
||||
renderContext->SetClipToBounds(true);
|
||||
auto pattern = host->GetPattern<SearchPattern>();
|
||||
CHECK_NULL_RETURN(pattern, 0.0);
|
||||
renderContext->SetClipToBounds(!pattern->NeedFocusBox());
|
||||
}
|
||||
|
||||
const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint();
|
||||
@ -644,6 +647,7 @@ void SearchLayoutAlgorithm::LayoutCancelButton(const LayoutSearchParams& params)
|
||||
{
|
||||
auto dividerSideSpace = params.searchTheme->GetDividerSideSpace().ConvertToPx();
|
||||
auto dividerWidth = params.searchTheme->GetSearchDividerWidth().ConvertToPx();
|
||||
auto borderWidth = params.searchTheme->GetBorderWidth().ConvertToPx();
|
||||
|
||||
auto cancelButtonWrapper = params.layoutWrapper->GetOrCreateChildByIndex(CANCEL_BUTTON_INDEX);
|
||||
CHECK_NULL_VOID(cancelButtonWrapper);
|
||||
@ -677,7 +681,7 @@ void SearchLayoutAlgorithm::LayoutCancelButton(const LayoutSearchParams& params)
|
||||
cancelButtonHorizontalOffset =
|
||||
std::max(searchButtonHorizontalOffset - cancelButtonOffsetToSearchButton, 0.0);
|
||||
} else {
|
||||
cancelButtonHorizontalOffset = params.searchFrameWidth - cancelButtonFrameWidth;
|
||||
cancelButtonHorizontalOffset = params.searchFrameWidth - cancelButtonFrameWidth - borderWidth;
|
||||
}
|
||||
}
|
||||
auto cancelButtonOffset = OffsetF(cancelButtonHorizontalOffset, cancelButtonVerticalOffset);
|
||||
|
@ -75,6 +75,34 @@ RefPtr<TextFieldControllerBase> SearchModelNG::Create(const std::optional<std::s
|
||||
return pattern->GetSearchController();
|
||||
}
|
||||
|
||||
void SearchModelNG::UpdateSearchNodeBorderProps(const RefPtr<SearchNode> frameNode)
|
||||
{
|
||||
CHECK_NULL_VOID(frameNode);
|
||||
auto pipeline = frameNode->GetContext();
|
||||
CHECK_NULL_VOID(pipeline);
|
||||
auto searchTheme = pipeline->GetTheme<SearchTheme>();
|
||||
CHECK_NULL_VOID(searchTheme);
|
||||
auto renderContext = frameNode->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
auto layoutProperty = frameNode->GetLayoutProperty<SearchLayoutProperty>();
|
||||
CHECK_NULL_VOID(layoutProperty);
|
||||
|
||||
layoutProperty->UpdateCancelButtonStyle(searchTheme->GetCancelButtonStyle());
|
||||
if (!layoutProperty->GetBorderWidthProperty()) {
|
||||
if (!renderContext->HasBorderWidth()) {
|
||||
BorderWidthProperty borderWidth;
|
||||
borderWidth.SetBorderWidth(searchTheme->GetBorderWidth());
|
||||
layoutProperty->UpdateBorderWidth(borderWidth);
|
||||
renderContext->UpdateBorderWidth(borderWidth);
|
||||
}
|
||||
if (!renderContext->HasBorderColor()) {
|
||||
BorderColorProperty borderColor;
|
||||
borderColor.SetColor(searchTheme->GetBorderColor());
|
||||
renderContext->UpdateBorderColor(borderColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<SearchNode> SearchModelNG::CreateSearchNode(int32_t nodeId, const std::optional<std::string>& value,
|
||||
const std::optional<std::string>& placeholder, const std::optional<std::string>& icon)
|
||||
{
|
||||
@ -107,7 +135,7 @@ RefPtr<SearchNode> SearchModelNG::CreateSearchNode(int32_t nodeId, const std::op
|
||||
BorderRadiusProperty borderRadius { radius.GetX(), radius.GetY(), radius.GetY(), radius.GetX() };
|
||||
renderContext->UpdateBorderRadius(borderRadius);
|
||||
|
||||
auto layoutProperty = frameNode->GetLayoutProperty<SearchLayoutProperty>();
|
||||
UpdateSearchNodeBorderProps(frameNode);
|
||||
auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(TEXTFIELD_INDEX));
|
||||
auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
|
||||
pattern->SetSearchController(textFieldPattern->GetTextFieldController());
|
||||
@ -741,8 +769,9 @@ void SearchModelNG::CreateTextField(const RefPtr<SearchNode>& parentNode, const
|
||||
textFieldLayoutProperty->UpdatePlaceholder(placeholder.value_or(""));
|
||||
textFieldLayoutProperty->UpdateMaxLines(1);
|
||||
textFieldLayoutProperty->UpdatePlaceholderMaxLines(1);
|
||||
if (!textFieldPaintProperty || !textFieldPaintProperty->HasTextColorFlagByUser()) {
|
||||
if (!hasTextFieldNode) {
|
||||
textFieldLayoutProperty->UpdateTextColor(searchTheme->GetTextColor());
|
||||
textFieldLayoutProperty->UpdatePlaceholderTextColor(searchTheme->GetPlaceholderColor());
|
||||
}
|
||||
}
|
||||
pattern->SetTextFieldController(AceType::MakeRefPtr<TextFieldController>());
|
||||
@ -750,6 +779,8 @@ void SearchModelNG::CreateTextField(const RefPtr<SearchNode>& parentNode, const
|
||||
pattern->SetTextEditController(AceType::MakeRefPtr<TextEditController>());
|
||||
pattern->InitSurfaceChangedCallback();
|
||||
pattern->InitSurfacePositionChangedCallback();
|
||||
pattern->SetTextFadeoutCapacity(true);
|
||||
|
||||
if (pipeline->GetHasPreviewTextOption()) {
|
||||
pattern->SetSupportPreviewText(pipeline->GetSupportPreviewText());
|
||||
}
|
||||
@ -783,6 +814,7 @@ void SearchModelNG::TextFieldUpdateContext(const RefPtr<FrameNode>& frameNode)
|
||||
BorderRadiusProperty borderRadius;
|
||||
textFieldPaintProperty->UpdateBorderRadiusFlagByUser(borderRadius);
|
||||
pattern->SetEnableTouchAndHoverEffect(true);
|
||||
textFieldPaintProperty->UpdateBackgroundColor(Color::TRANSPARENT);
|
||||
renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
|
||||
}
|
||||
|
||||
|
@ -159,6 +159,7 @@ public:
|
||||
private:
|
||||
static RefPtr<SearchNode> CreateSearchNode(int32_t nodeId, const std::optional<std::string>& value,
|
||||
const std::optional<std::string>& placeholder, const std::optional<std::string>& icon);
|
||||
static void UpdateSearchNodeBorderProps(const RefPtr<SearchNode> frameNode);
|
||||
static void CreateTextField(const RefPtr<SearchNode>& parentNode,
|
||||
const std::optional<std::string>& placeholder, const std::optional<std::string>& value, bool hasTextFieldNode);
|
||||
static void CreateButton(const RefPtr<SearchNode>& parentNode, bool hasButtonNode);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "core/components_ng/pattern/text/text_pattern.h"
|
||||
#include "core/components_ng/pattern/text_field/text_field_pattern.h"
|
||||
#include "core/event/touch_event.h"
|
||||
#include "core/components/theme/app_theme.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
@ -203,6 +204,7 @@ void SearchPattern::OnModifyDone()
|
||||
layoutProperty->UpdateMargin(margin);
|
||||
}
|
||||
|
||||
InitSearchTheme();
|
||||
HandleBackgroundColor();
|
||||
|
||||
auto searchButton = layoutProperty->GetSearchButton();
|
||||
@ -229,6 +231,11 @@ void SearchPattern::OnModifyDone()
|
||||
CHECK_NULL_VOID(cancelButtonLayoutProperty);
|
||||
cancelButtonLayoutProperty->UpdateLabel("");
|
||||
cancelButtonFrameNode->MarkModifyDone();
|
||||
InitAllEvent();
|
||||
}
|
||||
|
||||
void SearchPattern::InitAllEvent()
|
||||
{
|
||||
InitButtonAndImageClickEvent();
|
||||
InitCancelButtonClickEvent();
|
||||
InitTextFieldValueChangeEvent();
|
||||
@ -236,10 +243,14 @@ void SearchPattern::OnModifyDone()
|
||||
InitTextFieldClickEvent();
|
||||
InitButtonMouseAndTouchEvent();
|
||||
HandleTouchableAndHitTestMode();
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto focusHub = host->GetFocusHub();
|
||||
CHECK_NULL_VOID(focusHub);
|
||||
InitOnKeyEvent(focusHub);
|
||||
InitFocusEvent(focusHub);
|
||||
InitHoverEvent();
|
||||
InitTouchEvent();
|
||||
InitClickEvent();
|
||||
HandleEnabled();
|
||||
SetAccessibilityAction();
|
||||
@ -895,17 +906,42 @@ bool SearchPattern::OnKeyEvent(const KeyEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
void SearchPattern::PaintSearchFocusState()
|
||||
{
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
|
||||
CHECK_NULL_VOID(textFieldFrameNode);
|
||||
auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
|
||||
CHECK_NULL_VOID(textFieldLayoutProperty);
|
||||
if (textFieldLayoutProperty->GetTextColorValue(normalTextColor_) == normalTextColor_) {
|
||||
textFieldLayoutProperty->UpdateTextColor(focusTextColor_);
|
||||
isFocusTextColorSet_ = true;
|
||||
}
|
||||
if (textFieldLayoutProperty->GetPlaceholderTextColorValue(normalPlaceholderColor_) == normalPlaceholderColor_) {
|
||||
textFieldLayoutProperty->UpdatePlaceholderTextColor(focusPlaceholderColor_);
|
||||
isFocusPlaceholderColorSet_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SearchPattern::PaintFocusState(bool recoverFlag)
|
||||
{
|
||||
TAG_LOGI(AceLogTag::ACE_SEARCH, "Focus Choice = %{public}d", static_cast<int>(focusChoice_));
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
if (renderContext->GetBackgroundColor().value_or(searchNormalColor_) == searchNormalColor_) {
|
||||
renderContext->UpdateBackgroundColor(focusBgColor_);
|
||||
isFocusBgColorSet_ = true;
|
||||
}
|
||||
auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
|
||||
CHECK_NULL_VOID(textFieldFrameNode);
|
||||
auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
|
||||
if (focusChoice_ == FocusChoice::SEARCH) {
|
||||
PaintSearchFocusState();
|
||||
if (!recoverFlag) {
|
||||
if (!textFieldPattern->GetTextValue().empty()) {
|
||||
textFieldPattern->NeedRequestKeyboard();
|
||||
@ -925,6 +961,10 @@ void SearchPattern::PaintFocusState(bool recoverFlag)
|
||||
textFieldPattern->CloseKeyboard(true);
|
||||
}
|
||||
|
||||
if (GetDefaultIconColor(IMAGE_INDEX) == normalIconColor_) {
|
||||
SetSearchIconColor(focusIconColor_);
|
||||
isFocusIconColorSet_ = true;
|
||||
}
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(context);
|
||||
RoundRect focusRect;
|
||||
@ -935,6 +975,30 @@ void SearchPattern::PaintFocusState(bool recoverFlag)
|
||||
host->MarkModifyDone();
|
||||
}
|
||||
|
||||
void SearchPattern::GetSearchFocusPaintRadius(
|
||||
float& radiusTopLeft, float& radiusTopRight, float& radiusBottomLeft, float& radiusBottomRight)
|
||||
{
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
auto radius = renderContext->GetBorderRadius();
|
||||
if (radius.has_value()) {
|
||||
if (radius->radiusTopLeft.has_value()) {
|
||||
radiusTopLeft = static_cast<float>(radius->radiusTopLeft->ConvertToPx());
|
||||
}
|
||||
if (radius->radiusTopRight.has_value()) {
|
||||
radiusTopRight = static_cast<float>(radius->radiusTopRight->ConvertToPx());
|
||||
}
|
||||
if (radius->radiusBottomLeft.has_value()) {
|
||||
radiusBottomLeft = static_cast<float>(radius->radiusBottomLeft->ConvertToPx());
|
||||
}
|
||||
if (radius->radiusBottomRight.has_value()) {
|
||||
radiusBottomRight = static_cast<float>(radius->radiusBottomRight->ConvertToPx());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SearchPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
|
||||
{
|
||||
float originX = 0.0f;
|
||||
@ -947,7 +1011,14 @@ void SearchPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
|
||||
float radiusBottomRight = 0.0f;
|
||||
float focusOffset = FOCUS_OFFSET.ConvertToPx();
|
||||
if (focusChoice_ == FocusChoice::SEARCH) {
|
||||
return;
|
||||
if (!needFocusBox_) {
|
||||
return;
|
||||
}
|
||||
originX = searchOffset_.GetX() - DOUBLE * focusOffset;
|
||||
originY = searchOffset_.GetY() - DOUBLE * focusOffset;
|
||||
endX = searchSize_.Width() + searchOffset_.GetX() + DOUBLE * focusOffset;
|
||||
endY = searchSize_.Height() + searchOffset_.GetY() + DOUBLE * focusOffset;
|
||||
GetSearchFocusPaintRadius(radiusTopLeft, radiusTopRight, radiusBottomLeft, radiusBottomRight);
|
||||
}
|
||||
if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
|
||||
originX = cancelButtonOffset_.GetX() + focusOffset;
|
||||
@ -1133,6 +1204,19 @@ void SearchPattern::AnimateTouchAndHover(RefPtr<RenderContext>& renderContext, f
|
||||
option, [renderContext, highlightEnd]() { renderContext->OnBackgroundColorUpdate(highlightEnd); });
|
||||
}
|
||||
|
||||
void SearchPattern::AnimateSearchTouchAndHover(RefPtr<RenderContext>& renderContext,
|
||||
Color& blendColorFrom, Color& blendColorTo, int32_t duration, const RefPtr<Curve>& curve)
|
||||
{
|
||||
Color highlightStart = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColorFrom);
|
||||
Color highlightEnd = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColorTo);
|
||||
renderContext->OnBackgroundColorUpdate(highlightStart);
|
||||
AnimationOption option = AnimationOption();
|
||||
option.SetDuration(duration);
|
||||
option.SetCurve(curve);
|
||||
AnimationUtils::Animate(
|
||||
option, [renderContext, highlightEnd]() { renderContext->OnBackgroundColorUpdate(highlightEnd); });
|
||||
}
|
||||
|
||||
void SearchPattern::ResetDragOption()
|
||||
{
|
||||
ClearButtonStyle(BUTTON_INDEX);
|
||||
@ -1150,6 +1234,99 @@ void SearchPattern::ClearButtonStyle(int32_t childId)
|
||||
AnimateTouchAndHover(renderContext, TOUCH_OPACITY, 0.0f, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
|
||||
}
|
||||
|
||||
void SearchPattern::InitSearchTheme()
|
||||
{
|
||||
auto pipeline = PipelineBase::GetCurrentContext();
|
||||
CHECK_NULL_VOID(pipeline);
|
||||
auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
|
||||
CHECK_NULL_VOID(textFieldTheme);
|
||||
searchNormalColor_ = textFieldTheme->GetBgColor();
|
||||
auto searchTheme = pipeline->GetTheme<SearchTheme>();
|
||||
CHECK_NULL_VOID(searchTheme);
|
||||
needFocusBox_ = searchTheme->NeedFocusBox();
|
||||
searchHoverColor_ = searchTheme->GetHoverColor();
|
||||
searchTouchColor_ = searchTheme->GetTouchColor();
|
||||
focusBgColor_ = searchTheme->GetFocusBgColor();
|
||||
focusIconColor_ = searchTheme->GetFocusIconColor();
|
||||
normalTextColor_ = searchTheme->GetTextColor();
|
||||
focusTextColor_ = searchTheme->GetFocusTextColor();
|
||||
normalPlaceholderColor_ = searchTheme->GetPlaceholderColor();
|
||||
focusPlaceholderColor_ = searchTheme->GetFocusPlaceholderColor();
|
||||
normalIconColor_ = searchTheme->GetSymbolIconColor();
|
||||
}
|
||||
|
||||
void SearchPattern::InitHoverEvent()
|
||||
{
|
||||
if (searchHoverListener_) {
|
||||
return;
|
||||
}
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto eventHub = host->GetEventHub<SearchEventHub>();
|
||||
auto inputHub = eventHub->GetOrCreateInputEventHub();
|
||||
|
||||
auto mouseTask = [weak = WeakClaim(this)](bool isHover) {
|
||||
auto pattern = weak.Upgrade();
|
||||
CHECK_NULL_VOID(pattern);
|
||||
pattern->HandleHoverEvent(isHover);
|
||||
};
|
||||
searchHoverListener_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
|
||||
inputHub->AddOnHoverEvent(searchHoverListener_);
|
||||
}
|
||||
|
||||
void SearchPattern::HandleHoverEvent(bool isHover)
|
||||
{
|
||||
isSearchHover_ = isHover;
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto eventHub = host->GetEventHub<EventHub>();
|
||||
CHECK_NULL_VOID(eventHub);
|
||||
auto enabled = eventHub->IsEnabled();
|
||||
auto inputEventHub = host->GetOrCreateInputEventHub();
|
||||
auto hoverEffect = inputEventHub->GetHoverEffect();
|
||||
if (hoverEffect == HoverEffectType::NONE || hoverEffect == HoverEffectType::SCALE) {
|
||||
return;
|
||||
}
|
||||
if (!isSearchPress_ && (enabled || !isHover)) {
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
AnimateSearchTouchAndHover(renderContext, isHover ? transparentColor_ : searchHoverColor_,
|
||||
isHover ? searchHoverColor_ : transparentColor_, HOVER_DURATION, Curves::FRICTION);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchPattern::InitTouchEvent()
|
||||
{
|
||||
if (searchTouchListener_) {
|
||||
return;
|
||||
}
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto gesture = host->GetOrCreateGestureEventHub();
|
||||
CHECK_NULL_VOID(gesture);
|
||||
auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
|
||||
auto pattern = weak.Upgrade();
|
||||
CHECK_NULL_VOID(pattern);
|
||||
auto infoTouches = info.GetTouches();
|
||||
CHECK_EQUAL_VOID(infoTouches.empty(), true);
|
||||
pattern->OnTouchDownOrUp(infoTouches.front().GetTouchType() == TouchType::DOWN);
|
||||
};
|
||||
searchTouchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
|
||||
gesture->AddTouchEvent(searchTouchListener_);
|
||||
}
|
||||
|
||||
void SearchPattern::OnTouchDownOrUp(bool isDown)
|
||||
{
|
||||
isSearchPress_ = isDown;
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto searchEventHub = GetEventHub<SearchEventHub>();
|
||||
CHECK_NULL_VOID(searchEventHub);
|
||||
auto renderContext = host->GetRenderContext();
|
||||
AnimateSearchTouchAndHover(renderContext, isDown ? searchHoverColor_ : searchTouchColor_,
|
||||
isDown ? searchTouchColor_ : searchHoverColor_, TOUCH_DURATION, Curves::FRICTION);
|
||||
}
|
||||
|
||||
void SearchPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
|
||||
{
|
||||
auto focusTask = [weak = WeakClaim(this)]() {
|
||||
@ -1202,8 +1379,28 @@ void SearchPattern::HandleBlurEvent()
|
||||
{
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
if (isFocusBgColorSet_) {
|
||||
renderContext->UpdateBackgroundColor(searchNormalColor_);
|
||||
isFocusBgColorSet_ = false;
|
||||
}
|
||||
if (isFocusIconColorSet_) {
|
||||
SetSearchIconColor(normalIconColor_);
|
||||
isFocusIconColorSet_ = false;
|
||||
}
|
||||
auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
|
||||
CHECK_NULL_VOID(textFieldFrameNode);
|
||||
auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
|
||||
CHECK_NULL_VOID(textFieldLayoutProperty);
|
||||
if (isFocusTextColorSet_) {
|
||||
textFieldLayoutProperty->UpdateTextColor(normalTextColor_);
|
||||
isFocusTextColorSet_ = false;
|
||||
}
|
||||
if (isFocusPlaceholderColorSet_) {
|
||||
textFieldLayoutProperty->UpdatePlaceholderTextColor(normalPlaceholderColor_);
|
||||
isFocusPlaceholderColorSet_ = false;
|
||||
}
|
||||
auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
textFieldPattern->HandleBlurEvent();
|
||||
@ -1647,6 +1844,9 @@ void SearchPattern::UpdateSearchSymbolIconColor()
|
||||
auto layoutProperty = cancelButtonFrameNode->GetLayoutProperty<TextLayoutProperty>();
|
||||
CHECK_NULL_VOID(layoutProperty);
|
||||
layoutProperty->UpdateSymbolColorList({ GetSearchNode()->GetSearchSymbolIconColor() });
|
||||
if (isFocusIconColorSet_ && GetDefaultIconColor(IMAGE_INDEX) == normalIconColor_) {
|
||||
SetSearchIconColor(focusIconColor_);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchPattern::CreateCancelIcon()
|
||||
@ -1838,6 +2038,32 @@ void SearchPattern::SetCancelButtonStyle(const CancelButtonStyle& style)
|
||||
UpdateChangeEvent(textFieldPattern->GetTextValue(), static_cast<int16_t>(style));
|
||||
}
|
||||
|
||||
Color SearchPattern::GetDefaultIconColor(int32_t index)
|
||||
{
|
||||
Color defaultIconColor = normalIconColor_;
|
||||
CHECK_NULL_RETURN(GetSearchNode(), defaultIconColor);
|
||||
auto iconFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
|
||||
CHECK_NULL_RETURN(iconFrameNode, defaultIconColor);
|
||||
if (iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
|
||||
auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
|
||||
CHECK_NULL_RETURN(symbolLayoutProperty, defaultIconColor);
|
||||
std::vector<Color> symbolColorList = symbolLayoutProperty->GetSymbolColorListValue({ normalIconColor_ });
|
||||
if (symbolColorList.size() >= 1) {
|
||||
defaultIconColor = symbolColorList[0];
|
||||
}
|
||||
} else {
|
||||
auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
|
||||
CHECK_NULL_RETURN(imageLayoutProperty, defaultIconColor);
|
||||
auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
|
||||
if (imageSourceInfo.IsSvg()) {
|
||||
auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
|
||||
CHECK_NULL_RETURN(imageRenderProperty, defaultIconColor);
|
||||
defaultIconColor = imageRenderProperty->GetSvgFillColorValue(normalIconColor_);
|
||||
}
|
||||
}
|
||||
return defaultIconColor;
|
||||
}
|
||||
|
||||
void SearchPattern::SetCancelImageIcon(IconOptions& iconOptions)
|
||||
{
|
||||
CHECK_NULL_VOID(GetSearchNode());
|
||||
|
@ -190,6 +190,11 @@ public:
|
||||
return buttonSize_;
|
||||
}
|
||||
|
||||
bool NeedFocusBox() const
|
||||
{
|
||||
return needFocusBox_;
|
||||
}
|
||||
|
||||
void ResetDragOption() override;
|
||||
void OnColorConfigurationUpdate() override;
|
||||
|
||||
@ -235,6 +240,9 @@ private:
|
||||
bool OnKeyEvent(const KeyEvent& event);
|
||||
void PaintFocusState(bool recoverFlag = false);
|
||||
void GetInnerFocusPaintRect(RoundRect& paintRect);
|
||||
void PaintSearchFocusState();
|
||||
void GetSearchFocusPaintRadius(float& radiusTopLeft, float& radiusTopRight,
|
||||
float& radiusBottomLeft, float& radiusBottomRight);
|
||||
void RequestKeyboard();
|
||||
// Init touch and hover event
|
||||
void InitTextFieldValueChangeEvent();
|
||||
@ -263,6 +271,8 @@ private:
|
||||
|
||||
void AnimateTouchAndHover(RefPtr<RenderContext>& renderContext, float startOpacity, float endOpacity,
|
||||
int32_t duration, const RefPtr<Curve>& curve);
|
||||
void AnimateSearchTouchAndHover(RefPtr<RenderContext>& renderContext, Color& blendColorFrom, Color& blendColorTo,
|
||||
int32_t duration, const RefPtr<Curve>& curve);
|
||||
void InitFocusEvent(const RefPtr<FocusHub>& focusHub);
|
||||
void HandleFocusEvent(bool forwardFocusMovement, bool backwardFocusMovement);
|
||||
void HandleBlurEvent();
|
||||
@ -270,6 +280,12 @@ private:
|
||||
void HandleClickEvent(GestureEvent& info);
|
||||
void UpdateIconChangeEvent();
|
||||
bool IsEventEnabled(const std::string& textValue, int16_t style);
|
||||
void InitAllEvent();
|
||||
void InitHoverEvent();
|
||||
void InitTouchEvent();
|
||||
void InitSearchTheme();
|
||||
void OnTouchDownOrUp(bool isDown);
|
||||
void HandleHoverEvent(bool isHover);
|
||||
|
||||
void UpdateSearchSymbolIconColor();
|
||||
void UpdateCancelSymbolIconColor();
|
||||
@ -293,6 +309,7 @@ private:
|
||||
void UpdateIconColor(int32_t index, const Color& color);
|
||||
void UpdateIconSize(int32_t index, const Dimension& value);
|
||||
const Dimension ConvertImageIconScaleLimit(const Dimension& fontSizeValue);
|
||||
Color GetDefaultIconColor(int32_t index);
|
||||
|
||||
uint32_t GetMaxLength() const;
|
||||
std::string SearchTypeToString() const;
|
||||
@ -312,16 +329,36 @@ private:
|
||||
RefPtr<TextFieldController> searchController_;
|
||||
FocusChoice focusChoice_ = FocusChoice::SEARCH;
|
||||
|
||||
RefPtr<TouchEventImpl> searchTouchListener_;
|
||||
RefPtr<TouchEventImpl> searchButtonTouchListener_;
|
||||
RefPtr<TouchEventImpl> cancelButtonTouchListener_;
|
||||
RefPtr<InputEvent> searchHoverListener_;
|
||||
RefPtr<InputEvent> searchButtonMouseEvent_;
|
||||
RefPtr<InputEvent> cancelButtonMouseEvent_;
|
||||
RefPtr<InputEvent> textFieldHoverEvent_ = nullptr;
|
||||
RefPtr<ClickEvent> clickListener_;
|
||||
|
||||
bool isSearchHover_ = false;
|
||||
bool isSearchPress_ = false;
|
||||
bool isCancelButtonHover_ = false;
|
||||
bool isSearchButtonHover_ = false;
|
||||
bool isSearchButtonEnabled_ = false;
|
||||
bool needFocusBox_ = false;
|
||||
bool isFocusPlaceholderColorSet_ = false;
|
||||
bool isFocusBgColorSet_ = false;
|
||||
bool isFocusIconColorSet_ = false;
|
||||
bool isFocusTextColorSet_ = false;
|
||||
Color searchHoverColor_;
|
||||
Color searchTouchColor_;
|
||||
Color searchNormalColor_;
|
||||
Color focusBgColor_;
|
||||
Color focusIconColor_;
|
||||
Color normalIconColor_;
|
||||
Color focusTextColor_;
|
||||
Color normalTextColor_;
|
||||
Color focusPlaceholderColor_;
|
||||
Color normalPlaceholderColor_;
|
||||
Color transparentColor_ = Color::TRANSPARENT;
|
||||
|
||||
WeakPtr<FrameNode> cancelButtonNode_;
|
||||
WeakPtr<FrameNode> buttonNode_;
|
||||
|
@ -44,9 +44,9 @@ const FontWeight FONT_WEIGHT_CONVERT_MAP[] = {
|
||||
FontWeight::W500,
|
||||
FontWeight::W400,
|
||||
};
|
||||
constexpr Dimension ERROR_TEXT_UNDERLINE_MARGIN = 8.0_vp;
|
||||
constexpr Dimension ERROR_TEXT_CAPSULE_MARGIN = 8.0_vp;
|
||||
constexpr float ROUND_VALUE = 0.5f;
|
||||
constexpr Dimension DEFAULT_FADEOUT_VP = 16.0_vp;
|
||||
constexpr double MAX_TEXTFADEOUT_PERCENT = 0.5;
|
||||
|
||||
inline FontWeight ConvertFontWeight(FontWeight fontWeight)
|
||||
{
|
||||
@ -78,52 +78,13 @@ TextFieldContentModifier::TextFieldContentModifier(const WeakPtr<OHOS::Ace::NG::
|
||||
|
||||
void TextFieldContentModifier::onDraw(DrawingContext& context)
|
||||
{
|
||||
auto& canvas = context.canvas;
|
||||
auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
auto paragraph = textFieldPattern->GetParagraph();
|
||||
CHECK_NULL_VOID(paragraph);
|
||||
auto contentOffset = contentOffset_->Get();
|
||||
auto contentRect = textFieldPattern->GetContentRect();
|
||||
auto clipRectHeight = 0.0f;
|
||||
auto errorMargin = 0.0f;
|
||||
auto frameNode = textFieldPattern->GetHost();
|
||||
CHECK_NULL_VOID(frameNode);
|
||||
auto layoutProperty = frameNode->GetLayoutProperty<TextFieldLayoutProperty>();
|
||||
CHECK_NULL_VOID(layoutProperty);
|
||||
if (layoutProperty->GetShowUnderlineValue(false) && showErrorState_->Get()) {
|
||||
errorMargin = ERROR_TEXT_UNDERLINE_MARGIN.ConvertToPx();
|
||||
} else if (textFieldPattern->NeedShowPasswordIcon() && showErrorState_->Get()) {
|
||||
errorMargin = ERROR_TEXT_CAPSULE_MARGIN.ConvertToPx();
|
||||
} else if (showErrorState_->Get()) {
|
||||
errorMargin = ERROR_TEXT_CAPSULE_MARGIN.ConvertToPx();
|
||||
if (textFieldPattern->IsInlineMode() || !textFadeoutEnabled_) {
|
||||
DoNormalDraw(context);
|
||||
} else {
|
||||
errorMargin = 0;
|
||||
DoTextFadeoutDraw(context);
|
||||
}
|
||||
ProcessErrorParagraph(context, errorMargin);
|
||||
clipRectHeight = contentRect.GetY() + contentRect.Height();
|
||||
canvas.Save();
|
||||
RSRect clipInnerRect = RSRect(contentRect.GetX(), contentRect.GetY(),
|
||||
contentRect.Width() + contentRect.GetX() + textFieldPattern->GetInlinePadding(), clipRectHeight);
|
||||
canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT);
|
||||
if (paragraph) {
|
||||
auto textField = textFieldPattern->IsTextArea() ? "TextArea" : "TextInput";
|
||||
ACE_LAYOUT_SCOPED_TRACE("[%s][id:%d] [Rect:%s]", textField, frameNode->GetId(), contentRect.ToString().c_str());
|
||||
if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
|
||||
canvas.Save();
|
||||
RSRect clipRect;
|
||||
std::vector<RSPoint> clipRadius;
|
||||
GetFrameRectClip(clipRect, clipRadius);
|
||||
canvas.ClipRoundRect(clipRect, clipRadius, true);
|
||||
paragraph->Paint(canvas, textFieldPattern->GetTextRect().GetX(),
|
||||
textFieldPattern->IsTextArea() ? textFieldPattern->GetTextRect().GetY() : contentOffset.GetY());
|
||||
canvas.Restore();
|
||||
} else {
|
||||
paragraph->Paint(canvas, textFieldPattern->GetTextRect().GetX(),
|
||||
textFieldPattern->IsTextArea() ? textFieldPattern->GetTextRect().GetY() : contentOffset.GetY());
|
||||
}
|
||||
}
|
||||
canvas.Restore();
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::GetFrameRectClip(RSRect& clipRect, std::vector<RSPoint>& clipRadius)
|
||||
@ -621,4 +582,163 @@ void TextFieldContentModifier::UpdateTextDecorationMeasureFlag(PropertyChangeFla
|
||||
}
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::SetTextFadeoutEnabled(bool enabled)
|
||||
{
|
||||
textFadeoutEnabled_ = enabled;
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::SetErrorTipsSpacing(const Dimension& errTipsSpacing)
|
||||
{
|
||||
errorTipsSpacing_ = errTipsSpacing;
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::DoNormalDraw(DrawingContext& context)
|
||||
{
|
||||
auto& canvas = context.canvas;
|
||||
auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
auto paragraph = textFieldPattern->GetParagraph();
|
||||
CHECK_NULL_VOID(paragraph);
|
||||
auto contentOffset = contentOffset_->Get();
|
||||
auto contentRect = textFieldPattern->GetContentRect();
|
||||
auto textRect = textFieldPattern->GetTextRect();
|
||||
auto clipRectHeight = 0.0f;
|
||||
auto errorMargin = 0.0f;
|
||||
auto frameNode = textFieldPattern->GetHost();
|
||||
CHECK_NULL_VOID(frameNode);
|
||||
if (showErrorState_->Get()) {
|
||||
errorMargin = errorTipsSpacing_.ConvertToPx();
|
||||
} else {
|
||||
errorMargin = 0;
|
||||
}
|
||||
ProcessErrorParagraph(context, errorMargin);
|
||||
clipRectHeight = contentRect.GetY() + contentRect.Height();
|
||||
canvas.Save();
|
||||
RSRect clipInnerRect = RSRect(contentRect.GetX(), contentRect.GetY(),
|
||||
contentRect.Width() + contentRect.GetX() + textFieldPattern->GetInlinePadding(), clipRectHeight);
|
||||
canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT);
|
||||
if (paragraph) {
|
||||
auto textField = textFieldPattern->IsTextArea() ? "TextArea" : "TextInput";
|
||||
ACE_LAYOUT_SCOPED_TRACE("[%s][id:%d] [Rect:%s]", textField, frameNode->GetId(), contentRect.ToString().c_str());
|
||||
if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
|
||||
canvas.Save();
|
||||
RSRect clipRect;
|
||||
std::vector<RSPoint> clipRadius;
|
||||
GetFrameRectClip(clipRect, clipRadius);
|
||||
canvas.ClipRoundRect(clipRect, clipRadius, true);
|
||||
paragraph->Paint(
|
||||
canvas, textRect.GetX(), textFieldPattern->IsTextArea() ? textRect.GetY() : contentOffset.GetY());
|
||||
canvas.Restore();
|
||||
} else {
|
||||
paragraph->Paint(
|
||||
canvas, textRect.GetX(), textFieldPattern->IsTextArea() ? textRect.GetY() : contentOffset.GetY());
|
||||
}
|
||||
}
|
||||
canvas.Restore();
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::DoTextFadeoutDraw(DrawingContext& context)
|
||||
{
|
||||
auto& canvas = context.canvas;
|
||||
auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
auto paragraph = textFieldPattern->GetParagraph();
|
||||
CHECK_NULL_VOID(paragraph);
|
||||
auto contentRect = textFieldPattern->GetContentRect();
|
||||
auto clipRectHeight = 0.0f;
|
||||
auto errorMargin = 0.0f;
|
||||
auto errorViewHeight = 0.0f;
|
||||
auto errorParagraph = textFieldPattern->GetErrorParagraph();
|
||||
auto textFrameRect = textFieldPattern->GetFrameRect();
|
||||
if (showErrorState_->Get()) {
|
||||
errorMargin = errorTipsSpacing_.ConvertToPx();
|
||||
} else {
|
||||
errorMargin = 0;
|
||||
}
|
||||
ProcessErrorParagraph(context, errorMargin);
|
||||
if (errorParagraph && showErrorState_->Get()) {
|
||||
errorViewHeight = textFrameRect.Bottom() - textFrameRect.Top() + errorMargin;
|
||||
}
|
||||
clipRectHeight = contentRect.GetY() + contentRect.Height() + errorViewHeight;
|
||||
RSRect clipInnerRect = RSRect(contentRect.GetX(), contentRect.GetY(),
|
||||
contentRect.Width() + contentRect.GetX() + textFieldPattern->GetInlinePadding(), clipRectHeight);
|
||||
RSSaveLayerOps slo(&clipInnerRect, nullptr);
|
||||
canvas.SaveLayer(slo);
|
||||
|
||||
DrawTextFadeout(context);
|
||||
|
||||
canvas.Restore();
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::DrawTextFadeout(DrawingContext& context)
|
||||
{
|
||||
auto& canvas = context.canvas;
|
||||
auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
auto frameNode = textFieldPattern->GetHost();
|
||||
CHECK_NULL_VOID(frameNode);
|
||||
auto paragraph = textFieldPattern->GetParagraph();
|
||||
CHECK_NULL_VOID(paragraph);
|
||||
auto contentOffset = contentOffset_->Get();
|
||||
auto contentRect = frameNode->GetGeometryNode()->GetContentRect();
|
||||
auto contentRectX = contentRect.GetX();
|
||||
auto textRect = textFieldPattern->GetTextRect();
|
||||
auto textRectX = textRect.GetX();
|
||||
auto textWidth = paragraph->GetTextWidth();
|
||||
auto leftFadeOn = false;
|
||||
auto rigthFadeOn = false;
|
||||
auto textFadeoutWidth = DEFAULT_FADEOUT_VP.ConvertToPx();
|
||||
auto gradientPercent = std::min(MAX_TEXTFADEOUT_PERCENT,
|
||||
textFadeoutWidth / std::max(static_cast<double>(contentRect.Width()), textFadeoutWidth));
|
||||
auto textFadeRect = RectF(contentRect.GetX(), contentOffset.GetY(), contentRect.Width(),
|
||||
std::max(textRect.Height(), contentRect.Height()));
|
||||
AdjustTextFadeRect(textFadeRect);
|
||||
|
||||
RSRect clipRect;
|
||||
std::vector<RSPoint> clipRadius;
|
||||
GetFrameRectClip(clipRect, clipRadius);
|
||||
canvas.ClipRoundRect(clipRect, clipRadius, true);
|
||||
|
||||
canvas.Save();
|
||||
RSRect clipTextInnerRect = RSRect(textFadeRect.GetX(), textFadeRect.GetY(),
|
||||
textFadeRect.Width() + textFadeRect.GetX(), textFadeRect.GetY() + textFadeRect.Height());
|
||||
canvas.ClipRect(clipTextInnerRect, RSClipOp::INTERSECT);
|
||||
paragraph->Paint(canvas, textRectX, contentOffset.GetY());
|
||||
canvas.Restore();
|
||||
|
||||
auto textIndent = std::max(textFieldPattern->GetTextParagraphIndent(), 0.0f);
|
||||
if (GreatNotEqual(textWidth + textIndent, contentRect.Width())) {
|
||||
leftFadeOn = LessNotEqual(textRectX, contentRectX);
|
||||
rigthFadeOn = GreatNotEqual((textRectX + textWidth + textIndent), contentRect.Right());
|
||||
}
|
||||
UpdateTextFadeout(canvas, textFadeRect, gradientPercent, leftFadeOn, rigthFadeOn);
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::AdjustTextFadeRect(RectF& textFadeRect)
|
||||
{
|
||||
const float TEXT_FADE_ADJUST_PX = 1;
|
||||
|
||||
textFadeRect -= OffsetF(TEXT_FADE_ADJUST_PX, TEXT_FADE_ADJUST_PX);
|
||||
textFadeRect += SizeF((TEXT_FADE_ADJUST_PX + TEXT_FADE_ADJUST_PX), (TEXT_FADE_ADJUST_PX + TEXT_FADE_ADJUST_PX));
|
||||
}
|
||||
|
||||
void TextFieldContentModifier::UpdateTextFadeout(
|
||||
RSCanvas& canvas, const RectF& textRect, float gradientPercent, bool leftFade, bool rightFade)
|
||||
{
|
||||
RSBrush brush;
|
||||
std::vector<RSPoint> points = { RSPoint(textRect.Left(), textRect.Top()),
|
||||
RSPoint(textRect.Right(), textRect.Top()) };
|
||||
std::vector<RSColorQuad> colors = { Color::TRANSPARENT.GetValue(), Color::WHITE.GetValue(), Color::WHITE.GetValue(),
|
||||
Color::TRANSPARENT.GetValue() };
|
||||
float leftEndPercent = leftFade ? gradientPercent : 0;
|
||||
float rightStartPercent = rightFade ? (1.0f - gradientPercent) : 1.0f;
|
||||
std::vector<RSScalar> pos = { 0.0f, leftEndPercent, rightStartPercent, 1.0f };
|
||||
brush.SetShaderEffect(
|
||||
RSShaderEffect::CreateLinearGradient(points.at(0), points.at(1), colors, pos, RSTileMode::CLAMP));
|
||||
brush.SetBlendMode(RSBlendMode::DST_IN);
|
||||
RSRect textFadeoutRect = RSRect(textRect.Left(), textRect.Top(), textRect.Right(), textRect.Bottom());
|
||||
canvas.AttachBrush(brush);
|
||||
canvas.DrawRect(textFadeoutRect);
|
||||
canvas.DetachBrush();
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
void SetTextOverflow(const TextOverflow value);
|
||||
void SetTextDecoration(const TextDecoration& value, const Color& color, const TextDecorationStyle& style);
|
||||
void ContentChange();
|
||||
void SetTextFadeoutEnabled(bool enabled);
|
||||
void SetErrorTipsSpacing(const Dimension& errTipsSpacing);
|
||||
|
||||
private:
|
||||
void SetDefaultFontSize(const TextStyle& textStyle);
|
||||
@ -79,6 +81,12 @@ private:
|
||||
void ProcessErrorParagraph(DrawingContext& context, float errorMargin);
|
||||
void ModifyDecorationInTextStyle(TextStyle& textStyle);
|
||||
void UpdateTextDecorationMeasureFlag(PropertyChangeFlag& flag);
|
||||
void DoNormalDraw(DrawingContext& context);
|
||||
void DoTextFadeoutDraw(DrawingContext& context);
|
||||
void DrawTextFadeout(DrawingContext& context);
|
||||
void UpdateTextFadeout(
|
||||
RSCanvas& canvas, const RectF& textRect, float gradientPercent, bool leftFade, bool rightFade);
|
||||
void AdjustTextFadeRect(RectF& textFadeRect);
|
||||
|
||||
WeakPtr<Pattern> pattern_;
|
||||
RefPtr<PropertyString> fontFamilyString_;
|
||||
@ -122,6 +130,9 @@ private:
|
||||
RefPtr<PropertyBool> fontReady_;
|
||||
RefPtr<PropertyInt> textOverflow_;
|
||||
|
||||
bool textFadeoutEnabled_ { false };
|
||||
Dimension errorTipsSpacing_ = 0.0_vp;
|
||||
|
||||
ACE_DISALLOW_COPY_AND_MOVE(TextFieldContentModifier);
|
||||
};
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -69,6 +69,11 @@ public:
|
||||
return unitWidth_;
|
||||
}
|
||||
|
||||
float GetTextIndent() const
|
||||
{
|
||||
return indent_;
|
||||
}
|
||||
|
||||
InlineMeasureItem GetInlineMeasureItem() const
|
||||
{
|
||||
return inlineMeasureItem_;
|
||||
|
@ -85,6 +85,7 @@ void TextFieldModelNG::CreateNode(
|
||||
CHECK_NULL_VOID(textFieldTheme);
|
||||
textfieldPaintProperty->UpdatePressBgColor(textFieldTheme->GetPressColor());
|
||||
textfieldPaintProperty->UpdateHoverBgColor(textFieldTheme->GetHoverColor());
|
||||
pattern->SetHoverPressBgColorEnabled(textFieldTheme->GetHoverAndPressBgColorEnabled());
|
||||
SetCaretColor(textFieldTheme->GetCursorColor());
|
||||
CaretStyle caretStyle;
|
||||
caretStyle.caretWidth = textFieldTheme->GetCursorWidth();
|
||||
|
@ -117,6 +117,7 @@ void TextFieldPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
|
||||
!textFieldPattern->IsNormalInlineState());
|
||||
textFieldContentModifier_->SetErrorTextValue(layoutProperty->GetErrorTextValue(""));
|
||||
textFieldContentModifier_->SetShowUnderlineState(layoutProperty->GetShowUnderlineValue(false));
|
||||
DoTextRaceIfNeed(paintWrapper);
|
||||
PropertyChangeFlag flag = 0;
|
||||
if (textFieldContentModifier_->NeedMeasureUpdate(flag)) {
|
||||
frameNode->MarkDirtyNode(flag);
|
||||
@ -199,6 +200,28 @@ void TextFieldPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper)
|
||||
UpdateScrollBar();
|
||||
}
|
||||
|
||||
void TextFieldPaintMethod::DoTextRaceIfNeed(PaintWrapper* paintWrapper)
|
||||
{
|
||||
CHECK_NULL_VOID(paintWrapper);
|
||||
CHECK_NULL_VOID(textFieldContentModifier_);
|
||||
auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
auto textFieldTheme = textFieldPattern->GetTheme();
|
||||
CHECK_NULL_VOID(textFieldTheme);
|
||||
auto frameNode = textFieldPattern->GetHost();
|
||||
CHECK_NULL_VOID(frameNode);
|
||||
textFieldContentModifier_->SetErrorTipsSpacing(textFieldTheme->GetTextInputAndErrTipsSpacing());
|
||||
if ((textFieldTheme->TextFadeoutEnabled() && textFieldPattern->GetTextFadeoutCapacity())) {
|
||||
auto paragraph = textFieldPattern->GetParagraph();
|
||||
CHECK_NULL_VOID(paragraph);
|
||||
auto paintContentWidth = paintWrapper->GetContentSize().Width();
|
||||
auto textFadeoutEnabled =
|
||||
GreatNotEqual(paintContentWidth, 0.0) &&
|
||||
GreatNotEqual(paragraph->GetTextWidth() + textFieldPattern->GetTextParagraphIndent(), paintContentWidth);
|
||||
textFieldContentModifier_->SetTextFadeoutEnabled(textFadeoutEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
void TextFieldPaintMethod::UpdateScrollBar()
|
||||
{
|
||||
auto scrollBar = scrollBar_.Upgrade();
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
private:
|
||||
void UpdateTextStyleToModifier(
|
||||
const RefPtr<TextFieldLayoutProperty>& layoutProperty, const RefPtr<TextFieldTheme>& theme, bool isDisabled);
|
||||
void DoTextRaceIfNeed(PaintWrapper* paintWrapper);
|
||||
|
||||
private:
|
||||
WeakPtr<Pattern> pattern_;
|
||||
RefPtr<TextFieldOverlayModifier> textFieldOverlayModifier_;
|
||||
|
@ -111,7 +111,6 @@ const BorderRadiusProperty ZERO_BORDER_RADIUS_PROPERTY(0.0_vp);
|
||||
// need to be moved to TextFieldTheme
|
||||
constexpr Dimension BORDER_DEFAULT_WIDTH = 0.0_vp;
|
||||
constexpr Dimension TYPING_UNDERLINE_WIDTH = 2.0_px;
|
||||
constexpr Dimension ERROR_BORDER_WIDTH = 1.0_vp;
|
||||
constexpr Dimension OVER_COUNT_BORDER_WIDTH = 1.0_vp;
|
||||
constexpr Dimension INLINE_BORDER_WIDTH = 2.0_vp;
|
||||
constexpr Dimension ERROR_UNDERLINE_WIDTH = 2.0_px;
|
||||
@ -164,6 +163,7 @@ constexpr int32_t PREVIEW_BAD_PARAMETERS = -1;
|
||||
constexpr double MINIMAL_OFFSET = 0.01f;
|
||||
constexpr float RICH_DEFAULT_SHADOW_COLOR = 0x33000000;
|
||||
constexpr float RICH_DEFAULT_ELEVATION = 120.0f;
|
||||
constexpr int32_t HOVER_ANIMATION_DURATION = 250;
|
||||
|
||||
static std::unordered_map<TextContentType, std::pair<AceAutoFillType, std::string>> contentTypeMap_ = {
|
||||
{TextContentType::VISIBLE_PASSWORD,
|
||||
@ -543,6 +543,7 @@ bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dir
|
||||
}
|
||||
SetAccessibilityClearAction();
|
||||
SetAccessibilityPasswordIconAction();
|
||||
textParagraphIndent_ = textFieldLayoutAlgorithm->GetTextIndent();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -914,10 +915,104 @@ void TextFieldPattern::HandleFocusEvent()
|
||||
}
|
||||
ProcessFocusStyle();
|
||||
RequestKeyboardByFocusSwitch();
|
||||
SetFocusStyle();
|
||||
AddIsFocusActiveUpdateEvent();
|
||||
host->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity<float>()) <= 1 ?
|
||||
PROPERTY_UPDATE_MEASURE_SELF : PROPERTY_UPDATE_MEASURE);
|
||||
}
|
||||
|
||||
void TextFieldPattern::SetFocusStyle()
|
||||
{
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
auto paintProperty = GetPaintProperty<TextFieldPaintProperty>();
|
||||
CHECK_NULL_VOID(paintProperty);
|
||||
auto layoutProperty = GetLayoutProperty<TextFieldLayoutProperty>();
|
||||
CHECK_NULL_VOID(layoutProperty);
|
||||
auto textFieldTheme = GetTheme();
|
||||
CHECK_NULL_VOID(textFieldTheme);
|
||||
|
||||
if (!paintProperty->HasBackgroundColor() && !IsUnderlineMode()) {
|
||||
auto defaultBGColor = textFieldTheme->GetBgColor();
|
||||
if (paintProperty->GetBackgroundColorValue(defaultBGColor) == defaultBGColor) {
|
||||
renderContext->UpdateBackgroundColor(textFieldTheme->GetFocusBgColor());
|
||||
isFocusBGColorSet_ = true;
|
||||
}
|
||||
}
|
||||
auto defaultTextColor = textFieldTheme->GetTextColor();
|
||||
if (layoutProperty->GetTextColorValue(defaultTextColor) == defaultTextColor) {
|
||||
layoutProperty->UpdateTextColor(textFieldTheme->GetFocusTextColor());
|
||||
isFocusTextColorSet_ = true;
|
||||
}
|
||||
auto defaultPlaceholderColor = textFieldTheme->GetPlaceholderColor();
|
||||
if (layoutProperty->GetPlaceholderTextColorValue(defaultPlaceholderColor) == defaultPlaceholderColor) {
|
||||
layoutProperty->UpdatePlaceholderTextColor(textFieldTheme->GetFocusPlaceholderColor());
|
||||
isFocusPlaceholderColorSet_ = true;
|
||||
}
|
||||
host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
|
||||
}
|
||||
|
||||
void TextFieldPattern::ClearFocusStyle()
|
||||
{
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
auto paintProperty = GetPaintProperty<TextFieldPaintProperty>();
|
||||
CHECK_NULL_VOID(paintProperty);
|
||||
auto layoutProperty = GetLayoutProperty<TextFieldLayoutProperty>();
|
||||
CHECK_NULL_VOID(layoutProperty);
|
||||
auto textFieldTheme = GetTheme();
|
||||
CHECK_NULL_VOID(textFieldTheme);
|
||||
|
||||
if (isFocusBGColorSet_) {
|
||||
renderContext->UpdateBackgroundColor(textFieldTheme->GetBgColor());
|
||||
isFocusBGColorSet_ = false;
|
||||
}
|
||||
if (isFocusTextColorSet_) {
|
||||
layoutProperty->UpdateTextColor(textFieldTheme->GetTextColor());
|
||||
isFocusTextColorSet_ = false;
|
||||
}
|
||||
if (isFocusPlaceholderColorSet_) {
|
||||
layoutProperty->UpdatePlaceholderTextColor(textFieldTheme->GetPlaceholderColor());
|
||||
isFocusPlaceholderColorSet_ = false;
|
||||
}
|
||||
host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
|
||||
}
|
||||
|
||||
void TextFieldPattern::AddIsFocusActiveUpdateEvent()
|
||||
{
|
||||
if (!isFocusActiveUpdateEvent_) {
|
||||
isFocusActiveUpdateEvent_ = [weak = WeakClaim(this)](bool isFocusAcitve) {
|
||||
auto pattern = weak.Upgrade();
|
||||
CHECK_NULL_VOID(pattern);
|
||||
pattern->OnIsFocusActiveUpdate(isFocusAcitve);
|
||||
};
|
||||
}
|
||||
|
||||
auto pipline = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(pipline);
|
||||
pipline->AddIsFocusActiveUpdateEvent(GetHost(), isFocusActiveUpdateEvent_);
|
||||
}
|
||||
|
||||
void TextFieldPattern::RemoveIsFocusActiveUpdateEvent()
|
||||
{
|
||||
auto pipline = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(pipline);
|
||||
pipline->RemoveIsFocusActiveUpdateEvent(GetHost());
|
||||
}
|
||||
|
||||
void TextFieldPattern::OnIsFocusActiveUpdate(bool isFocusAcitve)
|
||||
{
|
||||
if (isFocusAcitve) {
|
||||
SetFocusStyle();
|
||||
} else {
|
||||
ClearFocusStyle();
|
||||
}
|
||||
}
|
||||
|
||||
void TextFieldPattern::ProcessFocusStyle()
|
||||
{
|
||||
bool needTwinkling = true;
|
||||
@ -1249,6 +1344,8 @@ void TextFieldPattern::HandleBlurEvent()
|
||||
isCursorAlwaysDisplayed_ = false;
|
||||
ReportEvent();
|
||||
ScheduleDisappearDelayTask();
|
||||
ClearFocusStyle();
|
||||
RemoveIsFocusActiveUpdateEvent();
|
||||
}
|
||||
|
||||
void TextFieldPattern::ModifyInnerStateInBlurEvent()
|
||||
@ -1684,6 +1781,7 @@ void TextFieldPattern::HandleTouchEvent(const TouchEventInfo& info)
|
||||
|
||||
void TextFieldPattern::HandleTouchDown(const Offset& offset)
|
||||
{
|
||||
UpdatePressStyle(true);
|
||||
moveCaretState_.touchDownOffset = offset;
|
||||
if (HasStateStyle(UI_STATE_PRESSED)) {
|
||||
return;
|
||||
@ -1698,6 +1796,7 @@ void TextFieldPattern::HandleTouchDown(const Offset& offset)
|
||||
|
||||
void TextFieldPattern::HandleTouchUp()
|
||||
{
|
||||
UpdatePressStyle(false);
|
||||
if (GetIsPreviewText() && isTouchPreviewText_) {
|
||||
StartTwinkling();
|
||||
}
|
||||
@ -2681,6 +2780,7 @@ void TextFieldPattern::OnModifyDone()
|
||||
CHECK_NULL_VOID(layoutProperty);
|
||||
auto textFieldTheme = GetTheme();
|
||||
CHECK_NULL_VOID(textFieldTheme);
|
||||
InitTextFieldThemeColors(textFieldTheme);
|
||||
auto paintProperty = GetPaintProperty<TextFieldPaintProperty>();
|
||||
CHECK_NULL_VOID(paintProperty);
|
||||
CheckIfNeedToResetKeyboard();
|
||||
@ -3264,9 +3364,83 @@ void TextFieldPattern::OnHover(bool isHover)
|
||||
pipeline->ChangeMouseStyle(frameId, MouseFormat::DEFAULT, windowId);
|
||||
pipeline->FreeMouseStyleHoldNode(frameId);
|
||||
}
|
||||
UpdateHoverStyle(isHover);
|
||||
isOnHover_ = isHover;
|
||||
}
|
||||
|
||||
void TextFieldPattern::InitTextFieldThemeColors(const RefPtr<TextFieldTheme>& theme)
|
||||
{
|
||||
CHECK_NULL_VOID(theme);
|
||||
|
||||
defaultThemeBgColor_ = theme->GetBgColor();
|
||||
focusThemeBgColor_ = theme->GetFocusBgColor();
|
||||
hoverThemeBgColor_ = theme->GetPressColor();
|
||||
pressThemeBgColor_ = theme->GetHoverColor();
|
||||
}
|
||||
|
||||
void TextFieldPattern::UpdateHoverStyle(bool isHover)
|
||||
{
|
||||
if (hoverAndPressBgColorEnabled_) {
|
||||
auto paintProperty = GetPaintProperty<TextFieldPaintProperty>();
|
||||
CHECK_NULL_VOID(paintProperty);
|
||||
auto textFieldBgColor = paintProperty->GetBackgroundColorValue(defaultThemeBgColor_);
|
||||
auto bgColor = textFieldBgColor == defaultThemeBgColor_
|
||||
? (IsUnderlineMode() ? Color::TRANSPARENT : defaultThemeBgColor_)
|
||||
: textFieldBgColor;
|
||||
|
||||
auto hoverColor = bgColor.BlendColor(hoverThemeBgColor_);
|
||||
if (!HasFocus()) {
|
||||
if (isHover) {
|
||||
PlayAnimationHoverAndPress(hoverColor);
|
||||
} else {
|
||||
PlayAnimationHoverAndPress(bgColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextFieldPattern::UpdatePressStyle(bool isPressed)
|
||||
{
|
||||
if (hoverAndPressBgColorEnabled_) {
|
||||
auto paintProperty = GetPaintProperty<TextFieldPaintProperty>();
|
||||
CHECK_NULL_VOID(paintProperty);
|
||||
auto textFieldBgColor = paintProperty->GetBackgroundColorValue(defaultThemeBgColor_);
|
||||
auto bgColor =
|
||||
textFieldBgColor == defaultThemeBgColor_
|
||||
? (IsUnderlineMode() ? Color::TRANSPARENT : (HasFocus() ? focusThemeBgColor_ : defaultThemeBgColor_))
|
||||
: textFieldBgColor;
|
||||
auto pressColor = bgColor.BlendColor(pressThemeBgColor_);
|
||||
|
||||
if (isPressed) {
|
||||
PlayAnimationHoverAndPress(pressColor);
|
||||
} else {
|
||||
PlayAnimationHoverAndPress(bgColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextFieldPattern::PlayAnimationHoverAndPress(const Color& color)
|
||||
{
|
||||
AnimationOption option = AnimationOption();
|
||||
option.SetDuration(HOVER_ANIMATION_DURATION);
|
||||
option.SetCurve(Curves::FRICTION);
|
||||
AnimationUtils::Animate(option, [weak = AceType::WeakClaim(this), color]() {
|
||||
auto textFieldPattern = weak.Upgrade();
|
||||
CHECK_NULL_VOID(textFieldPattern);
|
||||
textFieldPattern->UpdateTextFieldBgColor(color);
|
||||
});
|
||||
}
|
||||
|
||||
void TextFieldPattern::UpdateTextFieldBgColor(const Color& color)
|
||||
{
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
renderContext->UpdateBackgroundColor(color);
|
||||
host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
|
||||
}
|
||||
|
||||
void TextFieldPattern::RestoreDefaultMouseState()
|
||||
{
|
||||
int32_t windowId = 0;
|
||||
@ -5804,7 +5978,7 @@ void TextFieldPattern::SetShowError()
|
||||
} else if (passWordMode) {
|
||||
BorderWidthProperty borderWidth;
|
||||
BorderColorProperty borderColor;
|
||||
borderWidth.SetBorderWidth(ERROR_BORDER_WIDTH);
|
||||
borderWidth.SetBorderWidth(textFieldTheme->GetErrorTextInputBorderWidth());
|
||||
layoutProperty->UpdateBorderWidth(borderWidth);
|
||||
borderColor.SetColor(textFieldTheme->GetPasswordErrorBorderColor());
|
||||
renderContext->UpdateBorderColor(borderColor);
|
||||
@ -7024,7 +7198,10 @@ bool TextFieldPattern::IsShowPasswordIcon() const
|
||||
{
|
||||
auto layoutProperty = GetLayoutProperty<TextFieldLayoutProperty>();
|
||||
CHECK_NULL_RETURN(layoutProperty, false);
|
||||
return layoutProperty->GetShowPasswordIconValue(true) && IsInPasswordMode();
|
||||
auto textfieldTheme = GetTheme();
|
||||
CHECK_NULL_RETURN(textfieldTheme, false);
|
||||
bool isShowPasswordIcon = textfieldTheme->IsShowPasswordIcon();
|
||||
return layoutProperty->GetShowPasswordIconValue(isShowPasswordIcon) && IsInPasswordMode();
|
||||
}
|
||||
|
||||
std::optional<bool> TextFieldPattern::IsShowPasswordText() const
|
||||
@ -7252,9 +7429,45 @@ void TextFieldPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
|
||||
auto unitRect = unitNode->GetGeometryNode()->GetFrameRect();
|
||||
paintRect.SetRect(unitRect);
|
||||
}
|
||||
} else {
|
||||
GetTextInputFocusPaintRect(paintRect);
|
||||
}
|
||||
}
|
||||
|
||||
void TextFieldPattern::GetTextInputFocusPaintRect(RoundRect& paintRect)
|
||||
{
|
||||
auto textfieldTheme = GetTheme();
|
||||
CHECK_NULL_VOID(textfieldTheme);
|
||||
auto isNeedFocusBox = textfieldTheme->NeedFocusBox();
|
||||
if (!isNeedFocusBox) {
|
||||
return;
|
||||
}
|
||||
auto host = GetHost();
|
||||
CHECK_NULL_VOID(host);
|
||||
auto geometryNode = host->GetGeometryNode();
|
||||
CHECK_NULL_VOID(geometryNode);
|
||||
auto textInputSize = geometryNode->GetFrameSize();
|
||||
auto focusPaintPadding = textfieldTheme->GetFocusPadding().ConvertToPx();
|
||||
float width = textInputSize.Width() + 2 * focusPaintPadding;
|
||||
float height = textInputSize.Height() + 2 * focusPaintPadding;
|
||||
paintRect.SetRect({ -focusPaintPadding, -focusPaintPadding, width, height });
|
||||
auto renderContext = host->GetRenderContext();
|
||||
CHECK_NULL_VOID(renderContext);
|
||||
auto radius = renderContext->GetBorderRadius().value_or(BorderRadiusProperty());
|
||||
paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS,
|
||||
static_cast<float>(radius.radiusTopLeft->ConvertToPx() + focusPaintPadding),
|
||||
static_cast<float>(radius.radiusTopLeft->ConvertToPx() + focusPaintPadding));
|
||||
paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS,
|
||||
static_cast<float>(radius.radiusTopRight->ConvertToPx() + focusPaintPadding),
|
||||
static_cast<float>(radius.radiusTopRight->ConvertToPx() + focusPaintPadding));
|
||||
paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS,
|
||||
static_cast<float>(radius.radiusBottomLeft->ConvertToPx() + focusPaintPadding),
|
||||
static_cast<float>(radius.radiusBottomLeft->ConvertToPx() + focusPaintPadding));
|
||||
paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS,
|
||||
static_cast<float>(radius.radiusBottomRight->ConvertToPx() + focusPaintPadding),
|
||||
static_cast<float>(radius.radiusBottomRight->ConvertToPx() + focusPaintPadding));
|
||||
}
|
||||
|
||||
void TextFieldPattern::PaintCancelRect()
|
||||
{
|
||||
RoundRect focusRect;
|
||||
@ -7604,7 +7817,7 @@ void TextFieldPattern::SetThemeBorderAttr()
|
||||
CHECK_NULL_VOID(theme);
|
||||
if (!paintProperty->HasBorderColorFlagByUser()) {
|
||||
BorderColorProperty borderColor;
|
||||
borderColor.SetColor(Color::BLACK);
|
||||
borderColor.SetColor(theme->GetTextInputColor());
|
||||
renderContext->UpdateBorderColor(borderColor);
|
||||
} else {
|
||||
renderContext->UpdateBorderColor(paintProperty->GetBorderColorFlagByUserValue());
|
||||
@ -7621,7 +7834,7 @@ void TextFieldPattern::SetThemeBorderAttr()
|
||||
|
||||
if (!paintProperty->HasBorderWidthFlagByUser()) {
|
||||
BorderWidthProperty borderWidth;
|
||||
borderWidth.SetBorderWidth(BORDER_DEFAULT_WIDTH);
|
||||
borderWidth.SetBorderWidth(theme->GetTextInputWidth());
|
||||
renderContext->UpdateBorderWidth(borderWidth);
|
||||
layoutProperty->UpdateBorderWidth(borderWidth);
|
||||
} else {
|
||||
@ -7644,7 +7857,8 @@ void TextFieldPattern::SetThemeAttr()
|
||||
CHECK_NULL_VOID(theme);
|
||||
SetThemeBorderAttr();
|
||||
if (!paintProperty->HasBackgroundColor()) {
|
||||
auto backgroundColor = IsUnderlineMode() ? Color::TRANSPARENT : theme->GetBgColor();
|
||||
auto backgroundColor = isFocusBGColorSet_ ? theme->GetFocusBgColor() : theme->GetBgColor();
|
||||
backgroundColor = IsUnderlineMode() ? Color::TRANSPARENT : backgroundColor;
|
||||
renderContext->UpdateBackgroundColor(backgroundColor);
|
||||
} else {
|
||||
renderContext->UpdateBackgroundColor(paintProperty->GetBackgroundColorValue());
|
||||
@ -7671,7 +7885,8 @@ void TextFieldPattern::SetThemeAttr()
|
||||
}
|
||||
|
||||
if (!paintProperty->HasTextColorFlagByUser()) {
|
||||
layoutProperty->UpdateTextColor(theme->GetTextColor());
|
||||
auto textColor = isFocusTextColorSet_ ? theme->GetFocusTextColor() : theme->GetTextColor();
|
||||
layoutProperty->UpdateTextColor(textColor);
|
||||
} else {
|
||||
layoutProperty->UpdateTextColor(paintProperty->GetTextColorFlagByUserValue());
|
||||
}
|
||||
|
@ -71,6 +71,7 @@
|
||||
#include "core/components_ng/pattern/text_field/text_selector.h"
|
||||
#include "core/components_ng/pattern/text_input/text_input_layout_algorithm.h"
|
||||
#include "core/components_ng/property/property.h"
|
||||
#include "core/components/theme/app_theme.h"
|
||||
|
||||
#if not defined(ACE_UNITTEST)
|
||||
#if defined(ENABLE_STANDARD_INPUT)
|
||||
@ -358,6 +359,13 @@ public:
|
||||
{
|
||||
FocusPattern focusPattern = { FocusType::NODE, true, FocusStyleType::FORCE_NONE };
|
||||
focusPattern.SetIsFocusActiveWhenFocused(true);
|
||||
auto pipelineContext = PipelineBase::GetCurrentContext();
|
||||
CHECK_NULL_RETURN(pipelineContext, focusPattern);
|
||||
auto theme = pipelineContext->GetTheme<TextFieldTheme>();
|
||||
CHECK_NULL_RETURN(theme, focusPattern);
|
||||
if (theme->NeedFocusBox()) {
|
||||
focusPattern.SetStyleType(FocusStyleType::OUTER_BORDER);
|
||||
}
|
||||
return focusPattern;
|
||||
}
|
||||
void PerformAction(TextInputAction action, bool forceCloseKeyboard = false) override;
|
||||
@ -534,6 +542,11 @@ public:
|
||||
textRect_ = textRect;
|
||||
}
|
||||
|
||||
float GetTextParagraphIndent() const
|
||||
{
|
||||
return textParagraphIndent_;
|
||||
}
|
||||
|
||||
const RectF& GetFrameRect() const
|
||||
{
|
||||
return frameRect_;
|
||||
@ -882,6 +895,11 @@ public:
|
||||
const std::optional<SelectionOptions>& options = std::nullopt, bool isForward = false);
|
||||
void HandleBlurEvent();
|
||||
void HandleFocusEvent();
|
||||
void SetFocusStyle();
|
||||
void ClearFocusStyle();
|
||||
void AddIsFocusActiveUpdateEvent();
|
||||
void RemoveIsFocusActiveUpdateEvent();
|
||||
void OnIsFocusActiveUpdate(bool isFocusAcitve);
|
||||
void ProcessFocusStyle();
|
||||
bool OnBackPressed() override;
|
||||
void CheckScrollable();
|
||||
@ -1025,6 +1043,7 @@ public:
|
||||
void SetTextInputFlag(bool isTextInput)
|
||||
{
|
||||
isTextInput_ = isTextInput;
|
||||
SetTextFadeoutCapacity(isTextInput_);
|
||||
}
|
||||
|
||||
void SetSingleLineHeight(float height)
|
||||
@ -1425,6 +1444,20 @@ public:
|
||||
adaptFontSize_ = adaptFontSize;
|
||||
}
|
||||
|
||||
void SetTextFadeoutCapacity(bool enabled)
|
||||
{
|
||||
haveTextFadeoutCapacity_ = enabled;
|
||||
}
|
||||
bool GetTextFadeoutCapacity()
|
||||
{
|
||||
return haveTextFadeoutCapacity_;
|
||||
}
|
||||
|
||||
void SetHoverPressBgColorEnabled(bool enabled)
|
||||
{
|
||||
hoverAndPressBgColorEnabled_ = enabled;
|
||||
}
|
||||
|
||||
void ShowCaretAndStopTwinkling();
|
||||
|
||||
bool IsTextEditableForStylus() override;
|
||||
@ -1487,6 +1520,11 @@ private:
|
||||
void InitMouseEvent();
|
||||
void HandleHoverEffect(MouseInfo& info, bool isHover);
|
||||
void OnHover(bool isHover);
|
||||
void UpdateHoverStyle(bool isHover);
|
||||
void UpdatePressStyle(bool isPressed);
|
||||
void PlayAnimationHoverAndPress(const Color& color);
|
||||
void UpdateTextFieldBgColor(const Color& color);
|
||||
void InitTextFieldThemeColors(const RefPtr<TextFieldTheme>& theme);
|
||||
void ChangeMouseState(
|
||||
const Offset location, const RefPtr<PipelineContext>& pipeline, int32_t frameId, bool isByPass = false);
|
||||
void HandleMouseEvent(MouseInfo& info);
|
||||
@ -1588,6 +1626,7 @@ private:
|
||||
void PaintTextRect();
|
||||
void GetIconPaintRect(const RefPtr<TextInputResponseArea>& responseArea, RoundRect& paintRect);
|
||||
void GetInnerFocusPaintRect(RoundRect& paintRect);
|
||||
void GetTextInputFocusPaintRect(RoundRect& paintRect);
|
||||
void PaintResponseAreaRect();
|
||||
void PaintCancelRect();
|
||||
void PaintUnitRect();
|
||||
@ -1675,6 +1714,7 @@ private:
|
||||
|
||||
RectF frameRect_;
|
||||
RectF textRect_;
|
||||
float textParagraphIndent_ = 0.0;
|
||||
RefPtr<Paragraph> paragraph_;
|
||||
RefPtr<Paragraph> errorParagraph_;
|
||||
RefPtr<Paragraph> dragParagraph_;
|
||||
@ -1841,6 +1881,17 @@ private:
|
||||
bool textAreaBlurOnSubmit_ = false;
|
||||
bool isDetachFromMainTree_ = false;
|
||||
|
||||
bool haveTextFadeoutCapacity_ = false;
|
||||
bool isFocusTextColorSet_ = false;
|
||||
bool isFocusBGColorSet_ = false;
|
||||
bool isFocusPlaceholderColorSet_ = false;
|
||||
Color defaultThemeBgColor_ = Color::TRANSPARENT;
|
||||
Color focusThemeBgColor_ = Color::TRANSPARENT;
|
||||
Color hoverThemeBgColor_ = Color::TRANSPARENT;
|
||||
Color pressThemeBgColor_ = Color::TRANSPARENT;
|
||||
bool hoverAndPressBgColorEnabled_ = false;
|
||||
std::function<void(bool)> isFocusActiveUpdateEvent_;
|
||||
|
||||
Dimension previewUnderlineWidth_ = 2.0_vp;
|
||||
bool hasSupportedPreviewText_ = true;
|
||||
bool hasPreviewText_ = false;
|
||||
|
Loading…
Reference in New Issue
Block a user