Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: WSH Panel Mod (Read 819116 times) previous topic - next topic
0 Members and 2 Guests are viewing this topic.

WSH Panel Mod

Reply #401
Is there a way to force the minimum height (or width) of a WSH panel?
Thanks

WSH Panel Mod

Reply #402
@NEMO7538:
I'll consider add that in the future, if it possible.

WSH Panel Mod

Reply #403
1.2.0 Beta 1 Uploaded.

WSH Panel Mod

Reply #404
Quote
v1.2.0
- ADD: Preprocessor directive "@import", See Preprocessors.txt for more details.
- ADD: Preprocessor sample.
- ADD: utils.ReadTextFile()
- FIX: Misc bugs and crashes fixed.

WSH Panel Mod

Reply #405
I noticed error with NEMO7538's rating script when starting foobar with empty playlist. It's not related to latest WSH version
The script isn't initliased until something is in playlist. Debugger points here:
[font= "Courier New"]
Invalid procedure call or argument

function on_metadb_changed() {
      g_drag = 0;
      rating = g_tfo.EvalWithMetadb(g_metadb);
      if (rating == "?") {rating = 0;}
      lrating = rating;
      window.Repaint();
}[/font]


Can we do something about this error?

WSH Panel Mod

Reply #406
you can add one line:
if (g_metadb)
into a proper place to ensure that g_metadb is valid.

WSH Panel Mod

Reply #407
Thanks. Changed red line to:

if (g_metadb) {rating = g_tfo.EvalWithMetadb(g_metadb);}

works fine, without error

WSH Panel Mod

Reply #408
Here another WSH Panel mod Script:


Statistics
Collects global callback statistics




Code: [Select]
//Statistics by grimes
function RGB(r, g, b) {
    return (0xff000000 | (r << 16) | (g << 8) | (b));
}

var g_font = gdi.Font("Segoi UI", 12, 0);

var g_timer1 = 0;
var count2 = 0;

var on_item_played2 = 0;
var on_volume_change2 = 0;
var on_get_album_art_done2 = 0;
var on_metadb_changed2 = 0;
var on_item_focus_change2 = 0;
var on_playback_order_changed2 = 0;
var on_playback_time2 = 0;
var on_playback_dynamic_info_track2 = 0;
var on_playback_dynamic_info2 = 0;
var on_playback_edited2 = 0;
var on_playback_pause2 = 0;
var on_playback_seek2 = 0;
var on_playback_stop2 = 0;
var on_playback_new_track2 = 0;
var on_playback_starting2 = 0;
var seconds = 0;
var minutes = 0;
var hours = 0;
var days = 0;
var seconds2 = 0;
var minutes2 = 0;
var hours2 = 0;
var days2 = 0;
var seconds3 = 0;
var minutes3 = 0;
var hours3 = 0;
var days3 = 0;

var dt = Date();
g_timer1 = window.CreateTimerInterval(1000);
var dt2 = "Never";
var dt3 = "Never";
var dt4 = "Never";
var dt5 = "Never";
var dt6 = "Never";
var dt7 = "Never";
var dt8 = "Never";
var dt9 = "Never";
var dt10 = "Never";
var dt11 = "Never";
var dt12 = "Never";
var dt13 = "Never";
var dt14 = "Never";
var dt15 = "Never";
var dt16 = "Never";
var dt17 = "Never";
var dt18 = "Never";

var idle = 0;
var proc = 0;
var proc2 = 0;
var sum = 0;



