using java.security; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; 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.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace InABox.WPF; /// /// Interaction logic for ZoomPanel.xaml /// public partial class ZoomPanel : ContentControl, INotifyPropertyChanged { public delegate void AreaChangedHandler(ZoomPanel panel); public event AreaChangedHandler? AreaChanged; private bool _showNavigationButtons = false; public bool ShowNavigationButtons { get => _showNavigationButtons; set { _showNavigationButtons = value; OnPropertyChanged(); } } public double _minScale = 0.5; public double MinScale { get => _minScale; set { _minScale = value; if(_scale < _minScale) { Scale = _minScale; } } } public double _scale = 1; public double Scale { get => _scale; set { _scale = value; OnPropertyChanged(); AreaChanged?.Invoke(this); } } private ScrollViewer Scroll => (ScrollViewer)GetTemplateChild("PART_Scroll"); private Border ContentBorder => (Border)GetTemplateChild("PART_ContentBorder"); public double ScrollX { get => Scroll.HorizontalOffset; set { Scroll.ScrollToHorizontalOffset(value); AreaChanged?.Invoke(this); } } public double ScrollY { get => Scroll.VerticalOffset; set { Scroll.ScrollToVerticalOffset(value); AreaChanged?.Invoke(this); } } public double WheelSpeed { get; set; } = 0.002; public double PanAmount { get; set; } = 50; static ZoomPanel() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ZoomPanel), new FrameworkPropertyMetadata(typeof(ZoomPanel))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); ((Button)GetTemplateChild("PART_ZoomInButton")).Click += ZoomInButton_Click; ((Button)GetTemplateChild("PART_ZoomOutButton")).Click += ZoomOutButton_Click; ((Button)GetTemplateChild("PART_LeftButton")).Click += LeftButton_Click; ((Button)GetTemplateChild("PART_RightButton")).Click += RightButton_Click; ((Button)GetTemplateChild("PART_UpButton")).Click += UpButton_Click; ((Button)GetTemplateChild("PART_DownButton")).Click += DownButton_Click; ((Button)GetTemplateChild("PART_DownButton")).Click += DownButton_Click; ((Border)GetTemplateChild("PART_ContentBorder")).MouseWheel += ItemsControl_MouseWheel; } public event PropertyChangedEventHandler? PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private void ZoomInButton_Click(object sender, RoutedEventArgs e) { Scale *= 1.1; } private void ZoomOutButton_Click(object sender, RoutedEventArgs e) { Scale /= 1.1; } private void Pan(double x, double y) { ScrollX += x; ScrollY += y; //Origin = new(Origin.X - x, Origin.Y - y); } private void DownButton_Click(object sender, RoutedEventArgs e) { Pan(0, PanAmount); } private void UpButton_Click(object sender, RoutedEventArgs e) { Pan(0, -PanAmount); } private void RightButton_Click(object sender, RoutedEventArgs e) { Pan(PanAmount, 0); } private void LeftButton_Click(object sender, RoutedEventArgs e) { Pan(-PanAmount, 0); } private void ItemsControl_MouseWheel(object sender, MouseWheelEventArgs e) { if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { var pos = e.GetPosition(ContentBorder); var contentMPos = new Point(pos.X / Scale, pos.Y / Scale); if (e.Delta > 0) { Scale *= 1 + e.Delta * WheelSpeed; } else { Scale /= 1 + (-e.Delta) * WheelSpeed; } Scale = Math.Max(MinScale, Scale); var scaledPos = new Point(contentMPos.X * Scale, contentMPos.Y * Scale); var offset = scaledPos - pos; Pan(offset.X, offset.Y); e.Handled = true; } else if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) { Pan(-e.Delta, 0); e.Handled = true; } } }