Browse Source

checkpoint

pull/4/head
Steven Kirk 12 years ago
parent
commit
3b19bc25b6
  1. 4
      Perspex.Windows/Input/WindowsKeyboardDevice.cs
  2. 16
      Perspex.Windows/Window.cs
  3. 1
      Perspex/Application.cs
  4. 4
      Perspex/Controls/Control.cs
  5. 8
      Perspex/Controls/Decorator.cs
  6. 2
      Perspex/Controls/TemplatedControl.cs
  7. 3
      Perspex/Controls/TreeViewItem.cs
  8. 18
      Perspex/Diagnostics/Debug.cs
  9. 14
      Perspex/Diagnostics/DevTools.cs
  10. 47
      Perspex/IVisual.cs
  11. 2
      Perspex/Input/IInputElement.cs
  12. 3
      Perspex/Input/InputElement.cs
  13. 25
      Perspex/Input/KeyboardDevice.cs
  14. 30
      Perspex/Interactive.cs
  15. 1
      Perspex/Perspex.csproj
  16. 81
      Perspex/Visual.cs

4
Perspex.Windows/Input/WindowsKeyboardDevice.cs

@ -55,6 +55,10 @@ namespace Perspex.Windows.Input
} }
} }
public void WindowActivated(Window window)
{
this.FocusedElement = window;
}
public string StringFromVirtualKey(uint virtualKey) public string StringFromVirtualKey(uint virtualKey)
{ {

16
Perspex.Windows/Window.cs

@ -80,6 +80,8 @@ namespace Perspex.Windows
}); });
} }
public event EventHandler Activated;
public event EventHandler Closed; public event EventHandler Closed;
public Size ClientSize public Size ClientSize
@ -173,6 +175,16 @@ namespace Perspex.Windows
} }
} }
private void OnActivated()
{
WindowsKeyboardDevice.Instance.WindowActivated(this);
if (this.Activated != null)
{
this.Activated(this, EventArgs.Empty);
}
}
private void OnClosed() private void OnClosed()
{ {
if (this.Closed != null) if (this.Closed != null)
@ -190,6 +202,10 @@ namespace Perspex.Windows
switch ((UnmanagedMethods.WindowsMessage)msg) switch ((UnmanagedMethods.WindowsMessage)msg)
{ {
case UnmanagedMethods.WindowsMessage.WM_ACTIVATE:
this.OnActivated();
break;
case UnmanagedMethods.WindowsMessage.WM_DESTROY: case UnmanagedMethods.WindowsMessage.WM_DESTROY:
this.OnClosed(); this.OnClosed();
break; break;

1
Perspex/Application.cs

@ -6,7 +6,6 @@
namespace Perspex namespace Perspex
{ {
using System.Threading;
using Perspex.Controls; using Perspex.Controls;
using Perspex.Input; using Perspex.Input;
using Perspex.Styling; using Perspex.Styling;

4
Perspex/Controls/Control.cs

@ -11,6 +11,7 @@ namespace Perspex.Controls
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using Perspex.Input; using Perspex.Input;
using Perspex.Layout;
using Perspex.Media; using Perspex.Media;
using Perspex.Styling; using Perspex.Styling;
using Splat; using Splat;
@ -190,11 +191,10 @@ namespace Perspex.Controls
get { return Enumerable.Empty<ILogical>(); } get { return Enumerable.Empty<ILogical>(); }
} }
protected override void OnAttachedToVisualTree() protected override void OnAttachedToVisualTree(ILayoutRoot root)
{ {
IStyler styler = Locator.Current.GetService<IStyler>(); IStyler styler = Locator.Current.GetService<IStyler>();
styler.ApplyStyles(this); styler.ApplyStyles(this);
base.OnAttachedToVisualTree();
} }
protected void AddPseudoClass(PerspexProperty<bool> property, string className) protected void AddPseudoClass(PerspexProperty<bool> property, string className)

8
Perspex/Controls/Decorator.cs

@ -26,14 +26,14 @@ namespace Perspex.Controls
{ {
if (x.Item1 != null) if (x.Item1 != null)
{ {
((IVisual)x.Item1).VisualParent = null; ((IVisual)this).RemoveVisualChild(x.Item1);
((ILogical)x.Item1).LogicalParent = null; ((ILogical)this).RemoveLogicalChild(x.Item1);
} }
if (x.Item2 != null) if (x.Item2 != null)
{ {
((IVisual)x.Item2).VisualParent = this; ((IVisual)this).AddVisualChild(x.Item2);
((ILogical)x.Item2).LogicalParent = this; ((ILogical)this).AddLogicalChild(x.Item2);
} }
}); });
} }

