Browse Source

Added beginnings of TabStrip control.

pull/4/head
Steven Kirk 12 years ago
parent
commit
173ed94df2
  1. 2
      Perspex/Controls/ContentPresenter.cs
  2. 2
      Perspex/Controls/Control.cs
  3. 5
      Perspex/Controls/DataTemplate.cs
  4. 15
      Perspex/Controls/ItemsControl.cs
  5. 33
      Perspex/Controls/ItemsPresenter.cs
  6. 12
      Perspex/Controls/Tab.cs
  7. 15
      Perspex/Controls/TabItem.cs
  8. 14
      Perspex/Controls/TabStrip.cs
  9. 6
      Perspex/Diagnostics/Debug.cs
  10. 2
      Perspex/Layout/Layoutable.cs
  11. 7
      Perspex/Media/Brushes.cs
  12. 4
      Perspex/Perspex.csproj
  13. 3
      Perspex/Styling/Selector.cs
  14. 5
      Perspex/Styling/Style.cs
  15. 2
      Perspex/Themes/Default/ContentControlStyle.cs
  16. 2
      Perspex/Themes/Default/DefaultTheme.cs
  17. 1
      Perspex/Themes/Default/ItemsControlStyle.cs
  18. 48
      Perspex/Themes/Default/TabItemStyle.cs
  19. 13
      Perspex/Themes/Default/TabStripStyle.cs
  20. 42
      Perspex/Themes/Default/TabStyle.cs
  21. 2
      Perspex/Themes/Default/TextBoxStyle.cs
  22. 10
      TestApplication/Program.cs

2
Perspex/Controls/ContentPresenter.cs

@ -82,7 +82,7 @@ namespace Perspex.Controls
if (this.visualChild != null) if (this.visualChild != null)
{ {
((IVisual)this.visualChild).VisualParent = this; this.visualChild.VisualParent = this;
((Control)this.visualChild).TemplatedParent = null; ((Control)this.visualChild).TemplatedParent = null;
} }
} }

2
Perspex/Controls/Control.cs

@ -218,7 +218,7 @@ namespace Perspex.Controls
if (visual != null) if (visual != null)
{ {
return new DataTemplate(_ => true, x => visual); return new DataTemplate(x => visual);
} }
ILogical node = this; ILogical node = this;

5
Perspex/Controls/DataTemplate.cs

@ -14,6 +14,11 @@ namespace Perspex.Controls
public static readonly DataTemplate Default = public static readonly DataTemplate Default =
new DataTemplate(typeof(object), o => new TextBlock { Text = o.ToString() }); new DataTemplate(typeof(object), o => new TextBlock { Text = o.ToString() });
public DataTemplate(Func<object, IVisual> build)
: this(o => true, build)
{
}
public DataTemplate(Type type, Func<object, IVisual> build) public DataTemplate(Type type, Func<object, IVisual> build)
: this(o => type.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()), build) : this(o => type.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()), build)
{ {

15
Perspex/Controls/ItemsControl.cs

@ -10,18 +10,17 @@ namespace Perspex.Controls
public class ItemsControl : TemplatedControl public class ItemsControl : TemplatedControl
{ {
private static readonly ItemsPanelTemplate defaultPanel = private static readonly ItemsPanelTemplate DefaultPanel =
new ItemsPanelTemplate(() => new StackPanel { Orientation = Orientation.Vertical }); new ItemsPanelTemplate(() => new StackPanel { Orientation = Orientation.Vertical });
public static readonly PerspexProperty<IEnumerable> ItemsProperty = public static readonly PerspexProperty<IEnumerable> ItemsProperty =
PerspexProperty.Register<ItemsControl, IEnumerable>("Items"); PerspexProperty.Register<ItemsControl, IEnumerable>("Items");
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty = public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty =
PerspexProperty.Register<ItemsControl, ItemsPanelTemplate>("ItemsPanel", defaultValue: defaultPanel); PerspexProperty.Register<ItemsControl, ItemsPanelTemplate>("ItemsPanel", defaultValue: DefaultPanel);
public ItemsControl() public static readonly PerspexProperty<DataTemplate> ItemTemplateProperty =
{ PerspexProperty.Register<ItemsControl, DataTemplate>("ItemTemplate");
}
public IEnumerable Items public IEnumerable Items
{ {
@ -34,5 +33,11 @@ namespace Perspex.Controls
get { return this.GetValue(ItemsPanelProperty); } get { return this.GetValue(ItemsPanelProperty); }
set { this.SetValue(ItemsPanelProperty, value); } set { this.SetValue(ItemsPanelProperty, value); }
} }
public DataTemplate ItemTemplate
{
get { return this.GetValue(ItemTemplateProperty); }
set { this.SetValue(ItemTemplateProperty, value); }
}
} }
} }

