Added wooting layout images

Added timeline (WIP)
This commit is contained in:
SpoinkyNL committed 2020-01-01 23:12:55 +01:00
1 parent 9df2eb0f9c
commit 5d340199cc
124 files changed
+494 -67

No files matched your search

@@ -0,0 +1,148 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.Controls
{
public class TimelineTime : FrameworkElement
{
public static readonly DependencyProperty FillProperty = DependencyProperty.Register(nameof(Fill), typeof(Brush), typeof(TimelineTime),
new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register(nameof(FontFamily), typeof(FontFamily), typeof(TimelineTime),
new FrameworkPropertyMetadata(TextBlock.FontFamilyProperty.DefaultMetadata.DefaultValue, FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty PixelsPerSecondProperty = DependencyProperty.Register(nameof(PixelsPerSecond), typeof(int), typeof(TimelineTime),
new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty FrameStartProperty = DependencyProperty.Register(nameof(FrameStart), typeof(int), typeof(TimelineTime),
new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.AffectsRender));
private double _subd1;
private double _subd2;
private double _subd3;
public Brush Fill
{
get => (Brush) GetValue(FillProperty);
set => SetValue(FillProperty, value);
}
public FontFamily FontFamily
{
get => (FontFamily) GetValue(FontFamilyProperty);
set => SetValue(FontFamilyProperty, value);
}
public int PixelsPerSecond
{
get => (int) GetValue(PixelsPerSecondProperty);
set => SetValue(PixelsPerSecondProperty, value);
}
public int FrameStart
{
get => (int) GetValue(FrameStartProperty);
set => SetValue(FrameStartProperty, value);
}
// TODO: Does this get called when the size changes?
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
UpdateTimeScale();
var linePen = new Pen(Fill, 1);
var width = RenderSize.Width;
var units = PixelsPerSecond / _subd1;
var offsetUnits = FrameStart * PixelsPerSecond % units;
// Labels
var count = (width + offsetUnits) / units;
for (var i = 0; i < count; i++)
{
var x = i * units - offsetUnits;
var t = TimeSpan.FromSeconds((i * units - offsetUnits) / PixelsPerSecond + FrameStart);
if (PixelsPerSecond > 200)
RenderLabel(drawingContext, $"{Math.Floor(t.TotalSeconds):00}.{t.Milliseconds:000}", x);
else if (PixelsPerSecond > 60)
RenderLabel(drawingContext, $"{Math.Floor(t.TotalSeconds):00}.{t.Milliseconds:000}", x);
else
RenderLabel(drawingContext, $"{Math.Floor(t.TotalMinutes):0}:{t.Seconds:00}", x);
}
// Large ticks
units = PixelsPerSecond / _subd2;
count = (width + offsetUnits) / units;
for (var i = 0; i < count; i++)
{
var x = i * units - offsetUnits;
drawingContext.DrawLine(linePen, new Point(x, 15), new Point(x, 30));
}
// Small ticks
var mul = _subd3 / _subd2;
units = PixelsPerSecond / _subd3;
count = (width + offsetUnits) / units;
for (var i = 0; i < count; i++)
{
if (Math.Abs(i % mul) < 0.001) continue;
var x = i * units - offsetUnits;
drawingContext.DrawLine(linePen, new Point(x, 22), new Point(x, 30));
}
}
private void RenderLabel(DrawingContext drawingContext, string text, double x)
{
var typeFace = new Typeface(FontFamily, new FontStyle(), new FontWeight(), new FontStretch());
var formattedText = new FormattedText(text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, typeFace, 9, Fill, null, VisualTreeHelper.GetDpi(this).PixelsPerDip);
drawingContext.DrawText(formattedText, new Point(x, 0));
}
private void UpdateTimeScale()
{
object[] subds;
if (PixelsPerSecond > 350)
subds = new object[] {12d, 12d, 60d};
else if (PixelsPerSecond > 250)
subds = new object[] {6d, 12d, 60d};
else if (PixelsPerSecond > 200)
subds = new object[] {6d, 6d, 30d};
else if (PixelsPerSecond > 150)
subds = new object[] {4d, 4d, 20d};
else if (PixelsPerSecond > 100)
subds = new object[] {4d, 4d, 8d};
else if (PixelsPerSecond > 90)
subds = new object[] {4d, 4d, 8d};
else if (PixelsPerSecond > 60)
subds = new object[] {2d, 4d, 8d};
else if (PixelsPerSecond > 40)
subds = new object[] {1d, 2d, 10d};
else if (PixelsPerSecond > 30)
subds = new object[] {1d, 2d, 10d};
else if (PixelsPerSecond > 10)
subds = new object[] {1d / 2d, 1d / 2d, 1d / 2d};
else if (PixelsPerSecond > 4)
subds = new object[] {1d / 5d, 1d / 5d, 1d / 5d};
else if (PixelsPerSecond > 3)
subds = new object[] {1d / 10d, 1d / 10d, 1d / 5d};
else if (PixelsPerSecond > 1)
subds = new object[] {1d / 20d, 1d / 20d, 1d / 10d};
else if (PixelsPerSecond >= 1)
subds = new object[] {1d / 30d, 1d / 30d, 1d / 15d};
else
{
// 1s per pixel
subds = new object[] {1d / 60d, 1d / 60d, 1d / 15d};
}
_subd1 = (double) subds[0]; // big ticks / labels
_subd2 = (double) subds[1]; // medium ticks
_subd3 = (double) subds[2]; // small ticks
}
}
}
@@ -1,12 +1,83 @@
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.LayerPropertiesTimelineView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:timeline="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:controls="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance timeline:LayerPropertiesTimelineViewModel}">
<UserControl.Resources>
<Style x:Key="ItemsControlVirtualizedStyle" TargetType="ItemsControl">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border
BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer x:Name="Keyframes"
Grid.Row="0"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Hidden"
Padding="5 0 5 0">
<StackPanel>
<controls:TimelineTime Height="30" Fill="{StaticResource MaterialDesignBody}" PixelsPerSecond="{Binding PixelsPerSecond}"/>
<ItemsControl ItemsSource="{Binding TimelinePropertyRailViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
<StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Right">
<TextBlock Text="{Binding PixelsPerSecond}" />
<Slider Grid.Row="2"
Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="10"
TickFrequency="5"
Minimum="1"
Maximum="600"
Value="{Binding PixelsPerSecond}"
Width="600" />
</StackPanel>
</Grid>
</UserControl>
</UserControl>
@@ -25,4 +25,4 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
InitializeComponent();
}
}
}
}
@@ -1,12 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
class LayerPropertiesTimelineViewModel
public class LayerPropertiesTimelineViewModel : PropertyChangedBase
{
private int _pixelsPerSecond = 1;
public LayerPropertiesTimelineViewModel()
{
TimelinePropertyRailViewModels = new BindableCollection<TimelinePropertyRailViewModel>();
CreateTestValues();
Update();
}
public int PixelsPerSecond
{
get => _pixelsPerSecond;
set
{
_pixelsPerSecond = value;
Update();
}
}
public BindableCollection<TimelinePropertyRailViewModel> TimelinePropertyRailViewModels { get; set; }
private void CreateTestValues()
{
var propertyRailViewModels = new List<TimelinePropertyRailViewModel>();
for (var i = 0; i < 20; i++)
propertyRailViewModels.Add(new TimelinePropertyRailViewModel());
TimelinePropertyRailViewModels.AddRange(propertyRailViewModels);
}
public void Update()
{
foreach (var timelinePropertyRailViewModel in TimelinePropertyRailViewModels)
timelinePropertyRailViewModel.Update(PixelsPerSecond);
}
}
}
}
@@ -0,0 +1,11 @@
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.TimelineKeyframeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50"
d:DataContext="{d:DesignInstance local:TimelineKeyframeViewModel}">
<Ellipse Fill="{StaticResource PrimaryHueMidBrush}" Width="10" Height="10" Margin="-5,6,0,0" ToolTip="{Binding Timestamp}"></Ellipse>
</UserControl>
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
/// <summary>
/// Interaction logic for TimelineKeyframeView.xaml
/// </summary>
public partial class TimelineKeyframeView : UserControl
{
public TimelineKeyframeView()
{
InitializeComponent();
}
}
}
@@ -0,0 +1,23 @@
using System;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
public class TimelineKeyframeViewModel : PropertyChangedBase
{
private const double BaseSize = 60.0;
public TimeSpan Position { get; set; }
public double X { get; set; }
public string Timestamp { get; set; }
public void Update(int pixelsPerSecond)
{
// var timelinePartWidth = pixelsPerSecond % BaseSize + BaseSize;
// var millisecondsPerPart = extraParts > 0 ? BaseSize * 1000 / extraParts : BaseSize * 1000;
X = pixelsPerSecond * Position.TotalSeconds;
Timestamp = $"{Math.Floor(Position.TotalSeconds):00}.{Position.Milliseconds:000}";
}
}
}
@@ -0,0 +1,31 @@
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.TimelinePropertyRailView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:TimelinePropertyRailViewModel}">
<Border BorderThickness="0,1" BorderBrush="{StaticResource MaterialDesignTextAreaBorder}" Height="25" Margin="0,0,0,-1">
<ItemsControl ItemsSource="{Binding TimelineKeyframeViewModels}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</UserControl>
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
/// <summary>
/// Interaction logic for TimelinePropertyRailView.xaml
/// </summary>
public partial class TimelinePropertyRailView : UserControl
{
public TimelinePropertyRailView()
{
InitializeComponent();
}
}
}
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
public class TimelinePropertyRailViewModel : PropertyChangedBase
{
public TimelinePropertyRailViewModel()
{
TimelineKeyframeViewModels = new BindableCollection<TimelineKeyframeViewModel>();
CreateTestValues();
}
public BindableCollection<TimelineKeyframeViewModel> TimelineKeyframeViewModels { get; set; }
public void CreateTestValues()
{
var keyframeViewModels = new List<TimelineKeyframeViewModel>();
for (var i = 0; i < 20; i++)
{
keyframeViewModels.Add(new TimelineKeyframeViewModel());
keyframeViewModels[i].Position = TimeSpan.FromSeconds(i);
}
TimelineKeyframeViewModels.AddRange(keyframeViewModels);
}
public void Update(int pixelsPerSecond)
{
foreach (var timelineKeyframeViewModel in TimelineKeyframeViewModels)
timelineKeyframeViewModel.Update(pixelsPerSecond);
if (pixelsPerSecond == 10)
Console.WriteLine();
}
}
}