2
Perspex/Controls/TemplatedControl.cs

@ -17,8 +17,6 @@ namespace Perspex.Controls
public static readonly PerspexProperty<ControlTemplate> TemplateProperty = public static readonly PerspexProperty<ControlTemplate> TemplateProperty =
PerspexProperty.Register<TemplatedControl, ControlTemplate>("Template"); PerspexProperty.Register<TemplatedControl, ControlTemplate>("Template");
private IVisual visualChild;
public ControlTemplate Template public ControlTemplate Template
{ {
get { return this.GetValue(TemplateProperty); } get { return this.GetValue(TemplateProperty); }

3
Perspex/Controls/TreeViewItem.cs

@ -46,9 +46,8 @@ namespace Perspex.Controls
} }
} }
protected override void OnAttachedToVisualTree() protected override void OnVisualParentChanged(IVisual oldParent)
{ {
base.OnAttachedToVisualTree();
this.parent = this.GetVisualAncestor<TreeView>(); this.parent = this.GetVisualAncestor<TreeView>();
} }
} }

18
Perspex/Diagnostics/Debug.cs

@ -1,12 +1,18 @@
using System; // -----------------------------------------------------------------------
using System.Collections.Generic; // <copyright file="Debug.cs" company="Steven Kirk">
using System.Linq; // Copyright 2014 MIT Licence. See licence.md for more information.
using System.Text; // </copyright>
using System.Threading.Tasks; // -----------------------------------------------------------------------
using Perspex.Controls;
namespace Perspex.Diagnostics namespace Perspex.Diagnostics
{ {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Controls;
public static class Debug public static class Debug
{ {
public static string PrintVisualTree(IVisual visual) public static string PrintVisualTree(IVisual visual)

14
Perspex/Diagnostics/DevTools.cs

@ -0,0 +1,14 @@
// -----------------------------------------------------------------------
// <copyright file="DevTools.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Diagnostics
{
using Perspex.Controls;
public class DevTools : Control
{
}
}

47
Perspex/IVisual.cs

@ -6,28 +6,61 @@
namespace Perspex namespace Perspex
{ {
using System;
using System.Collections.Generic;
using Perspex.Media; using Perspex.Media;
/// <summary>
/// Represents a node in the visual scene graph.
/// </summary>
/// <remarks>
/// The <see cref="IVisual"/> interface defines the interface required for a renderer to
/// render a scene graph. You should not usually need to reference this interface unless
/// you are writing a renderer; instead use the extension methods defined in
/// <see cref="VisualExtensions"/> to traverse the scene graph. This interface is
/// implemented by <see cref="Visual"/>. It should not be necessary to implement it
/// anywhere else.
/// </remarks>
public interface IVisual public interface IVisual
{ {
Rect Bounds { get; set; } /// <summary>
/// Gets the bounds of the scene graph node.
IEnumerable<IVisual> ExistingVisualChildren { get; } /// </summary>
/// <returns></returns>
Rect Bounds { get; }
/// <summary>
/// Gets a value indicating whether this scene graph node is visible.
/// </summary>
bool IsVisible { get; } bool IsVisible { get; }
/// <summary>
/// Gets the opacity of the scene graph node.
/// </summary>
double Opacity { get; } double Opacity { get; }
/// <summary>
/// Gets the render transform of the scene graph node.
/// </summary>
Transform RenderTransform { get; } Transform RenderTransform { get; }
/// <summary>
/// Gets the transform origin of the scene graph node.
/// </summary>
Origin TransformOrigin { get; } Origin TransformOrigin { get; }
IEnumerable<IVisual> VisualChildren { get; } /// <summary>
/// Gets the scene graph node's child nodes.
/// </summary>
PerspexList<IVisual> VisualChildren { get; }
IVisual VisualParent { get; set; } /// <summary>
/// Gets the scene graph node's parent node.
/// </summary>
IVisual VisualParent { get; }
/// <summary>
/// Renders the scene graph node to a <see cref="IDrawingContext"/>.
/// </summary>
/// <param name="context">The context.</param>
void Render(IDrawingContext context); void Render(IDrawingContext context);
} }
} }

2
Perspex/Input/IInputElement.cs

@ -31,5 +31,7 @@ namespace Perspex.Input
bool IsPointerOver { get; } bool IsPointerOver { get; }
void Focus(); void Focus();
void RaiseEvent(RoutedEventArgs e);
} }
} }

3
Perspex/Input/InputElement.cs

@ -37,6 +37,9 @@ namespace Perspex.Input
public static readonly RoutedEvent<KeyEventArgs> KeyDownEvent = public static readonly RoutedEvent<KeyEventArgs> KeyDownEvent =
RoutedEvent.Register<InputElement, KeyEventArgs>("KeyDown", RoutingStrategy.Bubble); RoutedEvent.Register<InputElement, KeyEventArgs>("KeyDown", RoutingStrategy.Bubble);
public static readonly RoutedEvent<KeyEventArgs> PreviewKeyDownEvent =
RoutedEvent.Register<InputElement, KeyEventArgs>("PreviewKeyDown", RoutingStrategy.Tunnel);
public static readonly RoutedEvent<PointerEventArgs> PointerEnterEvent = public static readonly RoutedEvent<PointerEventArgs> PointerEnterEvent =
RoutedEvent.Register<InputElement, PointerEventArgs>("PointerEnter", RoutingStrategy.Direct); RoutedEvent.Register<InputElement, PointerEventArgs>("PointerEnter", RoutingStrategy.Direct);

25
Perspex/Input/KeyboardDevice.cs

@ -33,25 +33,40 @@ namespace Perspex.Input
get { return Locator.Current.GetService<IFocusManager>(); } get { return Locator.Current.GetService<IFocusManager>(); }
} }
public IInputElement FocusedElement
{
get;
protected set;
}
public abstract ModifierKeys Modifiers { get; } public abstract ModifierKeys Modifiers { get; }
private void ProcessRawEvent(RawKeyEventArgs e) private void ProcessRawEvent(RawKeyEventArgs e)
{ {
Interactive interactive = FocusManager.Current as Interactive; IInputElement element = this.FocusedElement;
if (interactive != null) if (element != null)
{ {
switch (e.Type) switch (e.Type)
{ {
case RawKeyEventType.KeyDown: case RawKeyEventType.KeyDown:
interactive.RaiseEvent(new KeyEventArgs element.RaiseEvent(new KeyEventArgs
{
RoutedEvent = Control.PreviewKeyDownEvent,
Device = this,
Key = e.Key,
Text = e.Text,
Source = element,
OriginalSource = element,
});
element.RaiseEvent(new KeyEventArgs
{ {
RoutedEvent = Control.KeyDownEvent, RoutedEvent = Control.KeyDownEvent,
Device = this, Device = this,
Key = e.Key, Key = e.Key,
Text = e.Text, Text = e.Text,
Source = interactive, Source = element,
OriginalSource = interactive, OriginalSource = element,
}); });
break; break;
} }

30
Perspex/Interactive.cs

@ -8,6 +8,7 @@ namespace Perspex
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using Perspex.Layout; using Perspex.Layout;
@ -68,8 +69,9 @@ namespace Perspex
case RoutingStrategy.Direct: case RoutingStrategy.Direct:
this.RaiseEventImpl(e); this.RaiseEventImpl(e);
break; break;
default: case RoutingStrategy.Tunnel:
throw new NotImplementedException(); this.TunnelEvent(e);
break;
} }
} }
} }
@ -78,12 +80,29 @@ namespace Perspex
{ {
Contract.Requires<NullReferenceException>(e != null); Contract.Requires<NullReferenceException>(e != null);
Interactive target = this; foreach (var target in this.GetVisualAncestorsAndSelf().OfType<Interactive>())
{
target.RaiseEventImpl(e);
if (e.Handled)
{
break;
}
}
}
private void TunnelEvent(RoutedEventArgs e)
{
Contract.Requires<NullReferenceException>(e != null);
while (target != null) foreach (var target in this.GetVisualAncestorsAndSelf().OfType<Interactive>().Reverse())
{ {
target.RaiseEventImpl(e); target.RaiseEventImpl(e);
target = target.GetVisualAncestor<Interactive>();
if (e.Handled)
{
break;
}
} }
} }
@ -97,7 +116,6 @@ namespace Perspex
{ {
foreach (Delegate handler in delegates) foreach (Delegate handler in delegates)
{ {
// TODO: Implement the Handled stuff.
handler.DynamicInvoke(this, e); handler.DynamicInvoke(this, e);
} }
} }

1
Perspex/Perspex.csproj

@ -101,6 +101,7 @@
<Compile Include="Controls\LogicalChildren.cs" /> <Compile Include="Controls\LogicalChildren.cs" />
<Compile Include="Controls\Panel.cs" /> <Compile Include="Controls\Panel.cs" />
<Compile Include="Controls\StackPanel.cs" /> <Compile Include="Controls\StackPanel.cs" />
<Compile Include="Diagnostics\DevTools.cs" />
<Compile Include="ICloseable.cs" /> <Compile Include="ICloseable.cs" />
<Compile Include="IHeadered.cs" /> <Compile Include="IHeadered.cs" />
<Compile Include="Diagnostics\Debug.cs" /> <Compile Include="Diagnostics\Debug.cs" />

