Skip to content

Instantly share code, notes, and snippets.

@Mesqalito
Created January 20, 2011 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mesqalito/788967 to your computer and use it in GitHub Desktop.
Save Mesqalito/788967 to your computer and use it in GitHub Desktop.
WSH PanelMod Cut
//Modified by Mesqalito v4
// Flags, used with GdiDrawText
// For more information, see: http://msdn.microsoft.com/en-us/library/dd162498(VS.85).aspx
var 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/system.drawing.stringalignment(VS.71).aspx
var StringAlignment = {
Near: 0,
Center: 1,
Far: 2
};
// FYI: http://msdn.microsoft.com/en-us/library/system.drawing.stringtrimming(VS.71).aspx
var StringTrimming = {
None: 0,
Character: 1,
Word: 2,
EllipsisCharacter: 3,
EllipsisWord: 4,
EllipsisPath: 5
};
// FYI: http://msdn.microsoft.com/en-us/library/system.drawing.stringformatflags(VS.71).aspx
var 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<<8)|(b)); }
function RGBA(r, g, b, a) {
r &= 0xff; g &= 0xff; b &= 0xff; a &= 0xff;
return ((a << 24) | (r << 16) | (g << 8) | (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
}
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...";
window.SetProperty("02.Panel.StrArray", this.StrArray);
}
this.StrArray = this.StrArray.split(",");
for(var i = 0; i < this.StrArray.length; i++)
this.StrArray[i] = this.StrArray[i].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)")
}
)
}
)
}
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[i].Items.length; j++)
{
var Item1 = new AItem(Properties.Groups[i].Items[j].caption + Properties.Item.Separator, null);
Items1.push(Item1);
}
var Group1 = new AGroup(Properties.Groups[i].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[i].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[i].CalcPos(gr);
if (this.Items[i].Pos.height > 0){
this.height = this.height + this.Items[i].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[i].Pos.y = this.Items[i-1].Pos.y + this.Items[i-1].Pos.height;
if (this.Items[i].Pos.height > 0)
this.Items[i].Pos.height = this.Items[i].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[i].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);
}
}
/* ━━━━━━━━━━━━━━━━ 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[i].x = Group_x;
Groups[i].width = newGroup_width;
}
for (var i = 0; i<Groups.length; i++){
if (i > 0) Groups[i].y = Groups[i-1].y + Groups[i-1].height;
Groups[i].CalcLayout(gr);
}
sumheight = 0;
for (i = 0; i<Groups.length; i++){
sumheight = sumheight + Groups[i].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[i].x = Group_x;
Groups[i].width = newGroup_width;
}
for (var i = 0; i<Groups.length; i++){
if (i > 0) Groups[i].y = Groups[i-1].y + Groups[i-1].height;
Groups[i].CalcLayout(gr);
}
sumheight = 0;
for (i = 0; i<Groups.length; i++){
sumheight = sumheight + Groups[i].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[i].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.CreateTimerInterval(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.Dispose();
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.CreateTimerInterval(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[i].Items.length; j++)
Groups[i].Items[j].Value = metadb ? fb.TitleFormat(Properties.Groups[i].Items[j].tf).EvalWithMetadb(metadb) : "N/A";
}
// 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[i].ContainXY(x,y);
var cs = IDC_ARROW;
for (var i = 0; i<Groups.length; i++)
if (Groups[i].MouseInHeader){
cs = IDC_HAND;
break;
}
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);
}
function on_mouse_lbtn_up(x,y){
Scrollbar.direction = "";
Scrollbar.mousedown = false;
Scrollbar.timer && Scrollbar.timer.Dispose();
Scrollbar.timer = null;
CollectGarbage(); // Release memory.
for (i = 0; i<Groups.length; i++){
if (Groups[i].ContainXY(x,y)){
Groups[i].Click();
break;
}
}
}
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[i] == "[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 {
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[i];
}
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[i]) TColor[i] = 255;
if (TColor[i] < 0)
TColor[i] = 0
else if (TColor[i] > 255)
TColor[i] = 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.CreateTimerInterval(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);
}
}
}
/* ━━━━━━━━━━━━━━━━ 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[i].Flag || MF_STRING;
id = items[i].ID || ItemID++;
menu.AppendMenuItem(mf, id, items[i].Caption);
if (i == items.Radio-1)
radio = id;
ItemList[id] = items[i];
}
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.
}
}
//EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment