Browse Source

Started adding a styling system.

pull/4/head
grokys 12 years ago
parent
commit
4ca80d4ec8
  1. 14
      Perspex/Controls/ContentControl.cs
  2. 74
      Perspex/Controls/Control.cs
  3. 3
      Perspex/Perspex.csproj
  4. 83
      Perspex/PerspexObject.cs
  5. 21
      Perspex/Selectors.cs
  6. 38
      Perspex/Setter.cs
  7. 67
      Perspex/Style.cs
  8. 35
      TestApplication/Program.cs

14
Perspex/Controls/ContentControl.cs

@ -1,5 +1,6 @@
namespace Perspex.Controls
{
using System;
using System.Linq;
public abstract class ContentControl : TemplatedControl
@ -7,6 +8,19 @@
public static readonly PerspexProperty<object> ContentProperty =
PerspexProperty.Register<ContentControl, object>("Content");
public ContentControl()
{
this.GetObservable(ContentProperty).Subscribe(x =>
{
Control control = x as Control;
if (control != null)
{
control.SetValue(ParentPropertyRW, this);
}
});
}
public object Content
{
get { return this.GetValue(ContentProperty); }

74
Perspex/Controls/Control.cs

@ -1,9 +1,11 @@
namespace Perspex.Controls
{
using System;
using System.Diagnostics.Contracts;
using Perspex.Layout;
using Perspex.Media;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
using Perspex.Layout;
using Perspex.Media;
public enum HorizontalAlignment
{
@ -23,14 +25,20 @@
public abstract class Control : Visual, ILayoutable
{
internal static readonly PerspexProperty<Control> ParentPropertyRW =
PerspexProperty.Register<Control, Control>("Parent");
public static readonly ReadOnlyPerspexProperty<Control> ParentProperty =
new ReadOnlyPerspexProperty<Control>(ParentPropertyRW);
public static readonly PerspexProperty<Brush> BackgroundProperty =
PerspexProperty.Register<Border, Brush>("Background");
PerspexProperty.Register<Control, Brush>("Background");
public static readonly PerspexProperty<Brush> BorderBrushProperty =
PerspexProperty.Register<Border, Brush>("BorderBrush");
PerspexProperty.Register<Control, Brush>("BorderBrush");
public static readonly PerspexProperty<double> BorderThicknessProperty =
PerspexProperty.Register<Border, double>("BorderThickness");
PerspexProperty.Register<Control, double>("BorderThickness");
public static readonly PerspexProperty<HorizontalAlignment> HorizontalAlignmentProperty =
PerspexProperty.Register<Control, HorizontalAlignment>("HorizontalAlignment");
@ -41,6 +49,13 @@
public static readonly PerspexProperty<Thickness> MarginProperty =
PerspexProperty.Register<Control, Thickness>("Margin");
public Control()
{
this.Classes = new ObservableCollection<string>();
this.Styles = new ObservableCollection<Style>();
this.GetObservableWithHistory(ParentPropertyRW).Subscribe(this.ParentChanged);
}
public Brush Background
{
get { return this.GetValue(BackgroundProperty); }
@ -59,6 +74,18 @@
set { this.SetValue(BorderThicknessProperty, value); }
}
public ObservableCollection<string> Classes
{
get;
private set;
}
public IEnumerable<Style> Styles
{
get;
set;
}
public Size? DesiredSize
{
get;
@ -85,8 +112,8 @@
public Control Parent
{
get;
internal set;
get { return this.GetValue(ParentPropertyRW); }
internal set { this.SetValue(ParentPropertyRW, value); }
}
public ILayoutRoot GetLayoutRoot()
@ -130,5 +157,36 @@
}
protected abstract Size MeasureContent(Size availableSize);
private void AttachStyles(Control control)
{
if (control.Styles != null)
{
foreach (Style style in control.Styles)
{
style.Attach(this);
}
}
Control parent = control.Parent;
if (parent != null)
{
this.AttachStyles(parent);
}
}
private void ParentChanged(Tuple<Control, Control> values)
{
if (values.Item1 != null)
{
//this.DetatchStyles(values.Item1);
}
if (values.Item2 != null)
{
this.AttachStyles(this);
}
}
}
}

3
Perspex/Perspex.csproj

@ -92,10 +92,13 @@
<Compile Include="PerspexPropertyChangedEventArgs.cs" />
<Compile Include="Point.cs" />
<Compile Include="ReadOnlyPerspexProperty.cs" />
<Compile Include="Selectors.cs" />
<Compile Include="ServiceLocator.cs" />
<Compile Include="Setter.cs" />
<Compile Include="Size.cs" />
<Compile Include="Rect.cs" />
<Compile Include="Controls\TemplatedControl.cs" />
<Compile Include="Style.cs" />
<Compile Include="Thickness.cs" />
<Compile Include="Visual.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

83
Perspex/PerspexObject.cs

@ -203,6 +203,33 @@ namespace Perspex
this.values.Remove(property);
}
/// <summary>
/// Gets an observable for a <see cref="PerspexProperty"/>.
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
public IObservable<object> GetObservable(PerspexProperty property)
{
return Observable.Create<object>(observer =>
{
EventHandler<PerspexPropertyChangedEventArgs> handler = (s, e) =>
{
if (e.Property == property)
{
observer.OnNext(e.NewValue);
}
};
this.PropertyChanged += handler;
observer.OnNext(this.GetValue(property));
return () =>
{
this.PropertyChanged -= handler;
};
});
}
/// <summary>
/// Gets an observable for a <see cref="PerspexProperty"/>.
/// </summary>
@ -231,6 +258,44 @@ namespace Perspex
});
}
/// <summary>
/// Gets an observable for a <see cref="ReadOnlyPerspexProperty"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="property"></param>
/// <returns></returns>
public IObservable<T> GetObservable<T>(ReadOnlyPerspexProperty<T> property)
{
return this.GetObservable((PerspexProperty<T>)property.Property);
}
/// <summary>
/// Gets an observable for a <see cref="PerspexProperty"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="property"></param>
/// <returns></returns>
public IObservable<Tuple<T, T>> GetObservableWithHistory<T>(PerspexProperty<T> property)
{
return Observable.Create<Tuple<T, T>>(observer =>
{
EventHandler<PerspexPropertyChangedEventArgs> handler = (s, e) =>
{
if (e.Property == property)
{
observer.OnNext(Tuple.Create((T)e.OldValue, (T)e.NewValue));
}
};
this.PropertyChanged += handler;
return () =>
{
this.PropertyChanged -= handler;
};
});
}
/// <summary>
/// Gets a <see cref="PerspexProperty"/> value.
/// </summary>
@ -297,16 +362,15 @@ namespace Perspex
/// <summary>
/// Sets a <see cref="PerspexProperty"/> value.
/// </summary>
/// <typeparam name="T">The type of the property.</typeparam>
/// <param name="property">The property.</param>
/// <param name="value">The value.</param>
public void SetValue<T>(PerspexProperty<T> property, T value)
public void SetValue(PerspexProperty property, object value)
{
Contract.Requires<NullReferenceException>(property != null);
this.ClearBinding(property);
T oldValue = this.GetValue(property);
object oldValue = this.GetValue(property);
if (!object.Equals(oldValue, value))
{
@ -315,6 +379,19 @@ namespace Perspex
}
}
/// <summary>
/// Sets a <see cref="PerspexProperty"/> value.
/// </summary>
/// <typeparam name="T">The type of the property.</typeparam>
/// <param name="property">The property.</param>
/// <param name="value">The value.</param>
public void SetValue<T>(PerspexProperty<T> property, T value)
{
Contract.Requires<NullReferenceException>(property != null);
this.SetValue((PerspexProperty)property, value);
}
/// <summary>
/// Called when a property is changed on the current <see cref="InheritanceParent"/>.
/// </summary>

