private string CreateTitle(OutputSizeInfo size) { if (size.Par.Num == size.Par.Den) { return(string.Format(PreviewRes.PreviewWindowTitleSimple, size.OutputWidth, size.OutputHeight)); } else { int width = size.OutputWidth; int height = size.OutputHeight; int parWidth = size.Par.Num; int parHeight = size.Par.Den; if (parWidth <= 0 || parHeight <= 0) { StaticResolver.Resolve <IAppLogger>().LogError("HandBrake returned a negative pixel aspect ratio. Cannot show preview."); return(PreviewRes.NoVideoSourceTitle); } return(string.Format( PreviewRes.PreviewWindowTitleComplex, Math.Round(width * ((double)parWidth / parHeight)), height, width, height)); } }
private void UpdateTitle(OutputSizeInfo size) { if (size.Par.Num == size.Par.Den) { this.Title = string.Format(PreviewRes.PreviewWindowTitleSimple, size.OutputWidth, size.OutputHeight); } else { this.Title = string.Format( PreviewRes.PreviewWindowTitleComplex, Math.Round(this.PreviewDisplayWidth), Math.Round(this.PreviewDisplayHeight), size.OutputWidth, size.OutputHeight); } }
public void Refresh() { if (this.mainViewModel.SelectedTitle != null) { var profile = this.presetsService.SelectedPreset.Preset.EncodingProfile; OutputSizeInfo outputSizeInfo = JsonEncodeFactory.GetOutputSize(profile, this.mainViewModel.SelectedTitle); if (this.Size == null || !outputSizeInfo.Equals(this.Size)) { this.Size = outputSizeInfo; } } else { this.Size = null; } }
public void RefreshImageSize() { var previewVM = (PreviewWindowViewModel)this.DataContext; PreviewFit fitControl; OutputSizeInfo outputSize = previewVM.PreviewImageService.OutputSizeInfo; if (outputSize != null) { int displayHeight = outputSize.OutputHeight; int displayWidth = outputSize.DisplayWidth; switch (previewVM.MainDisplay) { case PreviewMainDisplay.Default: fitControl = this.MainContent as PreviewFit; fitControl?.ResizeHolder(this.previewArea, displayWidth, displayHeight, showOneToOneWhenSmaller: true); break; case PreviewMainDisplay.FitToWindow: fitControl = this.MainContent as PreviewFit; fitControl?.ResizeHolder(this.previewArea, displayWidth, displayHeight, showOneToOneWhenSmaller: false); break; case PreviewMainDisplay.OneToOne: var oneToOneControl = this.MainContent as PreviewOneToOne; oneToOneControl?.ResizeHolder(displayWidth, displayHeight); break; case PreviewMainDisplay.StillCorners: var cornersControl = this.MainContent as PreviewCorners; cornersControl?.UpdateCornerImages(); break; } } }
public SizingPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { this.AutomaticChange = true; this.RotationChoices = new List <RotationViewModel> { new RotationViewModel { Rotation = VCPictureRotation.None, Display = CommonRes.None, Image = "/Icons/Empty.png", ShowImage = false }, new RotationViewModel { Rotation = VCPictureRotation.Clockwise90, Display = EncodingRes.Rotation_Clockwise90, Image = "/Icons/rotate_90_cw.png" }, new RotationViewModel { Rotation = VCPictureRotation.Clockwise270, Display = EncodingRes.Rotation_Counterclockwise90, Image = "/Icons/rotate_90_ccw.png" }, new RotationViewModel { Rotation = VCPictureRotation.Clockwise180, Display = EncodingRes.Rotation_180, Image = "/Icons/rotate_180.png" } }; this.SizingModeChoices = new List <ComboChoice <VCSizingMode> > { new ComboChoice <VCSizingMode>(VCSizingMode.Automatic, CommonRes.Automatic), new ComboChoice <VCSizingMode>(VCSizingMode.Manual, EncodingRes.SizingModeManual), }; this.ScalingModeChoices = new List <ComboChoice <VCScalingMode> > { new ComboChoice <VCScalingMode>(VCScalingMode.DownscaleOnly, EncodingRes.ScalingMode_DownscaleOnly), new ComboChoice <VCScalingMode>(VCScalingMode.UpscaleFill, EncodingRes.ScalingMode_Fill), new ComboChoice <VCScalingMode>(VCScalingMode.Upscale2X, string.Format(EncodingRes.UpscaleMaxFormat, 2)), new ComboChoice <VCScalingMode>(VCScalingMode.Upscale3X, string.Format(EncodingRes.UpscaleMaxFormat, 3)), new ComboChoice <VCScalingMode>(VCScalingMode.Upscale4X, string.Format(EncodingRes.UpscaleMaxFormat, 4)), }; this.PaddingModeChoices = new List <ComboChoice <VCPaddingMode> > { new ComboChoice <VCPaddingMode>(VCPaddingMode.None, CommonRes.None), new ComboChoice <VCPaddingMode>(VCPaddingMode.Fill, EncodingRes.PaddingMode_Fill), new ComboChoice <VCPaddingMode>(VCPaddingMode.Width, EncodingRes.PaddingMode_Width), new ComboChoice <VCPaddingMode>(VCPaddingMode.Height, EncodingRes.PaddingMode_Height), new ComboChoice <VCPaddingMode>(VCPaddingMode.Custom, CommonRes.Custom), }; this.RegisterProfileProperties(); // WidthLabel this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, x => x.ScalingMode, (sizingMode, paddingMode, scalingMode) => { if (sizingMode == VCSizingMode.Manual) { return(EncodingRes.WidthLabel); } switch (paddingMode) { case VCPaddingMode.Fill: case VCPaddingMode.Width: return(EncodingRes.WidthLabel); case VCPaddingMode.Height: return(EncodingRes.MaxWidthLabel); case VCPaddingMode.None: case VCPaddingMode.Custom: switch (scalingMode) { case VCScalingMode.UpscaleFill: return(EncodingRes.TargetWidthLabel); default: return(EncodingRes.MaxWidthLabel); } } return(string.Empty); }).ToProperty(this, x => x.WidthLabel, out this.widthLabel); // HeightLabel this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, x => x.ScalingMode, (sizingMode, paddingMode, scalingMode) => { if (sizingMode == VCSizingMode.Manual) { return(EncodingRes.HeightLabel); } switch (paddingMode) { case VCPaddingMode.Fill: case VCPaddingMode.Height: return(EncodingRes.HeightLabel); case VCPaddingMode.Width: return(EncodingRes.MaxHeightLabel); case VCPaddingMode.None: case VCPaddingMode.Custom: switch (scalingMode) { case VCScalingMode.UpscaleFill: return(EncodingRes.TargetHeightLabel); default: return(EncodingRes.MaxHeightLabel); } } return(string.Empty); }).ToProperty(this, x => x.HeightLabel, out this.heightLabel); // AllowEmptyResolution this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, x => x.ScalingMode, (sizingMode, paddingMode, scalingMode) => { if (sizingMode == VCSizingMode.Manual) { return(false); } switch (paddingMode) { case VCPaddingMode.None: case VCPaddingMode.Custom: return(scalingMode != VCScalingMode.UpscaleFill);; default: return(false); } }).ToProperty(this, x => x.AllowEmptyResolution, out this.allowEmptyResolution); // InputPreview this.MainViewModel.WhenAnyValue(x => x.SelectedTitle).Select(selectedTitle => { var previewLines = new List <SizingPreviewLineViewModel>(); if (selectedTitle == null) { return(previewLines); } string inputStorageResolutionString = selectedTitle.Geometry.Width + " x " + selectedTitle.Geometry.Height; if (selectedTitle.Geometry.PAR.Num == selectedTitle.Geometry.PAR.Den) { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.ResolutionLabel, inputStorageResolutionString)); } else { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.StorageResolutionLabel, inputStorageResolutionString)); previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.PixelAspectRatioLabel, CreateParDisplayString(selectedTitle.Geometry.PAR.Num, selectedTitle.Geometry.PAR.Den))); double pixelAspectRatio = ((double)selectedTitle.Geometry.PAR.Num) / selectedTitle.Geometry.PAR.Den; double displayWidth = selectedTitle.Geometry.Width * pixelAspectRatio; int displayWidthRounded = (int)Math.Round(displayWidth); string displayResolutionString = displayWidthRounded + " x " + selectedTitle.Geometry.Height; previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.DisplayResolutionLabel, displayResolutionString)); } return(previewLines); }).ToProperty(this, x => x.InputPreview, out this.inputPreview); // OutputPreview this.outputSizeService.WhenAnyValue(x => x.Size).Select(size => { var previewLines = new List <SizingPreviewLineViewModel>(); if (size == null) { return(previewLines); } string outputStorageResolutionString = size.OutputWidth + " x " + size.OutputHeight; if (size.Par.Num == size.Par.Den) { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.ResolutionLabel, outputStorageResolutionString)); } else { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.StorageResolutionLabel, outputStorageResolutionString)); previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.PixelAspectRatioLabel, CreateParDisplayString(size.Par.Num, size.Par.Den))); string displayResolutionString = Math.Round(size.OutputWidth * (((double)size.Par.Num) / size.Par.Den)) + " x " + size.OutputHeight; previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.DisplayResolutionLabel, displayResolutionString)); } return(previewLines); }).ToProperty(this, x => x.OutputPreview, out this.outputPreview); // PadColorEnabled this.WhenAnyValue(x => x.PaddingMode, paddingMode => { return(paddingMode != VCPaddingMode.None); }).ToProperty(this, x => x.PadColorEnabled, out this.padColorEnabled); // CroppingUIEnabled this.WhenAnyValue(x => x.CroppingType, croppingType => { return(croppingType == VCCroppingType.Custom); }).ToProperty(this, x => x.CroppingUIEnabled, out this.croppingUIEnabled); // Update the underlying profile when our local Crop properties change. This only applies for // CroppingType.Custom this.WhenAnyValue(x => x.CropTop) .Skip(1) .Subscribe(cropTop => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Top), nameof(this.CropTop), cropTop, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.CropBottom) .Skip(1) .Subscribe(cropBottom => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Bottom), nameof(this.CropBottom), cropBottom, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.CropLeft) .Skip(1) .Subscribe(cropLeft => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Left), nameof(this.CropLeft), cropLeft, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.CropRight) .Skip(1) .Subscribe(cropRight => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Right), nameof(this.CropRight), cropRight, raisePropertyChanged: false); }); // Auto-fill the cropping properties when type is Auto or None this.WhenAnyValue( x => x.CroppingType, x => x.MainViewModel.SelectedTitle, (croppingType, selectedTitle) => { return(new { croppingType, selectedTitle }); }) .Subscribe(x => { bool oldAutoValue = this.AutomaticChange; if (x.croppingType == VCCroppingType.None) { this.AutomaticChange = true; this.CropTop = 0; this.CropBottom = 0; this.CropLeft = 0; this.CropRight = 0; } else if (x.croppingType == VCCroppingType.Automatic) { this.AutomaticChange = true; if (x.selectedTitle == null) { this.CropTop = 0; this.CropBottom = 0; this.CropLeft = 0; this.CropRight = 0; } else { this.CropTop = x.selectedTitle.Crop[0]; this.CropBottom = x.selectedTitle.Crop[1]; this.CropLeft = x.selectedTitle.Crop[2]; this.CropRight = x.selectedTitle.Crop[3]; } } this.AutomaticChange = oldAutoValue; }); // When the preset changes, update the local crop values for Custom. this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(_ => { if (this.PresetsService.SelectedPreset.Preset.EncodingProfile.CroppingType == VCCroppingType.Custom) { bool oldAutoValue = this.AutomaticChange; this.AutomaticChange = true; var cropping = this.PresetsService.SelectedPreset.Preset.EncodingProfile.Cropping; this.CropLeft = cropping.Left; this.CropTop = cropping.Top; this.CropRight = cropping.Right; this.CropBottom = cropping.Bottom; this.AutomaticChange = oldAutoValue; } }); // PaddingUIEnabled this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, (sizingMode, paddingMode) => { if (sizingMode == VCSizingMode.Manual) { return(true); } return(paddingMode == VCPaddingMode.Custom); }).ToProperty(this, x => x.PaddingUIEnabled, out this.paddingUIEnabled); // Update the underlying profile when our local Pad properties change. this.WhenAnyValue(x => x.PadTop) .Skip(1) .Subscribe(padTop => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Top), nameof(this.PadTop), padTop, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.PadBottom) .Skip(1) .Subscribe(padBottom => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Bottom), nameof(this.PadBottom), padBottom, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.PadLeft) .Skip(1) .Subscribe(padLeft => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Left), nameof(this.PadLeft), padLeft, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.PadRight) .Skip(1) .Subscribe(padRight => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Right), nameof(this.PadRight), padRight, raisePropertyChanged: false); }); // Auto-fill the padding properties when UI is disabled this.WhenAnyValue( x => x.SizingMode, x => x.ScalingMode, x => x.PaddingMode, x => x.Width, x => x.Height, x => x.MainViewModel.SelectedTitle, (sizingMode, scalingMode, paddingMode, width, height, selectedTitle) => { return(new { sizingMode, scalingMode, paddingMode, width, height, selectedTitle }); }) .Subscribe(x => { bool oldAutoValue = this.AutomaticChange; if (x.sizingMode == VCSizingMode.Automatic && x.paddingMode == VCPaddingMode.None) { this.AutomaticChange = true; this.PadTop = 0; this.PadBottom = 0; this.PadLeft = 0; this.PadRight = 0; } else if (x.sizingMode == VCSizingMode.Automatic && x.paddingMode != VCPaddingMode.Custom) { if (x.selectedTitle == null) { this.PadTop = 0; this.PadBottom = 0; this.PadLeft = 0; this.PadRight = 0; } else { // Calculate the correct padding from input variables OutputSizeInfo outputSize = JsonEncodeFactory.GetOutputSize(this.Profile, x.selectedTitle); this.PadTop = outputSize.Padding.Top; this.PadBottom = outputSize.Padding.Bottom; this.PadLeft = outputSize.Padding.Left; this.PadRight = outputSize.Padding.Right; } } this.AutomaticChange = oldAutoValue; }); // When the preset changes, update the local pad values. this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(_ => { VCProfile profile = this.PresetsService.SelectedPreset.Preset.EncodingProfile; if (profile.SizingMode == VCSizingMode.Manual || profile.PaddingMode == VCPaddingMode.Custom) { bool oldAutoValue = this.AutomaticChange; this.AutomaticChange = true; var padding = profile.Padding; this.PadLeft = padding.Left; this.PadTop = padding.Top; this.PadRight = padding.Right; this.PadBottom = padding.Bottom; this.AutomaticChange = oldAutoValue; } }); this.AutomaticChange = false; }
private void RefreshPreviews() { this.job = this.mainViewModel.EncodeJob; OutputSizeInfo newOutputSizeInfo = this.outputSizeService.Size; int width = newOutputSizeInfo.OutputWidth; int height = newOutputSizeInfo.OutputHeight; int parWidth = newOutputSizeInfo.Par.Num; int parHeight = newOutputSizeInfo.Par.Den; if (parWidth <= 0 || parHeight <= 0) { this.HasPreview = false; StaticResolver.Resolve <IAppLogger>().LogError("HandBrake returned a negative pixel aspect ratio. Cannot show preview."); return; } if (width < 100 || height < 100) { this.HasPreview = false; return; } this.OutputSizeInfo = newOutputSizeInfo; var profile = this.PresetsService.SelectedPreset.Preset.EncodingProfile; this.PadColor = ColorUtilities.ToWindowsColor(profile.PadColor); // Update the number of previews. this.previewCount = this.ScanInstance.PreviewCount; foreach (PreviewImageServiceClient client in this.clients.Items) { if (client.PreviewIndex >= this.previewCount) { client.PreviewIndex = this.previewCount - 1; } } this.RaisePropertyChanged(nameof(this.PreviewCount)); this.HasPreview = true; lock (this.imageSync) { this.previewImageCache = new BitmapSource[this.previewCount]; updateVersion++; // Clear main work queue. this.previewImageWorkQueue.Clear(); // Clear old images out of the file cache. this.ClearImageFileCache(); this.imageFileSync = new List <object>(this.previewCount); for (int i = 0; i < this.previewCount; i++) { this.imageFileSync.Add(new object()); } this.BeginBackgroundImageLoad(); } }
private void RefreshPreviews() { this.originalScanInstance = this.ScanInstance; this.job = this.mainViewModel.EncodeJob; OutputSizeInfo newOutputSizeInfo = this.outputSizeService.Size; int width = newOutputSizeInfo.OutputWidth; int height = newOutputSizeInfo.OutputHeight; int parWidth = newOutputSizeInfo.Par.Num; int parHeight = newOutputSizeInfo.Par.Den; if (parWidth <= 0 || parHeight <= 0) { this.HasPreview = false; this.Title = PreviewRes.NoVideoSourceTitle; Ioc.Get <IAppLogger>().LogError("HandBrake returned a negative pixel aspect ratio. Cannot show preview."); return; } if (width < 100 || height < 100) { this.HasPreview = false; this.UpdateTitle(newOutputSizeInfo); return; } this.PreviewDisplayHeight = height; this.PreviewDisplayWidth = width * ((double)parWidth / parHeight); this.OutputSizeInfo = newOutputSizeInfo; var profile = this.PresetsService.SelectedPreset.Preset.EncodingProfile; this.PadColor = ColorUtilities.ToWindowsColor(profile.PadColor); // Update the number of previews. this.previewCount = this.ScanInstance.PreviewCount; if (this.selectedPreview >= this.previewCount) { this.selectedPreview = this.previewCount - 1; this.RaisePropertyChanged(nameof(this.SelectedPreview)); } this.RaisePropertyChanged(nameof(this.PreviewCount)); this.HasPreview = true; lock (this.imageSync) { this.previewImageCache = new BitmapSource[this.previewCount]; updateVersion++; // Clear main work queue. this.previewImageWorkQueue.Clear(); this.imageFileCacheFolder = Path.Combine( Utilities.ImageCacheFolder, Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture), updateVersion.ToString(CultureInfo.InvariantCulture)); if (!Directory.Exists(this.imageFileCacheFolder)) { Directory.CreateDirectory(this.imageFileCacheFolder); } // Clear old images out of the file cache. this.ClearImageFileCache(); this.imageFileSync = new List <object>(this.previewCount); for (int i = 0; i < this.previewCount; i++) { this.imageFileSync.Add(new object()); } this.BeginBackgroundImageLoad(); this.View?.RefreshImageSize(); } this.UpdateTitle(newOutputSizeInfo); }