using Microsoft.Win32;
using NEIntelligentControl2.Models;
using NEIntelligentControl2.Models.BoostStation;
using NEIntelligentControl2.Models.Datas;
using NEIntelligentControl2.Models.Messages;
using NEIntelligentControl2.Service.User;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace NEIntelligentControl2.Pages.BoostStation
{
///
/// 升压站页面
///
public partial class PageStation : Page
{
public static readonly DependencyProperty AngleProperty = DependencyProperty.Register("Angle", typeof(int), typeof(PageStation));
public static readonly DependencyProperty DataTagProperty = DependencyProperty.Register("DataTag", typeof(string), typeof(PageStation));
public static readonly DependencyProperty CoordinateProperty = DependencyProperty.Register("Coordinate", typeof(Point), typeof(PageStation));
public static readonly DependencyProperty IsEditModelProperty = DependencyProperty.Register("IsEditModel", typeof(bool), typeof(PageStation));
public static readonly DependencyProperty IsNegateProperty = DependencyProperty.Register("IsNegate", typeof(bool), typeof(PageStation));
///
/// 控件方向
///
public int Angle { get => (int)GetValue(AngleProperty); set => SetValue(AngleProperty, value); }
///
/// 数据标签
///
public string DataTag { get => GetValue(DataTagProperty) as string; set => SetValue(DataTagProperty, value); }
///
/// 控件坐标
///
public Point Coordinate { get => (Point)GetValue(CoordinateProperty); set => SetValue(CoordinateProperty, value); }
///
/// 是否取反
///
public bool IsNegate { get => (bool)GetValue(IsNegateProperty); set => SetValue(IsNegateProperty, value); }
private Control _CurrentControl;
private Control _TempleteControl;
private bool _IsSelectAction;
public BoostStationInfo StationInfo { get; set; }
///
/// 保存动作
///
public Action SaveAction { get; set; }
///
/// 是否被编辑
///
private bool IsEdited;
///
/// 是否继续刷新数据
///
private bool _IsRefreshData;
///
/// 所有数据点
///
private List _BoostStationPoints;
///
/// 数据地址
///
private string _Url = "";
///
/// 是否是编辑模式
///
public bool IsEditModel { get => (bool)GetValue(IsEditModelProperty); set => SetValue(IsEditModelProperty, value); }
///
/// 服务地址
///
private string _InfoUrl = "";
///
/// 单击时间
///
private DateTime _ClickTime;
private string _BackgroundOld;
private static readonly object locker = new object();
private UserManager _UserManager;
private WEBHelper _WEBHelper;
public PageStation(UserManager um, WEBHelper web)
{
InitializeComponent();
_UserManager = um;
_WEBHelper = web;
try
{
#if (DEBUG)
_InfoUrl = ConfigurationManager.AppSettings["ServicePathDebug"];
#else
_InfoUrl = ConfigurationManager.AppSettings["ServicePath"];
#endif
}
catch (Exception ex)
{
Console.WriteLine("读取配置文件[ServicePath]出错!", ex);
}
}
private void Init()
{
_BoostStationPoints = new List();
try
{
if (!string.IsNullOrWhiteSpace(StationInfo.Background))
{
BitmapImage image = GetBackgroundImage(StationInfo.Background);
_Canvas.Background = new ImageBrush(image) { Stretch = Stretch.Uniform };
}
}
catch { }
_Canvas.Children.Clear();
foreach (var v in StationInfo.BoostStationPointInfos)
{
try
{
var obj = Activator.CreateInstance(Type.GetType($"NEIntelligentControl2.Views.BoostStation.{v.Type}")) as IBoostStationPoint;
if (obj == null)
{
continue;
}
_BoostStationPoints.Add(obj);
obj.DataTag = v.DataTag;
obj.Proportion = v.Proportion;
obj.Info = v.Info;
obj.IsNegate = v.IsNegate;
var ct = obj as Control;
Canvas.SetLeft(ct, v.Coordinate.X);
Canvas.SetTop(ct, v.Coordinate.Y);
ct.RenderTransform = GetTransform(v);
_Canvas.Children.Add(ct);
}
catch { }
}
var keys = string.Join(",", _BoostStationPoints.Where(b => !string.IsNullOrWhiteSpace(b.DataTag)).Select(b => b.DataTag).ToArray());
try
{
#if (DEBUG)
var ul = ConfigurationManager.AppSettings["DataServicePathDebug"];
#else
var ul = ConfigurationManager.AppSettings["DataServicePath"];
#endif
_Url = $"{ul}/ts/latest?keys={keys}";
}
catch (Exception ex)
{
Console.WriteLine("读取配置文件[DataServicePath]出错!", ex);
}
}
private void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_CurrentControl?.ReleaseMouseCapture();
if (e.OriginalSource != sender) return;
ClosePopup();
}
private void ClosePopup(bool isSelect = false)
{
if (!isSelect)
{
AllNotSelect();
}
if (!_Popup.IsOpen)
{
return;
}
_Popup.IsOpen = false;
var sp = _CurrentControl as IBoostStationPoint;
if (sp == null) return;
sp.DataTag = this.DataTag;
sp.IsNegate = this.IsNegate;
Canvas.SetLeft(_CurrentControl, Coordinate.X);
Canvas.SetTop(_CurrentControl, Coordinate.Y);
_CurrentControl = null;
IsEdited = true;
}
private void AllNotSelect()
{
var vvs = GetSelectedItems();
foreach (var v in vvs)
{
var issp = v as IBoostStationPoint;
if (issp != null)
{
issp.IsSelected = false;
}
}
}
private Transform GetTransform()
{
RotateTransform rt = new RotateTransform();
if (_TempleteControl != null)
{
RotateTransform ort = _TempleteControl.RenderTransform as RotateTransform;
rt.Angle = ort.Angle;
rt.CenterX = ort.CenterX;
rt.CenterY = ort.CenterY;
}
return rt;
}
private Transform GetTransform(Control obj)
{
RotateTransform rt = new RotateTransform();
rt.Angle = this.Angle;
rt.CenterX = obj.ActualWidth / 2;
rt.CenterY = obj.ActualHeight / 2;
return rt;
}
private Transform GetTransform(BoostStationPointInfo v)
{
RotateTransform rt = new RotateTransform();
rt.Angle = v.Angle;
rt.CenterX = v.CenterCoordinate.X;
rt.CenterY = v.CenterCoordinate.Y;
return rt;
}
///
/// 小控件被单击
///
private void PointClicked(Control c)
{
if ((c as IBoostStationPoint).IsTemplete)
{
TempleteClicked();
}
else
{
SelectClicked(c);
}
}
private void SelectClicked(Control c)
{
_ClickTime = DateTime.Now;
if (_Popup.IsOpen)
{
ClosePopup(true);
}
_CurrentControl = c;
_CurrentControl.CaptureMouse();
Coordinate = new Point(Canvas.GetLeft(c), Canvas.GetTop(c));
DataTag = (c as IBoostStationPoint).DataTag;
IsNegate = (c as IBoostStationPoint).IsNegate;
_Popup.IsOpen = true;
_LBISelect.Focus();
}
private void TempleteClicked()
{
var obj = Activator.CreateInstance(_TempleteControl.GetType()) as Control;
if (obj == null) return;
(obj as IBoostStationPoint).Clicked = PointClicked;
(obj as IBoostStationPoint).IsEditModel = true;
(obj as IBoostStationPoint).Proportion = (_TempleteControl as IBoostStationPoint).Proportion;
Canvas.SetLeft(obj, Canvas.GetLeft(_TempleteControl));
Canvas.SetTop(obj, Canvas.GetTop(_TempleteControl));
obj.RenderTransform = GetTransform();
_Canvas.Children.Add(obj);
IsEdited = true;
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (_IsSelectAction)
{
if (e.LeftButton != MouseButtonState.Pressed || e.OriginalSource == _Canvas || (DateTime.Now - _ClickTime).TotalMilliseconds < 300) return;
MovePoint(_CurrentControl, e);
_Popup.IsOpen = false;
}
else if (_TempleteControl != null)
{
MovePoint(_TempleteControl, e);
}
}
private void _Canvas_MouseLeave(object sender, MouseEventArgs e)
{
if (_TempleteControl == null) return;
_TempleteControl.Visibility = Visibility.Collapsed;
if (_Popup.IsOpen)
{
_Popup.IsOpen = false;
}
}
private void _Canvas_MouseEnter(object sender, MouseEventArgs e)
{
if (_TempleteControl == null) return;
_TempleteControl.Visibility = Visibility.Visible;
}
private void ListBoxItem_Selected(object sender, RoutedEventArgs e)
{
string action = ((Control)sender).Tag as string;
_IsSelectAction = action == "Select";
if (_TempleteControl != null)
{
_Canvas.Children.Remove(_TempleteControl);
}
if (_IsSelectAction)
{
_CurrentControl = null;
_TempleteControl?.ReleaseMouseCapture();
_TempleteControl = null;
}
else
{
_TempleteControl?.CaptureMouse();
}
var ct = Type.GetType($"NEIntelligentControl2.Views.BoostStation.{action}");
if (ct == null) return;
var obj = Activator.CreateInstance(ct);
if (!(obj is IBoostStationPoint)) return;
(obj as IBoostStationPoint).IsTemplete = true;
(obj as IBoostStationPoint).IsEditModel = true;
(obj as IBoostStationPoint).Clicked = PointClicked;
_TempleteControl = obj as Control;
_TempleteControl.Loaded += PointLoaded;
_Canvas.Children.Add(obj as Control);
}
private void PointLoaded(object sender, RoutedEventArgs e)
{
Control c = sender as Control;
if (c == null) return;
c.RenderTransform = GetTransform(c);
}
private void MovePoint(FrameworkElement c, MouseEventArgs e)
{
if (c == null) return;
Point p = e.GetPosition(_Canvas);
Canvas.SetTop(c, p.Y - c.ActualHeight / 2);
Canvas.SetLeft(c, p.X - c.ActualWidth / 2);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
switch (((Control)sender).Tag)
{
case "angle":// 角度
AngleChange();
break;
case "background":// 选择背景图片
ChoseBackground();
break;
case "delete":// 删除
DeletePoint();
break;
case "save":// 保存
Save();
break;
case "close":// 放弃保存
Close();
break;
case "narrow":// 缩小控件
Narrow();
break;
case "enlarge":// 放大控件
Enlarge();
break;
default: return;
}
}
///
/// 放大控件
///
private void Enlarge()
{
if (_CurrentControl != null)
{
(_CurrentControl as IBoostStationPoint).Zoom(1);
}
if (_TempleteControl != null)
{
(_TempleteControl as IBoostStationPoint).Zoom(1);
}
}
///
/// 缩小控件
///
private void Narrow()
{
if (_CurrentControl != null)
{
(_CurrentControl as IBoostStationPoint).Zoom(-1);
}
if (_TempleteControl != null)
{
(_TempleteControl as IBoostStationPoint).Zoom(-1);
}
}
private void Close()
{
var v = MessageBox.Show("放弃保存?", "提示", MessageBoxButton.YesNo);
if (v != MessageBoxResult.Yes) return;
if (StationInfo.Background != _BackgroundOld)
{
StationInfo.Background = _BackgroundOld;
BitmapImage image = GetBackgroundImage(StationInfo.Background);
_Canvas.Background = new ImageBrush(image) { Stretch = Stretch.Uniform };
}
ToNormalModel();
}
///
/// 回到正常模式
///
private void ToNormalModel()
{
_ToolPane.Visibility = Visibility.Collapsed;
IsEdited = false;
IsEditModel = false;
_Popup.IsOpen = false;
lock (locker)
{
Init();
}
}
///
/// 保存
///
private void Save()
{
try
{
if (!IsEdited)
{
ToNormalModel();
return;
}
if (_TempleteControl == null)
{
_Canvas.Children.Remove(_TempleteControl);
_TempleteControl = null;
}
StationInfo.BoostStationPointInfos = GetBoostStationPointInfo();
StationInfo.UpdatedDate = DateTime.Now.Ticks;
SaveAction?.Invoke(StationInfo);
ToNormalModel();
}
catch (Exception e) { Console.WriteLine(e.ToString()); }
}
///
/// 获取所有控件信息
///
///
private List GetBoostStationPointInfo()
{
List bspis = new List();
foreach (var v in _Canvas.Children)
{
if (!(v is IBoostStationPoint))
{
continue;
}
var point = v as IBoostStationPoint;
var ct = v as Control;
BoostStationPointInfo bspi = new BoostStationPointInfo();
bspi.Type = v.GetType().Name;
bspi.DataTag = point.DataTag;
bspi.Proportion = point.Proportion;
bspi.Info = point.Info;
bspi.IsNegate = point.IsNegate;
RotateTransform rotate = ct.RenderTransform as RotateTransform;
if (rotate != null)
{
bspi.CenterCoordinate = new Point(rotate.CenterX, rotate.CenterY);
bspi.Angle = (int)rotate.Angle;
}
Point pt = new Point(Canvas.GetLeft(ct), Canvas.GetTop(ct));
bspi.Coordinate = pt;
bspis.Add(bspi);
}
return bspis;
}
///
/// 更改角度
///
private void AngleChange()
{
Angle = Angle >= 270 ? 0 : Angle + 90;
if (_CurrentControl != null)
{
_CurrentControl.RenderTransform = GetTransform(_CurrentControl);
}
if (_TempleteControl != null)
{
var tr = _TempleteControl.RenderTransform as RotateTransform;
tr.Angle = this.Angle;
_TempleteControl.RenderTransform = tr;
}
var vs = GetSelectedItems();
foreach (var v in vs)
{
v.RenderTransform = GetTransform(v);
}
IsEdited = true;
}
///
/// 删除标签点
///
private void DeletePoint()
{
List list = GetSelectedItems();
if (list.Count <= 0) return;
foreach (var v in list)
{
_Canvas.Children.Remove(v);
}
IsEdited = true;
}
private List GetSelectedItems()
{
List ls = new List();
foreach (var v in _Canvas.Children)
{
var c = v as IBoostStationPoint;
if (c == null || !c.IsSelected) continue;
ls.Add(c as Control);
}
return ls;
}
private void ChoseBackground()
{
var dl = new OpenFileDialog();
dl.Filter = "图片(.png)|*.png";
dl.Title = "选择背景图片";
var b = dl.ShowDialog();
if (b == null || b == false) return;
try
{
_BackgroundOld = StationInfo.Background;
StationInfo.Background = GetBackgroundByFile(dl.FileName);
BitmapImage image = GetBackgroundImage(StationInfo.Background);
_Canvas.Background = new ImageBrush(image) { Stretch = Stretch.Uniform };
IsEdited = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
///
/// 从文件中获取背景图片文字
///
///
private string GetBackgroundByFile(string url)
{
var bs = File.ReadAllBytes(url);
return Convert.ToBase64String(bs);
}
private BitmapImage GetBackgroundImage(string v)
{
if (string.IsNullOrWhiteSpace(v)) return null;
BitmapImage bt = new BitmapImage();
bt.BeginInit();
bt.CacheOption = BitmapCacheOption.OnLoad;
var bs = Convert.FromBase64String(v);
using (Stream stream = new MemoryStream(bs))
{
bt.StreamSource = stream;
bt.EndInit();
bt.Freeze();
}
return bt;
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
switch (((Control)sender).Tag)
{
case "edit":// 编辑
EditModel();
break;
}
}
///
/// 开启编辑模式
///
private void EditModel()
{
if (!_UserManager.IsLogined || _UserManager.User.Level != Models.User.UserLevel.Administrator)
{
MessageBox.Show("请登录管理员账号进入编辑模式!", "提示:", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
_BackgroundOld = StationInfo.Background;
IsEditModel = true;
_ToolPane.Visibility = Visibility.Visible;
foreach (var v in _Canvas.Children)
{
var bsp = v as IBoostStationPoint;
if (bsp == null) continue;
bsp.Clicked = PointClicked;
bsp.IsEditModel = true;
}
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
Init();
this._IsRefreshData = true;
Task.Factory.StartNew(RefreshData, TaskCreationOptions.LongRunning);
Task.Factory.StartNew(CheckUpdate, TaskCreationOptions.LongRunning);
}
///
/// 检查更新
///
private async void CheckUpdate()
{
while (_IsRefreshData)
{
try
{
var dtstr = _WEBHelper.HttpGetString($"{_InfoUrl}/api/station/boost_station/update_time/{StationInfo.Id}");
long.TryParse(dtstr, out long dt);
if (dt > 0 && dt != StationInfo.UpdatedDate)
{
var info = _WEBHelper.HttpGetJSON($"{_InfoUrl}/api/station/boost_station/{StationInfo.Id}");
Dispatcher.Invoke(() =>
{
lock (locker)
{
StationInfo = info;
Init();
}
});
}
}
catch { }
await Task.Delay(10000);
}
}
private async void RefreshData()
{
while (_IsRefreshData)
{
try
{
var vs = _WEBHelper.HttpGetJSON>(_Url);
if (vs != null && vs.Count > 0)
{
Dispatcher?.Invoke(() =>
{
lock (locker)
{
foreach (var v in _BoostStationPoints)
{
if (string.IsNullOrWhiteSpace(v.DataTag))
{
continue;
}
if (vs.ContainsKey(v.DataTag))
{
v.Value = vs[v.DataTag].Value;
}
}
}
});
}
Console.WriteLine($"刷新:{StationInfo.Id}");
}
catch { }
await Task.Delay(2000);
}
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
this._IsRefreshData = false;
if (IsEdited)
{
var v = MessageBox.Show("有未保存的改动,是否保存?", "提示:", MessageBoxButton.YesNo);
if (v == MessageBoxResult.Yes)
{
Save();
}
}
if (IsEditModel)
{
ToNormalModel();
}
}
private void _Canvas_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
if (_Popup.IsOpen)
{
ClosePopup();
}
_LBTools.SelectedIndex = 0;
}
private void Direction_Click(object sender, RoutedEventArgs e)
{
if (_CurrentControl == null) return;
int dtop = 0;
int dleft = 0;
switch (((Control)sender).Tag)
{
case "left":
dleft = -1;
break;
case "right":
dleft = 1;
break;
case "up":
dtop = -1;
break;
case "down":
dtop = 1;
break;
default: return;
}
double top = Canvas.GetTop(_CurrentControl) + dtop;
double left = Canvas.GetLeft(_CurrentControl) + dleft;
Coordinate = new Point(left, top);
Canvas.SetTop(_CurrentControl, top);
Canvas.SetLeft(_CurrentControl, left);
}
}
}