// ==PREPROCESSOR== // @name "WSH Playlist Viewer" // @version "2.1.0" // @author "Br3tt aka Falstaff >> http://br3tt.deviantart.com___moded by Terro" // @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 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('A','A','A','A','A','A','?','C','E','E','E','E', 'I','I','I','I', '?','N','O','O','O','O','O','O','U','U','U','U','Y', '?','?'); 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); }; */ String.prototype.repeat = function(num) { if(num>=0 && num<=5) { var g = Math.round(num); } else { return ""; }; return new Array(g+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)|%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%%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=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.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.samplerate = tf_samplerate.EvalWithMetadb(this.metadb); this.bitrate2 = tf_bitrate2.EvalWithMetadb(this.metadb); this.bitspersample = tf_bitspersample.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.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.date = tf_date.EvalWithMetadb(this.metadb); this.codec = tf_codec.EvalWithMetadb(this.metadb); this.samplerate = tf_samplerate.EvalWithMetadb(this.metadb); this.bitrate2 = tf_bitrate2.EvalWithMetadb(this.metadb); this.bitspersample = tf_bitspersample.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, ppt.g_textcolor_sel_item&0x20ffffff);//g_textcolor gr.FillGradRect(this.x+2, this.y, this.w-vscrollbar.w-4, this.h-1, 90, 0, ppt.g_textcolor_sel_item&RGBA(255,255,255,ppt.item_select_alpha), 1.0); // RGBA(255,255,255,ppt.progress_bar_alpha) 0x15ffffff g_textcolor 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, ppt.g_textcolor_sel_item&0x20ffffff); //g_textcolor&0x20ffffff); gr.FillGradRect(this.x+2, this.y, this.w-vscrollbar.w-4, this.h-1, 90, 0, ppt.g_textcolor_sel_item&RGBA(255,255,255,ppt.item_select_alpha), 1.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, mini_font)+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, ppt.progress_bar_color_custom == true ? (ppt.progress_bar_color&RGBA(255,255,255,ppt.progress_bar_alpha)) : (g_textcolor_sel&RGBA(255,255,255,ppt.progress_bar_alpha)) , 0, 0.5); //0x80ffffff g_textcolor_sel }; // calc dynamic other tf values --- playicon 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+6, 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+6, 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, ppt.tr_number_grad_color_1&RGBA(255,255,255,ppt.tr_number_grad_color_1_alpha), ppt.tr_number_grad_color_2&RGBA(255,255,255,ppt.tr_number_grad_color_2_alpha), 1.0); //g_backcolor&0x15ffffff, g_textcolor&0x15ffffff gr.DrawRect(columns.tracknumber_x+3, this.y+3, columns.tracknumber_w-8, this.h-7, 1.0, ppt.tr_number_rect_color&RGBA(255,255,255,ppt.tr_number_rect_color_alpha)); //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, (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); gr.GdiDrawText(new_tracknumber, g_font, (queue_index>=0 || isQueuePlaylistActive())?RGB(100,180,100):(isplaying?ppt.tr_number_text_color_1:ppt.tr_number_text_color_2), 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("tahoma", 11), (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); if(tf_title_w > columns.title_w) { tf_title_w = columns.title_w; this.tooltip = false; }; gr.GdiDrawText(this.title, g_font, 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); } catch(e) { tf_title_w = gr.CalcTextWidth(this.title, gdi.Font("tahoma", 11)); if(tf_title_w > columns.title_w) { tf_title_w = columns.title_w; this.tooltip = false; }; gr.GdiDrawText(this.title, gdi.Font("tahoma", 11), 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); if(tf_artist_w > artist_w) { tf_artist_w = artist_w; this.tooltip = false; }; if(tf_title_w < columns.title_w) { gr.GdiDrawText(" "+panel.tag_separator+" "+this.artist, g_font, 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("tahoma", 11)); if(tf_artist_w > artist_w) { tf_artist_w = artist_w; this.tooltip = false; }; if(tf_title_w < columns.title_w) { gr.GdiDrawText(" "+panel.tag_separator+" "+this.artist, gdi.Font("tahoma", 11), 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, mini_font, ppt.extra_group_infos_color&RGBA(255,255,255,ppt.extra_group_infos_color_alpha), playcount_x, this.y-4, playcount_w, this.h-row.parity, rc_stringformat); } catch(e) { gr.DrawString(this.playcount, gdi.Font("tahoma", 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, 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("tahoma", 11), 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&0x50ffffff); } 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, 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("tahoma", 11), 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(!ppt.touch_on && 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.id0) { // --------------------- // ::: 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); //g_backcolor&0xddffffff gr.DrawString(this.date, gh_date_font, ppt.date_color&RGBA(255,255,255,ppt.date_color_alpha), year_x, grp_y-8, year_w, group.nbrows*row.h-1, lc_stringformat); //g_textcolor&0x55ffffff }; // 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_headers, 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_headers, 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("tahoma",11), 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("tahoma",11), 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, 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("tahoma",11), 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, 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("tahoma",11), 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, 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("tahoma",11), 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?" TRKS":" TRK")+" | "+this.codec+" | "+this.genre.toUpperCase(), mini_font, ppt.extra_group_infos_color&RGBA(255,255,255,ppt.extra_group_infos_color_alpha), 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?" TRKS":" TRK")+" | "+this.codec+" | "+this.genre.toUpperCase(), gdi.Font("tahoma",11), g_textcolor&0x44ffffff, text_x+1, (this.y-cover.margin)+2, text_w-1, row.h, lb_stringformat); }; } else if(group.nbrows>2) { try { gr.DrawString(total_grp_items+(total_grp_items>1?" TRKS":" TRK")+" | "+this.codec+" | "+this.genre.toUpperCase(), mini_font, ppt.extra_group_infos_color&RGBA(255,255,255,ppt.extra_group_infos_color_alpha), 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?" TRKS":" TRK")+" | "+this.codec+" | "+this.genre.toUpperCase(), gdi.Font("tahoma",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(!ppt.touch_on && 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(ytoolbar.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=columns.mood_x && x<=columns.mood_x+columns.mood_w-3 && y>this.y+2 && y0) { 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) ? "" : this.l_rating), this.metadb); this.rating = this.l_rating; }; } else { var bool = fb.RunContextCommandWithMetadb("Rating/", 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_playcount = fb.TitleFormat("$if2(%play_counter%,$if2(%play_count%,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_samplerate = fb.Titleformat("%__samplerate%"); var tf_bitrate2 = fb.Titleformat("%__bitrate%"); var tf_bitspersample = fb.Titleformat("%__bitspersample%"); var tf_bitrate = fb.TitleFormat("$if(%__bitrate_dynamic%,$if(%el_isplaying%,%__bitrate_dynamic%'K',$if($stricmp($left(%codec_profile%,3),'VBR'),%codec_profile%,%__bitrate%'K')),$if($stricmp($left(%codec_profile%,3),'VBR'),%codec_profile%,%__bitrate%'K'))"); 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%)'K'"); 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(ppt.font_date_name, ppt.font_date_size, ppt.font_date_style); 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(ppt.font_mini_name, ppt.font_mini_size, 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("lucida console", ppt.incsearch_font_size, 0); var incsearch_font_big = gdi.Font("lucida console", ppt.incsearch_font_size, 1); var clear_incsearch_timer = false; var incsearch_timer = false; var g_playing_item_y = null; var g_seconds = 0; var progress = 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", false), //wallpaper_path: window.GetProperty("*USER.background.image.path", ".\\images\\background.jpg"), wallpaper_img: false, //show_wallpaper: window.GetProperty("*USER.background.image.enabled", true), show_shadow_border: window.GetProperty("SYSTEM.shadow.border.enabled", true), opacity: window.GetProperty("*USER.panel.opacity.level [0,255]", 50), 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", true), 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", false), 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", false), rating_x: 0, rating_w: 0, rating_timerID: false, rating_drag: false, mood: window.GetProperty("SYSTEM.columns.mood.enabled", false), 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", false) }; 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", 1), 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", true) }; row = { h: window.GetProperty("SYSTEM.row.height", 35), 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: window.GetProperty("SYSTEM.toolbar.size", -30),//-24, delta: 0, step: 3, state: false }; vscrollbar = { theme: false, show: window.GetProperty("SYSTEM.vscrollbar.visible", false), 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= 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;i0) { var vis_min_idx = list.item[list.tocut].id; var delta2max = (list.tocut+list.nbvis) - 1; if(delta2max=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;glist.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.h0) { 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 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); // set wallpaper if(fb.IsPlaying) { g_wallpaperImg = setWallpaperImg(ppt.wallpaperpath, fb.GetNowPlaying()); }; else { //g_wallpaperImg = null; g_wallpaperImg = setWallpaperImg(ppt.wallpaperpath, fb.GetNowPlaying()); }; 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 //================================== !window.IsTransparent && !ppt.showwallpaper && gr.FillSolidRect(0, 0, ww, wh, ppt.background_color); if(fb.IsPlaying && g_wallpaperImg && ppt.showwallpaper) { gr.GdiDrawBitmap(g_wallpaperImg, 0, 0, ww, wh, 0, 0, g_wallpaperImg.Width, g_wallpaperImg.Height); gr.FillSolidRect(0, 0, ww, wh, g_color_normal_bg & RGBA(255,255,255,ppt.wallpaperalpha)); }; else { if(g_wallpaperImg && ppt.showwallpaper) { gr.GdiDrawBitmap(g_wallpaperImg, 0, 0, ww, wh, 0, 0, g_wallpaperImg.Width, g_wallpaperImg.Height); gr.FillSolidRect(0, 0, ww, wh, g_color_normal_bg & RGBA(255,255,255,ppt.wallpaperalpha)); }; else { gr.FillSolidRect(0, 0, ww, wh, g_color_normal_bg); }; }; //================================== if(panel.opacity>=255) { gr.FillSolidRect(0, 0, ww, wh, g_backcolor); } else if(panel.opacity<=1) {}; 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;idx0) { 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, ppt.toolbar_color&RGBA(255,255,255,ppt.toolbar_color_alpha)); 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, ppt.toolbar_rect_color&RGBA(255,255,255,ppt.toolbar_rect_color_alpha)); //rect color RGBA(250,250,250,40) gr.SetSmoothingMode(0); // draw toolbar buttons for(i=0;i