From 7dd3f7183c87fc133e58e0a393e4463037d998ee Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Thu, 18 Jul 2019 01:12:53 +0800 Subject: [PATCH] add basic codes --- .../UserControl/Controls/GifImageDemoCtl.xaml | 6 +- .../Controls/ImageBlockDemoCtl.xaml | 18 ++- .../Controls/Image/GifImage.cs | 26 ++- .../Controls/Image/ImageBlock.cs | 153 ++++++++++++++++-- 4 files changed, 181 insertions(+), 22 deletions(-) diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml index a35701a0..0b4a7597 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/GifImageDemoCtl.xaml @@ -4,10 +4,6 @@ xmlns:hc="https://handyorg.github.io/handycontrol" Background="{DynamicResource RegionBrush}"> - - - - - + diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml index e0db05bd..7b94f8bc 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/ImageBlockDemoCtl.xaml @@ -1,6 +1,18 @@  - - + xmlns:userControl="clr-namespace:HandyControlDemo.UserControl" + xmlns:hc="https://handyorg.github.io/handycontrol"> + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs b/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs index 98557f94..e352119a 100644 --- a/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs +++ b/src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs @@ -33,6 +33,22 @@ namespace HandyControl.Controls VisibilityProperty.OverrideMetadata(typeof(GifImage), new PropertyMetadata(default(Visibility), OnVisibilityChanged)); } + public static readonly DependencyProperty UriProperty = DependencyProperty.Register( + "Uri", typeof(Uri), typeof(GifImage), new PropertyMetadata(default(Uri), OnUriChanged)); + + private static void OnUriChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (GifImage) d; + var v = (Uri)e.NewValue; + ctl.Source = new BitmapImage(v); + } + + public Uri Uri + { + get => (Uri) GetValue(UriProperty); + set => SetValue(UriProperty, value); + } + private static void OnVisibilityChanged(DependencyObject s, DependencyPropertyChangedEventArgs e) { var ctl = (GifImage)s; @@ -56,10 +72,14 @@ namespace HandyControl.Controls if (DesignerProperties.GetIsInDesignMode(this)) return; if (_isLoaded) return; _isLoaded = true; - if (Source is BitmapImage image) + if (Uri != null) { - var uri = image.UriSource; - GetGifStreamFromPack(uri); + GetGifStreamFromPack(Uri); + StartAnimate(); + } + else if (Source is BitmapImage image) + { + GetGifStreamFromPack(image.UriSource); StartAnimate(); } }; diff --git a/src/Shared/HandyControl_Shared/Controls/Image/ImageBlock.cs b/src/Shared/HandyControl_Shared/Controls/Image/ImageBlock.cs index 8a55f7b8..d11fb550 100644 --- a/src/Shared/HandyControl_Shared/Controls/Image/ImageBlock.cs +++ b/src/Shared/HandyControl_Shared/Controls/Image/ImageBlock.cs @@ -1,24 +1,111 @@ -using System.Windows; +using System; +using System.Windows; using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Threading; using HandyControl.Data; namespace HandyControl.Controls { public class ImageBlock : FrameworkElement { - public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( - "Source", typeof(ImageSource), typeof(ImageBlock), new FrameworkPropertyMetadata(default(ImageSource), - FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender)); + private readonly DispatcherTimer _dispatcherTimer; - public ImageSource Source + private int _indexMax; + + private int _indexMin; + + private int _currentIndex; + + public ImageBlock() { - get => (ImageSource) GetValue(SourceProperty); - set => SetValue(SourceProperty, value); + _dispatcherTimer = new DispatcherTimer + { + Interval = Interval + }; + _dispatcherTimer.Tick += DispatcherTimer_Tick; + _dispatcherTimer.Start(); + } + + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) + { + base.OnRenderSizeChanged(sizeInfo); + OnPositionsChanged(); + } + + private void DispatcherTimer_Tick(object sender, EventArgs e) => InvalidateVisual(); + + public static readonly DependencyProperty StartColumnProperty = DependencyProperty.Register( + "StartColumn", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + private void OnPositionsChanged() + { + _indexMin = StartRow * Columns + StartColumn; + _indexMax = EndRow * Columns + EndColumn; + } + + private static void OnPositionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ImageBlock)d; + ctl.OnPositionsChanged(); + } + + public int StartColumn + { + get => (int) GetValue(StartColumnProperty); + set => SetValue(StartColumnProperty, value); + } + + public static readonly DependencyProperty StartRowProperty = DependencyProperty.Register( + "StartRow", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + public int StartRow + { + get => (int) GetValue(StartRowProperty); + set => SetValue(StartRowProperty, value); + } + + public static readonly DependencyProperty EndColumnProperty = DependencyProperty.Register( + "EndColumn", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + public int EndColumn + { + get => (int) GetValue(EndColumnProperty); + set => SetValue(EndColumnProperty, value); + } + + public static readonly DependencyProperty EndRowProperty = DependencyProperty.Register( + "EndRow", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnPositionsChanged)); + + public int EndRow + { + get => (int) GetValue(EndRowProperty); + set => SetValue(EndRowProperty, value); + } + + public static readonly DependencyProperty IsPlayingProperty = DependencyProperty.Register( + "IsPlaying", typeof(bool), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnIsPlayingChanged)); + + private static void OnIsPlayingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ImageBlock)d; + ctl._dispatcherTimer.IsEnabled = (bool) e.NewValue; + } + + public bool IsPlaying + { + get => (bool) GetValue(IsPlayingProperty); + set => SetValue(IsPlayingProperty, value); } public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( "Columns", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int1Box, - FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender)); + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), obj => (int)obj >= 1); public int Columns { @@ -28,7 +115,7 @@ namespace HandyControl.Controls public static readonly DependencyProperty RowsProperty = DependencyProperty.Register( "Rows", typeof(int), typeof(ImageBlock), new FrameworkPropertyMetadata(ValueBoxes.Int1Box, - FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender)); + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), obj => (int)obj >= 1); public int Rows { @@ -36,11 +123,55 @@ namespace HandyControl.Controls set => SetValue(RowsProperty, value); } + public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register( + "Interval", typeof(TimeSpan), typeof(ImageBlock), new PropertyMetadata(TimeSpan.FromSeconds(1), OnIntervalChanged)); + + private static void OnIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (ImageBlock) d; + ctl._dispatcherTimer.Interval = (TimeSpan) e.NewValue; + } + + public TimeSpan Interval + { + get => (TimeSpan) GetValue(IntervalProperty); + set => SetValue(IntervalProperty, value); + } + + public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( + "Source", typeof(ImageSource), typeof(ImageBlock), new FrameworkPropertyMetadata(default(ImageSource), + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender)); + + public ImageSource Source + { + get => (ImageSource)GetValue(SourceProperty); + set => SetValue(SourceProperty, value); + } + protected override void OnRender(DrawingContext dc) { - var imageSource = Source; + if (Source != null && Source is BitmapSource source) + { + // ReSharper disable once AssignNullToNotNullAttribute + var croppedBitmap = new CroppedBitmap(source, CalDisplayRect()); + dc.DrawImage(croppedBitmap, new Rect(0, 0, RenderSize.Width, RenderSize.Height)); + } + } - if (imageSource != null) dc.DrawImage(imageSource, new Rect(new Point(), RenderSize)); + private Int32Rect CalDisplayRect() + { + if (_currentIndex > _indexMax) + { + _currentIndex = _indexMin; + } + + var x = (int) (_currentIndex % Columns * RenderSize.Width); + // ReSharper disable once PossibleLossOfFraction + var y = (int) (_currentIndex / Columns * RenderSize.Height); + + var rect = new Int32Rect(x, y, (int)RenderSize.Width, (int)RenderSize.Height); + _currentIndex++; + return rect; } } } \ No newline at end of file