1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Added timeline scrolling

Added timeline caret
This commit is contained in:
Robert 2020-01-02 19:27:16 +01:00
parent 884bd0f03b
commit 615f5b0b40
6 changed files with 81 additions and 58 deletions

View File

@ -18,13 +18,17 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.Contr
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));
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(TimelineTime),
new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty VisibleWidthProperty = DependencyProperty.Register(nameof(VisibleWidth), typeof(double), typeof(TimelineTime),
new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsRender));
private double _subd1;
private double _subd2;
private double _subd3;
public Brush Fill
{
get => (Brush) GetValue(FillProperty);
@ -43,31 +47,45 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.Contr
set => SetValue(PixelsPerSecondProperty, value);
}
public int FrameStart
public double HorizontalOffset
{
get => (int) GetValue(FrameStartProperty);
set => SetValue(FrameStartProperty, value);
get => (double) GetValue(HorizontalOffsetProperty);
set => SetValue(HorizontalOffsetProperty, value);
}
public double VisibleWidth
{
get => (double) GetValue(VisibleWidthProperty);
set => SetValue(VisibleWidthProperty, value);
}
// TODO: Does this get called when the size changes?
protected override void OnRender(DrawingContext drawingContext)
{
SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
base.OnRender(drawingContext);
UpdateTimeScale();
var linePen = new Pen(Fill, 1);
var width = RenderSize.Width;
var width = HorizontalOffset + VisibleWidth;
var frameStart = 0;
var units = PixelsPerSecond / _subd1;
var offsetUnits = FrameStart * PixelsPerSecond % units;
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)
var x = i * units - offsetUnits + 1;
// Add a 100px margin to allow the text to partially render when needed
if (x < HorizontalOffset - 100 || x > HorizontalOffset + width)
continue;
var t = TimeSpan.FromSeconds((i * units - offsetUnits) / PixelsPerSecond + frameStart);
// 0.00 is always formatted as 0.00
if (t == TimeSpan.Zero)
RenderLabel(drawingContext, "0.00", x);
else 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);
@ -80,8 +98,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.Contr
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));
var x = i * units - offsetUnits + 1;
if (x > HorizontalOffset && x < HorizontalOffset + width)
drawingContext.DrawLine(linePen, new Point(x, 20), new Point(x, 30));
}
// Small ticks
@ -91,8 +110,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.Contr
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));
var x = i * units - offsetUnits + 1;
if (x > HorizontalOffset && x < HorizontalOffset + width)
drawingContext.DrawLine(linePen, new Point(x, 25), new Point(x, 30));
}
}
@ -100,7 +120,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.Contr
{
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));
if (x == 1)
drawingContext.DrawText(formattedText, new Point(x, 2));
else
drawingContext.DrawText(formattedText, new Point(x - formattedText.Width /2, 2));
}
private void UpdateTimeScale()

View File

@ -9,36 +9,6 @@
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="*" />
@ -48,15 +18,24 @@
<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}"/>
VerticalScrollBarVisibility="Hidden">
<StackPanel x:Name="KeyframesContainer">
<!-- Time caret -->
<Canvas ZIndex="10" Height="25" Margin="{Binding TimeCaretPosition}">
<Polygon Points="-10,0 0,20, 10,00" Fill="{StaticResource SecondaryAccentBrush}" />
<Line X1="0" X2="0" Y1="0" Y2="10000" StrokeThickness="2" Stroke="{StaticResource SecondaryAccentBrush}" />
</Canvas>
<!-- Time -->
<controls:TimelineTime Height="30"
Fill="{DynamicResource MaterialDesignBody}"
PixelsPerSecond="{Binding PixelsPerSecond}"
HorizontalOffset="{Binding ContentHorizontalOffset, ElementName=Keyframes}"
VisibleWidth="{Binding ActualWidth, ElementName=Keyframes}" />
<!-- Keyframes -->
<ItemsControl ItemsSource="{Binding TimelinePropertyRailViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" />
<ContentControl s:View.Model="{Binding}" HorizontalAlignment="Stretch" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

View File

@ -1,4 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Markup;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
@ -11,6 +14,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
TimelinePropertyRailViewModels = new BindableCollection<TimelinePropertyRailViewModel>();
TimeCaretTime = TimeSpan.FromSeconds(3);
CreateTestValues();
Update();
}
@ -25,6 +29,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
}
public TimeSpan TimeCaretTime { get; set; }
public Thickness TimeCaretPosition
{
get => new Thickness(TimeCaretTime.TotalSeconds * PixelsPerSecond, 0, 0, 0);
set => TimeCaretTime = TimeSpan.FromSeconds(value.Left / PixelsPerSecond);
}
public BindableCollection<TimelinePropertyRailViewModel> TimelinePropertyRailViewModels { get; set; }
private void CreateTestValues()

View File

@ -9,8 +9,12 @@
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}">
<Border BorderThickness="0,1" BorderBrush="{DynamicResource MaterialDesignDivider}" Height="25" Margin="0,0,0,-1">
<ItemsControl ItemsSource="{Binding TimelineKeyframeViewModels}"
Width="{Binding Width}"
MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}}"
Background="{DynamicResource MaterialDesignToolBarBackground}"
HorizontalAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
@ -13,6 +14,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
public BindableCollection<TimelineKeyframeViewModel> TimelineKeyframeViewModels { get; set; }
public double Width { get; set; }
public void CreateTestValues()
{
@ -31,8 +33,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
foreach (var timelineKeyframeViewModel in TimelineKeyframeViewModels)
timelineKeyframeViewModel.Update(pixelsPerSecond);
if (pixelsPerSecond == 10)
Console.WriteLine();
// End time is the last keyframe + 10 sec
var lastKeyFrame = TimelineKeyframeViewModels.OrderByDescending(t => t.Position).FirstOrDefault();
var endTime = lastKeyFrame?.Position.Add(new TimeSpan(0, 0, 0, 10)) ?? TimeSpan.FromSeconds(10);
Width = endTime.TotalSeconds * pixelsPerSecond;
}
}
}

View File

@ -126,7 +126,7 @@ namespace Artemis.UI.Screens.Settings
{
_windowManager.ShowWindow(_kernel.Get<DebugViewModel>());
}
public void ShowLogsFolder()
{
Process.Start(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"));