[code]// Flags, used with GdiDrawText
// For more information, see:
http://msdn.microsoft.com/en-us/library/dd162498(VS.85).aspxvar DT_TOP = 0x00000000;
var DT_LEFT = 0x00000000;
var DT_CENTER = 0x00000001;
var DT_RIGHT = 0x00000002;
var DT_VCENTER = 0x00000004;
var DT_BOTTOM = 0x00000008;
var DT_WORDBREAK = 0x00000010;
var DT_SINGLELINE = 0x00000020;
var DT_EXPANDTABS = 0x00000040;
var DT_TABSTOP = 0x00000080;
var DT_NOCLIP = 0x00000100;
var DT_EXTERNALLEADING = 0x00000200;
var DT_CALCRECT = 0x00000400;
var DT_NOPREFIX = 0x00000800;
var DT_INTERNAL = 0x00001000;
var DT_EDITCONTROL = 0x00002000;
var DT_PATH_ELLIPSIS = 0x00004000;
var DT_END_ELLIPSIS = 0x00008000;
var DT_MODIFYSTRING = 0x00010000;
var DT_RTLREADING = 0x00020000;
var DT_WORD_ELLIPSIS = 0x00040000;
var DT_NOFULLWIDTHCHARBREAK = 0x00080000;
var DT_HIDEPREFIX = 0x00100000;
var DT_PREFIXONLY = 0x00200000;
// -- flags
var TextRenderingHint = {
SystemDefault: 0, // Glyph with system default rendering hint
SingleBitPerPixelGridFit: 1, // Glyph bitmap with hinting
SingleBitPerPixel: 2, // Glyph bitmap without hinting
AntiAliasGridFit: 3, // Glyph anti-alias bitmap with hinting
AntiAlias: 4, // Glyph anti-alias bitmap without hinting
ClearTypeGridFit: 5 // Glyph ClearType bitmap with hinting
};
// FYI, you can combine these flags using '|' operator
var FontStyle = {
Regular: 0,
Bold: 1,
Italic: 2,
BoldItalic: 3,
Underline: 4,
Strikeout: 8
};
// FYI:
http://msdn.microsoft.com/en-us/library/sy...ent(VS.71).aspxvar StringAlignment = {
Near: 0,
Center: 1,
Far: 2
};
// FYI:
http://msdn.microsoft.com/en-us/library/sy...ing(VS.71).aspxvar StringTrimming = {
None: 0,
Character: 1,
Word: 2,
EllipsisCharacter: 3,
EllipsisWord: 4,
EllipsisPath: 5
};
// FYI:
http://msdn.microsoft.com/en-us/library/sy...ags(VS.71).aspxvar StringFormatFlags = {
DirectionRightToLeft: 0x00000001,
DirectionVertical : 0x00000002,
NoFitBlackBox: 0x00000004,
DisplayFormatControl: 0x00000020,
NoFontFallback: 0x00000400,
MeasureTrailingSpaces: 0x00000800,
NoWrap: 0x00001000,
LineLimit: 0x00002000,
NoClip: 0x00004000,
BypassGDI: 0x80000000
}
// Flags of Menu
var MF_SEPARATOR = 0x00000800;
var MF_GRAYED = 0x00000001;
var MF_UNCHECKED = 0x00000000;
var MF_CHECKED = 0x00000008;
var MF_STRING = 0x00000000;
var MF_POPUP = 0x00000010;
// Used window.SetCursor();
var IDC_ARROW = 32512;
var IDC_HAND = 32649;
function RGB(r,g,b){ return (0xff000000|(r<<16)|(g<<
|(b)); }
function RGBA(r, g, b, a) {
r &= 0xff; g &= 0xff; b &= 0xff; a &= 0xff;
return ((a << 24) | (r << 16) | (g <<
| (b));
}
function StringFormat(h_align, v_align, trim, flag) {return ((h_align << 28) | (v_align << 24) | (trim << 20) | flag);}
var CursorFollowMode = {
Auto : 1,
OnlyStoped : 2,
Always : 3,
Never : 4
}
// Math.floor 取 <=
// Math.round 取 四舍五入
// Math.ceil 取 >=
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var WshShell = new ActiveXObject("WScript.Shell");
var Properties = new GetProperties();
/* ━━━━━━━━━━━━━━━━ GetProperteis Function ━━━━━━━━━━━━━━━━*/
function GetProperties(){
// 1 ---------------------------------------------------------------------
// The buttons's images / Help File /
this.WorkDirectory = fb.TitleFormat(window.GetProperty("01.Panel.WorkDirectory", "Images\\EIKO\\WSH TrackInfo Panel\\")).Eval(true);
// All needed Strings.
this.StrArray = window.GetProperty("02.Panel.StrArray", "");
// Cursor Follow Mode
this.CursorFollowMode = window.GetProperty("03.Panel.CursorFollowMode", CursorFollowMode.Always);
this.CursorFollowAutoRefreshInterval = window.GetProperty("03_Panel.CursorFollowAutoRefreshInterval", 5000);
if (this.StrArray.length < 1){
this.StrArray = "WSH TrackInfo Panel,path does not exist.,file does not exist.,Cursor Follow Mode,Auto,Only Stoped,Always,Never,Properties,Help...";
//this.StrArray = "WSH 音轨属性,路径不存在。,文件不存在,光标跟随模式,自动,仅在非播放时,总是,从不,属性,帮助...";
window.SetProperty("02.Panel.StrArray", this.StrArray);
}
this.StrArray = this.StrArray.split(",");
for(var i = 0; i < this.StrArray.length; i++)
this.StrArray
= this.StrArray.replace(/\^/g,",");
if (this.WorkDirectory && this.WorkDirectory.indexOf(":") < 0)
this.WorkDirectory = fb.FoobarPath + this.WorkDirectory;
var path = this.WorkDirectory;
if (this.WorkDirectory && path.substring(path.length-1,path.length) != "\\") // must be end with "\\"
this.WorkDirectory = path + "\\";
if (!FSO.FolderExists(this.WorkDirectory))
WshShell.Popup("Properties\r01.Panel.WorkDirectory\r\r\" " + this.WorkDirectory + " \"\r" + this.StrArray[1], 7, this.StrArray[0], 0 + 16);
else{
// Help file
this.HelpFile = this.WorkDirectory + "WSH TrackInfo Help.txt";
}
if (this.CursorFollowMode < CursorFollowMode.Auto){
this.CursorFollowMode = CursorFollowMode.Auto;
window.SetProperty("03.Panel.CursorFollowMode", this.CursorFollowMode);
}
else if (this.CursorFollowMode > CursorFollowMode.Never){
this.CursorFollowMode = CursorFollowMode.Never;
window.SetProperty("03.Panel.CursorFollowMode", this.CursorFollowMode);
}
if (this.CursorFollowAutoRefreshInterval < 2000){
this.CursorFollowAutoRefreshInterval = 2000;
window.SetProperty("03_Panel.CursorFollowAutoRefreshInterval", this.CursorFollowAutoRefreshInterval);
}
this.Group = {
Height : window.GetProperty("04.Group.Height", 25),
LeftMargin : window.GetProperty("05.Group.LeftMargin", 2),
RightMargin : window.GetProperty("06.Group.RightMargin", 2),
PenColor : window.GetProperty("07.Group.Pen.Color", "67,121,182,160"),
BrushColor : window.GetProperty("08.Group.Brush.Color", "67,121,182,160"),
Font : window.GetProperty("09.Group.Font", "Segoe UI, 13, 1"),
FontColor : window.GetProperty("10.Group.Font.Color", "250,250,218"),
Font2 : window.GetProperty("11.Group.Font2", "Segoe UI, 11, 2"),
Font2Color : window.GetProperty("12.Group.Font2.Color", "0,64,128")
}
if (this.Group.LeftMargin < 0){
this.Group.LeftMargin = 0;
window.SetProperty("05.Group.LeftMargin", this.Group.LeftMargin);
}
if (this.Group.RightMargin < 2){
this.Group.RightMargin = 2;
window.SetProperty("06.Group.RightMargin", this.Group.RightMargin);
}
this.Group.PenColor = CheckColor(this.Group.PenColor);
this.Group.BrushColor = CheckColor(this.Group.BrushColor);
this.Group.Font = SetFont(this.Group.Font);
this.Group.Font2 = SetFont(this.Group.Font2);
this.Group.FontColor = CheckColor(this.Group.FontColor);
this.Group.Font2Color = CheckColor(this.Group.Font2Color);
this.Item = {
VerticalOffset : window.GetProperty("13.Item.Vertical.Offset", 5),
Key_Val : window.GetProperty("14.Item.Key : Val", "0.382 : 0.618"),
Separator : window.GetProperty("15.Item.Separator", " : "),
KeyFont : window.GetProperty("16.Item.Key.Font", "Segoe UI, 12, 0"),
KeyFontColor : window.GetProperty("17.Item.Key.Font.Color", "128,128,64"),
ValFont : window.GetProperty("18.Item.Value.Font", "Arial Rounded MT Bold, 12, 0"),
ValFontColor : window.GetProperty("19.Item.Value.Font.Color", "0,64,128")
}
if (this.Item.VerticalOffset < 0){
this.Item.VerticalOffset = 0;
window.SetProperty("13.Item.Vertical.Offset", this.Item.VerticalOffset);
}
if (this.Item.Key_Val.indexOf(":") <= 0){
this.Item.Key_Val = "0.382:0.618";
window.SetProperty("14.Item.Key_Val", this.Item.Key_Val);
}
this.Item.Key_Val = this.Item.Key_Val.split(":");
this.Item.Key_Val = this.Item.Key_Val[0] / (Math.abs(this.Item.Key_Val[0]) + Math.abs(this.Item.Key_Val[1]));
this.Item.KeyFont = SetFont(this.Item.KeyFont);
this.Item.ValFont = SetFont(this.Item.ValFont);
this.Item.KeyFontColor = CheckColor(this.Item.KeyFontColor);
this.Item.ValFontColor = CheckColor(this.Item.ValFontColor);
this.Groups = new Array(
{
Caption : window.GetProperty("20.TrackInfo.caption", "音轨信息"),
Items: new Array (
{ caption : window.GetProperty("21.title.caption", "标题"),
tf : window.GetProperty("22.title.tf", "$caps2($trim($if2(%title%,'N/A')))")
},
{ caption : window.GetProperty("23.artist.caption", "艺人"),
tf : window.GetProperty("24.artist.tf", "$caps2($trim($if2(%artist%,'N/A')))")
},
{ caption : window.GetProperty("25.album.caption", "专辑"),
tf : window.GetProperty("26.album.tf", "$caps2($trim($if2(%album%,'N/A')))")
},
{ caption : window.GetProperty("27.track#.caption", "索引"),
tf : window.GetProperty("28.track#.tf", "$if2(%tracknumber%,'N/A')")
},
{ caption : window.GetProperty("29.date.caption", "发行"),
tf : window.GetProperty("30.date.tf", "$if2(%date%,'N/A')")
},
{ caption : window.GetProperty("31.genre.caption", "流派"),
tf : window.GetProperty("32.genre.tf", "$if2(%genre%,'N/A')")
},
{ caption : window.GetProperty("33.comment.caption", "注释"),
tf : window.GetProperty("34.comment.tf", "$if(%comment%,$fix_eol(%comment%),)")
}
)
},
{
Caption : window.GetProperty("35.TechInfo.caption", "技术信息"),
Items: new Array (
{ caption : window.GetProperty("36.codec.caption", "编码格式"),
tf : window.GetProperty("37.codec.tf", "%codec%$if2(' ('%codec_profile%')',)")
},
{ caption : window.GetProperty("38.description.caption", "编码配置"),
tf : window.GetProperty("39.description.tf", "$put(desc,)$if($stricmp(%__codec%,MP3),$put(desc,'MPEG-1 Audio Layer 3'),)$if($stricmp(%__codec%,AAC),$put(desc,'Advanced Audio Coding'),)$if($stricmp(%__codec%,FLAC),$put(desc,'Free Lossless Audio Codec'),)$if($stricmp(%__codec%,ATSC A/52),$put(desc,'Dolby Digital AC3'),)$if($stricmp(%__codec%,Vorbis),$put(desc,$caps($ext(%_filename_ext%))' File'),)$if($stricmp(%__codec%,PCM),$put(desc,'Wave'),)$if($or($stricmp($ext(%_filename_ext%),mka),$stricmp($ext(%_filename_ext%),mkv)),$put(desc,'Matroska'),)$if($stricmp($cut(%__codec%,6),Monkey),$put(desc,'Lossless Audio Compressor'),)$if($stricmp(%__codec%,Musepack),$put(desc,'MPEGPlus/MP+'),)$if($stricmp(%__codec%,MP2),$put(desc,'MPEG-1 Audio Layer 2'),)$if($stricmp(%__codec%,CDDA),$put(desc,'CD Digital Audio'),)$if($stricmp(%__codec%,wma),$put(desc,'Windows Media Audio'),)$if($stricmp($get(desc),),$put(desc,$upper($ext(%_filename_ext% file))),)")
},
{ caption : window.GetProperty("40.bitrate.caption", "比特率"),
tf : window.GetProperty("41.bitrate.tf", "%bitrate% 'KBPS'")
},
{ caption : window.GetProperty("42.samplerate.caption", "采样率"),
tf : window.GetProperty("43.samplerate.tf", "%samplerate%' Hz'")
},
{ caption : window.GetProperty("44.channels.caption", "声道"),
tf : window.GetProperty("45.channels.tf", "$if($stricmp($codec(),MP3),$get(space2)$caps(%__mp3_stereo_mode%),$if(%__channels%,$ifgreater(%__channels%,1,Stereo,Mono),$if($strcmp(%__channels%,4),4 Ch,$sub(%__channels%,1)'.1' Ch)))")
},
{ caption : window.GetProperty("46.length.caption", "长度"),
tf : window.GetProperty("47.length.tf", "$if2(%length%, N/A)")
}
)
},
{
Caption : window.GetProperty("48.UserInfo.caption", "用户信息"),
Items: new Array (
{ caption : window.GetProperty("49.palycount.caption", "播放次数"),
tf : window.GetProperty("50.playcount.tf", "$if2(%play_count%,'Never Played')")
},
{ caption :window.GetProperty("51.rating.caption", "评定星级"),
tf : window.GetProperty("52.rating.tf", "%rating%")
},
{ caption :window.GetProperty("53.added.caption", "添加日期"),
tf : window.GetProperty("54.added.tf", "$if2(%added%,)")
},
{ caption :window.GetProperty("55.firstplayed.caption", "首次播放"),
tf : window.GetProperty("56.firstplayed.tf", "$if2(%first_played%,)")
},
{ caption :window.GetProperty("57.lastplayed.caption", "上次播放"),
tf : window.GetProperty("58.lastplayed.tf", "$if2(%last_played%,)")
},
{ caption :window.GetProperty("59.lyrics.caption", "内嵌歌词"),
tf : window.GetProperty("60.lyrics.tf", "$if2(%lyrics%,)")
},
{ caption :window.GetProperty("61.trackgain.caption", "音轨增益"),
tf : window.GetProperty("62.trackgain.tf", "$if2(%replaygain_track_gain%,)")
},
{ caption :window.GetProperty("63.albumgain.caption", "专辑增益"),
tf : window.GetProperty("64.albumgain.tf", "$if2(%replaygain_album_gain%,)")
}
)
},
{
Caption : window.GetProperty("65.FileInfo.caption", "文件信息"),
Items: new Array (
{ caption : window.GetProperty("66.filename.caption", "文件名"),
tf : window.GetProperty("67.filename.tf", "%filename_ext%")
},
{ caption : window.GetProperty("68.filepath.caption", "路径"),
tf : window.GetProperty("69.filepath.tf", "$directory_path(%path%)")
},
{ caption : window.GetProperty("70.filesize.caption", "大小"),
tf : window.GetProperty("71.filesize.tf", "%filesize_natural%")
},
{ caption : window.GetProperty("72.referenced_file.caption", "引用文件"),
tf : window.GetProperty("73.referenced_file.tf", "$info(referenced_file)")
},
{ caption : window.GetProperty("74.referenced_filesize.caption", "引用文件大小"),
tf : window.GetProperty("75.referenced_filesize.tf", "$info(referenced_file)")
}
)
},
{
Caption : window.GetProperty("76.ExtraInfo.caption", "附加信息"),
Items: new Array (
{ caption : window.GetProperty("77.www.caption", "www"),
tf : window.GetProperty("78.www.tf", "$if(%www%,$lower(%www%),)")
},
{ caption : window.GetProperty("79.style.caption", "风格"),
tf : window.GetProperty("80.style.tf", "$if2(%style%,)")
}
)
},
{
Caption : window.GetProperty("81.LastfmInfo.caption", "Last.fm电台信息"),
Items: new Array (
{ caption : window.GetProperty("82.similarartists.caption", "相近艺术家"),
tf : window.GetProperty("83.similarartists.tf", "$if(%lastfm_similar_artist%,$replace(%lastfm_similar_artist%,'&','and'),)")
},
{ caption : window.GetProperty("84.artistplaycount.caption", "点播次数"),
tf : window.GetProperty("85.artistplaycount.tf", "$if2(%lastfm_artist_playcount%,)")
},
{ caption : window.GetProperty("86.listeners.caption", "听众"),
tf : window.GetProperty("87.listeners.tf", "$if2(%lastfm_artist_listeners%,)")
}
)
}
)
}
var Y0 = 0;
var sumheight = 0;
var Group_x, Group_width;
var Key_x, Key_width, Value_x, Value_width ;
var Scrollbar = new fScrollbar();
var MouseY;
var PopMenu = new PopMenuFunc(Properties);
//──────────────────────── Define Groups ────────────────────────
var Groups = new Array();
for (var i = 0; i < Properties.Groups.length; i++){
var Items1 = new Array();
for (var j = 0; j < Properties.Groups.Items.length; j++){
if (i == 2 && j == 1) // Add Rating Item.
var Item1 = new ARatingItem(Properties.Groups[2].Items[1].caption + Properties.Item.Separator, null)
else
var Item1 = new AItem(Properties.Groups.Items[j].caption + Properties.Item.Separator, null);
Items1.push(Item1);
}
var Group1 = new AGroup(Properties.Groups.Caption, Items1);
Groups.push(Group1);
}
//──────────────────────── AGroup function ────────────────────────
var img_col = gdi.image(Properties.WorkDirectory + "\\col.png");
var Group_TextFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS;
var glength_TextFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS;
function AGroup(ATitle, Items){
this.x = 0; this.y = 0; this.width = 0; this.height = 0;
this.Title = ATitle;
this.Items = Items;
this.Collapsed = false;
var Prop = Properties;
this.CalcLayout = function(gr){
var visible = false;
for (var i = 0; i < this.Items.length; i++){
if (this.Items.Value.length > 0){
visible = true;
break;
}
}
if (!visible){
this.height = 0;
return;
}
this.header = {
x : this.x,
y : this.y,
width : this.width,
height : Prop.Group.Height
}
this.height = this.header.height;
this.ItemsVisible = 0;
if (this.Collapsed) return;
// calculator items.y .height and groups.height .itemsvisible...
for (var i = 0; i< this.Items.length; i++) {
this.Items.CalcPos(gr);
if (this.Items.Pos.height > 0){
this.height = this.height + this.Items.Pos.height + Prop.Item.VerticalOffset;
this.ItemsVisible ++;
}
}
this.Items[0].Pos.y = this.header.y + this.header.height + Math.floor(Prop.Item.VerticalOffset / 2);
if (this.Items[0].Pos.height > 0)
this.Items[0].Pos.height = this.Items[0].Pos.height + Prop.Item.VerticalOffset;
for (var i = 1; i< this.Items.length; i++) {
this.Items.Pos.y = this.Items[i-1].Pos.y + this.Items[i-1].Pos.height;
if (this.Items.Pos.height > 0)
this.Items.Pos.height = this.Items.Pos.height + Prop.Item.VerticalOffset;
}
}
this.draw = function(gr){
if (this.height == 0) return;
gr.FillRoundRect(this.header.x+1, Y0 + this.header.y + 3, this.header.width-2, this.header.height-6, 3, 3, Prop.Group.BrushColor);
gr.DrawRoundRect(this.header.x, Y0 + this.header.y + 2, this.header.width, this.header.height-4, 3, 3, 1, Prop.Group.PenColor);
gr.DrawImage(img_col, this.x+7, Y0 + this.y +(this.header.height -10)/2, 10, 10, this.Collapsed ? (this.MouseInHeader ? 10 : 0) : (this.MouseInHeader ? 30: 20), 0, 10, 10, 0, 255);
gr.GdiDrawText(this.Title, Prop.Group.Font, RGB(20,20,20), this.header.x + 23, Y0 + this.header.y+1, this.header.width - 40, this.header.height, Group_TextFormat);
gr.GdiDrawText(this.Title, Prop.Group.Font, Prop.Group.FontColor, this.header.x + 22, Y0 + this.header.y, this.header.width - 40, this.header.height, Group_TextFormat);
gr.GdiDrawText("(" + this.ItemsVisible + "/" + this.Items.length + ")", Prop.Group.Font2, Prop.Group.Font2Color, this.header.x + 20, Y0 + this.header.y, this.header.width -40, this.header.height, glength_TextFormat);
if (this.Collapsed) return;
for (var i = 0; i< this.Items.length; i++) {
this.Items.draw(gr);
}
}
this.MouseInHeader = false;
this.Refresh = false;
this.ContainXY = function (x, y) {
if (this.width <= 0 || this.height <=0) return;
this.MouseInHeader = (this.header.x <= x) && (x <= this.header.x + this.header.width) && (Y0 + this.header.y <= y) && (y <= Y0 + this.header.y + this.header.height);
if (!this.MouseInHeader && this.Refresh) {
window.RepaintRect(this.x+5, Y0 + this.y, 15, this.header.height);
this.Refresh = false;
}
if (this.MouseInHeader && !this.Refresh) {
window.RepaintRect(this.x+5, Y0 + this.y, 15, this.header.height);
this.Refresh = true;
}
return this.MouseInHeader;
}
this.Click = function(){
this.Collapsed = !this.Collapsed;
GetScrollbarVisible ();
if (Scrollbar.visible && Y0 < window.height - sumheight) {
Y0 = window.height - sumheight - Groups[0].y;
if (Y0 > 0) Y0 = 0;
}
window.Repaint();
}
}
// for %bitrate_dynamic%;//RGB(255,0,0);
var DynamicColor = Properties.Item.ValFontColor;
Groups[1].Items[2].draw = function(gr){
gr.GdiDrawText(this.Key, Properties.Item.KeyFont, Properties.Item.KeyFontColor, Key_x, Y0 + this.Pos.y, Key_width, this.Pos.height, Key_TextFormat);
gr.DrawString(this.Value, Properties.Item.ValFont, DynamicColor, Value_x, Y0 + this.Pos.y, Value_width, this.Pos.height, Value_StringFormat);
}
//──────────────────────── AItem Function ────────────────────────
var Key_TextFormat = DT_RIGHT | DT_TOP | DT_SINGLELINE | DT_WORD_ELLIPSIS;
var Value_StringFormat = StringFormat(StringAlignment.Near, StringAlignment.Near, 0, StringFormatFlags.BypassGDI);
function AItem(AKey, AValue){
this.Key = AKey;
this.Value = AValue;
this.CalcPos = function(gr){
this.Pos = GetStringInfo(gr, this.Value, Properties.Item.ValFont, Value_x, 0, Value_width, window.height, Value_StringFormat);
}
this.draw = function(gr){
gr.GdiDrawText(this.Key, Properties.Item.KeyFont, Properties.Item.KeyFontColor, Key_x, Y0 + this.Pos.y, Key_width, this.Pos.height, Key_TextFormat);
gr.DrawString(this.Value, Properties.Item.ValFont, Properties.Item.ValFontColor, Value_x, Y0 + this.Pos.y, Value_width, this.Pos.height, Value_StringFormat);
}
}
var RatingProp = new RatingProperties();
var Rating = new RatingFunc(0,3,124,16);
function ARatingItem(AKey, AValue){
this.Key = AKey;
this.Value = AValue;
this.CalcPos = function (){
this.Pos = {
x : Value_x,
y : 0,
width : Value_width,
height : Math.max(Properties.Item.KeyFont.Height, 16),
lines : 1,
chars : 0
}
}
this.draw = function(gr){
gr.GdiDrawText(this.Key, Properties.Item.KeyFont, Properties.Item.KeyFontColor, Key_x, Y0 + this.Pos.y, Key_width, this.Pos.height, Key_TextFormat);
Rating.x = Value_x;
Rating.y = Y0 + this.Pos.y - 2;
Rating.OnPaint(gr);
}
}
/* ━━━━━━━━━━━━━━━━ Set Cursor Follow Mode Function ━━━━━━━━━━━━━━━━
Entrance, To get the Image.metadb
*/
var CursorFollowAutoTimer;
function SetCursorFollowMode(AFollowMode){
if (AFollowMode != Properties.CursorFollowMode) {
Properties.CursorFollowMode = AFollowMode;
window.SetProperty("03.Panel.CursorFollowMode", AFollowMode);
/* Only for WSH Cover Viewer of Window Info */
window.NotifyOthers("InfoPanelCursorFollowMode", AFollowMode);
CursorFollow(AFollowMode);
}
}
function CursorFollow(AFollowMode){
KillCursorFollowAutoTimer();
if (AFollowMode == CursorFollowMode.Auto){
if (fb.IsPlaying | fb.IsPaused)
on_playback_new_track()
else
on_item_focus_change();
}
else if (AFollowMode == CursorFollowMode.OnlyStoped) {
if (fb.IsPlaying | fb.IsPaused)
on_playback_new_track()
else
on_item_focus_change();
}
else if (AFollowMode == CursorFollowMode.Always) {
on_item_focus_change();
}
else { //CursorFollowMode.Never
if (fb.IsPlaying | fb.IsPaused)
on_playback_new_track()
else
on_playback_stop();
}
SkipFocus = null;
}
/* ━━━━━━━━━━━━━━━━ Callbacks ━━━━━━━━━━━━━━━━*/
function GetScrollbarVisible (gr){
// Initially, assume that Scrollbar.visible = true.
Scrollbar.visible = true;
var newGroup_width= Group_width - 15;
Key_x = Group_x;
Key_width = Math.ceil(newGroup_width * Properties.Item.Key_Val);
Value_x = Key_x + Key_width;
Value_width = newGroup_width - Key_width;
for (i = 0; i<Groups.length; i++){
Groups.x = Group_x;
Groups.width = newGroup_width;
}
for (var i = 0; i<Groups.length; i++){
if (i > 0) Groups.y = Groups[i-1].y + Groups[i-1].height;
Groups.CalcLayout(gr);
}
sumheight = 0;
for (i = 0; i<Groups.length; i++){
sumheight = sumheight + Groups.height;
}
// end Scrollbar.visible = true;
if (sumheight <= window.height){
Scrollbar.visible = false;
Y0 = 0;
var newGroup_width= Group_width;
Key_x = Group_x;
Key_width = Math.ceil(newGroup_width * Properties.Item.Key_Val);
Value_x = Key_x + Key_width;
Value_width = newGroup_width - Key_width;
for (i = 0; i<Groups.length; i++){
Groups.x = Group_x;
Groups.width = newGroup_width;
}
for (var i = 0; i<Groups.length; i++){
if (i > 0) Groups.y = Groups[i-1].y + Groups[i-1].height;
Groups.CalcLayout(gr);
}
sumheight = 0;
for (i = 0; i<Groups.length; i++){
sumheight = sumheight + Groups.height;
}
}
}
function on_paint(gr){
if (!window.Width || !window.Height) return;
gr.SetSmoothingMode(2);
gr.SetTextRenderingHint(TextRenderingHint.ClearTypeGridFit);
GetScrollbarVisible (gr);
if (Scrollbar.visible)
Scrollbar.draw(gr);
for (var i = 0; i<Groups.length; i++){
Groups.draw(gr);
}
}
var OnIni; //Initialization, for skipfocus only at initialization in on_playback_new_track(metadb);
function on_size() {
if(window.width<=0 || window.height <=0) return;
OnIni = true;
Group_x = Properties.Group.LeftMargin;
Group_width = window.width - Properties.Group.LeftMargin - Properties.Group.RightMargin;
Scrollbar.x = window.width - 14;
Scrollbar.y = 1;
Scrollbar.width = 17;
Scrollbar.height = window.height - 2;
if (Scrollbar.visible && Y0 < window.height - sumheight) {
Y0 = window.height - sumheight - Groups[0].y;
if (Y0 > 0) Y0 = 0;
}
if (!Groups[0].Items[0].Value)
CursorFollow(Properties.CursorFollowMode);
OnIni = null;
}
var SkipFocus;
function on_playback_new_track(metadb){
if (Properties.CursorFollowMode == CursorFollowMode.Auto && CursorFollowAutoTimer){
return;
}
if (Properties.CursorFollowMode == CursorFollowMode.Auto ||
Properties.CursorFollowMode == CursorFollowMode.OnlyStoped ||
Properties.CursorFollowMode == CursorFollowMode.Never){
var metadb = fb.GetNowPlaying();
Y0 = 0;
on_metadb_changed(metadb);
if(!OnIni && fb.CursorFollowPlayback)
SkipFocus = true;
}
}
function on_item_focus_change(){
if (SkipFocus){
SkipFocus = null;
return;
}
if (Properties.CursorFollowMode == CursorFollowMode.Auto ||
((Properties.CursorFollowMode == CursorFollowMode.OnlyStoped) && (!fb.IsPlaying && !fb.IsPaused)) ||
Properties.CursorFollowMode== CursorFollowMode.Always
)
{
if (Properties.CursorFollowMode == CursorFollowMode.Auto && (fb.IsPlaying | fb.IsPaused)){
KillCursorFollowAutoTimer();
CursorFollowAutoTimer = window.ClearTimeout(Properties.CursorFollowAutoRefreshInterval);
}
var metadb = fb.GetFocusItem();
on_metadb_changed(metadb);
}
}
// cmd: (integer, begin with 0): default, play, next, prev, settrack, rand, resume:0123456
function on_playback_starting(cmd, is_paused) {
// Skip all on_stop procedure playing immediately after stoped.
if (StopTimer){
KillStopTimer();
return;
}
}
var StopTimer;
function KillStopTimer(){
if (StopTimer){
StopTimer = null;
CollectGarbage();
}
}
// reason: (integer, begin with 0): user, eof, starting_another, shutting_down:0123
function on_playback_stop(reason) {
// If a command will playing immediately after stoped(like prev, next etc.), on_stop procedure will be skiped in on_starting().
if (reason || reason == 0){
StopTimer = window.SetInterval(on_timer, 10);
return;
}
// The real Stop, will come back from on_timer(), but reason will be null.
if (Properties.CursorFollowMode == CursorFollowMode.Auto && CursorFollowAutoTimer){
KillCursorFollowAutoTimer();
return;
}
if (Properties.CursorFollowMode == CursorFollowMode.Always)
return;
if (Properties.CursorFollowMode == CursorFollowMode.Auto || Properties.CursorFollowMode == CursorFollowMode.OnlyStoped)
var metadb = fb.GetFocusItem()
else if (Properties.CursorFollowMode == CursorFollowMode.Never)
var metadb = null;
Y0 = 0;
on_metadb_changed(metadb);
}
// for dynamic_info
var displaying_metadb;
function on_metadb_changed(metadb, fromhook) {
for (var i = 0; i < Groups.length; i++){
for (var j = 0; j < Groups.Items.length; j++)
Groups.Items[j].Value = metadb ? fb.TitleFormat(Properties.Groups.Items[j].tf).EvalWithMetadb(metadb) : "N/A";
}
// rating
Rating.GetRating(metadb);
// reference_file size
if (metadb && Groups[3].Items[4].Value.length > 0){
var path = fb.TitleFormat("$directory_path(%path%)").EvalWithMetadb(metadb) + "\\" + Groups[3].Items[4].Value;
var size = FSO.GetFile(path).Size;
if (size > 1024*1024)
size = Math.floor(size/1024/1024*100)/100 + "MB"
else if (size > 1024)
size = Math.floor(size/1024*100)/100 + "KB"
else
size = size + "Bytes";
Groups[3].Items[4].Value = size;
}
// dynamic_info
DynamicColor = Properties.Item.ValFontColor;
displaying_metadb = metadb;
if (Y0 !=0){
GetScrollbarVisible ();
if (Scrollbar.visible && Y0 < window.height - sumheight) {
Y0 = window.height - sumheight - 5;
if (Y0 > 0) Y0 = 0;
}
}
CollectGarbage();
window.Repaint();
if (metadb)
window.WatchMetadb(metadb)
else
window.UnWatchMetadb();
}
function on_playback_dynamic_info() {
if (IsFocusPlaying(displaying_metadb, fb.GetNowPlaying())){
Groups[1].Items[2].Value = fb.TitleFormat("%__bitrate_dynamic%").Eval(true) + " KBPS";
if (DynamicColor == Properties.Item.ValFontColor)
DynamicColor = RGB(255,255,255)
else
DynamicColor = Properties.Item.ValFontColor;
if (Groups[1].Items[2].Pos)
window.RepaintRect(Value_x, Y0 + Groups[1].Items[2].Pos.y, Value_width, Groups[1].Items[2].Pos.height);
}
}
// Per-track dynamic info (stream track titles etc) change. Happens less often than on_playback_dynamic_info().
function on_playback_dynamic_info_track() {
if (IsFocusPlaying(displaying_metadb, fb.GetNowPlaying())){
Groups[1].Items[2].Value = fb.TitleFormat("%__bitrate_dynamic%").Eval(true) + " KBPS";
if (DynamicColor == Properties.Item.ValFontColor)
DynamicColor = RGB(255,255,255)
else
DynamicColor = Properties.Item.ValFontColor;
window.RepaintRect(Value_x, Y0 + Groups[1].Items[2].Pos.y, Value_width, Groups[1].Items[2].Pos.height);
}
}
function on_mouse_move(x,y){
if (Scrollbar.visible)
Scrollbar.containXY(x,y);
if (Scrollbar.mousedown)
Scrollbar.mouse_move(x,y)
else{
for (var i = 0; i<Groups.length; i++)
Groups.ContainXY(x,y);
if (!Groups[2].Collapsed)
Rating.OnMouseMove(x, y);
var cs = IDC_ARROW;
for (var i = 0; i<Groups.length; i++)
if (Groups.MouseInHeader){
cs = IDC_HAND;
break;
}
if (Rating.ContainXY)
cs = IDC_HAND
window.SetCursor(cs);
}
}
function on_mouse_lbtn_down(x,y){
MouseY = y;
if (Scrollbar.direction == "pos")
Scrollbar.mousedown = true
else if (Scrollbar.direction != "")
Scrollbar.mouse_lbtn_down(x,y);
if (!Groups[2].Collapsed)
Rating.OnMouseLbtnDown(x, y);
}
function on_mouse_lbtn_up(x,y){
//if (Scrollbar.mousedown) {
Scrollbar.direction = "";
Scrollbar.mousedown = false;
Scrollbar.timer = null;
CollectGarbage(); // Release memory.
//}
//else {
for (i = 0; i<Groups.length; i++){
if (Groups.ContainXY(x,y)){
Groups.Click();
break;
}
}
if (!Groups[2].Collapsed)
Rating.OnMouseLbtnUp(x, y);
//}
}
function on_mouse_wheel(delta){
if (Scrollbar.visible)
Scrollbar.wheel(delta);
}
function on_mouse_leave() {
on_mouse_move(-1,-1);
}
function on_timer(id){
if (CursorFollowAutoTimer && id == CursorFollowAutoTimer.ID){
KillCursorFollowAutoTimer();
if (fb.IsPlaying || fb.IsPaused) {
on_playback_new_track();
SkipFocus = null;
}
}
else if (StopTimer && id == StopTimer.ID){
KillStopTimer();
on_playback_stop();
}
else if (Scrollbar.timer && Scrollbar.timer.ID == id){
if (Scrollbar.direction == "" || Scrollbar.direction == "pos" ) {
Scrollbar.timer && Scrollbar.timer.Dispose();
Scrollbar.timer = null;
CollectGarbage(); // Release memory.
}
else
Scrollbar.timerIsOn();
}
}
function on_notify_data(name, info) {
/* Only for WSH Cover Viewer of Window Info */
if (name == "InfoCoverCursorFollowMode"){
SetCursorFollowMode(info);
}
else if (name == "StrArray") {
info = info.split(",");
for (var i = 0; i < info.length; i++){
if (info == "[WSH Track Info Panel]"){
Properties.StrArray = info.splice(i+1, 10);
window.SetProperty("02.Panel.StrArray", Properties.StrArray.toString());
for(var j = 0; j < Properties.StrArray.length; j++)
Properties.StrArray[j] = Properties.StrArray[j].replace(/\^/g,",");
break;
}
}
}
}
MK_SHIFT = 0x0004; // The SHIFT key is down.
function on_mouse_rbtn_up(x, y, vkey){
if (vkey == MK_SHIFT)
return false;
else
PopMenu.Show(x,y); // Show customize menu.
return true;
/*
return false:popup system menu;
return true : don't popup system menu;
*/
}
/* User Functions */
/* ━━━━━━━━━━━━━━━━ Kill timer Functions ━━━━━━━━━━━━━━━━*/
function KillCursorFollowAutoTimer (){
if (CursorFollowAutoTimer){
CursorFollowAutoTimer.Dispose();
CursorFollowAutoTimer = null;
CollectGarbage();
}
}
//──────────────── Get String Information function ───────────
function GetStringInfo(gr, AStr, AFont, AX, AY, AWidth, AHeight, Flags){
var StringInfo;
if (AWidth <=0 || AHeight <=0 || !AStr) {
StringInfo = {
x : 0,
y : 0,
width : 0,
height : 0,
lines : 0,
chars : 0
}
}
else {
/* 如果需要计算的非常多,不能定义g,内存占用很大,效率很低
var CI = gdi.CreateImage(window.Width, window.Height);
var g = CI.GetGraphics(); */
var CI;
if (!gr){
CI = gdi.CreateImage(window.Width, window.Height);
gr = CI.GetGraphics();
}
var ms = gr.MeasureString(AStr, AFont, AX, AY, AWidth, AHeight, Flags);
var StringInfo = {
x : Math.ceil(ms.x),
y : Math.ceil(ms.y),
width : Math.ceil(ms.Width),
height : Math.ceil(ms.Height),
lines : ms.lines,
chars : Math.ceil(ms.chars)
}
if (CI){
CI.ReleaseGraphics(gr);
CI = null;
CollectGarbage(); // Release memory.
}
}
return StringInfo;
}
//──────────────── Check Playing function ───────────
function IsFocusPlaying(g_metadb_Focus, g_metadb_Playing){
var bool = false;
if(g_metadb_Focus && g_metadb_Playing){
var TitleFocus = fb.TitleFormat("%title%").EvalWithMetadb(g_metadb_Focus);
var TitlePlaying = fb.TitleFormat("%title%").EvalWithMetadb(g_metadb_Playing);
if ((g_metadb_Focus.Path == g_metadb_Playing.Path) &&
(g_metadb_Focus.Length == g_metadb_Playing.Length) &&
(TitleFocus == TitlePlaying))
bool = true;
}
return bool;
}
/* ━━━━━━━━━━━━━━━━ SetFont Function ━━━━━━━━━━━━━━━━*/
function SetFont(AFontStr){
if (!AFontStr) return;
AFontStr = AFontStr.split(",");
var s = AFontStr[2].replace(/ | /g, "");
s = s.split("|");
var st;
for (var i = 0; i < s.length; i++){
st = st | s;
}
return gdi.Font(AFontStr[0], AFontStr[1], st);
}
/* ━━━━━━━━━━━━━━━━ CheckColor Function ━━━━━━━━━━━━━━━━*/
function CheckColor(TColor){
TColor = TColor.replace(/ | /g, "");
TColor = TColor.split(",");
if (TColor.length < 3) return;
for (var i = 0; i < 4 ; i++) {
if (!TColor) TColor = 255;
if (TColor < 0)
TColor = 0
else if (TColor > 255)
TColor = 255
}
return RGBA(TColor[0], TColor[1], TColor[2], TColor[3]);
}
/* ━━━━━━━━━━━━━━━━ Scrollbar Function ━━━━━━━━━━━━━━━━*/
var img_scroll = gdi.image(Properties.WorkDirectory + "\\vscroll.png");
var img_scrollpos = gdi.image(Properties.WorkDirectory + "\\scrollpos.png");
function fScrollbar(){
this.x = window.width - 20; this.y = 5; this.width = 17; this.height = window.height - 10;
this.visible = false;
this.pos = this.y + 14;
this.step = 0;
this.direction = "";
this.mousedown = false;
this.refresh = false;
this.containXY = function (x, y) {
var bool = (this.x <= x) && (x <= this.x + this.width) && (this.y <= y) && (y <= this.y + this.height);
if (bool){
if (y<= 15){
this.direction = "top";
this.step = 1;
}
else if (y < this.pos){
this.direction = "up";
this.step = 10;
}
else if ((y > this.pos+10) && (y < this.y + this.height - 17)){
this.direction = "down";
this.step = 10;
}
else if (y >= this.y + this.height - 15){
this.direction = "bottom";
this.step = 1;
}
else this.direction = "pos";
}
else
this.direction = "";
if (this.refresh) {
window.RepaintRect(this.x, this.y, this.width, this.height);
this.refresh = false;
}
if (bool) {
window.RepaintRect(this.x, this.y, this.width, this.height);
this.refresh = true;
}
return bool;
}
this.mouse_lbtn_down = function (x,y){
if (this.direction != "" && !this.timer)
this.timer = window.SetInterval(on_timer, 50); // Start the animation.
}
this.timerIsOn = function(){
if (this.direction == "top"){
Y0 = Y0 + this.step;
if (Y0 > 0) {
Y0 = 0;
Scrollbar.timer && Scrollbar.timer.Dispose();
Scrollbar.timer = null;
CollectGarbage(); // Release memory.
}
}
else if (this.direction == "up"){
Y0 = Y0 + this.step;
if (Y0 > 0) {
Y0 = 0;
Scrollbar.timer && Scrollbar.timer.Dispose();
Scrollbar.timer = null;
CollectGarbage(); // Release memory.
}
}
else if (this.direction == "down"){
Y0 = Y0 - this.step;
if (Y0< window.height - sumheight) {
Y0 = window.height - sumheight - 5;
Scrollbar.timer && Scrollbar.timer.Dispose();
Scrollbar.timer = null;
CollectGarbage(); // Release memory.
}
}
else if (this.direction == "bottom"){
Y0 = Y0 - this.step;
if (Y0< window.height - sumheight) {
Y0 = window.height - sumheight - 5;
Scrollbar.timer && Scrollbar.timer.Dispose();
Scrollbar.timer = null;
CollectGarbage(); // Release memory.
}
}
this.pos = Math.ceil(-Y0/(sumheight - window.height)*(this.height - 30)+14);
if (this.pos < this.y+14) this.pos = this.y +14;
if (this.pos > this.y + this.height - 22) this.pos = this.height - 22;
if (this.direction == "down" && this.pos +10 > MouseY){
Y0 = Math.ceil(-(MouseY - 19) /(this.height - 30)*(sumheight - window.height));
this.direction = "";
}
if (this.direction == "up" && this.pos < MouseY){
Y0 = Math.ceil(-(MouseY - 19) /(this.height - 30)*(sumheight - window.height));
this.direction = "";
}
window.Repaint();
}
this.mouse_move = function(x,y) {
this.pos = y - 5;
if (this.pos < this.y+14) this.pos = this.y +14;
if (this.pos > this.y + this.height - 22) this.pos = this.height - 22;
Y0 = Math.ceil(-(y - 19) /(this.height - 30)*(sumheight - window.height));
if (Y0 > 0) Y0 = 0;
if (this.pos == this.height -22)
Y0 = window.height - sumheight - Groups[0].y;
window.Repaint();
}
this.wheel = function(delta){
this.step = 40;
if (delta > 0) {
Y0 = Y0 + this.step;
if (Y0 > 0) Y0 = 0;
}
else{
Y0 = Y0 - this.step;
if (Y0< window.height - sumheight) Y0 = window.height - sumheight - 5;
}
window.Repaint();
}
this.draw = function(gr){
if (this.visible){
this.pos = Math.ceil(-Y0/(sumheight - window.height)*(this.height - 30)+14);
if (this.pos < this.y+14) this.pos = this.y +14;
if (this.pos > this.y + this.height - 22) this.pos = this.height - 22;
gr.DrawImage(img_scroll, this.x, this.y, this.width-6, 17, this.direction == "top" ? 11 : 0, 0, 11, 17, 0, 255);
gr.DrawLine(this.x, this.y+10, this.x , this.y + this.height - 10, 1, RGBA(46,48,63,255));
gr.DrawLine(this.x+10, this.y+10, this.x+10 , this.y + this.height - 10, 1, RGBA(46,48,63,255));
gr.DrawImage(img_scroll, this.x, this.y + this.height - 17, this.width-6, 17, this.direction == "bottom" ? 10 : -1, -1, 11, 17, 180, 255);
gr.DrawImage(img_scrollpos, this.x + 1 , this.pos, 9 ,9, 0, 0, 9, 9);
//gr.DrawImage(img_scroll, this.x, this.y, this.width-6, 17, this.direction == "top" ? 11 : 0, 0, 11, 17, 0, 255);
//gr.DrawLine(this.x, this.y+10, this.x , this.y + this.height - 10, 1, RGBA(20,58,82,255));
//gr.DrawLine(this.x+10, this.y+10, this.x+10 , this.y + this.height - 10, 1, RGBA(20,58,82,255));
//gr.DrawImage(img_scroll, this.x, this.y + this.height - 17, this.width-6, 17, this.direction == "bottom" ? 10 : -1, -1, 11, 17, 180, 255);
//gr.DrawImage(img_scrollpos, this.x + 1 , this.pos, 9 ,9, 0, 0, 9, 9);
}
}
}
/* ━━━━━━━━━━━━━━━━ PopMenu Function ━━━━━━━━━━━━━━━━
*/
function PopMenuFunc(Prop){
var ItemList = {}; //save all MenuItems
var ItemID = 1;
var BuildMenu = function (items) {
// create a PopupMenu and return it.
var menu = window.CreatePopupMenu();
var mf, id, radio;
for (var i = 0; i < items.length; i++) {
mf = items.Flag || MF_STRING;
id = items.ID || ItemID++;
menu.AppendMenuItem(mf, id, items.Caption);
if (i == items.Radio-1)
radio = id;
ItemList[id] = items;
}
radio && menu.CheckMenuRadioItem(1, id, radio);
return menu;
}
// define all Menu Items and create the PopMenu
function AMenu(){
// Submenu: Cursor Follow -------------------------
var SubItems_CursorFollow = new Array(
{ Caption: Prop.StrArray[4],
Func: function(){SetCursorFollowMode(CursorFollowMode.Auto)} // CursorFollowMode.Auto
},
{ Caption: Prop.StrArray[5],
Func: function(){SetCursorFollowMode(CursorFollowMode.OnlyStoped)} // CursorFollowMode.OnlyStoped
},
{ Caption: Prop.StrArray[6],
Func: function(){SetCursorFollowMode(CursorFollowMode.Always)} // CursorFollowMode.Always
},
{ Caption: Prop.StrArray[7],
Func: function(){SetCursorFollowMode(CursorFollowMode.Never)} // CursorFollowMode.Never
}
);
SubItems_CursorFollow.Radio = Prop.CursorFollowMode;
var SubMenu_CursorFollow = BuildMenu(SubItems_CursorFollow);
var Items = new Array(
{ Flag: MF_POPUP, // FollowCursor SubMenu
Caption: Prop.StrArray[3],
ID: SubMenu_CursorFollow.ID
},
{ Flag: MF_SEPARATOR
},
{ Caption: Prop.StrArray[8], // Show Properties
Func: function(){window.ShowProperties();}
},
{ Caption: Prop.StrArray[9], // Show Help File
Func: function(){
if (!FSO.FileExists(Prop.HelpFile)) {
WshShell.Popup("Help File :\r" + Prop.HelpFile + "\r" + Prop.StrArray[2], 7, Prop.StrArray[0], 0 + 16);
return;
}
var file = FSO.OpenTextFile(Prop.HelpFile, 1);
var txt = file.ReadAll();
fb.ShowPopupMessage(txt, Prop.StrArray[0], 2);
file.Close();
}
}
);
return BuildMenu(Items);
}
// Show PopupMenu
this.Show = function (x, y){
ItemList = {};
ItemID = 1;
var Menu = new AMenu();
var ret = Menu.TrackPopupMenu(x, y);
if (ret != 0)
ItemList[ret].Func();
Menu.Dispose();
CollectGarbage(); // Release memory.
}
}
// ━━━━━━━━━━━━━ Properties Function of Rating ━━━━━━━━━━━━━
function RatingProperties (){
// The image's folder
this.WorkDirectory = fb.TitleFormat(window.GetProperty("R01.Panel.WorkDirectory", "Images\\EIKO\\WSH TrackInfo Panel\\")).Eval(true);
// All needed Strings.
this.StrArray = window.GetProperty("R02.Panel.StrArray", "");
// AutoRating by Playcounts
this.AutoRatingEnable = window.GetProperty("R03.AutoRating.Enable", true);
this.AutoRatingPlaycounts = window.GetProperty("R04.AutoRating.Playcounts", "10, 20, 40, 70, 100");
this.File_DB = window.GetProperty("R05.Rating.Save2File(1)orDB(2)", 1);
if (this.StrArray.length < 1){
this.StrArray = "WSH Rating Panel,path does not exist.,file does not exist.,Save Rating to Tag,Save Rating to PlaybackStatistics";
//this.StrArray ="WSH 评级面板,路径不存在。,文件不存在。,评级保存到文件标签,评级保存到播放统计信息";
window.SetProperty("R02.Panel.StrArray", this.StrArray);
}
this.StrArray = this.StrArray.split(",");
for(var i = 0; i < this.StrArray.length; i++)
this.StrArray = this.StrArray.replace(/\^/g,",");
if (this.WorkDirectory && this.WorkDirectory.indexOf(":") < 0)
this.WorkDirectory = fb.FoobarPath + this.WorkDirectory;
var path = this.WorkDirectory;
if (this.WorkDirectory && path.substring(path.length-1, path.length) != "\\") // must be end with "\\"
this.WorkDirectory = path + "\\";
if (!FSO.FolderExists(this.WorkDirectory))
WshShell.Popup("Properties\rR01.Panel.WorkDirectory\r\r\" " + this.WorkDirectory + " \"\r" + this.StrArray[1], 7, this.StrArray[0], 0 + 16);
this.AutoRatingPlaycounts = "0," + this.AutoRatingPlaycounts;
this.AutoRatingPlaycounts = this.AutoRatingPlaycounts.replace(/ | /g, "");
this.AutoRatingPlaycounts = this.AutoRatingPlaycounts.split(",");
for (var i = 0; i < this.AutoRatingPlaycounts.length; i++){
this.AutoRatingPlaycounts = Math.floor(this.AutoRatingPlaycounts);
}
if (this.File_DB < 1){
this.File_DB = 1;
window.SetProperty("R05.Rating.Save2File(1)orDB(2)", this.File_DB);
}
else if (this.File_DB > 2){
this.File_DB = 2;
window.SetProperty("R05.Rating.Save2File(1)orDB(2)", this.File_DB);
}
}
// ━━━━━━━━━━━━━ Rating Function ━━━━━━━━━━━━━
var img_file_db = gdi.Image(RatingProp.WorkDirectory + "file_db.png");
var img_star = gdi.Image(RatingProp.WorkDirectory + "star.png");
var img_mood = gdi.Image(RatingProp.WorkDirectory + "mood.png");
var img_skip = gdi.Image(RatingProp.WorkDirectory + "skip.png");
function RatingFunc (x, y, width, height){
this.x = x;
this.y = y;
this.width = 124;
this.height = 16;
var tooltip = window.CreateTooltip();
tooltip.text = RatingProp.StrArray[RatingProp.File_DB == 1 ? 3 : 4];
var onfile_db;
var onstar;
var onmood;
var onskip;
var down;
var rating = 0;
var color_star = 0;
var mood = 0;
var skip = 0;
this.OnPaint = function (gr){
gr.DrawImage(img_file_db, this.x, this.y + (down ? (onfile_db ? 1 : 0) : 0), 16, 16, (RatingProp.File_DB == 1 ? 0 : 1)*16, 0, 16, 16);
for (i = 1; i <= 5; i++){
var xi = onstar ?
(i > onstar ? 0 : (onstar == rating ? (RatingProp.File_DB == color_star ? 4 : (RatingProp.File_DB == 1 ? 1 : 2)) : (RatingProp.File_DB == 1 ? 1 : 2)))
:
(i > rating ? 0 : (color_star == 1 ? 1 : (color_star == 2 ? 2 : 3)));
gr.DrawImage(img_star, this.x + 16 + (i-1) * 15, this.y + (down ? (i <= onstar ? 1 : 0) : 0), 15, 15, xi*15, 0, 15, 15);
}
var xi = onmood ? (mood == 1 ? 2 : 1) : (mood == 1 ? 1 : 0);
gr.DrawImage(img_mood, this.x + 92, this.y - 2 + (down ? (onmood ? 1 : 0) : 0), 20, 20, xi * 20, 0, 20, 20);
var xi = onskip ? (skip == 1 ? 0 : 1) : (skip == 1 ? 1 : 0);
gr.DrawImage(img_skip, this.x + 110, this.y+1+ (down ? (onskip ? 1 : 0) : 0), 14, 14, xi*14, 0, 14, 14);
}
this.Refreshed = null;
this.OnMouseMove = function (x2, y2){
if (!this.metadb) return;
this.ContainXY = (this.x <= x2) && (x2 <= this.x + this.width) && (this.y <= y2) && (y2 <= this.y + this.height);
if (!this.ContainXY){
onfile_db = null;
onstar = null;
onmood = null;
onskip = null;
if (this.Refreshed){
this.Refreshed = null;
window.RepaintRect(this.x, this.y, this.width, this.height);
}
}
if (this.ContainXY){
this.Refreshed = true;
var tonfile_db = null;
var tonstar = null;
var tonmood = null;
var tonskip = null;
window.SetCursor(IDC_HAND);
if (this.x < x2 && x2 < this.x + 16){
tonfile_db = true;
tooltip.Activate()
}
else
tooltip.Deactivate();
for (var i = 1; i <=5; i++){
if (this.x + 16 < x2 && x2 < this.x + 16 + i * 15){
tonstar = i;
break;
}
}
if (this.x + 92 < x2 && x2 < this.x +108)
tonmood = true;
if (this.x + 110 < x2 && x2 < this.x +123)
tonskip = true;
}
else{
window.SetCursor(IDC_ARROW);
tooltip.Deactivate();
}
if (onfile_db != tonfile_db){
onfile_db = tonfile_db;
window.RepaintRect(this.x, this.y, this.width, this.height);
}
else if (onstar != tonstar){
onstar = tonstar;
window.RepaintRect(this.x, this.y, this.width, this.height);
}
else if (onmood != tonmood){
onmood = tonmood;
window.RepaintRect(this.x, this.y, this.width, this.height);
}
else if (onskip != tonskip){
onskip = tonskip;
window.RepaintRect(this.x, this.y, this.width, this.height);
}
}
this.OnMouseLbtnDown = function(x, y, mask){
if (!this.metadb) return;
if (this.ContainXY) down = true
else down = null;
window.RepaintRect(this.x, this.y, this.width, this.height);
}
this.OnMouseLbtnUp = function (x, y, mask){
if (down){
down = null;
if (onfile_db){
RatingProp.File_DB = RatingProp.File_DB + 1;
if (RatingProp.File_DB > 2) RatingProp.File_DB = 1;
tooltip.text = RatingProp.StrArray[RatingProp.File_DB == 1 ? 3 : 4];
window.SetProperty("R05.Rating.Save2File(1)orDB(2)", RatingProp.File_DB);
}
if (onstar){
if (RatingProp.File_DB == 1){
this.metadb.UpdateFileInfoSimple("RATING",(onstar != rating ? onstar : (color_star == 1 ? 0 : onstar)));
}
else {
fb.RunContextCommandWithMetadb("Rating/" + (onstar != rating ? onstar : (color_star == 2 ? "<not set>" : onstar)) , this.metadb);
}
}
if (onmood){
this.metadb.UpdateFileInfoSimple("MOOD",(mood == 1 ? 0 : 1));