123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- // Engine/Source/Runtime/WebBrowser/Private/CEF/CEFTextInputMethodContext.cpp
- #include "CEF/CEFInterfaceTextInputMethodContext.h"
- #if WITH_CEF3 && !PLATFORM_LINUX
- #include "CEF/CEFWebInterfaceBrowserWindow.h"
- #include "CEFInterfaceImeHandler.h"
- #include "Framework/Application/SlateApplication.h"
- TSharedRef<FCEFInterfaceTextInputMethodContext> FCEFInterfaceTextInputMethodContext::Create(const TSharedRef<FCEFInterfaceImeHandler>& InOwner)
- {
- return MakeShareable(new FCEFInterfaceTextInputMethodContext(InOwner));
- }
- FCEFInterfaceTextInputMethodContext::FCEFInterfaceTextInputMethodContext(const TSharedRef<FCEFInterfaceImeHandler>& InOwner)
- : Owner(InOwner)
- , bIsComposing(false)
- , CompositionBeginIndex(0)
- , CompositionLength(0)
- , SelectionRangeBeginIndex(0)
- , SelectionRangeLength(0)
- , SelectionCaretPosition(ECaretPosition::Ending)
- {
- }
- void FCEFInterfaceTextInputMethodContext::AbortComposition()
- {
- bIsComposing = false;
- Owner->InternalCefBrowser->GetHost()->ImeCancelComposition();
- ResetComposition();
- }
- bool FCEFInterfaceTextInputMethodContext::UpdateCachedGeometry(const FGeometry& AllottedGeometry)
- {
- bool bCachedGeometryUpdated = false;
- if (CachedGeometry != AllottedGeometry)
- {
- CachedGeometry = AllottedGeometry;
- bCachedGeometryUpdated = true;
- }
- return bCachedGeometryUpdated;
- }
- bool FCEFInterfaceTextInputMethodContext::CEFCompositionRangeChanged(const CefRange& SelectionRange, const CefRenderHandler::RectList& CharacterBounds)
- {
- if (bIsComposing)
- {
- if (CharacterBounds != CefCompositionBounds)
- {
- CefCompositionBounds = CharacterBounds;
- return true;
- }
- }
- return false;
- }
- bool FCEFInterfaceTextInputMethodContext::IsComposing()
- {
- return bIsComposing;
- }
- bool FCEFInterfaceTextInputMethodContext::IsReadOnly()
- {
- return false;
- }
- uint32 FCEFInterfaceTextInputMethodContext::GetTextLength()
- {
- return CompositionString.Len();
- }
- void FCEFInterfaceTextInputMethodContext::GetSelectionRange(uint32& BeginIndex, uint32& Length, ECaretPosition& CaretPosition)
- {
- BeginIndex = SelectionRangeBeginIndex;
- Length = SelectionRangeLength;
- CaretPosition = SelectionCaretPosition;
- }
- void FCEFInterfaceTextInputMethodContext::SetSelectionRange(const uint32 BeginIndex, const uint32 Length, const ECaretPosition CaretPosition)
- {
- SelectionRangeBeginIndex = BeginIndex;
- SelectionRangeLength = Length;
- SelectionCaretPosition = CaretPosition;
- CefString Str = TCHAR_TO_WCHAR(*CompositionString);
- std::vector<CefCompositionUnderline> underlines;
- Owner->InternalCefBrowser->GetHost()->ImeSetComposition(
- Str,
- underlines,
- CefRange(UINT32_MAX, UINT32_MAX),
- CefRange(SelectionRangeBeginIndex, SelectionRangeLength));
- }
- void FCEFInterfaceTextInputMethodContext::GetTextInRange(const uint32 BeginIndex, const uint32 Length, FString& OutString)
- {
- OutString = CompositionString.Mid(BeginIndex, Length);
- }
- void FCEFInterfaceTextInputMethodContext::SetTextInRange(const uint32 BeginIndex, const uint32 Length, const FString& InString)
- {
- FString NewString;
- if (BeginIndex > 0)
- {
- NewString = CompositionString.Mid(0, BeginIndex);
- }
- NewString += InString;
- if ((int32)(BeginIndex + Length) < CompositionString.Len())
- {
- NewString += CompositionString.Mid(BeginIndex + Length, CompositionString.Len() - (BeginIndex + Length));
- }
- CompositionString = NewString;
- CefString Str = TCHAR_TO_WCHAR(*CompositionString);
- std::vector<CefCompositionUnderline> underlines;
- Owner->InternalCefBrowser->GetHost()->ImeSetComposition(
- Str,
- underlines,
- CefRange(UINT32_MAX, UINT32_MAX),
- CefRange(0, Str.length()));
- }
- int32 FCEFInterfaceTextInputMethodContext::GetCharacterIndexFromPoint(const FVector2D& Point)
- {
- int32 ResultIdx = INDEX_NONE;
- const FVector2D LocalPoint = CachedGeometry.AbsoluteToLocal(Point);
- CefPoint CefLocalPoint = CefPoint(FMath::RoundToInt(LocalPoint.X), FMath::RoundToInt(LocalPoint.Y));
- for (uint32 CharIdx = 0; CharIdx < CefCompositionBounds.size(); CharIdx++)
- {
- if (CefCompositionBounds[CharIdx].Contains(CefLocalPoint))
- {
- ResultIdx = CharIdx;
- break;
- }
- }
- return ResultIdx;
- }
- bool FCEFInterfaceTextInputMethodContext::GetTextBounds(const uint32 BeginIndex, const uint32 Length, FVector2D& Position, FVector2D& Size)
- {
- if (CefCompositionBounds.size() < BeginIndex ||
- CefCompositionBounds.size() < BeginIndex + Length)
- {
- if (CefCompositionBounds.size() > 0)
- {
- // Fall back to the start of the composition
- Position = CachedGeometry.LocalToAbsolute(FVector2D(CefCompositionBounds[0].x, CefCompositionBounds[0].y));
- Size = FVector2D(CefCompositionBounds[0].width, CefCompositionBounds[0].height);
- return false;
- }
- else
- {
- // We don't have any updated composition bounds so we'll just default to the window bounds and say we are clipped.
- GetScreenBounds(Position, Size);
- return true;
- }
- }
- FVector2D LocalSpaceMin(FLT_MAX, FLT_MAX);
- FVector2D LocalSpaceMax(-FLT_MAX, -FLT_MAX);
- for (uint32 CharIdx = BeginIndex; CharIdx < BeginIndex + Length; CharIdx++)
- {
- if (LocalSpaceMin.X > CefCompositionBounds[CharIdx].x)
- {
- LocalSpaceMin.X = CefCompositionBounds[CharIdx].x;
- }
- if (LocalSpaceMax.X < CefCompositionBounds[CharIdx].x + CefCompositionBounds[CharIdx].width)
- {
- LocalSpaceMax.X = CefCompositionBounds[CharIdx].x + CefCompositionBounds[CharIdx].width;
- }
- if (LocalSpaceMin.Y > CefCompositionBounds[CharIdx].y)
- {
- LocalSpaceMin.Y = CefCompositionBounds[CharIdx].y;
- }
- if (LocalSpaceMax.Y < CefCompositionBounds[CharIdx].y + CefCompositionBounds[CharIdx].height)
- {
- LocalSpaceMax.Y = CefCompositionBounds[CharIdx].y + CefCompositionBounds[CharIdx].height;
- }
- }
- Position = CachedGeometry.LocalToAbsolute(LocalSpaceMin);
- Size = LocalSpaceMax - LocalSpaceMin;
- return false; // false means "not clipped"
- }
- void FCEFInterfaceTextInputMethodContext::GetScreenBounds(FVector2D& Position, FVector2D& Size)
- {
- Position = CachedGeometry.GetAccumulatedRenderTransform().GetTranslation();
- Size = TransformVector(CachedGeometry.GetAccumulatedRenderTransform(), CachedGeometry.GetLocalSize());
- }
- TSharedPtr<FGenericWindow> FCEFInterfaceTextInputMethodContext::GetWindow()
- {
- if (CachedSlateWindow.IsValid())
- {
- return CachedSlateWindow.Pin()->GetNativeWindow();
- }
- const TSharedPtr<SWidget> CachedSlateWidgetPtr = Owner->InternalBrowserSlateWidget.Pin();
- if (!CachedSlateWidgetPtr.IsValid())
- {
- return nullptr;
- }
- TSharedPtr<SWindow> SlateWindow = FSlateApplication::Get().FindWidgetWindow(CachedSlateWidgetPtr.ToSharedRef());
- CachedSlateWindow = SlateWindow;
- return SlateWindow.IsValid() ? SlateWindow->GetNativeWindow() : nullptr;
- }
- void FCEFInterfaceTextInputMethodContext::BeginComposition()
- {
- if (!bIsComposing)
- {
- bIsComposing = true;
- }
- }
- void FCEFInterfaceTextInputMethodContext::UpdateCompositionRange(const int32 InBeginIndex, const uint32 InLength)
- {
- CompositionBeginIndex = InBeginIndex;
- CompositionLength = InLength;
- }
- void FCEFInterfaceTextInputMethodContext::EndComposition()
- {
- if (bIsComposing)
- {
- bIsComposing = false;
- if (CompositionString.Len() > 0)
- {
- CefString Result = TCHAR_TO_WCHAR(*CompositionString);
- Owner->InternalCefBrowser->GetHost()->ImeCommitText(Result, CefRange(UINT32_MAX, UINT32_MAX), 0);
- }
- else
- {
- Owner->InternalCefBrowser->GetHost()->ImeCancelComposition();
- }
- ResetComposition();
- }
- }
- void FCEFInterfaceTextInputMethodContext::ResetComposition()
- {
- CompositionString.Empty();
- CefCompositionBounds.clear();
- CompositionBeginIndex = 0;
- CompositionLength = 0;
- SelectionRangeBeginIndex = 0;
- SelectionRangeLength = 0;
- }
- #endif
|