using Microsoft.WindowsAPICodePack.Shell;
using System;
using System.Collections.Generic;
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.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace HistoryDLL
{
///
/// PlaneRotateMap.xaml 的互動邏輯
///
public partial class PlaneRotateMap : UserControl
{
//創造 PlaneRotateMap 物件
private delegate void CreatePlaneRotateMapDelegate();
private delegate void DynamicChangeLan();
private DispatcherTimer RotateWaitTime = new DispatcherTimer();
//該PlaneRotate中有幾個可以顯示的物件
private int ImageWidth, ImageHeight;
private List ElementForRotateList = new List();
private Rectangle RectForTouch = new Rectangle();
//當前顯示的物件是屬於ElementForRotateList中的第幾個索引
private int CurrentShowIndex = 0;
//該輪播塊是屬於該年事件中的第幾個索引
public int indexOfEvent = -1;
//亂數產生
private Random rnd = new Random(Guid.NewGuid().GetHashCode());
//切換資訊的亂數時間範圍 changeInfoTimeMin <= s < changeInfoTimeMax
private int changeInfoTimeMin = 8;
private int changeInfoTimeMax = 32;
//Other Number
private double RotateAngle = 10.0; //區塊旋轉時候的角度
private double TextFontSize = 23; //顯示的資訊如果是文字~則設定文字大小
private int RotateAnimationTime = 400;
private Storyboard sbStepOne = new Storyboard();
private DoubleAnimation dbOffsetOne = new DoubleAnimation();
private Storyboard sbStepTwo = new Storyboard();
private DoubleAnimation dbOffsetTwo = new DoubleAnimation();
private SolidColorBrush RotateContainColor = new SolidColorBrush(ConfigSettingClass.EventCollect.BackgroundColor);
private SolidColorBrush RotateContainTextColor = new SolidColorBrush(ConfigSettingClass.EventCollect.TextColor);
//判斷是否資料已經到底的紀錄的 Index
private int RecordInfoCount = 1;
//資料暫存
public MonthClass RotateMonthClass = new MonthClass();
private string[] imgfilter = { ".jpeg", ".jpg", ".bmp", ".png" };
private string[] mediafilter = { ".mp4", ".wmv", ".mpeg", "mpg", "avi" };
//該PlaneRotateMap在LiveContainer 中的哪個區塊
public int BlockIndex = -1;
public bool ChangeInfo = false;
public PlaneRotateMap()
{ InitializeComponent(); }
public PlaneRotateMap(MonthClass sourcemonthClass, int ImageWidth, int ImageHeight)
{
InitializeComponent();
if (GlobalFunction.isSolutionUsing4K)
TextFontSize *= 1.5;
//將暫時設定一下顏色
uxRotateContain.Background = RotateContainColor;
//設定翻轉頻率
SetRotateFreq();
//設定旋轉動作的相關Timer
SettingRotateMap();
RotateWaitTime.Tick += new EventHandler(RotateWaitTime_Tick);
//資料存到緩衝
RotateMonthClass = sourcemonthClass;
//設定寬高
uxRotateContain.Width = uxRotateMainGrid.Width = this.ImageWidth = ImageWidth;
uxRotateContain.Height = uxRotateMainGrid.Height = this.ImageHeight = ImageHeight;
//設定可觸控層
SetTouchLay(ImageWidth, ImageHeight);
//翻轉角度設定
uxMyPlanerator.FieldOfView = RotateAngle;
}
private void DynamicChangeLanEvent()
{
//第 0 個一定是文字
Grid gd = ElementForRotateList[0] as Grid;
TextBlock tb = gd.Children[0] as TextBlock;
//假如現在是第一種語系
if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language1")
{
tb.Text = RotateMonthClass.titleLan1;
}
else if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language2")
{
tb.Text = RotateMonthClass.titleLan2;
}
else if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language3")
{
tb.Text = RotateMonthClass.titleLan3;
}
else if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language4")
{
tb.Text = RotateMonthClass.titleLan4;
}
}
//動態改變 PlaneRotate 內容物件的語系
internal void ChangeLanByDynamic()
{
this.Dispatcher.BeginInvoke(new DynamicChangeLan(DynamicChangeLanEvent),
DispatcherPriority.Background);
}
private void SetRotateFreq()
{
changeInfoTimeMin = 8;
if (ConfigSettingClass.MainBackCollect.ScreenSetting == 1)
{
changeInfoTimeMax = 32;
}
else if (ConfigSettingClass.MainBackCollect.ScreenSetting == 2)
{
changeInfoTimeMax = 48;
}
else if (ConfigSettingClass.MainBackCollect.ScreenSetting == 3)
{
changeInfoTimeMax = 64;
}
}
internal void CreatePlaneRotateMap()
{
//透過RotateMonthClass取得該PlaneRotateMap 顯示資訊
GetInformationToShow();
}
private void GetInformationToShow()
{
System.Windows.Application.Current.Dispatcher.Invoke(new CreatePlaneRotateMapDelegate(AddRotateInfoToList), DispatcherPriority.Background);
//點擊區
uxRotateMainGrid.Children.Add(RectForTouch);
}
private void SettingRotateMap()
{
dbOffsetOne = new DoubleAnimation()
{
Duration = TimeSpan.FromMilliseconds(RotateAnimationTime),
EasingFunction = new PowerEase()
{
EasingMode = EasingMode.EaseIn,
Power = 2
},
};
dbOffsetOne.From = 0;
dbOffsetOne.To = 90;
dbOffsetTwo = new DoubleAnimation()
{
Duration = TimeSpan.FromMilliseconds(RotateAnimationTime),
EasingFunction = new PowerEase()
{
EasingMode = EasingMode.EaseOut,
Power = 2
},
};
dbOffsetTwo.From = -90;
dbOffsetTwo.To = 0;
Storyboard.SetTarget(dbOffsetOne, (DependencyObject)this.FindName("uxMyPlanerator"));
Storyboard.SetTargetProperty(dbOffsetOne, new PropertyPath(NLPlaneRotator.PlaneRotator.RotationXProperty));
sbStepOne.Children.Add(dbOffsetOne);
sbStepOne.FillBehavior = FillBehavior.HoldEnd;
sbStepOne.Completed += new EventHandler(sbStepOne_Completed);
Storyboard.SetTarget(dbOffsetTwo, (DependencyObject)this.FindName("uxMyPlanerator"));
Storyboard.SetTargetProperty(dbOffsetTwo, new PropertyPath(NLPlaneRotator.PlaneRotator.RotationXProperty));
sbStepTwo.Children.Add(dbOffsetTwo);
sbStepTwo.FillBehavior = FillBehavior.HoldEnd;
}
///
/// 旋轉
///
public void RotateTheObject()
{
sbStepOne.Begin();
}
public void sbStepOne_Completed(object sender, EventArgs e)
{
//改變資料
if (ChangeInfo)
{
SendChangeBlockIndex("Prepare", BlockIndex);
}
CurrentShowIndex++;
ChangeElementForShow(ref CurrentShowIndex);
sbStepTwo.Begin();
}
///
/// 判斷該資料是否已經到底了~如果是~則通知 LiveContainer
///
/// 紀錄已經播放幾筆資料
private void CheckTheFileEndToSend(ref int RecordInfoCount)
{
if (RecordInfoCount >= ElementForRotateList.Count)
{
//到底~將該區塊的索引值傳回 LiveContainer
SendChangeBlockIndex("DataEnd", BlockIndex);
}
}
///
/// 設定可觸控層以方便之後能夠點擊觸發
///
private void SetTouchLay(int ImageWidth, int ImageHeight)
{
RectForTouch.Width = ImageWidth;
RectForTouch.Height = ImageHeight;
RectForTouch.Fill = Brushes.Transparent;
RectForTouch.PreviewTouchDown += new EventHandler(RectForTouch_PreviewTouchDown);
}
void RectForTouch_PreviewTouchDown(object sender, TouchEventArgs e)
{
//通知被點擊
SendInfoToLiveContainer(indexOfEvent, CurrentShowIndex - 1);
}
///
/// 該PlaneRotate 顯示資訊
///
public void startShow()
{
//將紀錄設定為第一筆資料 <一開始會先顯示的資料>
RecordInfoCount = 1;
//一開始先顯示圖片或者文字(亂數取)
CurrentShowIndex = rnd.Next(0, ElementForRotateList.Count);
//透過索引值~改變要顯示的是該月份的第幾個資料~文字或者圖~?
ChangeElementForShow(ref CurrentShowIndex);
}
///
/// 停止該PlaneRotate自轉模式
///
public void stopShow()
{
//清除所有顯示資訊
uxRotateContain.Children.Clear();
ElementForRotateList.Clear();
RotateWaitTime.Stop();
}
///
/// 取得下次要翻轉的等待時間 (翻轉開始呼叫函數~)
///
public void StartCountDownForRatate()
{
//亂數取得
int time = rnd.Next(changeInfoTimeMin, changeInfoTimeMax);
RotateWaitTime.Interval = TimeSpan.FromSeconds(time);
RotateWaitTime.Start();
}
//如果等待時間到~則開始旋轉並在設定其下次要旋轉的等待時間
void RotateWaitTime_Tick(object sender, EventArgs e)
{
RotateWaitTime.Stop();
StartCountDownForRatate();
RotateTheObject();
#region 判斷是否資料已經到底
//該遍資料紀錄值加一
RecordInfoCount++;
//判斷該資料是否已經到底了~如果是~則通知 LiveContainer
CheckTheFileEndToSend(ref RecordInfoCount);
#endregion
}
///
/// 停止翻轉功能
///
public void StopCountDownForRatate()
{
RotateWaitTime.Stop();
}
///
/// 先將可以顯示的資訊放到 ElementForRotateList 中
///
private void AddRotateInfoToList()
{
ElementForRotateList.Clear();
#region 先加文字
Grid gridfortext = new Grid();
TextBlock textblock = new TextBlock();
if (ConfigSettingClass.MainBackCollect.DefaultLangIndex < ConfigSettingClass.MainBackCollect.LangFlowDir.Length)
{
textblock.FlowDirection = ConfigSettingClass.MainBackCollect.LangFlowDir[ConfigSettingClass.MainBackCollect.DefaultLangIndex];
}
try
{
//假如現在是第一種語系
if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language1")
{
textblock.Text = RotateMonthClass.titleLan1;
}
else if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language2")
{
textblock.Text = RotateMonthClass.titleLan2;
}
else if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language3")
{
textblock.Text = RotateMonthClass.titleLan3;
}
else if (System.Windows.Application.Current.Properties["Language"].ToString() == "Language4")
{
textblock.Text = RotateMonthClass.titleLan4;
}
}
catch
{
}
gridfortext.VerticalAlignment = System.Windows.VerticalAlignment.Center;
gridfortext.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
gridfortext.Width = ImageWidth;
gridfortext.Height = ImageHeight;
textblock.TextWrapping = TextWrapping.Wrap;
textblock.FontSize = TextFontSize;
textblock.Foreground = RotateContainTextColor;
textblock.Margin = new Thickness(10);
gridfortext.Children.Add(textblock);
ElementForRotateList.Add(gridfortext);
#endregion
#region 加圖片
//做法 : 先將 imagepath 路徑下的圖片縮圖, 之後放到 image controller 下再放到 ElementForRotateList 中
if (RotateMonthClass.imagepath != "")
{
string[] tempFile;
if (Directory.Exists(GlobalFunction.EventFileImgPath + RotateMonthClass.imagepath))
{
tempFile = Directory.GetFiles(GlobalFunction.EventFileImgPath + RotateMonthClass.imagepath);
// tempFile 為全部的圖片張數,避免記憶體吃太多~ 每個事件框以亂數載入五張為最多
int startupIndex = 0;
int targetIndex = 0;
bool startGet = true;
int maxLoadValue = 5;
if (tempFile.Count() > maxLoadValue)
{
startGet = false;
startupIndex = rnd.Next(0, tempFile.Count() - maxLoadValue);
}
foreach (string item in tempFile)
{
if (targetIndex != startupIndex && !startGet)
{
targetIndex++;
}
else
{
// 開始取圖
startGet = true;
if (maxLoadValue < 0)
break;
maxLoadValue--;
if (imgfilter.Contains(System.IO.Path.GetExtension(item).ToLower()))
{
Grid gd = new Grid();
Image img = new Image();
FileInfo fileinfo = new FileInfo(item);
string FilePath = fileinfo.FullName.ToString().Trim();
RenderOptions.SetBitmapScalingMode(img, BitmapScalingMode.HighQuality);
img.Source = MediaViewerLib.Utilities.MediaUtilties.LoadBitmapImage(FilePath, ImageWidth);
img.Stretch = Stretch.UniformToFill;
img.VerticalAlignment = System.Windows.VerticalAlignment.Center;
img.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
gd.Width = ImageWidth;
gd.Height = ImageHeight;
gd.Children.Add(img);
ElementForRotateList.Add(gd);
}
else if (mediafilter.Contains(System.IO.Path.GetExtension(item).ToLower()))
{
Grid gd = new Grid();
Image img = new Image();
FileInfo fileinfo = new FileInfo(item);
string FilePath = fileinfo.FullName.ToString().Trim();
// 影片取縮圖
RenderOptions.SetBitmapScalingMode(img, BitmapScalingMode.HighQuality);
ShellFile shellFile = ShellFile.FromFilePath(FilePath);
BitmapSource shellThumb = shellFile.Thumbnail.ExtraLargeBitmapSource;
img.Source = shellThumb;
img.Stretch = Stretch.UniformToFill;
img.VerticalAlignment = System.Windows.VerticalAlignment.Center;
img.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
gd.Width = ImageWidth;
gd.Height = ImageHeight;
gd.Children.Add(img);
ElementForRotateList.Add(gd);
}
}
}
}
}
#endregion
#region 加預設logo圖
//如果以上圖文只有一個有資料~則加上預設的圖
if (ElementForRotateList.Count <= 1 && ConfigSettingClass.MainBackCollect.ImgLogo != "")
{
string DefaultLogoPath = ConfigSettingClass.MainBackCollect.ImgLogo;
if (File.Exists(GlobalFunction.thumbPath + DefaultLogoPath))
{
Grid gd = new Grid();
Image img = new Image();
img.Source = MediaViewerLib.Utilities.MediaUtilties.LoadBitmapImage(GlobalFunction.thumbPath + DefaultLogoPath, ImageWidth);
img.Stretch = Stretch.Uniform;
img.VerticalAlignment = System.Windows.VerticalAlignment.Center;
img.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
gd.Width = ImageWidth;
gd.Height = ImageHeight;
gd.Children.Add(img);
ElementForRotateList.Add(gd);
}
}
#endregion
SendChangeBlockIndex("Load Complete", 0);
}
///
/// 增加事件~增加從 LiveContainer Callback Event
///
///
public void ListenFromLiveContainerCode(LiveContainer liveContainer)
{
liveContainer.LiveContainerBubbleToPlaneRotateEvent += new LiveContainer.LiveContainerBubbleToPlaneRotateMap(ReceiveFromLiveContainerForFileChange);
}
///
/// 將該索引加到uxRotateContain
///
/// 指向 ElementForRotateList 中的索引值
private void ChangeElementForShow(ref int index)
{
uxRotateContain.Children.Clear();
if (index >= ElementForRotateList.Count)
{
//超過資料上限~重頭播放
index = 0;
}
if (ElementForRotateList.Count == 0)
{
return;
}
uxRotateContain.Children.Add(ElementForRotateList[index]);
}
///
/// 取得圖片Source
///
/// 指定圖片路徑
///
private ImageSource GetBitmapImage(string imgpath)
{
BitmapImage bitmapImg = new BitmapImage();
bitmapImg.BeginInit();
bitmapImg.UriSource = new Uri(imgpath, UriKind.RelativeOrAbsolute);
//忽略原始圖檔的色盤設定,使用預設值,可縮短載入圖檔的時間
//如有遇到色彩不正確的問題,或者原圖有特殊的自定義色盤,請不要使用此設定
bitmapImg.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
//使用以下的預先載入設定,在BitmapImage創建完成之後,可立刻釋放其所占用或鎖住的資源,以免咬住檔案
bitmapImg.CacheOption = BitmapCacheOption.OnLoad;
//根據欲顯示的區域長或寬,來設定 DecodePixelHeight 或 DecodePixelWidth 的值
//bitmapImg.DecodePixelHeight = THUMB_HEIGHT;
//bitmapImg.DecodePixelWidth = THUMB_WIDTH;
bitmapImg.EndInit();
bitmapImg.Freeze();
return bitmapImg;
}
}
}