Skip to content

Commit

Permalink
Merge branch 'develop' into feature/themed-document-handler
Browse files Browse the repository at this point in the history
# Conflicts:
#	Source/Eto.Test/Eto.Test/Eto.Test - pcl.csproj
  • Loading branch information
cwensley committed Sep 24, 2017
2 parents dc64213 + d32a115 commit 90df42c
Show file tree
Hide file tree
Showing 16 changed files with 424 additions and 55 deletions.
29 changes: 20 additions & 9 deletions Source/Eto.Gtk/Forms/Controls/TextAreaHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class TextAreaHandler<TControl, TWidget, TCallback> : GtkControl<TControl
where TWidget: TextArea
where TCallback: TextArea.ICallback
{
bool sendSelectionChanged = true;
int suppressSelectionAndTextChanged;
readonly Gtk.ScrolledWindow scroll;
Gtk.TextTag tag;

Expand Down Expand Up @@ -70,14 +70,16 @@ protected class TextAreaConnector : GtkControlConnector

public void HandleBufferChanged(object sender, EventArgs e)
{
Handler.Callback.OnTextChanged(Handler.Widget, EventArgs.Empty);
var handler = Handler;
if (handler.suppressSelectionAndTextChanged == 0)
handler.Callback.OnTextChanged(Handler.Widget, EventArgs.Empty);
}

public void HandleSelectionChanged(object o, Gtk.MarkSetArgs args)
{
var handler = Handler;
var selection = handler.Selection;
if (handler.sendSelectionChanged && selection != lastSelection)
if (handler.suppressSelectionAndTextChanged == 0 && selection != lastSelection)
{
handler.Callback.OnSelectionChanged(handler.Widget, EventArgs.Empty);
lastSelection = selection;
Expand All @@ -88,7 +90,7 @@ public void HandleCaretIndexChanged(object o, Gtk.MarkSetArgs args)
{
var handler = Handler;
var caretIndex = handler.CaretIndex;
if (handler.sendSelectionChanged && caretIndex != lastCaretIndex)
if (handler.suppressSelectionAndTextChanged == 0 && caretIndex != lastCaretIndex)
{
handler.Callback.OnCaretIndexChanged(handler.Widget, EventArgs.Empty);
lastCaretIndex = caretIndex;
Expand All @@ -108,9 +110,15 @@ public override string Text
get { return Control.Buffer.Text; }
set
{
var sel = Selection;
suppressSelectionAndTextChanged++;
Control.Buffer.Text = value;
if (tag != null)
Control.Buffer.ApplyTag(tag, Control.Buffer.StartIter, Control.Buffer.EndIter);
Callback.OnTextChanged(Widget, EventArgs.Empty);
suppressSelectionAndTextChanged--;
if (sel != Selection)
Callback.OnSelectionChanged(Widget, EventArgs.Empty);
}
}

Expand Down Expand Up @@ -173,7 +181,7 @@ public string SelectedText
}
set
{
sendSelectionChanged = false;
suppressSelectionAndTextChanged++;
Gtk.TextIter start, end;
if (Control.Buffer.GetSelectionBounds(out start, out end))
{
Expand All @@ -191,8 +199,9 @@ public string SelectedText
Control.Buffer.InsertAtCursor(value);
if (tag != null)
Control.Buffer.ApplyTag(tag, Control.Buffer.StartIter, Control.Buffer.EndIter);
Callback.OnTextChanged(Widget, EventArgs.Empty);
Callback.OnSelectionChanged(Widget, EventArgs.Empty);
sendSelectionChanged = true;
suppressSelectionAndTextChanged--;
}
}

Expand All @@ -202,17 +211,19 @@ public Range<int> Selection
{
Gtk.TextIter start, end;
if (Control.Buffer.GetSelectionBounds(out start, out end))
{
return new Range<int>(start.Offset, end.Offset - 1);
return new Range<int>(Control.Buffer.CursorPosition, 0);
}
return Range.FromLength(Control.Buffer.CursorPosition, 0);
}
set
{
sendSelectionChanged = false;
suppressSelectionAndTextChanged++;
var start = Control.Buffer.GetIterAtOffset(value.Start);
var end = Control.Buffer.GetIterAtOffset(value.End + 1);
Control.Buffer.SelectRange(start, end);
Callback.OnSelectionChanged(Widget, EventArgs.Empty);
sendSelectionChanged = true;
suppressSelectionAndTextChanged--;
}
}

Expand Down
1 change: 1 addition & 0 deletions Source/Eto.Mac/Forms/Controls/RichTextAreaHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ public void Load(Stream stream, RichTextAreaFormat format)
default:
throw new NotSupportedException();
}
Callback.OnTextChanged(Widget, EventArgs.Empty);
}

public void Save(Stream stream, RichTextAreaFormat format)
Expand Down
37 changes: 22 additions & 15 deletions Source/Eto.Mac/Forms/Controls/TextAreaHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public class TextAreaHandler : TextAreaHandler<TextArea, TextArea.ICallback>, Te