81
Perspex/Visual.cs

@ -8,6 +8,7 @@ namespace Perspex
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using Perspex.Layout; using Perspex.Layout;
using Perspex.Media; using Perspex.Media;
@ -28,10 +29,12 @@ namespace Perspex
public static readonly PerspexProperty<Origin> TransformOriginProperty = public static readonly PerspexProperty<Origin> TransformOriginProperty =
PerspexProperty.Register<Visual, Origin>("TransformOrigin", defaultValue: Origin.Default); PerspexProperty.Register<Visual, Origin>("TransformOrigin", defaultValue: Origin.Default);
private IVisual visualParent;
private Rect bounds; private Rect bounds;
private PerspexList<IVisual> visualChildren;
private IVisual visualParent;
static Visual() static Visual()
{ {
AffectsRender(IsVisibleProperty); AffectsRender(IsVisibleProperty);
@ -69,38 +72,28 @@ namespace Perspex
IEnumerable<IVisual> IVisual.ExistingVisualChildren IEnumerable<IVisual> IVisual.ExistingVisualChildren
{ {
get { return ((IVisual)this).VisualChildren; } get { return this.visualChildren != null ? this.visualChildren : Enumerable.Empty<IVisual>(); }
} }
IEnumerable<IVisual> IVisual.VisualChildren PerspexList<IVisual> IVisual.VisualChildren
{
get { return Enumerable.Empty<Visual>(); }
}
IVisual IVisual.VisualParent
{ {
get get
{
return this.visualParent;
}
set
{ {
if (this.visualParent != value) if (this.visualChildren == null)
{ {
IVisual oldValue = this.visualParent; this.visualChildren = new PerspexList<IVisual>(this.CreateVisualChildren());
this.visualParent = value; this.visualChildren.CollectionChanged += VisualChildrenChanged;
this.InheritanceParent = (PerspexObject)value;
this.OnVisualParentChanged(oldValue, value);
if (this.GetVisualAncestor<ILayoutRoot>() != null)
{
this.NotifyAttachedToVisualTree();
}
} }
return this.visualChildren;
} }
} }
IVisual IVisual.VisualParent
{
get { return this.visualParent; }
}
protected static void AffectsRender(PerspexProperty property) protected static void AffectsRender(PerspexProperty property)
{ {
property.Changed.Subscribe(AffectsRenderInvalidate); property.Changed.Subscribe(AffectsRenderInvalidate);
@ -131,26 +124,54 @@ namespace Perspex
Contract.Requires<ArgumentNullException>(context != null); Contract.Requires<ArgumentNullException>(context != null);
} }
protected virtual void OnAttachedToVisualTree() private IEnumerable<IVisual> CreateVisualChildren()
{
return Enumerable.Empty<IVisual>();
}
protected virtual void OnAttachedToVisualTree(ILayoutRoot root)
{ {
} }
protected virtual void OnVisualParentChanged(IVisual oldValue, IVisual newValue) protected virtual void OnDetachedFromVisualTree(ILayoutRoot oldRoot)
{ {
} }
private void NotifyAttachedToVisualTree() protected virtual void OnVisualParentChanged(IVisual oldParent)
{
}
private void VisualChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
{
}
private void NotifyAttachedToVisualTree(ILayoutRoot root)
{ {
this.Log().Debug(string.Format( this.Log().Debug(string.Format(
"Attached {0} (#{1:x8}) to visual tree", "Attached {0} (#{1:x8}) to visual tree",
this.GetType().Name, this.GetType().Name,
this.GetHashCode())); this.GetHashCode()));
this.OnAttachedToVisualTree(); this.OnAttachedToVisualTree(root);
foreach (Visual child in ((IVisual)this).ExistingVisualChildren.OfType<Visual>())
{
child.NotifyAttachedToVisualTree(root);
}
}
private void NotifyDetachedFromVisualTree(ILayoutRoot oldRoot)
{
this.Log().Debug(string.Format(
"Detached {0} (#{1:x8}) from visual tree",
this.GetType().Name,
this.GetHashCode()));
this.OnDetachedFromVisualTree(oldRoot);
foreach (Visual child in ((IVisual)this).ExistingVisualChildren.OfType<Visual>()) foreach (Visual child in ((IVisual)this).ExistingVisualChildren.OfType<Visual>())
{ {
child.NotifyAttachedToVisualTree(); child.NotifyDetachedFromVisualTree(oldRoot);
} }
} }
} }

Loading…
Cancel
Save