33
Perspex/Controls/ItemsPresenter.cs

@ -15,10 +15,13 @@ namespace Perspex.Controls
public class ItemsPresenter : Control, IVisual public class ItemsPresenter : Control, IVisual
{ {
public static readonly PerspexProperty<IEnumerable> ItemsProperty = public static readonly PerspexProperty<IEnumerable> ItemsProperty =
PerspexProperty.Register<ItemsPresenter, IEnumerable>("Items"); ItemsControl.ItemsProperty.AddOwner<ItemsPresenter>();
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty = public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty =
PerspexProperty.Register<ItemsPresenter, ItemsPanelTemplate>("ItemsPanel"); ItemsControl.ItemsPanelProperty.AddOwner<ItemsPresenter>();
public static readonly PerspexProperty<DataTemplate> ItemTemplateProperty =
ItemsControl.ItemTemplateProperty.AddOwner<ItemsPresenter>();
private Panel panel; private Panel panel;
@ -39,6 +42,12 @@ namespace Perspex.Controls
set { this.SetValue(ItemsPanelProperty, value); } set { this.SetValue(ItemsPanelProperty, value); }
} }
public DataTemplate ItemTemplate
{
get { return this.GetValue(ItemTemplateProperty); }
set { this.SetValue(ItemTemplateProperty, value); }
}
IEnumerable<IVisual> IVisual.ExistingVisualChildren IEnumerable<IVisual> IVisual.ExistingVisualChildren
{ {
get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); } get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); }
@ -62,6 +71,20 @@ namespace Perspex.Controls
return finalSize; return finalSize;
} }
protected override DataTemplate FindDataTemplate(object content)
{
TabItem tabItem = content as TabItem;
if (tabItem != null)
{
return new DataTemplate(_ => tabItem);
}
else
{
return this.ItemTemplate ?? base.FindDataTemplate(content);
}
}
private IEnumerable<Control> CreateItems(IEnumerable items) private IEnumerable<Control> CreateItems(IEnumerable items)
{ {
if (items != null) if (items != null)
@ -82,6 +105,7 @@ namespace Perspex.Controls
if (this.panel == null && this.ItemsPanel != null) if (this.panel == null && this.ItemsPanel != null)
{ {
this.panel = this.ItemsPanel.Build(); this.panel = this.ItemsPanel.Build();
((IVisual)this.panel).VisualParent = this;
this.ItemsChanged(this.Items); this.ItemsChanged(this.Items);
} }
@ -93,6 +117,11 @@ namespace Perspex.Controls
if (this.panel != null) if (this.panel != null)
{ {
this.panel.Children = new PerspexList<Control>(this.CreateItems(items)); this.panel.Children = new PerspexList<Control>(this.CreateItems(items));
if (this.panel.Children.Count > 0)
{
((TabItem)this.panel.Children[0]).Classes.Add(":selected");
}
} }
} }
} }

12
Perspex/Controls/Tab.cs

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perspex.Controls
{
public class Tab : ContentControl
{
}
}

15
Perspex/Controls/TabItem.cs

@ -0,0 +1,15 @@
// -----------------------------------------------------------------------
// <copyright file="TabItem.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
public class TabItem : HeaderedContentControl
{
public TabItem()
{
}
}
}

14
Perspex/Controls/TabStrip.cs

@ -12,16 +12,16 @@ namespace Perspex.Controls
public class TabStrip : ItemsControl public class TabStrip : ItemsControl
{ {
private static readonly DataTemplate TabTemplate = new DataTemplate(_ => true, CreateTab); private static readonly ItemsPanelTemplate PanelTemplate = new ItemsPanelTemplate(
() => new StackPanel());
protected override DataTemplate FindDataTemplate(object content) private static readonly DataTemplate TabTemplate = new DataTemplate(
{ o => new TabItem { Content = o });
return TabTemplate;
}
private static IVisual CreateTab(object o) static TabStrip()
{ {
return new Tab { Content = o }; ItemsPanelProperty.OverrideDefaultValue(typeof(TabStrip), PanelTemplate);
ItemTemplateProperty.OverrideDefaultValue(typeof(TabStrip), TabTemplate);
} }
} }
} }

6
Perspex/Diagnostics/Debug.cs

@ -36,10 +36,10 @@ namespace Perspex.Diagnostics
builder.Append(" | "); builder.Append(" | ");
builder.Append(value.Item1.Name); builder.Append(value.Item1.Name);
builder.Append(" = "); builder.Append(" = ");
builder.Append(value.Item2); builder.Append(value.Item2 ?? "(null)");
builder.Append(" ("); builder.Append(" [");
builder.Append(value.Item3); builder.Append(value.Item3);
builder.AppendLine(")"); builder.AppendLine("]");
} }
} }

