Merge pull request #344 from sevoku/add-text-cursor-selection
[MAC] add missing cursor position and selection support to TextEntryBackend
This commit is contained in:
Коммит
aa7e600b56
|
@ -102,6 +102,9 @@ namespace Xwt.Mac
|
|||
ITextEntryEventSink entryEventSink;
|
||||
ApplicationContext context;
|
||||
|
||||
int cacheSelectionStart, cacheSelectionLength;
|
||||
bool checkMouseMovement;
|
||||
|
||||
public MacComboBox (IComboBoxEventSink eventSink, ApplicationContext context)
|
||||
{
|
||||
this.context = context;
|
||||
|
@ -127,6 +130,125 @@ namespace Xwt.Mac
|
|||
if (entryEventSink != null) {
|
||||
context.InvokeUserCode (delegate {
|
||||
entryEventSink.OnChanged ();
|
||||
entryEventSink.OnSelectionChanged ();
|
||||
});
|
||||
}
|
||||
}
|
||||
public override void KeyUp (NSEvent theEvent)
|
||||
{
|
||||
base.KeyUp (theEvent);
|
||||
HandleSelectionChanged ();
|
||||
}
|
||||
|
||||
|
||||
NSTrackingArea trackingArea;
|
||||
public override void UpdateTrackingAreas ()
|
||||
{
|
||||
if (trackingArea != null) {
|
||||
RemoveTrackingArea (trackingArea);
|
||||
trackingArea.Dispose ();
|
||||
}
|
||||
System.Drawing.RectangleF viewBounds = this.Bounds;
|
||||
var options = NSTrackingAreaOptions.MouseMoved | NSTrackingAreaOptions.ActiveInKeyWindow | NSTrackingAreaOptions.MouseEnteredAndExited;
|
||||
trackingArea = new NSTrackingArea (viewBounds, options, this, null);
|
||||
AddTrackingArea (trackingArea);
|
||||
}
|
||||
|
||||
public override void RightMouseDown (NSEvent theEvent)
|
||||
{
|
||||
base.RightMouseDown (theEvent);
|
||||
var p = ConvertPointFromView (theEvent.LocationInWindow, null);
|
||||
ButtonEventArgs args = new ButtonEventArgs ();
|
||||
args.X = p.X;
|
||||
args.Y = p.Y;
|
||||
args.Button = PointerButton.Right;
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnButtonPressed (args);
|
||||
});
|
||||
}
|
||||
|
||||
public override void RightMouseUp (NSEvent theEvent)
|
||||
{
|
||||
base.RightMouseUp (theEvent);
|
||||
var p = ConvertPointFromView (theEvent.LocationInWindow, null);
|
||||
ButtonEventArgs args = new ButtonEventArgs ();
|
||||
args.X = p.X;
|
||||
args.Y = p.Y;
|
||||
args.Button = PointerButton.Right;
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnButtonReleased (args);
|
||||
});
|
||||
}
|
||||
|
||||
public override void MouseDown (NSEvent theEvent)
|
||||
{
|
||||
base.MouseDown (theEvent);
|
||||
var p = ConvertPointFromView (theEvent.LocationInWindow, null);
|
||||
ButtonEventArgs args = new ButtonEventArgs ();
|
||||
args.X = p.X;
|
||||
args.Y = p.Y;
|
||||
args.Button = PointerButton.Left;
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnButtonPressed (args);
|
||||
});
|
||||
}
|
||||
|
||||
public override void MouseUp (NSEvent theEvent)
|
||||
{
|
||||
base.MouseUp (theEvent);
|
||||
var p = ConvertPointFromView (theEvent.LocationInWindow, null);
|
||||
ButtonEventArgs args = new ButtonEventArgs ();
|
||||
args.X = p.X;
|
||||
args.Y = p.Y;
|
||||
args.Button = (PointerButton) theEvent.ButtonNumber + 1;
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnButtonReleased (args);
|
||||
});
|
||||
}
|
||||
|
||||
public override void MouseEntered (NSEvent theEvent)
|
||||
{
|
||||
base.MouseEntered (theEvent);
|
||||
checkMouseMovement = true;
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnMouseEntered ();
|
||||
});
|
||||
}
|
||||
|
||||
public override void MouseExited (NSEvent theEvent)
|
||||
{
|
||||
base.MouseExited (theEvent);
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnMouseExited ();
|
||||
});
|
||||
checkMouseMovement = false;
|
||||
HandleSelectionChanged ();
|
||||
}
|
||||
|
||||
public override void MouseMoved (NSEvent theEvent)
|
||||
{
|
||||
base.MouseMoved (theEvent);
|
||||
if (!checkMouseMovement)
|
||||
return;
|
||||
var p = ConvertPointFromView (theEvent.LocationInWindow, null);
|
||||
MouseMovedEventArgs args = new MouseMovedEventArgs ((long) TimeSpan.FromSeconds (theEvent.Timestamp).TotalMilliseconds, p.X, p.Y);
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnMouseMoved (args);
|
||||
});
|
||||
if (checkMouseMovement)
|
||||
HandleSelectionChanged ();
|
||||
}
|
||||
|
||||
void HandleSelectionChanged ()
|
||||
{
|
||||
if (entryEventSink == null || CurrentEditor == null)
|
||||
return;
|
||||
if (cacheSelectionStart != CurrentEditor.SelectedRange.Location ||
|
||||
cacheSelectionLength != CurrentEditor.SelectedRange.Length) {
|
||||
cacheSelectionStart = CurrentEditor.SelectedRange.Location;
|
||||
cacheSelectionLength = CurrentEditor.SelectedRange.Length;
|
||||
context.InvokeUserCode (delegate {
|
||||
entryEventSink.OnSelectionChanged ();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ namespace Xwt.Mac
|
|||
{
|
||||
public class TextEntryBackend: ViewBackend<NSView,ITextEntryEventSink>, ITextEntryBackend
|
||||
{
|
||||
int cacheSelectionStart, cacheSelectionLength;
|
||||
bool checkMouseSelection;
|
||||
|
||||
public TextEntryBackend ()
|
||||
{
|
||||
}
|
||||
|
@ -51,6 +54,18 @@ namespace Xwt.Mac
|
|||
ViewObject = new CustomAlignedContainer (EventSink, ApplicationContext, (NSView)view);
|
||||
MultiLine = false;
|
||||
}
|
||||
|
||||
Frontend.MouseEntered += delegate {
|
||||
checkMouseSelection = true;
|
||||
};
|
||||
Frontend.MouseExited += delegate {
|
||||
checkMouseSelection = false;
|
||||
HandleSelectionChanged ();
|
||||
};
|
||||
Frontend.MouseMoved += delegate {
|
||||
if (checkMouseSelection)
|
||||
HandleSelectionChanged ();
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnSizeToFit ()
|
||||
|
@ -140,13 +155,78 @@ namespace Xwt.Mac
|
|||
}
|
||||
}
|
||||
|
||||
public int CursorPosition { get; set; }
|
||||
public int CursorPosition {
|
||||
get {
|
||||
if (Widget.CurrentEditor == null)
|
||||
return 0;
|
||||
return Widget.CurrentEditor.SelectedRange.Location;
|
||||
}
|
||||
set {
|
||||
Widget.CurrentEditor.SelectedRange = new MonoMac.Foundation.NSRange (value, SelectionLength);
|
||||
HandleSelectionChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectionStart { get; set; }
|
||||
public int SelectionStart {
|
||||
get {
|
||||
if (Widget.CurrentEditor == null)
|
||||
return 0;
|
||||
return Widget.CurrentEditor.SelectedRange.Location;
|
||||
}
|
||||
set {
|
||||
Widget.CurrentEditor.SelectedRange = new MonoMac.Foundation.NSRange (value, SelectionLength);
|
||||
HandleSelectionChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectionLength { get; set; }
|
||||
public int SelectionLength {
|
||||
get {
|
||||
if (Widget.CurrentEditor == null)
|
||||
return 0;
|
||||
return Widget.CurrentEditor.SelectedRange.Length;
|
||||
}
|
||||
set {
|
||||
Widget.CurrentEditor.SelectedRange = new MonoMac.Foundation.NSRange (SelectionStart, value);
|
||||
HandleSelectionChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedText { get; set; }
|
||||
public string SelectedText {
|
||||
get {
|
||||
if (Widget.CurrentEditor == null)
|
||||
return String.Empty;
|
||||
int start = SelectionStart;
|
||||
int end = start + SelectionLength;
|
||||
if (start == end) return String.Empty;
|
||||
try {
|
||||
return Text.Substring (start, end - start);
|
||||
} catch {
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
set {
|
||||
int cacheSelStart = SelectionStart;
|
||||
int pos = cacheSelStart;
|
||||
if (SelectionLength > 0) {
|
||||
Text = Text.Remove (pos, SelectionLength).Insert (pos, value);
|
||||
}
|
||||
SelectionStart = pos;
|
||||
SelectionLength = value.Length;
|
||||
HandleSelectionChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSelectionChanged ()
|
||||
{
|
||||
if (cacheSelectionStart != SelectionStart ||
|
||||
cacheSelectionLength != SelectionLength) {
|
||||
cacheSelectionStart = SelectionStart;
|
||||
cacheSelectionLength = SelectionLength;
|
||||
ApplicationContext.InvokeUserCode (delegate {
|
||||
EventSink.OnSelectionChanged ();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetFocus ()
|
||||
{
|
||||
|
@ -179,8 +259,20 @@ namespace Xwt.Mac
|
|||
base.DidChange (notification);
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnChanged ();
|
||||
eventSink.OnSelectionChanged ();
|
||||
});
|
||||
}
|
||||
|
||||
int cachedCursorPosition;
|
||||
public override void KeyUp (NSEvent theEvent)
|
||||
{
|
||||
base.KeyUp (theEvent);
|
||||
if (cachedCursorPosition != CurrentEditor.SelectedRange.Location)
|
||||
context.InvokeUserCode (delegate {
|
||||
eventSink.OnSelectionChanged ();
|
||||
});
|
||||
cachedCursorPosition = CurrentEditor.SelectedRange.Location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче