<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using SchematicControls;

namespace LiveSPICE
{
    /// <summary>
    /// Interaction logic for SchematicViewer.xaml
    /// </summary>
    public partial class SchematicViewer : UserControl
    {
        protected double MaxZoom = 8;
        protected Point? mouse;

        protected ScaleTransform scale = new ScaleTransform();

        public SchematicControl Schematic
        {
            get { return ((SchematicControl)scroll.Content); }
            set
            {
                scroll.Content = value;
                if (value != null)
                {
                    value.LayoutTransform = scale;
                    value.UpdateLayout();
                    Zoom = Math.Max(Zoom, MinZoom(ViewportSize));
                    FocusCenter();
                }
            }
        }

        private double LogFloor(double x) { return Math.Pow(2, Math.Floor(Math.Log(x, 2))); }

        private Size ViewportSize { get { return new Size(scroll.ViewportWidth, scroll.ViewportHeight); } }

        private double MinZoom(Size Size)
        {
            return LogFloor(Math.Min(
Size.Width / (Schematic.ActualWidth + 1e-6),
Size.Height / (Schematic.ActualHeight + 1e-6)));
        }

        public double Zoom
        {
            get { return scale.ScaleX; }
            set
            {
                Point focus = mouse.HasValue ? mouse.Value : new Point(scroll.ViewportWidth / 2, scroll.ViewportHeight / 2);
                Point at = TranslatePoint(focus, Schematic);

                double zoom = LogFloor(value);

                scale.ScaleX = scale.ScaleY = Math.Max(Math.Min(zoom, MaxZoom), MinZoom(ViewportSize));
                Schematic.UpdateLayout();

                at = Schematic.TranslatePoint(at, this);
                scroll.ScrollToHorizontalOffset(scroll.HorizontalOffset + at.X - focus.X);
                scroll.ScrollToVerticalOffset(scroll.VerticalOffset + at.Y - focus.Y);
            }
        }

        public SchematicViewer()
        {
            InitializeComponent();

            CommandBindings.Add(new CommandBinding(NavigationCommands.Zoom, (o, e) => Zoom *= 2));
            CommandBindings.Add(new CommandBinding(NavigationCommands.DecreaseZoom, (o, e) => Zoom *= 0.5));
            CommandBindings.Add(new CommandBinding(Commands.ZoomFit, (o, e) => FocusCenter()));

            scroll.PreviewMouseWheel += (o, e) =>
            {
                Zoom = LogFloor(Zoom * (e.Delta > 0 ? 2 : 0.5));
                e.Handled = true;
            };
            scroll.PreviewMouseMove += (o, e) => mouse = e.GetPosition(this);
            scroll.MouseLeave += (o, e) => mouse = null;

            SizeChanged += SchematicViewer_SizeChanged;<commit_msg>Enable smoother zooming<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using SchematicControls;

namespace LiveSPICE
{
    /// <summary>
    /// Interaction logic for SchematicViewer.xaml
    /// </summary>
    public partial class SchematicViewer : UserControl
    {
        protected double MaxZoom = 8;
        protected Point? mouse;

        protected ScaleTransform scale = new ScaleTransform();

        public SchematicControl Schematic
        {
            get { return ((SchematicControl)scroll.Content); }
            set
            {
                scroll.Content = value;
                if (value != null)
                {
                    value.LayoutTransform = scale;
                    value.UpdateLayout();
                    Zoom = Math.Max(Zoom, MinZoom(ViewportSize));
                    FocusCenter();
                }
            }
        }

        private double LogFloor(double x) { return Math.Pow(2, Math.Floor(Math.Log(x, 2))); }

        private Size ViewportSize { get { return new Size(scroll.ViewportWidth, scroll.ViewportHeight); } }

        private double MinZoom(Size Size)
        {
            return LogFloor(Math.Min(
                Size.Width / (Schematic.ActualWidth + 1e-6),
                Size.Height / (Schematic.ActualHeight + 1e-6)));
        }

        public double Zoom
        {
            get { return scale.ScaleX; }
            set
            {
                Point focus = mouse ?? new Point(scroll.ViewportWidth / 2, scroll.ViewportHeight / 2);
                Point at = TranslatePoint(focus, Schematic);

                double zoom = value;

                scale.ScaleX = scale.ScaleY = Math.Max(Math.Min(zoom, MaxZoom), MinZoom(ViewportSize));
                Schematic.UpdateLayout();

                at = Schematic.TranslatePoint(at, this);
                scroll.ScrollToHorizontalOffset(scroll.HorizontalOffset + at.X - focus.X);
                scroll.ScrollToVerticalOffset(scroll.VerticalOffset + at.Y - focus.Y);
            }
        }

        public SchematicViewer()
        {
            InitializeComponent();

            CommandBindings.Add(new CommandBinding(NavigationCommands.Zoom, (o, e) => Zoom *= 1.5));
            CommandBindings.Add(new CommandBinding(NavigationCommands.DecreaseZoom, (o, e) => Zoom *= 1 / 1.5));
            CommandBindings.Add(new CommandBinding(Commands.ZoomFit, (o, e) => FocusCenter()));

            scroll.PreviewMouseWheel += (o, e) =>
            {
                Zoom *= e.Delta > 0 ? 1.1 : (1 / 1.1);
                e.Handled = true;
            };
            scroll.PreviewMouseMove += (o, e) => mouse = e.GetPosition(this);
            scroll.MouseLeave += (o, e) => mouse = null;

            SizeChanged += SchematicViewer_SizeChanged;
{'fraction_non_alphanumeric': 0.10768175582990398, 'fraction_numerical': 0.006172839506172839, 'mean_word_length': 1.8246973365617434, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '812198', 'n_tokens_mistral': 1614, 'n_tokens_neox': 1510, 'n_words': 339}