public ZoomableTimeline()
{
InitializeComponent();
Loaded += (_, __) => RebuildAll();
SizeChanged += (_, __) => Redraw();
}
private void RebuildAll()
{
// Set the total content width so we can scroll
var width = Math.Max(0, TotalTicks * PixelsPerTick);
TicksCanvas.Width = width;
BlocksSurface.Width = width;
RedrawTicks();
}
private void Redraw() => RebuildAll();
private double ViewportWidth() => PART_Scroll?.ViewportWidth > 0 ? PART_Scroll.ViewportWidth : ActualWidth;
private Point? _dragStart;
private double _dragOriginOffset;
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
_dragStart = e.GetPosition(PART_Scroll);
_dragOriginOffset = PART_Scroll.HorizontalOffset;
Mouse.Capture((IInputElement)sender);
}
}
private void OnPreviewMouseMove(object sender, MouseEventArgs e)
{
if (_dragStart is Point start && e.LeftButton == MouseButtonState.Pressed)
{
var cur = e.GetPosition(PART_Scroll);
var dx = cur.X - start.X;
PART_Scroll.ScrollToHorizontalOffset(Math.Max(0, _dragOriginOffset + dx));
RedrawTicks(); // redraws the ticks/labels as panning/scrolling
}
}
private void OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
_dragStart = null;
Mouse.Capture(null);
}
}
// zooms into/out of the canvas
private void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
// calls RebuildAll()
}
public ZoomableTimeline()
{
InitializeComponent();
Loaded += (_, __) => RebuildAll();
SizeChanged += (_, __) => Redraw();
}
private void RebuildAll()
{
// Set the total content width so we can scroll
var width = Math.Max(0, TotalTicks * PixelsPerTick);
TicksCanvas.Width = width;
BlocksSurface.Width = width;
RedrawTicks();
}
private void Redraw() => RebuildAll();
private double ViewportWidth() => PART_Scroll?.ViewportWidth > 0 ? PART_Scroll.ViewportWidth : ActualWidth;
private Point? _dragStart;
private double _dragOriginOffset;
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
_dragStart = e.GetPosition(PART_Scroll);
_dragOriginOffset = PART_Scroll.HorizontalOffset;
Mouse.Capture((IInputElement)sender);
}
}
private void OnPreviewMouseMove(object sender, MouseEventArgs e)
{
if (_dragStart is Point start && e.LeftButton == MouseButtonState.Pressed)
{
var cur = e.GetPosition(PART_Scroll);
var dx = cur.X - start.X;
PART_Scroll.ScrollToHorizontalOffset(Math.Max(0, _dragOriginOffset + dx));
RedrawTicks(); // redraws the ticks/labels as panning/scrolling
}
}
private void OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
_dragStart = null;
Mouse.Capture(null);
}
}
// zooms into/out of the canvas
private void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
// calls RebuildAll()
}