diff --git a/CefSharp.Core/Internals/CefBrowserHostWrapper.cpp b/CefSharp.Core/Internals/CefBrowserHostWrapper.cpp index 2c1cffe608..59eba1d107 100644 --- a/CefSharp.Core/Internals/CefBrowserHostWrapper.cpp +++ b/CefSharp.Core/Internals/CefBrowserHostWrapper.cpp @@ -301,6 +301,57 @@ void CefBrowserHostWrapper::Invalidate(PaintElementType type) _browserHost->Invalidate((CefBrowserHost::PaintElementType)type); } +void CefBrowserHostWrapper::ImeSetComposition(String^ text, cli::array^ underlines, Nullable selectionRange) +{ + ThrowIfDisposed(); + + std::vector underlinesVector = std::vector(); + CefRange range; + + if (underlines != nullptr && underlines->Length > 0) + { + for each (CompositionUnderline underline in underlines) + { + auto c = CefCompositionUnderline(); + c.range = CefRange(underline.Range.From, underline.Range.To); + c.color = underline.Color; + c.background_color = underline.BackgroundColor; + c.thick = (int)underline.Thick; + underlinesVector.push_back(c); + } + } + + if (selectionRange.HasValue) + { + range = CefRange(selectionRange.Value.From, selectionRange.Value.To); + } + + //Replacement Range is Mac OSX only + _browserHost->ImeSetComposition(StringUtils::ToNative(text), underlinesVector, CefRange(), range); +} + +void CefBrowserHostWrapper::ImeCommitText(String^ text) +{ + ThrowIfDisposed(); + + //Range and cursor position are Mac OSX only + _browserHost->ImeCommitText(StringUtils::ToNative(text), CefRange(), NULL); +} + +void CefBrowserHostWrapper::ImeFinishComposingText(bool keepSelection) +{ + ThrowIfDisposed(); + + _browserHost->ImeFinishComposingText(keepSelection); +} + +void CefBrowserHostWrapper::ImeCancelComposition() +{ + ThrowIfDisposed(); + + _browserHost->ImeCancelComposition(); +} + void CefBrowserHostWrapper::SendMouseClickEvent(int x, int y, MouseButtonType mouseButtonType, bool mouseUp, int clickCount, CefEventFlags modifiers) { ThrowIfDisposed(); diff --git a/CefSharp.Core/Internals/CefBrowserHostWrapper.h b/CefSharp.Core/Internals/CefBrowserHostWrapper.h index 880533592b..32076c6fef 100644 --- a/CefSharp.Core/Internals/CefBrowserHostWrapper.h +++ b/CefSharp.Core/Internals/CefBrowserHostWrapper.h @@ -82,6 +82,11 @@ namespace CefSharp virtual void Invalidate(PaintElementType type); + virtual void ImeSetComposition(String^ text, cli::array^ underlines, Nullable selectionRange); + virtual void ImeCommitText(String^ text); + virtual void ImeFinishComposingText(bool keepSelection); + virtual void ImeCancelComposition(); + virtual void SendMouseClickEvent(int x, int y, MouseButtonType mouseButtonType, bool mouseUp, int clickCount, CefEventFlags modifiers); virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave, CefEventFlags modifiers); diff --git a/CefSharp.Core/Internals/RenderClientAdapter.h b/CefSharp.Core/Internals/RenderClientAdapter.h index c0859cd5d8..aee4ddbce8 100644 --- a/CefSharp.Core/Internals/RenderClientAdapter.h +++ b/CefSharp.Core/Internals/RenderClientAdapter.h @@ -185,6 +185,37 @@ namespace CefSharp return _renderWebBrowser->StartDragging(%dragDataWrapper, (CefSharp::DragOperationsMask)allowedOps, x, y); } + /// + // Called when the web view wants to update the mouse cursor during a + // drag & drop operation. |operation| describes the allowed operation + // (none, move, copy, link). + /// + /*--cef()--*/ + virtual DECL void UpdateDragCursor(CefRefPtr browser, CefRenderHandler::DragOperation operation) + { + return _renderWebBrowser->UpdateDragCursor((CefSharp::DragOperationsMask)operation); + } + + /// + // Called when the IME composition range has changed. |selected_range| is the + // range of characters that have been selected. |character_bounds| is the + // bounds of each character in view coordinates. + /// + /*--cef()--*/ + virtual DECL void OnImeCompositionRangeChanged(CefRefPtr browser, const CefRange& selectedRange, const RectList& characterBounds) + { + //TODO: use cli:array rather then creating a list then calling ToArray() + auto charBounds = gcnew List((int)characterBounds.size()); + + std::vector::const_iterator it = + characterBounds.begin(); + for (; it != characterBounds.end(); ++it) + { + charBounds->Add(Rect((*it).x, (*it).y, (*it).width, (*it).height)); + } + _renderWebBrowser->OnImeCompositionRangeChanged(Range(selectedRange.from, selectedRange.to), charBounds->ToArray()); + } + private: void ReleaseBitmapHandlers(BitmapInfo^ bitmapInfo) { diff --git a/CefSharp.OffScreen/ChromiumWebBrowser.cs b/CefSharp.OffScreen/ChromiumWebBrowser.cs index b44551fd3b..c67af3ea2c 100644 --- a/CefSharp.OffScreen/ChromiumWebBrowser.cs +++ b/CefSharp.OffScreen/ChromiumWebBrowser.cs @@ -749,6 +749,11 @@ bool IRenderWebBrowser.StartDragging(IDragData dragData, DragOperationsMask mask return false; } + void IRenderWebBrowser.UpdateDragCursor(DragOperationsMask operation) + { + //TODO: Someone should implement this + } + /// /// Sets the popup is open. /// @@ -780,6 +785,11 @@ void IRenderWebBrowser.SetPopupSizeAndPosition(int width, int height, int x, int popupSize.Height = height; } + void IRenderWebBrowser.OnImeCompositionRangeChanged(Range selectedRange, Rect[] characterBounds) + { + //TODO: Implement this + } + /// /// Handles the event. /// diff --git a/CefSharp.Wpf/ChromiumWebBrowser.cs b/CefSharp.Wpf/ChromiumWebBrowser.cs index eb8238ce88..7f38a225fa 100644 --- a/CefSharp.Wpf/ChromiumWebBrowser.cs +++ b/CefSharp.Wpf/ChromiumWebBrowser.cs @@ -595,6 +595,11 @@ bool IRenderWebBrowser.StartDragging(IDragData dragData, DragOperationsMask mask return true; } + void IRenderWebBrowser.UpdateDragCursor(DragOperationsMask operation) + { + //TODO: Someone should implement this + } + /// /// Invokes the render asynchronous. /// @@ -676,6 +681,11 @@ void IRenderWebBrowser.SetCursor(IntPtr handle, CefCursorType type) } } + void IRenderWebBrowser.OnImeCompositionRangeChanged(Range selectedRange, Rect[] characterBounds) + { + //TODO: Implement this + } + /// /// Sets the address. /// @@ -2076,5 +2086,6 @@ public bool IsDisposed // } // } //} + } } diff --git a/CefSharp/CefSharp.csproj b/CefSharp/CefSharp.csproj index 39d487af72..874ea6b179 100644 --- a/CefSharp/CefSharp.csproj +++ b/CefSharp/CefSharp.csproj @@ -80,6 +80,7 @@ + @@ -209,6 +210,7 @@ + diff --git a/CefSharp/CompositionUnderline.cs b/CefSharp/CompositionUnderline.cs new file mode 100644 index 0000000000..bfb0c7bc67 --- /dev/null +++ b/CefSharp/CompositionUnderline.cs @@ -0,0 +1,45 @@ +// Copyright © 2010-2016 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +namespace CefSharp +{ + /// + /// Represents an IME composition underline. + /// + public struct CompositionUnderline + { + public CompositionUnderline(Range range, uint color, uint backGroundColor, bool thick) + : this() + { + Range = range; + Color = color; + BackgroundColor = backGroundColor; + Thick = thick; + } + + /// + /// Underline character range. + /// + public Range Range { get; private set; } + + /// + /// Text color. 32-bit ARGB color value, not premultiplied. The color components are always + /// in a known order. Equivalent to the SkColor type. + /// + public uint Color { get; private set; } + /// + /// Background color. 32-bit ARGB color value, not premultiplied. The color components are always + /// in a known order. Equivalent to the SkColor type. + /// + public uint BackgroundColor { get; private set; } + + /// + /// true for thickunderline + /// + public bool Thick { get; private set; } + + + } +} + diff --git a/CefSharp/IBrowserHost.cs b/CefSharp/IBrowserHost.cs index 7ed166c8bc..76e067a7d9 100644 --- a/CefSharp/IBrowserHost.cs +++ b/CefSharp/IBrowserHost.cs @@ -120,6 +120,52 @@ public interface IBrowserHost : IDisposable /// indicates which surface to re-paint either View or Popup. void Invalidate(PaintElementType type); + /// + /// Begins a new composition or updates the existing composition. Blink has a + /// special node (a composition node) that allows the input method to change + /// text without affecting other DOM nodes. + /// + /// This method may be called multiple times as the composition changes. When + /// the client is done making changes the composition should either be canceled + /// or completed. To cancel the composition call ImeCancelComposition. To + /// complete the composition call either ImeCommitText or + /// ImeFinishComposingText. Completion is usually signaled when: + /// The client receives a WM_IME_COMPOSITION message with a GCS_RESULTSTR + /// flag (on Windows). + /// This method is only used when window rendering is disabled. (WPF and OffScreen) + /// + /// is the optional text that + /// will be inserted into the composition node + /// is an optional set + /// of ranges that will be underlined in the resulting text. + /// is an optional range of the resulting text that + /// will be selected after insertion or replacement. + void ImeSetComposition(string text, CompositionUnderline[] underlines, Range? selectionRange); + + /// + /// Completes the existing composition by optionally inserting the specified + /// text into the composition node. + /// This method is only used when window rendering is disabled. (WPF and OffScreen) + /// + /// + /// text that will be committed + void ImeCommitText(string text); + /// + /// Completes the existing composition by applying the current composition node + /// contents. See comments on ImeSetComposition for usage. + /// This method is only used when window rendering is disabled. (WPF and OffScreen) + /// + /// If keepSelection is false the current selection, if any, will be discarded. + void ImeFinishComposingText(bool keepSelection); + + /// + /// Cancels the existing composition and discards the composition node + /// contents without applying them. See comments on ImeSetComposition for + /// usage. + /// This method is only used when window rendering is disabled. (WPF and OffScreen) + /// + void ImeCancelComposition(); + /// /// Get/Set Mouse cursor change disabled /// diff --git a/CefSharp/Internals/IRenderWebBrowser.cs b/CefSharp/Internals/IRenderWebBrowser.cs index c2175c078c..3b417e3a24 100644 --- a/CefSharp/Internals/IRenderWebBrowser.cs +++ b/CefSharp/Internals/IRenderWebBrowser.cs @@ -17,8 +17,16 @@ public interface IRenderWebBrowser : IWebBrowserInternal void SetCursor(IntPtr cursor, CefCursorType type); bool StartDragging(IDragData dragData, DragOperationsMask mask, int x, int y); + void UpdateDragCursor(DragOperationsMask operation); void SetPopupIsOpen(bool show); void SetPopupSizeAndPosition(int width, int height, int x, int y); + + /// + /// Called when the IME composition range has changed. + /// + /// is the range of characters that have been selected + /// is the bounds of each character in view coordinates. + void OnImeCompositionRangeChanged(Range selectedRange, Rect[] characterBounds); }; } diff --git a/CefSharp/Range.cs b/CefSharp/Range.cs new file mode 100644 index 0000000000..f0d6e20d15 --- /dev/null +++ b/CefSharp/Range.cs @@ -0,0 +1,22 @@ +// Copyright © 2010-2016 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +namespace CefSharp +{ + /// + /// Represents a range + /// + public struct Range + { + public Range(int from, int to) + : this() + { + From = from; + To = to; + } + + public int From { get; private set; } + public int To { get; private set; } + } +}