|
1 | | - |
2 | 1 | // Copyright (c) Microsoft Corporation. |
3 | 2 | // Licensed under the MIT License. |
4 | 3 |
|
@@ -639,6 +638,11 @@ void WindowsTextInputComponentView::updateProps( |
639 | 638 | } |
640 | 639 | } |
641 | 640 |
|
| 641 | + if (oldTextInputProps.placeholder != newTextInputProps.placeholder || |
| 642 | + oldTextInputProps.placeholderTextColor != newTextInputProps.placeholderTextColor) { |
| 643 | + m_needsRedraw = true; |
| 644 | + } |
| 645 | + |
642 | 646 | /* |
643 | 647 | if (oldTextInputProps.textAttributes.foregroundColor != newTextInputProps.textAttributes.foregroundColor) { |
644 | 648 | if (newTextInputProps.textAttributes.foregroundColor) |
@@ -675,10 +679,6 @@ void WindowsTextInputComponentView::updateProps( |
675 | 679 | m_element.IsTextScaleFactorEnabled(newTextInputProps.allowFontScaling); |
676 | 680 | } |
677 | 681 |
|
678 | | - if (oldTextInputProps.placeholder != newTextInputProps.placeholder) { |
679 | | - m_element.PlaceholderText(winrt::to_hstring(newTextInputProps.placeholder)); |
680 | | - } |
681 | | -
|
682 | 682 | if (oldTextInputProps.selection.start != newTextInputProps.selection.start || |
683 | 683 | oldTextInputProps.selection.end != newTextInputProps.selection.end) { |
684 | 684 | m_element.Select( |
@@ -819,6 +819,7 @@ void WindowsTextInputComponentView::OnTextUpdated() noexcept { |
819 | 819 | // return; |
820 | 820 | data.attributedString = getAttributedString(); |
821 | 821 | data.mostRecentEventCount = m_nativeEventCount; |
| 822 | + |
822 | 823 | m_state->updateState(std::move(data)); |
823 | 824 |
|
824 | 825 | if (m_eventEmitter && !m_comingFromJS) { |
@@ -865,7 +866,11 @@ void WindowsTextInputComponentView::finalizeUpdates(RNComponentViewUpdateMask up |
865 | 866 | UpdateSpecialBorderLayers(m_layoutMetrics, *m_props); |
866 | 867 | } |
867 | 868 | ensureDrawingSurface(); |
| 869 | + if (m_needsRedraw) { |
| 870 | + DrawText(); |
| 871 | + } |
868 | 872 | } |
| 873 | + |
869 | 874 | void WindowsTextInputComponentView::prepareForRecycle() noexcept {} |
870 | 875 | facebook::react::Props::Shared WindowsTextInputComponentView::props() noexcept { |
871 | 876 | return m_props; |
@@ -982,6 +987,29 @@ void WindowsTextInputComponentView::ShowCaret(bool show) noexcept { |
982 | 987 | m_caretVisual.IsVisible(show); |
983 | 988 | } |
984 | 989 |
|
| 990 | +winrt::com_ptr<::IDWriteTextLayout> WindowsTextInputComponentView::CreatePlaceholderLayout() { |
| 991 | + // Create a fragment with text attributes |
| 992 | + winrt::com_ptr<::IDWriteTextLayout> textLayout = nullptr; |
| 993 | + facebook::react::AttributedString attributedString; |
| 994 | + facebook::react::AttributedString::Fragment fragment1; |
| 995 | + facebook::react::TextAttributes textAttributes = m_props->textAttributes; |
| 996 | + if (std::isnan(m_props->textAttributes.fontSize)) { |
| 997 | + textAttributes.fontSize = 12.0f; |
| 998 | + } |
| 999 | + fragment1.string = m_props->placeholder; |
| 1000 | + fragment1.textAttributes = textAttributes; |
| 1001 | + attributedString.appendFragment(fragment1); |
| 1002 | + |
| 1003 | + facebook::react::LayoutConstraints constraints; |
| 1004 | + constraints.maximumSize.width = static_cast<FLOAT>(m_imgWidth); |
| 1005 | + constraints.maximumSize.height = static_cast<FLOAT>(m_imgHeight); |
| 1006 | + |
| 1007 | + facebook::react::TextLayoutManager::GetTextLayout( |
| 1008 | + facebook::react::AttributedStringBox(attributedString), {} /*TODO*/, constraints, textLayout); |
| 1009 | + |
| 1010 | + return textLayout; |
| 1011 | +} |
| 1012 | + |
985 | 1013 | void WindowsTextInputComponentView::DrawText() noexcept { |
986 | 1014 | m_needsRedraw = true; |
987 | 1015 | if (m_cDrawBlock) { |
@@ -1029,6 +1057,31 @@ void WindowsTextInputComponentView::DrawText() noexcept { |
1029 | 1057 | auto hrDraw = m_textServices->TxDrawD2D(d2dDeviceContext.get(), &rc, nullptr, TXTVIEW_ACTIVE); |
1030 | 1058 | winrt::check_hresult(hrDraw); |
1031 | 1059 |
|
| 1060 | + // draw placeholder text if needed |
| 1061 | + if (!m_props->placeholder.empty() && GetTextFromRichEdit().empty()) { |
| 1062 | + // set brush color |
| 1063 | + winrt::com_ptr<ID2D1SolidColorBrush> brush; |
| 1064 | + if (m_props->placeholderTextColor) { |
| 1065 | + auto color = m_props->placeholderTextColor.AsD2DColor(); |
| 1066 | + winrt::check_hresult(d2dDeviceContext->CreateSolidColorBrush(color, brush.put())); |
| 1067 | + } else { |
| 1068 | + winrt::check_hresult( |
| 1069 | + d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Gray, 1.0f), brush.put())); |
| 1070 | + } |
| 1071 | + |
| 1072 | + // Create placeholder text layout |
| 1073 | + winrt::com_ptr<::IDWriteTextLayout> textLayout = CreatePlaceholderLayout(); |
| 1074 | + |
| 1075 | + // draw text |
| 1076 | + d2dDeviceContext->DrawTextLayout( |
| 1077 | + D2D1::Point2F( |
| 1078 | + static_cast<FLOAT>((offset.x + m_layoutMetrics.contentInsets.left) / m_layoutMetrics.pointScaleFactor), |
| 1079 | + static_cast<FLOAT>((offset.y + m_layoutMetrics.contentInsets.top) / m_layoutMetrics.pointScaleFactor)), |
| 1080 | + textLayout.get(), |
| 1081 | + brush.get(), |
| 1082 | + D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT); |
| 1083 | + } |
| 1084 | + |
1032 | 1085 | // restore dpi state |
1033 | 1086 | d2dDeviceContext->SetDpi(oldDpiX, oldDpiY); |
1034 | 1087 |
|
|
0 commit comments