react-native-windows 0.81.37 → 0.81.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Microsoft.ReactNative/Fabric/AbiComponentDescriptor.cpp +6 -2
- package/Microsoft.ReactNative/Fabric/AbiShadowNode.cpp +0 -47
- package/Microsoft.ReactNative/Fabric/AbiShadowNode.h +40 -8
- package/Microsoft.ReactNative/Fabric/AbiState.h +26 -8
- package/Microsoft.ReactNative/Fabric/AbiTextInputProps.h +51 -0
- package/Microsoft.ReactNative/Fabric/AbiTextInputShadowNode.cpp +88 -0
- package/Microsoft.ReactNative/Fabric/AbiTextInputShadowNode.h +65 -0
- package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +52 -18
- package/Microsoft.ReactNative/Fabric/AbiViewShadowNode.cpp +0 -18
- package/Microsoft.ReactNative/Fabric/AbiViewShadowNode.h +16 -4
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +1 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +3 -2
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +22 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/AbiTextInputState.h +38 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/ConcreteTextInputShadowNode.h +272 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h +21 -14
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +328 -75
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +24 -4
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +0 -205
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +22 -65
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +2 -1
- package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +0 -1
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +5 -0
- package/Microsoft.ReactNative/ViewProps.idl +11 -0
- package/Microsoft.ReactNative.Cxx/ComponentView.Experimental.interop.h +12 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/WinUI.props +2 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/Instance.cpp +386 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.h +148 -0
- package/Scripts/EnableInternalWinAppSDKFeed.ps1 +12 -5
- package/Scripts/NuGetRestoreForceEvaluateAllSolutions.ps1 +2 -2
- package/Shared/Shared.vcxitems +3 -3
- package/Shared/Shared.vcxitems.filters +1 -1
- package/index.windows.js +5 -0
- package/package.json +2 -2
- package/Microsoft.ReactNative/Fabric/AbiState.cpp +0 -29
package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "WindowsTextInputComponentView.h"
|
|
7
7
|
|
|
8
8
|
#include <AutoDraw.h>
|
|
9
|
+
#include <Fabric/AbiTextInputProps.h>
|
|
9
10
|
#include <Fabric/Composition/UiaHelpers.h>
|
|
10
11
|
#include <Fabric/platform/react/renderer/graphics/PlatformColorUtils.h>
|
|
11
12
|
#include <Utils/ThemeUtils.h>
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
#include <winrt/Windows.System.h>
|
|
20
21
|
#include <winrt/Windows.UI.h>
|
|
21
22
|
#include <mutex>
|
|
23
|
+
#include <string_view>
|
|
22
24
|
#include "../Composition.Input.h"
|
|
23
25
|
#include "../CompositionHelpers.h"
|
|
24
26
|
#include "../RootComponentView.h"
|
|
@@ -543,28 +545,118 @@ AutoCorrectOffCallback(LANGID langid, const WCHAR *pszBefore, WCHAR *pszAfter, L
|
|
|
543
545
|
}
|
|
544
546
|
|
|
545
547
|
facebook::react::AttributedString WindowsTextInputComponentView::getAttributedString() const {
|
|
546
|
-
// Use BaseTextShadowNode to get attributed string from children
|
|
547
|
-
|
|
548
548
|
auto attributedString = facebook::react::AttributedString{};
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
549
|
+
const auto &props = windowsTextInputProps();
|
|
550
|
+
auto baseTextAttributes = facebook::react::TextAttributes::defaultTextAttributes();
|
|
551
|
+
baseTextAttributes.fontSizeMultiplier = m_fontSizeMultiplier;
|
|
552
|
+
baseTextAttributes.apply(props.textAttributes);
|
|
553
|
+
baseTextAttributes.allowFontScaling = baseTextAttributes.allowFontScaling.value_or(props.allowFontScaling);
|
|
554
|
+
baseTextAttributes.foregroundColor = props.textAttributes.foregroundColor;
|
|
555
|
+
baseTextAttributes.backgroundColor = facebook::react::clearColor();
|
|
556
|
+
attributedString.setBaseTextAttributes(baseTextAttributes);
|
|
557
|
+
|
|
558
|
+
if (!m_textServices) {
|
|
559
|
+
return attributedString;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
winrt::com_ptr<::IUnknown> richEditOle;
|
|
563
|
+
LRESULT result;
|
|
564
|
+
winrt::check_hresult(
|
|
565
|
+
m_textServices->TxSendMessage(EM_GETOLEINTERFACE, 0, reinterpret_cast<LPARAM>(richEditOle.put()), &result));
|
|
566
|
+
winrt::check_bool(richEditOle != nullptr);
|
|
567
|
+
auto document = richEditOle.as<ITextDocument>();
|
|
568
|
+
winrt::com_ptr<ITextRange> range;
|
|
569
|
+
winrt::check_hresult(document->Range(0, 0, range.put()));
|
|
570
|
+
LONG storyLength;
|
|
571
|
+
winrt::check_hresult(range->GetStoryLength(&storyLength));
|
|
572
|
+
LRESULT textMode{};
|
|
573
|
+
winrt::check_hresult(m_textServices->TxSendMessage(EM_GETTEXTMODE, 0, 0, &textMode));
|
|
574
|
+
// Only rich-text stories include a final paragraph mark outside the TextInput's value.
|
|
575
|
+
const LONG textLength = storyLength - ((textMode & TM_RICHTEXT) ? 1 : 0);
|
|
576
|
+
|
|
577
|
+
float fontSizeMultiplier = 1.0f;
|
|
578
|
+
if (*baseTextAttributes.allowFontScaling) {
|
|
579
|
+
auto maxFontSizeMultiplier = baseTextAttributes.maxFontSizeMultiplier;
|
|
580
|
+
fontSizeMultiplier = (maxFontSizeMultiplier >= 1.0f)
|
|
581
|
+
? std::min(maxFontSizeMultiplier, baseTextAttributes.fontSizeMultiplier)
|
|
582
|
+
: baseTextAttributes.fontSizeMultiplier;
|
|
583
|
+
}
|
|
584
|
+
winrt::check_bool(fontSizeMultiplier > 0);
|
|
585
|
+
|
|
586
|
+
for (LONG position = 0; position < textLength;) {
|
|
587
|
+
winrt::check_hresult(range->SetRange(position, position));
|
|
588
|
+
LONG delta;
|
|
589
|
+
winrt::check_hresult(range->EndOf(tomCharFormat, tomExtend, &delta));
|
|
590
|
+
LONG end;
|
|
591
|
+
winrt::check_hresult(range->GetEnd(&end));
|
|
592
|
+
end = std::min(end, textLength);
|
|
593
|
+
winrt::check_bool(end > position);
|
|
594
|
+
winrt::check_hresult(range->SetRange(position, end));
|
|
595
|
+
|
|
558
596
|
auto fragment = facebook::react::AttributedString::Fragment{};
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
597
|
+
BSTR text = nullptr;
|
|
598
|
+
winrt::check_hresult(range->GetText(&text));
|
|
599
|
+
auto bstrToString = [](BSTR value) {
|
|
600
|
+
auto converted = value ? winrt::to_string(std::wstring_view{value, SysStringLen(value)}) : std::string{};
|
|
601
|
+
SysFreeString(value);
|
|
602
|
+
return converted;
|
|
603
|
+
};
|
|
604
|
+
fragment.string = bstrToString(text);
|
|
605
|
+
auto &textAttributes = fragment.textAttributes;
|
|
606
|
+
textAttributes = baseTextAttributes;
|
|
607
|
+
|
|
608
|
+
winrt::com_ptr<ITextFont> font;
|
|
609
|
+
winrt::check_hresult(range->GetFont(font.put()));
|
|
610
|
+
BSTR fontName = nullptr;
|
|
611
|
+
winrt::check_hresult(font->GetName(&fontName));
|
|
612
|
+
textAttributes.fontFamily = bstrToString(fontName);
|
|
613
|
+
float fontSize;
|
|
614
|
+
winrt::check_hresult(font->GetSize(&fontSize));
|
|
615
|
+
// TOM reports rendered points; store unscaled DIPs so UpdateText does not scale them twice.
|
|
616
|
+
textAttributes.fontSize = fontSize * (4.0f / 3.0f) / fontSizeMultiplier;
|
|
617
|
+
LONG weight;
|
|
618
|
+
winrt::check_hresult(font->GetWeight(&weight));
|
|
619
|
+
textAttributes.fontWeight = static_cast<facebook::react::FontWeight>(weight);
|
|
620
|
+
LONG italic;
|
|
621
|
+
winrt::check_hresult(font->GetItalic(&italic));
|
|
622
|
+
textAttributes.fontStyle =
|
|
623
|
+
italic == tomTrue ? facebook::react::FontStyle::Italic : facebook::react::FontStyle::Normal;
|
|
624
|
+
float spacing;
|
|
625
|
+
winrt::check_hresult(font->GetSpacing(&spacing));
|
|
626
|
+
textAttributes.letterSpacing = spacing;
|
|
627
|
+
|
|
628
|
+
LONG underline;
|
|
629
|
+
LONG strikethrough;
|
|
630
|
+
winrt::check_hresult(font->GetUnderline(&underline));
|
|
631
|
+
winrt::check_hresult(font->GetStrikeThrough(&strikethrough));
|
|
632
|
+
const bool hasUnderline = underline != tomNone;
|
|
633
|
+
const bool hasStrikethrough = strikethrough == tomTrue;
|
|
634
|
+
textAttributes.textDecorationLineType = hasUnderline
|
|
635
|
+
? (hasStrikethrough ? facebook::react::TextDecorationLineType::UnderlineStrikethrough
|
|
636
|
+
: facebook::react::TextDecorationLineType::Underline)
|
|
637
|
+
: (hasStrikethrough ? facebook::react::TextDecorationLineType::Strikethrough
|
|
638
|
+
: facebook::react::TextDecorationLineType::None);
|
|
639
|
+
|
|
640
|
+
LONG foreground;
|
|
641
|
+
LONG background;
|
|
642
|
+
winrt::check_hresult(font->GetForeColor(&foreground));
|
|
643
|
+
winrt::check_hresult(font->GetBackColor(&background));
|
|
644
|
+
if (foreground != tomAutoColor) {
|
|
645
|
+
textAttributes.foregroundColor =
|
|
646
|
+
facebook::react::colorFromRGBA(GetRValue(foreground), GetGValue(foreground), GetBValue(foreground), 255);
|
|
647
|
+
}
|
|
648
|
+
if (background != tomAutoColor) {
|
|
649
|
+
textAttributes.backgroundColor =
|
|
650
|
+
facebook::react::colorFromRGBA(GetRValue(background), GetGValue(background), GetBValue(background), 255);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
auto &fragments = attributedString.getFragments();
|
|
654
|
+
if (!fragments.empty() && fragments.back().textAttributes == textAttributes) {
|
|
655
|
+
fragments.back().string += fragment.string;
|
|
656
|
+
} else {
|
|
657
|
+
attributedString.appendFragment(std::move(fragment));
|
|
658
|
+
}
|
|
659
|
+
position = end;
|
|
568
660
|
}
|
|
569
661
|
|
|
570
662
|
return attributedString;
|
|
@@ -573,13 +665,15 @@ facebook::react::AttributedString WindowsTextInputComponentView::getAttributedSt
|
|
|
573
665
|
WindowsTextInputComponentView::WindowsTextInputComponentView(
|
|
574
666
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
575
667
|
facebook::react::Tag tag,
|
|
576
|
-
winrt::Microsoft::ReactNative::ReactContext const &reactContext
|
|
668
|
+
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
669
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder)
|
|
577
670
|
: Super(
|
|
578
671
|
WindowsTextInputComponentView::defaultProps(),
|
|
579
672
|
compContext,
|
|
580
673
|
tag,
|
|
581
674
|
reactContext,
|
|
582
|
-
ComponentViewFeatures::Default & ~ComponentViewFeatures::Background
|
|
675
|
+
ComponentViewFeatures::Default & ~ComponentViewFeatures::Background,
|
|
676
|
+
builder) {}
|
|
583
677
|
|
|
584
678
|
WindowsTextInputComponentView::~WindowsTextInputComponentView() {
|
|
585
679
|
// Release text services first to prevent further callbacks into CompTextHost.
|
|
@@ -591,6 +685,17 @@ WindowsTextInputComponentView::~WindowsTextInputComponentView() {
|
|
|
591
685
|
}
|
|
592
686
|
}
|
|
593
687
|
|
|
688
|
+
winrt::Microsoft::ReactNative::ViewProps WindowsTextInputComponentView::ViewPropsInner() noexcept {
|
|
689
|
+
// During initialization, even custom text inputs still have native default props.
|
|
690
|
+
if (auto abiProps = dynamic_cast<const ::Microsoft::ReactNative::AbiTextInputProps *>(viewProps().get())) {
|
|
691
|
+
if (auto props = abiProps->ViewProps()) {
|
|
692
|
+
return props;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
return winrt::make<winrt::Microsoft::ReactNative::implementation::TextInputProps>(viewProps());
|
|
697
|
+
}
|
|
698
|
+
|
|
594
699
|
void WindowsTextInputComponentView::HandleCommand(
|
|
595
700
|
const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
|
|
596
701
|
Super::HandleCommand(args);
|
|
@@ -608,7 +713,9 @@ void WindowsTextInputComponentView::HandleCommand(
|
|
|
608
713
|
{
|
|
609
714
|
if (text.has_value()) {
|
|
610
715
|
DrawBlock db(*this);
|
|
611
|
-
|
|
716
|
+
facebook::react::AttributedString attributedString;
|
|
717
|
+
attributedString.appendFragment({winrt::to_string(text.value()), windowsTextInputProps().textAttributes, {}});
|
|
718
|
+
UpdateText(attributedString);
|
|
612
719
|
}
|
|
613
720
|
|
|
614
721
|
SELCHANGE sc;
|
|
@@ -1160,6 +1267,12 @@ void WindowsTextInputComponentView::updateCursorColor(
|
|
|
1160
1267
|
m_caretVisual.Brush(theme()->Brush(*caretColor));
|
|
1161
1268
|
}
|
|
1162
1269
|
|
|
1270
|
+
const winrt::Microsoft::ReactNative::IComponentProps WindowsTextInputComponentView::userProps(
|
|
1271
|
+
facebook::react::Props::Shared const &props) noexcept {
|
|
1272
|
+
const auto &textInputProps = *std::static_pointer_cast<const ::Microsoft::ReactNative::AbiTextInputProps>(props);
|
|
1273
|
+
return textInputProps.UserProps();
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1163
1276
|
void WindowsTextInputComponentView::updateProps(
|
|
1164
1277
|
facebook::react::Props::Shared const &props,
|
|
1165
1278
|
facebook::react::Props::Shared const &oldProps) noexcept {
|
|
@@ -1270,15 +1383,28 @@ void WindowsTextInputComponentView::updateProps(
|
|
|
1270
1383
|
void WindowsTextInputComponentView::updateState(
|
|
1271
1384
|
facebook::react::State::Shared const &state,
|
|
1272
1385
|
facebook::react::State::Shared const &oldState) noexcept {
|
|
1273
|
-
|
|
1386
|
+
if (m_builder) {
|
|
1387
|
+
m_abistate = std::static_pointer_cast<::Microsoft::ReactNative::AbiTextInputShadowNode::ConcreteState const>(state);
|
|
1388
|
+
} else {
|
|
1389
|
+
m_state = std::static_pointer_cast<facebook::react::WindowsTextInputShadowNode::ConcreteState const>(state);
|
|
1390
|
+
}
|
|
1274
1391
|
|
|
1275
|
-
if
|
|
1392
|
+
// Avoid new-ing up a new AbiComponentState on every state change if we are not a custom component
|
|
1393
|
+
if (m_builder && m_builder->UpdateStateHandler()) {
|
|
1394
|
+
m_builder->UpdateStateHandler()(
|
|
1395
|
+
*this,
|
|
1396
|
+
winrt::make<::Microsoft::ReactNative::AbiComponentState<::Microsoft::ReactNative::AbiTextInputStateData>>(
|
|
1397
|
+
state));
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
if (!m_state && !m_abistate) {
|
|
1276
1401
|
assert(false && "State is `null` for <TextInput> component.");
|
|
1277
1402
|
return;
|
|
1278
1403
|
}
|
|
1279
1404
|
|
|
1280
1405
|
if (!oldState) {
|
|
1281
|
-
m_mostRecentEventCount =
|
|
1406
|
+
m_mostRecentEventCount =
|
|
1407
|
+
m_builder ? m_abistate->getData().mostRecentEventCount : m_state->getData().mostRecentEventCount;
|
|
1282
1408
|
}
|
|
1283
1409
|
|
|
1284
1410
|
if (auto root = rootComponentView()) {
|
|
@@ -1290,22 +1416,32 @@ void WindowsTextInputComponentView::updateState(
|
|
|
1290
1416
|
}
|
|
1291
1417
|
}
|
|
1292
1418
|
|
|
1293
|
-
|
|
1419
|
+
// Userdata-only updates must not replay potentially stale native text.
|
|
1420
|
+
const bool textChanged = !m_builder || !oldState ||
|
|
1421
|
+
m_abistate->getData().attributedStringBox !=
|
|
1422
|
+
static_cast<const ::Microsoft::ReactNative::AbiTextInputShadowNode::ConcreteState *>(oldState.get())
|
|
1423
|
+
->getData()
|
|
1424
|
+
.attributedStringBox;
|
|
1425
|
+
if (textChanged &&
|
|
1426
|
+
(m_builder ? m_mostRecentEventCount == m_abistate->getData().mostRecentEventCount
|
|
1427
|
+
: m_mostRecentEventCount == m_state->getData().mostRecentEventCount)) {
|
|
1294
1428
|
m_comingFromState = true;
|
|
1295
|
-
auto &fragments = m_state->getData().attributedStringBox.getValue().getFragments();
|
|
1296
1429
|
{
|
|
1297
1430
|
// DrawBlock defers DrawText() until after UpdateText completes
|
|
1298
1431
|
DrawBlock db(*this);
|
|
1299
|
-
UpdateText(
|
|
1432
|
+
UpdateText(
|
|
1433
|
+
m_builder ? m_abistate->getData().attributedStringBox.getValue()
|
|
1434
|
+
: m_state->getData().attributedStringBox.getValue());
|
|
1300
1435
|
}
|
|
1301
1436
|
m_comingFromState = false;
|
|
1302
1437
|
}
|
|
1303
1438
|
}
|
|
1304
1439
|
|
|
1305
|
-
void WindowsTextInputComponentView::UpdateText(const
|
|
1440
|
+
void WindowsTextInputComponentView::UpdateText(const facebook::react::AttributedString &attributedString) noexcept {
|
|
1441
|
+
DrawBlock db(*this);
|
|
1306
1442
|
SETTEXTEX stt;
|
|
1307
1443
|
memset(&stt, 0, sizeof(stt));
|
|
1308
|
-
stt.flags =
|
|
1444
|
+
stt.flags = 0x20 /*ST_PLAINTEXTONLY*/;
|
|
1309
1445
|
stt.codepage = CP_UTF8;
|
|
1310
1446
|
LRESULT res;
|
|
1311
1447
|
|
|
@@ -1313,8 +1449,51 @@ void WindowsTextInputComponentView::UpdateText(const std::string &str) noexcept
|
|
|
1313
1449
|
cr.cpMin = cr.cpMax = 0;
|
|
1314
1450
|
winrt::check_hresult(m_textServices->TxSendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr), &res));
|
|
1315
1451
|
|
|
1452
|
+
// Formatting uses temporary selections and must not publish intermediate text or selection changes.
|
|
1453
|
+
LRESULT eventMask;
|
|
1454
|
+
winrt::check_hresult(m_textServices->TxSendMessage(EM_GETEVENTMASK, 0, 0, &eventMask));
|
|
1455
|
+
winrt::check_hresult(
|
|
1456
|
+
m_textServices->TxSendMessage(EM_SETEVENTMASK, 0, eventMask & ~(ENM_CHANGE | ENM_SELCHANGE), &res));
|
|
1457
|
+
|
|
1458
|
+
auto text = attributedString.getString();
|
|
1316
1459
|
winrt::check_hresult(m_textServices->TxSendMessage(
|
|
1317
|
-
EM_SETTEXTEX, reinterpret_cast<WPARAM>(&stt), reinterpret_cast<LPARAM>(
|
|
1460
|
+
EM_SETTEXTEX, reinterpret_cast<WPARAM>(&stt), reinterpret_cast<LPARAM>(text.c_str()), &res));
|
|
1461
|
+
|
|
1462
|
+
auto baseTextAttributes = windowsTextInputProps().textAttributes;
|
|
1463
|
+
baseTextAttributes.apply(attributedString.getBaseTextAttributes());
|
|
1464
|
+
auto charFormat = GetCharFormat(baseTextAttributes);
|
|
1465
|
+
winrt::check_hresult(
|
|
1466
|
+
m_textServices->TxSendMessage(EM_SETCHARFORMAT, SCF_ALL, reinterpret_cast<LPARAM>(&charFormat), &res));
|
|
1467
|
+
winrt::check_bool(res != 0);
|
|
1468
|
+
|
|
1469
|
+
// Richedit in password mode does not support per-fragment formatting, so we only apply it when not in secureTextEntry
|
|
1470
|
+
// mode.
|
|
1471
|
+
if (!windowsTextInputProps().secureTextEntry) {
|
|
1472
|
+
LONG position = 0;
|
|
1473
|
+
bool previousWasCR = false;
|
|
1474
|
+
for (const auto &fragment : attributedString.getFragments()) {
|
|
1475
|
+
auto fragmentText = ::Microsoft::Common::Unicode::Utf8ToUtf16(fragment.string);
|
|
1476
|
+
LONG end = position;
|
|
1477
|
+
for (auto character : fragmentText) {
|
|
1478
|
+
// RichEdit positions count UTF-16 code units, with CRLF normalized to a single paragraph mark.
|
|
1479
|
+
if (character != L'\n' || !previousWasCR) {
|
|
1480
|
+
++end;
|
|
1481
|
+
}
|
|
1482
|
+
previousWasCR = character == L'\r';
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
if (end != position) {
|
|
1486
|
+
auto textAttributes = baseTextAttributes;
|
|
1487
|
+
textAttributes.apply(fragment.textAttributes);
|
|
1488
|
+
charFormat = GetCharFormat(textAttributes);
|
|
1489
|
+
winrt::check_hresult(m_textServices->TxSendMessage(EM_SETSEL, position, end, &res));
|
|
1490
|
+
winrt::check_hresult(m_textServices->TxSendMessage(
|
|
1491
|
+
EM_SETCHARFORMAT, SCF_SELECTION, reinterpret_cast<LPARAM>(&charFormat), &res));
|
|
1492
|
+
winrt::check_bool(res != 0);
|
|
1493
|
+
}
|
|
1494
|
+
position = end;
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1318
1497
|
|
|
1319
1498
|
winrt::check_hresult(
|
|
1320
1499
|
m_textServices->TxSendMessage(EM_SETSEL, static_cast<WPARAM>(cr.cpMin), static_cast<LPARAM>(cr.cpMax), &res));
|
|
@@ -1322,6 +1501,20 @@ void WindowsTextInputComponentView::UpdateText(const std::string &str) noexcept
|
|
|
1322
1501
|
// enable colored emojis
|
|
1323
1502
|
winrt::check_hresult(
|
|
1324
1503
|
m_textServices->TxSendMessage(EM_SETTYPOGRAPHYOPTIONS, 0x1000 | 0x2000, 0x1000 | 0x2000, nullptr));
|
|
1504
|
+
|
|
1505
|
+
m_recalculateContentVerticalOffset = true;
|
|
1506
|
+
winrt::check_hresult(m_textServices->TxSendMessage(EM_SETEVENTMASK, 0, eventMask, &res));
|
|
1507
|
+
if ((eventMask & ENM_CHANGE) && !m_comingFromState) {
|
|
1508
|
+
OnTextUpdated();
|
|
1509
|
+
}
|
|
1510
|
+
if (eventMask & ENM_SELCHANGE) {
|
|
1511
|
+
CHARRANGE finalSelection;
|
|
1512
|
+
winrt::check_hresult(
|
|
1513
|
+
m_textServices->TxSendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&finalSelection), &res));
|
|
1514
|
+
if (finalSelection.cpMin != cr.cpMin || finalSelection.cpMax != cr.cpMax) {
|
|
1515
|
+
OnSelectionChanged(finalSelection.cpMin, finalSelection.cpMax);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1325
1518
|
}
|
|
1326
1519
|
|
|
1327
1520
|
void WindowsTextInputComponentView::updateLayoutMetrics(
|
|
@@ -1373,7 +1566,10 @@ std::pair<float, float> WindowsTextInputComponentView::GetContentSize() const no
|
|
|
1373
1566
|
|
|
1374
1567
|
SIZE extentHimetric = {
|
|
1375
1568
|
static_cast<LONG>(availableWidth * scale * HIMETRIC_PER_INCH / dpi),
|
|
1376
|
-
|
|
1569
|
+
// -1 measures without zoom, matching how this host draws (TxGetExtent returns E_NOTIMPL).
|
|
1570
|
+
// A positive extent is taken as a zoom reference; LONG_MAX scaled to HIMETRIC saturated to a
|
|
1571
|
+
// huge positive value on ARM64 and shrank the natural height to about 0.
|
|
1572
|
+
-1};
|
|
1377
1573
|
|
|
1378
1574
|
SIZE naturalSize = {0, 0};
|
|
1379
1575
|
|
|
@@ -1401,14 +1597,22 @@ std::pair<float, float> WindowsTextInputComponentView::GetContentSize() const no
|
|
|
1401
1597
|
|
|
1402
1598
|
// When we are notified by RichEdit that the text changed, we need to notify JS
|
|
1403
1599
|
void WindowsTextInputComponentView::OnTextUpdated() noexcept {
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1600
|
+
if (m_builder) {
|
|
1601
|
+
auto attributedStringBox = facebook::react::AttributedStringBox(getAttributedString());
|
|
1602
|
+
const auto eventCount = m_nativeEventCount;
|
|
1603
|
+
m_abistate->updateState([attributedStringBox = std::move(attributedStringBox),
|
|
1604
|
+
eventCount](const ::Microsoft::ReactNative::AbiTextInputStateData &oldData) {
|
|
1605
|
+
auto data = oldData;
|
|
1606
|
+
data.attributedStringBox = attributedStringBox;
|
|
1607
|
+
data.mostRecentEventCount = eventCount;
|
|
1608
|
+
return std::make_shared<const ::Microsoft::ReactNative::AbiTextInputStateData>(std::move(data));
|
|
1609
|
+
});
|
|
1610
|
+
} else {
|
|
1611
|
+
auto data = m_state->getData();
|
|
1612
|
+
data.attributedStringBox = facebook::react::AttributedStringBox(getAttributedString());
|
|
1613
|
+
data.mostRecentEventCount = m_nativeEventCount;
|
|
1614
|
+
m_state->updateState(std::move(data));
|
|
1615
|
+
}
|
|
1412
1616
|
|
|
1413
1617
|
if (m_eventEmitter && !m_comingFromJS) {
|
|
1414
1618
|
// call onChange event
|
|
@@ -1537,7 +1741,9 @@ std::optional<std::string> WindowsTextInputComponentView::getAccessiblityValue()
|
|
|
1537
1741
|
}
|
|
1538
1742
|
|
|
1539
1743
|
void WindowsTextInputComponentView::setAcccessiblityValue(std::string &&value) noexcept {
|
|
1540
|
-
|
|
1744
|
+
facebook::react::AttributedString attributedString;
|
|
1745
|
+
attributedString.appendFragment({std::move(value), windowsTextInputProps().textAttributes, {}});
|
|
1746
|
+
UpdateText(attributedString);
|
|
1541
1747
|
}
|
|
1542
1748
|
|
|
1543
1749
|
bool WindowsTextInputComponentView::getAcccessiblityIsReadOnly() noexcept {
|
|
@@ -1554,6 +1760,11 @@ const facebook::react::WindowsTextInputProps &WindowsTextInputComponentView::win
|
|
|
1554
1760
|
}
|
|
1555
1761
|
|
|
1556
1762
|
void WindowsTextInputComponentView::UpdateCharFormat() noexcept {
|
|
1763
|
+
m_cf = GetCharFormat(windowsTextInputProps().textAttributes);
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
CHARFORMAT2W WindowsTextInputComponentView::GetCharFormat(
|
|
1767
|
+
const facebook::react::TextAttributes &textAttributes) noexcept {
|
|
1557
1768
|
CHARFORMAT2W cfNew = {0};
|
|
1558
1769
|
// Set CHARFORMAT structure
|
|
1559
1770
|
cfNew.cbSize = sizeof(CHARFORMAT2W);
|
|
@@ -1567,15 +1778,18 @@ void WindowsTextInputComponentView::UpdateCharFormat() noexcept {
|
|
|
1567
1778
|
// m_crText = RemoveAlpha(fontDetails.FontColor);
|
|
1568
1779
|
// }
|
|
1569
1780
|
|
|
1570
|
-
const auto &props = windowsTextInputProps();
|
|
1571
1781
|
float fontSize =
|
|
1572
|
-
(std::isnan(
|
|
1573
|
-
|
|
1782
|
+
(std::isnan(textAttributes.fontSize) ? facebook::react::TextAttributes::defaultTextAttributes().fontSize
|
|
1783
|
+
: textAttributes.fontSize);
|
|
1574
1784
|
|
|
1575
1785
|
// Apply maxFontSizeMultiplier if specified
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1786
|
+
if (textAttributes.allowFontScaling.value_or(windowsTextInputProps().allowFontScaling)) {
|
|
1787
|
+
auto fontSizeMultiplier =
|
|
1788
|
+
std::isnan(textAttributes.fontSizeMultiplier) ? m_fontSizeMultiplier : textAttributes.fontSizeMultiplier;
|
|
1789
|
+
auto maxFontSizeMultiplier = textAttributes.maxFontSizeMultiplier;
|
|
1790
|
+
fontSize *=
|
|
1791
|
+
(maxFontSizeMultiplier >= 1.0f) ? std::min(maxFontSizeMultiplier, fontSizeMultiplier) : fontSizeMultiplier;
|
|
1792
|
+
}
|
|
1579
1793
|
|
|
1580
1794
|
cfNew.dwMask |= CFM_SIZE;
|
|
1581
1795
|
// set font size -- 15 to convert twips to pt
|
|
@@ -1583,20 +1797,19 @@ void WindowsTextInputComponentView::UpdateCharFormat() noexcept {
|
|
|
1583
1797
|
|
|
1584
1798
|
// set bold
|
|
1585
1799
|
cfNew.dwMask |= CFM_WEIGHT;
|
|
1586
|
-
cfNew.wWeight =
|
|
1587
|
-
props.textAttributes.fontWeight ? static_cast<WORD>(*props.textAttributes.fontWeight) : DWRITE_FONT_WEIGHT_NORMAL;
|
|
1800
|
+
cfNew.wWeight = textAttributes.fontWeight ? static_cast<WORD>(*textAttributes.fontWeight) : DWRITE_FONT_WEIGHT_NORMAL;
|
|
1588
1801
|
|
|
1589
1802
|
// set font style (italic)
|
|
1590
1803
|
cfNew.dwMask |= CFM_ITALIC;
|
|
1591
|
-
if (
|
|
1592
|
-
|
|
1804
|
+
if (textAttributes.fontStyle == facebook::react::FontStyle::Italic ||
|
|
1805
|
+
textAttributes.fontStyle == facebook::react::FontStyle::Oblique) {
|
|
1593
1806
|
cfNew.dwEffects |= CFE_ITALIC;
|
|
1594
1807
|
}
|
|
1595
1808
|
|
|
1596
1809
|
// set text decoration (underline and strikethrough)
|
|
1597
1810
|
cfNew.dwMask |= (CFM_UNDERLINE | CFM_STRIKEOUT);
|
|
1598
|
-
if (
|
|
1599
|
-
auto decorationType = *
|
|
1811
|
+
if (textAttributes.textDecorationLineType.has_value()) {
|
|
1812
|
+
auto decorationType = *textAttributes.textDecorationLineType;
|
|
1600
1813
|
if (decorationType == facebook::react::TextDecorationLineType::Underline ||
|
|
1601
1814
|
decorationType == facebook::react::TextDecorationLineType::UnderlineStrikethrough) {
|
|
1602
1815
|
cfNew.dwEffects |= CFE_UNDERLINE;
|
|
@@ -1608,11 +1821,10 @@ void WindowsTextInputComponentView::UpdateCharFormat() noexcept {
|
|
|
1608
1821
|
}
|
|
1609
1822
|
|
|
1610
1823
|
// set font family
|
|
1611
|
-
if (!
|
|
1824
|
+
if (!textAttributes.fontFamily.empty()) {
|
|
1612
1825
|
cfNew.dwMask |= CFM_FACE;
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
wcsncpy_s(cfNew.szFaceName, fontFamily.c_str(), LF_FACESIZE);
|
|
1826
|
+
auto fontFamily = ::Microsoft::Common::Unicode::Utf8ToUtf16(textAttributes.fontFamily);
|
|
1827
|
+
wcsncpy_s(cfNew.szFaceName, fontFamily.c_str(), _TRUNCATE);
|
|
1616
1828
|
} else {
|
|
1617
1829
|
cfNew.dwMask |= CFM_FACE;
|
|
1618
1830
|
wcsncpy_s(cfNew.szFaceName, L"Segoe UI\0", LF_FACESIZE);
|
|
@@ -1624,17 +1836,29 @@ void WindowsTextInputComponentView::UpdateCharFormat() noexcept {
|
|
|
1624
1836
|
cfNew.yOffset = 0;
|
|
1625
1837
|
|
|
1626
1838
|
// set letter spacing
|
|
1627
|
-
float letterSpacing =
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1839
|
+
float letterSpacing = textAttributes.letterSpacing;
|
|
1840
|
+
cfNew.dwMask |= CFM_SPACING;
|
|
1841
|
+
cfNew.sSpacing = std::isnan(letterSpacing) ? 0 : static_cast<SHORT>(letterSpacing * 20); // Convert to TWIPS
|
|
1842
|
+
|
|
1843
|
+
cfNew.dwMask |= CFM_COLOR | CFM_BACKCOLOR;
|
|
1844
|
+
cfNew.dwEffects |= CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
|
|
1845
|
+
if (textAttributes.foregroundColor &&
|
|
1846
|
+
textAttributes.foregroundColor != windowsTextInputProps().textAttributes.foregroundColor) {
|
|
1847
|
+
auto color = theme()->Color(*textAttributes.foregroundColor);
|
|
1848
|
+
cfNew.crTextColor = RGB(color.R, color.G, color.B);
|
|
1849
|
+
cfNew.dwEffects &= ~CFE_AUTOCOLOR;
|
|
1850
|
+
}
|
|
1851
|
+
if (facebook::react::isColorMeaningful(textAttributes.backgroundColor)) {
|
|
1852
|
+
auto color = theme()->Color(*textAttributes.backgroundColor);
|
|
1853
|
+
cfNew.crBackColor = RGB(color.R, color.G, color.B);
|
|
1854
|
+
cfNew.dwEffects &= ~CFE_AUTOBACKCOLOR;
|
|
1631
1855
|
}
|
|
1632
1856
|
|
|
1633
1857
|
// set charset
|
|
1634
1858
|
cfNew.dwMask |= CFM_CHARSET;
|
|
1635
1859
|
cfNew.bCharSet = DEFAULT_CHARSET;
|
|
1636
1860
|
|
|
1637
|
-
|
|
1861
|
+
return cfNew;
|
|
1638
1862
|
}
|
|
1639
1863
|
|
|
1640
1864
|
void WindowsTextInputComponentView::UpdateParaFormat() noexcept {
|
|
@@ -1885,21 +2109,50 @@ void WindowsTextInputComponentView::DrawText() noexcept {
|
|
|
1885
2109
|
m_needsRedraw = false;
|
|
1886
2110
|
}
|
|
1887
2111
|
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
2112
|
+
void WindowsTextInputComponentView::ensureTextHost() noexcept {
|
|
2113
|
+
if (!m_textHost) {
|
|
2114
|
+
winrt::check_hresult(HrEnsureRichEd20Loaded());
|
|
2115
|
+
m_textHost = winrt::make<CompTextHost>(this);
|
|
2116
|
+
winrt::com_ptr<::IUnknown> spUnk;
|
|
2117
|
+
winrt::check_hresult(g_pfnCreateTextServices(nullptr, m_textHost.get(), spUnk.put()));
|
|
2118
|
+
spUnk.as(m_textServices);
|
|
2119
|
+
winrt::check_bool(m_textServices != nullptr);
|
|
2120
|
+
|
|
2121
|
+
// Enable TSF support
|
|
2122
|
+
winrt::check_hresult(m_textServices->TxSendMessage(EM_SETEDITSTYLE, SES_USECTF, SES_USECTF, nullptr));
|
|
2123
|
+
winrt::check_hresult(m_textServices->TxSendMessage(EM_SETTEXTMODE, TM_RICHTEXT, 0, nullptr));
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
1897
2126
|
|
|
2127
|
+
HRESULT WindowsTextInputComponentView::GetTextDocument(ITextDocument2 **textDocument) noexcept {
|
|
2128
|
+
winrt::com_ptr<IUnknown> spUnk;
|
|
2129
|
+
winrt::com_ptr<ITextDocument2> spTextDoc;
|
|
2130
|
+
ensureTextHost();
|
|
2131
|
+
|
|
2132
|
+
// initialize TOM
|
|
1898
2133
|
LRESULT res;
|
|
1899
|
-
|
|
2134
|
+
m_textServices->TxSendMessage(EM_GETOLEINTERFACE, 0, reinterpret_cast<LPARAM>(spUnk.put()), &res);
|
|
2135
|
+
HRESULT hr = spUnk->QueryInterface(__uuidof(ITextDocument2), reinterpret_cast<void **>(spTextDoc.put()));
|
|
2136
|
+
spTextDoc.copy_to(textDocument);
|
|
2137
|
+
return hr;
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
HRESULT WindowsTextInputComponentView::GetTextServices(ITextServices2 **textServices) noexcept {
|
|
2141
|
+
ensureTextHost();
|
|
2142
|
+
m_textServices.copy_to(textServices);
|
|
2143
|
+
return S_OK;
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
HRESULT WindowsTextInputComponentView::GetTextHost(ITextHost **textHost) noexcept {
|
|
2147
|
+
ensureTextHost();
|
|
2148
|
+
m_textHost.copy_to(textHost);
|
|
2149
|
+
return S_OK;
|
|
2150
|
+
}
|
|
1900
2151
|
|
|
1901
|
-
|
|
1902
|
-
|
|
2152
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual
|
|
2153
|
+
WindowsTextInputComponentView::createVisual() noexcept {
|
|
2154
|
+
auto visual = m_compContext.CreateSpriteVisual();
|
|
2155
|
+
ensureTextHost();
|
|
1903
2156
|
|
|
1904
2157
|
m_caretVisual = m_compContext.CreateCaretVisual();
|
|
1905
2158
|
visual.InsertAt(m_caretVisual.InnerVisual(), 0);
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
#pragma once
|
|
6
6
|
|
|
7
7
|
#include "Composition.WindowsTextInputComponentView.g.h"
|
|
8
|
+
#include <ComponentView.Experimental.interop.h>
|
|
9
|
+
#include <Fabric/AbiTextInputShadowNode.h>
|
|
8
10
|
#include <ReactContext.h>
|
|
9
11
|
#include <Windows.Graphics.DirectX.Direct3D11.interop.h>
|
|
10
12
|
#include <richedit.h>
|
|
@@ -22,10 +24,16 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
|
22
24
|
struct CompTextHost;
|
|
23
25
|
|
|
24
26
|
struct WindowsTextInputComponentView
|
|
25
|
-
: WindowsTextInputComponentViewT<
|
|
27
|
+
: public WindowsTextInputComponentViewT<
|
|
28
|
+
WindowsTextInputComponentView,
|
|
29
|
+
ViewComponentView,
|
|
30
|
+
::Microsoft::ReactNative::Composition::Experimental::ITextInputComponentInterop> {
|
|
26
31
|
friend CompTextHost;
|
|
27
32
|
|
|
28
|
-
using Super = WindowsTextInputComponentViewT<
|
|
33
|
+
using Super = WindowsTextInputComponentViewT<
|
|
34
|
+
WindowsTextInputComponentView,
|
|
35
|
+
ViewComponentView,
|
|
36
|
+
::Microsoft::ReactNative::Composition::Experimental::ITextInputComponentInterop>;
|
|
29
37
|
[[nodiscard]] static winrt::Microsoft::ReactNative::ComponentView Create(
|
|
30
38
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
31
39
|
facebook::react::Tag tag,
|
|
@@ -71,6 +79,9 @@ struct WindowsTextInputComponentView
|
|
|
71
79
|
void OnContextMenuKey(
|
|
72
80
|
const winrt::Microsoft::ReactNative::Composition::Input::ContextMenuKeyEventArgs &args) noexcept override;
|
|
73
81
|
void onMounted() noexcept override;
|
|
82
|
+
const winrt::Microsoft::ReactNative::IComponentProps userProps(
|
|
83
|
+
facebook::react::Props::Shared const &props) noexcept override;
|
|
84
|
+
winrt::Microsoft::ReactNative::ViewProps ViewPropsInner() noexcept override;
|
|
74
85
|
|
|
75
86
|
std::optional<std::string> getAccessiblityValue() noexcept override;
|
|
76
87
|
void setAcccessiblityValue(std::string &&value) noexcept override;
|
|
@@ -80,13 +91,18 @@ struct WindowsTextInputComponentView
|
|
|
80
91
|
WindowsTextInputComponentView(
|
|
81
92
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
82
93
|
facebook::react::Tag tag,
|
|
83
|
-
winrt::Microsoft::ReactNative::ReactContext const &reactContext
|
|
94
|
+
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
95
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder = nullptr);
|
|
84
96
|
~WindowsTextInputComponentView();
|
|
85
97
|
|
|
86
98
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual createVisual() noexcept;
|
|
87
99
|
|
|
88
100
|
std::pair<facebook::react::Cursor, HCURSOR> cursor() const noexcept override;
|
|
89
101
|
|
|
102
|
+
HRESULT GetTextDocument(ITextDocument2 **) noexcept;
|
|
103
|
+
HRESULT GetTextServices(ITextServices2 **textServices) noexcept;
|
|
104
|
+
HRESULT GetTextHost(ITextHost **textHost) noexcept;
|
|
105
|
+
|
|
90
106
|
private:
|
|
91
107
|
struct DrawBlock {
|
|
92
108
|
DrawBlock(WindowsTextInputComponentView &view);
|
|
@@ -100,8 +116,9 @@ struct WindowsTextInputComponentView
|
|
|
100
116
|
void ShowCaret(bool show) noexcept;
|
|
101
117
|
winrt::com_ptr<::IDWriteTextLayout> CreatePlaceholderLayout();
|
|
102
118
|
void UpdateCharFormat() noexcept;
|
|
119
|
+
CHARFORMAT2W GetCharFormat(const facebook::react::TextAttributes &textAttributes) noexcept;
|
|
103
120
|
void UpdateParaFormat() noexcept;
|
|
104
|
-
void UpdateText(const
|
|
121
|
+
void UpdateText(const facebook::react::AttributedString &attributedString) noexcept;
|
|
105
122
|
void OnTextUpdated() noexcept;
|
|
106
123
|
void EmitOnScrollEvent() noexcept;
|
|
107
124
|
void OnSelectionChanged(LONG start, LONG end) noexcept;
|
|
@@ -124,6 +141,8 @@ struct WindowsTextInputComponentView
|
|
|
124
141
|
void ShowContextMenu(const winrt::Windows::Foundation::Point &position) noexcept;
|
|
125
142
|
void calculateContentVerticalOffset() noexcept;
|
|
126
143
|
|
|
144
|
+
void ensureTextHost() noexcept;
|
|
145
|
+
|
|
127
146
|
winrt::Windows::UI::Composition::CompositionSurfaceBrush m_brush{nullptr};
|
|
128
147
|
winrt::Microsoft::ReactNative::Composition::Experimental::ICaretVisual m_caretVisual{nullptr};
|
|
129
148
|
winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush m_drawingSurface{nullptr};
|
|
@@ -136,6 +155,7 @@ struct WindowsTextInputComponentView
|
|
|
136
155
|
winrt::com_ptr<ITextServices2> m_textServices;
|
|
137
156
|
unsigned int m_imgWidth{0}, m_imgHeight{0};
|
|
138
157
|
std::shared_ptr<facebook::react::WindowsTextInputShadowNode::ConcreteState const> m_state;
|
|
158
|
+
std::shared_ptr<::Microsoft::ReactNative::AbiTextInputShadowNode::ConcreteState const> m_abistate;
|
|
139
159
|
float m_fontSizeMultiplier{1.0};
|
|
140
160
|
int64_t m_mostRecentEventCount{0};
|
|
141
161
|
int m_nativeEventCount{0};
|