Browse Source

Merge branch 'master' into window-topmost

pull/1647/head
Jumar Macato 8 years ago
committed by GitHub
parent
commit
fa9f4d1815
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      src/Avalonia.Controls/Primitives/ScrollBar.cs
  2. 53
      src/Avalonia.Controls/Primitives/ScrollEventType.cs
  3. 3
      src/Avalonia.Controls/ToolTip.cs
  4. 31
      src/Skia/Avalonia.Skia/FormattedTextImpl.cs
  5. 59
      tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs

37
src/Avalonia.Controls/Primitives/ScrollBar.cs

@ -6,9 +6,21 @@ using System.Reactive;
using System.Reactive.Linq;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.Input;
namespace Avalonia.Controls.Primitives
{
public class ScrollEventArgs : EventArgs
{
public ScrollEventArgs(ScrollEventType eventType, double newValue)
{
ScrollEventType = eventType;
NewValue = newValue;
}
public double NewValue { get; private set; }
public ScrollEventType ScrollEventType { get; private set; }
}
/// <summary>
/// A scrollbar control.
/// </summary>
@ -44,6 +56,9 @@ namespace Avalonia.Controls.Primitives
{
PseudoClass(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragComplete, RoutingStrategies.Bubble);
}
/// <summary>
@ -88,6 +103,8 @@ namespace Avalonia.Controls.Primitives
set { SetValue(OrientationProperty, value); }
}
public event EventHandler<ScrollEventArgs> Scroll;
/// <summary>
/// Calculates whether the scrollbar should be visible.
/// </summary>
@ -140,6 +157,8 @@ namespace Avalonia.Controls.Primitives
_pageUpButton = e.NameScope.Find<Button>("PART_PageUpButton");
_pageDownButton = e.NameScope.Find<Button>("PART_PageDownButton");
if (_lineUpButton != null)
{
_lineUpButton.Click += LineUpClick;
@ -184,21 +203,39 @@ namespace Avalonia.Controls.Primitives
private void SmallDecrement()
{
Value = Math.Max(Value - SmallChange * ViewportSize, Minimum);
OnScroll(ScrollEventType.SmallDecrement);
}
private void SmallIncrement()
{
Value = Math.Min(Value + SmallChange * ViewportSize, Maximum);
OnScroll(ScrollEventType.SmallIncrement);
}
private void LargeDecrement()
{
Value = Math.Max(Value - LargeChange * ViewportSize, Minimum);
OnScroll(ScrollEventType.LargeDecrement);
}
private void LargeIncrement()
{
Value = Math.Min(Value + LargeChange * ViewportSize, Maximum);
OnScroll(ScrollEventType.LargeIncrement);
}
private void OnThumbDragDelta(VectorEventArgs e)
{
OnScroll(ScrollEventType.ThumbTrack);
}
private void OnThumbDragComplete(VectorEventArgs e)
{
OnScroll(ScrollEventType.EndScroll);
}
protected void OnScroll(ScrollEventType scrollEventType)
{
Scroll?.Invoke(this, new ScrollEventArgs(scrollEventType, Value));
}
}
}

53
src/Avalonia.Controls/Primitives/ScrollEventType.cs

@ -0,0 +1,53 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
namespace Avalonia.Controls.Primitives
{
/// <summary>
/// Specifies the type of Avalonia.Controls.Primitives.ScrollBar.Scroll event
/// that occurred.
/// </summary>
public enum ScrollEventType
{
/// <summary>
/// Specifies that the Avalonia.Controls.Primitives.Thumb moved a specified
/// distance, as determined by the value of Avalonia.Controls.Primitives.RangeBase.SmallChange.
/// The Avalonia.Controls.Primitives.Thumb moved to the left for a horizontal
/// Avalonia.Controls.Primitives.ScrollBar or upward for a vertical Avalonia.Controls.Primitives.ScrollBar.
/// </summary>
SmallDecrement = 0,
/// <summary>
/// Specifies that the Avalonia.Controls.Primitives.Thumb moved a specified
/// distance, as determined by the value of Avalonia.Controls.Primitives.RangeBase.SmallChange.
/// The Avalonia.Controls.Primitives.Thumb moved to the right for a horizontal
/// Avalonia.Controls.Primitives.ScrollBar or downward for a vertical Avalonia.Controls.Primitives.ScrollBar.
/// </summary>
SmallIncrement = 1,
/// <summary>
/// Specifies that the Avalonia.Controls.Primitives.Thumb moved a specified
/// distance, as determined by the value of Avalonia.Controls.Primitives.RangeBase.LargeChange.
/// The Avalonia.Controls.Primitives.Thumb moved to the left for a horizontal
/// Avalonia.Controls.Primitives.ScrollBar or upward for a vertical Avalonia.Controls.Primitives.ScrollBar.
/// </summary>
LargeDecrement = 2,
/// <summary>
/// Specifies that the Avalonia.Controls.Primitives.Thumb moved a specified
/// distance, as determined by the value of Avalonia.Controls.Primitives.RangeBase.LargeChange.
/// The Avalonia.Controls.Primitives.Thumb moved to the right for a horizontal
/// Avalonia.Controls.Primitives.ScrollBar or downward for a vertical Avalonia.Controls.Primitives.ScrollBar.
/// </summary>
LargeIncrement = 3,
/// <summary>
/// The Avalonia.Controls.Primitives.Thumb was dragged and caused a Avalonia.UIElement.MouseMove
/// event. A Avalonia.Controls.Primitives.ScrollBar.Scroll event of this Avalonia.Controls.Primitives.ScrollEventType
/// may occur more than one time when the Avalonia.Controls.Primitives.Thumb
/// is dragged in the Avalonia.Controls.Primitives.ScrollBar.
/// </summary>
ThumbTrack = 4,
/// <summary>
/// Specifies that the Avalonia.Controls.Primitives.Thumb was dragged to a
/// new position and is now no longer being dragged by the user.
/// </summary>
EndScroll = 5
}
}