21
Perspex/Selectors.cs

@ -0,0 +1,21 @@
namespace Perspex
{
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Controls;
public static class Selectors
{
public static IObservable<bool> OfType<T>(this Control control)
{
Contract.Requires<ArgumentNullException>(control != null);
return Observable.Return(control is T);
}
}
}

38
Perspex/Setter.cs

@ -0,0 +1,38 @@
namespace Perspex
{
using System;
using System.Diagnostics.Contracts;
using Perspex.Controls;
public class Setter
{
private object oldValue;
public PerspexProperty Property
{
get;
set;
}
public object Value
{
get;
set;
}
public void Apply(Control control)
{
Contract.Requires<NullReferenceException>(control != null);
this.oldValue = control.GetValue(this.Property);
control.SetValue(this.Property, this.Value);
}
public void Detach(Control control)
{
Contract.Requires<NullReferenceException>(control != null);
control.SetValue(this.Property, this.oldValue);
}
}
}

67
Perspex/Style.cs

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Text;
using System.Threading.Tasks;
using Perspex.Controls;
namespace Perspex
{
public class Style
{
public Style()
{
this.Setters = new List<Setter>();
}
public Func<Control, IObservable<bool>> Selector
{
get;
set;
}
public IEnumerable<Setter> Setters
{
get;
set;
}
public void Attach(Control control)
{
this.Selector(control).Subscribe(x =>
{
if (x)
{
this.Apply(control);
}
else
{
this.Unapply(control);
}
});
}
private void Apply(Control control)
{
if (this.Setters != null)
{
foreach (Setter setter in this.Setters)
{
setter.Apply(control);
}
}
}
private void Unapply(Control control)
{
if (this.Setters != null)
{
foreach (Setter setter in this.Setters)
{
setter.Detach(control);
}
}
}
}
}

35
TestApplication/Program.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
@ -19,16 +20,32 @@ namespace TestApplication
{
ServiceLocator.Register<ITextService>(() => new TextService(new SharpDX.DirectWrite.Factory()));
Window window = new Window();
window.Content = new Button
Window window = new Window
{
Content = "Hello World",
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Background = new SolidColorBrush(0xff808080),
BorderThickness = 2,
BorderBrush = new SolidColorBrush(0xff000000),
Styles = new ObservableCollection<Style>
{
new Style
{
Selector = x => x.OfType<Button>(),
Setters = new[]
{
new Setter
{
Property = Button.BackgroundProperty,
Value = new SolidColorBrush(0xffff8080),
}
},
}
},
Content = new Button
{
Content = "Hello World",
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Background = new SolidColorBrush(0xff808080),
BorderThickness = 2,
BorderBrush = new SolidColorBrush(0xff000000),
},
};
window.Show();

Loading…
Cancel
Save