diff options
author | José Medrano <jose.medrano@xamarin.com> | 2015-05-04 18:35:42 +0300 |
---|---|---|
committer | José Medrano <jose.medrano@xamarin.com> | 2015-05-04 18:35:42 +0300 |
commit | 5fe9514aa5f16c5f26d854e86aa0e54f76d1ba4d (patch) | |
tree | 9905f47be0eaf19db076a8aa547e30a9374f8b25 | |
parent | fecebb226779d764ec22646c1895791e2c53ab4d (diff) |
[Xwt] Added text selection in RichTextViewfeature_richtextview_text_selection
Gtk + XamMac backend
-rwxr-xr-x | Xwt.Gtk/Xwt.GtkBackend/RichTextViewBackend.cs | 114 | ||||
-rw-r--r-- | Xwt.XamMac/Xwt.Mac/RichTextViewBackend.cs | 18 | ||||
-rw-r--r-- | Xwt/Xwt.Backends/IRichTextViewBackend.cs | 10 | ||||
-rw-r--r-- | Xwt/Xwt/RichTextView.cs | 47 |
4 files changed, 187 insertions, 2 deletions
diff --git a/Xwt.Gtk/Xwt.GtkBackend/RichTextViewBackend.cs b/Xwt.Gtk/Xwt.GtkBackend/RichTextViewBackend.cs index 57246ba3..9dda6539 100755 --- a/Xwt.Gtk/Xwt.GtkBackend/RichTextViewBackend.cs +++ b/Xwt.Gtk/Xwt.GtkBackend/RichTextViewBackend.cs @@ -34,6 +34,67 @@ namespace Xwt.GtkBackend { public class RichTextViewBackend : WidgetBackend, IRichTextViewBackend { + protected new IRichTextViewEventSink EventSink { + get { return (IRichTextViewEventSink)base.EventSink; } + } + + public int CursorPosition { + get { return Widget.Buffer.CursorPosition; } + set { + if (CursorPosition != value) { + Widget.Buffer.GetIterAtOffset (0).ForwardChars (value); + HandleSelectionChanged (); + } + } + } + + public int SelectionStart { + get { + Gtk.TextIter start, end; + Widget.Buffer.GetSelectionBounds (out start, out end); + return end.Buffer.CursorPosition; + } + set { + Widget.GrabFocus (); + if (SelectionStart != value) { + var start = Widget.Buffer.GetIterAtOffset (value); + var end = Widget.Buffer.GetIterAtOffset (SelectionLength); + Widget.Buffer.SelectRange (start, end); + HandleSelectionChanged (); + } + } + } + + public int SelectionLength { + get { + Gtk.TextIter start, end; + Widget.Buffer.GetSelectionBounds (out start, out end); + return end.Buffer.CursorPosition - start.Buffer.CursorPosition; + } + set { + Widget.GrabFocus (); + if (SelectionLength != value) { + var start = Widget.Buffer.GetIterAtOffset (SelectionStart); + var end = Widget.Buffer.GetIterAtOffset (value); + Widget.Buffer.SelectRange (start, end); + HandleSelectionChanged (); + } + } + } + + public string SelectedText { + get { + int start = SelectionStart; + int end = start + SelectionLength; + if (start == end) return String.Empty; + try { + return Widget.Buffer.Text.Substring (start, end - start); + } catch { + return String.Empty; + } + } + } + Gtk.TextTagTable table; LinkLabel [] links; @@ -104,10 +165,63 @@ namespace Xwt.GtkBackend case RichTextViewEvent.NavigateToUrl: NavigateToUrlEnabled = true; break; + case RichTextViewEvent.SelectionChanged: + enableSelectionChangedEvent = true; + Widget.MoveCursor += HandleMoveCursor; + Widget.ButtonPressEvent += HandleButtonPressEvent; + Widget.ButtonReleaseEvent += HandleButtonReleaseEvent; + Widget.MotionNotifyEvent += HandleMotionNotifyEvent; + break; } } } + bool enableSelectionChangedEvent; + void HandleSelectionChanged () + { + if (enableSelectionChangedEvent) + ApplicationContext.InvokeUserCode (delegate { + EventSink.OnSelectionChanged (); + }); + } + + void HandleMoveCursor (object sender, EventArgs e) + { + HandleSelectionChanged (); + } + + int cacheSelectionStart, cacheSelectionLength; + bool isMouseSelection; + [GLib.ConnectBefore] + void HandleButtonPressEvent (object o, Gtk.ButtonPressEventArgs args) + { + if (args.Event.Button == 1) { + HandleSelectionChanged (); + cacheSelectionStart = SelectionStart; + cacheSelectionLength = SelectionLength; + isMouseSelection = true; + } + } + + [GLib.ConnectBefore] + void HandleMotionNotifyEvent (object o, Gtk.MotionNotifyEventArgs args) + { + if (isMouseSelection) + if (cacheSelectionStart != SelectionStart || cacheSelectionLength != SelectionLength) + HandleSelectionChanged (); + cacheSelectionStart = SelectionStart; + cacheSelectionLength = SelectionLength; + } + + [GLib.ConnectBefore] + void HandleButtonReleaseEvent (object o, Gtk.ButtonReleaseEventArgs args) + { + if (args.Event.Button == 1) { + isMouseSelection = false; + HandleSelectionChanged (); + } + } + public override void DisableEvent (object eventId) { base.DisableEvent (eventId); diff --git a/Xwt.XamMac/Xwt.Mac/RichTextViewBackend.cs b/Xwt.XamMac/Xwt.Mac/RichTextViewBackend.cs index 91d8cfb0..f09d39c5 100644 --- a/Xwt.XamMac/Xwt.Mac/RichTextViewBackend.cs +++ b/Xwt.XamMac/Xwt.Mac/RichTextViewBackend.cs @@ -55,6 +55,24 @@ namespace Xwt.Mac public class RichTextViewBackend : ViewBackend <NSTextView, IRichTextViewEventSink>, IRichTextViewBackend { NSFont font; + public int CursorPosition { + get { return (int) Widget.SelectedRange.Location; } + set { Widget.SelectedRange = new NSRange (value, SelectionLength); } + } + + public int SelectionStart { + get { return CursorPosition; } + set { CursorPosition = value; } + } + + public int SelectionLength { + get { return (int) Widget.SelectedRange.Length; } + set { Widget.SelectedRange = new NSRange (SelectionStart, value); } + } + + public string SelectedText { + get { return Widget.Value.Substring (SelectionStart, SelectionLength); } + } public override object Font { get { return base.Font; } diff --git a/Xwt/Xwt.Backends/IRichTextViewBackend.cs b/Xwt/Xwt.Backends/IRichTextViewBackend.cs index 4544e9e6..cb9082c9 100644 --- a/Xwt/Xwt.Backends/IRichTextViewBackend.cs +++ b/Xwt/Xwt.Backends/IRichTextViewBackend.cs @@ -20,8 +20,12 @@ namespace Xwt.Backends public interface IRichTextViewBackend : IWidgetBackend { - IRichTextBuffer CreateBuffer (); + int CursorPosition { get; set; } + int SelectionStart { get; set; } + int SelectionLength { get; set; } + string SelectedText { get; } + IRichTextBuffer CreateBuffer (); // Display the passed buffer void SetBuffer (IRichTextBuffer buffer); } @@ -60,11 +64,13 @@ namespace Xwt.Backends public interface IRichTextViewEventSink : IWidgetEventSink { + void OnSelectionChanged (); void OnNavigateToUrl (Uri uri); } public enum RichTextViewEvent { - NavigateToUrl = 1 + NavigateToUrl = 1, + SelectionChanged = 2 } } diff --git a/Xwt/Xwt/RichTextView.cs b/Xwt/Xwt/RichTextView.cs index 3d313172..55f4feb3 100644 --- a/Xwt/Xwt/RichTextView.cs +++ b/Xwt/Xwt/RichTextView.cs @@ -32,18 +32,58 @@ using System.Text; using Xwt.Backends; using Xwt.Formats; +using System.ComponentModel; namespace Xwt { [BackendType (typeof(IRichTextViewBackend))] public class RichTextView : Widget { + [DefaultValue (0)] + public int CursorPosition { + get { return Backend.CursorPosition; } + set { Backend.CursorPosition = value; } + } + + [DefaultValue (0)] + public int SelectionStart { + get { return Backend.SelectionStart; } + set { Backend.SelectionStart = value; } + } + + [DefaultValue (0)] + public int SelectionLength { + get { return Backend.SelectionLength; } + set { Backend.SelectionLength = value; } + } + + [DefaultValue ("")] + public string SelectedText { + get { return Backend.SelectedText; } + } + EventHandler selectionChanged; + public event EventHandler SelectionChanged { + add { + BackendHost.OnBeforeEventAdd (RichTextViewEvent.SelectionChanged, selectionChanged); + selectionChanged += value; + } + remove { + selectionChanged -= value; + BackendHost.OnAfterEventRemove (RichTextViewEvent.SelectionChanged, selectionChanged); + } + } + protected new class WidgetBackendHost : Widget.WidgetBackendHost, IRichTextViewEventSink { public void OnNavigateToUrl (Uri uri) { ((RichTextView) Parent).OnNavigateToUrl (new NavigateToUrlEventArgs (uri)); } + + public void OnSelectionChanged () + { + ((RichTextView)Parent).OnSelectionChanged (EventArgs.Empty); + } } IRichTextViewBackend Backend { @@ -68,6 +108,7 @@ namespace Xwt public RichTextView () { NavigateToUrl += delegate { }; // ensure the virtual method is always called + MapEvent (RichTextViewEvent.SelectionChanged, typeof(RichTextView), "OnSelectionChanged"); } public void LoadFile (string fileName, TextFormat format) @@ -95,6 +136,12 @@ namespace Xwt return new WidgetBackendHost (); } + protected virtual void OnSelectionChanged (EventArgs e) + { + if (selectionChanged != null) + selectionChanged (this, e); + } + protected virtual void OnNavigateToUrl (NavigateToUrlEventArgs e) { if (navigateToUrl != null) |