<commit_before>﻿using System;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using TCC.Controls;
using TCC.ViewModels;

namespace TCC.Windows
{
    public class TccWindow : Window
    {
        protected IntPtr _handle;
        protected WindowSettings _settings;
        protected WindowButtons _b;
        protected UIElement _c;
        DispatcherTimer _t;
        DoubleAnimation _showButtons;
        DoubleAnimation _hideButtons;
        protected bool _ignoreSize;
        protected bool clickThru;
        public bool ClickThru
        {
            get { return clickThru; }
            set
            {
                if (clickThru == value) return;
                clickThru = value;

                if (clickThru) FocusManager.MakeTransparent(_handle);
                else FocusManager.UndoTransparent(_handle);

                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ClickThru)));
            }
        }
        public WindowSettings WindowSettings => _settings;

        protected void InitWindow(WindowSettings ws, bool canClickThru = true, bool canHide = true, bool ignoreSize = true)
        {
            Topmost = true;
            _settings = ws;
            _settings.NotifyWindowSafeClose += CloseWindowSafe;
            _settings.PropertyChanged += _settings_PropertyChanged;
            Left = ws.X;
            Top = ws.Y;
            if (!ignoreSize)
            {
                if (ws.H != 0) Height = ws.H;
                if (ws.W != 0) Width = ws.W;
            }
            _ignoreSize = ignoreSize;
            Visibility = ws.Visible ? Visibility.Visible : Visibility.Hidden;
            SetClickThru(ws.ClickThruMode == ClickThruMode.Always);
            if (_settings.AutoDim) AnimateContentOpacity(_settings.DimOpacity);
            if (!WindowManager.IsTccVisible) AnimateContentOpacity(0);

            WindowManager.TccVisibilityChanged += OpacityChange;
            WindowManager.TccDimChanged += OpacityChange;
            SizeChanged += TccWindow_SizeChanged;
            Closed += TccWindow_Closed;
            Loaded += TccWindow_Loaded;

            if (_b == null) return;

            _hideButtons = new DoubleAnimation(0, TimeSpan.FromMilliseconds(1000));
            _showButtons = new DoubleAnimation(1, TimeSpan.FromMilliseconds(150));

            _t = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(2) };
            _t.Tick += (s, ev) =>
            {
                _t.Stop();
                if (this.IsMouseOver) return;
                _b.BeginAnimation(OpacityProperty, _hideButtons);
            };

            MouseEnter += (s, ev) => _b.BeginAnimation(OpacityProperty, _showButtons); 
            MouseLeave += (s, ev) => _t.Start();
            _b.MouseLeftButtonDown += Drag;
        }

        private void _settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(_settings.ClickThruMode))
            {
                switch (_settings.ClickThruMode)
                {
                    case ClickThruMode.Never:
                        FocusManager.UndoTransparent(_handle);
                        break;
                    case ClickThruMode.Always:
                        FocusManager.MakeTransparent(_handle);
                        break;
                    case ClickThruMode.WhenDim:
                        if (WindowManager.IsTccDim) FocusManager.MakeTransparent(_handle);
                        else FocusManager.UndoTransparent(_handle);
                        break;
                    case ClickThruMode.WhenUndim:
                        if (WindowManager.IsTccDim) FocusManager.UndoTransparent(_handle);
                        else FocusManager.MakeTransparent(_handle);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            else if (e.PropertyName == nameof(_settings.Scale))
            {
                Dispatcher.Invoke(() =>
                {
                    var vm = (TccWindowViewModel)DataContext;
                    vm.GetDispatcher().Invoke(() => vm.Scale = _settings.Scale);
                });
            }
            else if (e.PropertyName == nameof(_settings.Visible))
            {
                SetVisibility(_settings.Visible);
            }
        }

        private void TccWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _handle = new WindowInteropHelper(this).Handle;
            FocusManager.MakeUnfocusable(_handle);
            FocusManager.HideFromToolBar(_handle);

            if (!_settings.Enabled) CloseWindowSafe();
        }

        private void TccWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            CheckBounds();
            if (_ignoreSize) return;
            _settings.W = ActualWidth;
            _settings.H = ActualHeight;
            SettingsManager.SaveSettings();
        }

        private void TccWindow_Closed(object sender, EventArgs e)
        {
            Dispatcher.InvokeShutdown();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OpacityChange(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsTccVisible")
            {
                if (WindowManager.IsTccVisible)
                {
                    if (WindowManager.IsTccDim && _settings.AutoDim)
                    {
                        AnimateContentOpacity(_settings.DimOpacity);
                    }
                    else
                    {
                        AnimateContentOpacity(1);<commit_msg>don't shutdown the dispacher on window close, since now all windows are on the same thread<commit_after>﻿using System;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using TCC.Controls;
using TCC.ViewModels;

namespace TCC.Windows
{
    public class TccWindow : Window
    {
        protected IntPtr _handle;
        protected WindowSettings _settings;
        protected WindowButtons _b;
        protected UIElement _c;
        DispatcherTimer _t;
        DoubleAnimation _showButtons;
        DoubleAnimation _hideButtons;
        protected bool _ignoreSize;
        protected bool clickThru;
        public bool ClickThru
        {
            get { return clickThru; }
            set
            {
                if (clickThru == value) return;
                clickThru = value;

                if (clickThru) FocusManager.MakeTransparent(_handle);
                else FocusManager.UndoTransparent(_handle);

                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ClickThru)));
            }
        }
        public WindowSettings WindowSettings => _settings;

        protected void InitWindow(WindowSettings ws, bool canClickThru = true, bool canHide = true, bool ignoreSize = true)
        {
            Topmost = true;
            _settings = ws;
            _settings.NotifyWindowSafeClose += CloseWindowSafe;
            _settings.PropertyChanged += _settings_PropertyChanged;
            Left = ws.X;
            Top = ws.Y;
            if (!ignoreSize)
            {
                if (ws.H != 0) Height = ws.H;
                if (ws.W != 0) Width = ws.W;
            }
            _ignoreSize = ignoreSize;
            Visibility = ws.Visible ? Visibility.Visible : Visibility.Hidden;
            SetClickThru(ws.ClickThruMode == ClickThruMode.Always);
            if (_settings.AutoDim) AnimateContentOpacity(_settings.DimOpacity);
            if (!WindowManager.IsTccVisible) AnimateContentOpacity(0);

            WindowManager.TccVisibilityChanged += OpacityChange;
            WindowManager.TccDimChanged += OpacityChange;
            SizeChanged += TccWindow_SizeChanged;
            Closed += TccWindow_Closed;
            Loaded += TccWindow_Loaded;

            if (_b == null) return;

            _hideButtons = new DoubleAnimation(0, TimeSpan.FromMilliseconds(1000));
            _showButtons = new DoubleAnimation(1, TimeSpan.FromMilliseconds(150));

            _t = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(2) };
            _t.Tick += (s, ev) =>
            {
                _t.Stop();
                if (this.IsMouseOver) return;
                _b.BeginAnimation(OpacityProperty, _hideButtons);
            };

            MouseEnter += (s, ev) => _b.BeginAnimation(OpacityProperty, _showButtons); 
            MouseLeave += (s, ev) => _t.Start();
            _b.MouseLeftButtonDown += Drag;
        }

        private void _settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(_settings.ClickThruMode))
            {
                switch (_settings.ClickThruMode)
                {
                    case ClickThruMode.Never:
                        FocusManager.UndoTransparent(_handle);
                        break;
                    case ClickThruMode.Always:
                        FocusManager.MakeTransparent(_handle);
                        break;
                    case ClickThruMode.WhenDim:
                        if (WindowManager.IsTccDim) FocusManager.MakeTransparent(_handle);
                        else FocusManager.UndoTransparent(_handle);
                        break;
                    case ClickThruMode.WhenUndim:
                        if (WindowManager.IsTccDim) FocusManager.UndoTransparent(_handle);
                        else FocusManager.MakeTransparent(_handle);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            else if (e.PropertyName == nameof(_settings.Scale))
            {
                Dispatcher.Invoke(() =>
                {
                    var vm = (TccWindowViewModel)DataContext;
                    vm.GetDispatcher().Invoke(() => vm.Scale = _settings.Scale);
                });
            }
            else if (e.PropertyName == nameof(_settings.Visible))
            {
                SetVisibility(_settings.Visible);
            }
        }

        private void TccWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _handle = new WindowInteropHelper(this).Handle;
            FocusManager.MakeUnfocusable(_handle);
            FocusManager.HideFromToolBar(_handle);

            if (!_settings.Enabled) CloseWindowSafe();
        }

        private void TccWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            CheckBounds();
            if (_ignoreSize) return;
            _settings.W = ActualWidth;
            _settings.H = ActualHeight;
            SettingsManager.SaveSettings();
        }

        private void TccWindow_Closed(object sender, EventArgs e)
        {
            //Dispatcher.InvokeShutdown();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OpacityChange(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsTccVisible")
            {
                if (WindowManager.IsTccVisible)
                {
                    if (WindowManager.IsTccDim && _settings.AutoDim)
                    {
                        AnimateContentOpacity(_settings.DimOpacity);
                    }
                    else
                    {
                        AnimateContentOpacity(1);
{'fraction_non_alphanumeric': 0.07890539746495426, 'fraction_numerical': 0.0023503735415092756, 'mean_word_length': 1.6440301819795828, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, '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': '334540', 'n_tokens_mistral': 2999, 'n_tokens_neox': 2833, 'n_words': 592}