public EyeOverlayViewModel(
            [NotNull] [Dependency(WellKnownWindows.AllWindows)] IWindowTracker mainWindowTracker,
            [NotNull] IOverlayWindowController overlayWindowController,
            [NotNull] IAuraModelController auraModelController,
            [NotNull] IWindowListProvider windowListProvider,
            [NotNull] ISelectionAdornerViewModel selectionAdorner,
            [NotNull] [Dependency(WellKnownSchedulers.UI)] IScheduler uiScheduler)
        {
            using var sw = new BenchmarkTimer("Initialization", Log, nameof(EyeOverlayViewModel));
            SelectionAdorner = selectionAdorner.AddTo(Anchors);
            activeConfigEditorAnchors.AddTo(Anchors);
            this.mainWindowTracker = mainWindowTracker;
            this.overlayWindowController = overlayWindowController;
            this.auraModelController = auraModelController;
            this.windowListProvider = windowListProvider;
            MinSize = new Size(32, 32);
            SizeToContent = SizeToContent.Manual;
            Width = 400;
            Height = 400;
            Left = 200;
            Top = 200;
            IsUnlockable = true;
            Title = "EyeAuras";
            EnableHeader = false;
            thumbnailOpacity.SetDefaultValue(DefaultThumbnailOpacity);

            ResetRegionCommandExecuted();
            sw.Step("Basic properties initialized");
            
            WhenLoaded
                .Take(1)
                .Subscribe(ApplyConfig)
                .AddTo(Anchors);
            sw.Step("WhenLoaded executed");
            
            resetRegionCommand = CommandWrapper.Create(ResetRegionCommandExecuted, ResetRegionCommandCanExecute);
            selectRegionCommand = CommandWrapper.Create(SelectRegionCommandExecuted, SelectRegionCommandCanExecute);
            closeConfigEditorCommand = CommandWrapper.Create(CloseConfigEditorCommandExecuted);
            fitOverlayCommand = CommandWrapper.Create<double?>(FitOverlayCommandExecuted);
            setAttachedWindowCommand = CommandWrapper.Create<WindowHandle>(SetAttachedWindowCommandExecuted);
            setClickThroughCommand = CommandWrapper.Create<bool?>(SetClickThroughModeExecuted);
            DisableAuraCommand = CommandWrapper.Create(() => auraModelController.IsEnabled = false);
            CloseCommand = CommandWrapper.Create(CloseCommandExecuted, auraModelController.WhenAnyValue(x => x.CloseController).Select(CloseCommandCanExecute));
            ToggleLockStateCommand = CommandWrapper.Create(
                () =>
                {
                    if (IsLocked && UnlockWindowCommand.CanExecute(null))
                    {
                        UnlockWindowCommand.Execute(null);
                    }
                    else if (!IsLocked && LockWindowCommand.CanExecute(null))
                    {
                        LockWindowCommand.Execute(null);
                    }
                    else
                    {
                        throw new ApplicationException($"Something went wrong - invalid Overlay Lock state: {new {IsLocked, IsUnlockable, CanUnlock = UnlockWindowCommand.CanExecute(null), CanLock = LockWindowCommand.CanExecute(null)  }}");
                    }
                });

            auraModelController.WhenAnyValue(x => x.Name)
                .Where(x => !string.IsNullOrEmpty(x))
                .Subscribe(x => OverlayName = x)
                .AddTo(Anchors);

            this.RaiseWhenSourceValue(x => x.ActiveThumbnailOpacity, thumbnailOpacity, x => x.Value).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.ThumbnailOpacity, this, x => x.ActiveThumbnailOpacity).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.SourceBounds, Region, x => x.Bounds).AddTo(Anchors);

            isInEditMode = Observable.Merge(
                    this.WhenAnyProperty(x => x.IsInSelectMode, x => x.IsLocked))
                .Select(change => IsInSelectMode || !IsLocked)
                .ToPropertyHelper(this, x => x.IsInEditMode, uiScheduler)
                .AddTo(Anchors);

            this.WhenAnyValue(x => x.IsLocked)
                .Where(x => x && isInSelectMode)
                .Subscribe(() => IsInSelectMode = false)
                .AddTo(Anchors);

            aspectRatio = this.WhenAnyProperty(x => x.Bounds, x => x.ViewModelLocation)
                .Select(change => Width >= 0 && Height >= 0
                    ? Width / Height
                    : double.PositiveInfinity)
                .ToPropertyHelper(this, x => x.AspectRatio, uiScheduler)
                .AddTo(Anchors);
            sw.ResetStep();
            configEditorSupplier = new Lazy<OverlayConfigEditor>(() => CreateConfigEditor(this));
            sw.Step("Initialized Config editor");
        }
Beispiel #2
0
        public MicSwitchOverlayViewModel(
            IOverlayWindowController overlayWindowController,
            IMicrophoneControllerEx microphoneController,
            IConfigProvider<MicSwitchOverlayConfig> configProvider,
            IImageProvider imageProvider,
            [Dependency(WellKnownSchedulers.UI)] IScheduler uiScheduler)
        {
            this.overlayWindowController = overlayWindowController;
            this.microphoneController = microphoneController;
            this.configProvider = configProvider;
            this.imageProvider = imageProvider;
            OverlayMode = OverlayMode.Transparent;
            MinSize = new Size(40, 40);
            MaxSize = new Size(300, 300);
            DefaultSize = new Size(120, 120);
            SizeToContent = SizeToContent.Manual;
            TargetAspectRatio = MinSize.Width / MinSize.Height;
            IsUnlockable = true;
            Title = "MicSwitch";
            IsEnabled = true;

            this.WhenAnyValue(x => x.IsLocked)
                .SubscribeSafe(isLocked => OverlayMode = isLocked ? OverlayMode.Transparent : OverlayMode.Layered, Log.HandleUiException)
                .AddTo(Anchors);

            this.RaiseWhenSourceValue(x => x.IsEnabled, overlayWindowController, x => x.IsEnabled).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.Mute, microphoneController, x => x.Mute, uiScheduler).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.MicrophoneImage, imageProvider, x => x.MicrophoneImage, uiScheduler).AddTo(Anchors);
            
            ToggleLockStateCommand = CommandWrapper.Create(
                () =>
                {
                    if (IsLocked && UnlockWindowCommand.CanExecute(null))
                    {
                        UnlockWindowCommand.Execute(null);
                    }
                    else if (!IsLocked && LockWindowCommand.CanExecute(null))
                    {
                        LockWindowCommand.Execute(null);
                    }
                    else
                    {
                        throw new ApplicationException($"Something went wrong - invalid Overlay Lock state: {new {IsLocked, IsUnlockable, CanUnlock = UnlockWindowCommand.CanExecute(null), CanLock = LockWindowCommand.CanExecute(null)  }}");
                    }
                });

            this.WhenAnyValue(x => x.IsEnabled)
                .Where(x => !IsEnabled && !IsLocked)
                .ObserveOn(uiScheduler)
                .SubscribeSafe(() => LockWindowCommand.Execute(null), Log.HandleUiException)
                .AddTo(Anchors);

            this.WhenAnyValue(x => x.OverlayWindow)
                .Where(x => x != null)
                .SubscribeSafe(x => x.LogWndProc("MicOverlay").AddTo(Anchors), Log.HandleUiException)
                .AddTo(Anchors);

            this.WhenAnyValue(x => x.OverlayVisibilityMode, x => x.Mute)
                .Select(_ =>
                {
                    return OverlayVisibilityMode switch
                    {
                        OverlayVisibilityMode.Always => true,
                        OverlayVisibilityMode.Never => false,
                        OverlayVisibilityMode.WhenMuted => Mute,
                        OverlayVisibilityMode.WhenUnmuted => !Mute,
                        _ => throw new ArgumentOutOfRangeException(nameof(overlayVisibilityMode), overlayVisibilityMode, "Unknown visibility mode")
                    };
                })
                .DistinctUntilChanged()
                .ObserveOn(uiScheduler)
                .SubscribeSafe(x => IsEnabled = x, Log.HandleUiException)
                .AddTo(Anchors);
            
            WhenLoaded
                .Take(1)
                .SubscribeSafe(_ =>
                {
                    configProvider
                        .WhenChanged
                        .ObserveOn(uiScheduler)
                        .SubscribeSafe(LoadConfig, Log.HandleUiException)
                        .AddTo(Anchors);
                    
                    Observable.Merge(
                            this.ObservableForProperty(x => x.NativeBounds, skipInitial: true).ToUnit(),
                            this.ObservableForProperty(x => x.Opacity, skipInitial: true).ToUnit(),
                            this.ObservableForProperty(x => x.OverlayVisibilityMode, skipInitial: true).ToUnit(),
                            this.ObservableForProperty(x => x.IsEnabled, skipInitial: true).ToUnit(),
                            this.ObservableForProperty(x => x.IsLocked, skipInitial: true).ToUnit())
                        .SkipUntil(WhenLoaded)
                        .Throttle(ConfigThrottlingTimeout)
                        .ObserveOn(uiScheduler)
                        .SubscribeSafe(SaveConfig, Log.HandleUiException)
                        .AddTo(Anchors);
                }, Log.HandleUiException)
                .AddTo(Anchors);
        }
Beispiel #3
0
        public MicSwitchOverlayViewModel(
            [NotNull] IOverlayWindowController overlayWindowController,
            [NotNull] IMicrophoneControllerEx microphoneController,
            [NotNull] IConfigProvider<MicSwitchConfig> configProvider,
            [NotNull] IImageProvider imageProvider,
            [NotNull] [Dependency(WellKnownSchedulers.UI)] IScheduler uiScheduler)
        {
            this.overlayWindowController = overlayWindowController;
            this.microphoneController = microphoneController;
            this.configProvider = configProvider;
            this.imageProvider = imageProvider;
            OverlayMode = OverlayMode.Transparent;
            MinSize = new Size(120, 120);
            MaxSize = new Size(300, 300);
            SizeToContent = SizeToContent.Manual;
            TargetAspectRatio = MinSize.Width / MinSize.Height;
            IsUnlockable = true;
            Title = "MicSwitch";
            WhenLoaded
                .Take(1)
                .Select(x => configProvider.WhenChanged)
                .Switch()
                .ObserveOn(uiScheduler)
                .Subscribe(ApplyConfig)
                .AddTo(Anchors);

            this.WhenAnyValue(x => x.IsLocked)
                .Subscribe(isLocked => OverlayMode = isLocked ? OverlayMode.Transparent : OverlayMode.Layered)
                .AddTo(Anchors);

            configProvider.ListenTo(x => x.MicrophoneLineId)
                .ObserveOn(uiScheduler)
                .Subscribe(lineId => { microphoneController.LineId = lineId; })
                .AddTo(Anchors);

            this.RaiseWhenSourceValue(x => x.IsEnabled, overlayWindowController, x => x.IsEnabled).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.Mute, microphoneController, x => x.Mute, uiScheduler).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.MicrophoneImage, imageProvider, x => x.ActiveMicrophoneImage, uiScheduler).AddTo(Anchors);
            
            ToggleLockStateCommand = CommandWrapper.Create(
                () =>
                {
                    if (IsLocked && UnlockWindowCommand.CanExecute(null))
                    {
                        UnlockWindowCommand.Execute(null);
                    }
                    else if (!IsLocked && LockWindowCommand.CanExecute(null))
                    {
                        LockWindowCommand.Execute(null);
                    }
                    else
                    {
                        throw new ApplicationException($"Something went wrong - invalid Overlay Lock state: {new {IsLocked, IsUnlockable, CanUnlock = UnlockWindowCommand.CanExecute(null), CanLock = LockWindowCommand.CanExecute(null)  }}");
                    }
                });
            
            Observable.Merge(
                    this.ObservableForProperty(x => x.Left, skipInitial: true).ToUnit(),
                    this.ObservableForProperty(x => x.Top, skipInitial: true).ToUnit(),
                    this.ObservableForProperty(x => x.Width, skipInitial: true).ToUnit(),
                    this.ObservableForProperty(x => x.Height, skipInitial: true).ToUnit(),
                    this.ObservableForProperty(x => x.IsEnabled, skipInitial: true).ToUnit(),
                    this.ObservableForProperty(x => x.IsLocked, skipInitial: true).ToUnit())
                .SkipUntil(WhenLoaded)
                .Throttle(ConfigThrottlingTimeout)
                .ObserveOn(uiScheduler)
                .Subscribe(SaveConfig, Log.HandleUiException)
                .AddTo(Anchors);

            this.WhenAnyValue(x => x.IsEnabled)
                .Where(x => !IsEnabled && !IsLocked)
                .ObserveOn(uiScheduler)
                .Subscribe(() => LockWindowCommand.Execute(null), Log.HandleUiException)
                .AddTo(Anchors);
        }