2
Perspex/Layout/Layoutable.cs

@ -217,7 +217,7 @@ namespace Perspex.Layout
{ {
if (this.IsVisible) if (this.IsVisible)
{ {
Size measuredSize = this.MeasureOverride(availableSize.Deflate(this.Margin)); Size measuredSize = this.MeasureOverride(availableSize.Deflate(this.Margin)).Inflate(this.Margin);
double width = (this.Width > 0) ? this.Width : measuredSize.Width; double width = (this.Width > 0) ? this.Width : measuredSize.Width;
double height = (this.Height > 0) ? this.Height : measuredSize.Height; double height = (this.Height > 0) ? this.Height : measuredSize.Height;

7
Perspex/Media/Brushes.cs

@ -14,6 +14,7 @@ namespace Perspex.Media
static Brushes() static Brushes()
{ {
Black = new SolidColorBrush(0xff000000); Black = new SolidColorBrush(0xff000000);
Gray = new SolidColorBrush(0xff808080);
Red = new SolidColorBrush(0xffff0000); Red = new SolidColorBrush(0xffff0000);
} }
@ -23,6 +24,12 @@ namespace Perspex.Media
private set; private set;
} }
public static SolidColorBrush Gray
{
get;
private set;
}
public static SolidColorBrush Red public static SolidColorBrush Red
{ {
get; get;

4
Perspex/Perspex.csproj

@ -71,7 +71,7 @@
<Compile Include="Application.cs" /> <Compile Include="Application.cs" />
<Compile Include="BindingExtensions.cs" /> <Compile Include="BindingExtensions.cs" />
<Compile Include="Controls\HeaderedContentControl.cs" /> <Compile Include="Controls\HeaderedContentControl.cs" />
<Compile Include="Controls\Tab.cs" /> <Compile Include="Controls\TabItem.cs" />
<Compile Include="Controls\TabStrip.cs" /> <Compile Include="Controls\TabStrip.cs" />
<Compile Include="Controls\ItemsPresenter.cs" /> <Compile Include="Controls\ItemsPresenter.cs" />
<Compile Include="Controls\ItemsPanelTemplate.cs" /> <Compile Include="Controls\ItemsPanelTemplate.cs" />
@ -133,7 +133,7 @@
<Compile Include="Media\Stretch.cs" /> <Compile Include="Media\Stretch.cs" />
<Compile Include="Themes\Default\ContentControlStyle.cs" /> <Compile Include="Themes\Default\ContentControlStyle.cs" />
<Compile Include="Themes\Default\ItemsControlStyle.cs" /> <Compile Include="Themes\Default\ItemsControlStyle.cs" />
<Compile Include="Themes\Default\TabStyle.cs" /> <Compile Include="Themes\Default\TabItemStyle.cs" />
<Compile Include="Themes\Default\TabStripStyle.cs" /> <Compile Include="Themes\Default\TabStripStyle.cs" />
<Compile Include="Vector.cs" /> <Compile Include="Vector.cs" />
<Compile Include="Rendering\RenderManager.cs" /> <Compile Include="Rendering\RenderManager.cs" />

3
Perspex/Styling/Selector.cs

@ -82,8 +82,7 @@ namespace Perspex.Styling
while (selector != null) while (selector != null)
{ {
if ((selector.InTemplate && control.TemplatedParent == null) || if (selector.InTemplate && control.TemplatedParent == null)
(!selector.InTemplate && control.TemplatedParent != null))
{ {
inputs.Add(Observable.Return(false)); inputs.Add(Observable.Return(false));
} }

5
Perspex/Styling/Style.cs

@ -52,5 +52,10 @@ namespace Perspex.Styling
} }
} }
} }
public override string ToString()
{
return "Style: " + this.Selector.ToString();
}
} }
} }

2
Perspex/Themes/Default/ContentControlStyle.cs

@ -21,7 +21,7 @@ namespace Perspex.Themes.Default
{ {
Setters = new[] Setters = new[]
{ {
new Setter(Button.TemplateProperty, ControlTemplate.Create<ContentControl>(this.Template)), new Setter(ContentControl.TemplateProperty, ControlTemplate.Create<ContentControl>(this.Template)),
}, },
}, },
}); });

2
Perspex/Themes/Default/DefaultTheme.cs

@ -17,7 +17,7 @@ namespace Perspex.Themes.Default
this.Add(new ContentControlStyle()); this.Add(new ContentControlStyle());
this.Add(new ItemsControlStyle()); this.Add(new ItemsControlStyle());
this.Add(new TextBoxStyle()); this.Add(new TextBoxStyle());
this.Add(new TabStyle()); this.Add(new TabItemStyle());
this.Add(new TabStripStyle()); this.Add(new TabStripStyle());
} }
} }

