public EyeAurasSettingsViewModel( [NotNull] IHotkeyConverter hotkeyConverter, [NotNull] IConfigProvider <EyeAurasConfig> configProvider) { this.hotkeyConverter = hotkeyConverter; this.configProvider = configProvider; }
public HotkeyEditorViewModel(IHotkeyConverter hotkeyConverter) { this.hotkeyConverter = hotkeyConverter; this.WhenAnyValue(x => x.Key, x => x.AlternativeKey, x => x.SuppressKey) .Select(x => SaveToHotkeyConfig()) .SubscribeSafe(x => Properties = x, Log.HandleUiException) .AddTo(Anchors); }
public HotkeyIsActiveTrigger( [NotNull] IHotkeyConverter hotkeyConverter, [NotNull] IKeyboardEventsSource eventSource, [NotNull][Dependency(WellKnownWindows.MainWindow)] IWindowTracker mainWindowTracker, [NotNull][Dependency(WellKnownSchedulers.UI)] IScheduler uiScheduler) { this.hotkeyConverter = hotkeyConverter; Disposable .Create(() => Log.Debug($"Disposing HotkeyTrigger, gesture: {Hotkey} (mode: {HotkeyMode})")) .AddTo(Anchors); IsActive = true; this.RaiseWhenSourceValue(x => x.Properties, this, x => x.IsActive).AddTo(Anchors); this.WhenAnyValue(x => x.Hotkey) .Select(hotkey => hotkey == null ? Observable.Empty <HotkeyData>() : BuildHotkeySubscription(eventSource)) .Switch() .DistinctUntilChanged(x => new { x.Hotkey, x.KeyDown }) .Where( hotkeyData => { /* * This method MUST be executed on the same thread which emitted Key/Mouse event * otherwise .Handled value will be ignored due to obvious concurrency reasons */ if (mainWindowTracker.ActiveProcessId != CurrentProcessId) { Log.Debug($"Application is NOT active, processing hotkey {hotkeyData.Hotkey} (isDown: {hotkeyData.KeyDown}, suppressKey: {suppressKey}, configuredKey: {Hotkey}, mode: {HotkeyMode})"); if (suppressKey) { hotkeyData.MarkAsHandled(); } return(true); } Log.Debug($"Application is active, skipping hotkey {hotkeyData.Hotkey} (isDown: {hotkeyData.KeyDown}, suppressKey: {suppressKey}, configuredKey: {Hotkey}, mode: {HotkeyMode})"); return(false); }) .Subscribe( hotkeyData => { Log.Debug($"Hotkey {hotkeyData.Hotkey} pressed, state: {(hotkeyData.KeyDown ? "down" : "up")}, suppressed: {suppressKey}"); if (HotkeyMode == HotkeyMode.Click) { if (hotkeyData.KeyDown) { IsActive = !IsActive; } } else { IsActive = !IsActive; } }, Log.HandleUiException) .AddTo(Anchors); }
public ComplexHotkeyTracker( [NotNull] IHotkeyConverter hotkeyConverter, [NotNull] IConfigProvider <MicSwitchConfig> configProvider, [NotNull] IFactory <IHotkeyTracker> hotkeyTrackerFactory) { this.hotkeyConverter = hotkeyConverter; this.configProvider = configProvider; this.hotkeyTrackerFactory = hotkeyTrackerFactory; Log.Debug($"Scheduling HotkeyTracker initialization using background scheduler"); var bgThread = new Thread(x => Initialize()) { IsBackground = true, ApartmentState = ApartmentState.STA, Name = "HotkeyTracker" }; bgThread.Start(); }
public ComplexHotkeyTracker( [NotNull] IHotkeyConverter hotkeyConverter, [NotNull] IConfigProvider <MicSwitchHotkeyConfig> configProvider, [NotNull] IFactory <IHotkeyTracker> hotkeyTrackerFactory) { this.hotkeyConverter = hotkeyConverter; this.configProvider = configProvider; this.hotkeyTracker = hotkeyTrackerFactory.Create(); Log.Debug($"Scheduling HotkeyTracker initialization using background scheduler"); this.RaiseWhenSourceValue(x => x.IsActive, hotkeyTracker, x => x.IsActive).AddTo(Anchors); var bgThread = new Thread(x => Initialize()) { IsBackground = true, ApartmentState = ApartmentState.STA, Name = "HotkeyTracker" }; bgThread.Start(); }
public MainWindowViewModel( [NotNull] IFactory <IOverlayAuraViewModel, OverlayAuraProperties> auraViewModelFactory, [NotNull] IApplicationUpdaterViewModel appUpdater, [NotNull] IClipboardManager clipboardManager, [NotNull] IConfigSerializer configSerializer, [NotNull] IGenericSettingsViewModel settingsViewModel, [NotNull] IMessageBoxViewModel messageBox, [NotNull] IHotkeyConverter hotkeyConverter, [NotNull] IFactory <HotkeyIsActiveTrigger> hotkeyTriggerFactory, [NotNull] IConfigProvider <EyeAurasConfig> configProvider, [NotNull] IConfigProvider rootConfigProvider, [NotNull] IPrismModuleStatusViewModel moduleStatus, [NotNull] IMainWindowBlocksProvider mainWindowBlocksProvider, [NotNull] IFactory <IRegionSelectorService> regionSelectorServiceFactory, [NotNull] ISharedContext sharedContext, [NotNull] IComparisonService comparisonService, [NotNull][Dependency(WellKnownSchedulers.UI)] IScheduler uiScheduler) { using var unused = new OperationTimer(elapsed => Log.Debug($"{nameof(MainWindowViewModel)} initialization took {elapsed.TotalMilliseconds:F0}ms")); TabsList = new ReadOnlyObservableCollection <IEyeAuraViewModel>(sharedContext.AuraList); ModuleStatus = moduleStatus.AddTo(Anchors); var executingAssemblyName = Assembly.GetExecutingAssembly().GetName(); Title = $"{(AppArguments.Instance.IsDebugMode ? "[D]" : "")} {executingAssemblyName.Name} v{executingAssemblyName.Version}"; Disposable.Create(() => Log.Info("Disposing Main view model")).AddTo(Anchors); ApplicationUpdater = appUpdater.AddTo(Anchors); MessageBox = messageBox.AddTo(Anchors); Settings = settingsViewModel.AddTo(Anchors); StatusBarItems = mainWindowBlocksProvider.StatusBarItems; this.auraViewModelFactory = auraViewModelFactory; this.configProvider = configProvider; this.sharedContext = sharedContext; this.regionSelectorService = regionSelectorServiceFactory.Create(); this.clipboardManager = clipboardManager; this.configSerializer = configSerializer; this.hotkeyConverter = hotkeyConverter; this.hotkeyTriggerFactory = hotkeyTriggerFactory; CreateNewTabCommand = CommandWrapper.Create(() => AddNewCommandExecuted(OverlayAuraProperties.Default)); CloseTabCommand = CommandWrapper .Create <IOverlayAuraViewModel>(CloseTabCommandExecuted, CloseTabCommandCanExecute) .RaiseCanExecuteChangedWhen(this.WhenAnyProperty(x => x.SelectedTab)); DuplicateTabCommand = CommandWrapper .Create(DuplicateTabCommandExecuted, DuplicateTabCommandCanExecute) .RaiseCanExecuteChangedWhen(this.WhenAnyProperty(x => x.SelectedTab)); CopyTabToClipboardCommand = CommandWrapper .Create(CopyTabToClipboardExecuted, CopyTabToClipboardCommandCanExecute) .RaiseCanExecuteChangedWhen(this.WhenAnyProperty(x => x.SelectedTab).Select(x => x)); PasteTabCommand = CommandWrapper.Create(PasteTabCommandExecuted); UndoCloseTabCommand = CommandWrapper.Create(UndoCloseTabCommandExecuted, UndoCloseTabCommandCanExecute); OpenAppDataDirectoryCommand = CommandWrapper.Create(OpenAppDataDirectory); SelectRegionCommand = CommandWrapper.Create(SelectRegionCommandExecuted); Observable .FromEventPattern <OrderChangedEventArgs>(h => positionMonitor.OrderChanged += h, h => positionMonitor.OrderChanged -= h) .Select(x => x.EventArgs) .Subscribe(OnTabOrderChanged, Log.HandleUiException) .AddTo(Anchors); sharedContext .AuraList .ToObservableChangeSet() .ObserveOn(uiScheduler) .OnItemAdded(x => SelectedTab = x) .Subscribe() .AddTo(Anchors); this.WhenAnyValue(x => x.SelectedTab) .Subscribe(x => Log.Debug($"Selected tab: {x}")) .AddTo(Anchors); LoadConfig(); rootConfigProvider.Save(); if (sharedContext.AuraList.Count == 0) { CreateNewTabCommand.Execute(null); } configUpdateSubject .Sample(ConfigSaveSamplingTimeout) .Subscribe(SaveConfig, Log.HandleException) .AddTo(Anchors); Observable.Merge( this.WhenAnyProperty(x => x.Left, x => x.Top, x => x.Width, x => x.Height) .Sample(ConfigSaveSamplingTimeout) .Select(x => $"[{x.Sender}] Main window property change: {x.EventArgs.PropertyName}"), sharedContext.AuraList.ToObservableChangeSet() .Sample(ConfigSaveSamplingTimeout) .Select(x => "Tabs list change"), sharedContext.AuraList.ToObservableChangeSet() .WhenPropertyChanged(x => x.Properties) .Sample(ConfigSaveSamplingTimeout) .WithPrevious((prev, curr) => new { prev, curr }) .Select(x => new { x.curr.Sender, ComparisonResult = comparisonService.Compare(x.prev?.Value, x.curr.Value) }) .Where(x => !x.ComparisonResult.AreEqual) .Select(x => $"[{x.Sender.TabName}] Tab properties change: {x.ComparisonResult.DifferencesString}")) .Buffer(ConfigSaveSamplingTimeout) .Where(x => x.Count > 0) .Subscribe( reasons => { const int maxReasonsToOutput = 50; Log.Debug( $"Config Save reasons{(reasons.Count <= maxReasonsToOutput ? string.Empty : $"first {maxReasonsToOutput} of {reasons.Count} items")}:\r\n\t{reasons.Take(maxReasonsToOutput).DumpToTable()}"); configUpdateSubject.OnNext(Unit.Default); },