using Cosmos.Common; using Cosmos.ServiceProvider; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; namespace SPC.Kiosk.Common { /// /// SignPad.xaml에 대한 상호 작용 논리 /// public partial class SignPad : UserControl { #region [ Member ] /// /// Brush Color /// public static readonly DependencyProperty BrushColorProperty = DependencyProperty.Register(nameof(BrushColor), typeof(System.Windows.Media.Color), typeof(SignPad), new PropertyMetadata(Colors.Black, new PropertyChangedCallback(OnBrushColorPropertyChanged))); /// /// Brush Size /// public static readonly DependencyProperty BrushSizeProperty = DependencyProperty.Register(nameof(BrushSize), typeof(double), typeof(SignPad), new PropertyMetadata(5d, new PropertyChangedCallback(OnBrushSizePropertyChanged))); /// /// Background Color /// public static readonly DependencyProperty BackgroundColorProperty = DependencyProperty.Register(nameof(BackgroundColor), typeof(System.Windows.Media.Color), typeof(SignPad), new PropertyMetadata(Colors.White, new PropertyChangedCallback(OnBackgroundColorPropertyChanged))); /// /// Saved File /// public static readonly DependencyProperty SavedFileProperty = DependencyProperty.Register(nameof(SavedFile), typeof(string), typeof(SignPad), new PropertyMetadata(string.Empty)); /// /// SignData /// public static readonly DependencyProperty SignDataProperty = DependencyProperty.Register(nameof(SignData), typeof(string), typeof(SignPad), new PropertyMetadata(string.Empty)); /// /// SignPoints /// public static readonly DependencyProperty SignPointsProperty = DependencyProperty.Register(nameof(SignPoints), typeof(long), typeof(SignPad), new PropertyMetadata(0L, new PropertyChangedCallback(OnSignPointsPropertyChanged))); /// /// Useable Sign /// public static readonly DependencyProperty UseableSignProperty = DependencyProperty.Register(nameof(UseableSign), typeof(bool), typeof(SignPad), new PropertyMetadata(false)); /// /// TimeOutSeconds /// public static readonly DependencyProperty TimeOutSecondsProperty = DependencyProperty.Register(nameof(TimeOutSeconds), typeof(double), typeof(SignPad), new PropertyMetadata(0d, new PropertyChangedCallback(OnTimeOutSecondsPropertyChanged))); /// /// SignReset /// public static readonly DependencyProperty SignResetProperty = DependencyProperty.Register(nameof(SignReset), typeof(bool), typeof(SignPad), new PropertyMetadata(false, new PropertyChangedCallback(OnSignResetPropertyChanged))); /// /// SignEnd /// public static readonly DependencyProperty SignEndProperty = DependencyProperty.Register(nameof(SignEnd), typeof(bool), typeof(SignPad), new PropertyMetadata(false, new PropertyChangedCallback(OnSignEndPropertyChanged))); /// /// Brush Color /// public System.Windows.Media.Color BrushColor { get { return (System.Windows.Media.Color)GetValue(BrushColorProperty); } set { SetValue(BrushColorProperty, value); } } /// /// Brush Size /// public double BrushSize { get { return (double)GetValue(BrushSizeProperty); } set { SetValue(BrushSizeProperty, value); } } /// /// Background Color /// public System.Windows.Media.Color BackgroundColor { get { return (System.Windows.Media.Color)GetValue(BackgroundColorProperty); } set { SetValue(BackgroundColorProperty, value); } } /// /// Saved File /// public string SavedFile { get { return (string)GetValue(SavedFileProperty); } set { SetValue(SavedFileProperty, value); } } /// /// Sign Data /// public string SignData { get { return (string)GetValue(SignDataProperty); } set { SetValue(SignDataProperty, value); } } /// /// SignPoints /// public long SignPoints { get { return (long)GetValue(SignPointsProperty); } set { SetValue(SignPointsProperty, value); } } /// /// Useable Sign /// public bool UseableSign { get { return (bool)GetValue(UseableSignProperty); } set { SetValue(UseableSignProperty, value); } } /// /// TimeOutSeconds /// public double TimeOutSeconds { get { return (double)GetValue(TimeOutSecondsProperty); } set { SetValue(TimeOutSecondsProperty, value); } } /// /// SignReset /// public bool SignReset { get { return (bool)GetValue(SignResetProperty); } set { SetValue(SignResetProperty, value); } } /// /// SignEnd /// public bool SignEnd { get { return (bool)GetValue(SignEndProperty); } set { SetValue(SignEndProperty, value); } } private DateTime LastAccessTime { get; set; } = DateTime.Now; private DispatcherTimer SignTimer; #endregion #region [ Ctor / Etc] public SignPad() { try { InitializeComponent(); StrokeCollectionChangedEventHandler strokes_StrokesChanged = Strokes_StrokesChanged; inkCanvas.Strokes.StrokesChanged += strokes_StrokesChanged; inkCanvas.DefaultDrawingAttributes.Color = BrushColor; inkCanvas.DefaultDrawingAttributes.Height = BrushSize; inkCanvas.DefaultDrawingAttributes.Width = BrushSize; inkCanvas.DefaultDrawingAttributes.IgnorePressure = false; inkCanvas.DefaultDrawingAttributes.IsHighlighter = false; inkCanvas.DefaultDrawingAttributes.StylusTip = StylusTip.Ellipse; inkCanvas.Background = new SolidColorBrush(BackgroundColor); } catch (Exception ex) { CommonLog.ErrorLogWrite(this, "Ctor", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace)); } } private void SignPad_Unloaded(object sender, RoutedEventArgs e) { if (this.SignTimer != null) { SignTimer.Stop(); SignTimer.Tick -= SignTimer_Tick; SignTimer = null; } } #endregion #region [ Methods ] private void TimerEnable() { if (DesignerProperties.GetIsInDesignMode(this)) return; if (this.SignTimer != null) { LastAccessTime = DateTime.Now; this.SignTimer.Start(); } else { this.SignTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1), }; SignTimer.Tick += SignTimer_Tick; LastAccessTime = DateTime.Now; SignTimer.Start(); } } private void TimerDisable() { if (this.SignTimer != null) { this.SignTimer.Stop(); LastAccessTime = DateTime.Now; } } private void ConvertToBitmapSource() { try { var width = CommonValue.SignWidth; var height = CommonValue.SignHeight; var target = new RenderTargetBitmap((int)(inkCanvas.RenderSize.Width), (int)(inkCanvas.RenderSize.Height), 96, 96, PixelFormats.Default); var brush = new VisualBrush(inkCanvas); var visual = new DrawingVisual(); var drawingContext = visual.RenderOpen(); drawingContext.DrawRectangle(brush, null, new Rect(new System.Windows.Point(0, 0), new System.Windows.Point(inkCanvas.RenderSize.Width, inkCanvas.RenderSize.Height))); drawingContext.Close(); target.Render(visual); var bitmapSource = (BitmapSource)target.Clone(); var memoryStream = new MemoryStream(); var bmpBitmapEncoder = new BmpBitmapEncoder(); var bitmapFrame = BitmapFrame.Create(bitmapSource); bmpBitmapEncoder.Frames.Add(bitmapFrame); bmpBitmapEncoder.Save(memoryStream); using (var bitMap = new Bitmap(memoryStream)) { var targetSize = new System.Drawing.Size(width, height); var sizedImage = new Bitmap(bitMap, targetSize); var targetRectangle = new System.Drawing.Rectangle(0, 0, width, height); var lastImg = sizedImage.Clone(targetRectangle, System.Drawing.Imaging.PixelFormat.Format1bppIndexed); var filePath = ResourceManager.SignDataPath; if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath); var savedFile = System.IO.Path.Combine(filePath, CommonValue.SignFileName); lastImg.Save(savedFile, System.Drawing.Imaging.ImageFormat.Bmp); if (File.Exists(savedFile)) { var sManager = new SManager(); var m_cSignPad = (ISignPadUs)sManager.InitServiceInstance(ServiceLists.AGENT_OLEDEVICE.DLL, ServiceLists.AGENT_OLEDEVICE.DEVICE_SIGNPAD); var signData = string.Empty; if (m_cSignPad.GetSign_BmpToData(savedFile, ref signData)) { SignData = signData; SavedFile = savedFile; } m_cSignPad = null; sManager = null; } } } catch (Exception ex) { CommonLog.ErrorLogWrite(this, "ConvertToBitmapSource()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace)); } } private void CheckSignOK(long strokePoints) { if (strokePoints < CommonValue.SingPointsMin) { UseableSign = false; } else if (strokePoints >= CommonValue.SingPointsMin && strokePoints < CommonValue.SingPointsMax) { UseableSign = true; } else { UseableSign = false; } } #endregion #region [ Event Handlers ] private void SignTimer_Tick(object sender, EventArgs e) { if ((DateTime.Now - LastAccessTime) > TimeSpan.FromSeconds(TimeOutSeconds)) { TimerDisable(); if (UseableSign) { ConvertToBitmapSource(); inkCanvas.Strokes.Clear(); } else { TimerEnable(); } } } private static void OnSignEndPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SignPad target) { if (e.NewValue is bool newValue && newValue) { target.TimerDisable(); target.ConvertToBitmapSource(); target.inkCanvas.Strokes.Clear(); target.SignEnd = false; } } } private static void OnSignResetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SignPad target) { if (e.NewValue is bool newValue && newValue) { target.LastAccessTime = DateTime.Now; target.inkCanvas.Strokes.Clear(); target.SignReset = false; } } } private static void OnTimeOutSecondsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SignPad target) { if (e.NewValue is double newTimeout && newTimeout > 0 ) { target.TimerEnable(); } } } private static void OnBrushColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SignPad target) { target.inkCanvas.DefaultDrawingAttributes.Color = (System.Windows.Media.Color)e.NewValue; } } private static void OnBackgroundColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SignPad target) { target.inkCanvas.Background = new SolidColorBrush((System.Windows.Media.Color)e.NewValue); } } private static void OnBrushSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SignPad target) { target.inkCanvas.DefaultDrawingAttributes.Height = (double)e.NewValue < 1 ? 1 : (double)e.NewValue; target.inkCanvas.DefaultDrawingAttributes.Width = (double)e.NewValue < 1 ? 1 : (double)e.NewValue; } } private static void OnSignPointsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SignPad target) { if (e.NewValue is long strokePoints) { target.CheckSignOK(strokePoints); } } } private void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e) { LastAccessTime = DateTime.Now; var signPoints = 0L; foreach (var aStroke in inkCanvas.Strokes) { signPoints += aStroke.StylusPoints.Count; } SignPoints = signPoints; } #endregion } }