public interface ITextAreaHandler
{
int SuppressSelectionChanged { get; }

TextArea.ICallback Callback { get; }

TextArea Widget { get; }
Expand All @@ -72,17 +74,18 @@ public override void TextDidChange(NSNotification notification)

public override void DidChangeSelection(NSNotification notification)
{
var selection = Handler.Selection;
if (selection != Handler.lastSelection)
var handler = Handler;
var selection = handler.Selection;
if (handler.SuppressSelectionChanged == 0 && selection != Handler.lastSelection)
{
Handler.Callback.OnSelectionChanged(Handler.Widget, EventArgs.Empty);
Handler.lastSelection = selection;
handler.Callback.OnSelectionChanged(Handler.Widget, EventArgs.Empty);
handler.lastSelection = selection;
}
var caretIndex = Handler.CaretIndex;
if (caretIndex != Handler.lastCaretIndex)
var caretIndex = handler.CaretIndex;
if (caretIndex != handler.lastCaretIndex)
{
Handler.Callback.OnCaretIndexChanged(Handler.Widget, EventArgs.Empty);
Handler.lastCaretIndex = caretIndex;
handler.Callback.OnCaretIndexChanged(Handler.Widget, EventArgs.Empty);
handler.lastCaretIndex = caretIndex;
}
}
}
Expand Down Expand Up @@ -123,8 +126,10 @@ public class TextAreaHandler<TControl, TCallback> : MacView<NSTextView, TControl
where TControl: TextArea
where TCallback: TextArea.ICallback
{
int suppressSelectionChanged;
int? ITextAreaHandler.lastCaretIndex { get; set; }
Range<int> ITextAreaHandler.lastSelection { get; set; }
int ITextAreaHandler.SuppressSelectionChanged => suppressSelectionChanged;

public override void OnKeyDown(KeyEventArgs e)
{
Expand Down Expand Up @@ -254,6 +259,7 @@ public virtual string Text
{
Control.Value = value ?? string.Empty;
Control.NeedsDisplay = true;
Callback.OnTextChanged(Widget, EventArgs.Empty);
}
}

Expand Down Expand Up @@ -332,13 +338,14 @@ public string SelectedText
}
set
{
if (value != null)
{
var range = Control.SelectedRange;
Control.Replace(range, value);
range.Length = (nnint)value.Length;
Control.SetSelectedRange(range);
}
suppressSelectionChanged++;
var newText = value ?? string.Empty;
var range = Control.SelectedRange;
Control.Replace(range, newText);
range.Length = (nnint)newText.Length;
suppressSelectionChanged--;
Control.SetSelectedRange(range);
Callback.OnTextChanged(Widget, EventArgs.Empty);
}
}

