Explorar o código

Added Zoom Panel control

Kenric Nugteren hai 1 ano
pai
achega
d609dbab2f
Modificáronse 2 ficheiros con 222 adicións e 0 borrados
  1. 168 0
      inabox.wpf/Forms/ZoomPanel/ZoomPanel.xaml.cs
  2. 54 0
      inabox.wpf/Themes/Generic.xaml

+ 168 - 0
inabox.wpf/Forms/ZoomPanel/ZoomPanel.xaml.cs

@@ -0,0 +1,168 @@
+using InABox.WPF;
+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;
+
+/// <summary>
+/// Interaction logic for ZoomPanel.xaml
+/// </summary>
+public partial class ZoomPanel : ContentControl, INotifyPropertyChanged
+{
+    private bool _showNavigationButtons = false;
+    public bool ShowNavigationButtons
+    {
+        get => _showNavigationButtons;
+        set
+        {
+            _showNavigationButtons = value;
+            OnPropertyChanged();
+        }
+    }
+
+    public double _scale = 1;
+    public double Scale
+    {
+        get => _scale;
+        set
+        {
+            _scale = value;
+            OnPropertyChanged();
+        }
+    }
+
+    private ScrollViewer Scroll => (ScrollViewer)GetTemplateChild("PART_Scroll");
+    private Border ContentBorder => (Border)GetTemplateChild("PART_ContentBorder");
+
+    public double ScrollX
+    {
+        get => Scroll.HorizontalOffset;
+        set
+        {
+            Scroll.ScrollToHorizontalOffset(value);
+        }
+    }
+
+    public double ScrollY
+    {
+        get => Scroll.VerticalOffset;
+        set
+        {
+            Scroll.ScrollToVerticalOffset(value);
+        }
+    }
+
+    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(Scale, 0.5);
+
+            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;
+        }
+    }
+}

+ 54 - 0
inabox.wpf/Themes/Generic.xaml

@@ -2,6 +2,7 @@
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="clr-namespace:InABox.DynamicGrid"
+    xmlns:wpf="clr-namespace:InABox.Wpf"
     xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
     xmlns:themes="clr-namespace:InABox.WPF.Themes"
     x:Class="InABox.WPF.Generic"
@@ -41,6 +42,59 @@
         </Grid>
     </ControlTemplate>
 
+    <Style TargetType="wpf:ZoomPanel">
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="wpf:ZoomPanel">
+                    <ControlTemplate.Resources>
+                        <wpf:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
+                    </ControlTemplate.Resources>
+                    <Grid>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="*"/>
+                            <RowDefinition Height="Auto"/>
+                        </Grid.RowDefinitions>
+                        <ScrollViewer Grid.Row="0"
+                                      Background="{TemplateBinding Background}"
+                                      x:Name="PART_Scroll"
+                                      HorizontalScrollBarVisibility="Auto"
+                                      VerticalScrollBarVisibility="Auto">
+                            <Border Background="Transparent" x:Name="PART_ContentBorder">
+                                <ContentControl x:Name="PART_ZoomContent" VerticalAlignment="Center" Content="{TemplateBinding Content}">
+                                    <ContentControl.LayoutTransform>
+                                        <ScaleTransform ScaleX="{Binding Scale,RelativeSource={RelativeSource TemplatedParent}}"
+                                                        ScaleY="{Binding Scale,RelativeSource={RelativeSource TemplatedParent}}"/>
+                                    </ContentControl.LayoutTransform>
+                                </ContentControl>
+                            </Border>
+                        </ScrollViewer>
+                        <DockPanel Grid.Row="1" LastChildFill="False"
+                                   Visibility="{Binding ShowNavigationButtons,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource BoolToVisibilityConverter}}">
+                            <Button x:Name="PART_ZoomInButton" Margin="5">
+                                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/zoomin.png" Width="32" Height="32"/>
+                            </Button>
+                            <Button x:Name="PART_ZoomOutButton" Margin="0,5,5,5">
+                                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/zoomout.png" Width="32" Height="32"/>
+                            </Button>
+                            <Button x:Name="PART_LeftButton" Margin="0,5,5,5">
+                                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/leftarrow.png" Width="32" Height="32"/>
+                            </Button>
+                            <Button x:Name="PART_RightButton" Margin="0,5,5,5">
+                                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/rightarrow.png" Width="32" Height="32"/>
+                            </Button>
+                            <Button x:Name="PART_UpButton" Margin="0,5,5,5">
+                                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/uparrow.png" Width="32" Height="32"/>
+                            </Button>
+                            <Button x:Name="PART_DownButton" Margin="0,5,5,5">
+                                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/downarrow.png" Width="32" Height="32"/>
+                            </Button>
+                        </DockPanel>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
     <!-- DynamicSplitPanel -->
     <Style TargetType="{x:Type local:DynamicSplitPanel}">
         <Setter Property="Template">