3
src/Avalonia.Controls/ToolTip.cs

@ -234,11 +234,12 @@ namespace Avalonia.Controls
{
Close();
_popup = new PopupRoot { Content = this };
_popup = new PopupRoot { Content = this, };
((ISetLogicalParent)_popup).SetParent(control);
_popup.Position = Popup.GetPosition(control, GetPlacement(control), _popup,
GetHorizontalOffset(control), GetVerticalOffset(control));
_popup.Show();
_popup.SnapInsideScreenEdges();
}
private void Close()

31
src/Skia/Avalonia.Skia/FormattedTextImpl.cs

@ -560,13 +560,11 @@ namespace Avalonia.Skia
}
measured = LineBreak(Text, curOff, length, _paint, constraint, out trailingnumber);
AvaloniaFormattedTextLine line = new AvaloniaFormattedTextLine();
line.TextLength = measured;
line.Start = curOff;
subString = Text.Substring(line.Start, line.TextLength);
lineWidth = _paint.MeasureText(subString);
line.Start = curOff;
line.Length = measured - trailingnumber;
line.Width = lineWidth;
line.Height = _lineHeight;
@ -575,10 +573,33 @@ namespace Avalonia.Skia
_skiaLines.Add(line);
curY += _lineHeight;
curY += mLeading;
curOff += measured;
//if this is the last line and there are trailing newline characters then
//insert a additional line
if (curOff >= length)
{
var subStringMinusNewlines = subString.TrimEnd('\n', '\r');
var lengthDiff = subString.Length - subStringMinusNewlines.Length;
if (lengthDiff > 0)
{
AvaloniaFormattedTextLine lastLine = new AvaloniaFormattedTextLine();
lastLine.TextLength = lengthDiff;
lastLine.Start = curOff - lengthDiff;
var lastLineSubString = Text.Substring(line.Start, line.TextLength);
var lastLineWidth = _paint.MeasureText(lastLineSubString);
lastLine.Length = 0;
lastLine.Width = lastLineWidth;
lastLine.Height = _lineHeight;
lastLine.Top = curY;
_skiaLines.Add(lastLine);
curY += _lineHeight;
curY += mLeading;
}
}
}
// Now convert to Avalonia data formats

59
tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs

@ -5,6 +5,7 @@ using System;
using System.Linq;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Media;
using Xunit;
@ -59,6 +60,64 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Equal(50, target.Value);
}
[Fact]
public void Thumb_DragDelta_Event_Should_Raise_Scroll_Event()
{
var target = new ScrollBar
{
Template = new FuncControlTemplate<ScrollBar>(Template),
};
target.ApplyTemplate();
var track = (Track)target.GetTemplateChildren().First(x => x.Name == "track");
var raisedEvent = Assert.Raises<ScrollEventArgs>(
handler => target.Scroll += handler,
handler => target.Scroll -= handler,
() =>
{
var ev = new VectorEventArgs
{
RoutedEvent = Thumb.DragDeltaEvent,
Vector = new Vector(0, 0)
};
track.Thumb.RaiseEvent(ev);
});
Assert.Equal(ScrollEventType.ThumbTrack, raisedEvent.Arguments.ScrollEventType);
}
[Fact]
public void Thumb_DragComplete_Event_Should_Raise_Scroll_Event()
{
var target = new ScrollBar
{
Template = new FuncControlTemplate<ScrollBar>(Template),
};
target.ApplyTemplate();
var track = (Track)target.GetTemplateChildren().First(x => x.Name == "track");
var raisedEvent = Assert.Raises<ScrollEventArgs>(
handler => target.Scroll += handler,
handler => target.Scroll -= handler,
() =>
{
var ev = new VectorEventArgs
{
RoutedEvent = Thumb.DragCompletedEvent,
Vector = new Vector(0, 0)
};
track.Thumb.RaiseEvent(ev);
});
Assert.Equal(ScrollEventType.EndScroll, raisedEvent.Arguments.ScrollEventType);
}
[Fact]
public void ScrollBar_Can_AutoHide()
{

Loading…
Cancel
Save