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)
{

16
Perspex.Windows/Window.cs

@ -80,6 +80,8 @@ namespace Perspex.Windows
});
}
public event EventHandler Activated;
public event EventHandler Closed;
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()
{
if (this.Closed != null)
@ -190,6 +202,10 @@ namespace Perspex.Windows
switch ((UnmanagedMethods.WindowsMessage)msg)
{
case UnmanagedMethods.WindowsMessage.WM_ACTIVATE:
this.OnActivated();
break;
case UnmanagedMethods.WindowsMessage.WM_DESTROY:
this.OnClosed();
break;

1
Perspex/Application.cs

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

4
Perspex/Controls/Control.cs

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

8
Perspex/Controls/Decorator.cs

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

2
Perspex/Controls/TemplatedControl.cs

@ -17,8 +17,6 @@ namespace Perspex.Controls
public static readonly PerspexProperty<ControlTemplate> TemplateProperty =
PerspexProperty.Register<TemplatedControl, ControlTemplate>("Template");
private IVisual visualChild;
public ControlTemplate Template
{
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>();
}
}

18
Perspex/Diagnostics/Debug.cs

@ -1,12 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Controls;
// -----------------------------------------------------------------------
// <copyright file="Debug.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
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 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
{
using System;
using System.Collections.Generic;
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
{
Rect Bounds { get; set; }
IEnumerable<IVisual> ExistingVisualChildren { get; }
/// <summary>
/// Gets the bounds of the scene graph node.
/// </summary>
/// <returns></returns>
Rect Bounds { get; }
/// <summary>
/// Gets a value indicating whether this scene graph node is visible.
/// </summary>
bool IsVisible { get; }
/// <summary>
/// Gets the opacity of the scene graph node.
/// </summary>
double Opacity { get; }
/// <summary>
/// Gets the render transform of the scene graph node.
/// </summary>
Transform RenderTransform { get; }
/// <summary>
/// Gets the transform origin of the scene graph node.
/// </summary>
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);
}
}

2
Perspex/Input/IInputElement.cs

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

3
Perspex/Input/InputElement.cs

@ -37,6 +37,9 @@ namespace Perspex.Input
public static readonly RoutedEvent<KeyEventArgs> KeyDownEvent =
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 =
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>(); }
}
public IInputElement FocusedElement
{
get;
protected set;
}
public abstract ModifierKeys Modifiers { get; }
private void ProcessRawEvent(RawKeyEventArgs e)
{
Interactive interactive = FocusManager.Current as Interactive;
IInputElement element = this.FocusedElement;
if (interactive != null)
if (element != null)
{
switch (e.Type)
{
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,
Device = this,
Key = e.Key,
Text = e.Text,
Source = interactive,
OriginalSource = interactive,
Source = element,
OriginalSource = element,
});
break;
}

30
Perspex/Interactive.cs

@ -8,6 +8,7 @@ namespace Perspex
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using Perspex.Layout;
@ -68,8 +69,9 @@ namespace Perspex
case RoutingStrategy.Direct:
this.RaiseEventImpl(e);
break;
default:
throw new NotImplementedException();
case RoutingStrategy.Tunnel:
this.TunnelEvent(e);
break;
}
}
}
@ -78,12 +80,29 @@ namespace Perspex
{
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 = target.GetVisualAncestor<Interactive>();
if (e.Handled)
{
break;
}
}
}
@ -97,7 +116,6 @@ namespace Perspex
{
foreach (Delegate handler in delegates)
{
// TODO: Implement the Handled stuff.
handler.DynamicInvoke(this, e);
}
}

1
Perspex/Perspex.csproj

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

81
Perspex/Visual.cs

@ -8,6 +8,7 @@ namespace Perspex
{
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Perspex.Layout;
using Perspex.Media;
@ -28,10 +29,12 @@ namespace Perspex
public static readonly PerspexProperty<Origin> TransformOriginProperty =
PerspexProperty.Register<Visual, Origin>("TransformOrigin", defaultValue: Origin.Default);
private IVisual visualParent;
private Rect bounds;
private PerspexList<IVisual> visualChildren;
private IVisual visualParent;
static Visual()
{
AffectsRender(IsVisibleProperty);
@ -69,38 +72,28 @@ namespace Perspex
IEnumerable<IVisual> IVisual.ExistingVisualChildren
{
get { return ((IVisual)this).VisualChildren; }
get { return this.visualChildren != null ? this.visualChildren : Enumerable.Empty<IVisual>(); }
}
IEnumerable<IVisual> IVisual.VisualChildren
{
get { return Enumerable.Empty<Visual>(); }
}
IVisual IVisual.VisualParent
PerspexList<IVisual> IVisual.VisualChildren
{
get
{
return this.visualParent;
}
set
get
{
if (this.visualParent != value)
if (this.visualChildren == null)
{
IVisual oldValue = this.visualParent;
this.visualParent = value;
this.InheritanceParent = (PerspexObject)value;
this.OnVisualParentChanged(oldValue, value);
if (this.GetVisualAncestor<ILayoutRoot>() != null)
{
this.NotifyAttachedToVisualTree();
}
this.visualChildren = new PerspexList<IVisual>(this.CreateVisualChildren());
this.visualChildren.CollectionChanged += VisualChildrenChanged;
}
return this.visualChildren;
}
}
IVisual IVisual.VisualParent
{
get { return this.visualParent; }
}
protected static void AffectsRender(PerspexProperty property)
{
property.Changed.Subscribe(AffectsRenderInvalidate);
@ -131,26 +124,54 @@ namespace Perspex
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(
"Attached {0} (#{1:x8}) to visual tree",
this.GetType().Name,
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>())
{
child.NotifyAttachedToVisualTree();
child.NotifyDetachedFromVisualTree(oldRoot);
}
}
}

Loading…
Cancel
Save