Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==PREPROCESSOR==
- // @name "WSH Simple Playlist Viewer"
- // @version "0.7.0"
- // @author "Br3tt"
- // @feature "v1.4"
- // @feature "watch-metadb"
- // @feature "dragdrop"
- // ==/PREPROCESSOR==
- // [Requirements]
- // * foobar2000 v1.1 or better ( >> http://foobar2000.org)
- // * WSH panel Mod v1.5.0 or better ( >> http://http://code.google.com/p/foo-wsh-panel-mod/downloads/list)
- // * Fonts :
- // - guifx v2 transports ( >> http://http://blog.guifx.com/2009/04/02/guifx-v2-transport-font)
- // - lucida console (bundled with Windows)
- // - tahoma (bundled with Windows)
- // [/Requirements]
- // [Informations]
- // * change colors and fonts in foobar2000 Preferences > DefaultUI or ColumsUI
- // * Some Settings can be changed in window Properties (right click columns header > Properties)
- // * double click on columns header > Show Now Playing item
- // * use keyboard to search artist in the playlist (incremental search feature, search string displayd on bottom-left)
- // * to sort hte playlist, use menu Edit>Sort
- // [/Informations]
- //=================================================// General declarations
- // 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 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);
- };
- var 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 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 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();
- };
- 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;
- };
- //}}
- //=================================================// Image declarations
- var playicon_off;
- var playicon_light;
- var playicon_shadow;
- var nocover;
- var streamcover;
- var star_img_off;
- var star_img_on;
- var star_img_hov;
- var star_img_kill;
- //=================================================// Cover object
- cover2load = function () {
- this.create = function (item, timer_value) {
- this.item = item;
- this.timer = window.SetInterval(function() {
- window.ClearInterval(mycover2load[0].timer);
- var cx = mycover2load[0].item.x + cover.margin;
- var cy = mycover2load[0].item.y - ((cover.nbrows-1)*row.h);
- mycover2load[0].item.cover_img = g_image_cache.getit(mycover2load[0].item);
- mycover2load.shift();
- window.RepaintRect(cx-2, cy-2, cover.w+4, cover.h+4);
- }, timer_value);
- };
- };
- var mycover2load = Array();
- //=================================================// Cover Tools
- image_cache = function () {
- this._cachelist = {};
- this.hit = function (item) {
- var img = this._cachelist[item.metadb.path];
- if (typeof img == "undefined") {
- mycover2load.push(new cover2load);
- mycover2load[mycover2load.length-1].create(item, (250-mycover2load.length*5)*mycover2load.length);
- };
- return img;
- };
- this.getit = function (item) {
- var img = refresh_cover(item);
- 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;
- return image.Resize(w, h, 7);
- };
- function refresh_cover(item) {
- var type = 0;
- var cover_img;
- 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) {
- cover_img = FormatCover(utils.GetAlbumArtEmbedded(item.metadb.rawpath, type), pw, ph);
- if(!cover_img) {
- cover_img = FormatCover(utils.GetAlbumArtV2(item.metadb, type), pw, ph);
- if(!cover_img) {
- cover_img = FormatCover(nocover, pw, ph);
- item.cover_type = 0;
- }; else {
- item.cover_type = 1;
- };
- }; else {
- item.cover_type = 2;
- };
- };
- }; else if (fb.IsPlaying && fb.PlaybackLength) {
- cover_img = FormatCover(streamcover, pw, ph);
- item.cover_type = 3;
- }; else {
- cover_img = FormatCover(nocover, pw, ph);
- item.cover_type = 0;
- };
- return cover_img;
- };
- function reset_cover_timers() {
- for(var i in mycover2load) {
- mycover2load[i].timer && window.ClearInterval(mycover2load[i].timer);
- };
- mycover2load.splice(0, mycover2load.length);
- };
- //=================================================// 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.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;
- };
- };
- //=================================================// Titleformat field
- var tf_path = fb.TitleFormat("$left(%_path_raw%,4)");
- var tf_cover_path = fb.TitleFormat("$replace(%path%,%filename_ext%,)");
- var tf_tracknumber = fb.TitleFormat("%tracknumber%");
- 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%,'Single','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_playcount = fb.TitleFormat("$if2(%play_counter%,$if2(%play_count%,0))");
- var tf_length = fb.TitleFormat("$if2(%length%,' 0:00')");
- var tf_date = fb.TitleFormat("$if2($year(%date%),)");
- var tf_playback_time = fb.TitleFormat("%playback_time%");
- var tf_playback_time_remaining = fb.TitleFormat("$if(%length%,-%playback_time_remaining%,'0:00')");
- //=================================================// Globals
- wsh = {
- transparency: window.GetProperty("wsh.transparency.enabled", false),
- first_on_size: true,
- context_menu_called: false,
- action_shownowplaying: false,
- drag_drop_enabled: window.GetProperty("wsh.drag_drop.enabled", false),
- drag: false,
- is_hover: false,
- mousewheel_timerID: false,
- repaint_rating_timer_ID: false
- };
- cover = {
- visible: true,
- margin: 6,
- w: window.GetProperty("list.cover.size", 75),
- nbrows: 0,
- h: 0,
- top_offset: 0,
- show_total_tracks : window.GetProperty("cover.show_total_tracks.enabled", true)
- };
- column = {
- visible: false,
- h: 20,
- label: Array("Cover", "Track", "Artist / Title", "Rating", "Time"),
- w: Array(0, 52, 0, 74, 50),
- total: 5
- };
- list = {
- total: 0,
- nbvis: 0,
- stock: 0,
- offset: 0,
- tocut: 0,
- item: Array(),
- handlelist: null,
- metadblist_selection: plman.GetPlaylistSelectedItems(fb.ActivePlaylist),
- singleton_select_id: 0,
- nowplaying: plman.GetPlayingItemLocation(),
- nowplaying_y: 0
- };
- row = {
- h: window.GetProperty("list.row.height", 26),
- w: 0
- };
- toolbar = {
- visible: window.GetProperty("list.toolbar.visible", true),
- default_h: window.GetProperty("list.toolbar.height", 20),
- h: 20,
- arr_buttons: Array()
- };
- vscrollbar = {
- theme: false,
- themed: window.GetProperty("list.vscrollbar.themed", true),
- show: window.GetProperty("list.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("list.vscrollbar.step", 3),
- step: 3,
- arr_buttons: Array(),
- letter : null,
- timerID: false
- };
- button_up = {
- img_normal: null,
- img_hover: null,
- img_down: null,
- x: 0,
- y: 0,
- w: vscrollbar.default_w,
- h: vscrollbar.default_w,
- timerID: false
- };
- button_down = {
- img_normal: null,
- img_hover: null,
- img_down: null,
- x: 0,
- y: 0,
- w: vscrollbar.default_w,
- h: vscrollbar.default_w,
- timerID: false
- };
- 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
- };
- ItemStates = {
- normal: 0,
- hover: 1,
- selected: 2
- };
- //=================================================// Item object
- function repaint_rating(item) {
- if(!wsh.repaint_rating_timer_ID) {
- wsh.repaint_rating_timer_ID = window.SetTimeout(function() {
- window.RepaintRect(item.rating_x, item.rating_y, rating_w, rating_h);
- wsh.repaint_rating_timer_ID = false;
- },40);
- };
- };
- item = function () {
- var i;
- this.create = function(id, metadb, idx, gridx) {
- if (typeof this.id == "undefined") {
- this.idx = idx;
- this.id = id;
- this.gridx = gridx;
- this.state = ItemStates.normal;
- this.metadb = metadb;
- if(metadb) {
- this.track_type = TrackType(this.metadb.rawpath.substring(0,4));
- this.tracknumber = tf_tracknumber.EvalWithMetadb(this.metadb);
- this.artist = tf_artist.EvalWithMetadb(this.metadb);
- this.title = tf_title.EvalWithMetadb(this.metadb);
- this.albumartist = tf_albumartist.EvalWithMetadb(this.metadb);
- this.album = tf_album.EvalWithMetadb(this.metadb);
- this.disc = tf_disc.EvalWithMetadb(this.metadb);
- this.rating = tf_rating.EvalWithMetadb(this.metadb);
- this.playcount = tf_playcount.EvalWithMetadb(this.metadb);
- this.length = tf_length.EvalWithMetadb(this.metadb);
- this.date = tf_date.EvalWithMetadb(this.metadb);
- this.group_key = this.albumartist+this.album+this.disc;
- };
- this.x = 0;
- this.y = toolbar.h + (idx-list.tocut) * row.h;
- this.w = ww - (vscrollbar.visible && vscrollbar.show?vscrollbar.w:0);
- this.h = row.h;
- this.tooltip = false;
- };
- };
- this.template_it = function(id, metadb) {
- if (typeof this.id == "undefined") {
- this.id = id;
- this.metadb = metadb;
- if(metadb) {
- this.albumartist = tf_albumartist.EvalWithMetadb(this.metadb);
- this.album = tf_album.EvalWithMetadb(this.metadb);
- this.disc = tf_disc.EvalWithMetadb(this.metadb);
- this.group_key = this.albumartist+this.album+this.disc;
- };
- };
- };
- this.draw = function(gr, id) {
- var parity = (Math.round(id/2)==(id/2));
- if(this.metadb.Compare(fb.GetFocusItem())) {
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, plman.GetPlaylistFocusItemIndex(fb.ActivePlaylist), true);
- if(this.state!=ItemStates.selected) {
- this.state = ItemStates.selected;
- list.singleton_select_id = this.id;
- };
- };
- this.state = plman.IsPlaylistItemSelected(fb.ActivePlaylist, this.id) ? ItemStates.selected : ItemStates.normal;
- switch(this.state) {
- case ItemStates.normal:
- var text_colour = g_textcolor;
- var tracknumber_backcolor = g_textcolor;
- var tracknumber_textcolor = g_backcolor;
- break;
- case ItemStates.hover:
- var text_colour = g_textcolor;
- var tracknumber_backcolor = g_textcolor;
- var tracknumber_textcolor = g_backcolor;
- break;
- case ItemStates.selected:
- var text_colour = g_textcolor_sel;
- var tracknumber_backcolor = g_textcolor_sel;
- var tracknumber_textcolor = g_backcolor;
- break;
- };
- // Item background
- var bg_colour = parity?RGBA(255,255,255,6):RGBA(0,0,0,6);
- if(this.state==ItemStates.selected) {
- gr.FillSolidRect(this.x+column.w[0], this.y+1, this.w-column.w[0]-1, this.h-1, g_backcolor_sel&0x44ffffff);
- }; else {
- gr.FillSolidRect(this.x+column.w[0], this.y, this.w-column.w[0]-1, this.h, bg_colour);
- gr.FillGradRect(this.x+column.w[0], this.y, this.w-column.w[0]-1, 1, 0, 0, g_backcolor&0x20000000, 0.5);
- gr.FillGradRect(this.x+column.w[0], this.y+1, this.w-column.w[0]-1, 1, 0, 0, RGBA(255,255,255,35), 0.5);
- };
- gr.FillSolidRect(column.w[0]-0, this.y, 1, row.h, RGBA(0,0,0,100));
- gr.FillSolidRect(column.w[0]-1, this.y, 1, row.h, RGBA(255,255,255,25));
- gr.FillSolidRect(column.w[0]+1, this.y, 1, row.h, RGBA(0,0,0,60));
- gr.FillSolidRect(column.w[0]+2, this.y, 1, row.h, RGBA(0,0,0,30));
- gr.FillSolidRect(column.w[0]+3, this.y, 1, row.h, RGBA(0,0,0,10));
- // if last item, draw bottom shadow!
- if(this.id==list.total-1) {
- gr.FillGradRect(this.x+column.w[0], this.y+this.h, this.w-column.w[0], 4, 90, RGBA(0,0,0,70), 0, 1.0);
- gr.FillSolidRect(this.x+column.w[0], this.y+this.h, this.w-column.w[0], 1, RGBA(0,0,0,25));
- if(this.y+this.h<toolbar.h+wh) {
- gr.FillSolidRect(column.w[0]-0, this.y+this.h, 1, toolbar.h+wh-(this.y+this.h), RGBA(0,0,0,100));
- gr.FillSolidRect(column.w[0]-1, this.y+this.h, 1, toolbar.h+wh-(this.y+this.h), RGBA(255,255,255,25));
- gr.FillSolidRect(column.w[0]+1, this.y+this.h, 1, toolbar.h+wh-(this.y+this.h), RGBA(0,0,0,60));
- gr.FillSolidRect(column.w[0]+2, this.y+this.h, 1, toolbar.h+wh-(this.y+this.h), RGBA(0,0,0,30));
- gr.FillSolidRect(column.w[0]+3, this.y+this.h, 1, toolbar.h+wh-(this.y+this.h), RGBA(0,0,0,10));
- };
- };
- // Draw fields
- if(this.artist!=this.albumartist || this.grp_total < cover.nbrows) {
- var artist_title_field = " "+this.artist+" / "+this.title;
- }; else {
- var artist_title_field = " "+this.title;
- };
- var artist_title_width = gr.CalcTextWidth(artist_title_field, g_font);
- if(this.playcount!=0) {
- var measureStrTmp = gr.MeasureString("("+this.playcount+")", gdi.Font("tahoma", 8), 0, 0, 100, 7, 0);
- var playcount_width = measureStrTmp.Width;
- }; else {
- var playcount_width = 0;
- };
- if(this.tracknumber=="?") this.tracknumber = num(this.grp_idx+1,2);
- var tracknumber_width = gr.CalcTextWidth(this.tracknumber, g_font);
- // tracknumber
- gr.SetSmoothingMode(2);
- gr.FillRoundRect(this.x+column.w[0]+column.w[1]-(tracknumber_width+8)-4, this.y+5, (tracknumber_width+8), this.h-11, 1, 1, tracknumber_backcolor&0x66ffffff);
- gr.DrawRoundRect(this.x+column.w[0]+column.w[1]-(tracknumber_width+8)-4, this.y+5, (tracknumber_width+8), this.h-11, 1, 1, 1.0, tracknumber_backcolor&0x72ffffff);
- gr.SetSmoothingMode(0);
- gr.GdiDrawText(this.tracknumber, g_font, tracknumber_textcolor, this.x+column.w[0]+column.w[1]-(tracknumber_width+8)-4, this.y, (tracknumber_width+5), this.h, DT_RIGHT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
- // artist + title + playcount
- if(artist_title_width+playcount_width+2>column.w[2]) this.tooltip = true;
- gr.GdiDrawText(artist_title_field, g_font, text_colour, this.x+column.w[0]+column.w[1], this.y+1, (this.tooltip?column.w[2]-playcount_width-2:artist_title_width+2), this.h, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
- if(this.playcount!=0) {
- gr.SetTextRenderingHint(5);
- gr.DrawString("("+this.playcount+")", gdi.Font("tahoma", 8), text_colour&0x77ffffff, this.x+column.w[0]+column.w[1]+(this.tooltip?column.w[2]-playcount_width-2:artist_title_width+2), this.y-1, playcount_width, this.h, lc_stringformat);
- };
- // Draw Cover Art & Group Breaks
- if(this.grp_idx==0) {
- if(cover.visible && this.idx!=list.tocut && this.grp_total>=cover.nbrows) {
- gr.FillGradRect(this.x+10, this.y, column.w[0]-20, 1, 0, 0, RGBA(0,0,0,100), 0.5);
- gr.FillGradRect(this.x+5, this.y-1, column.w[0]-10, 1, 0, 0, RGBA(255,255,255,50), 0.5);
- };
- gr.FillGradRect(this.x+column.w[0], this.y, this.w-column.w[0], 1, 0, RGBA(0,0,0,100), RGBA(0,0,0,50), 0.5);
- gr.FillGradRect(this.x+column.w[0], this.y-1, this.w-column.w[0], 1, 0, RGBA(255,255,255,40), RGBA(255,255,255,10), 0.5);
- gr.FillGradRect(this.x+column.w[0], this.y+1, this.w-column.w[0], 1, 0, RGBA(0,0,0,40), 0, 0.5);
- };
- if(cover.visible) {
- // affect cover y to the items containing the cover art (part of the cover)
- if(this.grp_idx<cover.nbrows) {
- list.item[this.idx].cover_top_y = this.y-(this.grp_idx*row.h)+cover.margin;
- };
- };
- if(cover.visible && this.grp_idx==cover.nbrows-1) {
- this.cover_img = g_image_cache.hit(this);
- if(this.cover_img) {
- // Draw Cover Art
- gr.FillSolidRect(this.x+cover.margin-1, this.y-((cover.nbrows-1)*row.h)+cover.margin-(cover.top_offset*row.h)-1, cover.w-cover.margin*2+2, cover.h-cover.margin*2+2, RGBA(0,0,0,30));
- gr.FillSolidRect(this.x+cover.margin+1, this.y-((cover.nbrows-1)*row.h)+cover.margin-(cover.top_offset*row.h)+1, cover.w-cover.margin*2, cover.h-cover.margin*2, RGBA(0,0,0,75));
- gr.FillSolidRect(this.x+cover.margin+1, this.y-((cover.nbrows-1)*row.h)+cover.margin-(cover.top_offset*row.h)+1, cover.w-cover.margin*2+1, cover.h-cover.margin*2+1, RGBA(0,0,0,30));
- gr.DrawImage(this.cover_img, this.x+cover.margin, this.y-((cover.nbrows-1)*row.h)+cover.margin-(cover.top_offset*row.h), cover.w, cover.h, 0, 0, cover.w, cover.h, 0, 255);
- if(cover.show_total_tracks) {
- gr.FillSolidRect(this.x+cover.margin, this.cover_top_y+cover.h-cover.margin*2-10, cover.w-cover.margin*2, 10, RGBA(0,0,0,125));
- gr.FillSolidRect(this.x+cover.margin, this.cover_top_y+cover.h-cover.margin*2-11, cover.w-cover.margin*2, 1, RGBA(0,0,0,200));
- };
- gr.DrawRect(this.x+cover.margin, this.y-((cover.nbrows-1)*row.h)+cover.margin-(cover.top_offset*row.h), cover.w-cover.margin*2-1, cover.h-cover.margin*2-1, 1.0, RGB(255,255,255));
- gr.DrawRect(this.x+cover.margin+1, this.y-((cover.nbrows-1)*row.h)+cover.margin-(cover.top_offset*row.h)+1, cover.w-cover.margin*2-3, cover.h-cover.margin*2-3, 1.0, RGBA(0,0,0,50));
- if(cover.show_total_tracks) {
- gr.SetTextRenderingHint(5);
- gr.DrawString(this.grp_total+" TRACKS", gdi.Font("lucida console", 9), RGB(0,0,0), this.x+cover.margin, this.cover_top_y+cover.h-cover.margin*2-13+2, cover.w-cover.margin*2, 12, cc_stringformat);
- gr.DrawString(this.grp_total+" TRACKS", gdi.Font("lucida console", 9), RGB(255,255,255), this.x+cover.margin, this.cover_top_y+cover.h-cover.margin*2-13+1, cover.w-cover.margin*2, 12, cc_stringformat);
- };
- };
- };
- // Play icon + Duration
- if(fb.PlayingPlaylist==fb.ActivePlaylist) {
- if(fb.IsPlaying) {
- list.nowplaying = plman.GetPlayingItemLocation();
- if(this.id==list.nowplaying.PlaylistItemIndex) {
- list.nowplaying_y = this.y+this.h/2-playicon_off.Height/2;
- gr.DrawImage(playicon_shadow, this.x+column.w[0]+2, list.nowplaying_y, playicon_off.Width, playicon_off.Height, 0, 0, playicon_off.Width, playicon_off.Height, 0, 20);
- gr.DrawImage(playicon_shadow, this.x+column.w[0]+1, list.nowplaying_y, playicon_off.Width, playicon_off.Height, 0, 0, playicon_off.Width, playicon_off.Height, 0, 40);
- gr.DrawImage(playicon_shadow, this.x+column.w[0], list.nowplaying_y, playicon_off.Width, playicon_off.Height, 0, 0, playicon_off.Width, playicon_off.Height, 0, 60);
- gr.DrawImage(playicon_light, this.x+column.w[0], list.nowplaying_y, playicon_off.Width, playicon_off.Height, 0, 0, playicon_off.Width, playicon_off.Height, 0, 255);
- gr.DrawImage(playicon_off, this.x+column.w[0]-2, list.nowplaying_y, playicon_off.Width, playicon_off.Height, 0, 0, playicon_off.Width, playicon_off.Height, 0, 255);
- if(this.length==" 0:00") {
- this.playback_time_remaining = tf_playback_time.Eval(true);
- }; else {
- this.playback_time_remaining = tf_playback_time_remaining.Eval(true);
- };
- gr.GdiDrawText(this.playback_time_remaining+" ", g_font, text_colour, this.x+column.w[0]+column.w[1]+column.w[2]+column.w[3], this.y+1, column.w[4], this.h, DT_RIGHT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
- }; else {
- gr.GdiDrawText(this.length+" ", g_font, text_colour, this.x+column.w[0]+column.w[1]+column.w[2]+column.w[3], this.y+1, column.w[4], this.h, DT_RIGHT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
- };
- }; else {
- gr.GdiDrawText(this.length+" ", g_font, text_colour, this.x+column.w[0]+column.w[1]+column.w[2]+column.w[3], this.y+1, column.w[4], this.h, DT_RIGHT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
- };
- }; else {
- gr.GdiDrawText(this.length+" ", g_font, text_colour, this.x+column.w[0]+column.w[1]+column.w[2]+column.w[3], this.y+1, column.w[4], this.h, DT_RIGHT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
- };
- // Rating engine
- this.rating_x = this.x+column.w[0]+column.w[1]+column.w[2]+5;
- this.rating_y = this.y + Math.round(row.h/2 - star_img_off.Height/2)+2;
- if(this.rating_hov) {
- for (i = 1; i < 6; i++){
- if(this.track_type<2){
- var img = (i > (this.rating_hov ? this.l_rating : this.rating)) ? star_img_off : (this.rating_hov ? (i==this.rating ? (i==this.l_rating ? star_img_kill : star_img_hov) : star_img_hov) : star_img_on);
- if(this.rating_hov && this.l_rating==this.rating) {
- img = i<=this.l_rating ? star_img_kill : star_img_off;
- };
- }; else {
- var img = star_img_off;
- };
- gr.DrawImage(img, this.rating_x+img.Width*(i-1), this.rating_y, img.Width, img.Height, 0, 0, img.Width, img.Height, 0, 255);
- };
- }; else {
- gr.SetTextRenderingHint(4);
- for(i=0;i<5;i++) {
- gr.DrawString("b", rating_font, (i+1<=this.rating)?text_colour&0xaaffffff:g_textcolor&0x20ffffff, this.rating_x+i*13, this.rating_y, 13, 18, lt_stringformat);
- };
- };
- };
- this.checkstate = function (event, x, y, id) {
- this.ishover = (x > this.x && x < this.x + this.w && y >= this.y && y < this.y + this.h);
- if(this.ishover) {
- this.cover_ishover = (this.grp_idx<cover.nbrows && x>cover.margin && x<column.w[0]-cover.margin && y>this.cover_top_y && y<this.cover_top_y+cover.h-cover.margin*2);
- }; else {
- this.cover_ishover = false;
- };
- var tmp = this.rating_hov;
- var tmp_l_rating = this.l_rating;
- this.rating_hov = (x > this.x+column.w[0]+column.w[1]+column.w[2] && x < this.x+column.w[0]+column.w[1]+column.w[2]+column.w[3] && y > this.rating_y+0 && y < this.rating_y + 16);
- switch (event) {
- case "down":
- if(x>column.w[0]) {
- switch(this.state) {
- case ItemStates.normal:
- case ItemStates.hover:
- if(this.ishover && !this.rating_hov) {
- if(utils.IsKeyPressed(VK_CONTROL)) { // if Ctrl key pressed, add item to selection
- plman.SetPlaylistFocusItem(fb.ActivePlaylist, this.id);
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, this.id, true);
- this.state = ItemStates.selected;
- list.singleton_select_id = this.id;
- }; else if(utils.IsKeyPressed(VK_SHIFT)) {
- if(list.singleton_select_id != this.id) {
- SelectAtoB(list.singleton_select_id, this.id);
- };
- }; else {
- plman.SetPlaylistFocusItem(fb.ActivePlaylist, this.id);
- plman.ClearPlaylistSelection(fb.ActivePlaylist);
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, this.id, true);
- this.state = ItemStates.selected;
- list.singleton_select_id = this.id;
- };
- };
- break;
- case ItemStates.selected:
- if(this.ishover && !this.rating_hov && list.metadblist_selection.Count>1) {
- if(utils.IsKeyPressed(VK_CONTROL)) { // if Ctrl key pressed, remove item from selection
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, this.id, false);
- this.state = ItemStates.hover;
- }; else if(utils.IsKeyPressed(VK_SHIFT)) {
- if(list.singleton_select_id != this.id) {
- SelectAtoB(list.singleton_select_id, this.id);
- };
- }; else {
- plman.SetPlaylistFocusItem(fb.ActivePlaylist, this.id);
- plman.ClearPlaylistSelection(fb.ActivePlaylist);
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, this.id, true);
- this.state = ItemStates.selected;
- list.singleton_select_id = this.id;
- };
- };
- break;
- };
- // set Drag item status to true (for my WSH drag'n drop feature)
- if (this.ishover && !this.rating_hov && list.metadblist_selection.Count>0) wsh.drag = true;
- }; else {
- // Cover Click done, select all items in the group
- if(this.grp_total>=cover.nbrows && this.cover_ishover) {
- SelectGroupItems(this.id - this.grp_idx, this.group_key);
- };
- };
- break;
- case "dblclk":
- switch(this.state) {
- case ItemStates.selected:
- if(this.ishover && !this.rating_hov) {
- fb.RunContextCommandWithMetadb("Play", this.metadb);
- };
- break;
- };
- break;
- case "right":
- if(x>column.w[0]) {
- if(this.ishover && !this.rating_hov) {
- switch(this.state) {
- case ItemStates.normal:
- case ItemStates.hover:
- plman.SetPlaylistFocusItem(fb.ActivePlaylist, this.id);
- plman.ClearPlaylistSelection(fb.ActivePlaylist);
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, this.id, true);
- this.state = ItemStates.selected;
- break;
- };
- new_context_menu(x, y, this.id, this.idx);
- };
- }; else {
- if(this.grp_total>=cover.nbrows && this.cover_ishover) {
- // Cover Click done, select all items in the group
- SelectGroupItems(this.id - this.grp_idx, this.group_key);
- new_context_menu(x, y, this.id, this.idx);
- };
- };
- break;
- case "up":
- // Send handles to extra WSH panel that can support playlist add items from this panel selection
- if(wsh.drag) {
- if(!wsh.is_hover && wsh.drag_drop_enabled) {
- window.NotifyOthers("WSH_playlist_drag_drop", list.metadblist_selection);
- };
- wsh.drag = false;
- window.SetCursor(IDC_ARROW);
- };
- // Rating
- if(this.track_type<2 && this.rating_hov) {
- 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;
- };
- };
- };
- break;
- case "move":
- if(y<=toolbar.h) {
- this.l_rating = 0;
- repaint_rating();
- }; else {
- if(!wsh.drag) {
- // Rating
- if(this.rating_hov) {
- this.l_rating = Math.floor((x - this.rating_x) / star_img_off.Width) + 1;
- }; else {
- this.l_rating = 0;
- };
- switch(this.state) {
- case ItemStates.normal:
- if(this.ishover) {
- this.state = ItemStates.hover;
- if(this.rating_hov!=tmp) {
- repaint_rating(this);
- };
- }; else {
- if(this.rating_hov!=tmp) {
- repaint_rating(this);
- };
- };
- break;
- case ItemStates.selected:
- if(this.rating_hov!=tmp || (this.rating_hov && this.l_rating!=tmp_l_rating) || (this.rating_hov && this.l_rating==0)) {
- repaint_rating(this);
- };
- break;
- case ItemStates.hover:
- if(!this.ishover) {
- this.state = ItemStates.normal;
- if(this.rating_hov!=tmp) {
- repaint_rating(this);
- };
- }; else {
- if(this.rating_hov!=tmp || (this.rating_hov && this.l_rating!=tmp_l_rating) || (this.rating_hov && this.l_rating==0)) {
- repaint_rating(this);
- };
- };
- break;
- };
- };
- };
- break;
- case "leave":
- this.l_rating = 0;
- repaint_rating(this);
- break;
- };
- return this.state;
- };
- };
- //=================================================// Globals (general)
- var g_instancetype = window.InstanceType;
- var g_font = null;
- var g_font_headers = null;
- var rating_font = gdi.Font("guifx v2 transports", 17, 0);
- var incsearch_font = gdi.Font("lucida console", 9, 0);
- var ww = 0, wh = 0;
- var mouse_x = 0, mouse_y = 0;
- var rating_x = 0, rating_y = 0;
- var rating_w = 0, rating_h = 0;
- var g_textcolor = 0, g_textcolor_sel = 0, g_textcolor_hl = 0, g_backcolor = 0, g_backcolor_sel = 0;
- var foo_playcount = utils.CheckComponent("foo_playcount", true);
- var g_start_new_track;
- var g_playtime_parity;
- var g_is_focused = false;
- var g_search_string = "";
- var clear_incsearch_timer = false;
- var incsearch_timer = false;
- var g_tooltip = window.CreateTooltip();
- var show_tooltip = false;
- //=================================================// Tools (general)
- function get_system_scrollbar_width() {
- var Shell = new ActiveXObject("WScript.Shell");
- var tmp = Shell.RegRead("HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics\\ScrollWidth");
- return Math.abs(tmp) / 15;
- };
- function get_font() {
- if (g_instancetype == 0) { // CUI
- g_font = window.GetFontCUI(FontTypeCUI.items);
- g_font_headers = window.GetFontCUI(FontTypeCUI.labels);
- }; else if (g_instancetype == 1) { // DUI
- g_font = window.GetFontDUI(FontTypeDUI.playlists);
- g_font_headers = window.GetFontDUI(FontTypeDUI.tabs);
- };
- };
- function get_colors() {
- if(g_instancetype == 0) { // CUI
- 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) { // DUI
- 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;
- };
- };
- //=================================================// 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(0, 1, cursor.w-0, cursor.h-2, g_backcolor);
- gb.FillSolidRect(0, 1, cursor.w-0, cursor.h-2, RGBA(0,0,0,100));
- gb.FillSolidRect(0, 1, cursor.w-1, cursor.h-3, g_textcolor&0x77ffffff);
- gb.FillSolidRect(1, 2, cursor.w-2, cursor.h-4, g_backcolor);
- gb.FillSolidRect(1, 2, cursor.w-2, cursor.h-4, RGBA(255,255,255,25));
- };
- 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(0, 1, cursor.w-0, cursor.h-2, g_backcolor);
- gb.FillSolidRect(0, 1, cursor.w-0, cursor.h-2, RGBA(0,0,0,70));
- gb.FillSolidRect(0, 1, cursor.w-1, cursor.h-3, g_textcolor&0x99ffffff);
- gb.FillSolidRect(1, 2, cursor.w-2, cursor.h-4, g_backcolor);
- gb.FillSolidRect(1, 2, cursor.w-2, cursor.h-4, RGBA(255,255,255,50));
- };
- 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.FillSolidRect(0, 0, button_up.w-0, button_up.h-0, g_backcolor);
- gb.FillSolidRect(0, 0, button_up.w-0, button_up.h-0, RGBA(0,0,0,100));
- gb.FillSolidRect(0, 0, button_up.w-1, button_up.h-1, g_textcolor&0x77ffffff);
- gb.FillSolidRect(1, 1, button_up.w-2, button_up.h-2, g_backcolor);
- gb.FillSolidRect(1, 1, button_up.w-2, button_up.h-2, RGBA(255,255,255,25));
- gb.SetTextRenderingHint(4);
- gui_font = gdi.Font("guifx v2 transports", 12, 0);
- gb.DrawString(".", gui_font, RGBA(255,255,255,25), 0, 1, button_up.w-0, button_up.h, cc_stringformat);
- gb.DrawString(".", gui_font, g_textcolor, 0, 0, button_up.w-0, button_up.h, cc_stringformat);
- };
- 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.FillSolidRect(0, 0, button_up.w-0, button_up.h-0, g_backcolor);
- gb.FillSolidRect(0, 0, button_up.w-0, button_up.h-0, RGBA(0,0,0,70));
- gb.FillSolidRect(0, 0, button_up.w-1, button_up.h-1, g_textcolor&0x99ffffff);
- gb.FillSolidRect(1, 1, button_up.w-2, button_up.h-2, g_backcolor);
- gb.FillSolidRect(1, 1, button_up.w-2, button_up.h-2, RGBA(255,255,255,50));
- gb.SetTextRenderingHint(4);
- gui_font = gdi.Font("guifx v2 transports", 12, 0);
- gb.DrawString(".", gui_font, RGBA(255,255,255,50), 0, 1, button_up.w-0, button_up.h, cc_stringformat);
- gb.DrawString(".", gui_font, g_textcolor, 0, 0, button_up.w-0, button_up.h, cc_stringformat);
- };
- 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.FillSolidRect(0, 0, button_up.w-0, button_up.h-0, g_textcolor&0x77ffffff);
- gb.FillSolidRect(0, 0, button_up.w-0, button_up.h-0, g_backcolor);
- gb.FillSolidRect(0, 0, button_up.w-1, button_up.h-1, RGBA(0,0,0,100));
- gb.FillSolidRect(1, 1, button_up.w-2, button_up.h-2, g_backcolor);
- gb.FillSolidRect(1, 1, button_up.w-2, button_up.h-2, RGBA(255,255,255,25));
- gb.SetTextRenderingHint(4);
- gui_font = gdi.Font("guifx v2 transports", 12, 0);
- gb.DrawString(".", gui_font, RGBA(255,255,255,25), 0, 1, button_up.w-0, button_up.h, cc_stringformat);
- gb.DrawString(".", gui_font, g_textcolor, 0, 0, button_up.w-0, button_up.h, cc_stringformat);
- };
- 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.FillSolidRect(0, 0, button_down.w-0, button_down.h-0, g_backcolor);
- gb.FillSolidRect(0, 0, button_down.w-0, button_down.h-0, RGBA(0,0,0,100));
- gb.FillSolidRect(0, 0, button_down.w-1, button_down.h-1, g_textcolor&0x77ffffff);
- gb.FillSolidRect(1, 1, button_down.w-2, button_down.h-2, g_backcolor);
- gb.FillSolidRect(1, 1, button_down.w-2, button_down.h-2, RGBA(255,255,255,25));
- gb.SetTextRenderingHint(4);
- gui_font = gdi.Font("guifx v2 transports", 12, 0);
- gb.DrawString(",", gui_font, RGBA(255,255,255,25), 0, 1, button_down.w-0, button_down.h, cc_stringformat);
- gb.DrawString(",", gui_font, g_textcolor, 0, 0, button_down.w-0, button_down.h, cc_stringformat);
- };
- 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.FillSolidRect(0, 0, button_down.w-0, button_down.h-0, g_backcolor);
- gb.FillSolidRect(0, 0, button_down.w-0, button_down.h-0, RGBA(0,0,0,70));
- gb.FillSolidRect(0, 0, button_down.w-1, button_down.h-1, g_textcolor&0x99ffffff);
- gb.FillSolidRect(1, 1, button_down.w-2, button_down.h-2, g_backcolor);
- gb.FillSolidRect(1, 1, button_down.w-2, button_down.h-2, RGBA(255,255,255,50));
- gb.SetTextRenderingHint(4);
- gui_font = gdi.Font("guifx v2 transports", 12, 0);
- gb.DrawString(",", gui_font, RGBA(255,255,255,50), 0, 1, button_down.w-0, button_down.h, cc_stringformat);
- gb.DrawString(",", gui_font, g_textcolor, 0, 0, button_down.w-0, button_down.h, cc_stringformat);
- };
- 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.FillSolidRect(0, 0, button_down.w-0, button_down.h-0, g_textcolor&0x77ffffff);
- gb.FillSolidRect(0, 0, button_down.w-0, button_down.h-0, g_backcolor);
- gb.FillSolidRect(0, 0, button_down.w-1, button_down.h-1, RGBA(0,0,0,100));
- gb.FillSolidRect(1, 1, button_down.w-2, button_down.h-1, g_backcolor);
- gb.FillSolidRect(1, 1, button_down.w-2, button_down.h-1, RGBA(255,255,255,25));
- gb.SetTextRenderingHint(4);
- gui_font = gdi.Font("guifx v2 transports", 12, 0);
- gb.DrawString(",", gui_font, RGBA(255,255,255,25), 0, 1, button_down.w-0, button_down.h, cc_stringformat);
- gb.DrawString(",", gui_font, g_textcolor, 0, 0, button_down.w-0, button_down.h, cc_stringformat);
- };
- 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;
- };
- };
- };
- function init_icons() {
- var i;
- var gb;
- var gui_font = gdi.Font("guifx v2 transports", 15, 0);
- playicon_off = gdi.CreateImage(row.h+0, row.h+0);
- gb = playicon_off.GetGraphics();
- gb.SetSmoothingMode(2);
- var points = Array(0,0, (Math.floor(playicon_off.Width/2)>14?14:Math.floor(playicon_off.Width/2)),Math.floor(playicon_off.Width/2), 0,playicon_off.Width);
- gb.FillPolygon(g_backcolor, 0, points);
- gb.FillPolygon(RGBA(255,255,255,24), 0, points);
- gb.SetSmoothingMode(0);
- playicon_off.ReleaseGraphics(gb);
- playicon_light = gdi.CreateImage(row.h+0, row.h+0);
- gb = playicon_light.GetGraphics();
- gb.SetSmoothingMode(2);
- var points = Array(-1,0, (Math.floor(playicon_off.Width/2)>14?14:Math.floor(playicon_off.Width/2))-1,Math.floor(playicon_off.Width/2), -1,playicon_off.Width);
- gb.FillPolygon(g_backcolor, 0, points);
- gb.FillPolygon(RGBA(255,255,255,24), 0, points);
- gb.FillPolygon(RGBA(255,255,255,30), 0, points);
- gb.SetSmoothingMode(0);
- playicon_light.ReleaseGraphics(gb);
- playicon_shadow = gdi.CreateImage(row.h+0, row.h+0);
- gb = playicon_shadow.GetGraphics();
- gb.SetSmoothingMode(2);
- var points = Array(0,0, (Math.floor(playicon_off.Width/2)>14?14:Math.floor(playicon_off.Width/2)),Math.floor(playicon_off.Width/2), 0,playicon_off.Width);
- gb.FillPolygon(RGB(0,0,0), 0, points);
- gb.SetSmoothingMode(0);
- playicon_shadow.ReleaseGraphics(gb);
- star_img_off = gdi.CreateImage(13, 18);
- gb = star_img_off.GetGraphics();
- gui_font = gdi.Font("guifx v2 transports", 17, 0);
- gb.SetTextRenderingHint(4);
- gb.DrawString("b", gui_font, g_textcolor&0x20ffffff, 0, 0, 13, 18, lt_stringformat);
- star_img_off.ReleaseGraphics(gb);
- star_img_on = gdi.CreateImage(13, 18);
- gb = star_img_on.GetGraphics();
- gui_font = gdi.Font("guifx v2 transports", 17, 0);
- gb.SetTextRenderingHint(4);
- gb.DrawString("b", gui_font, g_textcolor_sel, 0, 0, 13, 18, lt_stringformat);
- star_img_on.ReleaseGraphics(gb);
- star_img_hov = gdi.CreateImage(13, 18);
- gb = star_img_hov.GetGraphics();
- gui_font = gdi.Font("guifx v2 transports", 17, 0);
- gb.SetTextRenderingHint(4);
- gb.DrawString("b", gui_font, g_textcolor_sel, 0, 0, 13, 18, lt_stringformat);
- star_img_hov.ReleaseGraphics(gb);
- star_img_kill = gdi.CreateImage(13, 18);
- gb = star_img_kill.GetGraphics();
- gui_font = gdi.Font("guifx v2 transports", 12, 0);
- gb.SetTextRenderingHint(4);
- gb.DrawString("x", gui_font, RGB(220,50,50), 2, 2, 13, 18, lt_stringformat);
- star_img_kill.ReleaseGraphics(gb);
- // Set rating area width
- rating_w = Math.floor(star_img_off.Width*5);
- rating_h = Math.floor(star_img_off.Height);
- nocover = gdi.CreateImage(200, 200);
- gb = nocover.GetGraphics();
- gb.SetSmoothingMode(2);
- gb.FillGradRect(0,0,200,200,90,RGB(200,200,200),RGB(240,240,240),1.0);
- gb.SetTextRenderingHint(3);
- gui_font = gdi.Font("guifx v2 transports", 132, 0);
- gb.DrawString("x", gui_font, RGB(255,255,255), 1, 3, 200, 200, cc_stringformat);
- gb.DrawString("x", gui_font, RGB(120,120,120), 1, 0, 200, 200, cc_stringformat);
- nocover.ReleaseGraphics(gb);
- streamcover = gdi.CreateImage(200, 200);
- gb = streamcover.GetGraphics();
- gb.SetSmoothingMode(2);
- gb.FillGradRect(0,0,nocover.Width,nocover.Height,90,RGB(200,200,200),RGB(240,240,240),1.0);
- gb.SetTextRenderingHint(3);
- gui_font = gdi.Font("guifx v2 transports", 126, 0);
- gb.DrawString("$", gui_font, RGB(255,255,255), 1, 3, 200, 200, cc_stringformat);
- gb.DrawString("$", gui_font, RGB(120,120,120), 1, 0, 200, 200, cc_stringformat);
- streamcover.ReleaseGraphics(gb);
- };
- //=================================================// Playlist view (load)
- function refresh_spv() {
- var group_item_index = 0;
- var group_items_total = 0;
- var prev_cursor_h = cursor.h;
- g_tooltip.Text="";
- reset_cover_timers();
- if(vscrollbar.show) {
- vscrollbar.visible = (list.total>list.nbvis);
- }; else {
- vscrollbar.visible = false;
- };
- list.item.splice(0, list.item.length);
- list.tocut = (list.offset >= cover.nbrows)?cover.nbrows:list.offset;
- var gdeb = list.offset - list.tocut;
- var i = gdeb;
- var k = 0;
- var previous_group_key = null;
- var loop = (list.total>0);
- var group_item_index_search = false;
- while(loop) {
- list.item.push(new item);
- list.item[k].create(i, list.handlelist.Item(i), k, 0);
- if(i==0 || previous_group_key!=list.item[k].group_key) {
- // count the number of tracks in the current new group
- group_items_total = GetGroupTotal(i, list.item[k].group_key);
- list.item[k].grp_total = group_items_total;
- // initialize the item index for the group
- if(i>0 && !group_item_index_search) {
- group_item_index_search = true;
- group_item_index = GetGroupItemIndex(i-1, list.item[k].group_key);
- }; else {
- group_item_index = 0;
- };
- list.item[k].grp_idx = group_item_index;
- list.item[k].showcover = true;
- }; else {
- group_item_index++;
- list.item[k].grp_idx = group_item_index;
- list.item[k].grp_total = group_items_total;
- };
- list.item[k].visible = (k>=list.tocut && k<list.tocut+list.nbvis);
- if(k<list.nbvis+list.tocut) {
- list.stock = list.total - i - 1;
- };
- if(i==list.total-1 || k>list.nbvis+list.tocut+cover.nbrows) {
- loop = false;
- }; else {
- previous_group_key = list.item[k].group_key;
- k++;
- i++;
- };
- };
- var ratio = list.nbvis / list.total;
- 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
- if(!cursor.bt || cursor.h!=prev_cursor_h) {
- set_scroller();
- };
- if(!cursor.drag) setcursory();
- };
- //=================================================// Offset calculations
- function setcursory() {
- if(list.total>list.nbvis) {
- var ratio = list.offset / (list.total-list.nbvis);
- cursor.y = vscrollbar.y + Math.round((vscrollbar.h-cursor.h) * ratio);
- }; else {
- cursor.y = vscrollbar.y;
- };
- };
- function setoffset() {
- var ratio = (cursor.y-vscrollbar.y) / (vscrollbar.h-cursor.h);
- list.offset = Math.round((list.total-list.nbvis) * ratio);
- };
- //=================================================// Colour & Font Callbacks
- function on_font_changed() {
- get_font();
- window.Repaint();
- };
- function on_colors_changed() {
- get_colors();
- init_icons();
- init_vscrollbar_buttons();
- set_scroller();
- window.Repaint();
- };
- //=================================================// START
- function on_size() {
- if (!window.Width || !window.Height) return;
- if(g_instancetype == 0) { // CUI
- window.MinWidth = 200;
- window.MinHeight = 100;
- }; else if(g_instancetype == 1) { // DUI
- window.MinWidth = 200;
- window.MinHeight = 100;
- window.MaxWidth = 700;
- window.MaxHeight = 700;
- };
- ww = window.Width;
- wh = window.Height;
- toolbar.h = toolbar.visible ? toolbar.default_h : 0;
- wh = wh - toolbar.h;
- get_colors();
- get_font();
- init_icons();
- list.nbvis = ((wh/row.h) == Math.ceil(wh/row.h)) ? Math.ceil(wh/row.h) : Math.ceil((wh/row.h)-1);
- if(vscrollbar.themed) {
- vscrollbar.theme = window.CreateThemeManager("scrollbar");
- }; else {
- vscrollbar.theme = false;
- };
- init_vscrollbar_buttons();
- button_up.y = 0;
- button_down.y = toolbar.h + wh - button_down.h;
- vscrollbar.y = button_up.h;
- vscrollbar.h = (wh+toolbar.h) - button_up.h - button_down.h;
- cursor.x = ww-vscrollbar.w;
- cursor.y = vscrollbar.y;
- if(cover.w>0) {
- cover.visible = true;
- column.w[0] = cover.w;
- cover.h = cover.w;
- cover.nbrows = Math.ceil(cover.w/row.h);
- }; else {
- cover.visible = false;
- column.w[0] = 0;
- cover.h = cover.w;
- cover.nbrows = Math.ceil(cover.w/row.h);
- };
- if(wsh.first_on_size) {
- // on foobar2000 launch (just before first repaint)
- wsh.first_on_size = false;
- on_playlist_switch();
- }; else {
- // on foobar2000 window resize
- on_resizing();
- };
- };
- function on_paint(gr) {
- var i;
- if(wsh.transparency) {
- gr.FillSolidRect(0, toolbar.h, ww, wh, g_backcolor&0xe0ffffff);
- // column[0] (cover)
- gr.FillGradRect(0, toolbar.h, column.w[0], wh, 0, RGBA(0,0,0,25), g_backcolor, 1.0);
- gr.FillGradRect(0, toolbar.h, column.w[0], wh, 0, RGBA(0,0,0,25), RGBA(255,255,255,25), 1.0);
- }; else {
- gr.FillSolidRect(0, toolbar.h, ww, wh, g_backcolor);
- // column[0] (cover)
- gr.FillSolidRect(0, toolbar.h, column.w[0], wh, g_backcolor);
- gr.FillGradRect(0, toolbar.h, column.w[0], wh, 0, RGBA(0,0,0,25), RGBA(255,255,255,25), 1.0);
- };
- if(list.total>0) {
- for(i=0;i<list.item.length;i++) {
- list.item[i].draw(gr, list.item[i].id);
- };
- }; else {
- gr.FillSolidRect(column.w[0]-0, toolbar.h, 1, wh, RGBA(0,0,0,100));
- gr.FillSolidRect(column.w[0]-1, toolbar.h, 1, wh, RGBA(255,255,255,25));
- gr.FillSolidRect(column.w[0]+1, toolbar.h, 1, wh, RGBA(0,0,0,60));
- gr.FillSolidRect(column.w[0]+2, toolbar.h, 1, wh, RGBA(0,0,0,30));
- gr.FillSolidRect(column.w[0]+3, toolbar.h, 1, wh, RGBA(0,0,0,10));
- if(fb.PlaylistCount>0) {
- var text_top = fb.GetPlaylistName(fb.ActivePlaylist);
- var text_bot = "This playlist is empty";
- }; else {
- var text_top = "WSH Simple Playlist Viewer";
- var text_bot = "Create a playlist to start!";
- };
- // empty playlist text info
- gr.GdiDrawText(text_top, gdi.Font("Tahoma", 17, 0), g_textcolor, column.w[0], toolbar.h-20, ww-column.w[0], wh, DT_CENTER | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
- gr.GdiDrawText(text_bot, gdi.Font("Tahoma", 13, 0), g_textcolor, column.w[0], toolbar.h+20, ww-column.w[0], wh, DT_CENTER | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
- gr.FillSolidRect(column.w[0], toolbar.h, ww-column.w[0], wh, g_backcolor&0xaaffffff);
- gr.FillGradRect(column.w[0]+40, toolbar.h+Math.floor(wh/2), ww-column.w[0]-80, 1, 0, 0, g_textcolor&0x66ffffff, 0.5);
- };
- // draw toolbar
- if(toolbar.visible) {
- gr.FillSolidRect(0, 0, ww, toolbar.h, g_backcolor);
- gr.FillSolidRect(0, toolbar.h-1, ww, 1, RGBA(0,0,0,100));
- gr.FillSolidRect(0, toolbar.h-2, ww, 1, RGBA(255,255,255,25));
- var start_point = 0;
- for(i=0;i<column.total;i++) {
- gr.GdiDrawText(column.label[i], g_font_headers, g_backcolor, start_point+5, 2, column.w[i]-10, toolbar.h-2, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
- gr.GdiDrawText(column.label[i], g_font_headers, g_textcolor, start_point+5, 1, column.w[i]-10, toolbar.h-2, DT_LEFT | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
- gr.FillSolidRect(start_point+5, 2, column.w[i]-10, toolbar.h-4, g_backcolor&0x33ffffff);
- start_point += column.w[i];
- };
- gr.FillGradRect(0, 0, ww, toolbar.h, 90, 0, g_textcolor&0x15ffffff, 1.0);
- start_point = 0;
- for(i=0;i<column.total-1;i++) {
- start_point += column.w[i];
- gr.FillSolidRect(start_point-1, 0, 1, toolbar.h-2, RGBA(255,255,255,25));
- gr.FillSolidRect(start_point, 0, 1, toolbar.h-1, RGBA(0,0,0,100));
- };
- gr.FillGradRect(0, 0, ww, Math.floor(toolbar.h/2), 90, RGBA(255,255,255,30), RGBA(255,255,255,15), 1.0);
- gr.FillGradRect(0, Math.ceil(toolbar.h/2), ww, Math.floor(toolbar.h/2), 90, g_textcolor&0x15ffffff, RGBA(0,0,0,50), 1.0);
- gr.FillSolidRect(0, 0, ww, 1, RGBA(255,255,255,50));
- };
- // 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+toolbar.h);
- gr.FillSolidRect(ww-vscrollbar.w-1, 0, 1, wh+toolbar.h, RGBA(0,0,0,100));
- }; catch(e) {
- gr.FillSolidRect(ww-vscrollbar.w, 0, vscrollbar.w, wh+toolbar.h, g_backcolor);
- gr.FillGradRect(ww-vscrollbar.w, 0, vscrollbar.w, wh+toolbar.h, 0, RGBA(0,0,0,100), g_backcolor, 0.5);
- gr.FillGradRect(ww-vscrollbar.w, 0, vscrollbar.w, wh+toolbar.h, 0, 0, RGBA(255,255,255,25), 0.5);
- gr.FillSolidRect(ww-vscrollbar.w-1, 0, 1, wh+toolbar.h, RGBA(0,0,0,100));
- };
- // 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].albumartist.substring(0,1).toUpperCase();
- cursor.popup && gr.DrawImage(cursor.popup, ww-vscrollbar.w-cursor.popup.Width-00, 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, 255);
- cursor.popup && gr.GdiDrawText(vscrollbar.letter, gdi.Font("segoe ui", 14, 0), g_backcolor, ww-vscrollbar.w-cursor.popup.Width-00, 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);
- };
- };
- // Incremental Search Tooltip (bot/left corner)
- if(g_search_string.length>0) {
- gr.SetSmoothingMode(2);
- gr.FillRoundRect(-10, window.Height-14, g_search_string.length*5+16, 30, 5, 5, g_textcolor);
- gr.DrawRoundRect(-10, window.Height-14, g_search_string.length*5+16, 30, 5, 5, 1.0, RGBA(0,0,0,200));
- gr.GdiDrawText(g_search_string, incsearch_font, g_backcolor, 3, window.Height-11 , g_search_string.length*5+3 , 12, DT_LEFT | DT_NOPREFIX | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
- };
- };
- //=================================================// Mouse Callbacks
- function on_mouse_lbtn_down(x, y) {
- var i;
- if(y>toolbar.h) {
- for(i=0;i<list.item.length;i++) {
- list.item[i].checkstate("down", x, y, i);
- };
- };
- if(vscrollbar.visible && vscrollbar.show) {
- if(cursor.bt.checkstate("down", x, y)==ButtonStates.down) {
- cursor.drag = true;
- cursor.grap_y = y - cursor.y;
- };
- if(vscrollbar.hover && !cursor.drag) {
- vscrollbar.step = list.nbvis;
- if(y<cursor.y) {
- on_mouse_wheel(1);
- button_up.timerID = window.SetInterval(function () { on_mouse_wheel(1); }, 100);
- }; else {
- on_mouse_wheel(-1);
- button_down.timerID = window.SetInterval(function () { on_mouse_wheel(-1); }, 100);
- };
- };
- // 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) {
- vscrollbar.step = 1;
- on_mouse_wheel(1);
- button_up.timerID = window.SetInterval(function () { on_mouse_wheel(1); }, 100);
- };
- break;
- case 1:
- if(vscrollbar.arr_buttons[i].checkstate("down", x, y)==ButtonStates.down) {
- vscrollbar.step = 1;
- on_mouse_wheel(-1);
- button_down.timerID = window.SetInterval(function () { on_mouse_wheel(-1); }, 100);
- };
- break;
- };
- };
- };
- };
- function on_mouse_lbtn_dblclk(x, y, mask) {
- if(y>0 && y<toolbar.h && x<ww-vscrollbar.w) {
- wsh.action_shownowplaying = true;
- if(fb.ActivePlaylist != fb.PlayingPlaylist) {
- list.handlelist = plman.GetPlaylistItems(fb.PlayingPlaylist);
- list.total = list.handlelist.Count;
- fb.ActivePlaylist = fb.PlayingPlaylist;
- }; else {
- ShowNowPlaying();
- window.Repaint();
- };
- }; else {
- if(x>ww-vscrollbar.w) {
- on_mouse_lbtn_down(x, y);
- }; else if(x>column.w[0]){
- for(var i in list.item) {
- list.item[i].checkstate("dblclk", x, y, i);
- };
- };
- };
- };
- function on_mouse_lbtn_up(x, y) {
- var i;
- // scrollbar button up and down RESET
- vscrollbar.step = vscrollbar.default_step;
- button_up.timerID && window.ClearInterval(button_up.timerID);
- button_up.timerID = false;
- button_down.timerID && window.ClearInterval(button_down.timerID);
- button_down.timerID = false;
- // 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) {
- setcursory();
- window.RepaintRect(ww-vscrollbar.w-cursor.popup.Width-5, 0, cursor.popup.Width+vscrollbar.w+5, toolbar.h+wh);
- cursor.drag = false;
- }; else {
- // check items
- for(i=list.tocut;i<list.item.length;i++) {
- list.item[i].checkstate("up", x, y, i);
- };
- };
- };
- function on_mouse_rbtn_down(x, y) {
- var i;
- for(i=list.tocut;i<list.item.length;i++) {
- list.item[i].checkstate("right", x, y, i);
- };
- };
- function on_mouse_move(x, y) {
- var i, txt;
- if(x==mouse_x && y==mouse_y) return true;
- wsh.is_hover = (x>=0 && x<=ww && y>=0 && y<=toolbar.h+wh);
- if(wsh.drag_drop_enabled && wsh.drag) window.SetCursor(IDC_HELP); else window.SetCursor(IDC_ARROW);
- if(x<ww-vscrollbar.w && y>toolbar.h) {
- show_tooltip = false;
- for(i=list.tocut;i<list.item.length;i++) {
- list.item[i].checkstate("move", x, y, i);
- if(list.item[i].ishover) {
- if(x>column.w[0] && x<column.w[0]+column.w[1]) {
- txt = list.item[i].artist+" / "+list.item[i].title;
- if(txt.length>0 && list.item[i].tooltip) show_tooltip = true;
- if(g_tooltip.Text != txt) {
- g_tooltip.Deactivate();
- g_tooltip.TrackActivate = true;
- g_tooltip.Text = txt;
- g_tooltip.TrackPosition(list.item[i].x+column.w[0]+column.w[1]+2, list.item[i].y+Math.floor(row.h/2)-(18/2));
- };
- }; else if(list.item[i].grp_total>=cover.nbrows && x>cover.margin && x<column.w[0]-cover.margin) {
- list.item[i].disc_info = tf_disc_info.EvalWithMetadb(list.item[i].metadb);
- if(list.item[i].album.length>0) {
- if(list.item[i].date.length>0) {
- txt = list.item[i].albumartist+": "+list.item[i].album+list.item[i].disc_info+" ("+list.item[i].date+")";
- }; else {
- txt = list.item[i].albumartist+": "+list.item[i].album+list.item[i].disc_info;
- };
- }; else {
- txt = list.item[i].artist+": Singles";
- };
- if(txt.length>0 && list.item[i].grp_idx<cover.nbrows && y>list.item[i].cover_top_y && y<list.item[i].cover_top_y+cover.h-cover.margin*2) {
- show_tooltip = true;
- if(g_tooltip.Text != txt) {
- g_tooltip.Deactivate();
- g_tooltip.TrackActivate = true;
- g_tooltip.Text = txt;
- g_tooltip.TrackPosition(list.item[i].x+cover.margin, list.item[i].cover_top_y+cover.h-cover.margin*2+2);
- };
- };
- };
- };
- };
- if(show_tooltip) {
- g_tooltip.Activate();
- g_tooltip.TrackActivate = true;
- }; else {
- g_tooltip.Deactivate();
- g_tooltip.TrackActivate = false;
- g_tooltip.Text="";
- };
- }; else {
- g_tooltip.Deactivate();
- g_tooltip.TrackActivate = false;
- g_tooltip.Text="";
- };
- if(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(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(!vscrollbar.timerID) {
- vscrollbar.timerID = window.SetTimeout(function() {
- window.RepaintRect(ww-vscrollbar.w,toolbar.h,vscrollbar.w,wh);
- }, 20);
- };
- if(!cursor.timerID) {
- cursor.timerID = window.SetTimeout(function() {
- setoffset();
- refresh_spv();
- window.Repaint();
- cursor.timerID = false;
- }, 50);
- };
- };
- };
- mouse_x = x;
- mouse_y = y;
- };
- function on_mouse_wheel(delta) {
- var i;
- if(delta>0) {
- for(i=0;i<vscrollbar.step;i++) {
- if(list.offset>0) list.offset--;
- };
- }; else {
- var step_max = list.stock<vscrollbar.step ? list.stock : vscrollbar.step;
- for(i=0;i<step_max;i++) {
- if(list.stock>0) list.offset++;
- };
- };
- reset_cover_timers();
- if(!wsh.mousewheel_timerID) {
- wsh.mousewheel_timerID = window.SetTimeout(function() {
- refresh_spv();
- window.Repaint();
- wsh.mousewheel_timerID = false;
- }, 25);
- };
- };
- function on_mouse_leave() {
- // check buttons
- cursor.bt.checkstate("leave", 0, 0);
- for(var i in vscrollbar.arr_buttons) {
- vscrollbar.arr_buttons[i].checkstate("leave", 0, 0);
- };
- for(i=list.tocut;i<list.item.length;i++) {
- list.item[i].checkstate("leave", 0, 0, i);
- };
- window.Repaint();
- g_tooltip.Text="";
- };
- //=================================================// Playlist Callbacks
- function on_playlists_changed() {
- window.Repaint();
- };
- function on_resizing() { // function called manually in on_size Callback
- refresh_spv();
- if(vscrollbar.show) {
- vscrollbar.visible = (list.total>list.nbvis);
- }; else {
- vscrollbar.visible = false;
- };
- vscrollbar.w = vscrollbar.visible?vscrollbar.default_w:0;
- column.w[2] = ww - column.w[0] - column.w[1] - column.w[3] - column.w[4] - vscrollbar.w;
- list.metadblist_selection = plman.GetPlaylistSelectedItems(fb.ActivePlaylist);
- window.Repaint();
- };
- function on_playlist_switch() {
- list.offset = 0;
- list.handlelist = plman.GetPlaylistItems(fb.ActivePlaylist);
- list.total = list.handlelist.Count;
- refresh_spv();
- if(vscrollbar.show) {
- vscrollbar.visible = (list.total>list.nbvis);
- }; else {
- vscrollbar.visible = false;
- };
- vscrollbar.w = vscrollbar.visible?vscrollbar.default_w:0;
- column.w[2] = ww - column.w[0] - column.w[1] - column.w[3] - column.w[4] - vscrollbar.w;
- if(wsh.action_shownowplaying) {
- ShowNowPlaying();
- }; else {
- ShowSelectedItem(-1);
- };
- list.metadblist_selection = plman.GetPlaylistSelectedItems(fb.ActivePlaylist);
- window.Repaint();
- };
- function on_playlist_items_added(playlist_idx) {
- if(playlist_idx==fb.ActivePlaylist) {
- on_playlist_switch();
- };
- };
- function on_playlist_items_reordered(playlist_idx) {
- if(playlist_idx==fb.ActivePlaylist) {
- on_playlist_switch();
- };
- };
- function on_selection_changed(metadb) {
- if(!g_start_new_track) {
- if(!wsh.context_menu_called) {
- ShowSelectedItem(-1);
- }; else {
- wsh.context_menu_called = false;
- //ShowSelectedItem(-1);
- window.Repaint();
- };
- };
- g_start_new_track = false;
- };
- function on_playlist_items_selection_change() {
- list.metadblist_selection = plman.GetPlaylistSelectedItems(fb.ActivePlaylist);
- window.Repaint();
- };
- //=================================================// Other Callbacks
- function on_item_focus_change() {
- list.handlelist = plman.GetPlaylistItems(fb.ActivePlaylist);
- list.total = list.handlelist.Count;
- if(list.offset>list.total) list.offset = 0;
- if(list.metadblist_selection) {
- on_metadb_changed();
- };
- };
- function on_metadb_changed() {
- plman.SetActivePlaylistContext();
- refresh_spv();
- window.Repaint();
- };
- function on_focus(is_focused) {
- g_is_focused = is_focused;
- };
- //=================================================// Keyboard Callbacks
- function on_key_up(vkey) {
- // scroll keys up and down RESET (step and timers)
- vscrollbar.step = vscrollbar.default_step;
- button_up.timerID && window.ClearInterval(button_up.timerID);
- button_up.timerID = false;
- button_down.timerID && window.ClearInterval(button_down.timerID);
- button_down.timerID = false;
- };
- function on_key_down(vkey) {
- var mask = GetKeyboardMask();
- var focus_id;
- if (mask == KMask.none) {
- switch (vkey) {
- case VK_BACK:
- if(g_search_string.length>0) {
- g_search_string = g_search_string.substring(0, g_search_string.length-1);
- window.RepaintRect(0, window.Height-15, ww, 16);
- clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
- incsearch_timer && window.ClearTimeout(incsearch_timer);
- incsearch_timer = window.SetTimeout(function () {
- IncrementalSearch();
- incsearch_timer = false;
- }, 500);
- };
- break;
- case VK_ESCAPE:
- case 222:
- // reset incremental search String
- g_search_string = "";
- if(!fb.IsPlaying) window.RepaintRect(0, window.Height-15, ww, 16);
- break;
- case VK_UP:
- if(!button_up.timerID) {
- vscrollbar.step = 1;
- on_mouse_wheel(1);
- button_up.timerID = window.SetInterval(function () { on_mouse_wheel(1); }, 100);
- };
- break;
- case VK_DOWN:
- if(!button_down.timerID) {
- vscrollbar.step = 1;
- on_mouse_wheel(-1);
- button_down.timerID = window.SetInterval(function () { on_mouse_wheel(-1); }, 100);
- };
- break;
- case VK_PGUP:
- if(!button_up.timerID) {
- vscrollbar.step = list.nbvis;
- on_mouse_wheel(1);
- button_up.timerID = window.SetInterval(function () { on_mouse_wheel(1); }, 100);
- };
- break;
- case VK_PGDN:
- if(!button_down.timerID) {
- vscrollbar.step = list.nbvis;
- on_mouse_wheel(-1);
- button_down.timerID = window.SetInterval(function () { on_mouse_wheel(-1); }, 100);
- };
- break;
- case VK_RETURN:
- // play focus item
- fb.RunContextCommandWithMetadb("Play", fb.GetFocusItem());
- break;
- case VK_END:
- list.offset = list.total-list.nbvis;
- on_metadb_changed();
- break;
- case VK_HOME:
- list.offset = 0;
- on_metadb_changed();
- break;
- case VK_DELETE:
- plman.RemovePlaylistSelection(fb.ActivePlaylist, false);
- on_playlist_switch();
- break;
- default:
- if(g_search_string.length<=20) {
- if((vkey>=65 && vkey<=90) || vkey==32) {
- var ch = String.fromCharCode(vkey);
- g_search_string = g_search_string + ch;
- window.RepaintRect(0, window.Height-15, ww, 16);
- clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
- clear_incsearch_timer = false;
- incsearch_timer && window.ClearTimeout(incsearch_timer);
- incsearch_timer = window.SetTimeout(function () {
- IncrementalSearch();
- incsearch_timer = false;
- }, 500);
- };
- if(vkey>=96 && vkey<=105) {
- var ch = (vkey-96);
- g_search_string = g_search_string + ch;
- window.RepaintRect(0, window.Height-15, ww, 16);
- clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
- clear_incsearch_timer = false;
- incsearch_timer && window.ClearInterval(incsearch_timer);
- incsearch_timer = window.SetInterval(function () {
- IncrementalSearch();
- incsearch_timer && window.ClearInterval(incsearch_timer);
- incsearch_timer = false;
- }, 500);
- };
- };
- break;
- };
- }; else {
- switch(mask) {
- case KMask.ctrl:
- if(vkey==65) { // CTRL+A
- fb.RunMainMenuCommand("Edit/Select all");
- window.Repaint();
- };
- 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;
- };
- };
- };
- //=================================================// Item Context Menu
- function new_context_menu(x, y, id, array_id) {
- var i;
- var MF_STRING = 0x00000000;
- var MF_SEPARATOR = 0x00000800;
- var MF_GRAYED = 0x00000001;
- var MF_DISABLED = 0x00000002;
- var MF_POPUP = 0x00000010;
- wsh.context_menu_called = true;
- var _menu = window.CreatePopupMenu();
- var Context = fb.CreateContextMenuManager();
- var _child01 = window.CreatePopupMenu();
- var _child02 = window.CreatePopupMenu();
- list.metadblist_selection = plman.GetPlaylistSelectedItems(fb.ActivePlaylist);
- Context.InitContext(list.metadblist_selection);
- Context.BuildMenu(_menu, 1, -1);
- _menu.AppendMenuItem(MF_SEPARATOR, 0, "");
- _menu.AppendMenuItem(MF_STRING | MF_POPUP, _child01.ID, "Selection...");
- _menu.AppendMenuItem(MF_SEPARATOR, 0, "");
- _menu.AppendMenuItem(fb.IsPlaying?MF_STRING:MF_DISABLED|MF_GRAYED, 880, "Show Now Playing");
- _menu.AppendMenuItem((list.total>0)?MF_STRING:MF_DISABLED|MF_GRAYED, 890, "Refresh playlist");
- _child01.AppendMenuItem((fb.IsAutoPlaylist(fb.ActivePlaylist))?MF_DISABLED|MF_GRAYED:MF_STRING, 1000, "Remove");
- _child01.AppendMenuItem(MF_STRING | MF_POPUP, _child02.ID, "Send to...");
- _child02.AppendMenuItem(MF_STRING, 2000, "a New playlist...");
- _child02.AppendMenuItem(MF_SEPARATOR, 0, "");
- for(i=0;i<fb.PlaylistCount;i++) {
- if(i!=fb.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:
- wsh.action_shownowplaying = true;
- if(fb.ActivePlaylist != fb.PlayingPlaylist) {
- list.handlelist = plman.GetPlaylistItems(fb.PlayingPlaylist);
- list.total = list.handlelist.Count;
- fb.ActivePlaylist = fb.PlayingPlaylist;
- }; else {
- ShowNowPlaying();
- window.Repaint();
- };
- break;
- case 890:
- g_image_cache = new image_cache;
- CollectGarbage();
- window.Repaint();
- break;
- };
- }; else {
- switch (ret) {
- case 1000:
- plman.RemovePlaylistSelection(fb.ActivePlaylist, false);
- on_playlist_switch();
- break;
- case 2000:
- fb.RunMainMenuCommand("File/New playlist");
- plman.InsertPlaylistItems(fb.PlaylistCount-1, 0, list.metadblist_selection, false);
- break;
- default:
- var insert_index = fb.PlaylistItemCount(ret-2001);
- plman.InsertPlaylistItems((ret-2001), insert_index, list.metadblist_selection, false);
- };
- };
- };
- //=================================================// Playback Callbacks
- function on_playback_new_track(info) {
- g_start_new_track = true;
- if(!cursor.drag && fb.CursorFollowPlayback) {
- CursorFollowsPlayback();
- refresh_spv();
- };
- window.Repaint();
- };
- function on_playback_stop(reason) {
- if(reason==0) { // on user Stop
- on_metadb_changed();
- };
- };
- function on_playback_pause(state){
- };
- function on_playback_time(time) {
- g_playtime_parity = (time/2-Math.floor(time/2)==0)?0:1;
- // only repaint the now playing line, if we aren't dragging vscrollbar cursor!
- if(!cursor.timerID) window.RepaintRect(column.w[0], list.nowplaying_y+1, ww-vscrollbar.w, row.h-2);
- };
- //=================================================// Playlist Tools
- function CursorFollowsPlayback() {
- if(!fb.IsPlaying || list.total<=list.nbvis) return true;
- if(fb.ActivePlaylist != fb.PlayingPlaylist) {
- fb.ActivePlaylist = fb.PlayingPlaylist;
- list.handlelist = plman.GetPlaylistItems(fb.ActivePlaylist);
- list.total = list.handlelist.Count;
- };
- list.nowplaying = plman.GetPlayingItemLocation();
- var pid = list.nowplaying.PlaylistItemIndex;
- var already_shown = false;
- for(var i in list.item) {
- if(list.item[i].id == pid) {
- if(list.item[i].visible) {
- already_shown = true;
- };
- break;
- };
- };
- if(!already_shown) {
- list.offset = pid - (pid<Math.floor(list.nbvis/2) ? pid : Math.floor(list.nbvis/2) );
- if(pid>list.total-1-Math.floor(list.nbvis/2)) {
- list.offset = list.total-list.nbvis;
- };
- };
- list.singleton_select_id = pid;
- };
- function ShowNowPlaying() {
- if(!fb.IsPlaying || list.total<=list.nbvis) return true;
- plman.ClearPlaylistSelection(fb.ActivePlaylist);
- wsh.action_shownowplaying = false;
- list.nowplaying = plman.GetPlayingItemLocation();
- var pid = list.nowplaying.PlaylistItemIndex;
- if(pid>=0 && pid<list.total) {
- list.offset = pid - (pid<Math.floor(list.nbvis/2) ? pid : Math.floor(list.nbvis/2) );
- if(pid>list.total-1-Math.floor(list.nbvis/2)) {
- list.offset = list.total-list.nbvis;
- };
- refresh_spv();
- };
- plman.SetPlaylistFocusItem(fb.ActivePlaylist, pid);
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, pid, true);
- };
- function ShowSelectedItem(pid) {
- if(list.total==0 || !fb.GetFocusItem(false)) return true;
- if(pid<0) {
- pid = plman.GetPlaylistFocusItemIndex(fb.ActivePlaylist);
- };
- var already_shown = false;
- for(var i in list.item) {
- if(list.item[i].id == pid) {
- if(list.item[i].visible) {
- already_shown = true;
- };
- break;
- };
- };
- if(!already_shown) {
- list.offset = pid - (pid<Math.floor(list.nbvis/2) ? pid : Math.floor(list.nbvis/2) );
- if(pid>list.total-1-Math.floor(list.nbvis/2)) {
- list.offset = list.total-0-list.nbvis;
- };
- refresh_spv();
- };
- plman.SetPlaylistFocusItem(fb.ActivePlaylist, pid);
- plman.SetPlaylistSelectionSingle(fb.ActivePlaylist, pid, true);
- };
- function SelectAtoB(start_id, end_id) {
- var i;
- var affectedItems = Array();
- plman.ClearPlaylistSelection(fb.ActivePlaylist);
- if(start_id<end_id) {
- var deb = start_id;
- var fin = end_id;
- }; else {
- var deb = end_id;
- var fin = start_id;
- };
- for(i=deb;i<=fin;i++) {
- affectedItems.push(i);
- };
- plman.SetPlaylistSelection(fb.ActivePlaylist, affectedItems, true);
- window.Repaint();
- };
- function SelectGroupItems(start_id, group_key) {
- var i;
- var count=0;
- var gitem;
- var affectedItems = Array();
- if(!utils.IsKeyPressed(VK_CONTROL)) {
- plman.ClearPlaylistSelection(fb.ActivePlaylist);
- };
- for(i=start_id;i<list.total;i++) {
- gitem = new item;
- gitem.template_it(i, list.handlelist.Item(i));
- if(gitem.group_key!=group_key) {
- break;
- }; else {
- affectedItems.push(i);
- };
- count++;
- if(count>9999) break;
- };
- plman.SetPlaylistSelection(fb.ActivePlaylist, affectedItems, true);
- list.singleton_select_id = start_id;
- plman.SetPlaylistFocusItem(fb.ActivePlaylist, start_id);
- on_item_focus_change();
- };
- function GetGroupItemIndex(start_id, group_key) {
- var i;
- var count=0;
- var gitem;
- for(i=start_id;i>=0;i--) {
- gitem = new item;
- gitem.template_it(i, list.handlelist.Item(i));
- if(gitem.group_key==group_key) {
- count++;
- if(count>9999) break;
- }; else {
- break;
- };
- };
- return count;
- };
- function GetGroupTotal(start_id, group_key) {
- var i;
- var count=1;
- var gitem;
- for(i=start_id+1;i<list.total;i++) {
- gitem = new item;
- gitem.template_it(i, list.handlelist.Item(i));
- if(gitem.group_key==group_key) {
- count++;
- if(count>9999) break;
- }; else {
- break;
- };
- };
- return count;
- };
- function IncrementalSearch() {
- var i;
- 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>500) {
- albumartist = tf_albumartist.EvalWithMetadb(list.handlelist.Item(Math.floor(list.total/2)));
- chr = albumartist.substring(0,1);
- if(chr.charCodeAt(chr) <= first_chr.charCodeAt(first_chr)) {
- gstart = Math.floor(list.total/2);
- }; else {
- gstart = 0;
- };
- }; else {
- gstart = 0;
- };
- for(i=gstart;i<list.total;i++) {
- albumartist = tf_albumartist.EvalWithMetadb(list.handlelist.Item(i));
- if(albumartist.substring(0,len).toUpperCase()==g_search_string) {
- pid = i;
- break;
- };
- };
- if(pid>0) { // found!
- plman.ClearPlaylistSelection(fb.ActivePlaylist);
- ShowSelectedItem(pid);
- };
- clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
- clear_incsearch_timer = window.SetInterval(function () {
- // reset incremental search string after 3 seconds without any key pressed
- g_search_string = "";
- window.RepaintRect(0, window.Height-15, ww, 16);
- clear_incsearch_timer && window.ClearInterval(clear_incsearch_timer);
- clear_incsearch_timer = false;
- }, 2000);
- };
- //=================================================// 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 = fb.ActivePlaylist;
- action.ToSelect = false;
- };
Add Comment
Please, Sign In to add comment