// ==PREPROCESSOR==
// @name "WSH Playlist Viewer"
// @version "2.0.1"
// @author "Br3tt aka Falstaff >> http://br3tt.deviantart.com"
// @feature "v1.4"
// @feature "watch-metadb"
// @feature "dragdrop"
// ==/PREPROCESSOR==
// [Requirements]
// * foobar2000 v1.1 or better >> http://foobar2000.org
// * WSH panel Mod v1.5.3.1 or better >> http://code.google.com/p/foo-wsh-panel-mod/downloads/list
// * Optional: Font uni 05_53 >> http://www.dafont.com/uni-05-x.font
// this font is required to display extra info in group header (codec + genre) and playcount info
// * Optional: Font guifx v2 transports >> http://blog.guifx.com/2009/04/02/guifx-v2-transport-font
// this font is required to get nice stars for the rating columns, but if not installed, it will works with standard star (*) character
// [/Requirements]
// [Installation]
// * import/paste this jscript into a WSH Panel Mod instance of your foobar2000 layout (DUI or CUI)
// [/Installation]
// [Informations]
// * Use Jscript9 engine (if supported by your system) for better performances
// * change colors and fonts in foobar2000 Preferences > DefaultUI or ColumsUI
// * Some Settings can be changed in window Properties (Properties from settings menu -> toolbar button)
// * double click on toolbar > Show Now Playing item
// * use keyboard to search artist in the playlist (incremental search feature)
// [/Informations]
//=================================================// General declarations
SM_CXVSCROLL = 2;
SM_CYHSCROLL = 3;
DLGC_WANTARROWS = 0x0001;
DLGC_WANTALLKEYS = 0x0004;
// }}
// Use with MenuManager()
// {{
MF_STRING = 0x00000000;
MF_SEPARATOR = 0x00000800;
MF_GRAYED = 0x00000001;
MF_DISABLED = 0x00000002;
MF_POPUP = 0x00000010;
// }}
// Used in window.SetCursor()
// {{
IDC_ARROW = 32512;
IDC_IBEAM = 32513;
IDC_WAIT = 32514;
IDC_CROSS = 32515;
IDC_UPARROW = 32516;
IDC_SIZE = 32640;
IDC_ICON = 32641;
IDC_SIZENWSE = 32642;
IDC_SIZENESW = 32643;
IDC_SIZEWE = 32644;
IDC_SIZENS = 32645;
IDC_SIZEALL = 32646;
IDC_NO = 32648;
IDC_APPSTARTING = 32650;
IDC_HAND = 32649;
IDC_HELP = 32651;
// }}
// Use with GdiDrawText()
// {{
var DT_LEFT = 0x00000000;
var DT_RIGHT = 0x00000002;
var DT_TOP = 0x00000000;
var DT_CENTER = 0x00000001;
var DT_VCENTER = 0x00000004;
var DT_WORDBREAK = 0x00000010;
var DT_SINGLELINE = 0x00000020;
var DT_CALCRECT = 0x00000400;
var DT_NOPREFIX = 0x00000800;
var DT_EDITCONTROL = 0x00002000;
var DT_END_ELLIPSIS = 0x00008000;
// }}
// Keyboard Flags & Tools
// {{
var VK_BACK = 0x08;
var VK_RETURN = 0x0D;
var VK_SHIFT = 0x10;
var VK_CONTROL = 0x11;
var VK_ALT = 0x12;
var VK_ESCAPE = 0x1B;
var VK_PGUP = 0x21;
var VK_PGDN = 0x22;
var VK_END = 0x23;
var VK_HOME = 0x24;
var VK_LEFT = 0x25;
var VK_UP = 0x26;
var VK_RIGHT = 0x27;
var VK_DOWN = 0x28;
var VK_INSERT = 0x2D;
var VK_DELETE = 0x2E;
var VK_SPACEBAR = 0x20;
var KMask = {
none: 0,
ctrl: 1,
shift: 2,
ctrlshift: 3,
ctrlalt: 4,
ctrlaltshift: 5,
alt: 6
};
function GetKeyboardMask() {
var c = utils.IsKeyPressed(VK_CONTROL) ? true : false;
var a = utils.IsKeyPressed(VK_ALT) ? true : false;
var s = utils.IsKeyPressed(VK_SHIFT) ? true : false;
var ret = KMask.none;
if (c && !a && !s) ret = KMask.ctrl;
if (!c && !a && s) ret = KMask.shift;
if (c && !a && s) ret = KMask.ctrlshift;
if (c && a && !s) ret = KMask.ctrlalt;
if (c && a && s) ret = KMask.ctrlaltshift;
if (!c && a && !s) ret = KMask.alt;
return ret;
};
// }}
// {{
// Used in window.GetColorCUI()
ColorTypeCUI = {
text: 0,
selection_text: 1,
inactive_selection_text: 2,
background: 3,
selection_background: 4,
inactive_selection_background: 5,
active_item_frame: 6
};
// Used in window.GetFontCUI()
FontTypeCUI = {
items: 0,
labels: 1
};
// Used in window.GetColorDUI()
ColorTypeDUI = {
text: 0,
background: 1,
highlight: 2,
selection: 3
};
// Used in window.GetFontDUI()
FontTypeDUI = {
defaults: 0,
tabs: 1,
lists: 2,
playlists: 3,
statusbar: 4,
console: 5
};
//}}
// {{
// Used in gr.DrawString()
function StringFormat() {
var h_align = 0,
v_align = 0,
trimming = 0,
flags = 0;
switch (arguments.length) {
case 3:
trimming = arguments[2];
case 2:
v_align = arguments[1];
case 1:
h_align = arguments[0];
break;
default:
return 0;
};
return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
};
StringAlignment = {
Near: 0,
Centre: 1,
Far: 2
};
var lt_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Near);
var ct_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Near);
var rt_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Near);
var lc_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Centre);
var cc_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Centre);
var rc_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Centre);
var lb_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Far);
var cb_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Far);
var rb_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Far);
//}}
// {{
// Used in utils.GetAlbumArt()
AlbumArtId = {
front: 0,
back: 1,
disc: 2,
icon: 3,
artist: 4
};
//}}
// {{
// Used everywhere!
function RGB(r, g, b) {
return (0xff000000 | (r << 16) | (g << 8) | (b));
};
function RGBA(r, g, b, a) {
return ((a << 24) | (r << 16) | (g << 8) | (b));
};
function getAlpha(color) {
return ((color >> 24) & 0xff);
}
function getRed(color) {
return ((color >> 16) & 0xff);
}
function getGreen(color) {
return ((color >> 8) & 0xff);
}
function getBlue(color) {
return (color & 0xff);
}
function num(strg, nb) {
var i;
var str = strg.toString();
var k = nb - str.length;
if (k > 0) {
for (i=0;i<k;i++) {
str = "0" + str;
};
};
return str.toString();
};
//Time formatting secondes -> 0:00
function TimeFromSeconds(t){
var zpad = function(n){
var str = n.toString();
return (str.length<2) ? "0"+str : str;
};
var h = Math.floor(t/3600); t-=h*3600;
var m = Math.floor(t/60); t-=m*60;
var s = Math.floor(t);
if(h>0) return h.toString()+":"+zpad(m)+":"+zpad(s);
return m.toString()+":"+zpad(s);
};
function TrackType(trkpath) {
var taggable;
var type;
switch (trkpath) {
case "file":
taggable = 1;
type = 0;
break;
case "cdda":
taggable = 1;
type = 1;
break;
case "FOO_":
taggable = 0;
type = 2;
break;
case "http":
taggable = 0;
type = 3;
break;
case "mms:":
taggable = 0;
type = 3;
break;
case "unpa":
taggable = 0;
type = 4;
break;
default:
taggable = 0;
type = 5;
};
return type;
};
function replaceAll(str, search, repl) {
while (str.indexOf(search) != -1) {
str = str.replace(search, repl);
};
return str;
};
function removeAccents(str) {
var norm = new Array('À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë',
'Ì','Í','Î','Ï', 'Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø','Ù','Ú','Û','Ü','Ý',
'Þ','ß');
var spec = new Array('A','A','A','A','A','A','AE','C','E','E','E','E',
'I','I','I','I', 'D','N','O','O','O','O','O','O','U','U','U','U','Y',
'b','SS');
for (var i = 0; i < spec.length; i++) {
str = replaceAll(str, norm[i], spec[i]);
};
return str;
};
//}}
//=================================================// Button object
ButtonStates = {normal: 0, hover: 1, down: 2};
button = function (normal, hover, down) {
this.img = Array(normal, hover, down);
this.w = this.img[0].Width;
this.h = this.img[0].Height;
this.state = ButtonStates.normal;
this.update = function (normal, hover, down) {
this.img = Array(normal, hover, down);
};
this.draw = function (gr, x, y, alpha) {
this.x = x;
this.y = y;
this.img[this.state] && gr.DrawImage(this.img[this.state], this.x, this.y, this.w, this.h, 0, 0, this.w, this.h, 0, alpha);
};
this.display_context_menu = function (x, y, id) {};
this.repaint = function () {
window.RepaintRect(this.x, this.y, this.w, this.h);
};
this.checkstate = function (event, x, y) {
this.ishover = (x > this.x && x < this.x + this.w - 1 && y > this.y && y < this.y + this.h - 1);
this.old = this.state;
switch (event) {
case "down":
switch(this.state) {
case ButtonStates.normal:
case ButtonStates.hover:
this.state = this.ishover ? ButtonStates.down : ButtonStates.normal;
break;
};
break;
case "up":
this.state = this.ishover ? ButtonStates.hover : ButtonStates.normal;
break;
case "right":
if(this.ishover) this.display_context_menu(x, y, id);
break;
case "move":
switch(this.state) {
case ButtonStates.normal:
case ButtonStates.hover:
this.state = this.ishover ? ButtonStates.hover : ButtonStates.normal;
break;
};
break;
case "leave":
this.state = this.isdown ? ButtonStates.down : ButtonStates.normal;
break;
};
if(this.state!=this.old) this.repaint();
return this.state;
};
};
//=================================================// Tools (general)
function get_system_scrollbar_width() {
var tmp = utils.GetSystemMetrics(SM_CXVSCROLL);
return tmp;
};
function get_system_scrollbar_height() {
var tmp = utils.GetSystemMetrics(SM_CYHSCROLL);
return tmp;
};
String.prototype.repeat = function(num) {
return new Array(num+1).join(this);
};
function getTimestamp() {
var d, s1, s2, s3, hh, min, sec, timestamp;
d = new Date();
s1 = d.getFullYear();
s2 = (d.getMonth() + 1);
s3 = d.getDate();
hh = d.getHours();
min = d.getMinutes();
sec = d.getSeconds();
if(s3.length == 1) s3 = "0" + s3;
timestamp = s1 + ((s2 < 10) ? "-0" : "-") + s2 + ((s3 < 10) ? "-0" : "-" ) + s3 + ((hh < 10) ? " 0" : " ") + hh + ((min < 10) ? ":0" : ":") + min + ((sec < 10) ? ":0" : ":") + sec;
return timestamp;
};
//=================================================// Sort pattern used in this panel
var sort_pattern_album = window.GetProperty("SYSTEM.sort_pattern_album", "%album artist%|$if(%album%,$if2(%date%,9999),0000)|%sound%|%album%|%discnumber%|%tracknumber%");
var sort_pattern_artist = window.GetProperty("SYSTEM.sort_pattern_artist", "%artist%|$if(%album%,$if2(%date%,9999),0000)|%album%|%discnumber%|%tracknumber%");
var sort_pattern_path = window.GetProperty("SYSTEM.sort_pattern_path", "%path%");
var sort_pattern_date = window.GetProperty("SYSTEM.sort_pattern_date", "%date%");
var sort_pattern_genre = window.GetProperty("SYSTEM.sort_pattern_genre", "%genre%");
//=================================================// Group pattern used in this panel
var group_pattern_album = window.GetProperty("SYSTEM.group_pattern_album", "%album artist%%album%%sound%%discnumber%");
var group_pattern_artist = window.GetProperty("SYSTEM.group_pattern_artist", "%artist%");
var group_pattern_path = window.GetProperty("SYSTEM.group_pattern_path", "%directory%");
//=================================================// Image declarations
var playicon_off;
var playicon_on;
var nocover;
var nocover_img;
var noartist;
var noartist_img;
var streamcover;
var streamcover_img;
var glass_reflect_img;
var icon_arrow_left;
var singleline_group_header_icon;
var bt_settings_off;
var bt_settings_ov;
var bt_settings_on;
var bt_sort_off;
var bt_sort_ov;
var bt_sort_on;
function on_get_album_art_done(metadb, art_id, image, image_path) {
var draw_limit = list.tocut+list.nbvis+group.nbrows+1;
if(draw_limit>list.item.length) draw_limit = list.item.length;
for(var i=list.tocut;i<draw_limit;i++) {
if(list.item[i].metadb && list.item[i].gridx==group.nbrows) {
if(list.item[i].metadb.Compare(metadb)) {
list.item[i].cover_img = g_image_cache.getit(list.item[i], image);
var cx = list.item[i].x + cover.margin;
var cy = list.item[i].y - ((group.nbrows-1)*row.h);
cx = cover.margin;
cy = list.item[i].y - ((group.nbrows-1)*row.h);
// fix for a weird behaviour with engine Jscript9
if(!cx) cx = 2; else if(cx<2) cx = 2;
if(!cy) cy = 2; else if(cy<2) cy = 2;
window.RepaintRect(cx-2, cy-2, group.nbrows*row.h, group.nbrows*row.h);
break;
};
};
};
};
//=================================================// Cover Tools
image_cache = function () {
this._cachelist = {};
this.hit = function (item) {
var img = this._cachelist[item.metadb.Path];
if (typeof img == "undefined") {
if(!cover.load_timer) {
cover.load_timer = window.SetTimeout(function() {
switch(group.type){
case 0:
var art_id = AlbumArtId.front;
break;
case 1:
var art_id = AlbumArtId.artist;
break;
case 2:
var art_id = AlbumArtId.front;
break;
};
utils.GetAlbumArtAsync(window.ID, item.metadb, art_id, true, false, false);
cover.load_timer && window.ClearTimeout(cover.load_timer);
cover.load_timer = false;
}, 35);
};
};
return img;
};
this.getit = function (item, image, image_path) {
var img;
if(cover.keepaspectratio) {
if(!image) {
var pw = (cover.w-cover.margin*2);
var ph = (cover.h-cover.margin*2);
} else {
if(image.Height>=image.Width) {
var ratio = image.Width / image.Height;
var pw = (cover.w-cover.margin*2)*ratio;
var ph = (cover.h-cover.margin*2);
} else {
var ratio = image.Height / image.Width;
var pw = (cover.w-cover.margin*2);
var ph = (cover.h-cover.margin*2)*ratio;
};
};
} else {
var pw = cover.w-cover.margin*2;
var ph = cover.h-cover.margin*2;
};
// item.cover_type : 0 = nocover, 1 = external cover, 2 = embedded cover, 3 = stream
if(item.track_type!=3) {
if(item.metadb) {
img = FormatCover(image, pw, ph);
if(!img) {
img = (group.type==1)?noartist_img:nocover_img;
item.cover_type = 0;
} else {
item.cover_type = 1;
};
};
} else {
img = streamcover_img;
item.cover_type = 3;
};
this._cachelist[item.metadb.Path] = img;
return img;
};
};
var g_image_cache = new image_cache;
function FormatCover(image, w, h) {
if(!image || w<=0 || h<=0) return image;
if(cover.draw_glass_effect) {
var new_img = image.Resize(w, h, 2);
var gb = new_img.GetGraphics();
if(h>w) {
gb.DrawImage(glass_reflect_img, Math.floor((h-w)/2)*-1+1, 1, h-2, h-2, 0, 0, glass_reflect_img.Width, glass_reflect_img.Height, 0, 150);
} else {
gb.DrawImage(glass_reflect_img, 1, Math.floor((w-h)/2)*-1+1, w-2, w-2, 0, 0, glass_reflect_img.Width, glass_reflect_img.Height, 0, 150);
};
new_img.ReleaseGraphics(gb);
return new_img;
} else {
return image.Resize(w, h, 2);
};
};
function FormatWP(image, w, h) {
if(!image || w<=0 || h<=0) return image;
return image.Resize(w, h, 2);
};
function draw_glass_reflect(w, h) {
// Mask for glass effect
var Mask_img = gdi.CreateImage(w, h);
var gb = Mask_img.GetGraphics();
gb.FillSolidRect(0,0,w,h,0xffffffff);
gb.FillGradRect(0,0,w-20,h,0,0xaa000000,0,1.0);
gb.SetSmoothingMode(2);
gb.FillEllipse(-20, 25, w*2+40, h*2, 0xffffffff);
Mask_img.ReleaseGraphics(gb);
// drawing the white rect
var glass_img = gdi.CreateImage(w, h);
gb = glass_img.GetGraphics();
gb.FillSolidRect(0, 0, w, h, 0xffffffff);
glass_img.ReleaseGraphics(gb);
// resizing and applying the mask
var Mask = Mask_img.Resize(w, h);
glass_img.ApplyMask(Mask);
Mask.Dispose();
return glass_img;
};
function reset_cover_timers() {
cover.load_timer && window.ClearTimeout(cover.load_timer);
cover.load_timer = false;
};
function repaint_rating(ry) {
if(!columns.rating_timerID) {
//columns.rating_timerID = window.SetTimeout(function() {
window.RepaintRect(columns.rating_x, ry, columns.rating_w, row.h);
columns.rating_timerID && window.ClearTimeout(columns.rating_timerID);
columns.rating_timerID = false;
//},50);
};
};
function repaint_mood(ry) {
if(!columns.mood_timerID) {
//columns.mood_timerID = window.SetTimeout(function() {
window.RepaintRect(columns.mood_x, ry, columns.mood_w, row.h);
columns.mood_timerID && window.ClearTimeout(columns.mood_timerID);
columns.mood_timerID = false;
//},25);
};
};
//=================================================// Item Object
ItemStates = {normal: 0, hover: 1, selected: 2};
item = function (id, idx, gridx) {
if (typeof this.id == "undefined") {
this.id = id;
this.idx = idx;
this.gridx = gridx;
this.grp_idx = 0;
this.metadb = list.handlelist.Item(this.id);
this.x = 0;
this.defaulty = toolbar.h + (idx) * row.h;
this.w = ww;
this.h = row.h;
this.l_rating = 0;
this.l_mood = 0;
this.tooltip = false;
if(this.metadb) {
this.albumartist = tf_albumartist.EvalWithMetadb(this.metadb);
this.album = tf_album.EvalWithMetadb(this.metadb);
this.group_key = tf_group_key.EvalWithMetadb(this.metadb);
this.track_type = TrackType(this.metadb.rawpath.substring(0,4));
if(this.gridx==0) {
this.tracknumber = tf_tracknumber.EvalWithMetadb(this.metadb);
this.artist = tf_artist.EvalWithMetadb(this.metadb);
this.title = tf_title.EvalWithMetadb(this.metadb);
this.sound = tf_sound.EvalWithMetadb(this.metadb);
this.playcount = columns.playcount ? tf_playcount.EvalWithMetadb(this.metadb) : 0;
this.duration = tf_duration.EvalWithMetadb(this.metadb);
this.mood = columns.mood ? tf_mood.EvalWithMetadb(this.metadb) : 0;
this.rating = columns.rating ? tf_rating.EvalWithMetadb(this.metadb) : 0;
this.bitrate = columns.bitrate ? tf_bitrate.EvalWithMetadb(this.metadb) : "";
} else {
this.genre = tf_genre.EvalWithMetadb(this.metadb);
this.date = tf_date.EvalWithMetadb(this.metadb);
this.codec = tf_codec.EvalWithMetadb(this.metadb);
this.disc_info = tf_disc_info.EvalWithMetadb(this.metadb);
};
};
};
this.update_infos = function() {
if(this.metadb) {
this.albumartist = tf_albumartist.EvalWithMetadb(this.metadb);
this.album = tf_album.EvalWithMetadb(this.metadb);
this.group_key = tf_group_key.EvalWithMetadb(this.metadb);
this.track_type = TrackType(this.metadb.rawpath.substring(0,4));
if(this.gridx==0) {
this.tracknumber = tf_tracknumber.EvalWithMetadb(this.metadb);
this.artist = tf_artist.EvalWithMetadb(this.metadb);
this.title = tf_title.EvalWithMetadb(this.metadb);
this.sound = tf_sound.EvalWithMetadb(this.metadb);
this.playcount = tf_playcount.EvalWithMetadb(this.metadb);
this.duration = tf_duration.EvalWithMetadb(this.metadb);
this.mood = columns.mood ? tf_mood.EvalWithMetadb(this.metadb) : 0;
this.rating = columns.rating ? tf_rating.EvalWithMetadb(this.metadb) : 0;
this.bitrate = columns.bitrate ? tf_bitrate.EvalWithMetadb(this.metadb) : "";
} else {
this.genre = tf_genre.EvalWithMetadb(this.metadb);
this.sound = tf_sound.EvalWithMetadb(this.metadb);
this.date = tf_date.EvalWithMetadb(this.metadb);
this.codec = tf_codec.EvalWithMetadb(this.metadb);
this.disc_info = tf_disc_info.EvalWithMetadb(this.metadb);
};
};
};
this.draw = function(gr, id, idx) {
this.y = this.defaulty - (list.tocut * row.h);
if(this.gridx==0) {
// ---------------------
// ::: Draw item
// ---------------------
if(list.focus_id==this.id) {
// focused item bg
var state = 2;
try {
list.theme.SetPartAndStateId(6, 10);
list.theme.DrawThemeBackground(gr, this.x, this.y, ww-vscrollbar.w, this.h);
} catch(e) {
gr.SetSmoothingMode(2);
gr.DrawRoundRect(this.x+1, this.y, this.w-vscrollbar.w-3, this.h-1, 2, 2, 1.0, g_textcolor&0x20ffffff);
gr.FillGradRect(this.x+2, this.y, this.w-vscrollbar.w-4, this.h-1, 90, 0, g_textcolor&0x15ffffff, 1.0);
gr.SetSmoothingMode(0);
};
} else {
if(plman.IsPlaylistItemSelected(plman.ActivePlaylist, this.id)) {
// selected item bg
var state = 1;
try {
list.theme.SetPartAndStateId(6, 10);
list.theme.DrawThemeBackground(gr, this.x, this.y, ww-vscrollbar.w, this.h);
} catch(e) {
gr.SetSmoothingMode(2);
gr.DrawRoundRect(this.x+1, this.y, this.w-vscrollbar.w-3, this.h-1, 2, 2, 1.0, g_textcolor&0x20ffffff);
gr.FillGradRect(this.x+2, this.y, this.w-vscrollbar.w-4, this.h-1, 90, 0, g_textcolor&0x15ffffff, 1.0);
gr.SetSmoothingMode(0);
};
} else {
// default item bg (odd/even)
var state = 0;
if(Math.floor(this.grp_idx/2) == this.grp_idx/2) {
gr.FillSolidRect(this.x, this.y, this.w-vscrollbar.w, this.h, RGBA(255,255,255,5));
} else {
gr.FillSolidRect(this.x, this.y, this.w-vscrollbar.w, this.h, RGBA(0,0,0,5));
};
if(list.gradient_lines_show) {
gr.FillGradRect(this.x+30, this.y, this.w-vscrollbar.w-60, 1, 0, 0, RGBA(0,0,0,80), 0.5);
gr.FillGradRect(this.x+30, this.y+1, this.w-vscrollbar.w-60, 1, 0, 0, RGBA(255,255,255,15), 0.5);
};
};
};
// last item shadow effect
if(this.id==list.total-1) {
gr.FillSolidRect(this.x, this.y+this.h+0, this.w-vscrollbar.w, 1, RGBA(0,0,0,75));
gr.FillSolidRect(this.x, this.y+this.h+1, this.w-vscrollbar.w, 1, RGBA(0,0,0,35));
gr.FillSolidRect(this.x, this.y+this.h+2, this.w-vscrollbar.w, 1, RGBA(0,0,0,12));
};
// ****************************
// .start. *** cols metrics ***
// ****************************
columns.playicon_x = 0;
if(columns.playicon) {
columns.playicon_w = (cover.margin + 20);
} else {
columns.playicon_w = 3;
};
//
columns.tracknumber_x = columns.playicon_x + columns.playicon_w;
if(columns.tracknumber) {
columns.tracknumber_w = 40;
} else {
columns.tracknumber_w = 5;
};
//
if(columns.rating || columns.bitrate || columns.mood) {
if(columns.duration_w<=0) {
columns.duration_w = gr.CalcTextWidth("00:00:00", g_font);
};
} else {
columns.duration_w = gr.CalcTextWidth(" -"+this.duration, g_font);
};
//
columns.duration_x = ww-vscrollbar.w - columns.duration_w - cover.margin;
//
if(columns.rating_w<=0) {
if(g_font_guifx_found) {
columns.rating_w = gr.CalcTextWidth("bbbbb", rating_font);
} else {
columns.rating_w = gr.CalcTextWidth("*****", rating_font);
};
};
columns.rating_x = columns.duration_x - (columns.rating_w*columns.rating);
//
if(columns.mood_w<=0) {
if(g_font_guifx_found) {
columns.mood_w = gr.CalcTextWidth("v", mood_font) + 3;
} else {
columns.mood_w = gr.CalcTextWidth("♥", mood_font) + 3;
};
};
columns.mood_x = columns.rating_x - (columns.mood_w*columns.mood);
//
if(columns.bitrate_w<=0) {
columns.bitrate_w = gr.CalcTextWidth("XXXXXXX", g_font)*columns.bitrate;
};
columns.bitrate_x = columns.mood_x - (columns.bitrate_w*columns.bitrate);
//
if(columns.playcount && this.playcount>0) {
var playcount_w = gr.CalcTextWidth(this.playcount, gdi.Font("Droid Sans", 10))+3;
} else {
var playcount_w = 0;
};
//
columns.title_x = columns.tracknumber_x + columns.tracknumber_w;
columns.title_w = (columns.rating_x - columns.title_x - 3 - playcount_w) - (columns.bitrate_w*columns.bitrate) - (columns.mood_w*columns.mood);
// **************************
// .end. *** cols metrics ***
// **************************
row.parity = (row.h/2==Math.floor(row.h))?1:0;
// now playing info : Play icon + Progress bar
var duration = this.duration;
var bitrate = this.bitrate;
if(plman.PlayingPlaylist == plman.ActivePlaylist) {
if(fb.IsPlaying) {
list.nowplaying = plman.GetPlayingItemLocation();
if(this.id==list.nowplaying.PlaylistItemIndex) {
var isplaying = true;
g_playing_item_y = this.y;
// progress bar (if not a stream!)
if(this.track_type!=3 && row.show_progress && fb.PlaybackLength) {
var length_seconds = tf_length_seconds.EvalWithMetadb(this.metadb);
var progress = Math.round(g_seconds / length_seconds * (ww-vscrollbar.w-this.x-2));
gr.FillGradRect(this.x+1, this.y, progress, this.h, 90, g_textcolor_sel&0x20ffffff, 0, 0.5);
};
// calc dynamic other tf values
duration = tf_playback_time_remaining.Eval(true);
bitrate = tf_bitrate_playing.Eval(true);
if(columns.playicon) {
if(g_seconds/2==Math.floor(g_seconds/2)) {
gr.DrawImage(playicon_off, columns.playicon_x+9, this.y, playicon_off.Width, playicon_off.Height, 0, 0, playicon_off.Width, playicon_off.Height, 0, 255);
} else {
gr.DrawImage(playicon_on, columns.playicon_x+9, this.y, playicon_off.Width, playicon_off.Height, 0, 0, playicon_off.Width, playicon_off.Height, 0, 255);
};
};
} else {
var isplaying = false;
};
};
};
// draw tracknumber
if(columns.tracknumber) {
if(plman.IsPlaybackQueueActive()) {
var queue_index = plman.FindPlaybackQueueItemIndex(this.metadb, plman.ActivePlaylist, this.id);
};
if(state==0) {
if(queue_index>=0) {
gr.FillGradRect(columns.tracknumber_x+3, this.y+3, columns.tracknumber_w-7, this.h-6, 90, g_backcolor&0x15ffffff, RGBA(100,180,100,70), 1.0);
gr.DrawRect(columns.tracknumber_x+3, this.y+3, columns.tracknumber_w-8, this.h-7, 1.0, RGBA(100,180,100,40));
} else {
if(isQueuePlaylistActive()) {
gr.FillGradRect(columns.tracknumber_x+3, this.y+3, columns.tracknumber_w-7, this.h-6, 90, g_backcolor&0x15ffffff, RGBA(100,180,100,70), 1.0);
gr.DrawRect(columns.tracknumber_x+3, this.y+3, columns.tracknumber_w-8, this.h-7, 1.0, RGBA(100,180,100,40));
} else {
gr.FillGradRect(columns.tracknumber_x+3, this.y+3, columns.tracknumber_w-7, this.h-6, 90, g_backcolor&0x15ffffff, g_textcolor&0x15ffffff, 1.0);
gr.DrawRect(columns.tracknumber_x+3, this.y+3, columns.tracknumber_w-8, this.h-7, 1.0, g_textcolor&0x10ffffff);
};
};
}
//var new_tracknumber = (this.tracknumber>0)? this.tracknumber : (group.nbrows>0?num(this.grp_idx+1,2):"?");
var new_tracknumber = (queue_index>=0) ? " " + num(queue_index+1,2) + "*" : ((this.tracknumber>0)? this.tracknumber : num(this.grp_idx+1,2));
try {
gr.GdiDrawText(new_tracknumber, g_font = gdi.Font("Corpid Caps Light", 14), (queue_index>=0 || isQueuePlaylistActive())?RGB(100,180,100):(isplaying?g_textcolor_sel:g_textcolor), columns.tracknumber_x, this.y, columns.tracknumber_w, this.h-row.parity, DT_CENTER | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
gr.GdiDrawText(new_tracknumber, gdi.Font("Corpid Light", 12), (queue_index>=0 || isQueuePlaylistActive())?RGB(100,180,100):(isplaying?g_textcolor_sel:g_textcolor), columns.tracknumber_x, this.y, columns.tracknumber_w, this.h-row.parity, DT_CENTER | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
};
// draw title
try {
tf_title_w = gr.CalcTextWidth(this.title, g_font = gdi.Font("Corpid light",14,0));
if(tf_title_w > columns.title_w) {
tf_title_w = columns.title_w;
this.tooltip = true;
};
gr.GdiDrawText(this.title, g_font, isplaying?g_textcolor_sel:g_textcolor, isplaying?g_font=gdi.Font("Corpid", 12):g_font,columns.title_x, this.y, columns.title_w, this.h-row.parity, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
tf_title_w = gr.CalcTextWidth(this.title, gdi.Font ("Corpid Light", 13));
if(tf_title_w > columns.title_w) {
tf_title_w = columns.title_w;
this.tooltip = true;
};
gr.GdiDrawText(this.title, gdi.Font("Corpid Light", 13), isplaying?g_textcolor_sel:g_textcolor, columns.title_x, this.y, columns.title_w, this.h-row.parity, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
// draw artist
if(group.nbrows==0 || (columns.title==1 && this.artist!=this.albumartist) || columns.title==2) {
var artist_x = columns.title_x + tf_title_w;
try {
var artist_w = columns.title_w - tf_title_w;
tf_artist_w = gr.CalcTextWidth(" "+panel.tag_separator+" "+this.artist, g_font = gdi.Font("Corpid Light", 12));
if(tf_artist_w > artist_w) {
tf_artist_w = artist_w;
this.tooltip = true;
};
if(tf_title_w < columns.title_w) {
gr.GdiDrawText(" "+panel.tag_separator+" "+this.artist, g_font = gdi.Font("Corpid Light",12), g_textcolor_hl, artist_x, this.y, artist_w, this.h-row.parity, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
} catch(e) {
var artist_w = columns.title_w - tf_title_w;
tf_artist_w = gr.CalcTextWidth(" "+panel.tag_separator+" "+this.artist, gdi.Font("Corpid Light", 12));
if(tf_artist_w > artist_w) {
tf_artist_w = artist_w;
this.tooltip = true;
};
if(tf_title_w < columns.title_w) {
gr.GdiDrawText(" "+panel.tag_separator+" "+this.artist, gdi.Font("Corpid Light", 12), g_textcolor_hl, artist_x, this.y, artist_w, this.h-row.parity, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
};
} else {
if(tf_title_w > columns.title_w) this.tooltip = true;
tf_artist_w = 0;
};
// draw playcount
if(columns.playcount && playcount_w>0) {
var playcount_x = columns.title_x + tf_title_w + tf_artist_w;
try {
gr.DrawString(this.playcount, gdi.Font("Droid Sans", 9), g_textcolor&0x40ffffff, playcount_x+3, this.y+1, playcount_w, this.h-row.parity, rc_stringformat);
} catch(e) {
gr.DrawString(this.playcount, gdi.Font("Droid Sans", 8), g_textcolor&0x40ffffff, playcount_x, this.y-4, playcount_w, this.h-row.parity, rc_stringformat);
};
};
// draw rating
if(columns.rating) {
// Rating engine
if(this.rating_hover) {
for (var i = 1; i < 6; i++){
if(this.track_type<2){
var r_color = (i > (this.rating_hover ? this.l_rating : this.rating)) ? g_textcolor&0x12ffffff : (this.rating_hover ? (i==this.rating ? (i==this.l_rating ? RGB(255,50,50) : g_textcolor_sel) : g_textcolor_sel) : g_textcolor&0x90ffffff);
if(this.rating_hover && this.l_rating==this.rating) {
r_color = i<=this.l_rating ? RGB(255,50,50) : g_textcolor&0x12ffffff;
}
} else {
var r_color = g_textcolor&0x12ffffff;
};
if(g_font_guifx_found) {
gr.SetTextRenderingHint(5);
if(r_color==RGB(255,50,50)){
gr.DrawString("x", del_rating_font, r_color, columns.rating_x+14*(i-1)+1, this.y-1, 14, row.h, lc_stringformat);
} else {
gr.DrawString("b", rating_font, r_color, columns.rating_x+14*(i-1), this.y, 14, row.h, lc_stringformat);
};
} else {
gr.SetTextRenderingHint(3);
gr.DrawString("*", rating_font, r_color, columns.rating_x+12*(i-1), this.y+4, 12, row.h, lc_stringformat);
};
};
} else {
if(g_font_guifx_found) {
gr.SetTextRenderingHint(5);
gr.DrawString("bbbbb", rating_font, g_textcolor&0x12ffffff, columns.rating_x, this.y-1, columns.rating_w+1, row.h, lc_stringformat);
gr.DrawString("b".repeat(Math.round(this.rating)), rating_font, g_textcolor&0x90ffffff, columns.rating_x, this.y-1, columns.rating_w+1, row.h, lc_stringformat);
} else {
gr.SetTextRenderingHint(3);
gr.DrawString("*****", rating_font, g_textcolor&0x12ffffff, columns.rating_x, this.y+4, columns.rating_w+1, row.h, lc_stringformat);
gr.DrawString("*".repeat(Math.round(this.rating)), rating_font, g_textcolor&0x90ffffff, columns.rating_x, this.y+4, columns.rating_w+1, row.h, lc_stringformat);
};
};
};
// draw bitrate
if(columns.bitrate) {
try {
gr.GdiDrawText(bitrate, g_font = gdi.Font("Corpid Light", 12), isplaying?g_textcolor_sel:g_textcolor, columns.bitrate_x, this.y, columns.bitrate_w, this.h-row.parity, DT_CENTER | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
gr.GdiDrawText(bitrate, gdi.Font("Corpid Light", 12), isplaying?g_textcolor_sel:g_textcolor, columns.bitrate_x, this.y, columns.bitrate_w, this.h-row.parity, DT_CENTER | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
};
// draw Mood icon
if(columns.mood) {
if(this.track_type<2){
r_color = this.mood_hover ? g_textcolor_sel : (this.mood!=0 ? RGB(255,80,120) : g_textcolor&0x12ffffff);
} else {
var r_color = g_textcolor&0x12ffffff;
};
if(g_font_guifx_found) {
gr.SetTextRenderingHint(4);
gr.DrawString("v", mood_font, r_color, columns.mood_x, this.y+1, columns.mood_w, row.h, lc_stringformat);
} else {
gr.SetTextRenderingHint(4);
gr.DrawString("♥", mood_font, r_color, columns.mood_x, this.y, columns.mood_w, row.h, lc_stringformat);
};
};
// draw playbacktime/duration
try {
gr.GdiDrawText(duration, g_font = gdi.Font("Corpid Light", 13), isplaying?g_textcolor_sel:g_textcolor, columns.duration_x, this.y, columns.duration_w, this.h-row.parity, DT_RIGHT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
gr.GdiDrawText(duration, gdi.Font("Corpid Light", 13), isplaying?g_textcolor_sel:g_textcolor, columns.duration_x, this.y, columns.duration_w, this.h-row.parity, DT_RIGHT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
// if dragging items, draw line at top of the hover items to show where dragged items will be inserted on mouse button up
if(dragndrop.drag_in && this.ishover && panel.ishover) {
if(!plman.IsPlaylistItemSelected(plman.ActivePlaylist, this.id)) {
if(this.id>dragndrop.drag_id) {
gr.DrawLine(this.x+5, this.y+this.h, ww-vscrollbar.w-5, this.y+this.h, 2.0, g_textcolor);
gr.DrawImage(icon_arrow_left, this.x, this.y+this.h-4, 8, 8, 0, 0, 8, 8, 0, 255);
gr.DrawImage(icon_arrow_left, this.x+ww-vscrollbar.w, this.y+this.h-4, -8, 8, 0, 0, 8, 8, 0, 255);
dragndrop.drop_id = this.id;
} else if(this.id<dragndrop.drag_id) {
gr.DrawLine(this.x+5, this.y, ww-vscrollbar.w-5, this.y, 2.0, g_textcolor);
gr.DrawImage(icon_arrow_left, this.x, this.y-4, 8, 8, 0, 0, 8, 8, 0, 255);
gr.DrawImage(icon_arrow_left, this.x+ww-vscrollbar.w, this.y-4, -8, 8, 0, 0, 8, 8, 0, 255);
dragndrop.drop_id = this.id;
};
};
};
} else if(this.gridx==group.nbrows && group.nbrows>0) {
// ---------------------
// ::: Draw group Header
// ---------------------
// total items in the group
var total_grp_items = list.groups[list.hlist[this.id]-1];
// background
if(group.nbrows>1 && group.type==0) { // display the year only if group by album (group.type = 0)
var date_str = gr.MeasureString(this.date, gh_date_font, 0, 0, 200, 30, 0);
var year_x = ww-vscrollbar.w-date_str.Width-cover.margin;
var year_w = (group.nbrows>1 && (this.album.length>0 || total_grp_items==1) && this.date)?date_str.Width+cover.margin*2:0;
} else {
var year_x = 0;
var year_w = 0;
};
gr.FillGradRect(this.x, this.y-((group.nbrows-1)*row.h), this.w-vscrollbar.w-year_w, group.nbrows*row.h, 90, RGBA(255,255,255,15), RGBA(0,0,0,15), 1.0);
//
gr.FillGradRect(this.x-30, this.y-((group.nbrows-1)*row.h), this.w-vscrollbar.w+60, 1, 0, 0, RGBA(0,0,0,15), 0.5);
gr.FillSolidRect(this.x, this.y-((group.nbrows-1)*row.h)+1, this.w-vscrollbar.w, 1, RGBA(255,255,255,15));
gr.FillSolidRect(this.x, this.y+row.h-0, this.w-vscrollbar.w, 1, RGBA(255,255,255,5));
gr.FillSolidRect(this.x, this.y+row.h-1, this.w-vscrollbar.w, 1, RGBA(0,0,0,15));
// draw cover art
if(cover.show && cover.visible && this.y>(0-group.nbrows*row.h) && this.y<(wh-toolbar.h)+(group.nbrows*row.h)) {
// cover bg
var cv_x = this.x+cover.margin;
var cv_y = ((this.y+row.h)-(row.h*group.nbrows))+cover.margin;
var cv_w = cover.w-cover.margin*2;
var cv_h = cover.h-cover.margin*2;
if(!cover.keepaspectratio) {
gr.FillSolidRect(cv_x+1, cv_y+1, cv_w-2, cv_h-2, g_backcolor);
gr.FillSolidRect(cv_x+1, cv_y+1, cv_w-2, cv_h-2, g_textcolor&0x15ffffff);
gr.DrawRect(cv_x, cv_y, cv_w-1, cv_h-1, 1.0, g_textcolor&0x80ffffff);
};
//
this.cover_img = g_image_cache.hit(this);
//
if(this.cover_img) {
if(cover.keepaspectratio) {
// *** check aspect ratio *** //
if(this.cover_img.Height>=this.cover_img.Width) {
var ratio = this.cover_img.Width / this.cover_img.Height;
var pw = cv_w*ratio;
var ph = cv_h;
this.left = Math.floor((ph-pw) / 2);
this.top = 0;
cv_x += this.left;
cv_y += this.top*1;
cv_w = cv_w - this.left*2 - cover.margin - 1;
cv_h = cv_h - this.top*2 - cover.margin - 1;
} else {
var ratio = this.cover_img.Height / this.cover_img.Width;
var pw = cv_w;
var ph = cv_h*ratio;
this.top = Math.floor((pw-ph) / 2);
this.left = 0;
cv_x += this.left;
cv_y += this.top*1;
cv_w = cv_w - this.left*2 - cover.margin - 1;
cv_h = cv_h - this.top*2 - cover.margin - 1;
};
// *** check aspect ratio *** //
};
// Draw Cover Art (when available)
if(cover.keepaspectratio) {
gr.DrawRect(cv_x+2, cv_y+2, cv_w+cover.margin*1, cv_h+cover.margin*1, 1.0, RGBA(0,0,0,15));
gr.DrawRect(cv_x+1, cv_y+1, cv_w+cover.margin*1, cv_h+cover.margin*1, 1.0, RGBA(0,0,0,45));
gr.DrawImage(this.cover_img, cv_x, cv_y, cover.w, cover.h, 0, 0, cover.w, cover.h, 0, 255);
gr.DrawRect(cv_x, cv_y, cv_w+cover.margin*1, cv_h+cover.margin*1, 1.0, g_backcolor);
gr.DrawRect(cv_x, cv_y, cv_w+cover.margin*1, cv_h+cover.margin*1, 1.0, g_textcolor&0x80ffffff);
} else {
gr.DrawRect(cv_x+2, cv_y+2, cv_w-1, cv_h-1, 1.0, RGBA(0,0,0,15));
gr.DrawRect(cv_x+1, cv_y+1, cv_w-1, cv_h-1, 1.0, RGBA(0,0,0,45));
gr.DrawImage(this.cover_img, cv_x, cv_y, cover.w, cover.h, 0, 0, cover.w, cover.h, 0, 255);
gr.DrawRect(cv_x, cv_y, cv_w-1, cv_h-1, 1.0, g_backcolor);
gr.DrawRect(cv_x, cv_y, cv_w-1, cv_h-1, 1.0, g_textcolor&0x80ffffff);
};
};
};
// draw TF text info of the group header
var grp_y = cover.margin+this.y-((group.nbrows-1)*row.h);
var grp_h = group.nbrows*row.h - cover.margin*2;
// Year info (& date separator & backgound)
if(year_w>0) {
gr.FillSolidRect(ww-vscrollbar.w-year_w, this.y-((group.nbrows-1)*row.h), year_w, group.nbrows*row.h, RGBA(0,0,0,15));
gr.FillGradRect(ww-vscrollbar.w-year_w, this.y-((group.nbrows-1)*row.h), 5, group.nbrows*row.h, 00, RGBA(0,0,0,15), 0, 1.0);
gr.FillGradRect(ww-vscrollbar.w-year_w-1, this.y-((group.nbrows-1)*row.h)+5, 1, group.nbrows*row.h-10, 90, 0, RGBA(255,255,255,25), 0.5);
gr.FillGradRect(ww-vscrollbar.w-year_w+0, this.y-((group.nbrows-1)*row.h)+5, 1, group.nbrows*row.h-10, 90, 0, RGBA(0,0,0,40), 0.5);
gr.FillGradRect(ww-vscrollbar.w-year_w+1, this.y-((group.nbrows-1)*row.h)+10, 1, group.nbrows*row.h-20, 90, 0, RGBA(0,0,0,15), 0.5);
gr.FillGradRect(ww-vscrollbar.w-year_w+1, this.y-((group.nbrows-1)*row.h)+15, 1, group.nbrows*row.h-30, 90, 0, RGBA(0,0,0,5), 0.5);
gr.SetTextRenderingHint(3);
gr.DrawString(this.date, gh_date_font, g_backcolor&0xddffffff, year_x, grp_y-7, year_w, group.nbrows*row.h-1, lc_stringformat);
gr.DrawString(this.date, gh_date_font, g_textcolor&0x25ffffff, year_x, grp_y-8, year_w, group.nbrows*row.h-1, lc_stringformat);
};
// Artist + Album infos
if(group.type==0) {
var album_tag = this.album.length>0?this.album:(total_grp_items>1?"Singles":"Single");
if(group.nbrows>1) {
var text_x = (cover.show && cover.visible) ? this.x+cover.w : this.x + cover.margin;
var text_w = (ww-vscrollbar.w)-cover.w-cover.margin*2-(year_w-5);
try {
gr.GdiDrawText(this.albumartist, g_font = gdi.Font("Corpid Caps Light",19,0), g_textcolor_hl, text_x, grp_y, text_w, Math.floor(grp_h/group.nbrows), DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
gr.GdiDrawText(album_tag+this.disc_info, g_font = gdi.Font("Corpid Caps Bold",23,0), g_textcolor_hl, text_x, grp_y+Math.floor(grp_h/group.nbrows), text_w, Math.ceil(grp_h/group.nbrows), DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
gr.GdiDrawText(this.albumartist, gdi.Font("Corpid Cd Bold", 18), g_textcolor_hl, text_x, grp_y, text_w, Math.floor(grp_h/group.nbrows), DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
gr.GdiDrawText(album_tag+this.disc_info, gdi.Font("Corpid Cd Bold", 18), g_textcolor_hl, text_x, grp_y+Math.floor(grp_h/group.nbrows), text_w, Math.ceil(grp_h/group.nbrows), DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
} else {
gr.DrawImage(singleline_group_header_icon, cover.margin, this.y+Math.floor(row.h/2)-8, 16, 16, 0, 0, 16, 16, 0, 255);
var text_x = this.x+cover.margin+singleline_group_header_icon.Width;
var text_w = ww-vscrollbar.w-cover.margin*2-singleline_group_header_icon.Width;
try {
gr.GdiDrawText(this.albumartist+" "+panel.tag_separator+" "+album_tag+this.disc_info, g_font = gdi.Font("Corpid Light", 12), g_textcolor_hl, text_x, grp_y, text_w, grp_h, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
gr.GdiDrawText(this.albumartist+" "+panel.tag_separator+" "+album_tag+this.disc_info, gdi.Font("Corpid Light", 12), g_textcolor_hl, text_x, grp_y, text_w, grp_h, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
};
} else {
var t_path = this.group_key;
if(group.nbrows>1) {
var text_x = (cover.show && cover.visible) ? this.x+cover.w : this.x + cover.margin;
var text_w = (ww-vscrollbar.w)-cover.w-cover.margin*2-(year_w-5);
try {
gr.GdiDrawText(t_path, g_font = gdi.Font("Corpid Light", 12), g_textcolor_hl, text_x, grp_y, text_w, grp_h, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
gr.GdiDrawText(t_path, gdi.Font("Corpid Light", 12), g_textcolor_hl, text_x, grp_y, text_w, grp_h, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
} else {
gr.DrawImage(singleline_group_header_icon, cover.margin, this.y+Math.floor(row.h/2)-8, 16, 16, 0, 0, 16, 16, 0, 255);
var text_x = this.x+cover.margin+singleline_group_header_icon.Width;
var text_w = ww-vscrollbar.w-cover.margin*2-singleline_group_header_icon.Width;
try {
gr.GdiDrawText(t_path, g_font = gdi.Font("Corpid Light", 12) , g_textcolor_hl, text_x, grp_y, text_w, grp_h, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
} catch(e) {
gr.GdiDrawText(t_path, gdi.Font("Corpid bold", 12), g_textcolor_hl, text_x, grp_y, text_w, grp_h, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
};
};
// extra group infos (3rd line)
gr.SetTextRenderingHint(5);
//var total_grp_length = TimeFromSeconds(list.groups[list.hlist[this.id]-1]);
if(group.nbrows==2 && group.type!=0) {
try {
gr.DrawString(total_grp_items+(total_grp_items>1?" TRACKS":" TRACK")+" | "+this.codec+" | "+this.sound+"| "+this.genre.toUpperCase(), gdi.Font("Droid Sans",11), g_textcolor&0x44ffffff, text_x+1, (this.y-cover.margin)+2, text_w-1, row.h, lb_stringformat);
} catch(e) {
gr.DrawString(total_grp_items+(total_grp_items>1?" TRACKS":" TRACK")+" | "+this.codec+" | "+this.sound+"| "+this.genre.toUpperCase(), gdi.Font("Droid Sans",11), g_textcolor&0x44ffffff, text_x+1, (this.y-cover.margin)+2, text_w-1, row.h, lb_stringformat);
};
} else if(group.nbrows>1) {
try {
gr.DrawString(total_grp_items+(total_grp_items>1?" TRACKS":" TRACK")+" | "+this.codec+" | "+this.sound+"| "+this.genre.toUpperCase(), gdi.Font("Droid Sans",11), g_textcolor&0x44ffffff, text_x+1, (this.y-cover.margin)+2, text_w-1, row.h, lc_stringformat);
} catch(e) {
gr.DrawString(total_grp_items+(total_grp_items>1?" TRACKS":" TRACK")+" | "+this.codec+" | "+this.sound+"| "+this.genre.toUpperCase(), gdi.Font("Droid Sans",11), g_textcolor&0x44ffffff, text_x+1, (this.y-cover.margin)+2, text_w-1, row.h, lc_stringformat);
};
};
};
if(group.nbrows>0 && this.gridx>0) {
// if dragging items, draw line at top of the hover items to show where dragged items will be inserted on mouse button up
if(dragndrop.drag_in && this.ishover && panel.ishover) {
if(!plman.IsPlaylistItemSelected(plman.ActivePlaylist, this.id)) {
if(this.id<=dragndrop.drag_id) {
gr.DrawLine(this.x+5, this.y-(this.gridx-1)*row.h, ww-vscrollbar.w-5, this.y-(this.gridx-1)*row.h, 2.0, g_textcolor);
gr.DrawImage(icon_arrow_left, this.x, this.y-(this.gridx-1)*row.h-4, 8, 8, 0, 0, 8, 8, 0, 255);
gr.DrawImage(icon_arrow_left, this.x+ww-vscrollbar.w, this.y-(this.gridx-1)*row.h-4, -8, 8, 0, 0, 8, 8, 0, 255);
dragndrop.drop_id = this.id;
} else {
gr.DrawLine(this.x+5, this.y+(group.nbrows-this.gridx+1)*row.h, ww-vscrollbar.w-5, this.y+(group.nbrows-this.gridx+1)*row.h, 2.0, g_textcolor);
gr.DrawImage(icon_arrow_left, this.x, this.y+(group.nbrows-this.gridx+1)*row.h-4, 8, 8, 0, 0, 8, 8, 0, 255);
gr.DrawImage(icon_arrow_left, this.x+ww-vscrollbar.w, this.y+(group.nbrows-this.gridx+1)*row.h-4, -8, 8, 0, 0, 8, 8, 0, 255);
dragndrop.drop_id = this.id>0?this.id-1:0;
};
};
};
};
};
this.checkstate = function (event, x, y, id) {
var state = 0;
if(y<toolbar.delta) return true;
var act_pls = plman.ActivePlaylist;
var prev_rating_hover = this.rating_hover;
var prev_l_rating = this.l_rating;
var prev_mood_hover = this.mood_hover;
var prev_l_mood = this.l_mood;
if(y>toolbar.h) {
this.ishover = (x > this.x && x < this.x + this.w - vscrollbar.w && y >= this.y && y < this.y + this.h);
} else {
this.ishover = false;
};
this.rating_hover = (this.gridx==0 && x>=columns.rating_x && x<=columns.rating_x+columns.rating_w && y>this.y+2 && y<this.y+this.h-2);
this.mood_hover = (this.gridx==0 && x>=columns.mood_x && x<=columns.mood_x+columns.mood_w-3 && y>this.y+2 && y<this.y+this.h-2);
if(row.buttons_hover) {
toolbar.timerID_on && window.ClearTimeout(toolbar.timerID_on);
toolbar.timerID_on = false;
} else {
row.buttons_hover = (this.rating_hover || this.mood_hover);
};
switch (event) {
case "down":
if(this.gridx>0) {
if(this.ishover) {
SelectGroupItems(this.id);
if(list.metadblist_selection.Count>=1) {
dragndrop.drag_out = true;
dragndrop.drag_id = this.id;
if(!isQueuePlaylistActive()) {
dragndrop.timerID = window.SetTimeout(function() {
dragndrop.drag_in = true;
dragndrop.timerID && window.ClearTimeout(dragndrop.timerID);
dragndrop.timerID = false;
}, 250);
};
};
};
} else {
if(this.rating_hover) {
columns.rating_drag = true;
} else if(this.mood_hover) {
columns.mood_drag = true;
} else {
if(plman.IsPlaylistItemSelected(act_pls, this.id)) {
if(this.ishover) {
if(list.metadblist_selection.Count>=1) {
dragndrop.drag_out = true;
if(list.metadblist_selection.Count>1) {
// test if selection is contigus, if not, drag'n drop disable
var first_item_selected_id = list.handlelist.Find(list.metadblist_selection.item(0));
var last_item_selected_id = list.handlelist.Find(list.metadblist_selection.item(list.metadblist_selection.Count-1));
var contigus_count = (last_item_selected_id - first_item_selected_id)+1;
} else {
var contigus_count = 0;
};
if(list.metadblist_selection.Count==1 || list.metadblist_selection.Count == contigus_count) {
dragndrop.drag_id = this.id;
if(!isQueuePlaylistActive()) {
dragndrop.timerID = window.SetTimeout(function() {
dragndrop.drag_in = true;
dragndrop.timerID && window.ClearTimeout(dragndrop.timerID);
dragndrop.timerID = false;
}, 250);
};
};
};
if(utils.IsKeyPressed(VK_SHIFT)) {
if(list.focus_id != this.id) {
if(list.SHIFT_start_id!=null) {
SelectAtoB(list.SHIFT_start_id, this.id);
} else {
SelectAtoB(list.focus_id, this.id);
};
};
} else if(utils.IsKeyPressed(VK_CONTROL)) {
if(plman.GetPlaylistFocusItemIndex(act_pls)!=this.id) {
plman.SetPlaylistSelectionSingle(act_pls, this.id, false);
};
} else if(list.metadblist_selection.Count==1) {
plman.SetPlaylistFocusItem(act_pls, this.id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, this.id, true);
};
};
} else {
if(this.ishover) {
if(utils.IsKeyPressed(VK_SHIFT)) {
if(list.focus_id != this.id) {
if(list.SHIFT_start_id!=null) {
SelectAtoB(list.SHIFT_start_id, this.id);
} else {
SelectAtoB(list.focus_id, this.id);
};
};
} else if(utils.IsKeyPressed(VK_CONTROL)) {
plman.SetPlaylistFocusItem(act_pls, this.id);
plman.SetPlaylistSelectionSingle(act_pls, this.id, true);
} else {
plman.SetPlaylistFocusItem(act_pls, this.id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, this.id, true);
};
};
};
list.metadblist_selection = plman.GetPlaylistSelectedItems(act_pls);
};
};
break;
case "dblclk":
if(this.gridx==0) {
if(this.rating_hover) {
} else if(this.mood_hover) {
} else {
if(!isQueuePlaylistActive()) {
if(plman.IsPlaylistItemSelected(act_pls, this.id)) {
if(this.ishover) {
plman.ExecutePlaylistDefaultAction(act_pls, this.id);
window.Repaint();
};
};
};
};
};
break;
case "right":
if(this.ishover) {
if(this.rating_hover) {
} else if(this.mood_hover) {
} else {
if(plman.IsPlaylistItemSelected(act_pls, this.id)) {
} else {
plman.SetPlaylistFocusItem(act_pls, this.id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, this.id, true);
};
new_context_menu(x, y, this.id, this.idx);
state = -1;
};
};
break;
case "up":
if(this.ishover) {
if(this.rating_hover) {
// Rating
if(this.track_type<2) {
if(foo_playcount) {
// Rate to database statistics brought by foo_playcount.dll
if (this.l_rating != this.rating) {
if(this.metadb) {
var bool = fb.RunContextCommandWithMetadb("Rating/"+((this.l_rating==0) ? "<not set>" : this.l_rating), this.metadb);
this.rating = this.l_rating;
};
} else {
var bool = fb.RunContextCommandWithMetadb("Rating/<not set>", this.metadb);
this.rating = 0;
};
} else {
// Rate to file
if (this.l_rating != this.rating) {
if(this.metadb) {
var bool = this.metadb.UpdateFileInfoSimple("RATING", this.l_rating);
this.rating = this.l_rating;
};
} else {
var bool = this.metadb.UpdateFileInfoSimple("RATING","");
this.rating = 0;
};
};
};
} else if(this.mood_hover) {
// Mood
if(this.track_type<2) {
// tag to file
if (this.l_mood != this.mood) {
if(this.metadb) {
var bool = this.metadb.UpdateFileInfoSimple("MOOD", getTimestamp());
this.mood = this.l_mood;
};
} else {
var bool = this.metadb.UpdateFileInfoSimple("MOOD","");
this.mood = 0;
};
};
} else {
if(plman.IsPlaylistItemSelected(act_pls, this.id)) {
if(!utils.IsKeyPressed(VK_SHIFT) && !utils.IsKeyPressed(VK_CONTROL)) {
if(!dragndrop.drag_in) {
if(this.gridx==0) {
plman.SetPlaylistFocusItem(act_pls, this.id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, this.id, true);
};
};
dragndrop.timerID && window.ClearTimeout(dragndrop.timerID);
dragndrop.timerID = false;
dragndrop.drag_in = false;
dragndrop.drag_out = false;
};
};
};
};
columns.rating_drag = false;
columns.mood_drag = false;
break;
case "move":
if(columns.rating && !columns.rating_drag) {
if(this.rating_hover) {
this.l_rating = Math.floor((x - columns.rating_x) / (g_font_guifx_found?14:12)) + 1;
if(this.l_rating>5) this.l_rating = 5;
} else {
this.l_rating = 0;
};
if(this.rating_hover != prev_rating_hover || this.l_rating != prev_l_rating) {
repaint_rating(this.y);
};
};
if(columns.mood && !columns.mood_drag) {
if(this.mood_hover) {
this.l_mood = 1;
} else {
this.l_mood = 0;
};
if(this.mood_hover != prev_mood_hover || this.l_mood != prev_l_mood) {
repaint_mood(this.y);
};
};
break;
case "leave":
break;
};
return state;
};
};
//=================================================// Titleformat field
var tf_cover_path = fb.TitleFormat("$replace(%path%,%filename_ext%,)");
var tf_tracknumber = fb.TitleFormat("$num($if2(%tracknumber%,0),2)");
var tf_artist = fb.TitleFormat("$if(%length%,%artist%,'Stream')");
var tf_title = fb.TitleFormat("%title%");
var tf_albumartist = fb.TitleFormat("$if(%length%,%album artist%,'Stream')");
var tf_album = fb.TitleFormat("$if2(%album%,$if(%length%,,'web radios'))");
var tf_disc = fb.TitleFormat("$if2(%discnumber%,0)");
var tf_disc_info = fb.TitleFormat("$if(%discnumber%,$ifgreater(%totaldiscs%,1,' - [disc '%discnumber%$if(%totaldiscs%,'/'%totaldiscs%']',']'),),)");
var tf_rating = fb.TitleFormat("$if2(%rating%,0)");
var tf_mood = fb.Titleformat("$if(%mood%,1,0)");
var tf_sound = fb.Titleformat("(%sound%)");
var tf_dynamicrange = fb.Titleformat("(%dynamic range%)")
var tf_playcount = fb.TitleFormat("$if2(%LASTFM_PLAYCOUNT_DB%,$if2(%LASTFM_PLAYCOUNT_DB%,0))");
var tf_duration = fb.TitleFormat("$if2(%length%,' 0:00')");
var tf_date = fb.TitleFormat("[$year($replace(%date%,/,-,.,-))]");
var tf_genre = fb.TitleFormat("$if2(%genre%,'Other')");
var tf_playback_time = fb.TitleFormat("%playback_time%");
var tf_playback_time_remaining = fb.TitleFormat("$if(%length%,-%playback_time_remaining%,'0:00')");
var tf_length_seconds = fb.TitleFormat("%length_seconds_fp%");
// GROUP
var tf_group_key = fb.TitleFormat(group_pattern_album);
// TECH
var tf_codec = fb.Titleformat("%__codec%");
var tf_sound = fb.Titleformat("(%sound%)");
var tf_samplerate = fb.Titleformat("%__samplerate%");
var tf_bitrate = fb.TitleFormat("$if(%__bitrate_dynamic%,$if(%el_isplaying%,%__bitrate_dynamic%'kbps',$if($stricmp($left(%codec_profile%,3),'VBR'),%codec_profile%,%__bitrate%'kbps')),$if($stricmp($left(%codec_profile%,3),'VBR'),%codec_profile%,%__bitrate%'kbps'))");
var tf_bitrate_playing = fb.TitleFormat("$if(%__bitrate_dynamic%,$if(%_isplaying%,$select($add($mod(%_time_elapsed_seconds%,2),1),%__bitrate_dynamic%,%__bitrate_dynamic%),%__bitrate_dynamic%),%__bitrate%)'kbps'");
var tf_channels = fb.TitleFormat("$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)))");
//=================================================// Globals
var g_instancetype = window.InstanceType;
var g_font = null;
var g_font_headers = null;
var gh_date_font = gdi.Font("Corpid caps", 27, 0);
var g_font_guifx_found = utils.CheckFont("guifx v2 transports");
var rating_font = null;
var mood_font = null;
var del_rating_font = null;
var mini_font = gdi.Font("uni 05_53", 8, 0);
var ww = 0, wh = 0;
var mouse_x = 0, mouse_y = 0;
var g_textcolor = 0, g_textcolor_sel = 0, g_textcolor_hl = 0, g_backcolor = 0, g_backcolor_sel = 0;
var g_backcolor_R = 0, g_backcolor_G = 0, g_backcolor_B = 0;
var g_metadb;
var bool_on_size = false;
var g_search_string = "";
var incsearch_font = gdi.Font("TheMixMono 3-Light", 9, 0);
var incsearch_font_big = gdi.Font("TheMixMono 3-Light", 20, 1);
var clear_incsearch_timer = false;
var incsearch_timer = false;
var g_playing_item_y = null;
var g_seconds = 0;
var foo_playcount = utils.CheckComponent("foo_playcount", true);
var g_tooltip = window.CreateTooltip();
var g_tooltip_timer = false;
var show_tooltip = false;
var g_menu_displayed = false;
var g_add_items_timerID = false;
var g_drag = false;
panel = {
themed: window.GetProperty("SYSTEM.panel.themed", true),
wallpaper_path: window.GetProperty("*USER.background.image.path", ".\\images\\background.jpg"),
wallpaper_img: false,
show_wallpaper: window.GetProperty("*USER.background.image.enabled", false),
show_shadow_border: window.GetProperty("SYSTEM.shadow.border.enabled", true),
opacity: window.GetProperty("*USER.panel.opacity.level [0,255]", 255),
custom_textcolor: window.GetProperty("*USER.custom.text.color.normal", "RGB(200,200,210)"),
custom_textcolor_selection: window.GetProperty("*USER.custom.text.color.selection", "RGB(64,128,200)"),
custom_textcolor_highlight: window.GetProperty("*USER.custom.text.color.highlight", "RGB(150,200,250)"),
custom_backcolor: window.GetProperty("*USER.custom.background.color", "RGB(30,30,35)"),
custom_colors: window.GetProperty("SYSTEM.panel.custom.colors", false),
nogroupheader: window.GetProperty("SYSTEM.no.group.header", false),
tag_separator: window.GetProperty("*USER.title-artist.separator", "|"),
properties_separator: window.GetProperty("----------------------------", "----------------------------")
};
dragndrop = {
enabled: window.GetProperty("SYSTEM.dragndrop.enabled", true),
drag_id: -1,
drop_id: -1,
timerID: false,
drag_in: false,
drag_out: false
};
clipboard = {
selection: null
};
columns = {
playicon: window.GetProperty("SYSTEM.columns.playicon.enabled", true),
playicon_x: 0,
playicon_w: 0,
tracknumber: window.GetProperty("SYSTEM.columns.tracknumber.enabled", true),
tracknumber_x: 0,
tracknumber_w: 0,
title: window.GetProperty("SYSTEM.columns.title.pattern", 1),
title_x: 0,
title_w: 0,
rating: window.GetProperty("SYSTEM.columns.rating.enabled", true),
rating_x: 0,
rating_w: 0,
rating_timerID: false,
rating_drag: false,
mood: window.GetProperty("SYSTEM.columns.mood.enabled", true),
mood_x: 0,
mood_w: 0,
mood_timerID: false,
mood_drag: false,
bitrate: window.GetProperty("SYSTEM.columns.bitrate.enabled", false),
bitrate_x: 0,
bitrate_w: 0,
duration_x: 0,
duration_w: 0,
playcount: window.GetProperty("SYSTEM.columns.playcount.enabled", true)
};
list = {
theme: false,
first_launch: true,
total: 0,
total_gh: 0,
total_with_gh: 0,
nbvis: 0,
gridx: 0,
item: Array(),
hlist: Array(),
empty: Array(),
groups: Array(),
collapse: false,
handlelist: null,
metadblist_selection: plman.GetPlaylistSelectedItems(plman.ActivePlaylist),
focus_id: 0,
tocut: 0,
mousewheel_scrollstep: window.GetProperty("SYSTEM.mousewheel.scrollstep", 3),
nowplaying: 0,
SHIFT_start_id: null,
SHIFT_count: 0,
inc_search_noresult: false,
keypressed: false,
buttonclicked: false,
gradient_lines_show: window.GetProperty("*USER.items.gradient.lines", false)
};
row = {
h: window.GetProperty("SYSTEM.row.height", 25),
parity: 0,
show_progress: window.GetProperty("*USER.show.progress.bar", true),
buttons_hover: false
};
group = {
nbrows_default: window.GetProperty("*USER.group.rows.number", 3),
nbrows: 0,
min_item_per_group: 5,
type: window.GetProperty("SYSTEM.group.type", 0),
key: window.GetProperty("SYSTEM.group Key", group_pattern_album),
w: 0
};
toolbar = {
h: 0,
lock: window.GetProperty("SYSTEM.toolbar.lock", false),
buttons: Array(),
timerID_on: false,
timerID_off: false,
timerID1: false,
timerID2: false,
collapsed_y: -24,
delta: 0,
step: 3,
state: false
};
vscrollbar = {
theme: false,
show: window.GetProperty("SYSTEM.vscrollbar.visible", true),
visible: true,
hover: false,
x: 0,
y: 0,
default_w: get_system_scrollbar_width(),
w: get_system_scrollbar_width(),
h: 0,
button_total: 2,
default_step: window.GetProperty("SYSTEM.vscrollbar.step", 3),
step: 3,
arr_buttons: Array(),
letter : null
};
scrollbarbt = {
timerID1: false,
timerID2: false,
timer1_value: 400,
timer2_value: 60
};
button_up = {
img_normal: null,
img_hover: null,
img_down: null,
x: 0,
y: 0,
w: vscrollbar.default_w,
h: vscrollbar.default_w
};
button_down = {
img_normal: null,
img_hover: null,
img_down: null,
x: 0,
y: 0,
w: vscrollbar.default_w,
h: vscrollbar.default_w
};
cursor = {
bt: null,
img_normal: null,
img_hover: null,
img_down: null,
popup: null,
x: 0,
y: 0,
w: vscrollbar.default_w,
h: vscrollbar.default_w+3,
default_h: vscrollbar.default_w+3,
hover: false,
drag: false,
grap_y: 0,
timerID: false,
last_y: 0
};
cover = {
show: window.GetProperty("*USER.cover.art.enabled", true),
draw_glass_effect: window.GetProperty("*USER.cover.art.glass.effect.enabled", true),
keepaspectratio: window.GetProperty("*USER.cover.keep.aspect.ratio", true),
visible: true,
margin: 6,
w: 0,
nbrows: 0,
h: 0,
top_offset: 0,
load_timer: false
};
// stats globals (used in on_playback_time & on_playback_new_track Callbacks)
stats = {
metadb: null,
path_prefix: "",
taggable_file: false,
enabled: window.GetProperty("SYSTEM.statistics.enabled", false),
updated: false,
foo_playcount: utils.CheckComponent("foo_playcount", true),
tf_length_seconds: fb.TitleFormat("%length_seconds_fp%"),
tf_first_played: fb.Titleformat("%first_played%"),
tf_play_counter: fb.Titleformat("%play_counter%"),
tf_play_count: fb.Titleformat("%play_count%"),
time_elapsed: 0,
delay: 0,
limit: 0
};
//=================================================// Playlist load
function refresh_spv_cursor(pls) {
reset_cover_timers();
// RAZ actual list
list.item.splice(0, list.item.length);
list.tocut = 0;
// calc ratio of the scroll cursor to calc the equivalent item for the full playlist (with gh)
var ratio = (cursor.y-vscrollbar.y) / (vscrollbar.h-cursor.h);
// calc idx of the item (of the full playlist with gh) to display at top of the panel list (visible)
var idx = Math.round((list.total_with_gh - list.nbvis) * ratio);
// search what's the item that is the first to display in the list, and calc the list.tocut if needed
var start_id_min = Math.floor(idx / (group.nbrows+1));
var b = 0;
for(var id = start_id_min; id < list.total; id++) {
b = id + (list.hlist[id]*group.nbrows);
if(b >= idx) {
break;
};
};
// item (id) is found, now we check how many line are to cut (c)!
if(b > idx) {
var c = b - group.nbrows;
for(var d = 1; d < group.nbrows+1; d++) {
if(idx == c + d) {
list.tocut = d;
break;
};
};
} else if(b == idx) {
if(id==0) {
list.tocut = group.nbrows;
} else {
if(list.hlist[id] > list.hlist[id-1]) {
list.tocut = group.nbrows;
} else {
list.tocut = 0;
};
};
};
if(id<=0) {
id = 0;
var previous_group_key = null;
} else {
var previous_group_key = list.hlist[id-1];
};
var i = id;
var k = 0;
while(i < list.total && k<=list.nbvis+group.nbrows) {
list.item.push(new item(i, k, 0));
if(group.nbrows>0) {
if(list.hlist[i] != previous_group_key) {
list.item[k].gridx = 1;
list.item[k].update_infos();
k++;
for(var j = 1; j < group.nbrows; j++) {
list.item.push(new item(i, k, j+1));
k++;
};
list.item.push(new item(i, k, 0));
};
};
previous_group_key = list.hlist[i];
k++;
i++;
};
// affect group index of each track of each group in list.item[]
set_grp_idx_all();
};
//=================================================// Playlist scroll down
function scrolldown_spv(pls, step) {
if(list.item.length<=list.nbvis) return true;
reset_cover_timers();
var last_item_id = list.item[list.item.length-1].id;
if(last_item_id >= list.total-1) { // dernier item id = le dernier id de la playlist!
var last_item_gridx = list.item[list.item.length-1].gridx;
if(last_item_gridx>0) {
var k = list.item.length;
for(var j=last_item_gridx+1;j<=group.nbrows;j++) {
list.item.push(new item(last_item_id, k, j));
k++;
};
list.item.push(new item(last_item_id, k, 0));
} else {
// is last_item already visible? otherwise, no scroll to do, bottom reached!
var idx_last_item_vis = list.tocut+list.nbvis-1;
if(idx_last_item_vis>list.item.length-1) idx_last_item_vis = list.item.length-1;
var last_item_vis_gridx = list.item[idx_last_item_vis].gridx;
if(last_item_vis_gridx>0) {
var last_item_vis_id = list.item[idx_last_item_vis].id - 1;
} else {
var last_item_vis_id = list.item[idx_last_item_vis].id;
};
if(last_item_vis_id >= last_item_id) {
return true;
} else {
// scroll to do (no new item to add at bottom, but tocut index to increase)
list.tocut++;
};
};
} else {
// on n'est pas sur le dernier id, on peut en ajouter un au tableau item!
var last_item_group_key = list.hlist[last_item_id];
var last_item_gridx = list.item[list.item.length-1].gridx;
if(last_item_gridx > 0) {
if(last_item_gridx < group.nbrows) {
var next_item_id = last_item_id;
var next_item_gridx = last_item_gridx + 1;
} else {
var next_item_id = last_item_id;
var next_item_gridx = 0;
};
} else {
var next_item_id = last_item_id + 1;
if(list.hlist[next_item_id] != last_item_group_key) {
if(group.nbrows>0) {
var next_item_gridx = 1;
} else {
var next_item_gridx = 0;
};
} else {
var next_item_gridx = 0;
};
};
// add the next item (new one) to the array
list.item.push(new item(next_item_id, list.item.length, next_item_gridx));
if(list.item[list.item.length-2].gridx>0) {
list.item[list.item.length-1].grp_idx = 0;
} else {
list.item[list.item.length-1].grp_idx = list.item[list.item.length-2].grp_idx + 1;
};
// remove the first item of the array, to always keep the same number of items in the Array
list.item.shift();
};
var len = list.item.length;
for(var i=0; i<len; i++) {
list.item[i].idx = i;
list.item[i].defaulty = toolbar.h + i * row.h;
list.item[i].y = list.item[i].defaulty - (list.tocut * row.h);
};
setcursory();
};
//=================================================// Playlist scroll up
function scrollup_spv(pls, step) {
if(list.item.length<list.nbvis) return true;
reset_cover_timers();
var first_item_id = list.item[0].id;
if(first_item_id <= 0) {
// is the first id already visible? otherwise, no scroll to do, top of the list is already reached!
var first_item_vis_id = list.item[list.tocut].id;
if(first_item_id >= first_item_vis_id) {
if(group.nbrows > 0) {
var first_item_gridx = list.item[0].gridx;
if(first_item_gridx==1) {
if(list.tocut==0) {
return true;
} else {
list.tocut--;
};
} else {
// prev item to add to complete the group header of the first item
var prev_item_id = first_item_id;
var prev_item_gridx = (first_item_gridx==0) ? group.nbrows : first_item_gridx - 1;
// add the next item (new one) to the array
list.item.unshift(new item(prev_item_id, 0, prev_item_gridx));
// set group index value of the new item
if(prev_item_gridx>0) {
list.item[0].grp_idx = 0;
} else {
if(list.item[1].gridx>0) {
set_grp_idx_first();
} else {
list.item[0].grp_idx = list.item[1].grp_idx - 1;
};
};
// remove the last item of the array, to always keep the same number of items in the Array
list.item.pop();
};
};
} else {
// scroll to do (no new item to add at top, but tocut index to decrease)
list.tocut--;
};
} else {
if(list.tocut>group.nbrows) {
list.tocut--;
} else {
// on n'est pas sur le premier id, on peut en ajouter un au tableau item!
var first_item_group_key = list.hlist[list.item[0].id];
var first_item_gridx = list.item[0].gridx;
if(first_item_gridx > 0) {
if(first_item_gridx == 1) {
var prev_item_id = first_item_id - 1;
var prev_item_gridx = 0;
} else {
var prev_item_id = first_item_id;
var prev_item_gridx = first_item_gridx - 1;
};
} else {
var prev_item_id = first_item_id - 1;
if(list.hlist[prev_item_id] != first_item_group_key) {
if(group.nbrows>0) {
prev_item_id = first_item_id;
prev_item_gridx = group.nbrows;
} else {
prev_item_gridx = 0;
};
} else {
prev_item_gridx = 0;
};
};
// add the next item (new one) to the array
list.item.unshift(new item(prev_item_id, 0, prev_item_gridx));
// set group index value of the new item
if(prev_item_gridx>0) {
list.item[0].grp_idx = 0;
} else {
if(list.item[1].gridx>0) {
set_grp_idx_first();
} else {
list.item[0].grp_idx = list.item[1].grp_idx - 1;
};
};
// remove the last item of the array, to always keep the same number of items in the Array
if(list.item.length - list.tocut > list.nbvis+1+group.nbrows) {
list.item.pop();
};
};
};
var len = list.item.length;
for(i=0;i<len;i++) {
list.item[i].idx = i;
list.item[i].defaulty = toolbar.h + i * row.h;
list.item[i].y = list.item[i].defaulty - (list.tocut * row.h);
};
setcursory();
};
//=================================================// Playlist load
function refresh_spv(pls, force) {
var nbvis = Math.ceil((wh-toolbar.h)/row.h);
var mid_nbvis = Math.round(nbvis / 2) - 1;
g_tooltip.Text="";
reset_cover_timers();
// test if center focus item required
if(!force && list.item.length>0) {
var vis_min_idx = list.item[list.tocut].id;
var delta2max = (list.tocut+list.nbvis) - 1;
if(delta2max<list.item.length) {
vis_max_idx = (list.item[delta2max].gridx==0) ? list.item[delta2max].id : (list.item[delta2max].id - 1);
} else {
vis_max_idx = list.item[list.item.length-1].id;
};
if(list.focus_id>=vis_min_idx && list.focus_id<=vis_max_idx) {
if(button_up.timerID && list.focus_id==0 && list.item[list.tocut].gridx!=1) {
} else {
return true;
};
};
};
var m;
var focus_idx = 0;
list.tocut = 0;
// RAZ actual list
list.item.splice(0, list.item.length);
if(list.total<=0) return true;
var r = list.focus_id - list.nbvis;
if(r<=0) {
r = 0;
var previous_group_key = null;
} else {
var previous_group_key = list.hlist[r-1];
};
var i = r;
var k = 0;
while(i < list.total && k<=((group.nbrows>0?(list.nbvis*group.nbrows):list.nbvis)*2)) {
list.item.push(new item(i, k, 0));
if(group.nbrows>0) {
if(list.hlist[i] != previous_group_key) {
list.item[k].gridx = 1;
list.item[k].update_infos();
k++;
for(var g=1;g<group.nbrows;g++) {
list.item.push(new item(i, k, g+1));
k++;
};
list.item.push(new item(i, k, 0));
};
};
if(list.item[k].id == list.focus_id) focus_idx = k;
previous_group_key = list.hlist[i];
k++;
i++;
};
// calc value of list.tocut
if(list.item.length<=list.nbvis) {
list.tocut = 0;
} else {
list.tocut = focus_idx - mid_nbvis;
if(list.tocut<=0) {
list.tocut = 0;
};
if(focus_idx+mid_nbvis+1>list.item.length-1) {
list.tocut = list.item.length - list.nbvis;
};
};
// affect group index of each track of each group in list.item[]
set_grp_idx_all();
if(vscrollbar.show) {
if(list.item.length<=list.nbvis) vscrollbar.visible = false; else vscrollbar.visible=true;
} else {
vscrollbar.visible = false;
};
var ratio = list.nbvis / list.total_with_gh;
if(ratio>1) ratio = 1;
cursor.h = Math.round(ratio * vscrollbar.h);
// boundaries for cursor height
if(cursor.h>vscrollbar.h) cursor.h = vscrollbar.h;
if(cursor.h<cursor.default_h) cursor.h = cursor.default_h;
// redraw cursor image
set_scroller();
// set cursor position
setcursory();
};
function set_grp_idx_all() {
if(list.item.length<=0) return true;
if(group.nbrows>0) {
var id = list.item[0].id;
var key1 = list.hlist[id];
var key2 = null;
var grp_idx = 0;
if(list.item[0].gridx==0) {
while(id>0) {
key2 = list.hlist[id-1];
if(key2 != key1) {
id = 0;
} else {
grp_idx++;
};
id--;
};
};
id = list.item[0].id;
for(var i=0; i < list.item.length; i++) {
if(list.item[i].gridx==0) {
list.item[i].grp_idx = grp_idx;
grp_idx++;
} else {
list.item[i].grp_idx = 0;
grp_idx = 0;
};
};
} else {
for(var i=0; i < list.item.length; i++) {
list.item[i].grp_idx = list.item[i].id;
};
};
};
function set_grp_idx_first() {
if(list.item.length<=0) return true;
if(group.nbrows>0) {
var id = list.item[0].id;
var key1 = list.hlist[id];
var key2 = null;
var grp_idx = 0;
if(list.item[0].gridx==0) {
while(id>0) {
key2 = list.hlist[id-1];
if(key2 != key1) {
id = 0;
} else {
grp_idx++;
};
id--;
};
list.item[0].grp_idx = grp_idx;
} else {
list.item[0].grp_idx = 0;
};
} else {
for(var i=0; i < list.item.length; i++) {
list.item[i].grp_idx = list.item[i].id;
};
};
};
//=================================================// Offset calculations
function setcursory() {
if(list.item.length<=list.nbvis) {
cursor.y = vscrollbar.y;
} else if(list.item.length>list.tocut){
var first_id = list.item[list.tocut].id;
if(list.item[list.tocut].gridx == 0) {
var ratio = (first_id + ((list.hlist[first_id]-0) * group.nbrows)) / (list.total_with_gh-list.nbvis);
} else {
var ratio = (first_id + ((list.hlist[first_id]-0) * group.nbrows) - (group.nbrows+1-list.item[list.tocut].gridx) ) / (list.total_with_gh-list.nbvis);
};
if(ratio<0) ratio = 0;
if(ratio>1) ratio = 1;
cursor.y = vscrollbar.y + Math.round((vscrollbar.h-cursor.h) * ratio);
};
};
function init_active_pls() {
var temp_key1;
var temp_key2;
var gh_count = 0;
var empty = 0;
var count = 0;
var grp_length = 0;
var metadb;
//var d1 = new Date();
//var t1 = d1.getSeconds()*1000 + d1.getMilliseconds();
//fb.trace("avant="+t1);
list.hlist.splice(0, list.hlist.length);
list.empty.splice(0, list.empty.length);
list.groups.splice(0, list.groups.length);
if(list.handlelist) list.handlelist.Dispose();
list.handlelist = plman.GetPlaylistItems(plman.ActivePlaylist);
list.total = list.handlelist.Count;
if(group.nbrows>0) {
for (var i = 0; i < list.total; i++) {
metadb = list.handlelist.Item(i);
temp_key2 = tf_group_key.EvalWithMetadb(metadb);
if(temp_key1 != temp_key2){
if(i>0) {
list.groups.push(count);
};
//list.groups.push(list.collapse);
if(i>0 && count<group.min_item_per_group) {
empty += (group.min_item_per_group - count);
};
count = 0;
//grp_length = 0;
gh_count++;
temp_key1 = temp_key2;
};
count++;
//grp_length += metadb.Length;
list.hlist.push(gh_count);
list.empty.push(empty);
// on last item
if(i == list.total-1) {
list.groups.push(count);
};
};
} else {
for (var i = 0; i < list.total; i++) {
list.hlist.push(0);
list.empty.push(0);
};
};
list.total_gh = gh_count;
list.total_with_gh = list.total + (list.total_gh * group.nbrows);
//var d2 = new Date();
//var t2 = d2.getSeconds()*1000 + d2.getMilliseconds();
//fb.trace("pl old apres="+t2+" ==> delta = "+Math.round(t2-t1)+" /list.hlist.length="+list.hlist.length);
};
//=================================================// Colour & Font Callbacks
function on_font_changed() {
get_font();
columns.duration_w = 0;
columns.bitrate_w = 0;
refresh_spv(plman.ActivePlaylist, true);
window.Repaint();
};
function on_colors_changed() {
get_colors();
init_icons();
redraw_stub_images();
init_vscrollbar_buttons();
set_scroller();
g_image_cache = new image_cache;
CollectGarbage();
window.Repaint();
};
//=================================================// Init
function on_init() {
tf_group_key = fb.TitleFormat(group.key);
};
on_init();
//=================================================// OnSize
function on_size() {
if (!window.Width || !window.Height) return;
window.DlgCode = DLGC_WANTALLKEYS;
bool_on_size = true;
if(g_instancetype == 0) { // CUI
window.MinWidth = 200;
window.MinHeight = 100;
} else if(g_instancetype == 1) { // DUI
window.MinWidth = 200;
window.MinHeight = 100;
};
ww = window.Width;
wh = window.Height;
if(wh<100) wh = 100;
// set wallpaper
panel.wallpaper_img = FormatWP(gdi.Image(panel.wallpaper_path), ww, wh);
get_font();
get_colors();
init_icons();
recalc_datas();
redraw_stub_images();
// only on first launch
if(list.first_launch) {
list.first_launch = false;
on_playlist_switch();
} else {
// if just a window resize, refresh list.item and repaint :)
refresh_spv(plman.ActivePlaylist, true);
vscrollbar.w = vscrollbar.visible?vscrollbar.default_w:0;
window.Repaint();
}
};
//=================================================// OnPaint
function on_paint(gr) {
// default background
if(panel.opacity>=255) {
gr.FillSolidRect(0, 0, ww, wh, g_backcolor);
} else {
if(panel.show_wallpaper) {
if(panel.wallpaper_img) {
gr.FillSolidRect(0, 0, ww, wh, g_backcolor);
gr.DrawImage(panel.wallpaper_img, 0, 0, ww, wh, 0, 0, panel.wallpaper_img.Width, panel.wallpaper_img.Height, 0, 255-panel.opacity);
} else {
gr.FillSolidRect(0, 0, ww, wh, RGBA(g_backcolor_R, g_backcolor_G, g_backcolor_B, panel.opacity));
};
} else {
gr.FillSolidRect(0, 0, ww, wh, RGBA(g_backcolor_R, g_backcolor_G, g_backcolor_B, panel.opacity));
};
};
// draw items
if(list.total>0){
g_playing_item_y = null;
var draw_limit = list.tocut+list.nbvis+group.nbrows+1;
if(draw_limit>list.item.length) draw_limit = list.item.length;
for(var idx=list.tocut;idx<draw_limit;idx++) {
list.item[idx].draw(gr, list.item[idx].id, idx);
};
} else {
vscrollbar.visible = false;
vscrollbar.w = 0;
if(fb.PlaylistCount>0) {
var text_top = fb.GetPlaylistName(plman.ActivePlaylist);
var text_bot = "This playlist is empty";
} else {
var text_top = "Br3tt's WSH Playlist Viewer";
var text_bot = "Create a playlist to start!";
};
// if empty playlist, display text info
gr.SetTextRenderingHint(5);
gr.DrawString(text_top, gdi.Font("tahoma", 17, 0), g_textcolor&0x40ffffff, 0, toolbar.h-20, ww, wh, cc_stringformat);
gr.DrawString(text_bot, gdi.Font("tahoma", 13, 0), g_textcolor&0x40ffffff, 0, toolbar.h+20, ww, wh, cc_stringformat);
gr.FillGradRect(40, toolbar.h+Math.floor(wh/2), ww-80, 1, 0, 0, g_textcolor&0x40ffffff, 0.5);
};
// draw toolbar
if(!toolbar.state && !toolbar.timerID1) {
// draw marker to indicate toolbar expandable
gr.DrawLine(Math.floor((ww-vscrollbar.w)/2)-3, 2, Math.floor((ww-vscrollbar.w)/2)+3, 2, 1.0, g_textcolor&0x44ffffff);
gr.DrawLine(Math.floor((ww-vscrollbar.w)/2)-2, 3, Math.floor((ww-vscrollbar.w)/2)+0, 5, 1.0, g_textcolor&0x44ffffff);
gr.DrawLine(Math.floor((ww-vscrollbar.w)/2)+2, 3, Math.floor((ww-vscrollbar.w)/2)+1, 4, 1.0, g_textcolor&0x44ffffff);
}
if(toolbar.state || toolbar.timerID1) {
gr.SetSmoothingMode(2);
gr.FillRoundRect(09, (toolbar.collapsed_y + toolbar.delta) - 10, ww-vscrollbar.w-20 + 2, Math.abs(toolbar.collapsed_y) + 10 + 1, 6, 6, RGBA(0,0,0,60));
gr.FillRoundRect(10, (toolbar.collapsed_y + toolbar.delta) - 10, ww-vscrollbar.w-20, Math.abs(toolbar.collapsed_y) + 10, 5, 5, RGBA(0,0,0,190));
gr.DrawRoundRect(11, (toolbar.collapsed_y + toolbar.delta) - 10, ww-vscrollbar.w-20-2, Math.abs(toolbar.collapsed_y) + 10-1, 4, 4, 1.0, RGBA(250,250,250,40));
gr.SetSmoothingMode(0);
// draw toolbar buttons
for(i=0;i<toolbar.buttons.length;i++) {
switch (i) {
case 0:
toolbar.buttons[i].draw(gr, 16, (toolbar.collapsed_y + toolbar.delta) + 3, 255);
break;
case 1:
toolbar.buttons[i].draw(gr, ww-vscrollbar.w-30-15, (toolbar.collapsed_y + toolbar.delta) + 3, 255);
break;
};
};
};
// draw vscrollbar
if(vscrollbar.visible && vscrollbar.show) {
// draw scrollbar background
try {
vscrollbar.theme.SetPartAndStateId(6, 1);
vscrollbar.theme.DrawThemeBackground(gr, ww-vscrollbar.w, 0, vscrollbar.w, wh);
} catch(e) {
gr.FillGradRect(ww-vscrollbar.w, 0, vscrollbar.w, wh, 0, RGBA(0,0,0,10), RGBA(255,255,255,5), 0.5);
gr.FillSolidRect(ww-vscrollbar.w, 0, 1, wh, RGBA(0,0,0,20));
};
// draw cursor
cursor.bt.draw(gr, ww-vscrollbar.w, cursor.y, 255);
try {
vscrollbar.theme.SetPartAndStateId(9, 1);
vscrollbar.theme.DrawThemeBackground(gr, ww-vscrollbar.w, cursor.y, cursor.w, cursor.h);
} catch(e) {};
// draw scrollbar buttons (up/down)
for(i=0;i<vscrollbar.arr_buttons.length;i++) {
switch (i) {
case 0:
vscrollbar.arr_buttons[i].draw(gr, ww-vscrollbar.w, button_up.y, 255);
break;
case 1:
vscrollbar.arr_buttons[i].draw(gr, ww-vscrollbar.w, button_down.y, 255);
break;
};
};
if(cursor.drag) {
vscrollbar.letter = list.item[list.tocut].group_key.substring(0,1).toUpperCase();
cursor.popup && gr.DrawImage(cursor.popup, ww-vscrollbar.w-cursor.popup.Width, cursor.y+Math.floor(cursor.h/2)-Math.floor(cursor.popup.Height/2), cursor.popup.Width, cursor.popup.Height, 0, 0, cursor.popup.Width, cursor.popup.Height, 0, 155);
cursor.popup && gr.GdiDrawText(vscrollbar.letter, gdi.Font("segoe ui", 14, 0), g_backcolor, ww-vscrollbar.w-cursor.popup.Width, cursor.y+Math.floor(cursor.h/2)-Math.floor(cursor.popup.Height/2), cursor.popup.Width-5, cursor.popup.Height, DT_CENTER | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
};
};
if(panel.show_shadow_border) {
// vertical left borders (Sunken effect)
gr.FillSolidRect(0, toolbar.h-1, 1, wh+1, RGBA(0,0,0,30));
gr.FillSolidRect(1, toolbar.h-1, 1, wh+1, RGBA(0,0,0,15));
gr.FillSolidRect(2, toolbar.h-1, 1, wh+1, RGBA(0,0,0,5));
// and the right one, only if scrollbar is hidden
if(!vscrollbar.visible || !vscrollbar.show) {
gr.FillSolidRect(ww-vscrollbar.w-1, toolbar.h-1, 1, wh+1, RGBA(0,0,0,30));
gr.FillSolidRect(ww-vscrollbar.w-2, toolbar.h-1, 1, wh+1, RGBA(0,0,0,15));
gr.FillSolidRect(ww-vscrollbar.w-3, toolbar.h-1, 1, wh+1, RGBA(0,0,0,5));
} else {
gr.FillSolidRect(ww-vscrollbar.w-1, toolbar.h-1, 1, wh+1, RGBA(0,0,0,10));
gr.FillSolidRect(ww-vscrollbar.w-2, toolbar.h-1, 1, wh+1, RGBA(0,0,0,5));
};
// top border
gr.FillSolidRect(0, 0, ww-vscrollbar.w, 1, RGBA(0,0,0,30));
gr.FillSolidRect(1, 1, ww-vscrollbar.w, 1, RGBA(0,0,0,15));
gr.FillSolidRect(2, 2, ww-vscrollbar.w, 1, RGBA(0,0,0,5));
// bot border
gr.FillSolidRect(0, wh-1, ww-vscrollbar.w, 1, RGBA(0,0,0,30));
gr.FillSolidRect(1, wh-2, ww-vscrollbar.w, 1, RGBA(0,0,0,15));
gr.FillSolidRect(2, wh-3, ww-vscrollbar.w, 1, RGBA(0,0,0,5));
};
// Incremental Search Tooltip
if(g_search_string.length>0) {
gr.SetSmoothingMode(2);
var tt_x = Math.floor(((ww-vscrollbar.w) / 2) - (((g_search_string.length*13)+(10*2)) / 2));
var tt_y = Math.floor((wh/2) - 30);
var tt_w = Math.round((g_search_string.length*13)+(10*2));
var tt_h = 60;
gr.FillRoundRect(tt_x, tt_y, tt_w, tt_h, 5, 5, RGBA(0,0,0,150));
gr.DrawRoundRect(tt_x, tt_y, tt_w, tt_h, 5, 5, 2.0, RGBA(255,255,255,200));
gr.DrawRoundRect(tt_x+2, tt_y+2, tt_w-4, tt_h-4, 3, 3, 1.0, RGBA(0,0,0,150));
gr.GdiDrawText(g_search_string, incsearch_font_big, RGB(0,0,0), tt_x+1, tt_y+1 , tt_w , tt_h, DT_CENTER | DT_NOPREFIX | DT_CALCRECT | DT_VCENTER);
gr.GdiDrawText(g_search_string, incsearch_font_big, list.inc_search_noresult?RGB(255,75,75):RGB(250,250,250), tt_x, tt_y , tt_w , tt_h, DT_CENTER | DT_NOPREFIX | DT_CALCRECT | DT_VCENTER);
};
};
//=================================================// Mouse Callbacks
function on_mouse_lbtn_down(x, y) {
g_drag = true;
bool_on_size = false;
var act_pls = plman.ActivePlaylist;
// check toolbar buttons
if(toolbar.state) {
for(var j=0;j<toolbar.buttons.length;j++) {
toolbar.buttons[j].checkstate("down", x, y);
};
};
if(y>toolbar.delta) {
// check items
var len = list.item.length;
row.buttons_hover = false;
for(var i=0;i<len;i++) {
list.item[i].checkstate("down", x, y, i);
};
};
// check scrollbar
if(vscrollbar.visible && vscrollbar.show) {
if(cursor.bt.checkstate("down", x, y)==ButtonStates.down) {
cursor.drag = true;
cursor.grap_y = y - cursor.y;
cursor.last_y = cursor.y;
};
if(vscrollbar.hover && !cursor.drag) {
vscrollbar.step = list.nbvis;
if(y<cursor.y) {
if(!list.buttonclicked) {
list.buttonclicked = true;
on_mouse_wheel(vscrollbar.step);
scrollbarbt.timerID1 = window.SetTimeout(function () {
on_mouse_wheel(vscrollbar.step);
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
if(vscrollbar.hover) {
if(mouse_x>ww-vscrollbar.w && cursor.y > mouse_y) {
on_mouse_wheel(vscrollbar.step);
};
};
}, scrollbarbt.timer2_value+30);
}, scrollbarbt.timer1_value);
};
} else {
if(!list.buttonclicked) {
list.buttonclicked = true;
on_mouse_wheel(-1*vscrollbar.step);
scrollbarbt.timerID1 = window.SetTimeout(function () {
on_mouse_wheel(-1*vscrollbar.step);
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
if(vscrollbar.hover) {
if(mouse_x>ww-vscrollbar.w && cursor.y+cursor.h < mouse_y) {
on_mouse_wheel(-1*vscrollbar.step);
};
};
}, scrollbarbt.timer2_value+30);
}, scrollbarbt.timer1_value);
};
};
};
// check other vscrollbar buttons
for(i=0;i<vscrollbar.arr_buttons.length;i++) {
switch(i) {
case 0:
if(vscrollbar.arr_buttons[i].checkstate("down", x, y)==ButtonStates.down) {
if(!list.buttonclicked) {
list.buttonclicked = true;
scrollup_spv(act_pls, 1);
window.Repaint();
scrollbarbt.timerID1 = window.SetTimeout(function () {
reset_cover_timers();
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
scrollup_spv(act_pls, 1);
window.Repaint();
}, scrollbarbt.timer2_value);
}, scrollbarbt.timer1_value);
};
};
break;
case 1:
if(vscrollbar.arr_buttons[i].checkstate("down", x, y)==ButtonStates.down) {
if(!list.buttonclicked) {
list.buttonclicked = true;
scrolldown_spv(act_pls, 1);
window.Repaint();
scrollbarbt.timerID1 = window.SetTimeout(function () {
reset_cover_timers();
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
scrolldown_spv(act_pls, 1);
window.Repaint();
}, scrollbarbt.timer2_value);
}, scrollbarbt.timer1_value);
};
};
break;
};
};
};
};
function on_mouse_lbtn_dblclk(x, y, mask) {
if(y<toolbar.delta) {
ShowNowPlaying();
} else if(x<ww-vscrollbar.w) {
var len = list.item.length;
row.buttons_hover = false;
for(var i=0;i<len;i++) {
list.item[i].checkstate("dblclk", x, y, i);
};
} else {
on_mouse_lbtn_down(x, y);
};
};
function on_mouse_lbtn_up(x, y) {
vscrollbar.step = vscrollbar.default_step;
// scrollbar button up and down RESET
list.buttonclicked = false;
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearTimeout(scrollbarbt.timerID2);
scrollbarbt.timerID2 = false;
// check toolbar buttons
if(toolbar.state) {
for(var j=0;j<toolbar.buttons.length;j++) {
switch(j) {
case 0:
if(toolbar.buttons[j].checkstate("up", x, y)==ButtonStates.hover) {
g_menu_displayed = true;
settings_menu(x, y);
};
break;
case 1:
if(toolbar.buttons[j].checkstate("up", x, y)==ButtonStates.hover) {
g_menu_displayed = true;
sort_group_menu(x, y);
};
break;
};
};
};
if(list.total>0) {
// check scrollbar buttons
cursor.bt.checkstate("up", x, y);
for(i=0;i<vscrollbar.arr_buttons.length;i++) {
vscrollbar.arr_buttons[i].checkstate("up", x, y);
};
if(cursor.drag) {
window.RepaintRect(ww-vscrollbar.w-cursor.popup.Width-5, 0, cursor.popup.Width+vscrollbar.w+5, wh);
cursor.drag = false;
//setcursory();
} else {
// check items
var len = list.item.length;
row.buttons_hover = false;
for(i=0;i<len;i++) {
list.item[i].checkstate("up", x, y, i);
};
};
window.Repaint();
};
// Drop items after a drag'n drop outside the playlist (e.g. to a WSH playlist tab manager panel)
if(dragndrop.drag_out) {
if(!panel.ishover) {
window.NotifyOthers("WSH_playlist_drag_drop", list.metadblist_selection);
dragndrop.drag_out = false;
};
};
// Drop items after a drag'n drop inside the panel playlist
if(dragndrop.drag_in) {
if(panel.ishover && dragndrop.drag_id>=0 && dragndrop.drop_id>=0){
var nb_selected_items = list.metadblist_selection.Count;
if(dragndrop.drop_id > dragndrop.drag_id) {
// on pointe sur le dernier item de la selection si on move vers le bas
var new_drag_pos = list.handlelist.Find(list.metadblist_selection.item(nb_selected_items-1));
} else {
// on pointe sur le 1er item de la selection si on move vers le haut
var new_drag_pos = list.handlelist.Find(list.metadblist_selection.item(0));
};
var move_delta = dragndrop.drop_id - new_drag_pos;
plman.MovePlaylistSelection(plman.ActivePlaylist, move_delta);
};
};
dragndrop.drag_id = -1;
dragndrop.drop_id = -1;
dragndrop.drag_in = false;
dragndrop.drag_out = false;
dragndrop.timerID && window.ClearTimeout(dragndrop.timerID);
dragndrop.timerID = false;
window.SetCursor(IDC_ARROW);
g_drag = false;
// toolbar collapse if mouse out after a lbtn up
if(!toolbar.lock) {
if(y>30 || x<10 || x>ww-vscrollbar.w-10) {
if(toolbar.delta==0) {
toolbar.timerID_on && window.ClearTimeout(toolbar.timerID_on);
toolbar.timerID_on = false;
};
if(toolbar.state) {
if(!toolbar.timerID_off) {
if(toolbar.delta == toolbar.collapsed_y*-1) {
toolbar.timerID_off = window.SetTimeout(function() {
if(!toolbar.timerID2) {
toolbar.timerID2 = window.SetInterval(function() {
toolbar.delta -= toolbar.step;
if(toolbar.delta <= 0) {
toolbar.delta = 0;
toolbar.state = false;
window.ClearInterval(toolbar.timerID2);
toolbar.timerID2 = false;
};
window.RepaintRect(0, 0, ww, 30);
}, 30);
} ;
toolbar.timerID_off && window.ClearTimeout(toolbar.timerID_off);
toolbar.timerID_off = false;
}, 400);
};
};
};
};
};
};
function on_mouse_rbtn_down(x, y) {
bool_on_size = false;
var len = list.item.length;
row.buttons_hover = false;
for(var i=0;i<len;i++) {
if(list.item[i].checkstate("right", x, y, i)==-1) break;
};
};
function on_mouse_rbtn_up(x, y) {
if(!utils.IsKeyPressed(VK_SHIFT)) {
return true;
};
};
function on_mouse_move(x, y) {
var txt = "";
show_tooltip = false;
if(x==mouse_x && y==mouse_y) return true;
var act_pls = plman.ActivePlaylist;
panel.ishover = (x>=0 && x<=ww && y>=0 && y<=wh);
if(dragndrop.enabled && (dragndrop.drag_in || dragndrop.drag_out)) window.SetCursor(IDC_HELP); else window.SetCursor(IDC_ARROW);
if(y>toolbar.delta) {
var len = list.item.length;
var move_limit = list.tocut+list.nbvis+group.nbrows+1;
if(move_limit>len) move_limit = len;
row.buttons_hover = false;
for(var j=list.tocut;j<move_limit;j++) {
list.item[j].checkstate("move", x, y, j);
if(list.item[j].ishover && x>columns.title_x && x<columns.title_x+columns.title_w) {
if(group.nbrows==0 || (columns.title==1 && list.item[j].artist!=list.item[j].albumartist) || columns.title==2) {
txt = list.item[j].title+" "+panel.tag_separator+" "+list.item[j].artist;
} else {
txt = list.item[j].title;
};
if(txt) {
if(txt.length>0 && list.item[j].tooltip && !g_tooltip_timer) {
show_tooltip = true;
}
};
if(g_tooltip.Text != txt) {
g_tooltip.Deactivate();
g_tooltip.TrackActivate = true;
g_tooltip.Text = txt ? txt : "";
g_tooltip.TrackPosition(columns.title_x-6, list.item[j].y+Math.floor(row.h/2)-(18/2));
};
};
};
} else {
// check toolbar buttons
if(toolbar.state) {
for(j=0;j<toolbar.buttons.length;j++) {
toolbar.buttons[j].checkstate("move", x, y);
};
};
};
if(show_tooltip) {
g_tooltip.Activate();
g_tooltip.TrackActivate = true;
} else {
g_tooltip.Deactivate();
g_tooltip.TrackActivate = false;
g_tooltip.Text="";
}
if(list.item.length>0 && vscrollbar.visible && vscrollbar.show) {
vscrollbar.hover = (x>=ww-vscrollbar.w && x<=ww && y>=vscrollbar.y && y<=vscrollbar.y+vscrollbar.h);
cursor.hover = (x>=cursor.x && x<=cursor.x+cursor.w && y>=cursor.y && y<=cursor.y+cursor.h);
// check buttons
cursor.bt.checkstate("move", x, y);
for(var i=0;i<vscrollbar.arr_buttons.length;i++) {
vscrollbar.arr_buttons[i].checkstate("move", x, y);
};
if(cursor.drag && mouse_y!=y) {
reset_cover_timers();
cursor.y = y - cursor.grap_y;
// check boundaries
if(cursor.y<vscrollbar.y) cursor.y = vscrollbar.y;
if(cursor.y>vscrollbar.y+vscrollbar.h-cursor.h) cursor.y = vscrollbar.y+vscrollbar.h-cursor.h;
if(!cursor.timerID) {
cursor.timerID = window.SetTimeout(function() {
refresh_spv_cursor(act_pls);
window.Repaint();
cursor.timerID && window.ClearTimeout(cursor.timerID);
cursor.timerID = false;
}, 30);
};
};
};
show_tooltip = false;
if(dragndrop.drag_in) {
if(y<toolbar.h && y > toolbar.h-row.h) {
if(!list.buttonclicked) {
list.buttonclicked = true;
scrollbarbt.timerID1 = window.SetInterval(function () {
reset_cover_timers();
for(i=0;i<list.mousewheel_scrollstep;i++) {
scrollup_spv(act_pls, 1);
};
window.Repaint();
}, 100);
};
} else if(y>wh && y < wh+row.h) {
if(!list.buttonclicked) {
list.buttonclicked = true;
scrollbarbt.timerID1 = window.SetInterval(function () {
reset_cover_timers();
for(i=0;i<list.mousewheel_scrollstep;i++) {
scrolldown_spv(act_pls, 1);
};
window.Repaint();
}, 100);
};
} else {
scrollbarbt.timerID1 && window.ClearInterval(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
list.buttonclicked = false;
if(Math.floor((y-toolbar.h)/row.h)!=Math.floor((mouse_y-toolbar.h)/row.h)) {
if(!dragndrop.timerID) {
dragndrop.timerID = window.SetTimeout(function() {
window.Repaint();
dragndrop.timerID && window.ClearTimeout(dragndrop.timerID);
dragndrop.timerID = false;
}, 30);
};
};
};
};
// hide/show toolbar
if(!toolbar.lock && !g_drag) {
if(y>=0 && y<=15 && x>10 && x<ww-vscrollbar.w-10) {
if(!row.buttons_hover && !dragndrop.drag_in && !dragndrop.drag_out) {
if(toolbar.delta==toolbar.collapsed_y*-1) {
toolbar.timerID_off && window.ClearTimeout(toolbar.timerID_off);
toolbar.timerID_off = false;
};
if(!toolbar.timerID_on) {
if(toolbar.delta==0) {
toolbar.timerID_on = window.SetTimeout(function() {
toolbar.timerID2 && window.ClearInterval(toolbar.timerID2);
toolbar.timerID2 = false;
if(!toolbar.timerID1) {
toolbar.timerID1 = window.SetInterval(function() {
toolbar.delta += toolbar.step;
if(toolbar.collapsed_y + toolbar.delta >= 0) {
toolbar.delta = toolbar.collapsed_y*-1;
toolbar.state = true;
window.ClearInterval(toolbar.timerID1);
toolbar.timerID1 = false;
};
window.RepaintRect(0, 0, ww, 30);
}, 30);
};
toolbar.timerID_on && window.ClearTimeout(toolbar.timerID_on);
toolbar.timerID_on = false;
}, 400);
} else if(toolbar.timerID2) {
toolbar.timerID2 && window.ClearInterval(toolbar.timerID2);
toolbar.timerID2 = false;
if(!toolbar.timerID1) {
toolbar.timerID1 = window.SetInterval(function() {
toolbar.delta += toolbar.step;
if(toolbar.collapsed_y + toolbar.delta >= 0) {
toolbar.delta = toolbar.collapsed_y*-1;
toolbar.state = true;
window.ClearInterval(toolbar.timerID1);
toolbar.timerID1 = false;
};
window.RepaintRect(0, 0, ww, 30);
}, 30);
};
};
};
};
} else if(y>30 || x<10 || x>ww-vscrollbar.w-10) {
if(toolbar.delta==0) {
toolbar.timerID_on && window.ClearTimeout(toolbar.timerID_on);
toolbar.timerID_on = false;
};
if(toolbar.state) {
if(!toolbar.timerID_off) {
if(toolbar.delta == toolbar.collapsed_y*-1) {
toolbar.timerID_off = window.SetTimeout(function() {
if(!toolbar.timerID2) {
toolbar.timerID2 = window.SetInterval(function() {
toolbar.delta -= toolbar.step;
if(toolbar.delta <= 0) {
toolbar.delta = 0;
toolbar.state = false;
window.ClearInterval(toolbar.timerID2);
toolbar.timerID2 = false;
};
window.RepaintRect(0, 0, ww, 30);
}, 30);
} ;
toolbar.timerID_off && window.ClearTimeout(toolbar.timerID_off);
toolbar.timerID_off = false;
}, 400);
};
};
};
};
};
mouse_x = x;
mouse_y = y;
};
function on_mouse_wheel(delta) {
g_tooltip.Text="";
reset_cover_timers();
var act_pls = plman.ActivePlaylist;
var abs_delta = Math.abs(delta);
if(abs_delta==1) {
if(delta>0) {
for(var i=0;i<list.mousewheel_scrollstep;i++) {
scrollup_spv(act_pls, 1);
};
window.Repaint();
} else {
for(var i=0;i<list.mousewheel_scrollstep;i++) {
scrolldown_spv(act_pls, 1);
};
window.Repaint();
};
} else if(delta>0) {
for(i=0;i<delta;i++) {
scrollup_spv(act_pls, 1);
};
window.Repaint();
} else {
for(i=0;i<abs_delta;i++) {
scrolldown_spv(act_pls, 1);
};
window.Repaint();
};
};
function on_mouse_leave() {
// check buttons
if(list.total>0) {
cursor.bt.checkstate("leave", 0, 0);
};
for(var i in vscrollbar.arr_buttons) {
vscrollbar.arr_buttons[i].checkstate("leave", 0, 0);
};
for(var j in toolbar.buttons) {
toolbar.buttons[j].checkstate("leave", 0, 0);
};
var len = list.item.length;
row.buttons_hover = false;
for(i=0;i<len;i++) {
list.item[i].checkstate("leave", 0, 0, i);
};
// toolbar is to hide if visible or amorced
if(toolbar.delta==0) {
toolbar.timerID_on && window.ClearTimeout(toolbar.timerID_on);
toolbar.timerID_on = false;
};
if(!toolbar.lock && !g_drag) {
if(!g_menu_displayed) {
if(!toolbar.timerID_off) {
toolbar.timerID_off = window.SetTimeout(function() {
if(!toolbar.timerID2) {
toolbar.timerID2 = window.SetInterval(function() {
toolbar.delta -= toolbar.step;
if(toolbar.delta <= 0) {
toolbar.delta = 0;
toolbar.state = false;
window.ClearInterval(toolbar.timerID2);
toolbar.timerID2 = false;
};
window.RepaintRect(0, 0, ww, 30);
}, 30);
} ;
toolbar.timerID_off && window.ClearTimeout(toolbar.timerID_off);
toolbar.timerID_off = false;
}, 400);
};
};
};
window.Repaint();
};
//=================================================// Callbacks
function refresh_playlist_content() {
init_active_pls();
var act_pls = plman.ActivePlaylist;
list.focus_id = plman.GetPlaylistFocusItemIndex(act_pls);
refresh_spv(act_pls, true);
vscrollbar.w = vscrollbar.visible?vscrollbar.default_w:0;
window.Repaint();
};
function on_playlist_switch() {
if(isQueuePlaylistActive()) {
ShowPlaylistQueue(0);
} else {
// test if there is an active playlist focused (may happen whenyou delete a playlist from pl manager)
var act_pls = plman.ActivePlaylist;
var pls_count = plman.PlaylistCount;
if(act_pls < 0 || act_pls > pls_count) {
if(pls_count>0) {
act_pls = 0;
plman.ActivePlaylist = 0;
};
};
refresh_playlist_content();
};
};
function on_playlist_items_added(playlist_idx) {
if(playlist_idx==plman.ActivePlaylist) {
// timer to avoid freeze due to many tracks added at the same time, with this tweaks, refresh will be done when last item added only!
if(g_add_items_timerID) {
g_add_items_timerID && window.ClearTimeout(g_add_items_timerID);
g_add_items_timerID = false;
} else {
g_add_items_timerID = window.SetTimeout(function() {
refresh_playlist_content();
plman.SetActivePlaylistContext();
g_add_items_timerID && window.ClearTimeout(g_add_items_timerID);
g_add_items_timerID = false;
}, 250);
};
};
};
function on_playlist_items_removed(playlist_idx, new_count) {
if(playlist_idx==plman.ActivePlaylist) {
refresh_playlist_content();
};
plman.SetActivePlaylistContext();
};
function on_playlist_items_reordered(playlist_idx) {
if(playlist_idx==plman.ActivePlaylist) {
refresh_playlist_content();
};
};
function on_selection_changed(metadb) {
};
function on_playlist_items_selection_change() {
window.Repaint();
};
function on_item_focus_change(playlist, from, to) {
if(!ww || !wh) return true;
if(to<0) { // after a remove item in playlist!
return true;
};
if(playlist!=plman.ActivePlaylist) { // case of the item played was from the queue but was the last queued so now queue is empty
return true;
};
list.focus_id = to;
plman.SetActivePlaylistContext();
refresh_spv(plman.ActivePlaylist, bool_on_size);
bool_on_size = false;
window.Repaint();
};
function on_metadb_changed(metadb_or_metadbs, fromhook) {
var len = list.item.length;
for(var i=0;i<len;i++) {
list.item[i].update_infos();
};
window.Repaint();
};
function on_focus(is_focused) {
if(is_focused) {
plman.SetActivePlaylistContext();
} else {
g_tooltip.Deactivate();
g_tooltip.TrackActivate = false;
g_tooltip.Text="";
g_tooltip_timer && window.ClearTimeout(g_tooltip_timer);
g_tooltip_timer = window.SetTimeout(function() {
g_tooltip_timer && window.ClearTimeout(g_tooltip_timer);
g_tooltip_timer = false;
}, 500);
};
};
//=================================================// Keyboard Callbacks
function on_key_up(vkey) {
vscrollbar.step = vscrollbar.default_step;
// scroll keys up and down RESET (step and timers)
list.keypressed = false;
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearTimeout(scrollbarbt.timerID2);
scrollbarbt.timerID2 = false;
if(vkey==VK_SHIFT) {
list.SHIFT_start_id = null;
list.SHIFT_count = 0;
};
};
function on_key_down(vkey) {
if(dragndrop.drag_in) return true;
var mask = GetKeyboardMask();
var act_pls = plman.ActivePlaylist;
if (mask == KMask.none) {
switch (vkey) {
case VK_SHIFT:
list.SHIFT_count = 0;
break;
case VK_BACK:
if(g_search_string.length>0) {
var tt_x = ((ww-vscrollbar.w) / 2) - (((g_search_string.length*13)+(10*2)) / 2);
var tt_y = (wh/2) - 30;
var tt_w = ((g_search_string.length*13)+(10*2));
var tt_h = 60;
g_search_string = g_search_string.substring(0, g_search_string.length-1);
window.RepaintRect(0, tt_y-2, ww-vscrollbar.w, tt_h+4);
clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
incsearch_timer && window.ClearTimeout(incsearch_timer);
incsearch_timer = window.SetTimeout(function () {
IncrementalSearch();
incsearch_timer = false;
}, 400);
};
break;
case VK_ESCAPE:
case 222:
var tt_x = ((ww-vscrollbar.w) / 2) - (((g_search_string.length*13)+(10*2)) / 2);
var tt_y = (wh/2) - 30;
var tt_w = ((g_search_string.length*13)+(10*2));
var tt_h = 60;
g_search_string = "";
window.RepaintRect(0, tt_y-2, ww-vscrollbar.w, tt_h+4);
break;
case VK_UP:
var new_focus_id = 0;
if(!list.keypressed) {
list.keypressed = true;
reset_cover_timers();
new_focus_id = (list.focus_id>0)?list.focus_id-1:0;
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
scrollbarbt.timerID1 = window.SetTimeout(function () {
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
new_focus_id = (list.focus_id>0)?list.focus_id-1:0;
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
}, scrollbarbt.timer2_value+5);
}, scrollbarbt.timer1_value);
}
break;
case VK_DOWN:
var new_focus_id = 0;
if(!list.keypressed) {
list.keypressed = true;
reset_cover_timers();
new_focus_id = (list.focus_id<list.total-1)?list.focus_id+1:list.total-1;
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
scrollbarbt.timerID1 = window.SetTimeout(function () {
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
new_focus_id = (list.focus_id<list.total-1)?list.focus_id+1:list.total-1;
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
}, scrollbarbt.timer2_value+5);
}, scrollbarbt.timer1_value);
};
break;
case VK_PGUP:
var delta = 0;
var step = 0;
var new_focus_id = 0;
if(!list.keypressed) {
list.keypressed = true;
reset_cover_timers();
delta = list.tocut;
step = list.focus_id - list.item[delta].id;
new_focus_id = (list.focus_id-step-1>0)?list.focus_id-step-1:0;
list.focus_id = new_focus_id;
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
scrollbarbt.timerID1 = window.SetTimeout(function () {
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
delta = list.tocut;
step = list.focus_id - list.item[delta].id;
new_focus_id = (list.focus_id-step-1>0)?list.focus_id-step-1:0;
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
}, scrollbarbt.timer2_value+30);
}, scrollbarbt.timer1_value);
};
break;
case VK_PGDN:
var delta = 0;
var step = 0;
var new_focus_id = 0;
if(!list.keypressed) {
list.keypressed = true;
reset_cover_timers();
delta = (list.tocut+list.nbvis<list.item.length)?list.tocut+list.nbvis:list.item.length-1;
step = list.item[delta].id - list.focus_id;
new_focus_id = (list.focus_id<list.total-1-step)?list.focus_id+step:list.total-1;
list.focus_id = new_focus_id;
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
scrollbarbt.timerID1 = window.SetTimeout(function () {
scrollbarbt.timerID1 && window.ClearTimeout(scrollbarbt.timerID1);
scrollbarbt.timerID1 = false;
scrollbarbt.timerID2 && window.ClearInterval(scrollbarbt.timerID2);
scrollbarbt.timerID2 = window.SetInterval(function () {
delta = (list.tocut+list.nbvis<list.item.length)?list.tocut+list.nbvis:list.item.length-1;
step = list.item[delta].id - list.focus_id;
new_focus_id = (list.focus_id<list.total-1-step)?list.focus_id+step:list.total-1;
plman.SetPlaylistFocusItem(act_pls, new_focus_id);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, new_focus_id, true);
}, scrollbarbt.timer2_value+30);
}, scrollbarbt.timer1_value);
};
break;
case VK_RETURN:
// play focus item
if(!isQueuePlaylistActive()) {
plman.ExecutePlaylistDefaultAction(act_pls, list.focus_id);
};
break;
case VK_END:
plman.SetPlaylistFocusItem(act_pls, list.total-1);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, list.total-1, true);
break;
case VK_HOME:
plman.SetPlaylistFocusItem(act_pls, 0);
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, 0, true);
break;
case VK_DELETE:
if(!fb.IsAutoPlaylist(act_pls)) {
if(isQueuePlaylistActive()) {
var affected_items = Array();
var first_focus_id = null;
var next_focus_id = null;
for(var k=0; k<list.total; k++) {
if(plman.IsPlaylistItemSelected(act_pls, k)) {
affected_items.push(k);
if(first_focus_id==null) fist_focus_id = k;
next_focus_id = k + 1;
};
};
if(next_focus_id>=list.total) {
next_focus_id = fist_focus_id;
};
if(next_focus_id!=null) {
plman.SetPlaylistFocusItem(act_pls, next_focus_id);
plman.SetPlaylistSelectionSingle(act_pls, next_focus_id, true);
};
plman.RemoveItemsFromPlaybackQueue(affected_items);
} else {
plman.RemovePlaylistSelection(act_pls, false);
};
plman.SetPlaylistSelectionSingle(act_pls, plman.GetPlaylistFocusItemIndex(act_pls), true);
};
break;
};
} else {
switch(mask) {
case KMask.shift:
if(vkey==VK_UP) { // SHIFT + KEY UP
if(list.SHIFT_count==0) {
if(list.SHIFT_start_id==null) {
list.SHIFT_start_id = list.focus_id;
};
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, true);
if(list.focus_id>0) {
list.SHIFT_count--;
list.focus_id--;
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, true);
plman.SetPlaylistFocusItem(act_pls, list.focus_id);
};
} else if(list.SHIFT_count<0) {
if(list.focus_id>0) {
list.SHIFT_count--;
list.focus_id--;
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, true);
plman.SetPlaylistFocusItem(act_pls, list.focus_id);
};
} else {
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, false);
list.SHIFT_count--;
list.focus_id--;
plman.SetPlaylistFocusItem(act_pls, list.focus_id);
};
};
if(vkey==VK_DOWN) { // SHIFT + KEY DOWN
if(list.SHIFT_count==0) {
if(list.SHIFT_start_id==null) {
list.SHIFT_start_id = list.focus_id;
};
plman.ClearPlaylistSelection(act_pls);
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, true);
if(list.focus_id<list.total-1) {
list.SHIFT_count++;
list.focus_id++;
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, true);
plman.SetPlaylistFocusItem(act_pls, list.focus_id);
};
} else if(list.SHIFT_count>0) {
if(list.focus_id<list.total-1) {
list.SHIFT_count++;
list.focus_id++;
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, true);
plman.SetPlaylistFocusItem(act_pls, list.focus_id);
};
} else {
plman.SetPlaylistSelectionSingle(act_pls, list.focus_id, false);
list.SHIFT_count++;
list.focus_id++;
plman.SetPlaylistFocusItem(act_pls, list.focus_id);
};
};
break;
case KMask.ctrl:
if(vkey==65) { // CTRL+A
fb.RunMainMenuCommand("Edit/Select all");
window.Repaint();
};
if(vkey==67) { // CTRL+C
clipboard.selection = plman.GetPlaylistSelectedItems(plman.ActivePlaylist);
};
if(vkey==86) { // CTRL+V
// insert the clipboard selection (handles) after the current position in the active playlist
if(clipboard.selection) {
if(clipboard.selection.Count>0) {
try {
if(list.total>0) {
plman.InsertPlaylistItems(plman.ActivePlaylist, list.focus_id+1, clipboard.selection);
} else {
plman.InsertPlaylistItems(plman.ActivePlaylist, 0, clipboard.selection);
};
} catch(e) {
fb.trace("WSH Playlist WARNING: Clipboard can't be paste, invalid clipboard content.");
};
};
};
};
if(vkey==70) { // CTRL+F
fb.RunMainMenuCommand("Edit/Search");
};
if(vkey==78) { // CTRL+N
fb.RunMainMenuCommand("File/New playlist");
};
if(vkey==79) { // CTRL+O
fb.RunMainMenuCommand("File/Open...");
};
if(vkey==80) { // CTRL+P
fb.RunMainMenuCommand("File/Preferences");
};
if(vkey==83) { // CTRL+S
fb.RunMainMenuCommand("File/Save playlist...");
};
break;
case KMask.alt:
if(vkey==65) { // ALT+A
fb.RunMainMenuCommand("View/Always on Top");
};
break;
};
};
};
function on_char(code) {
if(list.total>0) {
var tt_x = ((ww-vscrollbar.w) / 2) - (((g_search_string.length*13)+(10*2)) / 2);
var tt_y = (wh/2) - 30;
var tt_w = ((g_search_string.length*13)+(10*2));
var tt_h = 60;
if(code==32 && g_search_string.length==0) return true; // SPACE Char not allowed on 1st char
if(g_search_string.length<=20 && tt_w<=ww-vscrollbar.w-20) {
if (code > 31) {
g_search_string = g_search_string + String.fromCharCode(code).toUpperCase();
window.RepaintRect(0, tt_y-2, ww, tt_h+4);
clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
clear_incsearch_timer = false;
incsearch_timer && window.ClearTimeout(incsearch_timer);
incsearch_timer = window.SetTimeout(function () {
IncrementalSearch();
window.ClearTimeout(incsearch_timer);
incsearch_timer = false;
}, 400);
};
};
};
};
//=================================================// Playback Callbacks
function on_playback_new_track(info) {
g_seconds = 0;
g_metadb = fb.GetNowPlaying();
window.Repaint();
};
function on_playback_stop(reason) {
if(reason==0) { // on user Stop
g_metadb = fb.GetFocusItem();
on_metadb_changed();
};
g_seconds = 0;
};
function on_playback_pause(state){
};
function on_playback_seek(time) {
on_playback_time(time);
};
function on_playback_time(time) {
// refresh now playing track in the playlist (play icon + time elapsed/remaining)
g_seconds = time;
if(g_playing_item_y!=null && plman.PlayingPlaylist==plman.ActivePlaylist) {
if(g_playing_item_y>=0-row.h && g_playing_item_y<=wh+row.h) {
if(g_playing_item_y<0) {
g_playing_item_y = 0;
};
if(g_playing_item_y>wh-row.h) {
g_playing_item_y = wh-row.h;
};
window.RepaintRect(0, g_playing_item_y, ww-vscrollbar.w, row.h);
};
};
// -------------------------------------------------------------------------------/
// Statistics TAGs Engine (v1.0 by Br3tt)
// Update the TAGs below after 50% time played :
// <FIRST_PLAYED>, <LAST_PLAYED>, <PLAY_COUNTER> (<PLAY_COUNT> replaced if found)
// -------------------------------------------------------------------------------/
if(time <= 1) {
stats.updated = false;
stats.metadb = fb.GetNowPlaying();
stats.path_prefix = stats.metadb ? stats.metadb.rawpath.substring(0,4) : "";
stats.taggable_file = (stats.path_prefix == "file" || stats.path_prefix== "cdda");
};
if(stats.metadb && stats.taggable_file && fb.IsMetadbInMediaLibrary(stats.metadb)) {
if(time <= 1) {
var total_seconds = stats.tf_length_seconds.Eval();
stats.time_elapsed = Math.floor(time);
if(total_seconds >= 10) {
stats.limit = total_seconds - 5;
stats.delay = Math.floor(total_seconds / 2);
} else {
stats.limit = total_seconds - 1;
stats.delay = 2;
};
if(stats.delay < 0) stats.delay = 0;
} else if(stats.time_elapsed > 0) {
stats.time_elapsed++;
};
if(stats.time_elapsed >= stats.delay && time <= stats.limit) {
stats.time_elapsed = 0;
var new_play_counter;
var old_play_count, old_play_counter;
old_play_count = stats.tf_play_count.Eval();
old_play_counter = stats.tf_play_counter.Eval();
var timestamp = getTimestamp();
if(old_play_count >= 0 && old_play_counter == "?") {
new_play_counter = Math.floor(old_play_count) + 1;
} else if(old_play_counter=="?") {
new_play_counter = 1;
} else {
new_play_counter = Math.floor(old_play_counter) + 1;
};
var firstplayed_ts = stats.tf_first_played.Eval();
// UPDATE TAGs
if(stats.enabled && !stats.foo_playcount && !stats.updated) {
if(firstplayed_ts != "?") {
var bool = stats.metadb.UpdateFileInfoSimple("LAST_PLAYED", timestamp, "PLAY_COUNTER", new_play_counter, "PLAY_COUNT", "");
} else {
var bool = stats.metadb.UpdateFileInfoSimple("FIRST_PLAYED", timestamp, "LAST_PLAYED", timestamp, "PLAY_COUNTER", new_play_counter, "PLAY_COUNT", "");
};
stats.updated = true;
// report to console
fb.trace("WSH: Statistics updated to file at : " + fb.PlaybackTime + ".");
};
};
};
};
//=================================================// Font & Colors
function get_font() {
if (g_instancetype == 0) {
g_font = window.gdi.Font("corpid light",12,0);
g_font_headers = window.gdi.Font("corpid light",12,0);
} else if (g_instancetype == 1) {
g_font = window.GetFontDUI(FontTypeDUI.playlists);
g_font_headers = window.GetFontDUI(FontTypeDUI.tabs);
};
if(g_font_guifx_found) {
rating_font = gdi.Font("guifx v2 transports", 17, 0);
del_rating_font = gdi.Font("guifx v2 transports", 13, 0);
mood_font = gdi.Font("guifx v2 transports", 16, 0);
} else {
rating_font = gdi.Font("corpid CD Bold",22,0);
del_rating_font = gdi.Font("corpid CD Bold",22,0);
mood_font = gdi.Font("corpid CD Bold",22,1);
};
};
function get_colors() {
if (g_instancetype == 0) {
g_textcolor = window.GetColorCUI(ColorTypeCUI.text);
g_textcolor_sel = window.GetColorCUI(ColorTypeCUI.selection_text);
g_textcolor_hl = window.GetColorCUI(ColorTypeCUI.active_item_frame);
g_backcolor = window.GetColorCUI(ColorTypeCUI.background);
g_backcolor_sel = window.GetColorCUI(ColorTypeCUI.selection_background)
} else if (g_instancetype == 1) {
g_textcolor = window.GetColorDUI(ColorTypeDUI.text);
g_textcolor_sel = window.GetColorDUI(ColorTypeDUI.selection);
g_textcolor_hl = window.GetColorDUI(ColorTypeDUI.highlight);
g_backcolor = window.GetColorDUI(ColorTypeDUI.background);
g_backcolor_sel = g_textcolor_sel
};
// Custom colors set in Properties of the panel
if(panel.custom_colors) {
try{
if(panel.custom_textcolor.length>0) g_textcolor = eval(panel.custom_textcolor);
if(panel.custom_textcolor_selection.length>0) {
g_textcolor_sel = eval(panel.custom_textcolor_selection);
g_backcolor_sel = g_textcolor_sel;
};
if(panel.custom_backcolor.length>0) g_backcolor = eval(panel.custom_backcolor);
if(panel.custom_textcolor_highlight.length>0) g_textcolor_hl = eval(panel.custom_textcolor_highlight);
} catch(e) {};
};
g_backcolor_R = getRed(g_backcolor);
g_backcolor_G = getGreen(g_backcolor);
g_backcolor_B = getBlue(g_backcolor)
};
//=================================================// Images (general)
function set_scroller() {
var gb;
try {
cursor.img_normal = gdi.CreateImage(cursor.w, cursor.h);
} catch(e) {
cursor.h = cursor.default_h;
cursor.img_normal = gdi.CreateImage(cursor.w, cursor.h);
};
gb = cursor.img_normal.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(3, 1);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, cursor.w, cursor.h);
} catch(e) {
gb.FillSolidRect(3, 0, cursor.w-6, cursor.h, g_textcolor&0x44ffffff);
};
cursor.img_normal.ReleaseGraphics(gb);
cursor.img_hover = gdi.CreateImage(cursor.w, cursor.h);
gb = cursor.img_hover.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(3, 2);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, cursor.w, cursor.h);
} catch(e) {
gb.FillSolidRect(3, 0, cursor.w-6, cursor.h, g_textcolor&0x88ffffff);
};
cursor.img_hover.ReleaseGraphics(gb);
cursor.bt = new button(cursor.img_normal, cursor.img_hover, cursor.img_hover);
};
function init_vscrollbar_buttons() {
var i, gb;
cursor.popup = gdi.CreateImage(27, 22);
gb = cursor.popup.GetGraphics();
gb.SetSmoothingMode(2);
gb.FillRoundRect(0,0,22-1,22-1,3,3,g_textcolor);
gb.DrawRoundRect(0,0,22-1,22-1,3,3,1.0,RGBA(0,0,0,150));
var points = Array(22-2,7, 22-2+6,11, 22-2,22-7);
gb.FillPolygon(g_textcolor, 0, points);
gb.DrawPolygon(RGBA(0,0,0,150), 1.0, points);
gb.SetSmoothingMode(0);
gb.FillSolidRect(22-4,6,3,22-10,g_textcolor);
cursor.popup.ReleaseGraphics(gb);
button_up.img_normal = gdi.CreateImage(button_up.w, button_up.h);
gb = button_up.img_normal.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(1, 1);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, button_up.w, button_up.h);
} catch(e) {
gb.SetSmoothingMode(2);
var mid_x = Math.round(button_up.w/2);
gb.DrawLine(mid_x-4, 10, mid_x+0, 5, 2.0, g_textcolor&0x44ffffff);
gb.DrawLine(mid_x+0, 6, mid_x+3, 10, 2.0, g_textcolor&0x44ffffff);
};
button_up.img_normal.ReleaseGraphics(gb);
button_up.img_hover = gdi.CreateImage(button_up.w, button_up.h);
gb = button_up.img_hover.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(1, 2);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, button_up.w, button_up.h);
} catch(e) {
gb.SetSmoothingMode(2);
var mid_x = Math.round(button_up.w/2);
gb.DrawLine(mid_x-4, 10, mid_x+0, 5, 2.0, g_textcolor&0x88ffffff);
gb.DrawLine(mid_x+0, 6, mid_x+3, 10, 2.0, g_textcolor&0x88ffffff);
};
button_up.img_hover.ReleaseGraphics(gb);
button_up.img_down = gdi.CreateImage(button_up.w, button_up.h);
gb = button_up.img_down.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(1, 3);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, button_up.w, button_up.h);
} catch(e) {
gb.SetSmoothingMode(2);
var mid_x = Math.round(button_up.w/2);
gb.DrawLine(mid_x-4, 10, mid_x+0, 5, 2.0, g_textcolor);
gb.DrawLine(mid_x+0, 6, mid_x+3, 10, 2.0, g_textcolor);
};
button_up.img_down.ReleaseGraphics(gb);
button_down.img_normal = gdi.CreateImage(button_down.w, button_down.h);
gb = button_down.img_normal.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(1, 5);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, button_down.w, button_down.h);
} catch(e) {
gb.SetSmoothingMode(2);
var mid_x = Math.round(button_up.w/2);
gb.DrawLine(mid_x-4, button_down.h-11, mid_x+0, button_down.h-6, 2.0, g_textcolor&0x44ffffff);
gb.DrawLine(mid_x+0, button_down.h-7, mid_x+3, button_down.h-11, 2.0, g_textcolor&0x44ffffff);
};
button_down.img_normal.ReleaseGraphics(gb);
button_down.img_hover = gdi.CreateImage(button_down.w, button_down.h);
gb = button_down.img_hover.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(1, 6);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, button_down.w, button_down.h);
} catch(e) {
gb.SetSmoothingMode(2);
var mid_x = Math.round(button_up.w/2);
gb.DrawLine(mid_x-4, button_down.h-11, mid_x+0, button_down.h-6, 2.0, g_textcolor&0x88ffffff);
gb.DrawLine(mid_x+0, button_down.h-7, mid_x+3, button_down.h-11, 2.0, g_textcolor&0x88ffffff);
};
button_down.img_hover.ReleaseGraphics(gb);
button_down.img_down = gdi.CreateImage(button_down.w, button_down.h);
gb = button_down.img_down.GetGraphics();
// Draw Themed Scrollbar (lg/col)
try {
vscrollbar.theme.SetPartAndStateId(1, 7);
vscrollbar.theme.DrawThemeBackground(gb, 0, 0, button_down.w, button_down.h);
} catch(e) {
gb.SetSmoothingMode(2);
var mid_x = Math.round(button_up.w/2);
gb.DrawLine(mid_x-4, button_down.h-11, mid_x+0, button_down.h-6, 2.0, g_textcolor);
gb.DrawLine(mid_x+0, button_down.h-7, mid_x+3, button_down.h-11, 2.0, g_textcolor);
};
button_down.img_down.ReleaseGraphics(gb);
vscrollbar.arr_buttons.splice(0, vscrollbar.arr_buttons.length);
for(i=0;i<vscrollbar.button_total;i++) {
switch(i) {
case 0:
vscrollbar.arr_buttons.push(new button(button_up.img_normal, button_up.img_hover, button_up.img_down));
break;
case 1:
vscrollbar.arr_buttons.push(new button(button_down.img_normal, button_down.img_hover, button_down.img_down));
break;
};
};
};
//=================================================// Init Icons and Images (no_cover ...)
function init_icons() {
var i;
var gb;
var gui_font = gdi.Font("guifx v2 transports", 15, 0);
glass_reflect_img = draw_glass_reflect(120, 120);
playicon_off = gdi.CreateImage(20, row.h);
gb = playicon_off.GetGraphics();
gb.SetSmoothingMode(2);
var x1 = 0;
var y1 = Math.floor(row.h/2) - 6;
var x2 = 12;
var y2 = Math.floor(row.h/2);
var x3 = 0;
var y3 = Math.floor(row.h/2) + 6;
var points = Array(x1, y1, x2, y2, x3, y3);
gb.FillPolygon(g_backcolor, 0, points);
gb.DrawPolygon(g_textcolor, 1.0, points);
gb.SetSmoothingMode(0);
playicon_off.ReleaseGraphics(gb);
playicon_on = gdi.CreateImage(20, row.h);
gb = playicon_on.GetGraphics();
gb.SetSmoothingMode(2);
var x1 = 0;
var y1 = Math.floor(row.h/2) - 6;
var x2 = 12;
var y2 = Math.floor(row.h/2);
var x3 = 0;
var y3 = Math.floor(row.h/2) + 6;
var points = Array(x1, y1, x2, y2, x3, y3); gb.FillPolygon(g_backcolor, 0, points);
gb.FillPolygon(g_backcolor, 0, points);
gb.FillPolygon(g_textcolor_sel&0x77ffffff, 0, points);
gb.DrawPolygon(g_textcolor, 1.0, points);
gb.SetSmoothingMode(0);
playicon_on.ReleaseGraphics(gb);
// singleline group header icon
singleline_group_header_icon = gdi.CreateImage(18, 16);
gb = singleline_group_header_icon.GetGraphics();
gb.SetSmoothingMode(2);
gb.DrawEllipse(1,2,12,12,1.0,g_textcolor_hl&0x99ffffff);
gb.FillEllipse(3,4,8,8,g_textcolor&0x55ffffff);
singleline_group_header_icon.ReleaseGraphics(gb);
// drag_n_drop markers around line of insert
icon_arrow_left = gdi.CreateImage(8, 8);
gb = icon_arrow_left.GetGraphics();
gb.SetSmoothingMode(0);
gb.DrawLine(0, 0, 0, 7, 1.0, g_textcolor);
gb.DrawLine(1, 1, 1, 7-1, 1.0, g_textcolor);
gb.DrawLine(2, 2, 2, 7-2, 1.0, g_textcolor);
gb.DrawLine(3, 3, 3, 7-3, 1.0, g_textcolor);
icon_arrow_left.ReleaseGraphics(gb);
nocover = gdi.CreateImage(200, 200);
gb = nocover.GetGraphics();
gb.SetSmoothingMode(2);
gb.FillSolidRect(0,0,200,200,g_textcolor);
gb.FillGradRect(0,0,200,200,90,g_backcolor&0xbbffffff,g_backcolor,1.0);
gb.SetTextRenderingHint(3);
gui_font = gdi.Font("Segoe UI", 108, 1);
gb.DrawString("NO", gui_font, g_textcolor&0x25ffffff, 0, 0, 200, 110, cc_stringformat);
gui_font = gdi.Font("Segoe UI", 48, 1);
gb.DrawString("COVER", gui_font, g_textcolor&0x20ffffff, 1, 70, 200, 110, cc_stringformat);
gb.FillSolidRect(24, 155, 152, 20, g_textcolor&0x15ffffff);
nocover.ReleaseGraphics(gb);
noartist = gdi.CreateImage(200, 200);
gb = noartist.GetGraphics();
gb.SetSmoothingMode(2);
gb.FillSolidRect(0,0,200,200,g_textcolor);
gb.FillGradRect(0,0,200,200,90,g_backcolor&0xbbffffff,g_backcolor,1.0);
gb.FillEllipse(100-90/2,110,150,300,g_textcolor&0x25ffffff);
gb.FillEllipse(100-90/2,25,90,90,g_textcolor&0x25ffffff);
noartist.ReleaseGraphics(gb);
streamcover = gdi.CreateImage(200, 200);
gb = streamcover.GetGraphics();
gb.SetSmoothingMode(2);
gb.FillSolidRect(0,0,200,200,g_textcolor);
gb.FillGradRect(0,0,200,200,90,g_backcolor&0xbbffffff,g_backcolor,1.0);
gui_font = gdi.Font("Segoe UI", 42, 0);
gb.SetTextRenderingHint(3);
gb.DrawString("stream", gui_font, g_backcolor, 1, 2, 200, 190, cc_stringformat);
gb.DrawString("stream", gui_font, g_textcolor&0x99ffffff, 1, 0, 200, 190, cc_stringformat);
streamcover.ReleaseGraphics(gb);
// Toolbar buttons
// Settings Menu button
bt_settings_off = gdi.CreateImage(30, 20);
gb = bt_settings_off.GetGraphics();
gui_font = gdi.Font("Tahoma", 28, 1);
gb.SetTextRenderingHint(3);
gb.DrawString("*", gui_font, RGB(150,150,150), 0, 2, 20, 20, lc_stringformat);
gb.SetSmoothingMode(2);
gb.FillEllipse(2,3,12,10,RGB(140,140,140));
gb.DrawEllipse(5,5,6,6,2.0,RGBA(0,0,0,200));
gb.DrawEllipse(2,3,12,10,1.0,RGBA(0,0,0,80));
gb.SetSmoothingMode(0);
gb.DrawLine(16+8-4, 8-2+2, 16+8+4, 8-2+2, 1.0, RGB(140,140,140));
gb.DrawLine(16+8-3, 8-1+2, 16+8+3, 8-1+2, 1.0, RGB(140,140,140));
gb.DrawLine(16+8-2, 8-0+2, 16+8+2, 8-0+2, 1.0, RGB(140,140,140));
gb.DrawLine(16+8-1, 8+1+2, 16+8+1, 8+1+2, 1.0, RGB(140,140,140));
gb.FillSolidRect(16+8-0, 8+2+2, 1, 1, RGB(140,140,140));
bt_settings_off.ReleaseGraphics(gb);
bt_settings_ov = gdi.CreateImage(30, 20);
gb = bt_settings_ov.GetGraphics();
gui_font = gdi.Font("Tahoma", 28, 1);
gb.SetTextRenderingHint(3);
gb.DrawString("*", gui_font, RGB(190,190,190), 0, 2, 20, 20, lc_stringformat);
gb.SetSmoothingMode(2);
gb.FillEllipse(2,3,12,10,RGB(180,180,180));
gb.DrawEllipse(5,5,6,6,2.0,RGBA(0,0,0,220));
gb.DrawEllipse(2,3,12,10,1.0,RGBA(0,0,0,140));
gb.SetSmoothingMode(0);
gb.DrawLine(16+8-4, 8-2+2, 16+8+4, 8-2+2, 1.0, RGB(180,180,180));
gb.DrawLine(16+8-3, 8-1+2, 16+8+3, 8-1+2, 1.0, RGB(180,180,180));
gb.DrawLine(16+8-2, 8-0+2, 16+8+2, 8-0+2, 1.0, RGB(180,180,180));
gb.DrawLine(16+8-1, 8+1+2, 16+8+1, 8+1+2, 1.0, RGB(180,180,180));
gb.FillSolidRect(16+8-0, 8+2+2, 1, 1, RGB(180,180,180));
bt_settings_ov.ReleaseGraphics(gb);
bt_settings_on = gdi.CreateImage(30, 20);
gb = bt_settings_on.GetGraphics();
gui_font = gdi.Font("Tahoma", 28, 1);
gb.SetTextRenderingHint(3);
gb.DrawString("*", gui_font, RGB(230,230,230), 0, 2, 20, 20, lc_stringformat);
gb.SetSmoothingMode(2);
gb.FillEllipse(2,3,12,10,RGB(180,180,180));
gb.DrawEllipse(5,5,6,6,2.0,RGBA(0,0,0,240));
gb.DrawEllipse(2,3,12,10,1.0,RGBA(0,0,0,160));
gb.SetSmoothingMode(0);
gb.DrawLine(16+8-4, 8-2+2, 16+8+4, 8-2+2, 1.0, RGB(220,220,220));
gb.DrawLine(16+8-3, 8-1+2, 16+8+3, 8-1+2, 1.0, RGB(220,220,220));
gb.DrawLine(16+8-2, 8-0+2, 16+8+2, 8-0+2, 1.0, RGB(220,220,220));
gb.DrawLine(16+8-1, 8+1+2, 16+8+1, 8+1+2, 1.0, RGB(220,220,220));
gb.FillSolidRect(16+8-0, 8+2+2, 1, 1, RGB(220,220,220));
bt_settings_on.ReleaseGraphics(gb);
// Sort/group Menu button
bt_sort_off = gdi.CreateImage(30, 20);
gb = bt_sort_off.GetGraphics();
gui_font = gdi.Font("Tahoma", 15, 0);
gb.SetTextRenderingHint(5);
gb.DrawString("Az", gui_font, RGB(140,140,140), 0, -2, 20, 20, lc_stringformat);
gb.SetSmoothingMode(0);
gb.DrawLine(16+8-4, 8-2+2, 16+8+4, 8-2+2, 1.0, RGB(140,140,140));
gb.DrawLine(16+8-3, 8-1+2, 16+8+3, 8-1+2, 1.0, RGB(140,140,140));
gb.DrawLine(16+8-2, 8-0+2, 16+8+2, 8-0+2, 1.0, RGB(140,140,140));
gb.DrawLine(16+8-1, 8+1+2, 16+8+1, 8+1+2, 1.0, RGB(140,140,140));
gb.FillSolidRect(16+8-0, 8+2+2, 1, 1, RGB(140,140,140));
bt_sort_off.ReleaseGraphics(gb);
bt_sort_ov = gdi.CreateImage(30, 20);
gb = bt_sort_ov.GetGraphics();
gui_font = gdi.Font("Tahoma", 15, 0);
gb.SetTextRenderingHint(5);
gb.DrawString("Az", gui_font, RGB(180,180,180), 0, -2, 20, 20, lc_stringformat);
gb.SetSmoothingMode(0);
gb.DrawLine(16+8-4, 8-2+2, 16+8+4, 8-2+2, 1.0, RGB(180,180,180));
gb.DrawLine(16+8-3, 8-1+2, 16+8+3, 8-1+2, 1.0, RGB(180,180,180));
gb.DrawLine(16+8-2, 8-0+2, 16+8+2, 8-0+2, 1.0, RGB(180,180,180));
gb.DrawLine(16+8-1, 8+1+2, 16+8+1, 8+1+2, 1.0, RGB(180,180,180));
gb.FillSolidRect(16+8-0, 8+2+2, 1, 1, RGB(180,180,180));
bt_sort_ov.ReleaseGraphics(gb);
bt_sort_on = gdi.CreateImage(30, 20);
gb = bt_sort_on.GetGraphics();
gui_font = gdi.Font("Tahoma", 15, 0);
gb.SetTextRenderingHint(5);
gb.DrawString("Az", gui_font, RGB(220,220,220), 0, -2, 20, 20, lc_stringformat);
gb.SetSmoothingMode(0);
gb.DrawLine(16+8-4, 8-2+2, 16+8+4, 8-2+2, 1.0, RGB(220,220,220));
gb.DrawLine(16+8-3, 8-1+2, 16+8+3, 8-1+2, 1.0, RGB(220,220,220));
gb.DrawLine(16+8-2, 8-0+2, 16+8+2, 8-0+2, 1.0, RGB(220,220,220));
gb.DrawLine(16+8-1, 8+1+2, 16+8+1, 8+1+2, 1.0, RGB(220,220,220));
gb.FillSolidRect(16+8-0, 8+2+2, 1, 1, RGB(220,220,220));
bt_sort_on.ReleaseGraphics(gb);
toolbar.buttons.splice(0, toolbar.buttons.length);
for(i=0;i<2;i++) {
switch(i) {
case 0:
toolbar.buttons.push(new button(bt_settings_off, bt_settings_ov, bt_settings_on));
break;
case 1:
toolbar.buttons.push(new button(bt_sort_off, bt_sort_ov, bt_sort_on));
break;
};
};
};
function recalc_datas() {
if(toolbar.lock) {
toolbar.delta = toolbar.collapsed_y*-1;
toolbar.state = true;
};
if(panel.nogroupheader) {
group.nbrows = 0;
} else {
group.nbrows = group.nbrows_default;
};
list.nbvis = (((wh-toolbar.h)/row.h) == Math.ceil((wh-toolbar.h)/row.h)) ? Math.ceil((wh-toolbar.h)/row.h) : Math.ceil(((wh-toolbar.h)/row.h)-1);
if(panel.themed) {
vscrollbar.theme = window.CreateThemeManager("scrollbar");
list.theme = window.CreateThemeManager("listview");
} else {
vscrollbar.theme = false;
list.theme = false;
};
init_vscrollbar_buttons();
button_up.y = 0;
button_down.y = wh - button_down.h;
vscrollbar.y = button_up.h;
vscrollbar.h = wh - button_up.h - button_down.h;
cursor.x = ww-vscrollbar.w;
cursor.y = vscrollbar.y;
if(cover.show) {
cover.w = group.nbrows*row.h;
} else {
cover.w = 0;
};
if(cover.w>row.h) {
cover.visible = true;
cover.h = cover.w;
cover.nbrows = Math.ceil(cover.w/row.h);
} else {
cover.visible = false;
cover.h = cover.w;
cover.nbrows = Math.ceil(cover.w/row.h);
};
};
function redraw_stub_images() {
nocover_img = FormatCover(nocover, (cover.w-cover.margin*2), (cover.h-cover.margin*2));
noartist_img = FormatCover(noartist, (cover.w-cover.margin*2), (cover.h-cover.margin*2));
streamcover_img = FormatCover(streamcover, (cover.w-cover.margin*2), (cover.h-cover.margin*2));
};
function SelectGroupItems(start_id) {
var count = 0;
var affectedItems = Array();
if(!utils.IsKeyPressed(VK_CONTROL)) {
plman.ClearPlaylistSelection(plman.ActivePlaylist);
};
for(var i = start_id; i < list.total; i++) {
if(list.hlist[i] != list.hlist[start_id]) {
break;
} else {
affectedItems.push(i);
};
count++;
if(count>9999) break;
};
plman.SetPlaylistSelection(plman.ActivePlaylist, affectedItems, true);
plman.SetPlaylistFocusItem(plman.ActivePlaylist, start_id);
CollectGarbage();
};
function SelectAtoB(start_id, end_id) {
var affectedItems = Array();
if(list.SHIFT_start_id==null) {
list.SHIFT_start_id = start_id;
};
plman.ClearPlaylistSelection(plman.ActivePlaylist);
var previous_focus_id = list.focus_id;
if(start_id<end_id) {
var deb = start_id;
var fin = end_id;
} else {
var deb = end_id;
var fin = start_id;
};
for(var i=deb;i<=fin;i++) {
affectedItems.push(i);
};
plman.SetPlaylistSelection(plman.ActivePlaylist, affectedItems, true);
plman.SetPlaylistFocusItem(plman.ActivePlaylist, end_id);
if(affectedItems.length>1) {
if(end_id > previous_focus_id) {
var delta = end_id - previous_focus_id;
list.SHIFT_count += delta;
} else {
var delta = previous_focus_id - end_id;
list.SHIFT_count -= delta;
};
};
window.Repaint();
};
function ShowNowPlaying() {
if(fb.IsPlaying) {
if(plman.PlayingPlaylist!=plman.ActivePlaylist) {
plman.ActivePlaylist = plman.PlayingPlaylist;
};
if(plman.PlaylistItemCount(plman.PlayingPlaylist)==0 || !fb.GetFocusItem(false)) return true;
plman.ClearPlaylistSelection(plman.ActivePlaylist);
list.nowplaying = plman.GetPlayingItemLocation();
var pid = list.nowplaying.PlaylistItemIndex;
plman.SetPlaylistFocusItem(plman.ActivePlaylist, pid);
plman.SetPlaylistSelectionSingle(plman.ActivePlaylist, pid, true);
if(pid>=0 && pid<list.total) {
refresh_spv(plman.ActivePlaylist, false);
};
} else {
plman.ClearPlaylistSelection(plman.ActivePlaylist);
var pid = plman.GetPlaylistFocusItemIndex(plman.ActivePlaylist);
plman.SetPlaylistFocusItem(plman.ActivePlaylist, pid);
plman.SetPlaylistSelectionSingle(plman.ActivePlaylist, pid, true);
if(pid>=0 && pid<list.total) {
refresh_spv(plman.ActivePlaylist, false);
};
};
};
function ShowSelectedItem(pid) {
if(list.total==0 || !fb.GetFocusItem(false)) return true;
if(pid<0) {
pid = plman.GetPlaylistFocusItemIndex(plman.ActivePlaylist);
};
plman.ClearPlaylistSelection(plman.ActivePlaylist);
plman.SetPlaylistFocusItem(plman.ActivePlaylist, pid);
plman.SetPlaylistSelectionSingle(plman.ActivePlaylist, pid, true);
refresh_spv(plman.ActivePlaylist);
};
function IncrementalSearch() {
var count=0;
var albumartist;
var chr;
var gstart;
var pid = -1;
// exit if no search string in cache
if(g_search_string.length<=0) return true;
// 1st char of the search string
var first_chr = g_search_string.substring(0,1);
var len = g_search_string.length;
// which start point for the search
if(list.total>1000) {
albumartist = tf_albumartist.EvalWithMetadb(list.handlelist.Item(Math.floor(list.total/2)));
chr = albumartist.substring(0,1);
if(first_chr.charCodeAt(first_chr) > chr.charCodeAt(chr)) {
gstart = Math.floor(list.total/2);
} else {
gstart = 0;
};
} else {
gstart = 0;
};
var format_str = "";
for(var i=gstart;i<list.total;i++) {
albumartist = tf_albumartist.EvalWithMetadb(list.handlelist.Item(i));
format_str = albumartist.substring(0,len).toUpperCase();
if(format_str==g_search_string) {
pid = i;
break;
};
};
if(pid>=0) { // found!
ShowSelectedItem(pid);
} else {
list.inc_search_noresult = true;
window.Repaint();
};
clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
clear_incsearch_timer = window.SetInterval(function () {
// reset incremental search string after 1 seconds without any key pressed
var tt_x = ((ww-vscrollbar.w) / 2) - (((g_search_string.length*13)+(10*2)) / 2);
var tt_y = (wh/2) - 30;
var tt_w = ((g_search_string.length*13)+(10*2));
var tt_h = 60;
g_search_string = "";
window.RepaintRect(0, tt_y-2, ww-vscrollbar.w, tt_h+4);
clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
clear_incsearch_timer = false;
list.inc_search_noresult = false;
}, 1000);
};
//=================================================// Item Context Menu
function new_context_menu(x, y, id, array_id) {
var _menu = window.CreatePopupMenu();
var Context = fb.CreateContextMenuManager();
var _child01 = window.CreatePopupMenu();
var _child02 = window.CreatePopupMenu();
list.metadblist_selection = plman.GetPlaylistSelectedItems(plman.ActivePlaylist);
Context.InitContext(list.metadblist_selection);
Context.BuildMenu(_menu, 1, -1);
_child01.AppendTo(_menu, MF_STRING, "Selection...");
_child01.AppendMenuItem((fb.IsAutoPlaylist(plman.ActivePlaylist) || isQueuePlaylistActive())?MF_DISABLED|MF_GRAYED:MF_STRING, 1000, "Remove");
_child02.AppendTo(_child01, MF_STRING, "Send to...");
_child02.AppendMenuItem(MF_STRING, 2000, "a New playlist...");
_child02.AppendMenuItem(MF_SEPARATOR, 0, "");
var pl_count = plman.PlaylistCount;
for(var i=0;i<pl_count;i++) {
if(i!=plman.ActivePlaylist && !fb.IsAutoPlaylist(i)) {
_child02.AppendMenuItem(MF_STRING, 2001+i, plman.GetPlaylistName(i));
};
};
var ret = _menu.TrackPopupMenu(x, y);
if(ret<800) {
Context.ExecuteByID(ret - 1);
} else if(ret<1000) {
switch (ret) {
case 880:
break;
};
} else {
switch (ret) {
case 1000:
plman.RemovePlaylistSelection(plman.ActivePlaylist, false);
break;
case 2000:
fb.RunMainMenuCommand("File/New playlist");
plman.InsertPlaylistItems(plman.PlaylistCount-1, 0, list.metadblist_selection, false);
break;
default:
var insert_index = plman.PlaylistItemCount(ret-2001);
plman.InsertPlaylistItems((ret-2001), insert_index, list.metadblist_selection, false);
};
};
_child01.Dispose();
_child02.Dispose();
_menu.Dispose();
return true;
};
function sort_group_menu(x, y) {
var idx;
var _menu = window.CreatePopupMenu();
var _sort = window.CreatePopupMenu();
var _groupby = window.CreatePopupMenu();
_sort.AppendTo(_menu, MF_STRING, "Sort");
_sort.AppendMenuItem(MF_STRING, 100, "Sort by album");
_sort.AppendMenuItem(MF_STRING, 110, "Sort by artist");
_sort.AppendMenuItem(MF_STRING, 120, "Sort by file path");
_sort.AppendMenuItem(MF_STRING, 130, "Sort by date");
_sort.AppendMenuItem(MF_STRING, 140, "Sort by genre");
_sort.AppendMenuItem(MF_STRING, 150, "Randomize");
_sort.AppendMenuItem(MF_STRING, 160, "Reverse");
_groupby.AppendTo(_menu, MF_STRING, "Group/Sort");
_groupby.AppendMenuItem(MF_STRING, 200, "Group/Sort by album");
_groupby.AppendMenuItem(MF_STRING, 201, "Group/Sort by artist");
_groupby.AppendMenuItem(MF_STRING, 202, "Group/Sort by file path");
idx = _menu.TrackPopupMenu(x, y);
switch(idx) {
case 100:
plman.SortByFormat(plman.ActivePlaylist, sort_pattern_album, false);
break;
case 110:
plman.SortByFormat(plman.ActivePlaylist, sort_pattern_artist, false);
break;
case 120:
plman.SortByFormat(plman.ActivePlaylist, sort_pattern_path, false);
break;
case 130:
plman.SortByFormat(plman.ActivePlaylist, sort_pattern_date, false);
break;
case 140:
plman.SortByFormat(plman.ActivePlaylist, sort_pattern_genre, false);
break;
case 150:
plman.SortByFormat(plman.ActivePlaylist, "", false);
break;
case 160:
fb.RunMainMenuCommand("Edit/Sort/Reverse");
break;
case 200:
group.type = 0;
window.SetProperty("SYSTEM.group.type", group.type);
group.key = group_pattern_album;
window.SetProperty("SYSTEM.group Key", group.key);
tf_group_key = fb.TitleFormat(group.key);
//
redraw_stub_images();
g_image_cache = new image_cache;
CollectGarbage();
plman.SortByFormat(plman.ActivePlaylist, "%album artist% | %date% | %album% | %discnumber% | %tracknumber% | %title%", false);
break;
case 201:
group.type = 1;
window.SetProperty("SYSTEM.group.type", group.type);
group.key = group_pattern_artist;
window.SetProperty("SYSTEM.group Key", group.key);
tf_group_key = fb.TitleFormat(group.key);
//
redraw_stub_images();
g_image_cache = new image_cache;
CollectGarbage();
plman.SortByFormat(plman.ActivePlaylist, "%artist% | %date% | %album% | %discnumber% | %tracknumber% | %title%", false);
break;
case 202:
group.type = 2;
window.SetProperty("SYSTEM.group.type", group.type);
group.key = group_pattern_path;
window.SetProperty("SYSTEM.group Key", group.key);
tf_group_key = fb.TitleFormat(group.key);
//
redraw_stub_images();
g_image_cache = new image_cache;
CollectGarbage();
plman.SortByFormat(plman.ActivePlaylist, "%path%", false);
break;
default:
};
_sort.Dispose();
_groupby.Dispose();
_menu.Dispose();
g_menu_displayed = false;
// collapse toolbar
if(!toolbar.lock) {
if(toolbar.delta==0) {
toolbar.timerID_on && window.ClearTimeout(toolbar.timerID_on);
toolbar.timerID_on = false;
};
if(toolbar.state) {
if(!toolbar.timerID_off) {
if(toolbar.delta == toolbar.collapsed_y*-1) {
toolbar.timerID_off = window.SetTimeout(function() {
if(!toolbar.timerID2) {
toolbar.timerID2 = window.SetInterval(function() {
toolbar.delta -= toolbar.step;
if(toolbar.delta <= 0) {
toolbar.delta = 0;
toolbar.state = false;
window.ClearInterval(toolbar.timerID2);
toolbar.timerID2 = false;
};
window.RepaintRect(0, 0, ww, 30);
}, 30);
} ;
toolbar.timerID_off && window.ClearTimeout(toolbar.timerID_off);
toolbar.timerID_off = false;
}, 400);
};
};
};
};
return true;
};
function settings_menu(x, y) {
var idx;
var _menu = window.CreatePopupMenu();
var _columns = window.CreatePopupMenu();
var _appearance = window.CreatePopupMenu();
_menu.AppendMenuItem(MF_STRING, 1, "Lock Toolbar");
_menu.CheckMenuItem(1, toolbar.lock?1:0);
_menu.AppendMenuSeparator();
_appearance.AppendTo(_menu, MF_STRING, "Appearance");
_appearance.AppendMenuItem(MF_STRING, 100, "Use Themed Style");
_appearance.CheckMenuItem(100, panel.themed?1:0);
_appearance.AppendMenuItem(MF_STRING, 110, "Use Custom Colors");
_appearance.CheckMenuItem(110, panel.custom_colors?1:0);
_appearance.AppendMenuItem(MF_STRING, 120, "No Group Header");
_appearance.CheckMenuItem(120, panel.nogroupheader?1:0);
_appearance.AppendMenuItem(MF_STRING, 130, "Light Shadow Border (sunken effect)");
_appearance.CheckMenuItem(130, panel.show_shadow_border?1:0);
_appearance.AppendMenuItem(MF_STRING, 140, "Show Scrollbar");
_appearance.CheckMenuItem(140, vscrollbar.show?1:0);
_columns.AppendTo(_menu, MF_STRING, "Columns");
_columns.AppendMenuItem(MF_STRING, 200, "Play Icon");
_columns.CheckMenuItem(200, columns.playicon?1:0);
_columns.AppendMenuItem(MF_STRING, 210, "Track Number");
_columns.CheckMenuItem(210, columns.tracknumber?1:0);
_columns.AppendMenuSeparator();
_columns.AppendMenuItem(MF_STRING, 330, "Title");
_columns.AppendMenuItem(MF_STRING, 331, "Title (Smart)");
_columns.AppendMenuItem(MF_STRING, 332, "Title / Artist");
_columns.CheckMenuRadioItem(330, 332, columns.title+330);
_columns.AppendMenuSeparator();
_columns.AppendMenuItem(MF_STRING, 300, "Playcount");
_columns.CheckMenuItem(300, columns.playcount?1:0);
_columns.AppendMenuItem(MF_STRING, 310, "Rating");
_columns.CheckMenuItem(310, columns.rating?1:0);
_columns.AppendMenuItem(MF_STRING, 320, "Love Track");
_columns.CheckMenuItem(320, columns.mood?1:0);
_columns.AppendMenuItem(MF_STRING, 340, "Bitrate");
_columns.CheckMenuItem(340, columns.bitrate?1:0);
_menu.AppendMenuSeparator();
_menu.AppendMenuItem(fb.IsPlaying?MF_STRING:MF_GRAYED|MF_DISABLED, 6, "Show Now Playing");
_menu.AppendMenuItem(plman.IsPlaybackQueueActive()?MF_STRING:MF_GRAYED|MF_DISABLED, 7, "Show Queue Playlist");
_menu.AppendMenuItem((cover.show && list.total>0 && group.nbrows>1)?MF_STRING:MF_DISABLED|MF_GRAYED, 8, "Refresh Covers");
_menu.AppendMenuSeparator();
if(!stats.foo_playcount) {
_menu.AppendMenuItem(MF_STRING, 10, "Enable Playback Statistics");
_menu.CheckMenuItem(10, stats.enabled?1:0);
_menu.AppendMenuSeparator();
};
_menu.AppendMenuItem(MF_STRING, 20, "Properties");
_menu.AppendMenuItem(MF_STRING, 21, "Configure...");
idx = _menu.TrackPopupMenu(x, y);
switch(idx) {
case 1:
toolbar.lock = !toolbar.lock;
window.SetProperty("SYSTEM.toolbar.lock", toolbar.lock);
break;
case 6:
if(plman.ActivePlaylist != plman.PlayingPlaylist) {
if(list.handlelist) list.handlelist.Dispose();
list.handlelist = plman.GetPlaylistItems(fb.PlayingPlaylist);
list.total = list.handlelist.Count;
plman.ActivePlaylist = plman.PlayingPlaylist;
} else {
ShowNowPlaying();
window.Repaint();
};
break;
case 7:
ShowPlaylistQueue(0);
break;
case 8:
redraw_stub_images();
g_image_cache = new image_cache;
CollectGarbage();
refresh_playlist_content();
break;
case 10:
stats.enabled = !stats.enabled;
window.SetProperty("SYSTEM.statistics.enabled", stats.enabled);
break;
case 20:
window.ShowProperties();
break;
case 21:
window.ShowConfigure();
break;
case 100:
panel.themed = !panel.themed;
window.SetProperty("SYSTEM.panel.themed", panel.themed);
if(panel.themed) {
panel.theme = window.CreateThemeManager("scrollbar");
} else {
panel.theme = false;
};
recalc_datas();
init_icons();
set_scroller();
window.Repaint();
break;
case 110:
panel.custom_colors = !panel.custom_colors;
window.SetProperty("SYSTEM.panel.custom.colors", panel.custom_colors);
on_colors_changed();
break;
case 120:
panel.nogroupheader = !panel.nogroupheader;
window.SetProperty("SYSTEM.no.group.header", panel.nogroupheader);
recalc_datas();
redraw_stub_images();
refresh_playlist_content();
break;
case 130:
panel.show_shadow_border = !panel.show_shadow_border;
window.SetProperty("SYSTEM.shadow.border.enabled", panel.show_shadow_border);
window.Repaint();
break;
case 140:
vscrollbar.show = !vscrollbar.show;
window.SetProperty("SYSTEM.vscrollbar.visible", vscrollbar.show);
if(list.item.length>list.nbvis) {
if(vscrollbar.show) {
vscrollbar.visible = true;
} else {
vscrollbar.visible = false;
};
} else {
vscrollbar.visible = false;
};
refresh_playlist_content();
break;
case 200:
columns.playicon = !columns.playicon;
window.SetProperty("SYSTEM.columns.playicon.enabled", columns.playicon);
refresh_spv(plman.ActivePlaylist, true);
break;
case 210:
columns.tracknumber = !columns.tracknumber;
window.SetProperty("SYSTEM.columns.tracknumber.enabled", columns.tracknumber);
refresh_spv(plman.ActivePlaylist, true);
break;
case 300:
columns.playcount = !columns.playcount;
window.SetProperty("SYSTEM.columns.playcount.enabled", columns.playcount);
refresh_spv(plman.ActivePlaylist, true);
break;
case 310:
columns.duration_w = 0;
columns.bitrate_w = 0;
columns.rating = !columns.rating;
window.SetProperty("SYSTEM.columns.rating.enabled", columns.rating);
refresh_spv(plman.ActivePlaylist, true);
break;
case 320:
columns.duration_w = 0;
columns.bitrate_w = 0;
columns.mood = !columns.mood;
window.SetProperty("SYSTEM.columns.mood.enabled", columns.mood);
refresh_spv(plman.ActivePlaylist, true);
break;
case 340:
columns.duration_w = 0;
columns.bitrate_w = 0;
columns.bitrate = !columns.bitrate;
window.SetProperty("SYSTEM.columns.bitrate.enabled", columns.bitrate);
refresh_spv(plman.ActivePlaylist, true);
break;
case 330:
case 331:
case 332:
columns.title = idx - 330;
window.SetProperty("SYSTEM.columns.title.pattern", columns.title);
window.Repaint();
break;
default:
};
_appearance.Dispose();
_columns.Dispose();
_menu.Dispose();
g_menu_displayed = false;
// collapse toolbar
if(!toolbar.lock) {
if(toolbar.delta==0) {
toolbar.timerID_on && window.ClearTimeout(toolbar.timerID_on);
toolbar.timerID_on = false;
};
if(toolbar.state) {
if(!toolbar.timerID_off) {
if(toolbar.delta == toolbar.collapsed_y*-1) {
toolbar.timerID_off = window.SetTimeout(function() {
if(!toolbar.timerID2) {
toolbar.timerID2 = window.SetInterval(function() {
toolbar.delta -= toolbar.step;
if(toolbar.delta <= 0) {
toolbar.delta = 0;
toolbar.state = false;
window.ClearInterval(toolbar.timerID2);
toolbar.timerID2 = false;
};
window.RepaintRect(0, 0, ww, 30);
}, 30);
} ;
toolbar.timerID_off && window.ClearTimeout(toolbar.timerID_off);
toolbar.timerID_off = false;
}, 400);
};
};
};
};
return true;
};
//=================================================// Drag'n'Drop Callbacks
var wsh_dragging = false;
function on_drag_enter() {
wsh_dragging = true;
};
function on_drag_leave() {
wsh_dragging = false;
};
function on_drag_over(action, x, y, mask) {
on_mouse_move(x, y);
};
function on_drag_drop(action, x, y, mask) {
wsh_dragging = false;
// We are going to process the dropped items to a playlist
action.ToPlaylist();
action.Playlist = plman.ActivePlaylist;
action.ToSelect = false;
};
//=================================================// Queue Playlist features
function on_playback_queue_changed(origin) {
if(isQueuePlaylistActive()) {
ShowPlaylistQueue(0);
} else {
SetPlaylistQueue();
};
};
function isQueuePlaylistActive() {
var queue_pl_idx = isQueuePlaylistPresent();
if(queue_pl_idx<0) {
return false;
} else if(plman.ActivePlaylist == queue_pl_idx) {
return true;
};
};
function isQueuePlaylistPresent() {
for(var i=0; i<plman.PlaylistCount; i++) {
if(plman.GetPlaylistName(i)=="Queue Content") return i;
};
return -1;
};
function SetPlaylistQueue() {
var total_pl = plman.PlaylistCount;
var queue_pl_idx = isQueuePlaylistPresent();
if(queue_pl_idx<0) {
return true;
} else {
var total_in_pls = plman.PlaylistItemCount(queue_pl_idx);
if(total_in_pls > 0) {
var affected_items = Array();
for(var i=0; i<total_in_pls; i++) {
affected_items.push(i);
};
plman.SetPlaylistSelection(queue_pl_idx, affected_items, true);
plman.RemovePlaylistSelection(queue_pl_idx);
};
};
var queue_total = plman.GetPlaybackQueueCount();
var vbarr = plman.GetPlaybackQueueContents();
var arr = vbarr.toArray();
var q_handlelist = plman.GetPlaylistSelectedItems(queue_pl_idx);
q_handlelist.RemoveAll();
for(var j=0; j<queue_total; j++) {
q_handlelist.Add(arr[j].Handle);
};
plman.InsertPlaylistItems(queue_pl_idx, j, q_handlelist, false);
};
function ShowPlaylistQueue(focus_id) {
var total_pl = plman.PlaylistCount;
var queue_pl_idx = isQueuePlaylistPresent();
if(queue_pl_idx<0) {
plman.CreatePlaylist(total_pl, "Queue Content");
queue_pl_idx = total_pl;
plman.ActivePlaylist = queue_pl_idx;
} else {
plman.ActivePlaylist = queue_pl_idx;
fb.ClearPlaylist();
};
var queue_total = plman.GetPlaybackQueueCount();
var vbarr = plman.GetPlaybackQueueContents();
var arr = vbarr.toArray();
var q_handlelist = plman.GetPlaylistSelectedItems(queue_pl_idx);
q_handlelist.RemoveAll();
for(var i=0; i<queue_total; i++) {
q_handlelist.Add(arr[i].Handle);
};
plman.InsertPlaylistItems(queue_pl_idx, i, q_handlelist, false);
plman.SetPlaylistFocusItem(queue_pl_idx, focus_id);
};