Browse Source

continue working

pull/7810/head
daniel mayost 4 years ago
parent
commit
d5fd84ebc0
  1. 2
      samples/ControlCatalog/Pages/ScreenPage.cs
  2. 170
      src/Avalonia.Controls/Control.cs
  3. 2
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  4. 2
      src/Avalonia.Controls/TextBlock.cs
  5. 2
      src/Avalonia.Controls/TextBox.cs
  6. 2
      src/Avalonia.Controls/TopLevel.cs
  7. 1
      src/Avalonia.Themes.Fluent/Controls/CheckBox.xaml
  8. 2
      src/Avalonia.Visuals/Visual.cs

2
samples/ControlCatalog/Pages/ScreenPage.cs

@ -79,6 +79,6 @@ namespace ControlCatalog.Pages
Typeface.Default, 12, Brushes.Green);
}
protected override bool ShouldBeMirroredIfRightToLeft() => false;
protected override bool ShouldGetMirrored() => false;
}
}

170
src/Avalonia.Controls/Control.cs

@ -67,10 +67,17 @@ namespace Avalonia.Controls
/// </summary>
public static readonly AttachedProperty<FlowDirection> FlowDirectionProperty =
AvaloniaProperty.RegisterAttached<Control, Control, FlowDirection>(nameof(FlowDirection), inherits: true);
/// <summary>
/// Defines the <see cref="RenderTransform"/> property.
/// </summary>
public static new readonly StyledProperty<ITransform?> RenderTransformProperty =
Visual.RenderTransformProperty.AddOwner<Control>();
private DataTemplates? _dataTemplates;
private IControl? _focusAdorner;
private AutomationPeer? _automationPeer;
private bool _hasMirrorTransform;
/// <summary>
/// Gets or sets the control's focus adorner.
@ -126,6 +133,21 @@ namespace Avalonia.Controls
set => SetValue(FlowDirectionProperty, value);
}
/// <inheritdoc/>
public override ITransform? RenderTransform
{
get => base.RenderTransform;
set
{
if (_hasMirrorTransform)
{
value = MargeTransforms(MirrorTrasform(), value);
}
base.RenderTransform = value;
}
}
/// <summary>
/// Occurs when the user has completed a context input gesture, such as a right-click.
/// </summary>
@ -312,76 +334,152 @@ namespace Avalonia.Controls
static Control()
{
AffectsArrange<Control>(FlowDirectionProperty);
//var m = new StyledPropertyMetadata<ITransform?>(coerce: (s, e) => null);
//RenderTransformProperty.OverrideMetadata<Control>(m);
//AffectsRender<Control>(FlowDirectionProperty);
//FlowDirectionProperty.Changed.AddClassHandler<Control>((s, e) =>
//{
// s.InvalidateFlowDirection();
// foreach (var logical in LogicalTree.LogicalExtensions.GetLogicalDescendants(s))
// {
// if (logical is Control control)
// {
// //if (control)
// //control.InvalidateFlowDirection();
// }
// }
//});
}
private bool _mirrorApplied;
protected virtual bool ShouldBeMirroredIfRightToLeft()
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
{
if (Parent is Control parent)
{
return parent.ShouldBeMirroredIfRightToLeft();
}
else
base.OnPropertyChanged(change);
if (change.Property == FlowDirectionProperty)
{
return true;
// Avoid inherit value change to invoke this method
if (!GetBaseValue(FlowDirectionProperty, change.Priority).HasValue)
{
return;
}
InvalidateFlowDirection();
}
}
protected override void ArrangeCore(Rect finalRect)
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.ArrangeCore(finalRect);
base.OnAttachedToVisualTree(e);
InvalidateFlowDirection();
}
protected override void OnAttachedToLogicalTree(LogicalTree.LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
//InvalidateFlowDirection();
}
protected virtual bool ShouldGetMirrored() => true;
private void InvalidateFlowDirection()
{
FlowDirection parentFD = FlowDirection.LeftToRight;
FlowDirection thisFD = FlowDirection;
bool shouldBeMirroredIfRightToLeft = ShouldBeMirroredIfRightToLeft();
if (Parent is Control control)
bool parentShouldGetMirrored = true;
bool thisShouldGetMirrored = ShouldGetMirrored();
if (((Visual)this).GetVisualParent() is Control control)
{
parentFD = control.FlowDirection;
parentShouldGetMirrored = control.ShouldGetMirrored();
}
bool shouldMirror;
if (shouldBeMirroredIfRightToLeft)
else if (Parent is Control logicalControl)
{
shouldMirror = ShuoldApplyMirrorTransform(parentFD, thisFD);
if (Parent is Popup && thisFD == FlowDirection.RightToLeft)
{
shouldMirror = true;
}
parentFD = logicalControl.FlowDirection;
parentShouldGetMirrored = logicalControl.ShouldGetMirrored();
}
bool shouldBeMirrored = thisFD == FlowDirection.RightToLeft && thisShouldGetMirrored;
bool parentMirrored = parentFD == FlowDirection.RightToLeft && parentShouldGetMirrored;
bool shouldApplyMirrorTransform = shouldBeMirrored != parentMirrored;
if (shouldApplyMirrorTransform)
{
AddMirrorTransform();
}
else
{
shouldMirror = ShuoldApplyMirrorTransform(parentFD, FlowDirection.LeftToRight);
RemoveMirrorTransform();
}
if (shouldMirror)
foreach (var visual in VisualChildren)
{
ApplyMirrorTransform();
if (visual is Control child)
{
child.InvalidateFlowDirection();
}
}
else
}
private void AddMirrorTransform()
{
if (_hasMirrorTransform)
{
//RenderTransform = null;
return;
}
var mirrorTransform = MirrorTrasform();
ITransform? finalTransform = mirrorTransform;
if (RenderTransform != null)
{
finalTransform = MargeTransforms(RenderTransform, mirrorTransform);
}
RenderTransform = finalTransform;
_hasMirrorTransform = true;
}
private void ApplyMirrorTransform()
private void RemoveMirrorTransform()
{
if (_mirrorApplied)
if (!_hasMirrorTransform)
{
return;
}
var transform = new MatrixTransform(new Avalonia.Matrix(-1, 0, 0, 1, 0.0, 0.0));
RenderTransform = transform;
_mirrorApplied = true;
var mirrorTransform = MirrorTrasform();
ITransform? finalTransform = MargeTransforms(RenderTransform, mirrorTransform);
if (finalTransform!.Value == Matrix.Identity)
{
finalTransform = null;
}
_hasMirrorTransform = false;
RenderTransform = finalTransform;
}
internal static bool ShuoldApplyMirrorTransform(FlowDirection parentFD, FlowDirection thisFD)
static ITransform? MargeTransforms(ITransform? iTransform1, ITransform? iTransform2)
{
return ((parentFD == FlowDirection.LeftToRight && thisFD == FlowDirection.RightToLeft) ||
(parentFD == FlowDirection.RightToLeft && thisFD == FlowDirection.LeftToRight));
// don't know how to marge ITransform
if (iTransform1 is Transform transform1 && iTransform2 is Transform transform2)
{
TransformGroup groupTransform = new TransformGroup();
groupTransform.Children.Add(transform1);
groupTransform.Children.Add(transform2);
return groupTransform;
}
return iTransform1;
}
static ITransform MirrorTrasform() =>
new MatrixTransform(new Avalonia.Matrix(-1, 0, 0, 1, 0.0, 0.0));
}
}

