using System.Windows.Threading; using CursorLang.Models; using CursorLang.ViewModels; using CursorLang.Views; namespace CursorLang.Services; /// /// Настройки подсказки у курсора. /// public sealed class PopupOptions { /// Сколько подсказка держится на экране после последнего переключения. public TimeSpan Duration { get; init; } = TimeSpan.FromMilliseconds(500); /// Отступ от курсора в единицах WPF, чтобы подсказка не оказалась под ним. public double CursorOffset { get; init; } = 16; } /// /// Управляет временем жизни подсказки: окно отвечает только за показ, /// а решение «когда показать и когда убрать» принимается здесь. /// public sealed class LayoutPopupService : ILayoutPopupService, IDisposable { private readonly LayoutPopupWindow _window; private readonly LayoutPopupViewModel _viewModel; private readonly DispatcherTimer _hideTimer; public LayoutPopupService(LayoutPopupWindow window, LayoutPopupViewModel viewModel, PopupOptions options) { _window = window; _viewModel = viewModel; _hideTimer = new DispatcherTimer { Interval = options.Duration }; _hideTimer.Tick += OnHideTimerTick; } public void Show(KeyboardLayout layout) { _viewModel.ShortName = layout.ShortName; _window.ShowAtCursor(); // Перезапускаем таймер, чтобы быстрые переключения продлевали показ _hideTimer.Stop(); _hideTimer.Start(); } public void Dispose() { _hideTimer.Stop(); _hideTimer.Tick -= OnHideTimerTick; _window.Close(); } private void OnHideTimerTick(object? sender, EventArgs e) { _hideTimer.Stop(); _window.Hide(); } }