/// <summary> /// Attaches the style to a control if the style's selector matches. /// </summary> /// <param name="control">The control to attach to.</param> /// <param name="container"> /// The control that contains this style. May be null. /// </param> public void Attach(IStyleable control, IStyleHost container) { if (Selector != null) { var match = Selector.Match(control); if (match.ImmediateResult != false) { var subs = GetSubscriptions(control); foreach (var setter in Setters) { var sub = setter.Apply(this, control, match.ObservableResult); subs.Add(sub); } } } else if (control == container) { var subs = GetSubscriptions(control); foreach (var setter in Setters) { var sub = setter.Apply(this, control, null); subs.Add(sub); } } }
/// <inheritdoc/> public void Attach(IStyleable control, IStyleHost container) { if (Source != null) { Loaded.Attach(control, container); } }
/// <summary> /// Attaches the style to a control if the style's selector matches. /// </summary> /// <param name="control">The control to attach to.</param> /// <param name="container"> /// The control that contains this style. May be null. /// </param> public void Attach(IStyleable control, IStyleHost container) { if (Selector != null) { var description = "Style " + Selector.ToString(); var match = Selector.Match(control); if (match.ImmediateResult != false) { var activator = (match.ObservableResult ?? True) .TakeUntil(control.StyleDetach); foreach (var setter in Setters) { setter.Apply(this, control, activator); } } } else if (control == container) { foreach (var setter in Setters) { setter.Apply(this, control, null); } } }
public SelectorMatch Match(IStyleable control) { List<IObservable<bool>> inputs = new List<IObservable<bool>>(); Selector selector = this; while (selector != null) { if (selector._inTemplate && control.TemplatedParent == null) { return SelectorMatch.False; } var match = selector._evaluate(control); if (match.ImmediateResult == false) { return match; } else if (match.ObservableResult != null) { inputs.Add(match.ObservableResult); } selector = selector.MovePrevious(); } if (inputs.Count > 0) { return new SelectorMatch(new StyleActivator(inputs)); } else { return SelectorMatch.True; } }
/// <inheritdoc/> public bool Attach(IStyleable control, IStyleHost container) { if (Source != null) { return(Loaded.Attach(control, container)); } return(false); }
public void ApplyStyles(IStyleable target) { target = target ?? throw new ArgumentNullException(nameof(target)); if (target is IStyleHost styleHost) { ApplyStyles(target, styleHost); } }
public void ApplyStyles(IStyleable control) { var styleHost = control as IStyleHost; if (styleHost != null) { ApplyStyles(control, styleHost); } }
public PropertySetterLazyInstance( IStyleable target, DirectPropertyBase <T> property, Func <T> valueFactory) { _target = target; _directProperty = property; _valueFactory = valueFactory; }
public PropertySetterInstance( IStyleable target, DirectPropertyBase <T> property, T value) { _target = target; _directProperty = property; _value = value; }
public PropertyEqualsActivator( IStyleable control, AvaloniaProperty property, object?value) { _control = control ?? throw new ArgumentNullException(nameof(control)); _property = property ?? throw new ArgumentNullException(nameof(property)); _value = value; }
protected override SelectorMatch Evaluate(IStyleable control, IStyle?parent, bool subscribe) { if (parent is Style s && s.Selector is Selector selector) { return(selector.Match(control, (parent as Style)?.Parent, subscribe)); } throw new InvalidOperationException( "Nesting selector was specified but cannot determine parent selector."); }
public PropertySetterBindingInstance( IStyleable target, DirectPropertyBase <T> property, IBinding binding) { _target = target; _directProperty = property; _binding = binding.Initiate(_target, property); _inner = new Inner(this); }
private static SelectorMatch MatchPropertyEquals(IStyleable x, PerspexProperty property, object value) { if (!PerspexPropertyRegistry.Instance.IsRegistered(x, property)) { return(SelectorMatch.False); } else { return(new SelectorMatch(x.GetObservable(property).Select(v => Equals(v, value)))); } }
protected override SelectorMatch Evaluate(IStyleable control, IStyle?parent, bool subscribe) { var templatedParent = control.TemplatedParent as IStyleable; if (templatedParent == null) { return(SelectorMatch.NeverThisInstance); } return(_parent.Match(templatedParent, parent, subscribe)); }
/// <inheritdoc/> protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { if (subscribe) { return(new SelectorMatch(control.GetObservable(_property).Select(v => Equals(v ?? string.Empty, _value)))); } else { return(new SelectorMatch((control.GetValue(_property) ?? string.Empty).Equals(_value))); } }
/// <summary> /// Called when a control's <see cref="IStyleable.StyleDetach"/> is signalled to remove /// all applied styles. /// </summary> /// <param name="control">The control.</param> private static void ControlDetach(IStyleable control) { var subscriptions = _applied[control]; foreach (var subscription in subscriptions) { subscription.Dispose(); } _applied.Remove(control); }
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { IStyleable templatedParent = control.TemplatedParent as IStyleable; if (templatedParent == null) { throw new InvalidOperationException( "Cannot call Template selector on control with null TemplatedParent."); } return(_parent.Match(templatedParent, subscribe) ?? SelectorMatch.True); }
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { if (subscribe) { return(new SelectorMatch(new PropertyEqualsActivator(control, _property, _value))); } else { var result = (control.GetValue(_property) ?? string.Empty).Equals(_value); return(result ? SelectorMatch.AlwaysThisInstance : SelectorMatch.NeverThisInstance); } }
private static SelectorMatch MatchTemplate(IStyleable control, Selector previous) { IStyleable templatedParent = control.TemplatedParent as IStyleable; if (templatedParent == null) { throw new InvalidOperationException( "Cannot call Template selector on control with null TemplatedParent."); } return(previous.Match(templatedParent)); }
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { IStyleable templatedParent = control.TemplatedParent as IStyleable; if (templatedParent == null) { throw new InvalidOperationException( "Cannot call Template selector on control with null TemplatedParent."); } return _parent.Match(templatedParent, subscribe) ?? SelectorMatch.True; }
static Thickness Merge(IStyleable control, AvaloniaProperty <Thickness> property, Thickness newValue) { var oldValue = control.GetValue <Thickness>(property); return(new Thickness ( left: double.IsNaN(newValue.Left) ? oldValue.Left : newValue.Left, top: double.IsNaN(newValue.Top) ? oldValue.Top : newValue.Top, right: double.IsNaN(newValue.Right) ? oldValue.Right : newValue.Right, bottom: double.IsNaN(newValue.Bottom) ? oldValue.Bottom : newValue.Bottom )); }
/// <summary> /// Applies the setter to the control. /// </summary> /// <param name="style">The style that is being applied.</param> /// <param name="control">The control.</param> /// <param name="activator">An optional activator.</param> public void Apply(IStyle style, IStyleable control, IObservable <bool> activator) { if (activator == null) { control.SetValue(Property, Value, BindingPriority.Style); } else { var binding = new StyleBinding(activator, Value, style.ToString()); control.Bind(Property, binding, BindingPriority.StyleTrigger); } }
/// <summary> /// Applies the setter to the control. /// </summary> /// <param name="style">The style that is being applied.</param> /// <param name="control">The control.</param> /// <param name="activator">An optional activator.</param> public void Apply(IStyle style, IStyleable control, IObservable<bool> activator) { if (activator == null) { control.Bind(Property, Source, BindingPriority.Style); } else { var binding = new StyleBinding(activator, Source, style.ToString()); control.Bind(Property, binding, BindingPriority.StyleTrigger); } }
private static SelectorMatch MatchClass(IStyleable control, string name) { var observable = Observable.FromEventPattern < NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>( x => control.Classes.CollectionChanged += x, x => control.Classes.CollectionChanged -= x) .Select(_ => Unit.Default) .StartWith(Unit.Default) .Select(_ => control.Classes.Contains(name)); return(new SelectorMatch(observable)); }
/// <inheritdoc/> public void Attach(IStyleable control, IStyleHost container) { if (Source != null) { if (Loaded == null) { var loader = new PerspexXamlLoader(); Loaded = (IStyle)loader.Load(Source); } Loaded.Attach(control, container); } }
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { var controlParent = ((ILogical)control).LogicalParent; if (controlParent != null) { return _parent.Match((IStyleable)controlParent, subscribe); } else { return SelectorMatch.False; } }
protected override SelectorMatch Evaluate(IStyleable control, IStyle?parent, bool subscribe) { if (subscribe) { return(new SelectorMatch(new PropertyEqualsActivator(control, _property, _value))); } else { return(Compare(_property.PropertyType, control.GetValue(_property), _value) ? SelectorMatch.AlwaysThisInstance : SelectorMatch.NeverThisInstance); } }
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { var controlParent = ((ILogical)control).LogicalParent; if (controlParent != null) { return(_parent.Match((IStyleable)controlParent, subscribe)); } else { return(SelectorMatch.False); } }
private static SelectorMatch MatchChild(IStyleable control, Selector previous) { var parent = ((ILogical)control).LogicalParent; if (parent != null) { return(previous.Match((IStyleable)parent)); } else { return(SelectorMatch.False); } }
private static List <IDisposable> GetSubscriptions(IStyleable control) { List <IDisposable> subscriptions; if (!_applied.TryGetValue(control, out subscriptions)) { subscriptions = new List <IDisposable>(2); subscriptions.Add(control.StyleDetach.Subscribe(ControlDetach)); _applied.Add(control, subscriptions); } return(subscriptions); }
/// <summary> /// Attaches the style to a control if the style's selector matches. /// </summary> /// <param name="control">The control to attach to.</param> public void Attach(IStyleable control) { var description = "Style " + Selector.ToString(); var match = Selector.Match(control); if (match.ImmediateResult != false) { foreach (var setter in Setters) { setter.Apply(this, control, match.ObservableResult); } } }
/// <inheritdoc/> protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { if (TargetType != null) { var controlType = control.StyleKey ?? control.GetType(); if (IsConcreteType) { if (controlType != TargetType) { return(SelectorMatch.False); } } else { if (!TargetType.GetTypeInfo().IsAssignableFrom(controlType.GetTypeInfo())) { return(SelectorMatch.False); } } } if (Name != null && control.Name != Name) { return(SelectorMatch.False); } if (_classes.IsValueCreated && _classes.Value.Count > 0) { if (subscribe) { var observable = Observable.FromEventPattern < NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>( x => control.Classes.CollectionChanged += x, x => control.Classes.CollectionChanged -= x) .StartWith((EventPattern <NotifyCollectionChangedEventArgs>)null) .Select(_ => Matches(control.Classes)) .DistinctUntilChanged(); return(new SelectorMatch(observable)); } else { return(new SelectorMatch(Matches(control.Classes))); } } else { return(SelectorMatch.True); } }
public void Attach(IStyleable control) { var description = "Style " + this.Selector.ToString(); var match = this.Selector.Match(control); if (match.ImmediateResult.HasValue) { if (match.ImmediateResult == true) { foreach (Setter setter in this.Setters) { if (setter.Source != null && setter.Value != null) { throw new InvalidOperationException("Cannot set both Source and Value on a Setter."); } if (setter.Source == null) { control.SetValue(setter.Property, setter.Value, BindingPriority.Style); } else { control.Bind(setter.Property, setter.Source, BindingPriority.Style); } } } } else { foreach (Setter setter in this.Setters) { if (setter.Source != null && setter.Value != null) { throw new InvalidOperationException("Cannot set both Source and Value on a Setter."); } StyleBinding binding; if (setter.Source == null) { binding = new StyleBinding(match.ObservableResult, setter.Value, description); } else { binding = new StyleBinding(match.ObservableResult, setter.Source, description); } control.Bind(setter.Property, binding, BindingPriority.StyleTrigger); } } }
/// <summary> /// Tries to match the selector with a control. /// </summary> /// <param name="control">The control.</param> /// <param name="subscribe"> /// Whether the match should subscribe to changes in order to track the match over time, /// or simply return an immediate result. /// </param> /// <returns>A <see cref="SelectorMatch"/>.</returns> public SelectorMatch Match(IStyleable control, bool subscribe = true) { ValueSingleOrList <IObservable <bool> > inputs = default; var selector = this; var alwaysThisType = true; var hitCombinator = false; while (selector != null) { hitCombinator |= selector.IsCombinator; var match = selector.Evaluate(control, subscribe); if (!match.IsMatch) { return(hitCombinator ? SelectorMatch.NeverThisInstance : match); } else if (selector.InTemplate && control.TemplatedParent == null) { return(SelectorMatch.NeverThisInstance); } else if (match.Result == SelectorMatchResult.AlwaysThisInstance) { alwaysThisType = false; } else if (match.Result == SelectorMatchResult.Sometimes) { Debug.Assert(match.Activator != null); inputs.Add(match.Activator); } selector = selector.MovePrevious(); } if (inputs.HasList) { return(new SelectorMatch(StyleActivator.And(inputs.List))); } else if (inputs.IsSingle) { return(new SelectorMatch(inputs.Single)); } else { return(alwaysThisType && !hitCombinator ? SelectorMatch.AlwaysThisType : SelectorMatch.AlwaysThisInstance); } }
private void ApplyStyles(IStyleable target, IStyleHost host) { var parent = host.StylingParent; if (parent != null) { ApplyStyles(target, parent); } if (host.IsStylesInitialized) { host.Styles.TryAttach(target, host); } }
/// <summary> /// Applies the given style(s) to the given control. /// </summary> /// <param name="control">The control to apply the style(s) to.</param> /// <param name="styleHost">The style set to apply.</param> private void ApplyStyles(IStyleable control, IStyleHost styleHost) { Contract.Requires <ArgumentNullException>(control != null); Contract.Requires <ArgumentNullException>(styleHost != null); var parentContainer = styleHost.StylingParent; if (parentContainer != null) { ApplyStyles(control, parentContainer); } styleHost.Styles.Attach(control, styleHost); }
/// <summary> /// Applies the setter to a control. /// </summary> /// <param name="style">The style that is being applied.</param> /// <param name="control">The control.</param> /// <param name="activator">An optional activator.</param> public IDisposable Apply(IStyle style, IStyleable control, IObservable<bool> activator) { Contract.Requires<ArgumentNullException>(control != null); var description = style?.ToString(); if (Property == null) { throw new InvalidOperationException("Setter.Property must be set."); } var value = Value; var binding = value as IBinding; if (binding == null) { var template = value as ITemplate; bool isPropertyOfTypeITemplate = typeof(ITemplate).GetTypeInfo() .IsAssignableFrom(Property.PropertyType.GetTypeInfo()); if (template != null && !isPropertyOfTypeITemplate) { var materialized = template.Build(); NameScope.SetNameScope((Visual)materialized, new NameScope()); value = materialized; } if (activator == null) { return control.Bind(Property, ObservableEx.SingleValue(value), BindingPriority.Style); } else { var activated = new ActivatedValue(activator, value, description); return control.Bind(Property, activated, BindingPriority.StyleTrigger); } } else { var source = binding.Initiate(control, Property); if (source != null) { var cloned = Clone(source, style, activator); return BindingOperations.Apply(control, Property, cloned, null); } } return Disposable.Empty; }
/// <summary> /// Applies the setter to a control. /// </summary> /// <param name="style">The style that is being applied.</param> /// <param name="control">The control.</param> /// <param name="activator">An optional activator.</param> public IDisposable Apply(IStyle style, IStyleable control, IObservable <bool> activator) { Contract.Requires <ArgumentNullException>(control != null); var description = style?.ToString(); if (Property == null) { throw new InvalidOperationException("Setter.Property must be set."); } var value = Value; var binding = value as IBinding; if (binding == null) { var template = value as ITemplate; bool isPropertyOfTypeITemplate = typeof(ITemplate).GetTypeInfo() .IsAssignableFrom(Property.PropertyType.GetTypeInfo()); if (template != null && !isPropertyOfTypeITemplate) { var materialized = template.Build(); NameScope.SetNameScope((Visual)materialized, new NameScope()); value = materialized; } if (activator == null) { return(control.Bind(Property, ObservableEx.SingleValue(value), BindingPriority.Style)); } else { var activated = new ActivatedValue(activator, value, description); return(control.Bind(Property, activated, BindingPriority.StyleTrigger)); } } else { var source = binding.Initiate(control, Property); if (source != null) { var cloned = Clone(source, style, activator); return(BindingOperations.Apply(control, Property, cloned, null)); } } return(Disposable.Empty); }
private void ApplyStyles(IStyleable control, IStyleHost styleHost) { Contract.Requires<ArgumentNullException>(control != null); Contract.Requires<ArgumentNullException>(styleHost != null); var parentContainer = styleHost.StylingParent; if (parentContainer != null) { ApplyStyles(control, parentContainer); } styleHost.Styles.Attach(control, styleHost); }
private static SelectorMatch MatchUntilCombinator( IStyleable control, Selector start, bool subscribe, out Selector?combinator) { combinator = null; var activators = new AndActivatorBuilder(); var result = Match(control, start, subscribe, ref activators, ref combinator); return(result == SelectorMatchResult.Sometimes ? new SelectorMatch(activators.Get()) : new SelectorMatch(result)); }
/// <inheritdoc/> protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { if (!AvaloniaPropertyRegistry.Instance.IsRegistered(control, _property)) { return SelectorMatch.False; } else if (subscribe) { return new SelectorMatch(control.GetObservable(_property).Select(v => Equals(v, _value))); } else { return new SelectorMatch(control.GetValue(_property).Equals(_value)); } }
/// <inheritdoc/> protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { if (!PerspexPropertyRegistry.Instance.IsRegistered(control, _property)) { return(SelectorMatch.False); } else if (subscribe) { return(new SelectorMatch(control.GetObservable(_property).Select(v => Equals(v, _value)))); } else { return(new SelectorMatch(control.GetValue(_property).Equals(_value))); } }
public void ApplyStyles(IStyleable control) { IVisual visual = control as IVisual; IStyleHost styleContainer = visual .GetSelfAndVisualAncestors() .OfType<IStyleHost>() .FirstOrDefault(); IGlobalStyles global = PerspexLocator.Current.GetService<IGlobalStyles>(); global?.Styles.Attach(control, null); if (styleContainer != null) { ApplyStyles(control, styleContainer); } }
private void ApplyStyles(IStyleable control, IStyleHost container) { Contract.Requires<ArgumentNullException>(control != null); Contract.Requires<ArgumentNullException>(container != null); IVisual visual = container as IVisual; if (visual != null) { IStyleHost parentContainer = visual .GetVisualAncestors() .OfType<IStyleHost>() .FirstOrDefault(); if (parentContainer != null) { ApplyStyles(control, parentContainer); } } container.Styles.Attach(control, container); }
/// <summary> /// Applies the setter to the control. /// </summary> /// <param name="style">The style that is being applied.</param> /// <param name="control">The control.</param> /// <param name="activator">An optional activator.</param> public void Apply(IStyle style, IStyleable control, IObservable<bool> activator) { Contract.Requires<ArgumentNullException>(control != null); var description = style?.ToString(); if (Property == null) { throw new InvalidOperationException("Setter.Property must be set."); } var binding = Value as IBinding; if (binding != null) { if (activator == null) { control.Bind(Property, binding); } else { var subject = binding.CreateSubject(control, Property); var activated = new ActivatedSubject(activator, subject, description); Bind(control, Property, binding, activated); } } else { if (activator == null) { control.SetValue(Property, Value, BindingPriority.Style); } else { var activated = new ActivatedValue(activator, Value, description); control.Bind(Property, activated, BindingPriority.StyleTrigger); } } }
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { ILogical c = (ILogical)control; List<IObservable<bool>> descendentMatches = new List<IObservable<bool>>(); while (c != null) { c = c.LogicalParent; if (c is IStyleable) { var match = _parent.Match((IStyleable)c, subscribe); if (match.ImmediateResult != null) { if (match.ImmediateResult == true) { return SelectorMatch.True; } } else { descendentMatches.Add(match.ObservableResult); } } } if (descendentMatches.Count > 0) { return new SelectorMatch(StyleActivator.Or(descendentMatches)); } else { return SelectorMatch.False; } }
private static List<IDisposable> GetSubscriptions(IStyleable control) { List<IDisposable> subscriptions; if (!_applied.TryGetValue(control, out subscriptions)) { subscriptions = new List<IDisposable>(2); subscriptions.Add(control.StyleDetach.Subscribe(ControlDetach)); _applied.Add(control, subscriptions); } return subscriptions; }
/// <inheritdoc/> protected override SelectorMatch Evaluate(IStyleable control, bool subscribe) { if (TargetType != null) { var controlType = control.StyleKey ?? control.GetType(); if (IsConcreteType) { if (controlType != TargetType) { return SelectorMatch.False; } } else { if (!TargetType.GetTypeInfo().IsAssignableFrom(controlType.GetTypeInfo())) { return SelectorMatch.False; } } } if (Name != null && control.Name != Name) { return SelectorMatch.False; } if (_classes.IsValueCreated && _classes.Value.Count > 0) { if (subscribe) { var observable = Observable.FromEventPattern< NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>( x => control.Classes.CollectionChanged += x, x => control.Classes.CollectionChanged -= x) .StartWith((EventPattern<NotifyCollectionChangedEventArgs>)null) .Select(_ => Matches(control.Classes)); return new SelectorMatch(observable); } else { return new SelectorMatch(Matches(control.Classes)); } } else { return SelectorMatch.True; } }
private void Bind( IStyleable control, PerspexProperty property, IBinding binding, ISubject<object> subject) { var mode = binding.Mode; if (mode == BindingMode.Default) { mode = property.GetMetadata(control.GetType()).DefaultBindingMode; } control.Bind( property, subject, mode, binding.Priority); }
/// <summary> /// Evaluates the selector for a match. /// </summary> /// <param name="control">The control.</param> /// <param name="subscribe"> /// Whether the match should subscribe to changes in order to track the match over time, /// or simply return an immediate result. /// </param> /// <returns>A <see cref="SelectorMatch"/>.</returns> protected abstract SelectorMatch Evaluate(IStyleable control, bool subscribe);