[MAC] add missing cursor position and selection support to TextEntryBackend

This commit is contained in:
Vsevolod Kukol 2014-06-16 13:57:36 +02:00
Родитель 2e518d38ca
Коммит 897af2eb79
2 изменённых файлов: 219 добавлений и 5 удалений

Просмотреть файл

@ -101,7 +101,10 @@ namespace Xwt.Mac
IComboBoxEventSink eventSink;
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;
}
}
}