1
Perspex/Themes/Default/ItemsControlStyle.cs

@ -32,6 +32,7 @@ namespace Perspex.Themes.Default
{ {
[~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty], [~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty], [~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
[~ItemsPresenter.ItemTemplateProperty] = control[~ItemsControl.ItemTemplateProperty],
}; };
} }
} }

48
Perspex/Themes/Default/TabItemStyle.cs

@ -0,0 +1,48 @@
// -----------------------------------------------------------------------
// <copyright file="TabItemStyle.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Themes.Default
{
using System.Linq;
using Perspex.Controls;
using Perspex.Media;
using Perspex.Styling;
public class TabItemStyle : Styles
{
public TabItemStyle()
{
this.AddRange(new[]
{
new Style(x => x.OfType<TabItem>())
{
Setters = new[]
{
new Setter(TextBox.FontSizeProperty, 28.7),
new Setter(Control.ForegroundProperty, Brushes.Gray),
new Setter(Control.MarginProperty, new Thickness(8, 0)),
new Setter(TabItem.TemplateProperty, ControlTemplate.Create<TabItem>(this.Template)),
},
},
new Style(x => x.OfType<TabItem>().Class(":selected"))
{
Setters = new[]
{
new Setter(Control.ForegroundProperty, Brushes.Black),
},
},
});
}
private Control Template(TabItem control)
{
return new ContentPresenter
{
[~ContentPresenter.ContentProperty] = control[~TabItem.HeaderProperty],
};
}
}
}

13
Perspex/Themes/Default/TabStripStyle.cs

@ -8,7 +8,6 @@ namespace Perspex.Themes.Default
{ {
using System.Linq; using System.Linq;
using Perspex.Controls; using Perspex.Controls;
using Perspex.Media;
using Perspex.Styling; using Perspex.Styling;
public class TabStripStyle : Styles public class TabStripStyle : Styles
@ -21,7 +20,14 @@ namespace Perspex.Themes.Default
{ {
Setters = new[] Setters = new[]
{ {
new Setter(Button.TemplateProperty, ControlTemplate.Create<TabStrip>(this.Template)), new Setter(TabStrip.TemplateProperty, ControlTemplate.Create<TabStrip>(this.Template)),
},
},
new Style(x => x.OfType<TabStrip>().Template().OfType<StackPanel>())
{
Setters = new[]
{
new Setter(StackPanel.OrientationProperty, Orientation.Horizontal),
}, },
}, },
}); });
@ -31,8 +37,9 @@ namespace Perspex.Themes.Default
{ {
return new ItemsPresenter return new ItemsPresenter
{ {
ItemsPanel = new ItemsPanelTemplate(() => new StackPanel()),
[~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty], [~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
[~ItemsPresenter.ItemTemplateProperty] = control[~ItemsControl.ItemTemplateProperty],
}; };
} }
} }

42
Perspex/Themes/Default/TabStyle.cs

@ -1,42 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="TabStyle.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Themes.Default
{
using System.Linq;
using Perspex.Controls;
using Perspex.Media;
using Perspex.Styling;
public class TabStyle : Styles
{
public TabStyle()
{
this.AddRange(new[]
{
new Style(x => x.OfType<Tab>())
{
Setters = new[]
{
new Setter(Button.TemplateProperty, ControlTemplate.Create<Tab>(this.Template)),
},
},
});
}
private Control Template(Tab control)
{
return new Border
{
Background = Brushes.Red,
Content = new ContentPresenter
{
[~ContentPresenter.ContentProperty] = control[~Tab.ContentProperty],
}
};
}
}
}

2
Perspex/Themes/Default/TextBoxStyle.cs

@ -23,7 +23,7 @@ namespace Perspex.Themes.Default
{ {
Setters = new[] Setters = new[]
{ {
new Setter(Button.TemplateProperty, ControlTemplate.Create<TextBox>(this.Template)), new Setter(TextBox.TemplateProperty, ControlTemplate.Create<TextBox>(this.Template)),
new Setter(TextBox.BorderBrushProperty, new SolidColorBrush(0xff707070)), new Setter(TextBox.BorderBrushProperty, new SolidColorBrush(0xff707070)),
new Setter(TextBox.BorderThicknessProperty, 2.0), new Setter(TextBox.BorderThicknessProperty, 2.0),
}, },

10
TestApplication/Program.cs

@ -74,8 +74,14 @@ namespace TestApplication
{ {
Items = new[] Items = new[]
{ {
"Foo", new TabItem
"Bar", {
Header = "Tab 1",
},
new TabItem
{
Header = "Tab 2",
},
} }
} }
} }

Loading…
Cancel
Save