Expand Down
2 changes: 2 additions & 0 deletions Source/Eto.Test/Eto.Test/Eto.Test - pcl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
<Compile Include="UnitTests\Drawing\GraphicsTests.cs" />
<Compile Include="UnitTests\Drawing\MatrixTests.cs" />
<Compile Include="UnitTests\Forms\Controls\ComboBoxTests.cs" />
<Compile Include="UnitTests\Forms\Controls\CustomCellTests.cs" />
<Compile Include="UnitTests\Forms\Controls\NumericStepperTests.cs" />
<Compile Include="UnitTests\Forms\Controls\PanelTests.cs" />
<Compile Include="UnitTests\Forms\Controls\SplitterTests.cs" />
Expand Down Expand Up @@ -219,6 +220,7 @@
<Compile Include="UnitTests\Forms\Controls\GridViewTests.cs" />
<Compile Include="UnitTests\Forms\Controls\TreeGridViewTests.cs" />
<Compile Include="UnitTests\Forms\Controls\DocumentControlTests.cs" />
<Compile Include="UnitTests\Forms\Controls\TextAreaTests.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Sections\Serialization\Json\Test.json">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Eto.Forms;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Eto.Test.UnitTests.Forms.Controls
{
[TestFixture]
public class CustomCellTests : TestBase
{
class MyModel
{
public string Text { get; set; }
}

class MyCustomCell : StackLayout
{
public MyCustomCell()
{
Orientation = Orientation.Horizontal;
Items.Add(new Label { Text = "Hello!" });
var tb = new TextBox();
tb.TextBinding.BindDataContext((MyModel m) => m.Text);
Items.Add(new StackLayoutItem(tb, true));
}
}

/// <summary>
/// Test for WPF crash when a grid view and custom cell is on a separate tab and you switch to it.
/// </summary>
[Test]
public void CustomCellOnSeparateTabLoadIssue()
{
TabControl tabs = null;
Shown(form =>
{
var grid1 = new GridView { ShowHeader = false };
grid1.Columns.Add(new GridColumn { DataCell = CustomCell.Create<MyCustomCell>() });
grid1.DataStore = new List<MyModel>
{
new MyModel { Text = "Item 1"},
new MyModel { Text = "Item 2"},
new MyModel { Text = "Item 3"},
};

var grid2 = new GridView { ShowHeader = false };
grid2.Columns.Add(new GridColumn { DataCell = CustomCell.Create<MyCustomCell>() });
grid2.DataStore = new List<MyModel>
{
new MyModel { Text = "Item 1"},
new MyModel { Text = "Item 2"},
new MyModel { Text = "Item 3"},
};

tabs = new TabControl();
tabs.Pages.Add(new TabPage(grid1) { Text = "Tab 1" });
tabs.Pages.Add(new TabPage(grid2) { Text = "Tab 2" });
form.Content = tabs;
}, () =>
{
tabs.SelectedIndex = 1;
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,52 @@
namespace Eto.Test.UnitTests.Forms.Controls
{
[TestFixture]
public class RichTextAreaTests : TestBase
public class RichTextAreaTests : TextAreaTests<RichTextArea>
{

[Test]
public void CheckSelectionTextCaretAfterSettingRtf()
{
Invoke(() =>
{
// not supported in GTK yet
if (Platform.Instance.IsGtk)
Assert.Inconclusive("Gtk does not support RTF format");
int selectionChanged = 0;
int textChanged = 0;
int caretChanged = 0;
string val;
var textArea = new RichTextArea();
textArea.TextChanged += (sender, e) => textChanged++;
textArea.SelectionChanged += (sender, e) => selectionChanged++;
textArea.CaretIndexChanged += (sender, e) => caretChanged++;
Assert.AreEqual(Range.FromLength(0, 0), textArea.Selection, "#1");

textArea.Rtf = @"{\rtf1\ansi {Hello \ul Underline \i Italic \b Bold \strike Strike}}";
Assert.AreEqual(val = "Hello Underline Italic Bold Strike", textArea.Text.TrimEnd(), "#2-1");
Assert.AreEqual(Range.FromLength(val.Length, 0), textArea.Selection, "#2-2");
Assert.AreEqual(val.Length, textArea.CaretIndex, "#2-3");
Assert.AreEqual(1, textChanged, "#2-4");
Assert.AreEqual(1, selectionChanged, "#2-5");
Assert.AreEqual(1, caretChanged, "#2-6");

textArea.Selection = Range.FromLength(6, 5);
Assert.AreEqual(Range.FromLength(6, 5), textArea.Selection, "#3-1");
Assert.AreEqual(6, textArea.CaretIndex, "#3-2");
Assert.AreEqual(1, textChanged, "#3-3");
Assert.AreEqual(2, selectionChanged, "#3-4");
Assert.AreEqual(2, caretChanged, "#3-5");

textArea.Rtf = @"{\rtf1\ansi {Some \b other \i text}}";
Assert.AreEqual(val = "Some other text", textArea.Text.TrimEnd(), "#4-1");
Assert.AreEqual(Range.FromLength(val.Length, 0), textArea.Selection, "#4-2");
Assert.AreEqual(val.Length, textArea.CaretIndex, "#4-3");
Assert.AreEqual(2, textChanged, "#4-4");
Assert.AreEqual(3, selectionChanged, "#4-5");
Assert.AreEqual(3, caretChanged, "#4-6");
});
}

public static void TestSelectionAttributes(RichTextArea richText, string tag, bool italic = false, bool underline = false, bool bold = false, bool strikethrough = false)
{
Assert.AreEqual(italic, richText.SelectionItalic, tag + "-1");
Expand Down Expand Up @@ -42,19 +85,24 @@ public void SelectionAttributesShouldBeCorrectWithLoadedRtf()
}

[Test]
public void EnabledShouldNotAffectReadOnly()
public void NewLineAtEndShouldNotBeRemoved()
{
Invoke(() =>
{
string val;
var richText = new RichTextArea();
Assert.IsTrue(richText.Enabled, "#1");
Assert.IsFalse(richText.ReadOnly, "#2");
richText.Enabled = false;
Assert.IsFalse(richText.Enabled, "#3");
Assert.IsFalse(richText.ReadOnly, "#4");
richText.Enabled = true;
Assert.IsTrue(richText.Enabled, "#5");
Assert.IsFalse(richText.ReadOnly, "#6");
// winforms always returns \n instead of \r\n.. why??
var nl = Platform.Instance.IsWinForms ? "\n" : Environment.NewLine;

if (!Platform.Instance.IsWpf)
{
// why does WPF always add a newline even when the content doesn't have a newline?
richText.Text = val = $"This is{nl}some text";
Assert.AreEqual(val, richText.Text, "#1");
}

richText.Text = val = $"This is{nl}some text{nl}";
Assert.AreEqual(val, richText.Text, "#2");
});
}
}
Expand Down
Loading

0 comments on commit 90df42c

Please sign in to comment.