2
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -798,5 +798,7 @@ namespace Avalonia.Controls.Presenters
}
}
}
protected override bool ShouldGetMirrored() => false;
}
}

2
src/Avalonia.Controls/TextBlock.cs

@ -613,6 +613,6 @@ namespace Avalonia.Controls
InvalidateTextLayout();
}
protected override bool ShouldBeMirroredIfRightToLeft() => false;
protected override bool ShouldGetMirrored() => false;
}
}

2
src/Avalonia.Controls/TextBox.cs

@ -1504,7 +1504,5 @@ namespace Avalonia.Controls
}
}
}
protected override bool ShouldBeMirroredIfRightToLeft() => false;
}
}

2
src/Avalonia.Controls/TopLevel.cs

@ -529,5 +529,7 @@ namespace Avalonia.Controls
ITextInputMethodImpl? ITextInputMethodRoot.InputMethod =>
(PlatformImpl as ITopLevelImplWithTextInputMethod)?.TextInputMethod;
protected override bool ShouldGetMirrored() => false;
}
}

1
src/Avalonia.Themes.Fluent/Controls/CheckBox.xaml

@ -152,6 +152,7 @@
<Setter Property="Data" Value="M1507 31L438 1101L-119 543L-29 453L438 919L1417 -59L1507 31Z" />
<Setter Property="Width" Value="9" />
<Setter Property="Opacity" Value="1" />
<Setter Property="FlowDirection" Value="LeftToRight" />
</Style>
<!-- Checked PointerOver State -->

2
src/Avalonia.Visuals/Visual.cs

@ -222,7 +222,7 @@ namespace Avalonia
/// <summary>
/// Gets or sets the render transform of the control.
/// </summary>
public ITransform? RenderTransform
public virtual ITransform? RenderTransform
{
get { return GetValue(RenderTransformProperty); }
set { SetValue(RenderTransformProperty, value); }

Loading…
Cancel
Save