function on_paint(gr) {
    gr.DrawString("startup = " + count2 + "s (" + days2 + "d" + hours2 + "h" + minutes2 + "m" + seconds2 + "s) (" + dt + ")", g_font, RGB(200, 80, 80), 0, -160, window.Width, window.Height, 0x11005000);
    gr.DrawString("time idle = " + idle + "s (" + days3 + "d" + hours3 + "h" + minutes3 + "m" + seconds3 + "s) " + proc2 + "%", g_font, RGB(200, 80, 80), 0, -140, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_time = " + on_playback_time2 + "s (" + days + "d" + hours + "h" + minutes + "m" + seconds + "s) " + proc + "%", g_font, RGB(200, 80, 80), 0, -120, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_starting = " + on_playback_starting2 + " (" + dt2 + ")", g_font, RGB(80, 80, 80), 0, -100, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_new_track = " + on_playback_new_track2 + " (" + dt4 + ")", g_font, RGB(80, 80, 80), 0, -80, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_stop = " + on_playback_stop2 + " (" + dt5 + ")", g_font, RGB(80, 80, 80), 0, -60, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_seek = " + on_playback_seek2 + " (" + dt6 + ")", g_font, RGB(80, 80, 80), 0, -40, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_pause = " + on_playback_pause2 + " (" + dt7 + ")", g_font, RGB(80, 80, 80), 0, -20, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_edited = " + on_playback_edited2 + " (" + dt8 + ")", g_font, RGB(80, 80, 80), 0, 0, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_dynamic_info = " + on_playback_dynamic_info2 + " (" + dt9 + ")", g_font, RGB(80, 80, 80), 0, 20, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_dynamic_info_track = " + on_playback_dynamic_info_track2 + " (" + dt10 + ")", g_font, RGB(80, 80, 80), 0, 40, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_item_played = " + on_item_played2 + " (" + dt3 + ")", g_font, RGB(200, 80, 80), 0, 60, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_playback_order_changed = " + on_playback_order_changed2 + " (" + dt11 + ")", g_font, RGB(80, 80, 80), 0, 80, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_item_focus_change = " + on_item_focus_change2 + " (" + dt12 + ")", g_font, RGB(80, 80, 80), 0, 100, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_metadb_changed = " + on_metadb_changed2 + " (" + dt13 + ")", g_font, RGB(80, 80, 80), 0, 120, window.Width, window.Height, 0x11005000);
    gr.DrawString("on_get_album_art_done = " + on_get_album_art_done2 + " (" + dt14 + ")", g_font, RGB(80, 80, 80), 0, 140, window.Width, window.Height, 0x11005000);
    sum = on_playback_starting2 + on_playback_new_track2 + on_playback_stop2 + on_playback_seek2 + on_playback_pause2 + on_playback_edited2 + on_playback_dynamic_info2 + on_playback_dynamic_info_track2 + on_item_played2 + on_playback_order_changed2 + on_item_focus_change2 + on_metadb_changed2 + on_get_album_art_done2 + on_volume_change2;
    gr.DrawString("on_volume_change = " + on_volume_change2 + " (" + dt15 + ") [sum: " + sum + "]", g_font, RGB(80, 80, 80), 0, 160, window.Width, window.Height, 0x11005000);
}



function on_playback_starting(cmd, is_paused) {
    on_playback_starting2++;
    dt2 = Date();
    window.Repaint();
}



function on_item_played(metadb) {
    on_item_played2++;
    dt3 = Date();
    window.Repaint();
}



function on_playback_new_track(metadb) {
    on_playback_new_track2++;
    dt4 = Date();
    window.Repaint();
}



function on_playback_stop(reason) {
    on_playback_stop2++;
    dt5 = Date();
    window.Repaint();
}



function on_playback_seek(time) {
    on_playback_seek2++;
    dt6 = Date();
    window.Repaint();
}



function on_playback_pause(state) {
    on_playback_pause2++;
    dt7 = Date();
    window.Repaint();
}



function on_playback_edited() {
    on_playback_edited2++;
    dt8 = Date();
    window.Repaint();
}



function on_playback_dynamic_info() {
    on_playback_dynamic_info2++;
    dt9 = Date();
    window.Repaint();
}



function on_playback_dynamic_info_track() {
    on_playback_dynamic_info_track2++;
    dt10 = Date();
    window.Repaint();
}



function on_playback_time(time) {
    on_playback_time2++;
    var dt = new Date(on_playback_time2 * 1000);
    seconds = dt.getUTCSeconds();
    minutes = dt.getUTCMinutes();
    hours = dt.getUTCHours();
    days = Math.floor(on_playback_time2 / 86400);
    window.Repaint();
}



function on_playback_order_changed(new_order_index) {
    on_playback_order_changed2++;
    dt11 = Date();
    window.Repaint();
}



function on_item_focus_change() {
    on_item_focus_change2++;
    dt12 = Date();
    window.Repaint();
}



function on_metadb_changed(metadb, fromhook) {
    on_metadb_changed2++;
    dt13 = Date();
    window.Repaint();
}



function on_get_album_art_done(metadb, art_id, image) {
    on_get_album_art_done2++;
    dt14 = Date();
    window.Repaint();
}



function on_volume_change(val) {
    on_volume_change2++;
    dt15 = Date();
    window.Repaint();
}



function on_timer(id) {
    if (g_timer1 && id == g_timer1.ID) {
        count2++;
        idle = count2 - on_playback_time2;
        var dt1000 = new Date(idle * 1000);
        seconds3 = dt1000.getUTCSeconds();
        minutes3 = dt1000.getUTCMinutes();
        hours3 = dt1000.getUTCHours();
        days3 = Math.floor(count2 / 86400);
        var dt100 = new Date(count2 * 1000);
        seconds2 = dt100.getUTCSeconds();
        minutes2 = dt100.getUTCMinutes();
        hours2 = dt100.getUTCHours();
        days2 = Math.floor(count2 / 86400);
        proc = on_playback_time2 / count2 * 100;
        proc = Math.round(proc);
        proc2 = 100 - (on_playback_time2 / count2 * 100);
        proc2 = Math.round(proc2);
        window.Repaint();
    }
}

Take a look for updated versions here:
http://foobar-users.de/index.php?topic=200...g14184#msg14184

WSH Panel Mod

Reply #409
@2E7AH

Can you please post your rating code. I use NEMO7538's script too, but I get a different error message, and am less savvy with JS.

WSH Panel Mod

Reply #410
WSH has pretty much advanced editor so you should just change line 70 with the line from my last post

I feel strange to just paste the same script with only couple of lines changed, but OK if you can't manage JS
Spacing is changed from 20 to 16 px, and rating is focused in now playing track instead of what's selected, but if nothing is played it's focused on current selection:

Code: [Select]
function RGB(r,g,b){ return (0xff000000|(r<<16)|(g<<8)|(b)); }


var g_drag = 0;
var bool;
var g_metadb;
var imgname;
var rating;
var nrating;
var lrating;
var img;
var hofset=16;
var imgw=16;
var g_tfo = fb.TitleFormat("%rating%");

on_item_focus_change();

function on_paint(gr){
if (g_metadb) {
for (i = 1; i < 6; i++) {
img = gdi.image(fb.FoobarPath + "Images\\"
+ ((i > (g_drag ? lrating : rating)) ? "NoStar" : "Star" +  (g_drag ?  "-hover" : "")) + ".png");
gr.DrawImage(img, hofset+imgw*(i-1), 4, 16, 16, 0, 0, 16, 16);
}
}
}

function on_mouse_wheel(delta){}


function on_mouse_lbtn_up(x,y){
if (lrating !=rating) {if (g_metadb) {
bool = fb.RunContextCommandWithMetadb("Rating/"+((lrating==0) ? "<not set>" : lrating),g_metadb);
}}
}

function on_mouse_move(x, y) {
if (g_metadb) {
g_drag = 1;
nrating = Math.ceil((x-hofset)/imgw);
if (nrating > 5) nrating = 5;
if (nrating != lrating) {
lrating = nrating;
window.Repaint();
}
}
}
function on_mouse_leave() {
on_metadb_changed()
}

function on_item_focus_change() {
if (g_metadb) {window.UnwatchMetadb();}
g_metadb = fb.GetFocusItem();
if (fb.IsPlaying | fb.IsPaused) g_metadb = fb.GetNowPlaying();
if (g_metadb) {
on_metadb_changed();
window.WatchMetadb(g_metadb);
}

}
function on_metadb_changed() {
g_drag = 0;
if (g_metadb) {rating = g_tfo.EvalWithMetadb(g_metadb);}
if (rating == "?") {rating = 0;}
lrating = rating;
window.Repaint();
}

function on_playback_new_track(metadb) {on_item_focus_change();}
//EOF

WSH Panel Mod

Reply #411
Thanks, I just found out why I had problems. I think there is something broken with fb.ProfilePath. I just copied the images back into the foobar install folder and everything works again. Even though the path is still set to: img = gdi.image(fb.ProfilePath + "images\\columns\\rating\\4\\"

WSH Panel Mod

Reply #412
@qwertz
fb.ProfilePath now Fixed, please re-download the archive again.

 

WSH Panel Mod

Reply #413
Quote
- ADD: window.MaxWidth, window.MaxHeight, window.MinWidth and window.MinHeight properties.
Thanks T.P. Wang

For those who may be interested, here is a track info like panel that will display three lines of information, (vertical scrolling with mouse wheel) with automated horizontal scolling

Code: [Select]
function RGB(r,g,b){ return (0xff000000|(r<<16)|(g<<8)|(b)); }

DT_CENTER = 0x00000001;
DT_VCENTER = 0x00000004;
DT_SINGLELINE = 0x00000020;

var g_drag = 0;
var g_metadb;
var g_timer;



var g_tfo1 = fb.TitleFormat("%artist%  •  %title%");
var g_tfo2 = fb.TitleFormat("[%album%]  ['  # '$num(%tracknumber%,2)]");
var g_tfo3 = fb.TitleFormat("$left(%_path%,2)/$directory(%path%,3)/$directory(%path%,2)/...      [%genre%]");
var g_tfo;

var g_font = gdi.Font("Tahoma", 22, 1);
var backcol = RGB(240,240,226);
var playcol = RGB(48,0,0); var pausecol = RGB(128,128,92);
var hofset=8; var vofset =2;

var txt;
var strlength;
var i; var j;
var sens;

window.MinHeight = 32;
g_tfo = g_tfo1;

function on_paint(gr){
gr.FillSolidRect(0,0, window.Width, window.Height, backcol);
if (g_metadb) {
strlength = gr.CalcTextWidth(txt, g_font);
if (strlength > window.Width - 2*hofset ) {
if (g_timer) {
i = i + sens*1;
gr.GdiDrawText(txt, g_font, RGB(255,255,255), hofset+3-i, vofset+2, strlength, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
gr.GdiDrawText(txt, g_font, (fb.IsPaused ? pausecol : playcol), hofset+2-i, vofset+1, strlength, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
gr.FillSolidRect(0,0, hofset, window.Height, backcol);
gr.FillSolidRect(window.Width-hofset+1,0, hofset-1, window.Height, backcol);
if ((i > strlength - window.Width +2*hofset)||(i<0)) {
sens = -1*sens;
j = 0;
}
}
else {
j = 0; i = 0; sens = 1;
g_timer = window.CreateTimerInterval(50);
}
}
else {
if (g_timer) {window.KillTimer(g_timer); g_timer=false;}
gr.GdiDrawText(txt, g_font, RGB(255,255,255), hofset+3, vofset+2, window.Width - 2*hofset - 2, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
gr.GdiDrawText(txt, g_font, (fb.IsPaused ? pausecol : playcol), hofset+2, vofset+1, window.Width - 2*hofset - 2, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
}
}


function on_timer(id) {
if (g_timer && id == g_timer.ID) {
if (j==0) {
// window.RepaintRect(hofset, vofset, window.Width - 2*hofset +1, window.Height - 2*vofset , false);
window.Repaint();
}
if (j < 30) {j = j+1; }
else {
// window.RepaintRect(hofset, vofset, window.Width - 2*hofset+1 , window.Height - 2*vofset , false);
window.Repaint();
}
}
}
function on_size() {
if (g_timer) {window.KillTimer(g_timer); g_timer=false;}
}


function on_mouse_wheel(delta){
if (fb.IsPlaying | fb.IsPaused) {
if (g_tfo == g_tfo1) {g_tfo = g_tfo2;}
else {
if (g_tfo == g_tfo2) {g_tfo = g_tfo3;}
else {
if (g_tfo == g_tfo3) {g_tfo = g_tfo1;}
}
}
if (g_metadb) {txt = g_tfo.EvalWithMetadb(g_metadb);}
window.Repaint();
}
}



//function on_metadb_changed() {
// if (g_metadb) {txt = g_tfo.EvalWithMetadb(g_metadb);}
// window.Repaint();
// }

function on_playback_new_track(metadb) {
g_tfo = g_tfo1;
g_metadb = fb.GetNowPlaying();
if (g_metadb) {txt = g_tfo.EvalWithMetadb(g_metadb);}
window.Repaint();
}

// state = true when paused, false when resumed
function on_playback_pause(state) {
window.Repaint();
// window.RepaintRect(hofset, vofset, window.Width - 2*hofset , window.Height - 2*vofset , false);
}

// reason: (integer, begin with 0): user, eof, starting_another, shutting_down
function on_playback_stop(reason) {
txt = "";
window.Repaint();
}

// cmd: (integer, begin with 0): default, play, next, prev, settrack, rand, resume
function on_playback_starting(cmd, is_paused) {}


//EOF
@T.P. Wang, it seems that a '&' character within the formating strings is changed to '_'.
Do you have any idea?

WSH Panel Mod

Reply #414
NEMO7538, I get error:

Code: [Select]
Scripting Engine Initialization Failed (GUID: 051E807B-10EA-41AE-98AF-49A51380DCDF, CODE: 0x80020101): Unknown error code (2147614977)


debugger points at line 28

WSH Panel Mod

Reply #415
^do you have the latest version? i'm guessing not.

(works fine for me)

WSH Panel Mod

Reply #416
1.2.0 Beta 1

maybe something is wrong with my PC

[edit] Didn't notice that there is 1.2.0 stable. It works fine with it

WSH Panel Mod

Reply #417
@NEMO7538:
Pass DT_NOPREFIX (defined in Flags.txt) to GdiDrawText() combined with other flags if you like.

WSH Panel Mod

Reply #418
@T.P. Wang, it seems that a '&' character within the formating strings is changed to '_'.
Do you have any idea?


I have this same observation and was replacing them in the code with a similar sign that is displayed correctly, but I prefer a solution where it is displayed correctly in the first place.

WSH Panel Mod

Reply #419
@NEMO7538:
Pass DT_NOPREFIX (defined in Flags.txt) to GdiDrawText() combined with other flags if you like.
Thanks.
Updated code below
Code: [Select]
function RGB(r,g,b){ return (0xff000000|(r<<16)|(g<<8)|(b)); }

DT_CENTER = 0x00000001;
DT_VCENTER = 0x00000004;
DT_SINGLELINE = 0x00000020;
DT_NOPREFIX = 0x00000800;

var g_drag = 0;
var g_metadb;
var g_timer;



var g_tfo1 = fb.TitleFormat("%artist%  •  %title%");
var g_tfo2 = fb.TitleFormat("[%album%]  ['  # '$num(%tracknumber%,2)]");
var g_tfo3 = fb.TitleFormat("$left(%_path%,2)/$directory(%path%,3)/$directory(%path%,2)/...      [%genre%]");
var g_tfo;

var g_font = gdi.Font("Tahoma", 22, 1);
var backcol = RGB(240,240,226);
var playcol = RGB(48,0,0); var pausecol = RGB(128,128,92);
var hofset=8; var vofset =2;

var txt;
var strlength;
var i; var j;
var sens;

window.MinHeight = 32;
g_tfo = g_tfo1;

function on_paint(gr){
gr.FillSolidRect(0,0, window.Width, window.Height, backcol);
if (g_metadb) {
strlength = gr.CalcTextWidth(txt, g_font);
if (strlength > window.Width - 2*hofset ) {
if (g_timer) {
i = i + sens*1;
gr.GdiDrawText(txt, g_font, RGB(255,255,255), hofset+3-i, vofset+2, strlength, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
gr.GdiDrawText(txt, g_font, (fb.IsPaused ? pausecol : playcol), hofset+2-i, vofset+1, strlength, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
gr.FillSolidRect(0,0, hofset, window.Height, backcol);
gr.FillSolidRect(window.Width-hofset+1,0, hofset-1, window.Height, backcol);
if ((i > strlength - window.Width +2*hofset)||(i<0)) {
sens = -1*sens;
j = 0;
}
}
else {
j = 0; i = 0; sens = 1;
g_timer = window.CreateTimerInterval(50);
}
}
else {
if (g_timer) {window.KillTimer(g_timer); g_timer=false;}
gr.GdiDrawText(txt, g_font, RGB(255,255,255), hofset+3, vofset+2, window.Width - 2*hofset - 2, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
gr.GdiDrawText(txt, g_font, (fb.IsPaused ? pausecol : playcol), hofset+2, vofset+1, window.Width - 2*hofset - 2, window.Height - 2*vofset - 1, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
}
}
}


function on_timer(id) {
if (g_timer && id == g_timer.ID) {
if (j==0) {
// window.RepaintRect(hofset, vofset, window.Width - 2*hofset +1, window.Height - 2*vofset , false);
window.Repaint();
}
if (j < 30) {j = j+1; }
else {
// window.RepaintRect(hofset, vofset, window.Width - 2*hofset+1 , window.Height - 2*vofset , false);
window.Repaint();
}
}
}
function on_size() {
if (g_timer) {window.KillTimer(g_timer); g_timer=false;}
}


function on_mouse_wheel(delta){
if (fb.IsPlaying | fb.IsPaused) {
if (g_tfo == g_tfo1) {g_tfo = g_tfo2;}
else {
if (g_tfo == g_tfo2) {g_tfo = g_tfo3;}
else {
if (g_tfo == g_tfo3) {g_tfo = g_tfo1;}
}
}
if (g_metadb) {txt = g_tfo.EvalWithMetadb(g_metadb);}
window.Repaint();
}
}



//function on_metadb_changed() {
// if (g_metadb) {txt = g_tfo.EvalWithMetadb(g_metadb);}
// window.Repaint();
// }

function on_playback_new_track(metadb) {
g_tfo = g_tfo1;
g_metadb = fb.GetNowPlaying();
if (g_metadb) {txt = g_tfo.EvalWithMetadb(g_metadb);}
window.Repaint();
}

// state = true when paused, false when resumed
function on_playback_pause(state) {
window.Repaint();
// window.RepaintRect(hofset, vofset, window.Width - 2*hofset , window.Height - 2*vofset , false);
}

// reason: (integer, begin with 0): user, eof, starting_another, shutting_down
function on_playback_stop(reason) {
txt = "";
window.Repaint();
}

// cmd: (integer, begin with 0): default, play, next, prev, settrack, rand, resume
function on_playback_starting(cmd, is_paused) {}


//EOF

WSH Panel Mod

Reply #420
Quote
v1.2.0
- ADD: Preprocessor directive "@import", See Preprocessors.txt for more details.
- ADD: Preprocessor sample.


ah this is great. thanks T.P. 

WSH Panel Mod

Reply #421
i need help again.

edit: no i don't. problem my end. sorted.

WSH Panel Mod

Reply #422
here's a script that reads your lastfm playcount using the web services and then writes the response to your file tags. it only runs after the track has been playing for 60 seconds. it's not interactive in anyway so the panel should be hidden. just add a new column (default is LASTFM_PLAYCOUNT) and play your music as usual.

BTW, you need to signup for a lastfm API key here (only takes a few seconds if you're already logged in) - http://www.last.fm/api/account

Code: [Select]
var username = "YOUR_USERNAME";
var api_key = "YOUR_API_KEY";
var playcount_tag_name = "LASTFM_PLAYCOUNT";

function on_item_played() {
var g_metadb = fb.GetNowPlaying();
var artist = fb.TitleFormat("$replace(%artist%,&,'%'26)").EvalWithMetadb(g_metadb);
var track = fb.TitleFormat("$replace(%title%,&,'%'26)").EvalWithMetadb(g_metadb);
var url = unescape(encodeURIComponent("http://ws.audioscrobbler.com/2.0/?method=track.getinfo&api_key=" + api_key + "&username=" + username + "&artist=" + artist + "&track=" + track));
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
xhttp.open("GET",url,false);
xhttp.send();
xmlDoc = xhttp.responseXML;
var x = xmlDoc.getElementsByTagName("track");
if(x.length == 1) {
var y = xmlDoc.getElementsByTagName("userplaycount");
if(y.length == 1) {
var lastfm_playcount = xmlDoc.getElementsByTagName("userplaycount")[0].childNodes[0].nodeValue;
var old_lastfm_playcount = fb.TitleFormat("%" + playcount_tag_name + "%").EvalWithMetadb(g_metadb);
//only update file if lastfm value is different from current value
if(lastfm_playcount != old_lastfm_playcount) g_metadb.UpdateFileInfoSimple(playcount_tag_name, lastfm_playcount);
}
} else {
fb.trace("error:");
fb.trace(url);
fb.trace("returned:");
fb.trace(xhttp.responsetext);
}
}

WSH Panel Mod

Reply #423
i have a bug report to file. i'm using on_item_played to write tags to a file. but if the track is less than one minute, the function runs on the next track as soon as it begins playing, totally skipping the previous short track.


WSH Panel Mod

Reply #424
First a big thank you T.P Wang for releasing and developing this component. I ignored it for too long. Now that foo_uie_trackinfo_mod became problematic, I finally took the challenge and tried to master the mysteries of callbacks and repaint functions. It was to my best; I managed not only to mimic all functionality of my old trackinfo_mod trackinfo display, there is still much to come.

Here is my current "test" now playing WSH panel:



Maybe the code is for use to someone:
Code: [Select]
// -----------------------------------------------------------------------
// WSH-test-nowplaying
// a WSH panel script by ojdo
// last modified: 2009-12-04
// -----------------------------------------------------------------------

// HELPER FUNCTIONS

function StringFormat() {
var h_align = 0, v_align = 0, trimming = 0, flags = 0;
switch (arguments.length)
{
// fall-through
case 4: flags = arguments[3];
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);
}
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)); }

// INITIALIZATION

var g_albumart = null, g_albumart_rot = null;
var g_artistart = null, g_artistart_rot = null;
var g_font_title = gdi.Font("Calibri", 40, 0);
var g_font_artist = gdi.Font("Calibri", 26, 0);
var g_fontsmall = gdi.Font("Calibri", 14, 0);
var g_stringformat = StringFormat(1, 0);

var ww = 0, wh = 0; // Window width, height
var g_handle = null; // metadb handle variable for watching the currently played track
AlbumArtId = { front: 0, back: 1, disc: 2, icon: 3, artist: 4 };

// evoke callback function to initially paint the window
on_playback_new_track(fb.GetNowPlaying());

// -----------------------------------------------------------------------

// DRAW CANVAS CONTENT
function on_paint(gr) {
gr.SetTextRenderingHint(5); // enable cleartype font rendering

// Background
gr.FillSolidRect(0, 0, ww, wh, RGB(0,0,0));
gr.FillGradRect(0, 3*wh/4, ww, 20, 90,RGBA(128,128,128,64), RGBA(128,128,128,0));

// Reflected albumart
if(g_albumart) {
var scale_w = 0.9*ww / g_albumart.Width;
var scale_h = 0.9*(0.75*wh+20) / g_albumart.Height;
var scale = Math.min(scale_w, scale_h);
var pos_x = (ww - g_albumart.Width * scale) / 2;
var pos_y = 0.75*wh+20- g_albumart.height * scale;
var img_w = g_albumart.Width * scale;
var img_h = g_albumart.Height * scale;
gr.DrawImage(g_albumart_rot, pos_x, pos_y+img_h, img_w, img_h, 0, 0, g_albumart.Width, g_albumart.Height);
gr.DrawRect(pos_x+1,pos_y+img_h+1,img_w-2, wh-pos_y-img_h-2, 1.0,RGBA(128,128,128,64));
gr.FillGradRect(pos_x,pos_y+img_h,img_w,wh/5, 90, RGBA(0,0,0,128), RGB(0,0,0,255));
gr.FillSolidRect(pos_x,pos_y+img_h+wh/5,img_w,4*wh/5, RGBA(0,0,0,255));
}

// Rating and Mood
gr.FillGradRect(0, wh-40, rating*30, 10, 90, RGB(255,128,0), RGB(255,128,0));
gr.FillGradRect(ww-mood*30, wh-40, mood*30, 10, 90, RGB(0, 255, 0), RGB(0, 255, 0));
gr.DrawString(rating, g_fontsmall, RGB(255,255,255), rating*30+5, wh-45, 20, 20, StringFormat(0,0));
gr.DrawString(mood, g_fontsmall, RGB(255,255,255), ww-mood*30-25, wh-45, 20, 20, StringFormat(2,0));

// Artist & Title
gr.DrawString(title, g_font_title, RGB(255, 255, 255), 0, 0.83*wh, ww, 50, g_stringformat);
gr.DrawString(artist, g_font_artist, RGB(255, 255, 255), 0, 0.83*wh+40, ww, 30, g_stringformat);

// Progressbar
switch(fb.PlaybackOrder) { // change color of progressbar according to playback order
case 0: pbcolor = RGB(0,128,255); break; // Default
case 1: // RepeatPlaylist
case 2: pbcolor = RGB(255,255,0); break; // RepeatTrack
case 3: pbcolor = RGB(64,64,255); break; // Random
case 4: pbcolor = RGB(128,64,192); break; // ShuffleTracks
case 5: // ShuffleAlbums
case 6: pbcolor = RGB(64,64,255); break; // ShuffleFolders
default: pbcolor = RGB(255,0,0); break; // should not happen
}
if (fb.PlaybackLength>0) {
gr.FillSolidRect(0,wh-20, fb.PlaybackTime/fb.PlaybackLength*ww, 10, pbcolor);
}
gr.DrawString(fb.TitleFormat("%playback_time%").Eval(), g_fontsmall, RGB(255,255,255), fb.PlaybackTime/fb.PlaybackLength*ww+5, wh-25, 80, 20, StringFormat(0,0));

// Albumart
if (g_albumart) {
gr.DrawImage(g_albumart, pos_x, pos_y, img_w, img_h, 0, 0, g_albumart.Width, g_albumart.Height);
gr.DrawRect(pos_x+1,pos_y+1,img_w-2, img_h-2, 1.0,RGBA(128,128,128,32));
}
}

// -----------------------------------------------------------------------
// CALLBACKS
// -----------------------------------------------------------------------

// window size changed
function on_size() {
ww = window.Width;
wh = window.Height;
}

// new track
function on_playback_new_track(metadb) {
if (metadb) {
utils.GetAlbumArtAsync(window.ID, metadb, AlbumArtId.front);
utils.GetAlbumArtAsync(window.ID, metadb, AlbumArtId.artist);
}
g_albumart = null;
g_albumart_rot = null;
g_artistart = null;
g_artistart_rot = null;

if (g_handle) {window.UnwatchMetadb();}
g_handle = fb.GetNowPlaying();
if (g_handle) {
on_metadb_changed(); // calls on_metadb_changed()
window.WatchMetadb(g_handle);
}
}

// tag content changed
function on_metadb_changed() {
rating = fb.TitleFormat("%rating%").Eval(); if(rating == "?") rating=-1;
mood = fb.TitleFormat("%mood%").Eval(); if(mood == "?") mood=-1;
title = fb.TitleFormat("%title%").Eval();
artist = fb.TitleFormat("%artist%").Eval();
albumartist = fb.TitleFormat("%album artist%").Eval();
trackartist = fb.TitleFormat("%track artist").Eval();
album = fb.TitleFormat("%album%").Eval();
date = fb.TitleFormat("%date%").Eval();
window.RepaintRect(0,wh-40,ww,10); // calls on_paint()
}

// time (each second) and on seeking
function on_playback_time(time) { window.RepaintRect(0,wh-25,ww,20); }
function on_playback_seek(time) { window.RepaintRect(0,wh-25, ww, 20); }

// playback order changed
function on_playback_order_changed(new_order_index) { window.RepaintRect(0,wh-25, ww, 20); }

// album art retrieved
function on_get_album_art_done(metadb, art_id, image) {
switch(art_id) {
case AlbumArtId.front:
g_albumart = image;
g_albumart_rot = g_albumart.Clone(0, 0, g_albumart.Width, g_albumart.Height);
g_albumart_rot.RotateFlip(6);
window.Repaint(); // calls on_paint()
break;
case AlbumArtId.artist:
g_artistart = image;
g_artistart_rot = g_artistart.Clone(0, 0, g_artistart.Width, g_artistart.Height);
g_artistart_rot.RotateFlip(6);
window.Repaint(); // calls on_paint()
break;
}
}
// EOF

Next I plan to finally write a full replacement for my former fullscreen HTPC trackinfo displays.